Merge pull request #1467 from thinkyhead/marlin_configurator

Configurator utility
master
Scott Lahteine 10 years ago
commit b83e52e50f

@ -351,12 +351,12 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
#define max_software_endstops true // If true, axis won't move to coordinates greater than the defined lengths below.
// Travel limits after homing (units are in mm)
#define X_MAX_POS 200
#define X_MIN_POS 0
#define Y_MAX_POS 200
#define Y_MIN_POS 0
#define Z_MAX_POS 200
#define Z_MIN_POS 0
#define X_MAX_POS 200
#define Y_MAX_POS 200
#define Z_MAX_POS 200
#define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS)
#define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS)
@ -476,12 +476,14 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
//#define MANUAL_HOME_POSITIONS // If defined, MANUAL_*_HOME_POS below will be used
//#define BED_CENTER_AT_0_0 // If defined, the center of the bed is at (X=0, Y=0)
//Manual homing switch locations:
// Manual homing switch locations:
// For deltabots this means top and center of the Cartesian print volume.
#define MANUAL_X_HOME_POS 0
#define MANUAL_Y_HOME_POS 0
#define MANUAL_Z_HOME_POS 0
//#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
#ifdef MANUAL_HOME_POSITIONS
#define MANUAL_X_HOME_POS 0
#define MANUAL_Y_HOME_POS 0
#define MANUAL_Z_HOME_POS 0
//#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
#endif
//// MOVEMENT SETTINGS
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E

@ -286,8 +286,8 @@
//===========================================================================
#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly
#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceed this value, multiple the steps moved by ten to quickly advance the value
#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceed this value, multiple the steps moved by 100 to really quickly advance the value
#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value
#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value
//#define ENCODER_RATE_MULTIPLIER_DEBUG // If defined, output the encoder steps per second value
//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/

@ -0,0 +1,898 @@
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#include "boards.h"
//===========================================================================
//============================= Getting Started =============================
//===========================================================================
/*
Here are some standard links for getting your machine calibrated:
* http://reprap.org/wiki/Calibration
* http://youtu.be/wAL9d7FgInk
* http://calculator.josefprusa.cz
* http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide
* http://www.thingiverse.com/thing:5573
* https://sites.google.com/site/repraplogphase/calibration-of-your-reprap
* http://www.thingiverse.com/thing:298812
*/
// This configuration file contains the basic settings.
// Advanced settings can be found in Configuration_adv.h
// BASIC SETTINGS: select your board type, temperature sensor type, axis scaling, and endstop configuration
//===========================================================================
//============================= DELTA Printer ===============================
//===========================================================================
// For a Delta printer replace the configuration files with the files in the
// example_configurations/delta directory.
//
//===========================================================================
//============================= SCARA Printer ===============================
//===========================================================================
// For a Delta printer replace the configuration files with the files in the
// example_configurations/SCARA directory.
//
// @section info
// User-specified version info of this build to display in [Pronterface, etc] terminal window during
// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this
// build by the user have been successfully uploaded into firmware.
#define STRING_VERSION "1.0.2"
#define STRING_URL "reprap.org"
#define STRING_VERSION_CONFIG_H __DATE__ " " __TIME__ // build date and time
#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes.
#define STRING_SPLASH_LINE1 "v" STRING_VERSION // will be shown during bootup in line 1
//#define STRING_SPLASH_LINE2 STRING_VERSION_CONFIG_H // will be shown during bootup in line2
// @section machine
// SERIAL_PORT selects which serial port should be used for communication with the host.
// This allows the connection of wireless adapters (for instance) to non-default port pins.
// Serial port 0 is still used by the Arduino bootloader regardless of this setting.
// :[0,1,2,3,4,5,6,7]
#define SERIAL_PORT 0
// This determines the communication speed of the printer
// :[2400,9600,19200,38400,57600,115200,250000]
#define BAUDRATE 250000
// This enables the serial port associated to the Bluetooth interface
//#define BTENABLED // Enable BT interface on AT90USB devices
// The following define selects which electronics board you have.
// Please choose the name from boards.h that matches your setup
#ifndef MOTHERBOARD
#define MOTHERBOARD BOARD_ULTIMAKER
#endif
// Define this to set a custom name for your generic Mendel,
// #define CUSTOM_MENDEL_NAME "This Mendel"
// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines)
// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
// #define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
// This defines the number of extruders
// :[1,2,3,4]
#define EXTRUDERS 1
//// The following define selects which power supply you have. Please choose the one that matches your setup
// 1 = ATX
// 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC)
// :{1:'ATX',2:'X-Box 360'}
#define POWER_SUPPLY 1
// Define this to have the electronics keep the power supply off on startup. If you don't know what this is leave it.
// #define PS_DEFAULT_OFF
// @section temperature
//===========================================================================
//============================= Thermal Settings ============================
//===========================================================================
//
//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
//
//// Temperature sensor settings:
// -2 is thermocouple with MAX6675 (only for sensor 0)
// -1 is thermocouple with AD595
// 0 is not used
// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
// 3 is Mendel-parts thermistor (4.7k pullup)
// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup)
// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup)
// 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
// 10 is 100k RS thermistor 198-961 (4.7k pullup)
// 11 is 100k beta 3950 1% thermistor (4.7k pullup)
// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
// 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
// 20 is the PT100 circuit found in the Ultimainboard V2.x
// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
//
// 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k
// (but gives greater accuracy and more stable PID)
// 51 is 100k thermistor - EPCOS (1k pullup)
// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup)
//
// 1047 is Pt1000 with 4k7 pullup
// 1010 is Pt1000 with 1k pullup (non standard)
// 147 is Pt100 with 4k7 pullup
// 110 is Pt100 with 1k pullup (non standard)
// 998 and 999 are Dummy Tables. They will ALWAYS read 25°C or the temperature defined below.
// Use it for Testing or Development purposes. NEVER for production machine.
// #define DUMMY_THERMISTOR_998_VALUE 25
// #define DUMMY_THERMISTOR_999_VALUE 100
// :{ 0: "Not used", 4: "10k !! do not use for a hotend. Bad resolution at high temp. !!", 1: "100k / 4.7k - EPCOS", 51: "100k / 1k - EPCOS", 6: "100k / 4.7k EPCOS - Not as accurate as Table 1", 5: "100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", 7: "100k / 4.7k Honeywell 135-104LAG-J01", 71: "100k / 4.7k Honeywell 135-104LAF-J01", 8: "100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", 9: "100k / 4.7k GE Sensing AL03006-58.2K-97-G1", 10: "100k / 4.7k RS 198-961", 11: "100k / 4.7k beta 3950 1%", 12: "100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", 13: "100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", 60: "100k Maker's Tool Works Kapton Bed Thermistor beta=3950", 55: "100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", 2: "200k / 4.7k - ATC Semitec 204GT-2", 52: "200k / 1k - ATC Semitec 204GT-2", '-2': "Thermocouple + MAX6675 (only for sensor 0)", '-1': "Thermocouple + AD595", 3: "Mendel-parts / 4.7k", 1047: "Pt1000 / 4.7k", 1010: "Pt1000 / 1k (non standard)", 20: "PT100 (Ultimainboard V2.x)", 147: "Pt100 / 4.7k", 110: "Pt100 / 1k (non-standard)", 998: "Dummy 1", 999: "Dummy 2" }
#define TEMP_SENSOR_0 -1
#define TEMP_SENSOR_1 -1
#define TEMP_SENSOR_2 0
#define TEMP_SENSOR_3 0
#define TEMP_SENSOR_BED 0
// This makes temp sensor 1 a redundant sensor for sensor 0. If the temperatures difference between these sensors is to high the print will be aborted.
//#define TEMP_SENSOR_1_AS_REDUNDANT
#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10
// Actual temperature must be close to target for this long before M109 returns success
#define TEMP_RESIDENCY_TIME 10 // (seconds)
#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// The minimal temperature defines the temperature below which the heater will not be enabled It is used
// to check that the wiring to the thermistor is not broken.
// Otherwise this would lead to the heater being powered on all the time.
#define HEATER_0_MINTEMP 5
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_3_MINTEMP 5
#define BED_MINTEMP 5
// When temperature exceeds max temp, your heater will be switched off.
// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
// You should use MINTEMP for thermistor short/failure protection.
#define HEATER_0_MAXTEMP 275
#define HEATER_1_MAXTEMP 275
#define HEATER_2_MAXTEMP 275
#define HEATER_3_MAXTEMP 275
#define BED_MAXTEMP 150
// If your bed has low resistance e.g. .6 ohm and throws the fuse you can duty cycle it to reduce the
// average current. The value should be an integer and the heat bed will be turned on for 1 interval of
// HEATER_BED_DUTY_CYCLE_DIVIDER intervals.
//#define HEATER_BED_DUTY_CYCLE_DIVIDER 4
// If you want the M105 heater power reported in watts, define the BED_WATTS, and (shared for all extruders) EXTRUDER_WATTS
//#define EXTRUDER_WATTS (12.0*12.0/6.7) // P=I^2/R
//#define BED_WATTS (12.0*12.0/1.1) // P=I^2/R
//===========================================================================
//============================= PID Settings ================================
//===========================================================================
// PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning
// Comment the following line to disable PID and enable bang-bang.
#define PIDTEMP
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#ifdef PIDTEMP
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
//#define PID_PARAMS_PER_EXTRUDER // Uses separate PID parameters for each extruder (useful for mismatched extruders)
// Set/get with gcode: M301 E[extruder number, 0-2]
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
#define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term
#define K1 0.95 //smoothing factor within the PID
#define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
// If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
// Ultimaker
#define DEFAULT_Kp 22.2
#define DEFAULT_Ki 1.08
#define DEFAULT_Kd 114
// MakerGear
// #define DEFAULT_Kp 7.0
// #define DEFAULT_Ki 0.1
// #define DEFAULT_Kd 12
// Mendel Parts V9 on 12V
// #define DEFAULT_Kp 63.0
// #define DEFAULT_Ki 2.25
// #define DEFAULT_Kd 440
#endif // PIDTEMP
//===========================================================================
//============================= PID > Bed Temperature Control ===============
//===========================================================================
// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
//
// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
// If your configuration is significantly different than this and you don't understand the issues involved, you probably
// shouldn't use bed PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
//#define PIDTEMPBED
//
//#define BED_LIMIT_SWITCHING
// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option.
// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did,
// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED)
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
#ifdef PIDTEMPBED
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#define DEFAULT_bedKp 10.00
#define DEFAULT_bedKi .023
#define DEFAULT_bedKd 305.4
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from pidautotune
// #define DEFAULT_bedKp 97.1
// #define DEFAULT_bedKi 1.41
// #define DEFAULT_bedKd 1675.16
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
// @section extruder
//this prevents dangerous Extruder moves, i.e. if the temperature is under the limit
//can be software-disabled for whatever purposes by
#define PREVENT_DANGEROUS_EXTRUDE
//if PREVENT_DANGEROUS_EXTRUDE is on, you can still disable (uncomment) very long bits of extrusion separately.
#define PREVENT_LENGTHY_EXTRUDE
#define EXTRUDE_MINTEMP 170
#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances.
//===========================================================================
//============================= Thermal Runaway Protection ==================
//===========================================================================
/*
This is a feature to protect your printer from burn up in flames if it has
a thermistor coming off place (this happened to a friend of mine recently and
motivated me writing this feature).
The issue: If a thermistor come off, it will read a lower temperature than actual.
The system will turn the heater on forever, burning up the filament and anything
else around.
After the temperature reaches the target for the first time, this feature will
start measuring for how long the current temperature stays below the target
minus _HYSTERESIS (set_temperature - THERMAL_RUNAWAY_PROTECTION_HYSTERESIS).
If it stays longer than _PERIOD, it means the thermistor temperature
cannot catch up with the target, so something *may be* wrong. Then, to be on the
safe side, the system will he halt.
Bear in mind the count down will just start AFTER the first time the
thermistor temperature is over the target, so you will have no problem if
your extruder heater takes 2 minutes to hit the target on heating.
*/
// If you want to enable this feature for all your extruder heaters,
// uncomment the 2 defines below:
// Parameters for all extruder heaters
//#define THERMAL_RUNAWAY_PROTECTION_PERIOD 40 //in seconds
//#define THERMAL_RUNAWAY_PROTECTION_HYSTERESIS 4 // in degree Celsius
// If you want to enable this feature for your bed heater,
// uncomment the 2 defines below:
// Parameters for the bed heater
//#define THERMAL_RUNAWAY_PROTECTION_BED_PERIOD 20 //in seconds
//#define THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS 2 // in degree Celsius
//===========================================================================
//============================= Mechanical Settings =========================
//===========================================================================
// @section machine
// Uncomment this option to enable CoreXY kinematics
// #define COREXY
// Enable this option for Toshiba steppers
// #define CONFIG_STEPPERS_TOSHIBA
// @section homing
// coarse Endstop Settings
#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors
#ifndef ENDSTOPPULLUPS
// fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined
// #define ENDSTOPPULLUP_XMAX
// #define ENDSTOPPULLUP_YMAX
// #define ENDSTOPPULLUP_ZMAX
// #define ENDSTOPPULLUP_XMIN
// #define ENDSTOPPULLUP_YMIN
// #define ENDSTOPPULLUP_ZMIN
#endif
#ifdef ENDSTOPPULLUPS
#define ENDSTOPPULLUP_XMAX
#define ENDSTOPPULLUP_YMAX
#define ENDSTOPPULLUP_ZMAX
#define ENDSTOPPULLUP_XMIN
#define ENDSTOPPULLUP_YMIN
#define ENDSTOPPULLUP_ZMIN
#endif
// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins.
const bool X_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
const bool Y_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
const bool Z_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
const bool X_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
const bool Y_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
//#define DISABLE_MAX_ENDSTOPS
//#define DISABLE_MIN_ENDSTOPS
// @section machine
// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
// :{0:'Low',1:'High'}
#define X_ENABLE_ON 0
#define Y_ENABLE_ON 0
#define Z_ENABLE_ON 0
#define E_ENABLE_ON 0 // For all extruders
// Disables axis when it's not being used.
#define DISABLE_X false
#define DISABLE_Y false
#define DISABLE_Z false
// @section extruder
#define DISABLE_E false // For all extruders
#define DISABLE_INACTIVE_EXTRUDER true //disable only inactive extruders and keep active extruder enabled
// @section machine
// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way.
#define INVERT_X_DIR true // for Mendel set to false, for Orca set to true
#define INVERT_Y_DIR false // for Mendel set to true, for Orca set to false
#define INVERT_Z_DIR true // for Mendel set to false, for Orca set to true
// @section extruder
// For direct drive extruder v9 set to true, for geared extruder set to false.
#define INVERT_E0_DIR false // Direct drive extruder v9: true. Geared extruder: false
#define INVERT_E1_DIR false // Direct drive extruder v9: true. Geared extruder: false
#define INVERT_E2_DIR false // Direct drive extruder v9: true. Geared extruder: false
#define INVERT_E3_DIR false // Direct drive extruder v9: true. Geared extruder: false
// @section homing
// ENDSTOP SETTINGS:
// Sets direction of endstops when homing; 1=MAX, -1=MIN
// :[-1,1]
#define X_HOME_DIR -1
#define Y_HOME_DIR -1
#define Z_HOME_DIR -1
#define min_software_endstops true // If true, axis won't move to coordinates less than HOME_POS.
#define max_software_endstops true // If true, axis won't move to coordinates greater than the defined lengths below.
// @section machine
// Travel limits after homing (units are in mm)
#define X_MIN_POS 0
#define Y_MIN_POS 0
#define Z_MIN_POS 0
#define X_MAX_POS 205
#define Y_MAX_POS 205
#define Z_MAX_POS 200
// @section hidden
#define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS)
#define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS)
#define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS)
//===========================================================================
//============================= Bed Auto Leveling ===========================
//===========================================================================
// @section bedlevel
//#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line)
#define Z_PROBE_REPEATABILITY_TEST // If not commented out, Z-Probe Repeatability test will be included if Auto Bed Leveling is Enabled.
#ifdef ENABLE_AUTO_BED_LEVELING
// There are 2 different ways to specify probing locations
//
// - "grid" mode
// Probe several points in a rectangular grid.
// You specify the rectangle and the density of sample points.
// This mode is preferred because there are more measurements.
//
// - "3-point" mode
// Probe 3 arbitrary points on the bed (that aren't colinear)
// You specify the XY coordinates of all 3 points.
// Enable this to sample the bed in a grid (least squares solution)
// Note: this feature generates 10KB extra code size
#define AUTO_BED_LEVELING_GRID
#ifdef AUTO_BED_LEVELING_GRID
// The edges of the rectangle in which to probe
#define LEFT_PROBE_BED_POSITION 15
#define RIGHT_PROBE_BED_POSITION 170
#define FRONT_PROBE_BED_POSITION 20
#define BACK_PROBE_BED_POSITION 170
// Set the number of grid points per dimension
// You probably don't need more than 3 (squared=9)
#define AUTO_BED_LEVELING_GRID_POINTS 2
#else // !AUTO_BED_LEVELING_GRID
// Arbitrary points to probe. A simple cross-product
// is used to estimate the plane of the bed.
#define ABL_PROBE_PT_1_X 15
#define ABL_PROBE_PT_1_Y 180
#define ABL_PROBE_PT_2_X 15
#define ABL_PROBE_PT_2_Y 20
#define ABL_PROBE_PT_3_X 170
#define ABL_PROBE_PT_3_Y 20
#endif // AUTO_BED_LEVELING_GRID
// Offsets to the probe relative to the extruder tip (Hotend - Probe)
// X and Y offsets must be integers
#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // -left +right
#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // -front +behind
#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // -below (always!)
#define Z_RAISE_BEFORE_HOMING 4 // (in mm) Raise Z before homing (G28) for Probe Clearance.
// Be sure you have this distance over your Z_MAX_POS in case
#define XY_TRAVEL_SPEED 8000 // X and Y axis travel speed between probes, in mm/min
#define Z_RAISE_BEFORE_PROBING 15 //How much the extruder will be raised before traveling to the first probing point.
#define Z_RAISE_BETWEEN_PROBINGS 5 //How much the extruder will be raised when traveling from between next probing points
//#define Z_PROBE_SLED // turn on if you have a z-probe mounted on a sled like those designed by Charles Bell
//#define SLED_DOCKING_OFFSET 5 // the extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like.
//If defined, the Probe servo will be turned on only during movement and then turned off to avoid jerk
//The value is the delay to turn the servo off after powered on - depends on the servo speed; 300ms is good value, but you can try lower it.
// You MUST HAVE the SERVO_ENDSTOPS defined to use here a value higher than zero otherwise your code will not compile.
// #define PROBE_SERVO_DEACTIVATION_DELAY 300
//If you have enabled the Bed Auto Leveling and are using the same Z Probe for Z Homing,
//it is highly recommended you let this Z_SAFE_HOMING enabled!!!
#define Z_SAFE_HOMING // This feature is meant to avoid Z homing with probe outside the bed area.
// When defined, it will:
// - Allow Z homing only after X and Y homing AND stepper drivers still enabled
// - If stepper drivers timeout, it will need X and Y homing again before Z homing
// - Position the probe in a defined XY point before Z Homing when homing all axis (G28)
// - Block Z homing only when the probe is outside bed area.
#ifdef Z_SAFE_HOMING
#define Z_SAFE_HOMING_X_POINT (X_MAX_LENGTH/2) // X point for Z homing when homing all axis (G28)
#define Z_SAFE_HOMING_Y_POINT (Y_MAX_LENGTH/2) // Y point for Z homing when homing all axis (G28)
#endif
#endif // ENABLE_AUTO_BED_LEVELING
// @section homing
// The position of the homing switches
//#define MANUAL_HOME_POSITIONS // If defined, MANUAL_*_HOME_POS below will be used
//#define BED_CENTER_AT_0_0 // If defined, the center of the bed is at (X=0, Y=0)
// Manual homing switch locations:
// For deltabots this means top and center of the Cartesian print volume.
#ifdef MANUAL_HOME_POSITIONS
#define MANUAL_X_HOME_POS 0
#define MANUAL_Y_HOME_POS 0
#define MANUAL_Z_HOME_POS 0
//#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
#endif
// @section movement
//// MOVEMENT SETTINGS
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
#define HOMING_FEEDRATE {50*60, 50*60, 4*60, 0} // set the homing speeds (mm/min)
// default settings
#define DEFAULT_AXIS_STEPS_PER_UNIT {78.7402,78.7402,200.0*8/3,760*1.1} // default steps per unit for Ultimaker
#define DEFAULT_MAX_FEEDRATE {500, 500, 5, 25} // (mm/sec)
#define DEFAULT_MAX_ACCELERATION {9000,9000,100,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for Skeinforge 40+, for older versions raise them a lot.
#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for printing moves
#define DEFAULT_RETRACT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for retracts
// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing).
// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder).
// For the other hotends it is their distance from the extruder 0 hotend.
// #define EXTRUDER_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
// #define EXTRUDER_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis
// The speed change that does not require acceleration (i.e. the software might assume it can be done instantaneously)
#define DEFAULT_XYJERK 20.0 // (mm/sec)
#define DEFAULT_ZJERK 0.4 // (mm/sec)
#define DEFAULT_EJERK 5.0 // (mm/sec)
//=============================================================================
//============================= Additional Features ===========================
//=============================================================================
// @section more
// Custom M code points
#define CUSTOM_M_CODES
#ifdef CUSTOM_M_CODES
#define CUSTOM_M_CODE_SET_Z_PROBE_OFFSET 851
#define Z_PROBE_OFFSET_RANGE_MIN -15
#define Z_PROBE_OFFSET_RANGE_MAX -5
#endif
// @section extras
// EEPROM
// The microcontroller can store settings in the EEPROM, e.g. max velocity...
// M500 - stores parameters in EEPROM
// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
//define this to enable EEPROM support
//#define EEPROM_SETTINGS
//to disable EEPROM Serial responses and decrease program space by ~1700 byte: comment this out:
// please keep turned on if you can.
//#define EEPROM_CHITCHAT
// @section temperature
// Preheat Constants
#define PLA_PREHEAT_HOTEND_TEMP 180
#define PLA_PREHEAT_HPB_TEMP 70
#define PLA_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
#define ABS_PREHEAT_HOTEND_TEMP 240
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
//==============================LCD and SD support=============================
// @section lcd
// Define your display language below. Replace (en) with your language code and uncomment.
// en, pl, fr, de, es, ru, it, pt, pt-br, fi, an, nl, ca, eu
// See also language.h
//#define LANGUAGE_INCLUDE GENERATE_LANGUAGE_INCLUDE(en)
// Character based displays can have different extended charsets.
#define DISPLAY_CHARSET_HD44780_JAPAN // "ääööüüß23°"
//#define DISPLAY_CHARSET_HD44780_WESTERN // "ÄäÖöÜüß²³°" if you see a '~' instead of a 'arrow_right' at the right of submenuitems - this is the right one.
//#define ULTRA_LCD //general LCD support, also 16x2
//#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
//#define SDSUPPORT // Enable SD Card Support in Hardware Console
//#define SDSLOW // Use slower SD transfer mode (not normally needed - uncomment if you're getting volume init error)
//#define SD_CHECK_AND_RETRY // Use CRC checks and retries on the SD communication
//#define ENCODER_PULSES_PER_STEP 1 // Increase if you have a high resolution encoder
//#define ENCODER_STEPS_PER_MENU_ITEM 5 // Set according to ENCODER_PULSES_PER_STEP or your liking
//#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
//#define ULTIPANEL //the UltiPanel as on Thingiverse
//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 // this is the tone frequency the buzzer plays when on UI feedback. ie Screen Click
//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 // the duration the buzzer plays the UI feedback sound. ie Screen Click
// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3)
// http://reprap.org/wiki/PanelOne
//#define PANEL_ONE
// The MaKr3d Makr-Panel with graphic controller and SD support
// http://reprap.org/wiki/MaKr3d_MaKrPanel
//#define MAKRPANEL
// The Panucatt Devices Viki 2.0 and mini Viki with Graphic LCD
// http://panucatt.com
// ==> REMEMBER TO INSTALL U8glib to your ARDUINO library folder: http://code.google.com/p/u8glib/wiki/u8glib
//#define VIKI2
//#define miniVIKI
// The RepRapDiscount Smart Controller (white PCB)
// http://reprap.org/wiki/RepRapDiscount_Smart_Controller
//#define REPRAP_DISCOUNT_SMART_CONTROLLER
// The GADGETS3D G3D LCD/SD Controller (blue PCB)
// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel
//#define G3D_PANEL
// The RepRapDiscount FULL GRAPHIC Smart Controller (quadratic white PCB)
// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller
//
// ==> REMEMBER TO INSTALL U8glib to your ARDUINO library folder: http://code.google.com/p/u8glib/wiki/u8glib
//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
// The RepRapWorld REPRAPWORLD_KEYPAD v1.1
// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626
//#define REPRAPWORLD_KEYPAD
//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // how much should be moved when a key is pressed, eg 10.0 means 10mm per click
// The Elefu RA Board Control Panel
// http://www.elefu.com/index.php?route=product/product&product_id=53
// REMEMBER TO INSTALL LiquidCrystal_I2C.h in your ARDUINO library folder: https://github.com/kiyoshigawa/LiquidCrystal_I2C
//#define RA_CONTROL_PANEL
// @section hidden
//automatic expansion
#if defined (MAKRPANEL)
#define DOGLCD
#define SDSUPPORT
#define ULTIPANEL
#define NEWPANEL
#define DEFAULT_LCD_CONTRAST 17
#endif
#if defined(miniVIKI) || defined(VIKI2)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
#ifdef miniVIKI
#define DEFAULT_LCD_CONTRAST 95
#else
#define DEFAULT_LCD_CONTRAST 40
#endif
#define ENCODER_PULSES_PER_STEP 4
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#if defined (PANEL_ONE)
#define SDSUPPORT
#define ULTIMAKERCONTROLLER
#endif
#if defined (REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif
#if defined(ULTIMAKERCONTROLLER) || defined(REPRAP_DISCOUNT_SMART_CONTROLLER) || defined(G3D_PANEL)
#define ULTIPANEL
#define NEWPANEL
#endif
#if defined(REPRAPWORLD_KEYPAD)
#define NEWPANEL
#define ULTIPANEL
#endif
#if defined(RA_CONTROL_PANEL)
#define ULTIPANEL
#define NEWPANEL
#define LCD_I2C_TYPE_PCA8574
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#endif
//I2C PANELS
//#define LCD_I2C_SAINSMART_YWROBOT
#ifdef LCD_I2C_SAINSMART_YWROBOT
// This uses the LiquidCrystal_I2C library ( https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home )
// Make sure it is placed in the Arduino libraries directory.
#define LCD_I2C_TYPE_PCF8575
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define NEWPANEL
#define ULTIPANEL
#endif
// PANELOLU2 LCD with status LEDs, separate encoder and click inputs
//#define LCD_I2C_PANELOLU2
#ifdef LCD_I2C_PANELOLU2
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// (v1.2.3 no longer requires you to define PANELOLU in the LiquidTWI2.h library header file)
// Note: The PANELOLU2 encoder click input can either be directly connected to a pin
// (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1).
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD
#define NEWPANEL
#define ULTIPANEL
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 4
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#ifdef LCD_USE_I2C_BUZZER
#define LCD_FEEDBACK_FREQUENCY_HZ 1000
#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
#endif
#endif
// Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs
//#define LCD_I2C_VIKI
#ifdef LCD_I2C_VIKI
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// Note: The pause/stop/resume LCD button pin should be connected to the Arduino
// BTN_ENC pin (or set BTN_ENC to -1 if not used)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
#define NEWPANEL
#define ULTIPANEL
#endif
// Shift register panels
// ---------------------
// 2 wire Non-latching LCD SR from:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
//#define SAV_3DLCD
#ifdef SAV_3DLCD
#define SR_LCD_2W_NL // Non latching 2 wire shiftregister
#define NEWPANEL
#define ULTIPANEL
#endif
#ifdef ULTIPANEL
// #define NEWPANEL //enable this if you have a click-encoder panel
#define SDSUPPORT
#define ULTRA_LCD
#ifdef DOGLCD // Change number of lines to match the DOG graphic display
#define LCD_WIDTH 22
#define LCD_HEIGHT 5
#else
#define LCD_WIDTH 20
#define LCD_HEIGHT 4
#endif
#else //no panel but just LCD
#ifdef ULTRA_LCD
#ifdef DOGLCD // Change number of lines to match the 128x64 graphics display
#define LCD_WIDTH 22
#define LCD_HEIGHT 5
#else
#define LCD_WIDTH 16
#define LCD_HEIGHT 2
#endif
#endif
#endif
// @section lcd
// default LCD contrast for dogm-like LCD displays
#ifdef DOGLCD
# ifndef DEFAULT_LCD_CONTRAST
# define DEFAULT_LCD_CONTRAST 32
# endif
#endif
// @section extras
// Increase the FAN pwm frequency. Removes the PWM noise but increases heating in the FET/Arduino
//#define FAST_PWM_FAN
// Temperature status LEDs that display the hotend and bet temperature.
// If all hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on.
// Otherwise the RED led is on. There is 1C hysteresis.
//#define TEMP_STAT_LEDS
// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency
// which is not ass annoying as with the hardware PWM. On the other hand, if this frequency
// is too low, you should also increment SOFT_PWM_SCALE.
//#define FAN_SOFT_PWM
// Incrementing this by 1 will double the software PWM frequency,
// affecting heaters, and the fan if FAN_SOFT_PWM is enabled.
// However, control resolution will be halved for each increment;
// at zero value, there are 128 effective control positions.
#define SOFT_PWM_SCALE 0
// M240 Triggers a camera by emulating a Canon RC-1 Remote
// Data from: http://www.doc-diy.net/photo/rc-1_hacked/
// #define PHOTOGRAPH_PIN 23
// SF send wrong arc g-codes when using Arc Point as fillet procedure
//#define SF_ARC_FIX
// Support for the BariCUDA Paste Extruder.
//#define BARICUDA
//define BlinkM/CyzRgb Support
//#define BLINKM
/*********************************************************************\
* R/C SERVO support
* Sponsored by TrinityLabs, Reworked by codexmas
**********************************************************************/
// Number of servos
//
// If you select a configuration below, this will receive a default value and does not need to be set manually
// set it manually if you have more servos than extruders and wish to manually control some
// leaving it undefined or defining as 0 will disable the servo subsystem
// If unsure, leave commented / disabled
//
//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command
// Servo Endstops
//
// This allows for servo actuated endstops, primary usage is for the Z Axis to eliminate calibration or bed height changes.
// Use M206 command to correct for switch height offset to actual nozzle height. Store that setting with M500.
//
//#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1
//#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 70,0} // X,Y,Z Axis Extend and Retract angles
/**********************************************************************\
* Support for a filament diameter sensor
* Also allows adjustment of diameter at print time (vs at slicing)
* Single extruder only at this point (extruder 0)
*
* Motherboards
* 34 - RAMPS1.4 - uses Analog input 5 on the AUX2 connector
* 81 - Printrboard - Uses Analog input 2 on the Exp1 connector (version B,C,D,E)
* 301 - Rambo - uses Analog input 3
* Note may require analog pins to be defined for different motherboards
**********************************************************************/
// Uncomment below to enable
//#define FILAMENT_SENSOR
#define FILAMENT_SENSOR_EXTRUDER_NUM 0 //The number of the extruder that has the filament sensor (0,1,2)
#define MEASUREMENT_DELAY_CM 14 //measurement delay in cm. This is the distance from filament sensor to middle of barrel
#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm) - this is then used in the slicer software. Used for sensor reading validation
#define MEASURED_UPPER_LIMIT 3.30 //upper limit factor used for sensor reading validation in mm
#define MEASURED_LOWER_LIMIT 1.90 //lower limit factor for sensor reading validation in mm
#define MAX_MEASUREMENT_DELAY 20 //delay buffer size in bytes (1 byte = 1cm)- limits maximum measurement delay allowable (must be larger than MEASUREMENT_DELAY_CM and lower number saves RAM)
//defines used in the code
#define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA //set measured to nominal initially
//When using an LCD, uncomment the line below to display the Filament sensor data on the last line instead of status. Status will appear for 5 sec.
//#define FILAMENT_LCD_DISPLAY
#include "Configuration_adv.h"
#include "thermistortables.h"
#endif //__CONFIGURATION_H

@ -0,0 +1,584 @@
#ifndef CONFIGURATION_ADV_H
#define CONFIGURATION_ADV_H
// @section temperature
//===========================================================================
//=============================Thermal Settings ============================
//===========================================================================
#ifdef BED_LIMIT_SWITCHING
#define BED_HYSTERESIS 2 //only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS
#endif
#define BED_CHECK_INTERVAL 5000 //ms between checks in bang-bang control
//// Heating sanity check:
// This waits for the watch period in milliseconds whenever an M104 or M109 increases the target temperature
// If the temperature has not increased at the end of that period, the target temperature is set to zero.
// It can be reset with another M104/M109. This check is also only triggered if the target temperature and the current temperature
// differ by at least 2x WATCH_TEMP_INCREASE
//#define WATCH_TEMP_PERIOD 40000 //40 seconds
//#define WATCH_TEMP_INCREASE 10 //Heat up at least 10 degree in 20 seconds
#ifdef PIDTEMP
// this adds an experimental additional term to the heating power, proportional to the extrusion speed.
// if Kc is chosen well, the additional required power due to increased melting should be compensated.
#define PID_ADD_EXTRUSION_RATE
#ifdef PID_ADD_EXTRUSION_RATE
#define DEFAULT_Kc (1) //heating power=Kc*(e_speed)
#endif
#endif
//automatic temperature: The hot end target temperature is calculated by all the buffered lines of gcode.
//The maximum buffered steps/sec of the extruder motor are called "se".
//You enter the autotemp mode by a M109 S<mintemp> B<maxtemp> F<factor>
// the target temperature is set to mintemp+factor*se[steps/sec] and limited by mintemp and maxtemp
// you exit the value by any M109 without F*
// Also, if the temperature is set to a value <mintemp, it is not changed by autotemp.
// on an Ultimaker, some initial testing worked with M109 S215 B260 F1 in the start.gcode
#define AUTOTEMP
#ifdef AUTOTEMP
#define AUTOTEMP_OLDWEIGHT 0.98
#endif
//Show Temperature ADC value
//The M105 command return, besides traditional information, the ADC value read from temperature sensors.
//#define SHOW_TEMP_ADC_VALUES
// @section extruder
// extruder run-out prevention.
//if the machine is idle, and the temperature over MINTEMP, every couple of SECONDS some filament is extruded
//#define EXTRUDER_RUNOUT_PREVENT
#define EXTRUDER_RUNOUT_MINTEMP 190
#define EXTRUDER_RUNOUT_SECONDS 30.
#define EXTRUDER_RUNOUT_ESTEPS 14. //mm filament
#define EXTRUDER_RUNOUT_SPEED 1500. //extrusion speed
#define EXTRUDER_RUNOUT_EXTRUDE 100
// @section temperature
//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements.
//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET"
#define TEMP_SENSOR_AD595_OFFSET 0.0
#define TEMP_SENSOR_AD595_GAIN 1.0
//This is for controlling a fan to cool down the stepper drivers
//it will turn on when any driver is enabled
//and turn off after the set amount of seconds from last driver being disabled again
#define CONTROLLERFAN_PIN -1 //Pin used for the fan to cool controller (-1 to disable)
#define CONTROLLERFAN_SECS 60 //How many seconds, after all motors were disabled, the fan should run
#define CONTROLLERFAN_SPEED 255 // == full speed
// When first starting the main fan, run it at full speed for the
// given number of milliseconds. This gets the fan spinning reliably
// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu)
//#define FAN_KICKSTART_TIME 100
// @section extruder
// Extruder cooling fans
// Configure fan pin outputs to automatically turn on/off when the associated
// extruder temperature is above/below EXTRUDER_AUTO_FAN_TEMPERATURE.
// Multiple extruders can be assigned to the same pin in which case
// the fan will turn on when any selected extruder is above the threshold.
#define EXTRUDER_0_AUTO_FAN_PIN -1
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_3_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
//===========================================================================
//=============================Mechanical Settings===========================
//===========================================================================
// @section homing
#define ENDSTOPS_ONLY_FOR_HOMING // If defined the endstops will only be used for homing
// @section hidden
//// AUTOSET LOCATIONS OF LIMIT SWITCHES
//// Added by ZetaPhoenix 09-15-2012
#ifdef MANUAL_HOME_POSITIONS // Use manual limit switch locations
#define X_HOME_POS MANUAL_X_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#define Z_HOME_POS MANUAL_Z_HOME_POS
#else //Set min/max homing switch positions based upon homing direction and min/max travel limits
//X axis
#if X_HOME_DIR == -1
#ifdef BED_CENTER_AT_0_0
#define X_HOME_POS X_MAX_LENGTH * -0.5
#else
#define X_HOME_POS X_MIN_POS
#endif //BED_CENTER_AT_0_0
#else
#ifdef BED_CENTER_AT_0_0
#define X_HOME_POS X_MAX_LENGTH * 0.5
#else
#define X_HOME_POS X_MAX_POS
#endif //BED_CENTER_AT_0_0
#endif //X_HOME_DIR == -1
//Y axis
#if Y_HOME_DIR == -1
#ifdef BED_CENTER_AT_0_0
#define Y_HOME_POS Y_MAX_LENGTH * -0.5
#else
#define Y_HOME_POS Y_MIN_POS
#endif //BED_CENTER_AT_0_0
#else
#ifdef BED_CENTER_AT_0_0
#define Y_HOME_POS Y_MAX_LENGTH * 0.5
#else
#define Y_HOME_POS Y_MAX_POS
#endif //BED_CENTER_AT_0_0
#endif //Y_HOME_DIR == -1
// Z axis
#if Z_HOME_DIR == -1 //BED_CENTER_AT_0_0 not used
#define Z_HOME_POS Z_MIN_POS
#else
#define Z_HOME_POS Z_MAX_POS
#endif //Z_HOME_DIR == -1
#endif //End auto min/max positions
//END AUTOSET LOCATIONS OF LIMIT SWITCHES -ZP
// @section extras
//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
// A single Z stepper driver is usually used to drive 2 stepper motors.
// Uncomment this define to utilize a separate stepper driver for each Z axis motor.
// Only a few motherboards support this, like RAMPS, which have dual extruder support (the 2nd, often unused, extruder driver is used
// to control the 2nd Z axis stepper motor). The pins are currently only defined for a RAMPS motherboards.
// On a RAMPS (or other 5 driver) motherboard, using this feature will limit you to using 1 extruder.
//#define Z_DUAL_STEPPER_DRIVERS
#ifdef Z_DUAL_STEPPER_DRIVERS
#undef EXTRUDERS
#define EXTRUDERS 1
#endif
// Same again but for Y Axis.
//#define Y_DUAL_STEPPER_DRIVERS
// Define if the two Y drives need to rotate in opposite directions
#define INVERT_Y2_VS_Y_DIR true
#ifdef Y_DUAL_STEPPER_DRIVERS
#undef EXTRUDERS
#define EXTRUDERS 1
#endif
#if defined (Z_DUAL_STEPPER_DRIVERS) && defined (Y_DUAL_STEPPER_DRIVERS)
#error "You cannot have dual drivers for both Y and Z"
#endif
// Enable this for dual x-carriage printers.
// A dual x-carriage design has the advantage that the inactive extruder can be parked which
// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage
// allowing faster printing speeds.
//#define DUAL_X_CARRIAGE
#ifdef DUAL_X_CARRIAGE
// Configuration for second X-carriage
// Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop;
// the second x-carriage always homes to the maximum endstop.
#define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage
#define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed
#define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position
#define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position
// However: In this mode the EXTRUDER_OFFSET_X value for the second extruder provides a software
// override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops
// without modifying the firmware (through the "M218 T1 X???" command).
// Remember: you should set the second extruder x-offset to 0 in your slicer.
// Pins for second x-carriage stepper driver (defined here to avoid further complicating pins.h)
#define X2_ENABLE_PIN 29
#define X2_STEP_PIN 25
#define X2_DIR_PIN 23
// There are a few selectable movement modes for dual x-carriages using M605 S<mode>
// Mode 0: Full control. The slicer has full control over both x-carriages and can achieve optimal travel results
// as long as it supports dual x-carriages. (M605 S0)
// Mode 1: Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so
// that additional slicer support is not required. (M605 S1)
// Mode 2: Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all
// actions of the first x-carriage. This allows the printer to print 2 arbitrary items at
// once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm])
// This is the default power-up mode which can be later using M605.
#define DEFAULT_DUAL_X_CARRIAGE_MODE 0
// Default settings in "Auto-park Mode"
#define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder
#define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder
// Default x offset in duplication mode (typically set to half print bed width)
#define DEFAULT_DUPLICATION_X_OFFSET 100
#endif //DUAL_X_CARRIAGE
// @section homing
//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
#define X_HOME_RETRACT_MM 5
#define Y_HOME_RETRACT_MM 5
#define Z_HOME_RETRACT_MM 2
//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
// @section machine
#define AXIS_RELATIVE_MODES {false, false, false, false}
// @section hidden
#ifdef CONFIG_STEPPERS_TOSHIBA
#define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers
#else
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step)
#endif
// @section machine
//By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
#define INVERT_X_STEP_PIN false
#define INVERT_Y_STEP_PIN false
#define INVERT_Z_STEP_PIN false
#define INVERT_E_STEP_PIN false
//default stepper release if idle. Set to 0 to deactivate.
#define DEFAULT_STEPPER_DEACTIVE_TIME 60
#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate
#define DEFAULT_MINTRAVELFEEDRATE 0.0
// @section lcd
// Feedrates for manual moves along X, Y, Z, E from panel
#ifdef ULTIPANEL
#define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // set the speeds for manual moves (mm/min)
#endif
//Comment to disable setting feedrate multiplier via encoder
#ifdef ULTIPANEL
#define ULTIPANEL_FEEDMULTIPLY
#endif
// @section extras
// minimum time in microseconds that a movement needs to take if the buffer is emptied.
#define DEFAULT_MINSEGMENTTIME 20000
// If defined the movements slow down when the look ahead buffer is only half full
#define SLOWDOWN
// Frequency limit
// See nophead's blog for more info
// Not working O
//#define XY_FREQUENCY_LIMIT 15
// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end
// of the buffer and all stops. This should not be much greater than zero and should only be changed
// if unwanted behavior is observed on a user's machine when running at very slow speeds.
#define MINIMUM_PLANNER_SPEED 0.05// (mm/sec)
// MS1 MS2 Stepper Driver Microstepping mode table
#define MICROSTEP1 LOW,LOW
#define MICROSTEP2 HIGH,LOW
#define MICROSTEP4 LOW,HIGH
#define MICROSTEP8 HIGH,HIGH
#define MICROSTEP16 HIGH,HIGH
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16]
// Motor Current setting (Only functional when motor driver current ref pins are connected to a digital trimpot on supported boards)
#define DIGIPOT_MOTOR_CURRENT {135,135,135,135,135} // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
// uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
//#define DIGIPOT_I2C
// Number of channels available for I2C digipot, For Azteeg X3 Pro we have 8
#define DIGIPOT_I2C_NUM_CHANNELS 8
// actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS
#define DIGIPOT_I2C_MOTOR_CURRENTS {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}
//===========================================================================
//=============================Additional Features===========================
//===========================================================================
#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly
#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceed this value, multiple the steps moved by ten to quickly advance the value
#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceed this value, multiple the steps moved by 100 to really quickly advance the value
//#define ENCODER_RATE_MULTIPLIER_DEBUG // If defined, output the encoder steps per second value
//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/
#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again
// @section lcd
#define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers?
#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order.
// if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that.
// using:
//#define MENU_ADDAUTOSTART
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
#ifdef LCD_PROGRESS_BAR
// Amount of time (ms) to show the bar
#define PROGRESS_BAR_BAR_TIME 2000
// Amount of time (ms) to show the status message
#define PROGRESS_BAR_MSG_TIME 3000
// Amount of time (ms) to retain the status message (0=forever)
#define PROGRESS_MSG_EXPIRE 0
// Enable this to show messages for MSG_TIME then hide them
//#define PROGRESS_MSG_ONCE
#ifdef DOGLCD
#warning LCD_PROGRESS_BAR does not apply to graphical displays at this time.
#endif
#ifdef FILAMENT_LCD_DISPLAY
#error LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both.
#endif
#endif
// @section more
// The hardware watchdog should reset the microcontroller disabling all outputs, in case the firmware gets stuck and doesn't do temperature regulation.
//#define USE_WATCHDOG
#ifdef USE_WATCHDOG
// If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on.
// The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset.
// However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled.
//#define WATCHDOG_RESET_MANUAL
#endif
// Enable the option to stop SD printing when hitting and endstops, needs to be enabled from the LCD menu when this option is enabled.
//#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
// Babystepping enables the user to control the axis in tiny amounts, independently from the normal printing process
// it can e.g. be used to change z-positions in the print startup phase in real-time
// does not respect endstops!
//#define BABYSTEPPING
#ifdef BABYSTEPPING
#define BABYSTEP_XY //not only z, but also XY in the menu. more clutter, more functions
#define BABYSTEP_INVERT_Z false //true for inverse movements in Z
#define BABYSTEP_Z_MULTIPLICATOR 2 //faster z movements
#ifdef COREXY
#error BABYSTEPPING not implemented for COREXY yet.
#endif
#ifdef DELTA
#ifdef BABYSTEP_XY
#error BABYSTEPPING only implemented for Z axis on deltabots.
#endif
#endif
#endif
// extruder advance constant (s2/mm3)
//
// advance (steps) = STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K * cubic mm per second ^ 2
//
// Hooke's law says: force = k * distance
// Bernoulli's principle says: v ^ 2 / 2 + g . h + pressure / density = constant
// so: v ^ 2 is proportional to number of steps we advance the extruder
//#define ADVANCE
#ifdef ADVANCE
#define EXTRUDER_ADVANCE_K .0
#define D_FILAMENT 2.85
#define STEPS_MM_E 836
#define EXTRUSION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS]/ EXTRUSION_AREA)
#endif // ADVANCE
// Arc interpretation settings:
#define MM_PER_ARC_SEGMENT 1
#define N_ARC_CORRECTION 25
const unsigned int dropsegments=5; //everything with less than this number of steps will be ignored as move and joined with the next movement
// @section lcd
// If you are using a RAMPS board or cheap E-bay purchased boards that do not detect when an SD card is inserted
// You can get round this by connecting a push button or single throw switch to the pin defined as SDCARDCARDDETECT
// in the pins.h file. When using a push button pulling the pin to ground this will need inverted. This setting should
// be commented out otherwise
#define SDCARDDETECTINVERTED
// @section hidden
#ifdef ULTIPANEL
#undef SDCARDDETECTINVERTED
#endif
// Power Signal Control Definitions
// By default use ATX definition
#ifndef POWER_SUPPLY
#define POWER_SUPPLY 1
#endif
// 1 = ATX
#if (POWER_SUPPLY == 1)
#define PS_ON_AWAKE LOW
#define PS_ON_ASLEEP HIGH
#endif
// 2 = X-Box 360 203W
#if (POWER_SUPPLY == 2)
#define PS_ON_AWAKE HIGH
#define PS_ON_ASLEEP LOW
#endif
// @section temperature
// Control heater 0 and heater 1 in parallel.
//#define HEATERS_PARALLEL
//===========================================================================
//=============================Buffers ============================
//===========================================================================
// @section hidden
// The number of linear motions that can be in the plan at any give time.
// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering.
#if defined SDSUPPORT
#define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller
#else
#define BLOCK_BUFFER_SIZE 16 // maximize block buffer
#endif
// @section more
//The ASCII buffer for receiving from the serial:
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// @section extras
// Firmware based and LCD controlled retract
// M207 and M208 can be used to define parameters for the retraction.
// The retraction can be called by the slicer using G10 and G11
// until then, intended retractions can be detected by moves that only extrude and the direction.
// the moves are than replaced by the firmware controlled ones.
// #define FWRETRACT //ONLY PARTIALLY TESTED
#ifdef FWRETRACT
#define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt
#define RETRACT_LENGTH 3 //default retract length (positive mm)
#define RETRACT_LENGTH_SWAP 13 //default swap retract length (positive mm), for extruder change
#define RETRACT_FEEDRATE 45 //default feedrate for retracting (mm/s)
#define RETRACT_ZLIFT 0 //default retract Z-lift
#define RETRACT_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering)
#define RETRACT_RECOVER_LENGTH_SWAP 0 //default additional swap recover length (mm, added to retract length when recovering from extruder change)
#define RETRACT_RECOVER_FEEDRATE 8 //default feedrate for recovering from retraction (mm/s)
#endif
//adds support for experimental filament exchange support M600; requires display
#ifdef ULTIPANEL
#define FILAMENTCHANGEENABLE
#ifdef FILAMENTCHANGEENABLE
#define FILAMENTCHANGE_XPOS 3
#define FILAMENTCHANGE_YPOS 3
#define FILAMENTCHANGE_ZADD 10
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -100
#endif
#endif
#ifdef FILAMENTCHANGEENABLE
#ifdef EXTRUDER_RUNOUT_PREVENT
#error EXTRUDER_RUNOUT_PREVENT currently incompatible with FILAMENTCHANGE
#endif
#endif
//===========================================================================
//============================= Define Defines ============================
//===========================================================================
// @section hidden
#if defined (ENABLE_AUTO_BED_LEVELING) && defined (DELTA)
#error "Bed Auto Leveling is still not compatible with Delta Kinematics."
#endif
#if EXTRUDERS > 1 && defined TEMP_SENSOR_1_AS_REDUNDANT
#error "You cannot use TEMP_SENSOR_1_AS_REDUNDANT if EXTRUDERS > 1"
#endif
#if EXTRUDERS > 1 && defined HEATERS_PARALLEL
#error "You cannot use HEATERS_PARALLEL if EXTRUDERS > 1"
#endif
#if TEMP_SENSOR_0 > 0
#define THERMISTORHEATER_0 TEMP_SENSOR_0
#define HEATER_0_USES_THERMISTOR
#endif
#if TEMP_SENSOR_1 > 0
#define THERMISTORHEATER_1 TEMP_SENSOR_1
#define HEATER_1_USES_THERMISTOR
#endif
#if TEMP_SENSOR_2 > 0
#define THERMISTORHEATER_2 TEMP_SENSOR_2
#define HEATER_2_USES_THERMISTOR
#endif
#if TEMP_SENSOR_3 > 0
#define THERMISTORHEATER_3 TEMP_SENSOR_3
#define HEATER_3_USES_THERMISTOR
#endif
#if TEMP_SENSOR_BED > 0
#define THERMISTORBED TEMP_SENSOR_BED
#define BED_USES_THERMISTOR
#endif
#if TEMP_SENSOR_0 == -1
#define HEATER_0_USES_AD595
#endif
#if TEMP_SENSOR_1 == -1
#define HEATER_1_USES_AD595
#endif
#if TEMP_SENSOR_2 == -1
#define HEATER_2_USES_AD595
#endif
#if TEMP_SENSOR_3 == -1
#define HEATER_3_USES_AD595
#endif
#if TEMP_SENSOR_BED == -1
#define BED_USES_AD595
#endif
#if TEMP_SENSOR_0 == -2
#define HEATER_0_USES_MAX6675
#endif
#if TEMP_SENSOR_0 == 0
#undef HEATER_0_MINTEMP
#undef HEATER_0_MAXTEMP
#endif
#if TEMP_SENSOR_1 == 0
#undef HEATER_1_MINTEMP
#undef HEATER_1_MAXTEMP
#endif
#if TEMP_SENSOR_2 == 0
#undef HEATER_2_MINTEMP
#undef HEATER_2_MAXTEMP
#endif
#if TEMP_SENSOR_3 == 0
#undef HEATER_3_MINTEMP
#undef HEATER_3_MAXTEMP
#endif
#if TEMP_SENSOR_BED == 0
#undef BED_MINTEMP
#undef BED_MAXTEMP
#endif
#endif //__CONFIGURATION_ADV_H

@ -0,0 +1 @@
Header set Access-Control-Allow-Origin "*"

@ -0,0 +1,59 @@
#ifndef BOARDS_H
#define BOARDS_H
#define BOARD_UNKNOWN -1
#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics"
#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2
#define BOARD_GEN7_13 12 // Gen7 v1.3
#define BOARD_GEN7_14 13 // Gen7 v1.4
#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0
#define BOARD_SETHI 20 // Sethi 3D_1
#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2
#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 / 1.4 (Extruder, Fan, Bed)
#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 / 1.4 (Extruder0, Extruder1, Bed)
#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 / 1.4 (Extruder, Fan, Fan)
#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 / 1.4 (Extruder0, Extruder1, Fan)
#define BOARD_DUEMILANOVE_328P 4 // Duemilanove w/ ATMega328P pin assignments
#define BOARD_GEN6 5 // Gen6
#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe
#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2
#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above
#define BOARD_MELZI 63 // Melzi
#define BOARD_STB_11 64 // STB V1.1
#define BOARD_AZTEEG_X1 65 // Azteeg X1
#define BOARD_MELZI_1284 66 // Melzi with ATmega1284 (MaKr3d version)
#define BOARD_AZTEEG_X3 67 // Azteeg X3
#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro
#define BOARD_ULTIMAKER 7 // Ultimaker
#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare)
#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20)
#define BOARD_3DRAG 77 // 3Drag
#define BOARD_K8200 78 // Vellemann K8200 (derived from 3Drag)
#define BOARD_TEENSYLU 8 // Teensylu
#define BOARD_RUMBA 80 // Rumba
#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286)
#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646)
#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286)
#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84 make
#define BOARD_GEN3_PLUS 9 // Gen3+
#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics
#define BOARD_MEGATRONICS 70 // Megatronics
#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0
#define BOARD_MEGATRONICS_1 702 // Minitronics v1.0
#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0
#define BOARD_OMCA_A 90 // Alpha OMCA board
#define BOARD_OMCA 91 // Final OMCA board
#define BOARD_RAMBO 301 // Rambo
#define BOARD_ELEFU_3 21 // Elefu Ra Board (v3)
#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board
#define BOARD_LEAPFROG 999 // Leapfrog
#define BOARD_WITBOX 41 // bq WITBOX
#define BOARD_HEPHESTOS 42 // bq Prusa i3 Hephestos
#define BOARD_99 99 // This is in pins.h but...?
#define MB(board) (MOTHERBOARD==BOARD_##board)
#define IS_RAMPS (MB(RAMPS_OLD) || MB(RAMPS_13_EFB) || MB(RAMPS_13_EEB) || MB(RAMPS_13_EFF) || MB(RAMPS_13_EEF))
#endif //__BOARDS_H

@ -0,0 +1,228 @@
#ifndef LANGUAGE_H
#define LANGUAGE_H
#include "Configuration.h"
#define LANGUAGE_CONCAT(M) #M
#define GENERATE_LANGUAGE_INCLUDE(M) LANGUAGE_CONCAT(language_##M.h)
// NOTE: IF YOU CHANGE LANGUAGE FILES OR MERGE A FILE WITH CHANGES
//
// ==> ALWAYS TRY TO COMPILE MARLIN WITH/WITHOUT "ULTIPANEL" / "ULTRALCD" / "SDSUPPORT" #define IN "Configuration.h"
// ==> ALSO TRY ALL AVAILABLE LANGUAGE OPTIONS
// Languages
// en English
// pl Polish
// fr French
// de German
// es Spanish
// ru Russian
// it Italian
// pt Portuguese
// pt-br Portuguese (Brazil)
// fi Finnish
// an Aragonese
// nl Dutch
// ca Catalan
// eu Basque-Euskera
#ifndef LANGUAGE_INCLUDE
// pick your language from the list above
#define LANGUAGE_INCLUDE GENERATE_LANGUAGE_INCLUDE(en)
#endif
#define PROTOCOL_VERSION "1.0"
#define FIRMWARE_URL "https://github.com/MarlinFirmware/Marlin"
#if MB(ULTIMAKER)|| MB(ULTIMAKER_OLD)|| MB(ULTIMAIN_2)
#define MACHINE_NAME "Ultimaker"
#define FIRMWARE_URL "http://firmware.ultimaker.com"
#elif MB(RUMBA)
#define MACHINE_NAME "Rumba"
#elif MB(3DRAG)
#define MACHINE_NAME "3Drag"
#define FIRMWARE_URL "http://3dprint.elettronicain.it/"
#elif MB(K8200)
#define MACHINE_NAME "K8200"
#elif MB(5DPRINT)
#define MACHINE_NAME "Makibox"
#elif MB(SAV_MKI)
#define MACHINE_NAME "SAV MkI"
#define FIRMWARE_URL "https://github.com/fmalpartida/Marlin/tree/SAV-MkI-config"
#elif MB(WITBOX)
#define MACHINE_NAME "WITBOX"
#define FIRMWARE_URL "http://www.bq.com/gb/downloads-witbox.html"
#elif MB(HEPHESTOS)
#define MACHINE_NAME "HEPHESTOS"
#define FIRMWARE_URL "http://www.bq.com/gb/downloads-prusa-i3-hephestos.html"
#else // Default firmware set to Mendel
#define MACHINE_NAME "Mendel"
#endif
#ifdef CUSTOM_MENDEL_NAME
#define MACHINE_NAME CUSTOM_MENDEL_NAME
#endif
#ifndef MACHINE_UUID
#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
#endif
#define STRINGIFY_(n) #n
#define STRINGIFY(n) STRINGIFY_(n)
// Common LCD messages
/* nothing here yet */
// Common serial messages
#define MSG_MARLIN "Marlin"
// Serial Console Messages (do not translate those!)
#define MSG_Enqueing "enqueing \""
#define MSG_POWERUP "PowerUp"
#define MSG_EXTERNAL_RESET " External Reset"
#define MSG_BROWNOUT_RESET " Brown out Reset"
#define MSG_WATCHDOG_RESET " Watchdog Reset"
#define MSG_SOFTWARE_RESET " Software Reset"
#define MSG_AUTHOR " | Author: "
#define MSG_CONFIGURATION_VER " Last Updated: "
#define MSG_FREE_MEMORY " Free Memory: "
#define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: "
#define MSG_OK "ok"
#define MSG_FILE_SAVED "Done saving file."
#define MSG_ERR_LINE_NO "Line Number is not Last Line Number+1, Last Line: "
#define MSG_ERR_CHECKSUM_MISMATCH "checksum mismatch, Last Line: "
#define MSG_ERR_NO_CHECKSUM "No Checksum with line number, Last Line: "
#define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "No Line Number with checksum, Last Line: "
#define MSG_FILE_PRINTED "Done printing file"
#define MSG_BEGIN_FILE_LIST "Begin file list"
#define MSG_END_FILE_LIST "End file list"
#define MSG_M104_INVALID_EXTRUDER "M104 Invalid extruder "
#define MSG_M105_INVALID_EXTRUDER "M105 Invalid extruder "
#define MSG_M200_INVALID_EXTRUDER "M200 Invalid extruder "
#define MSG_M218_INVALID_EXTRUDER "M218 Invalid extruder "
#define MSG_M221_INVALID_EXTRUDER "M221 Invalid extruder "
#define MSG_ERR_NO_THERMISTORS "No thermistors - no temperature"
#define MSG_M109_INVALID_EXTRUDER "M109 Invalid extruder "
#define MSG_HEATING "Heating..."
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n"
#define MSG_COUNT_X " Count X: "
#define MSG_ERR_KILLED "Printer halted. kill() called!"
#define MSG_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
#define MSG_RESEND "Resend: "
#define MSG_UNKNOWN_COMMAND "Unknown command: \""
#define MSG_ACTIVE_EXTRUDER "Active Extruder: "
#define MSG_INVALID_EXTRUDER "Invalid extruder"
#define MSG_X_MIN "x_min: "
#define MSG_X_MAX "x_max: "
#define MSG_Y_MIN "y_min: "
#define MSG_Y_MAX "y_max: "
#define MSG_Z_MIN "z_min: "
#define MSG_Z_MAX "z_max: "
#define MSG_M119_REPORT "Reporting endstop status"
#define MSG_ENDSTOP_HIT "TRIGGERED"
#define MSG_ENDSTOP_OPEN "open"
#define MSG_HOTEND_OFFSET "Hotend offsets:"
#define MSG_SD_CANT_OPEN_SUBDIR "Cannot open subdir"
#define MSG_SD_INIT_FAIL "SD init fail"
#define MSG_SD_VOL_INIT_FAIL "volume.init failed"
#define MSG_SD_OPENROOT_FAIL "openRoot failed"
#define MSG_SD_CARD_OK "SD card ok"
#define MSG_SD_WORKDIR_FAIL "workDir open failed"
#define MSG_SD_OPEN_FILE_FAIL "open failed, File: "
#define MSG_SD_FILE_OPENED "File opened: "
#define MSG_SD_SIZE " Size: "
#define MSG_SD_FILE_SELECTED "File selected"
#define MSG_SD_WRITE_TO_FILE "Writing to file: "
#define MSG_SD_PRINTING_BYTE "SD printing byte "
#define MSG_SD_NOT_PRINTING "Not SD printing"
#define MSG_SD_ERR_WRITE_TO_FILE "error writing to file"
#define MSG_SD_CANT_ENTER_SUBDIR "Cannot enter subdir: "
#define MSG_STEPPER_TOO_HIGH "Steprate too high: "
#define MSG_ENDSTOPS_HIT "endstops hit: "
#define MSG_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented"
#define MSG_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented"
#define MSG_BABYSTEPPING_X "Babystepping X"
#define MSG_BABYSTEPPING_Y "Babystepping Y"
#define MSG_BABYSTEPPING_Z "Babystepping Z"
#define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure"
#define MSG_ERR_EEPROM_WRITE "Error writing to EEPROM!"
// LCD Menu Messages
// Add your own character. Reference: https://github.com/MarlinFirmware/Marlin/pull/1434 photos
// and https://www.sparkfun.com/datasheets/LCD/HD44780.pdf page 17-18
#ifdef DOGLCD
#define STR_Ae "\304" // 'Ä' U8glib
#define STR_ae "\344" // 'ä'
#define STR_Oe "\326" // 'Ö'
#define STR_oe STR_Oe // 'ö'
#define STR_Ue "\334" // 'Ü'
#define STR_ue STR_Ue // 'ü'
#define STR_sz "\337" // 'ß'
#define STR_h2 "\262" // '²'
#define STR_h3 "\263" // '³'
#define STR_Deg "\260" // '°'
#define STR_THERMOMETER "\377"
#else
#ifdef DISPLAY_CHARSET_HD44780_JAPAN // HD44780 ROM Code: A00 (Japan)
#define STR_ae "\xe1"
#define STR_Ae STR_ae
#define STR_oe "\357"
#define STR_Oe STR_oe
#define STR_ue "\365"
#define STR_Ue STR_ue
#define STR_sz "\342"
#define STR_h2 "2"
#define STR_h3 "3"
#define STR_Deg "\271"
#define STR_THERMOMETER "\002"
#endif
#ifdef DISPLAY_CHARSET_HD44780_WESTERN // HD44780 ROM Code: A02 (Western)
#define STR_Ae "\216"
#define STR_ae "\204"
#define STR_Oe "\211"
#define STR_oe "\204"
#define STR_Ue "\212"
#define STR_ue "\201"
#define STR_sz "\160"
#define STR_h2 "\262"
#define STR_h3 "\263"
#define STR_Deg "\337"
#define STR_THERMOMETER "\002"
#endif
#endif
/*
#define TESTSTRING000 "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017"
#define TESTSTRING020 "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
#define TESTSTRING040 "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
#define TESTSTRING060 "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
#define TESTSTRING100 "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
#define TESTSTRING120 "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
#define TESTSTRING140 "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
#define TESTSTRING160 "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
#define TESTSTRING200 "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
#define TESTSTRING220 "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
#define TESTSTRING240 "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
#define TESTSTRING260 "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
#define TESTSTRING300 "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
#define TESTSTRING320 "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
#define TESTSTRING340 "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
#define TESTSTRING360 "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
*/
#include LANGUAGE_INCLUDE
#include "language_en.h"
#endif //__LANGUAGE_H

@ -0,0 +1,344 @@
/* configurator.css */
/* Styles for Marlin Configurator */
.clear { clear: both; }
/* Prevent selection except PRE tags */
* {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
pre {
-webkit-touch-callout: text;
-webkit-user-select: text;
-khtml-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
body { margin: 0; padding: 0; background: #56A; color: #000; font-family: monospace; }
#main {
max-width: 1100px;
margin: 0 auto 10px;
padding: 0 2%; width: 96%;
}
h1, h2, h3, h4, h5, h6 { clear: both; }
h1, p.info { font-family: sans-serif; }
h1 {
height: 38px;
margin-bottom: -30px;
color: #FFF;
background: transparent url(logo.png) right top no-repeat;
}
p.info { padding: 0; color: #000; }
p.info span { color: #800; }
#message { text-align: center; }
#message { width: 80%; margin: 0 auto 0.25em; color: #FF0; }
#message p { padding: 2px 0; font-weight: bold; border-radius: 0.8em; }
#message p.message { color: #080; background: #CFC; }
#message p.error { color: #F00; background: #FF4; }
#message p.warning { color: #FF0; background: #BA4; }
#message p.message span,
#message p.error span,
#message p.warning span {
color: #A00;
background: rgba(255, 255, 255, 1);
border: 1px solid rgba(0,0,0,0.5);
border-radius: 1em;
float: right;
margin-right: 0.5em;
padding: 0 3px;
font-family: sans-serif;
font-size: small;
position: relative;
top: -1px;
}
#help strong { color: #0DD; }
img { display: none; }
/* Forms */
#config_form {
display: block;
background: #EEE;
padding: 6px 20px 20px;
color: #000;
position: relative;
border-radius: 1.5em;
border-top-left-radius: 0;
}
fieldset {
height: 16.1em;
overflow-y: scroll;
overflow-x: hidden;
margin-top: 10px;
}
label, input, select, textarea { display: block; float: left; margin: 1px 0; }
label.newline, textarea, fieldset { clear: both; }
label {
width: 120px; /* label area */
height: 1em;
padding: 10px 460px 10px 1em;
margin-right: -450px;
text-align: right;
}
label.blocked, label.added.blocked, label.added.blocked.sublabel { color: #AAA; }
label.added.sublabel {
width: auto;
margin: 11px -2.5em 0 1em;
padding: 0 3em 0 0;
font-style: italic;
color: #444;
}
label+label.added.sublabel {
margin-left: 0;
}
input[type="text"], select { margin: 0.75em 0 0; }
input[type="checkbox"], input[type="radio"], input[type="file"] { margin: 1em 0 0; }
input[type="checkbox"].enabler, input[type="radio"].enabler { margin-left: 1em; }
input:disabled { color: #BBB; }
#config_form input[type="text"].subitem { width: 4em; }
#config_form input[type="text"].subitem+.subitem { margin-left: 4px; }
input[type="text"].added { width: 20em; }
label.added {
width: 265px; /* label area */
height: 1em;
padding: 10px 370px 10px 1em;
margin-right: -360px;
text-align: right;
}
ul.tabs { padding: 0; list-style: none; }
ul.tabs li { display: inline; }
ul.tabs li a,
ul.tabs li a.active:hover,
ul.tabs li a.active:active {
display: block;
float: left;
background: #1E4059;
color: #CCC;
font-size: 110%;
border-radius: 0.25em 0.25em 0 0;
margin: 0 4px 0 0;
padding: 2px 8px;
text-decoration: none;
font-family: georgia,"times new roman",times;
}
ul.tabs li a.active:link,
ul.tabs li a.active:visited {
background: #DDD;
color: #06F;
cursor: default;
margin-top: -4px;
padding-bottom: 4px;
padding-top: 4px;
}
ul.tabs li a:hover,
ul.tabs li a:active {
background: #000;
color: #FFF;
}
fieldset { display: none; border: 1px solid #AAA; border-radius: 1em; }
fieldset legend { display: none; }
.hilightable span {
display: block;
float: left;
width: 100%;
height: 1.3em;
background: rgba(225,255,0,1);
margin: 0 -100% -1em 0;
}
#serial_stepper { padding-top: 0.75em; display: block; float: left; }
/*#SERIAL_PORT { display: none; }*/
/* Tooltips */
#tooltip {
display: none;
max-width: 30em;
padding: 8px;
border: 2px solid #73d699;
border-radius: 1em;
position: absolute;
z-index: 999;
font-family: sans-serif;
font-size: 85%;
color: #000;
line-height: 1.1;
background: #e2ff99; /* Old browsers */
background: -moz-linear-gradient(top, #e2ff99 0%, #73d699 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#e2ff99), color-stop(100%,#73d699)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #e2ff99 0%,#73d699 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #e2ff99 0%,#73d699 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #e2ff99 0%,#73d699 100%); /* IE10+ */
background: linear-gradient(to bottom, #e2ff99 0%,#73d699 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e2ff99', endColorstr='#73d699',GradientType=0 ); /* IE6-9 */
-webkit-box-shadow: 0px 6px 25px -4px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 6px 25px -4px rgba(0,0,0,0.75);
box-shadow: 0px 6px 25px -4px rgba(0,0,0,0.75);
}
#tooltip>span {
position: absolute;
content: "";
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #73d699;
z-index: 999;
bottom: -10px;
left: 20px;
}
#tooltip>strong { color: #00B; }
/* Tooltips Checkbox */
#tipson {
width: auto;
height: auto;
padding: 0;
margin-right: 0;
float: right;
font-weight: bold;
font-size: 100%;
font-family: helvetica;
text-align: left;
cursor: pointer;
}
#tipson input { float: none; display: inline; cursor: pointer; }
/* Config Text */
pre.config {
height: 25em;
padding: 10px;
border: 2px solid #888;
border-radius: 5px;
overflow: auto;
clear: both;
background-color: #FFF;
color: #000;
font-family: "Fira Mono", monospace;
font-size: small;
}
/* Pre Headers */
h2 {
width: 100%;
margin: 12px -300px 4px 0;
padding: 0;
float: left;
}
/* Disclosure Widget */
span.disclose, a.download, a.download-all {
display: block;
float: right;
margin-top: 12px;
}
span.disclose {
margin-right: -10px; /* total width */
margin-left: 14px;
width: 0;
height: 0;
position: relative;
left: 3px;
top: 3px;
cursor: pointer;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 10px solid #000;
}
span.disclose.closed {
margin-right: -8px; /* total width */
margin-left: 10px;
left: 0;
top: 0;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-right: 10px solid #000;
}
span.disclose.almost {
-ms-transform: rotate(45deg); /* IE 9 */
-webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
transform: rotate(45deg);
}
span.disclose.closed.almost {
left: 1px;
top: 3px;
-ms-transform: rotate(315deg); /* IE 9 */
-webkit-transform: rotate(315deg); /* Chrome, Safari, Opera */
transform: rotate(315deg);
}
/* Download Button */
a.download, a.download-all {
visibility: hidden;
padding: 2px;
border: 1px solid #494;
border-radius: 4px;
margin: 12px 0 0;
background: #FFF;
color: #494;
font-family: sans-serif;
font-size: small;
font-weight: bold;
text-decoration: none;
}
a.download-all { margin: 9px 2em 0; color: #449; border-color: #449; }
input[type="text"].one_of_2 { max-width: 15%; }
input[type="text"].one_of_3 { max-width: 10%; }
input[type="text"].one_of_4 { max-width: 7%; }
select.one_of_2 { max-width: 15%; }
select.one_of_3 { max-width: 10%; }
select.one_of_4 { max-width: 14%; }
select.one_of_4+span.label+select.one_of_4+span.label { clear: both; margin-left: 265px; padding-left: 1.75em; }
select.one_of_4+span.label+select.one_of_4+span.label+select.one_of_4+span.label { clear: none; margin-left: 1em; padding-left: 0; }
@media all and (min-width: 1140px) {
#main { max-width: 10000px; }
fieldset { float: left; width: 50%; height: auto; }
#config_text, #config_adv_text { float: right; clear: right; width: 45%; }
pre.config { height: 20em; }
.disclose { display: none; }
input[type="text"].one_of_2 { max-width: 15%; }
input[type="text"].one_of_3 { max-width: 9%; }
input[type="text"].one_of_4 { max-width: 8%; }
select.one_of_2 { max-width: 15%; }
select.one_of_3 { max-width: 10%; }
select.one_of_4 { max-width: 16%; }
}
/*label.blocked, .blocked { display: none; }*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,117 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Marlin Firmware Configurator</title>
<link href='http://fonts.googleapis.com/css?family=Fira+Mono&amp;subset=latin,latin-ext' rel='stylesheet' type='text/css' />
<script src="js/jquery-2.1.3.min.js"></script>
<script src="js/binarystring.js"></script>
<script src="js/binaryfileuploader.js"></script>
<script src="js/FileSaver.min.js"></script>
<script src="js/jszip.min.js"></script>
<script src="js/jcanvas.js"></script>
<script src="js/jstepper.js"></script>
<script src="js/configurator.js"></script>
<link rel="stylesheet" href="css/configurator.css" type="text/css" media="all" />
</head>
<body>
<section id="main">
<h1>Marlin Configurator</h1>
<p class="info">Select presets (coming soon), modify, and download.</p>
<div id="message"></div>
<div id="tabs"></div>
<form id="config_form">
<div id="tooltip"></div>
<label>Drop Files:</label><input type="file" id="file-upload" />
<label id="tipson"><input type="checkbox" checked /> ?</label>
<a href="" class="download-all">Download Zip</a>
<fieldset id="machine">
<legend>Machine</legend>
<label class="newline">Serial Port:</label><select name="SERIAL_PORT"></select><div id="serial_stepper"></div>
<label>Baud Rate:</label><select name="BAUDRATE"></select>
<label>AT90USB BT IF:</label>
<input name="BTENABLED" type="checkbox" value="1" checked />
<label class="newline">Motherboard:</label><select name="MOTHERBOARD"></select>
<label class="newline">Custom Name:</label><input name="CUSTOM_MENDEL_NAME" type="text" size="14" maxlength="12" value="" />
<label class="newline">Machine UUID:</label><input name="MACHINE_UUID" type="text" size="38" maxlength="36" value="" />
<label class="newline">Extruders:</label><select name="EXTRUDERS"></select>
<label class="newline">Power Supply:</label><select name="POWER_SUPPLY"></select>
<label>PS Default Off:</label>
<input name="PS_DEFAULT_OFF" type="checkbox" value="1" checked />
</fieldset>
<fieldset id="homing">
<legend>Homing</legend>
</fieldset>
<fieldset id="temperature">
<legend>Temperature</legend>
<label class="newline">Temp Sensor 0:</label><select name="TEMP_SENSOR_0"></select>
<label class="newline">Temp Sensor 1:</label><select name="TEMP_SENSOR_1"></select>
<label class="newline">Temp Sensor 2:</label><select name="TEMP_SENSOR_2"></select>
<label class="newline">Bed Temp Sensor:</label><select name="TEMP_SENSOR_BED"></select>
<label>Max Diff:</label>
<input name="MAX_REDUNDANT_TEMP_SENSOR_DIFF" type="text" size="3" maxlength="2" />
<label>Temp Residency Time (s):</label>
<input name="TEMP_RESIDENCY_TIME" type="text" size="3" maxlength="2" />
</fieldset>
<fieldset id="extruder">
<legend>Extruder</legend>
</fieldset>
<fieldset id="lcd">
<legend>LCD / SD</legend>
</fieldset>
<fieldset id="bedlevel">
<legend>Bed Leveling</legend>
</fieldset>
<fieldset id="extras">
<legend>Extras</legend>
</fieldset>
<fieldset id="info">
<legend>Info</legend>
</fieldset>
<fieldset id="more">
<legend>More…</legend>
</fieldset>
<section id="config_text">
<h2>Configuration.h</h2>
<span class="disclose"></span>
<a href="" class="download">Download</a>
<pre class="hilightable config"></pre>
</section>
<section id="config_adv_text">
<h2>Configuration_adv.h</h2>
<span class="disclose"></span>
<a href="" class="download">Download</a>
<pre class="hilightable config"></pre>
</section>
<br class="clear" />
</form>
</section>
</body>
</html>

@ -0,0 +1,2 @@
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs=saveAs||typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator)||function(view){"use strict";if(typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var doc=view.document,get_URL=function(){return view.URL||view.webkitURL||view},save_link=doc.createElementNS("http://www.w3.org/1999/xhtml","a"),can_use_save_link="download"in save_link,click=function(node){var event=doc.createEvent("MouseEvents");event.initMouseEvent("click",true,false,view,0,0,0,0,0,false,false,false,false,0,null);node.dispatchEvent(event)},webkit_req_fs=view.webkitRequestFileSystem,req_fs=view.requestFileSystem||webkit_req_fs||view.mozRequestFileSystem,throw_outside=function(ex){(view.setImmediate||view.setTimeout)(function(){throw ex},0)},force_saveable_type="application/octet-stream",fs_min_size=0,arbitrary_revoke_timeout=500,revoke=function(file){var revoker=function(){if(typeof file==="string"){get_URL().revokeObjectURL(file)}else{file.remove()}};if(view.chrome){revoker()}else{setTimeout(revoker,arbitrary_revoke_timeout)}},dispatch=function(filesaver,event_types,event){event_types=[].concat(event_types);var i=event_types.length;while(i--){var listener=filesaver["on"+event_types[i]];if(typeof listener==="function"){try{listener.call(filesaver,event||filesaver)}catch(ex){throw_outside(ex)}}}},FileSaver=function(blob,name){var filesaver=this,type=blob.type,blob_changed=false,object_url,target_view,dispatch_all=function(){dispatch(filesaver,"writestart progress write writeend".split(" "))},fs_error=function(){if(blob_changed||!object_url){object_url=get_URL().createObjectURL(blob)}if(target_view){target_view.location.href=object_url}else{var new_tab=view.open(object_url,"_blank");if(new_tab==undefined&&typeof safari!=="undefined"){view.location.href=object_url}}filesaver.readyState=filesaver.DONE;dispatch_all();revoke(object_url)},abortable=function(func){return function(){if(filesaver.readyState!==filesaver.DONE){return func.apply(this,arguments)}}},create_if_not_found={create:true,exclusive:false},slice;filesaver.readyState=filesaver.INIT;if(!name){name="download"}if(can_use_save_link){object_url=get_URL().createObjectURL(blob);save_link.href=object_url;save_link.download=name;click(save_link);filesaver.readyState=filesaver.DONE;dispatch_all();revoke(object_url);return}if(view.chrome&&type&&type!==force_saveable_type){slice=blob.slice||blob.webkitSlice;blob=slice.call(blob,0,blob.size,force_saveable_type);blob_changed=true}if(webkit_req_fs&&name!=="download"){name+=".download"}if(type===force_saveable_type||webkit_req_fs){target_view=view}if(!req_fs){fs_error();return}fs_min_size+=blob.size;req_fs(view.TEMPORARY,fs_min_size,abortable(function(fs){fs.root.getDirectory("saved",create_if_not_found,abortable(function(dir){var save=function(){dir.getFile(name,create_if_not_found,abortable(function(file){file.createWriter(abortable(function(writer){writer.onwriteend=function(event){target_view.location.href=file.toURL();filesaver.readyState=filesaver.DONE;dispatch(filesaver,"writeend",event);revoke(file)};writer.onerror=function(){var error=writer.error;if(error.code!==error.ABORT_ERR){fs_error()}};"writestart progress write abort".split(" ").forEach(function(event){writer["on"+event]=filesaver["on"+event]});writer.write(blob);filesaver.abort=function(){writer.abort();filesaver.readyState=filesaver.DONE};filesaver.readyState=filesaver.WRITING}),fs_error)}),fs_error)};dir.getFile(name,{create:false},abortable(function(file){file.remove();save()}),abortable(function(ex){if(ex.code===ex.NOT_FOUND_ERR){save()}else{fs_error()}}))}),fs_error)}),fs_error)},FS_proto=FileSaver.prototype,saveAs=function(blob,name){return new FileSaver(blob,name)};FS_proto.abort=function(){var filesaver=this;filesaver.readyState=filesaver.DONE;dispatch(filesaver,"abort")};FS_proto.readyState=FS_proto.INIT=0;FS_proto.WRITING=1;FS_proto.DONE=2;FS_proto.error=FS_proto.onwritestart=FS_proto.onprogress=FS_proto.onwrite=FS_proto.onabort=FS_proto.onerror=FS_proto.onwriteend=null;return saveAs}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!=null){define([],function(){return saveAs})}

@ -0,0 +1,79 @@
function BinaryFileUploader(o) {
this.options = null;
this._defaultOptions = {
element: null, // HTML file element
onFileLoad: function(file) {
console.log(file.toString());
}
};
this._init = function(o) {
if (!this.hasFileUploaderSupport()) return;
this._verifyDependencies();
this.options = this._mergeObjects(this._defaultOptions, o);
this._verifyOptions();
this.addFileChangeListener();
}
this.hasFileUploaderSupport = function() {
return !!(window.File && window.FileReader && window.FileList && window.Blob);
}
this.addFileChangeListener = function() {
this.options.element.addEventListener(
'change',
this._bind(this, this.onFileChange)
);
}
this.onFileChange = function(e) {
// TODO accept multiple files
var file = e.target.files[0],
reader = new FileReader();
reader.onload = this._bind(this, this.onFileLoad);
reader.readAsBinaryString(file);
}
this.onFileLoad = function(e) {
var content = e.target.result,
string = new BinaryString(content);
this.options.onFileLoad(string);
}
this._mergeObjects = function(starting, override) {
var merged = starting;
for (key in override) merged[key] = override[key];
return merged;
}
this._verifyOptions = function() {
if (!(this.options.element && this.options.element.type && this.options.element.type === 'file')) {
throw 'Invalid element param in options. Must be a file upload DOM element';
}
if (typeof this.options.onFileLoad !== 'function') {
throw 'Invalid onFileLoad param in options. Must be a function';
}
}
this._verifyDependencies = function() {
if (!window.BinaryString) throw 'BinaryString is missing. Check that you\'ve correctly included it';
}
// helper function for binding methods to objects
this._bind = function(object, method) {
return function() {return method.apply(object, arguments);};
}
this._init(o);
}

@ -0,0 +1,168 @@
function BinaryString(source) {
this._source = null;
this._bytes = [];
this._pos = 0;
this._length = 0;
this._init = function(source) {
this._source = source;
this._bytes = this._stringToBytes(this._source);
this._length = this._bytes.length;
}
this.current = function() {return this._pos;}
this.rewind = function() {return this.jump(0);}
this.end = function() {return this.jump(this.length() - 1);}
this.next = function() {return this.jump(this.current() + 1);}
this.prev = function() {return this.jump(this.current() - 1);}
this.jump = function(pos) {
if (pos < 0 || pos >= this.length()) return false;
this._pos = pos;
return true;
}
this.readByte = function(pos) {
pos = (typeof pos == 'number') ? pos : this.current();
return this.readBytes(1, pos)[0];
}
this.readBytes = function(length, pos) {
length = length || 1;
pos = (typeof pos == 'number') ? pos : this.current();
if (pos > this.length() ||
pos < 0 ||
length <= 0 ||
pos + length > this.length() ||
pos + length < 0
) {
return false;
}
var bytes = [];
for (var i = pos; i < pos + length; i++) {
bytes.push(this._bytes[i]);
}
return bytes;
}
this.length = function() {return this._length;}
this.toString = function() {
var string = '',
length = this.length();
for (var i = 0; i < length; i++) {
string += String.fromCharCode(this.readByte(i));
}
return string;
}
this.toUtf8 = function() {
var inc = 0,
string = '',
length = this.length();
// determine if first 3 characters are the BOM
// then skip them in output if so
if (length >= 3 &&
this.readByte(0) === 0xEF &&
this.readByte(1) === 0xBB &&
this.readByte(2) === 0xBF
) {
inc = 3;
}
for (; inc < length; inc++) {
var byte1 = this.readByte(inc),
byte2 = 0,
byte3 = 0,
byte4 = 0,
code1 = 0,
code2 = 0,
point = 0;
switch (true) {
// single byte character; same as ascii
case (byte1 < 0x80):
code1 = byte1;
break;
// 2 byte character
case (byte1 >= 0xC2 && byte1 < 0xE0):
byte2 = this.readByte(++inc);
code1 = ((byte1 & 0x1F) << 6) +
(byte2 & 0x3F);
break;
// 3 byte character
case (byte1 >= 0xE0 && byte1 < 0xF0):
byte2 = this.readByte(++inc);
byte3 = this.readByte(++inc);
code1 = ((byte1 & 0xFF) << 12) +
((byte2 & 0x3F) << 6) +
(byte3 & 0x3F);
break;
// 4 byte character
case (byte1 >= 0xF0 && byte1 < 0xF5):
byte2 = this.readByte(++inc);
byte3 = this.readByte(++inc);
byte4 = this.readByte(++inc);
point = ((byte1 & 0x07) << 18) +
((byte2 & 0x3F) << 12) +
((byte3 & 0x3F) << 6) +
(byte4 & 0x3F)
point -= 0x10000;
code1 = (point >> 10) + 0xD800;
code2 = (point & 0x3FF) + 0xDC00;
break;
default:
throw 'Invalid byte ' + this._byteToString(byte1) + ' whilst converting to UTF-8';
break;
}
string += (code2) ? String.fromCharCode(code1, code2)
: String.fromCharCode(code1);
}
return string;
}
this.toArray = function() {return this.readBytes(this.length() - 1, 0);}
this._stringToBytes = function(str) {
var bytes = [],
chr = 0;
for (var i = 0; i < str.length; i++) {
chr = str.charCodeAt(i);
bytes.push(chr & 0xFF);
}
return bytes;
}
this._byteToString = function(byte) {
var asString = byte.toString(16).toUpperCase();
while (asString.length < 2) {
asString = '0' + asString;
}
return '0x' + asString;
}
this._init(source);
}

@ -0,0 +1,1414 @@
/**
* configurator.js
*
* Marlin Configuration Utility
* - Web form for entering configuration options
* - A reprap calculator to calculate movement values
* - Uses HTML5 to generate downloadables in Javascript
* - Reads and parses standard configuration files from local folders
*
* Supporting functions
* - Parser to read Marlin Configuration.h and Configuration_adv.h files
* - Utilities to replace values in configuration files
*/
"use strict";
$(function(){
/**
* Github API useful GET paths. (Start with "https://api.github.com/repos/:owner/:repo/")
*
* contributors Get a list of contributors
* tags Get a list of tags
* contents/[path]?ref=branch/tag/commit Get the contents of a file
*/
// GitHub
// Warning! Limited to 60 requests per hour!
var config = {
type: 'github',
host: 'https://api.github.com',
owner: 'thinkyhead',
repo: 'Marlin',
ref: 'marlin_configurator',
path: 'Marlin/configurator/config'
};
/**/
/* // Remote
var config = {
type: 'remote',
host: 'http://www.thinkyhead.com',
path: '_marlin/config'
};
/**/
/* // Local
var config = {
type: 'local',
path: 'config'
};
/**/
function github_command(conf, command, path) {
var req = conf.host+'/repos/'+conf.owner+'/'+conf.repo+'/'+command;
if (path) req += '/' + path;
return req;
}
function config_path(item) {
var path = '', ref = '';
switch(config.type) {
case 'github':
path = github_command(config, 'contents', config.path);
if (config.ref !== undefined) ref = '?ref=' + config.ref;
break;
case 'remote':
path = config.host + '/' + config.path + '/';
break;
case 'local':
path = config.path + '/';
break;
}
return path + '/' + item + ref;
}
// Extend builtins
String.prototype.lpad = function(len, chr) {
if (chr === undefined) { chr = '&nbsp;'; }
var s = this+'', need = len - s.length;
if (need > 0) { s = new Array(need+1).join(chr) + s; }
return s;
};
String.prototype.prePad = function(len, chr) { return len ? this.lpad(len, chr) : this; };
String.prototype.zeroPad = function(len) { return this.prePad(len, '0'); };
String.prototype.toHTML = function() { return jQuery('<div>').text(this).html(); };
String.prototype.regEsc = function() { return this.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); }
String.prototype.lineCount = function(ind) { var len = (ind === undefined ? this : this.substr(0,ind*1)).split(/\r?\n|\r/).length; return len > 0 ? len - 1 : 0; };
String.prototype.line = function(num) { var arr = this.split(/\r?\n|\r/); return num < arr.length ? arr[1*num] : ''; };
String.prototype.replaceLine = function(num,txt) { var arr = this.split(/\r?\n|\r/); if (num < arr.length) { arr[num] = txt; return arr.join('\n'); } else return this; }
String.prototype.toLabel = function() { return this.replace(/[\[\]]/g, '').replace(/_/g, ' ').toTitleCase(); }
String.prototype.toTitleCase = function() { return this.replace(/([A-Z])(\w+)/gi, function(m,p1,p2) { return p1.toUpperCase() + p2.toLowerCase(); }); }
Number.prototype.limit = function(m1, m2) {
if (m2 == null) return this > m1 ? m1 : this;
return this < m1 ? m1 : this > m2 ? m2 : this;
};
Date.prototype.fileStamp = function(filename) {
var fs = this.getFullYear()
+ ((this.getMonth()+1)+'').zeroPad(2)
+ (this.getDate()+'').zeroPad(2)
+ (this.getHours()+'').zeroPad(2)
+ (this.getMinutes()+'').zeroPad(2)
+ (this.getSeconds()+'').zeroPad(2);
if (filename !== undefined)
return filename.replace(/^(.+)(\.\w+)$/g, '$1-['+fs+']$2');
return fs;
}
/**
* selectField.addOptions takes an array or keyed object
*/
$.fn.extend({
addOptions: function(arrObj) {
return this.each(function() {
var sel = $(this);
var isArr = Object.prototype.toString.call(arrObj) == "[object Array]";
$.each(arrObj, function(k, v) {
sel.append( $('<option>',{value:isArr?v:k}).text(v) );
});
});
},
noSelect: function() {
return this
.attr('unselectable', 'on')
.css('user-select', 'none')
.on('selectstart', false);
},
unblock: function(on) {
on ? this.removeClass('blocked') : this.addClass('blocked');
return this;
}
});
// The app is a singleton
window.configuratorApp = (function(){
// private variables and functions go here
var self,
pi2 = Math.PI * 2,
has_boards = false, has_config = false, has_config_adv = false,
boards_file = 'boards.h',
config_file = 'Configuration.h',
config_adv_file = 'Configuration_adv.h',
$msgbox = $('#message'),
$form = $('#config_form'),
$tooltip = $('#tooltip'),
$cfg = $('#config_text'), $adv = $('#config_adv_text'),
$config = $cfg.find('pre'), $config_adv = $adv.find('pre'),
config_file_list = [ boards_file, config_file, config_adv_file ],
config_list = [ $config, $config_adv ],
define_info = {}, // info for all defines, by name
define_list = [[],[]], // arrays with all define names
define_occur = [{},{}], // lines where defines occur in each file
define_groups = [{},{}], // similarly-named defines that group in the form
define_section = {}, // the section of each define
dependent_groups = {},
boards_list = {},
therms_list = {},
total_config_lines,
total_config_adv_lines,
hover_timer,
pulse_offset = 0;
// Return this anonymous object as configuratorApp
return {
my_public_var: 4,
logging: 1,
init: function() {
self = this; // a 'this' for use when 'this' is something else
// Set up the form, creating fields and fieldsets as-needed
this.initConfigForm();
// Make tabs for all the fieldsets
this.makeTabsForFieldsets();
// No selection on errors
// $msgbox.noSelect();
// Make a droppable file uploader, if possible
var $uploader = $('#file-upload');
var fileUploader = new BinaryFileUploader({
element: $uploader[0],
onFileLoad: function(file) { self.handleFileLoad(file, $uploader); }
});
if (!fileUploader.hasFileUploaderSupport())
this.setMessage("Your browser doesn't support the file reading API.", 'error');
// Make the disclosure items work
$('.disclose').click(function(){
var $dis = $(this), $pre = $dis.nextAll('pre:first');
var didAnim = function() {$dis.toggleClass('closed almost');};
$dis.addClass('almost').hasClass('closed')
? $pre.slideDown(200, didAnim)
: $pre.slideUp(200, didAnim);
});
// Adjust the form layout for the window size
$(window).bind('scroll resize', this.adjustFormLayout).trigger('resize');
// Read boards.h, Configuration.h, Configuration_adv.h
var ajax_count = 0, success_count = 0;
var loaded_items = {};
var isGithub = config.type == 'github';
var rateLimit = 0;
$.each(config_file_list, function(i,fname){
var url = config_path(fname);
$.ajax({
url: url,
type: 'GET',
dataType: isGithub ? 'jsonp' : undefined,
async: true,
cache: false,
error: function(req, stat, err) {
self.log(req, 1);
if (req.status == 200) {
if (typeof req.responseText === 'string') {
var txt = req.responseText;
loaded_items[fname] = function(){ self.fileLoaded(fname, txt, true); };
success_count++;
// self.setMessage('The request for "'+fname+'" may be malformed.', 'error');
}
}
else {
self.setRequestError(req.status ? req.status : '(Access-Control-Allow-Origin?)', url);
}
},
success: function(txt) {
if (isGithub && typeof txt.meta.status !== undefined && txt.meta.status != 200) {
self.setRequestError(txt.meta.status, url);
}
else {
// self.log(txt, 1);
if (isGithub) {
rateLimit = {
quota: 1 * txt.meta['X-RateLimit-Remaining'],
timeLeft: Math.floor(txt.meta['X-RateLimit-Reset'] - Date.now()/1000),
};
}
loaded_items[fname] = function(){ self.fileLoaded(fname, isGithub ? decodeURIComponent(escape(atob(txt.data.content))) : txt, true); };
success_count++;
}
},
complete: function() {
ajax_count++;
if (ajax_count >= config_file_list.length) {
// If not all files loaded set an error
if (success_count < ajax_count)
self.setMessage('Unable to load configurations. Try the upload field.', 'error');
// Is the request near the rate limit? Set an error.
var r;
if (r = rateLimit) {
if (r.quota < 20) {
self.setMessage(
'Approaching request limit (' +
r.quota + ' remaining.' +
' Reset in ' + Math.floor(r.timeLeft/60) + ':' + (r.timeLeft%60+'').zeroPad(2) + ')',
'warning'
);
}
}
// Post-process all the loaded files
$.each(config_file_list, function(){ if (loaded_items[this]) loaded_items[this](); });
}
}
});
});
},
/**
* Make a download link visible and active
*/
activateDownloadLink: function(cindex) {
var filename = config_file_list[cindex+1];
var $c = config_list[cindex], txt = $c.text();
$c.prevAll('.download:first')
.unbind('mouseover click')
.mouseover(function() {
var d = new Date(), fn = d.fileStamp(filename);
$(this).attr({ download:fn, href:'download:'+fn, title:'download:'+fn });
})
.click(function(){
var $button = $(this);
$(this).attr({ href:'data:text/plain;charset=utf-8,' + encodeURIComponent($c.text()) });
setTimeout(function(){
$button.attr({ href:$button.attr('title') });
}, 100);
return true;
})
.css({visibility:'visible'});
},
/**
* Make the download-all link visible and active
*/
activateDownloadAllLink: function() {
$('.download-all')
.unbind('mouseover click')
.mouseover(function() {
var d = new Date(), fn = d.fileStamp('MarlinConfig.zip');
$(this).attr({ download:fn, href:'download:'+fn, title:'download:'+fn });
})
.click(function(){
var $button = $(this);
var zip = new JSZip();
for (var e in [0,1]) zip.file(config_file_list[e+1], config_list[e].text());
var zipped = zip.generate({type:'blob'});
saveAs(zipped, $button.attr('download'));
return false;
})
.css({visibility:'visible'});
},
/**
* Init the boards array from a boards.h file
*/
initBoardsFromText: function(txt) {
boards_list = {};
var r, findDef = new RegExp('[ \\t]*#define[ \\t]+(BOARD_[\\w_]+)[ \\t]+(\\d+)[ \\t]*(//[ \\t]*)?(.+)?', 'gm');
while((r = findDef.exec(txt)) !== null) {
boards_list[r[1]] = r[2].prePad(3, '  ') + " — " + r[4].replace(/\).*/, ')');
}
this.log("Loaded boards:\n" + Object.keys(boards_list).join('\n'), 3);
has_boards = true;
},
/**
* Init the thermistors array from the Configuration.h file
*/
initThermistorList: function(txt) {
// Get all the thermistors and save them into an object
var r, s, findDef = new RegExp('(//.*\n)+\\s+(#define[ \\t]+TEMP_SENSOR_0)', 'g');
r = findDef.exec(txt);
findDef = new RegExp('^//[ \\t]*([-\\d]+)[ \\t]+is[ \\t]+(.*)[ \\t]*$', 'gm');
while((s = findDef.exec(r[0])) !== null) {
therms_list[s[1]] = s[1].prePad(4, '  ') + " — " + s[2];
}
},
/**
* Get all the unique define names, building lists that will be used
* when gathering info about each define.
*
* define_list[c][j] : Define names in each config (in order of occurrence)
* define_section[name] : Section where define should appear in the form
* define_occur[c][name][i] : Lines in each config where the same define occurs
* .cindex Config file index
* .lineNum Line number of the occurrence
* .line The occurrence line
*/
initDefineList: function(cindex) {
var section = 'hidden',
leave_out_defines = ['CONFIGURATION_H', 'CONFIGURATION_ADV_H'],
define_sect = {},
occ_list = {},
txt = config_list[cindex].text(),
r, findDef = new RegExp('^.*(@section|#define)[ \\t]+(\\w+).*$', 'gm');
while((r = findDef.exec(txt)) !== null) {
var name = r[2];
if (r[1] == '@section') {
section = name;
}
else if ($.inArray(name, leave_out_defines) < 0) {
var lineNum = txt.lineCount(r.index),
inst = { cindex:cindex, lineNum:lineNum, line:r[0] },
in_sect = (name in define_sect);
if (!in_sect) {
occ_list[name] = [ inst ];
}
if (!(name in define_section) && !in_sect) {
define_sect[name] = section; // new first-time define
}
else {
occ_list[name].push(inst);
}
}
}
define_list[cindex] = Object.keys(define_sect);
define_occur[cindex] = occ_list;
$.extend(define_section, define_sect);
this.log(define_list[cindex], 2);
this.log(occ_list, 2);
this.log(define_sect, 2);
},
/**
* Find the defines in one of the configs that are just variants.
* Group them together for form-building and other uses.
*
* define_groups[c][name]
* .pattern regexp matching items in the group
* .title title substitution
* .count number of items in the group
*/
refreshDefineGroups: function(cindex) {
var findDef = /^(|.*_)(([XYZE](MAX|MIN))|(E[0-3]|[XYZE01234])|MAX|MIN|(bed)?K[pid]|HOTEND|HPB|JAPAN|WESTERN|LEFT|RIGHT|BACK|FRONT|[XYZ]_POINT)(_.*|)$/i;
var match_prev, patt, title, nameList, groups = {}, match_section;
$.each(define_list[cindex], function(i, name) {
if (match_prev) {
if (match_prev.exec(name) && define_section[name] == match_section) {
nameList.push(name);
}
else {
if (nameList.length > 1) {
$.each(nameList, function(i,n){
groups[n] = {
pattern: patt,
title: title,
count: nameList.length
};
});
}
match_prev = null;
}
}
if (!match_prev) {
var r = findDef.exec(name);
if (r != null) {
title = '';
switch(r[2].toUpperCase()) {
case '0':
patt = '([0123])';
title = 'N';
break;
case 'X':
patt = '([XYZE])';
title = 'AXIS';
break;
case 'E0':
patt = 'E([0-3])';
title = 'E';
break;
case 'BEDKP':
patt = 'bed(K[pid])';
title = 'BED_PID';
break;
case 'KP':
patt = '(K[pid])';
title = 'PID';
break;
case 'LEFT':
case 'RIGHT':
case 'BACK':
case 'FRONT':
patt = '([LRBF])(EFT|IGHT|ACK|RONT)';
break;
case 'MAX':
case 'MIN':
patt = '(MAX|MIN)';
break;
case 'HOTEND':
case 'HPB':
patt = '(HOTEND|HPB)';
break;
case 'JAPAN':
case 'WESTERN':
patt = '(JAPAN|WESTERN)';
break;
case 'XMIN':
case 'XMAX':
patt = '([XYZ])'+r[4];
title = 'XYZ_'+r[4];
break;
default:
patt = null;
break;
}
if (patt) {
patt = '^' + r[1] + patt + r[7] + '$';
title = r[1] + title + r[7];
match_prev = new RegExp(patt, 'i');
match_section = define_section[name];
nameList = [ name ];
}
}
}
});
define_groups[cindex] = groups;
this.log(define_groups[cindex], 2);
},
/**
* Get all conditional blocks and their line ranges
* and store them in the dependent_groups list.
*
* dependent_groups[condition][i]
*
* .cindex config file index
* .start starting line
* .end ending line
*
*/
initDependentGroups: function() {
var findBlock = /^[ \t]*#(ifn?def|if|else|endif)[ \t]*(.*)([ \t]*\/\/[^\n]+)?$/gm,
leave_out_defines = ['CONFIGURATION_H', 'CONFIGURATION_ADV_H'];
dependent_groups = {};
$.each(config_list, function(i, $v) {
var ifStack = [];
var r, txt = $v.text();
while((r = findBlock.exec(txt)) !== null) {
var lineNum = txt.lineCount(r.index);
var code = r[2].replace(/[ \t]*\/\/.*$/, '');
switch(r[1]) {
case 'if':
var code = code
.replace(/([A-Z][A-Z0-9_]+)/g, 'self.defineValue("$1")')
.replace(/defined[ \t]*\(?[ \t]*self.defineValue\(("[A-Z][A-Z0-9_]+")\)[ \t]*\)?/g, 'self.defineIsEnabled($1)');
ifStack.push(['('+code+')', lineNum]); // #if starts on next line
self.log("push if " + code, 4);
break;
case 'ifdef':
if ($.inArray(code, leave_out_defines) < 0) {
ifStack.push(['self.defineIsEnabled("' + code + '")', lineNum]);
self.log("push ifdef " + code, 4);
}
else {
ifStack.push(0);
}
break;
case 'ifndef':
if ($.inArray(code, leave_out_defines) < 0) {
ifStack.push(['!self.defineIsEnabled("' + code + '")', lineNum]);
self.log("push ifndef " + code, 4);
}
else {
ifStack.push(0);
}
break;
case 'else':
case 'endif':
var c = ifStack.pop();
if (c) {
var cond = c[0], line = c[1];
self.log("pop " + c[0], 4);
if (dependent_groups[cond] === undefined) dependent_groups[cond] = [];
dependent_groups[cond].push({cindex:i,start:line,end:lineNum});
if (r[1] == 'else') {
// Reverse the condition
cond = (cond.indexOf('!') === 0) ? cond.substr(1) : ('!'+cond);
ifStack.push([cond, lineNum]);
self.log("push " + cond, 4);
}
}
else {
if (r[1] == 'else') ifStack.push(0);
}
break;
}
}
}); // text blobs loop
},
/**
* Init all the defineInfo structures after reload
* The "enabled" field may need an update for newly-loaded dependencies
*/
initDefineInfo: function() {
$.each(define_list, function(e,def_list){
$.each(def_list, function(i, name) {
define_info[name] = self.getDefineInfo(name, e);
});
});
},
/**
* Create fields for defines in a config that have none
* Use define_groups data to group fields together
*/
createFieldsForDefines: function(cindex) {
// var n = 0;
var grouping = false, group = define_groups[cindex],
g_pattern, g_regex, g_subitem, g_section, g_class,
fail_list = [];
$.each(define_list[cindex], function(i, name) {
var section = define_section[name];
if (section != 'hidden' && !$('#'+name).length) {
var inf = define_info[name];
if (inf) {
var label_text = name, sublabel;
// Is this field in a sequence?
// Then see if it's the second or after
if (grouping) {
if (name in group && g_pattern == group[name].pattern && g_section == section) {
g_subitem = true;
sublabel = g_regex.exec(name)[1];
}
else
grouping = false;
}
// Start grouping?
if (!grouping && name in group) {
grouping = true;
g_subitem = false;
var grp = group[name];
g_section = section;
g_class = 'one_of_' + grp.count;
g_pattern = grp.pattern;
g_regex = new RegExp(g_pattern, 'i');
label_text = grp.title;
sublabel = g_regex.exec(name)[1];
}
var $ff = $('#'+section), $newfield,
avail = eval(inf.enabled);
if (!(grouping && g_subitem)) {
var $newlabel = $('<label>',{for:name,class:'added'}).text(label_text.toLabel());
$newlabel.unblock(avail);
// if (!(++n % 3))
$newlabel.addClass('newline');
$ff.append($newlabel);
}
// Multiple fields?
if (inf.type == 'list') {
for (var i=0; i<inf.size; i++) {
var fieldname = i > 0 ? name+'-'+i : name;
$newfield = $('<input>',{type:'text',size:6,maxlength:10,id:fieldname,name:fieldname,class:'subitem added',disabled:!avail}).unblock(avail);
if (grouping) $newfield.addClass(g_class);
$ff.append($newfield);
}
}
else {
// Items with options, either toggle or select
// TODO: Radio buttons for other values
if (inf.options !== undefined) {
if (inf.type == 'toggle') {
$newfield = $('<input>',{type:'checkbox'});
}
else {
// Otherwise selectable
$newfield = $('<select>');
}
// ...Options added when field initialized
}
else {
$newfield = inf.type == 'switch' ? $('<input>',{type:'checkbox'}) : $('<input>',{type:'text',size:10,maxlength:40});
}
$newfield.attr({id:name,name:name,class:'added',disabled:!avail}).unblock(avail);
if (grouping) {
$newfield.addClass(g_class);
if (sublabel) {
$ff.append($('<label>',{class:'added sublabel',for:name}).text(sublabel.toTitleCase()).unblock(avail));
}
}
// Add the new field to the form
$ff.append($newfield);
}
}
else
fail_list.push(name);
}
});
if (fail_list.length) this.log('Unable to parse:\n' + fail_list.join('\n'), 2);
},
/**
* Handle a file being dropped on the file field
*/
handleFileLoad: function(txt, $uploader) {
txt += '';
var filename = $uploader.val().replace(/.*[\/\\](.*)$/, '$1');
if ($.inArray(filename, config_file_list))
this.fileLoaded(filename, txt);
else
this.setMessage("Can't parse '"+filename+"'!");
},
/**
* Process a file after it's been successfully loaded
*/
fileLoaded: function(filename, txt, wait) {
this.log("fileLoaded:"+filename,4);
var err, cindex;
switch(filename) {
case boards_file:
this.initBoardsFromText(txt);
$('#MOTHERBOARD').html('').addOptions(boards_list);
if (has_config) this.initField('MOTHERBOARD');
break;
case config_file:
if (has_boards) {
$config.text(txt);
total_config_lines = txt.lineCount();
// this.initThermistorList(txt);
if (!wait) cindex = 0;
has_config = true;
if (has_config_adv) {
this.activateDownloadAllLink();
if (wait) cindex = 2;
}
}
else {
err = boards_file;
}
break;
case config_adv_file:
if (has_config) {
$config_adv.text(txt);
total_config_adv_lines = txt.lineCount();
if (!wait) cindex = 1;
has_config_adv = true;
if (has_config) {
this.activateDownloadAllLink();
if (wait) cindex = 2;
}
}
else {
err = config_file;
}
break;
}
// When a config file loads defines need update
if (cindex != null) this.prepareConfigData(cindex);
this.setMessage(err
? 'Please upload a "' + boards_file + '" file first!'
: '"' + filename + '" loaded successfully.', err ? 'error' : 'message'
);
},
prepareConfigData: function(cindex) {
var inds = (cindex == 2) ? [ 0, 1 ] : [ cindex ];
$.each(inds, function(i,e){
// Purge old fields from the form, clear the define list
self.purgeAddedFields(e);
// Build the define_list
self.initDefineList(e);
// TODO: Find sequential names and group them
// Allows related settings to occupy one line in the form
self.refreshDefineGroups(e);
});
// Build the dependent defines list
this.initDependentGroups(); // all config text
// Get define_info for all known defines
this.initDefineInfo(); // all config text
$.each(inds, function(i,e){
// Create new fields
self.createFieldsForDefines(e); // create new fields
// Init the fields, set values, etc
self.refreshConfigForm(e);
self.activateDownloadLink(e);
});
},
/**
* Add initial enhancements to the existing form
*/
initConfigForm: function() {
// Modify form fields and make the form responsive.
// As values change on the form, we could update the
// contents of text areas containing the configs, for
// example.
// while(!$config_adv.text() == null) {}
// while(!$config.text() == null) {}
// Go through all form items with names
$form.find('[name]').each(function() {
// Set its id to its name
var name = $(this).attr('name');
$(this).attr({id: name});
// Attach its label sibling
var $label = $(this).prev('label');
if ($label.length) $label.attr('for',name);
});
// Get all 'switchable' class items and add a checkbox
// $form.find('.switchable').each(function(){
// $(this).after(
// $('<input>',{type:'checkbox',value:'1',class:'enabler added'})
// .prop('checked',true)
// .attr('id',this.id + '-switch')
// .change(self.handleSwitch)
// );
// });
// Add options to the popup menus
// $('#SERIAL_PORT').addOptions([0,1,2,3,4,5,6,7]);
// $('#BAUDRATE').addOptions([2400,9600,19200,38400,57600,115200,250000]);
// $('#EXTRUDERS').addOptions([1,2,3,4]);
// $('#POWER_SUPPLY').addOptions({'1':'ATX','2':'Xbox 360'});
// Replace the Serial popup menu with a stepper control
/*
$('#serial_stepper').jstepper({
min: 0,
max: 3,
val: $('#SERIAL_PORT').val(),
arrowWidth: '18px',
arrowHeight: '15px',
color: '#FFF',
acolor: '#F70',
hcolor: '#FF0',
id: 'select-me',
textStyle: {width:'1.5em',fontSize:'120%',textAlign:'center'},
onChange: function(v) { $('#SERIAL_PORT').val(v).trigger('change'); }
});
*/
},
/**
* Make tabs to switch between fieldsets
*/
makeTabsForFieldsets: function() {
// Make tabs for the fieldsets
var $fset = $form.find('fieldset'),
$tabs = $('<ul>',{class:'tabs'}),
ind = 1;
$fset.each(function(){
var tabID = 'TAB'+ind;
$(this).addClass(tabID);
var $leg = $(this).find('legend');
var $link = $('<a>',{href:'#'+ind,id:tabID}).text($leg.text());
$tabs.append($('<li>').append($link));
$link.click(function(e){
e.preventDefault;
var ind = this.id;
$tabs.find('.active').removeClass('active');
$(this).addClass('active');
$fset.hide();
$fset.filter('.'+this.id).show();
return false;
});
ind++;
});
$('#tabs').html('').append($tabs);
$('<br>',{class:'clear'}).appendTo('#tabs');
$tabs.find('a:first').trigger('click');
},
/**
* Update all fields on the form after loading a configuration
*/
refreshConfigForm: function(cindex) {
/**
* Any manually-created form elements will remain
* where they are. Unknown defines (currently most)
* are added to tabs based on section
*
* Specific exceptions can be managed by applying
* classes to the associated form fields.
* Sorting and arrangement can come from an included
* Javascript file that describes the configuration
* in JSON, or using information added to the config
* files.
*
*/
// Refresh the motherboard menu with new options
$('#MOTHERBOARD').html('').addOptions(boards_list);
// Init all existing fields, getting define info for those that need it
// refreshing the options and updating their current values
$.each(define_list[cindex], function(i, name) {
if ($('#'+name).length) {
self.initField(name);
self.initFieldValue(name);
}
else
self.log(name + " is not on the page yet.", 2);
});
// Set enabled state based on dependencies
// this.enableForDependentConditions();
},
/**
* Enable / disable fields in dependent groups
* based on their dependencies.
*/
refreshDependentFields: function() {
$.each(define_list, function(e,def_list){
$.each(def_list, function(i, name) {
var inf = define_info[name];
if (inf && inf.enabled != 'true') {
var $elm = $('#'+name), ena = eval(inf.enabled);
var isEnabled = (inf.type == 'switch') || self.defineIsEnabled(name);
$('#'+name+'-switch').attr('disabled', !ena);
$elm.attr('disabled', !(ena && isEnabled)).unblock(ena);
$('label[for="'+name+'"]').unblock(ena);
}
});
});
},
/**
* Make a field responsive, tooltip its label(s), add enabler if needed
*/
initField: function(name) {
this.log("initField:"+name,4);
var $elm = $('#'+name), inf = define_info[name];
$elm[0].defineInfo = inf;
// Create a tooltip on the label if there is one
if (inf.tooltip) {
// label for the item
var $tipme = $('label[for="'+name+'"]');
if ($tipme.length) {
$tipme.unbind('mouseenter mouseleave');
$tipme.hover(
function() {
if ($('#tipson input').prop('checked')) {
var pos = $tipme.position(), px = $tipme.width()/2;
$tooltip.html(inf.tooltip)
.append('<span>')
.css({bottom:($tooltip.parent().outerHeight()-pos.top+10)+'px',left:(pos.left+px)+'px'})
.show();
if (hover_timer) {
clearTimeout(hover_timer);
hover_timer = null;
}
}
},
function() {
hover_timer = setTimeout(function(){
hover_timer = null;
$tooltip.fadeOut(400);
}, 400);
}
);
}
}
// Make the element(s) respond to events
if (inf.type == 'list') {
// Multiple fields need to respond
for (var i=0; i<inf.size; i++) {
if (i > 0) $elm = $('#'+name+'-'+i);
$elm.unbind('input');
$elm.on('input', this.handleChange);
}
}
else {
var elmtype = $elm.attr('type');
// Set options on single fields if there are any
if (inf.options !== undefined && elmtype === undefined)
$elm.html('').addOptions(inf.options);
$elm.unbind('input change');
$elm.on(elmtype == 'text' ? 'input' : 'change', this.handleChange);
}
// Add an enabler checkbox if it needs one
if (inf.switchable && $('#'+name+'-switch').length == 0) {
// $elm = the last element added
$elm.after(
$('<input>',{type:'checkbox',value:'1',class:'enabler added'})
.prop('checked',self.defineIsEnabled(name))
.attr({id: name+'-switch'})
.change(self.handleSwitch)
);
}
},
/**
* Handle any value field being changed
* this = the field
*/
handleChange: function() {
self.updateDefineFromField(this.id);
self.refreshDependentFields();
},
/**
* Handle a switch checkbox being changed
* this = the switch checkbox
*/
handleSwitch: function() {
var $elm = $(this),
name = $elm[0].id.replace(/-.+/,''),
inf = define_info[name],
on = $elm.prop('checked') || false;
self.setDefineEnabled(name, on);
if (inf.type == 'list') {
// Multiple fields?
for (var i=0; i<inf.size; i++) {
$('#'+name+(i?'-'+i:'')).attr('disabled', !on);
}
}
else {
$elm.prev().attr('disabled', !on);
}
},
/**
* Get the current value of a #define
*/
defineValue: function(name) {
this.log('defineValue:'+name,4);
var inf = define_info[name];
if (inf == null) return 'n/a';
var r = inf.regex.exec(inf.line), val = r[inf.val_i];
this.log(r,2);
return (inf.type == 'switch') ? (val === undefined || val.trim() != '//') : val;
},
/**
* Get the current enabled state of a #define
*/
defineIsEnabled: function(name) {
this.log('defineIsEnabled:'+name,4);
var inf = define_info[name];
if (inf == null) return false;
var r = inf.regex.exec(inf.line);
this.log(r,2);
var on = r[1] != null ? r[1].trim() != '//' : true;
this.log(name + ' = ' + on, 2);
return on;
},
/**
* Set a #define enabled or disabled by altering the config text
*/
setDefineEnabled: function(name, val) {
this.log('setDefineEnabled:'+name,4);
var inf = define_info[name];
if (inf) {
var slash = val ? '' : '//';
var newline = inf.line
.replace(/^([ \t]*)(\/\/)([ \t]*)/, '$1$3') // remove slashes
.replace(inf.pre+inf.define, inf.pre+slash+inf.define); // add them back
this.setDefineLine(name, newline);
}
},
/**
* Update a #define (from the form) by altering the config text
*/
updateDefineFromField: function(name) {
this.log('updateDefineFromField:'+name,4);
// Drop the suffix on sub-fields
name = name.replace(/-\d+$/, '');
var $elm = $('#'+name), inf = define_info[name];
if (inf == null) return;
var isCheck = $elm.attr('type') == 'checkbox',
val = isCheck ? $elm.prop('checked') : $elm.val().trim();
var newline;
switch(inf.type) {
case 'switch':
var slash = val ? '' : '//';
newline = inf.line.replace(inf.repl, '$1'+slash+'$3');
break;
case 'list':
case 'quoted':
case 'plain':
if (isCheck) this.setMessage(name + ' should not be a checkbox!', 'error');
case 'toggle':
if (isCheck) {
val = val ? inf.options[1] : inf.options[0];
}
else {
if (inf.type == 'list')
for (var i=1; i<inf.size; i++) val += ', ' + $('#'+name+'-'+i).val().trim();
}
newline = inf.line.replace(inf.repl, '$1'+(''+val).replace('$','\\$')+'$3');
break;
}
this.setDefineLine(name, newline);
},
/**
* Set the define's line in the text to a new line,
* then update, highlight, and scroll to the line
*/
setDefineLine: function(name, newline) {
this.log('setDefineLine:'+name+'\n'+newline,4);
var inf = define_info[name];
var $c = $(inf.field), txt = $c.text();
var hilite_token = '[HIGHLIGHTER-TOKEN]';
txt = txt.replaceLine(inf.lineNum, hilite_token + newline); // for override line and lineNum would be changed
inf.line = newline;
// Convert txt into HTML before storing
var html = txt.toHTML().replace(hilite_token, '<span></span>');
// Set the final text including the highlighter
$c.html(html);
// Scroll to reveal the define
if ($c.is(':visible')) this.scrollToDefine(name);
},
/**
* Scroll a pre box to reveal a #define
*/
scrollToDefine: function(name, always) {
this.log('scrollToDefine:'+name,4);
var inf = define_info[name], $c = $(inf.field);
// Scroll to the altered text if it isn't visible
var halfHeight = $c.height()/2, scrollHeight = $c.prop('scrollHeight'),
lineHeight = scrollHeight/[total_config_lines, total_config_adv_lines][inf.cindex],
textScrollY = (inf.lineNum * lineHeight - halfHeight).limit(0, scrollHeight - 1);
if (always || Math.abs($c.prop('scrollTop') - textScrollY) > halfHeight) {
$c.find('span').height(lineHeight);
$c.animate({ scrollTop: textScrollY });
}
},
/**
* Set a form field to the current #define value in the config text
*/
initFieldValue: function(name) {
var $elm = $('#'+name), inf = define_info[name],
val = this.defineValue(name);
this.log('initFieldValue:' + name + ' to ' + val, 2);
// If the item is switchable then set enabled state too
var $cb = $('#'+name+'-switch'), avail = eval(inf.enabled), on = true;
if ($cb.length) {
on = self.defineIsEnabled(name);
$cb.prop('checked', on);
}
if (inf.type == 'list') {
$.each(val.split(','),function(i,v){
var $e = i > 0 ? $('#'+name+'-'+i) : $elm;
$e.val(v.trim());
$e.attr('disabled', !(on && avail)).unblock(avail);
});
}
else {
if (inf.type == 'toggle') val = val == inf.options[1];
$elm.attr('type') == 'checkbox' ? $elm.prop('checked', val) : $elm.val(''+val);
$elm.attr('disabled', !(on && avail)).unblock(avail); // enable/disable the form field (could also dim it)
}
$('label[for="'+name+'"]').unblock(avail);
},
/**
* Purge added fields and all their define info
*/
purgeAddedFields: function(cindex) {
$.each(define_list[cindex], function(i, name){
$('#'+name + ",[id^='"+name+"-'],label[for='"+name+"']").filter('.added').remove();
});
define_list[cindex] = [];
},
/**
* Get information about a #define from configuration file text:
*
* - Pre-examine the #define for its prefix, value position, suffix, etc.
* - Construct RegExp's for the #define to find and replace values.
* - Store the existing #define line as a fast key to finding it later.
* - Determine the line number of the #define
* - Gather nearby comments to be used as tooltips.
* - Look for JSON in nearby comments for use as select options.
*
* define_info[name]
* .type type of define: switch, list, quoted, plain, or toggle
* .size the number of items in a "list" type
* .options select options, if any
* .cindex config index
* .field pre containing the config text (config_list[cindex][0])
* .line the full line from the config text
* .pre any text preceding #define
* .define the "#define NAME" text (may have leading spaces)
* .post the text following the "#define NAME val" part
* .regex regexp to get the value from the line
* .repl regexp to replace the value in the line
* .val_i the value's index in the .regex result
*/
getDefineInfo: function(name, cindex) {
if (cindex === undefined) cindex = 0;
this.log('getDefineInfo:'+name,4);
var $c = config_list[cindex], txt = $c.text(),
info = { type:0, cindex:cindex, field:$c[0], val_i:2 }, post;
// a switch line with no value
var find = new RegExp('^([ \\t]*//)?([ \\t]*#define[ \\t]+' + name + ')([ \\t]*(/[*/].*)?)$', 'm'),
r = find.exec(txt);
if (r !== null) {
post = r[3] == null ? '' : r[3];
$.extend(info, {
type: 'switch',
val_i: 1,
regex: new RegExp('([ \\t]*//)?([ \\t]*' + r[2].regEsc() + post.regEsc() + ')', 'm'),
repl: new RegExp('([ \\t]*)(\/\/)?([ \\t]*' + r[2].regEsc() + post.regEsc() + ')', 'm')
});
}
else {
// a define with curly braces
find = new RegExp('^(.*//)?(.*#define[ \\t]+' + name + '[ \\t]+)(\{[^\}]*\})([ \\t]*(/[*/].*)?)$', 'm');
r = find.exec(txt);
if (r !== null) {
post = r[4] == null ? '' : r[4];
$.extend(info, {
type: 'list',
size: r[3].split(',').length,
regex: new RegExp('([ \\t]*//)?[ \\t]*' + r[2].regEsc() + '\{([^\}]*)\}' + post.regEsc(), 'm'),
repl: new RegExp('(([ \\t]*//)?[ \\t]*' + r[2].regEsc() + '\{)[^\}]*(\}' + post.regEsc() + ')', 'm')
});
}
else {
// a define with quotes
find = new RegExp('^(.*//)?(.*#define[ \\t]+' + name + '[ \\t]+)("[^"]*")([ \\t]*(/[*/].*)?)$', 'm');
r = find.exec(txt);
if (r !== null) {
post = r[4] == null ? '' : r[4];
$.extend(info, {
type: 'quoted',
regex: new RegExp('([ \\t]*//)?[ \\t]*' + r[2].regEsc() + '"([^"]*)"' + post.regEsc(), 'm'),
repl: new RegExp('(([ \\t]*//)?[ \\t]*' + r[2].regEsc() + '")[^"]*("' + post.regEsc() + ')', 'm')
});
}
else {
// a define with no quotes
find = new RegExp('^([ \\t]*//)?([ \\t]*#define[ \\t]+' + name + '[ \\t]+)(\\S*)([ \\t]*(/[*/].*)?)$', 'm');
r = find.exec(txt);
if (r !== null) {
post = r[4] == null ? '' : r[4];
$.extend(info, {
type: 'plain',
regex: new RegExp('([ \\t]*//)?[ \\t]*' + r[2].regEsc() + '(\\S*)' + post.regEsc(), 'm'),
repl: new RegExp('(([ \\t]*//)?[ \\t]*' + r[2].regEsc() + ')\\S*(' + post.regEsc() + ')', 'm')
});
if (r[3].match(/false|true/)) {
info.type = 'toggle';
info.options = ['false','true'];
}
}
}
}
}
// Success?
if (info.type) {
$.extend(info, {
line: r[0],
pre: r[1] == null ? '' : r[1].replace('//',''),
define: r[2],
post: post
});
// Get the end-of-line comment, if there is one
var tooltip = '', eoltip = '';
find = new RegExp('.*#define[ \\t].*/[/*]+[ \\t]*(.*)');
if (info.line.search(find) >= 0)
eoltip = tooltip = info.line.replace(find, '$1');
// Get all the comments immediately before the item
var s;
find = new RegExp('(([ \\t]*(//|#)[^\n]+\n){1,4})' + info.line.regEsc(), 'g');
if (r = find.exec(txt)) {
// Get the text of the found comments
find = new RegExp('^[ \\t]*//+[ \\t]*(.*)[ \\t]*$', 'gm');
while((s = find.exec(r[1])) !== null) {
var tip = s[1].replace(/[ \\t]*(={5,}|(#define[ \\t]+.*|@section[ \\t]+\w+))[ \\t]*/g, '');
if (tip.length) {
if (tip.match(/^#define[ \\t]/) != null) tooltip = eoltip;
// JSON data? Save as select options
if (!info.options && tip.match(/:[\[{]/) != null) {
// TODO
// :[1-6] = value limits
var o; eval('o=' + tip.substr(1));
info.options = o;
if (Object.prototype.toString.call(o) == "[object Array]" && o.length == 2 && !eval(''+o[0]))
info.type = 'toggle';
}
else {
// Other lines added to the tooltip
tooltip += ' ' + tip + '\n';
}
}
}
}
// Add .tooltip and .lineNum properties to the info
find = new RegExp('^'+name); // Strip the name from the tooltip
var lineNum = this.getLineNumberOfText(info.line, txt);
// See if this define is enabled conditionally
var enable_cond = '';
$.each(dependent_groups, function(cond,dat){
$.each(dat, function(i,o){
if (o.cindex == cindex && lineNum > o.start && lineNum < o.end) {
if (enable_cond != '') enable_cond += ' && ';
enable_cond += '(' + cond + ')';
}
});
});
$.extend(info, {
tooltip: '<strong>'+name+'</strong> '+tooltip.trim().replace(find,'').toHTML(),
lineNum: lineNum,
switchable: (info.type != 'switch' && info.line.match(/^[ \t]*\/\//)) || false, // Disabled? Mark as "switchable"
enabled: enable_cond ? enable_cond : 'true'
});
}
else
info = null;
this.log(info, 2);
return info;
},
/**
* Count the number of lines before a match, return -1 on fail
*/
getLineNumberOfText: function(line, txt) {
var pos = txt.indexOf(line);
return (pos < 0) ? pos : txt.lineCount(pos);
},
/**
* Add a temporary message to the page
*/
setMessage: function(msg,type) {
if (msg) {
if (type === undefined) type = 'message';
var $err = $('<p class="'+type+'">'+msg+'<span>x</span></p>').appendTo($msgbox), err = $err[0];
var baseColor = $err.css('color').replace(/rgba?\(([^),]+,[^),]+,[^),]+).*/, 'rgba($1,');
err.pulse_offset = (pulse_offset += 200);
err.startTime = Date.now() + pulse_offset;
err.pulser = setInterval(function(){
var pulse_time = Date.now() + err.pulse_offset;
var opac = 0.5+Math.sin(pulse_time/200)*0.4;
$err.css({color:baseColor+(opac)+')'});
if (pulse_time - err.startTime > 2500 && opac > 0.899) {
clearInterval(err.pulser);
}
}, 50);
$err.click(function(e) {
$(this).remove();
self.adjustFormLayout();
return false;
}).css({cursor:'pointer'});
}
else {
$msgbox.find('p.error, p.warning').each(function() {
if (this.pulser !== undefined && this.pulser)
clearInterval(this.pulser);
$(this).remove();
});
}
self.adjustFormLayout();
},
adjustFormLayout: function() {
var wtop = $(window).scrollTop(),
ctop = $cfg.offset().top,
thresh = $form.offset().top+100;
if (ctop < thresh) {
var maxhi = $form.height(); // pad plus heights of config boxes can't be more than this
var pad = wtop > ctop ? wtop-ctop : 0; // pad the top box to stay in view
var innerpad = Math.ceil($cfg.height() - $cfg.find('pre').height());
// height to use for the inner boxes
var hi = ($(window).height() - ($cfg.offset().top - pad) + wtop - innerpad)/2;
if (hi < 200) hi = 200;
$cfg.css({ paddingTop: pad });
var $pre = $('pre.config');
$pre.css({ height: Math.floor(hi) - $pre.position().top });
}
else {
$cfg.css({ paddingTop: wtop > ctop ? wtop-ctop : 0, height: '' });
}
},
setRequestError: function(stat, path) {
self.setMessage('Error '+stat+' ' + path.replace(/^(https:\/\/[^\/]+\/)?.+(\/[^\/]+)$/, '$1...$2'), 'error');
},
log: function(o,l) {
if (l === undefined) l = 0;
if (this.logging>=l*1) console.log(o);
},
logOnce: function(o) {
if (o.didLogThisObject === undefined) {
this.log(o);
o.didLogThisObject = true;
}
},
EOF: null
};
})();
// Typically the app would be in its own file, but this would be here
window.configuratorApp.init();
});

@ -0,0 +1,524 @@
/*!
jCanvas v2.2.1
Caleb Evans
2.2.1 revisions by Thinkyhead
*/
(function($, document, Math, Number, undefined) {
// jC global object
var jC = {};
jC.originals = {
width: 20,
height: 20,
cornerRadius: 0,
fillStyle: 'transparent',
strokeStyle: 'transparent',
strokeWidth: 5,
strokeCap: 'butt',
strokeJoin: 'miter',
shadowX: 0,
shadowY: 0,
shadowBlur: 10,
shadowColor: 'transparent',
x: 0, y: 0,
x1: 0, y1: 0,
radius: 10,
start: 0,
end: 360,
ccw: false,
inDegrees: true,
fromCenter: true,
closed: false,
sides: 3,
angle: 0,
text: '',
font: 'normal 12pt sans-serif',
align: 'center',
baseline: 'middle',
source: '',
repeat: 'repeat'
};
// Duplicate original defaults
jC.defaults = $.extend({}, jC.originals);
// Set global properties
function setGlobals(context, map) {
context.fillStyle = map.fillStyle;
context.strokeStyle = map.strokeStyle;
context.lineWidth = map.strokeWidth;
context.lineCap = map.strokeCap;
context.lineJoin = map.strokeJoin;
context.shadowOffsetX = map.shadowX;
context.shadowOffsetY = map.shadowY;
context.shadowBlur = map.shadowBlur;
context.shadowColor = map.shadowColor;
}
// Close path if chosen
function closePath(context, map) {
if (map.closed === true) {
context.closePath();
context.fill();
context.stroke();
} else {
context.fill();
context.stroke();
context.closePath();
}
}
// Measure angles in degrees if chosen
function checkUnits(map) {
if (map.inDegrees === true) {
return Math.PI / 180;
} else {
return 1;
}
}
// Set canvas defaults
$.fn.canvas = function(args) {
// Reset defaults if no value is passed
if (typeof args === 'undefined') {
jC.defaults = jC.originals;
} else {
jC.defaults = $.extend({}, jC.defaults, args);
}
return this;
};
// Load canvas
$.fn.loadCanvas = function(context) {
if (typeof context === 'undefined') {context = '2d';}
return this[0].getContext(context);
};
// Create gradient
$.fn.gradient = function(args) {
var ctx = this.loadCanvas(),
// Specify custom defaults
gDefaults = {
x1: 0, y1: 0,
x2: 0, y2: 0,
r1: 10, r2: 100
},
params = $.extend({}, gDefaults, args),
gradient, stops = 0, percent, i;
// Create radial gradient if chosen
if (typeof args.r1 === 'undefined' && typeof args.r2 === 'undefined') {
gradient = ctx.createLinearGradient(params.x1, params.y1, params.x2, params.y2);
} else {
gradient = ctx.createRadialGradient(params.x1, params.y1, params.r1, params.x2, params.y2, params.r2);
}
// Count number of color stops
for (i=1; i<=Number.MAX_VALUE; i+=1) {
if (params['c' + i]) {
stops += 1;
} else {
break;
}
}
// Calculate color stop percentages if absent
for (i=1; i<=stops; i+=1) {
percent = Math.round((100 / (stops-1)) * (i-1)) / 100;
if (typeof params['s' + i] === 'undefined') {
params['s' + i] = percent;
}
gradient.addColorStop(params['s' + i], params['c' + i]);
}
return gradient;
};
// Create pattern
$.fn.pattern = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
pattern,
img = document.createElement('img');
img.src = params.source;
// Create pattern
function create() {
if (img.complete === true) {
// Create pattern
pattern = ctx.createPattern(img, params.repeat);
} else {
throw "The pattern has not loaded yet";
}
}
try {
create();
} catch(error) {
img.onload = create;
}
return pattern;
};
// Clear canvas
$.fn.clearCanvas = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args);
// Draw from center if chosen
if (params.fromCenter === true) {
params.x -= params.width / 2;
params.y -= params.height / 2;
}
// Clear entire canvas if chosen
ctx.beginPath();
if (typeof args === 'undefined') {
ctx.clearRect(0, 0, this.width(), this.height());
} else {
ctx.clearRect(params.x, params.y, params.width, params.height);
}
ctx.closePath();
return this;
};
// Save canvas
$.fn.saveCanvas = function() {
var ctx = this.loadCanvas();
ctx.save();
return this;
};
// Restore canvas
$.fn.restoreCanvas = function() {
var ctx = this.loadCanvas();
ctx.restore();
return this;
};
// Scale canvas
$.fn.scaleCanvas = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args);
ctx.save();
ctx.translate(params.x, params.y);
ctx.scale(params.width, params.height);
ctx.translate(-params.x, -params.y)
return this;
};
// Translate canvas
$.fn.translateCanvas = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args);
ctx.save();
ctx.translate(params.x, params.y);
return this;
};
// Rotate canvas
$.fn.rotateCanvas = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
toRad = checkUnits(params);
ctx.save();
ctx.translate(params.x, params.y);
ctx.rotate(params.angle * toRad);
ctx.translate(-params.x, -params.y);
return this;
};
// Draw rectangle
$.fn.drawRect = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
toRad = checkUnits(params),
x1, y1, x2, y2, r;
setGlobals(ctx, params);
// Draw from center if chosen
if (params.fromCenter === true) {
params.x -= params.width / 2;
params.y -= params.height / 2;
}
// Draw rounded rectangle if chosen
if (params.cornerRadius > 0) {
x1 = params.x;
y1 = params.y;
x2 = params.x + params.width;
y2 = params.y + params.height;
r = params.cornerRadius;
if ((x2 - x1) - (2 * r) < 0) {
r = (x2 - x1) / 2;
}
if ((y2 - y1) - (2 * r) < 0) {
r = (y2 - y1) / 2;
}
ctx.beginPath();
ctx.moveTo(x1+r,y1);
ctx.lineTo(x2-r,y1);
ctx.arc(x2-r, y1+r, r, 270*toRad, 360*toRad, false);
ctx.lineTo(x2,y2-r);
ctx.arc(x2-r, y2-r, r, 0, 90*toRad, false);
ctx.lineTo(x1+r,y2);
ctx.arc(x1+r, y2-r, r, 90*toRad, 180*toRad, false);
ctx.lineTo(x1,y1+r);
ctx.arc(x1+r, y1+r, r, 180*toRad, 270*toRad, false);
ctx.fill();
ctx.stroke();
ctx.closePath();
} else {
ctx.fillRect(params.x, params.y, params.width, params.height);
ctx.strokeRect(params.x, params.y, params.width, params.height);
}
return this;
};
// Draw arc
$.fn.drawArc = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
toRad = checkUnits(params);
setGlobals(ctx, params);
// Draw from center if chosen
if (params.fromCenter === false) {
params.x += params.radius;
params.y += params.radius;
}
ctx.beginPath();
ctx.arc(params.x, params.y, params.radius, (params.start*toRad)-(Math.PI/2), (params.end*toRad)-(Math.PI/2), params.ccw);
// Close path if chosen
closePath(ctx, params);
return this;
};
// Draw ellipse
$.fn.drawEllipse = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
controlW = params.width * (4/3);
setGlobals(ctx, params);
// Draw from center if chosen
if (params.fromCenter === false) {
params.x += params.width / 2;
params.y += params.height / 2;
}
// Increment coordinates to prevent negative values
params.x += 1e-10;
params.y += 1e-10;
// Create ellipse
ctx.beginPath();
ctx.moveTo(params.x, params.y-params.height/2);
ctx.bezierCurveTo(params.x-controlW/2,params.y-params.height/2,
params.x-controlW/2,params.y+params.height/2,
params.x,params.y+params.height/2);
ctx.bezierCurveTo(params.x+controlW/2,params.y+params.height/2,
params.x+controlW/2,params.y-params.height/2,
params.x,params.y-params.height/2);
ctx.closePath();
ctx.fill();
ctx.stroke();
return this;
};
// Draw line
$.fn.drawLine = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
max = Number.MAX_VALUE, l,
lx, ly;
setGlobals(ctx, params);
// Draw each point
ctx.beginPath();
ctx.moveTo(params.x1, params.y1);
for (l=2; l<max; l+=1) {
lx = params['x' + l];
ly = params['y' + l];
// Stop loop when all points are drawn
if (typeof lx === 'undefined' || typeof ly === 'undefined') {
break;
}
ctx.lineTo(lx, ly);
}
// Close path if chosen
closePath(ctx, params);
return this;
};
// Draw quadratic curve
$.fn.drawQuad = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
max = Number.MAX_VALUE, l,
lx, ly, lcx, lcy;
setGlobals(ctx, params);
// Draw each point
ctx.beginPath();
ctx.moveTo(params.x1, params.y1);
for (l=2; l<max; l+=1) {
lx = params['x' + l];
if (typeof lx === 'undefined') break;
ly = params['y' + l];
if (typeof ly === 'undefined') break;
lcx = params['cx' + (l-1)];
if (typeof lcx === 'undefined') break;
lcy = params['cy' + (l-1)];
if (typeof lcy === 'undefined') break;
ctx.quadraticCurveTo(lcx, lcy, lx, ly);
}
// Close path if chosen
closePath(ctx, params);
return this;
};
// Draw Bezier curve
$.fn.drawBezier = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
max = Number.MAX_VALUE,
l=2, lc=1, lx, ly, lcx1, lcy1, lcx2, lcy2, i;
setGlobals(ctx, params);
// Draw each point
ctx.beginPath();
ctx.moveTo(params.x1, params.y1);
for (i=2; i<max; i+=1) {
lx = params['x' + l];
if (typeof lx === 'undefined') break;
ly = params['y' + l];
if (typeof ly === 'undefined') break;
lcx1 = params['cx' + lc];
if (typeof lcx1 === 'undefined') break;
lcy1 = params['cy' + lc];
if (typeof lcy1 === 'undefined') break;
lcx2 = params['cx' + (lc+1)];
if (typeof lcx2 === 'undefined') break;
lcy2 = params['cy' + (lc+1)];
if (typeof lcy2 === 'undefined') break;
ctx.bezierCurveTo(lcx1, lcy1, lcx2, lcy2, lx, ly);
l += 1;
lc += 2;
}
// Close path if chosen
closePath(ctx, params);
return this;
};
// Draw text
$.fn.drawText = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args);
setGlobals(ctx, params);
// Set text-specific properties
ctx.textBaseline = params.baseline;
ctx.textAlign = params.align;
ctx.font = params.font;
ctx.strokeText(params.text, params.x, params.y);
ctx.fillText(params.text, params.x, params.y);
return this;
};
// Draw image
$.fn.drawImage = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
// Define image source
img = document.createElement('img');
img.src = params.source;
setGlobals(ctx, params);
// Draw image function
function draw() {
if (img.complete) {
var scaleFac = img.width / img.height;
// If width/height are specified
if (typeof args.width !== 'undefined' && typeof args.height !== 'undefined') {
img.width = args.width;
img.height = args.height;
// If width is specified
} else if (typeof args.width !== 'undefined' && typeof args.height === 'undefined') {
img.width = args.width;
img.height = img.width / scaleFac;
// If height is specified
} else if (typeof args.width === 'undefined' && typeof args.height !== 'undefined') {
img.height = args.height;
img.width = img.height * scaleFac;
}
// Draw from center if chosen
if (params.fromCenter === true) {
params.x -= img.width / 2;
params.y -= img.height / 2;
}
// Draw image
ctx.drawImage(img, params.x, params.y, img.width, img.height);
} else {
throw "The image has not loaded yet.";
}
}
function dodraw() {
// console.log("dodraw...");
try {
// console.log("dodraw...try...");
draw();
}
catch(error) {
// console.log("dodraw...catch: " + error);
}
}
// Draw image if already loaded
// console.log("--------------------");
// console.log("drawImage " + img.src);
try {
// console.log("try...");
draw();
} catch(error) {
// console.log("catch: " + error);
img.onload = dodraw;
}
return this;
};
// Draw polygon
$.fn.drawPolygon = function(args) {
var ctx = this.loadCanvas(),
params = $.extend({}, jC.defaults, args),
theta, dtheta, x, y,
toRad = checkUnits(params), i;
setGlobals(ctx, params);
if (params.sides >= 3) {
// Calculate points and draw
theta = (Math.PI/2) + (Math.PI/params.sides) + (params.angle*toRad);
dtheta = (Math.PI*2) / params.sides;
for (i=0; i<params.sides; i+=1) {
x = params.x + (params.radius * Math.cos(theta)) + 1e-10;
y = params.y + (params.radius * Math.sin(theta)) + 1e-10;
if (params.fromCenter === false) {
x += params.radius;
y += params.radius;
}
ctx.lineTo(x, y);
theta += dtheta;
}
closePath(ctx, params);
}
return this;
};
return window.jCanvas = jC;
}(jQuery, document, Math, Number));

File diff suppressed because one or more lines are too long

@ -0,0 +1,220 @@
/*!
* jQuery "stepper" Plugin
* version 0.0.1
* @requires jQuery v1.3.2 or later
* @requires jCanvas
*
* Authored 2011-06-11 Scott Lahteine (thinkyhead.com)
*
* A very simple numerical stepper.
* TODO: place arrows based on div size, make 50/50 width
*
* Usage example:
*
* $('#mydiv').jstepper({
* min: 1,
* max: 4,
* val: 1,
* arrowWidth: 15,
* arrowHeight: '22px',
* color: '#FFF',
* acolor: '#F70',
* hcolor: '#FF0',
* id: 'select-me',
* stepperClass: 'inner',
* textStyle: {width:'1.5em',fontSize:'20px',textAlign:'center'},
* onChange: function(v) { },
* });
*
*/
;(function($) {
var un = 'undefined';
$.jstepperArrows = [
{ name:'prev', poly:[[1.0,0],[0,0.5],[1.0,1.0]] },
{ name:'next', poly:[[0,0],[1.0,0.5],[0,1.0]] }
];
$.fn.jstepper = function(args) {
return this.each(function() {
var defaults = {
min: 1,
max: null,
val: null,
active: true,
placeholder: null,
arrowWidth: 0,
arrowHeight: 0,
color: '#FFF',
hcolor: '#FF0',
acolor: '#F80',
id: '',
stepperClass: '',
textStyle: '',
onChange: (function(v){ if (typeof console.log !== 'undefined') console.log("val="+v); })
};
args = $.extend(defaults, args || {});
var min = args.min * 1,
max = (args.max !== null) ? args.max * 1 : min,
span = max - min + 1,
val = (args.val !== null) ? args.val * 1 : min,
active = !args.disabled,
placeholder = args.placeholder,
arrowWidth = 1 * args.arrowWidth.toString().replace(/px/,''),
arrowHeight = 1 * args.arrowHeight.toString().replace(/px/,''),
color = args.color,
hcolor = args.hcolor,
acolor = args.acolor,
$prev = $('<a href="#prev" style="cursor:w-resize;"><canvas/></a>'),
$marq = $('<div class="number"/>').css({float:'left',textAlign:'center'}),
$next = $('<a href="#next" style="cursor:e-resize;"><canvas/></a>'),
arrow = [ $prev.find('canvas')[0], $next.find('canvas')[0] ],
$stepper = $('<span class="jstepper"/>').append($prev).append($marq).append($next).append('<div style="clear:both;"/>'),
onChange = args.onChange;
if (args.id) $stepper[0].id = args.id;
if (args.stepperClass) $stepper.addClass(args.stepperClass);
if (args.textStyle) $marq.css(args.textStyle);
// replace a span, but embed elsewhere
if (this.tagName == 'SPAN') {
var previd = this.id;
$(this).replaceWith($stepper);
if (previd) $stepper.attr('id',previd);
}
else {
$(this).append($stepper);
}
// hook to call functions on this object
$stepper[0].ui = {
refresh: function() {
this.updateNumber();
this._drawArrow(0, 1);
this._drawArrow(1, 1);
return this;
},
_drawArrow: function(i,state) {
var $elm = $(arrow[i]),
desc = $.jstepperArrows[i],
fillStyle = (state == 2) ? hcolor : (state == 3) ? acolor : color,
draw = { fillStyle: fillStyle },
w = $elm.width(), h = $elm.height();
if (w <= 0) w = $elm.attr('width');
if (h <= 0) h = $elm.attr('height');
$.each(desc.poly,function(i,v){
++i;
draw['x'+i] = v[0] * w;
draw['y'+i] = v[1] * h;
});
$elm.restoreCanvas().clearCanvas().drawLine(draw);
},
updateNumber: function() {
$marq.html((active || placeholder === null) ? val.toString() : placeholder);
return this;
},
_doclick: function(i) {
this.add(i ? 1 : -1);
this._drawArrow(i, 3);
var self = this;
setTimeout(function(){ self._drawArrow(i, 2); }, 50);
},
add: function(x) {
val = (((val - min) + x + span) % span) + min;
this.updateNumber();
this.didChange(val);
return this;
},
min: function(v) {
if (typeof v === un) return min;
this.setRange(v,max);
return this;
},
max: function(v) {
if (typeof v === un) return max;
this.setRange(min,v);
return this;
},
val: function(v) {
if (typeof v === un) return val;
val = (((v - min) + span) % span) + min;
this.updateNumber();
return this;
},
setRange: function(lo, hi, ini) {
if (lo > hi) hi = (lo += hi -= lo) - hi;
min = lo; max = hi; span = hi - lo + 1;
if (typeof ini !== un) val = ini;
if (val < min) val = min;
if (val > max) val = max;
this.updateNumber();
return this;
},
active: function(a) {
if (typeof a === un) return active;
(active = a) ? $marq.removeClass('inactive') : $marq.addClass('inactive');
this.updateNumber();
return this;
},
disable: function() { this.active(false); return this; },
enable: function() { this.active(true); return this; },
clearPlaceholder: function() {
this.setPlaceholder(null);
return this;
},
setPlaceholder: function(p) {
placeholder = p;
if (!active) this.updateNumber();
return this;
},
didChange: onChange
};
// set hover and click for each arrow
$.each($.jstepperArrows, function(i,desc) {
var $elm = $(arrow[i]),
w = arrowWidth ? arrowWidth : $elm.width() ? $elm.width() : 15,
h = arrowHeight ? arrowHeight : $elm.height() ? $elm.height() : 24;
$elm[0]._index = i;
$elm
.css({float:'left'})
.attr({width:w,height:h,'class':desc.name})
.hover(
function(e) { $stepper[0].ui._drawArrow(e.target._index, 2); },
function(e) { $stepper[0].ui._drawArrow(e.target._index, 1); }
)
.click(function(e){
$stepper[0].ui._doclick(e.target._index);
return false;
});
});
// init the visuals first time
$stepper[0].ui.refresh();
}); // this.each
}; // $.fn.jstepper
})( jQuery );

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save