diff --git a/_locales/en/messages.json b/_locales/en/messages.json old mode 100755 new mode 100644 index f8ed4ab9..b8e1ecf7 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -73,6 +73,9 @@ "tabSetup": { "message": "Setup" }, + "tabSetupOSD": { + "message": "OSD Setup" + }, "tabConfiguration": { "message": "Configuration" }, @@ -100,6 +103,9 @@ "tabOsd": { "message": "OSD" }, + "tabPower": { + "message": "Power & Battery" + }, "tabGPS": { "message": "GPS" }, @@ -161,10 +167,13 @@ "message": "No configuration received within 10 seconds, communication failed" }, "firmwareVersionNotSupported": { - "message": "This firmware version is not supported. Please upgrade to firmware that supports api version $1 or higher. Use CLI for backup before flashing. CLI backup/restore procedure is in the documention." + "message": "This firmware version is not supported. Please upgrade to firmware that supports api version $1 or higher. Use CLI for backup before flashing. CLI backup/restore procedure is in the documention.
Alternatively download and use an old version of the configurator if you are not ready to upgrade." }, "firmwareTypeNotSupported": { - "message": "Non - Betaflight firmware is not supported. Please note that this tool is designed to support the advanced features of the Betaflight firmware, and does not support use with other types of firmware, except for in CLI mode." + "message": "Non - Cleanflight/Betaflight firmware is not supported, except for CLI mode." + }, + "firmwareUpgradeRequired": { + "message": "The firmware on this device needs upgrading to a newer version. Use CLI for backup before flashing. CLI backup/restore procedure is in the documention.
Alternatively download and use an old version of the configurator if you are not ready to upgrade." }, "tabSwitchConnectionRequired": { @@ -556,6 +565,9 @@ "featureOSD": { "message": "On Screen Display" }, + "featureVTX": { + "message": "Video Transmitter" + }, "featureFAILSAFE": { "message": "Enable Failsafe Stage 2" }, @@ -667,44 +679,8 @@ "configurationThrottleMinimumCommandHelp": { "message": "This is the value that is sent to the ESCs when the craft is disarmed. Set this to a value that has the motors stopped (1000 for most ESCs)." }, - "configurationBatteryVoltage": { - "message": "Battery Voltage" - }, - "configurationBatteryCurrent": { - "message": "Battery Current" - }, - "configurationBatteryMeterType": { - "message": "Battery Meter Type" - }, - "configurationBatteryMinimum": { - "message": "Minimum Cell Voltage" - }, - "configurationBatteryMaximum": { - "message": "Maximum Cell Voltage" - }, - "configurationBatteryWarning": { - "message": "Warning Cell Voltage" - }, - "configurationBatteryScale": { - "message": "Voltage Scale" - }, - "configurationCurrentMeterType": { - "message": "Current Meter Type" - }, - "configurationCurrent": { - "message": "Current Sensor" - }, - "configurationCurrentScale": { - "message": "Scale the output voltage to milliamps [1/10th mV/A]" - }, - "configurationCurrentOffset": { - "message": "Offset in millivolt steps" - }, - "configurationBatteryMultiwiiCurrent": { - "message": "Enable support for legacy Multiwii MSP current output" - }, "configuration3d": { - "message": "3D" + "message": "3D ESC/Motor Features" }, "configuration3dDeadbandLow": { "message": "3D Deadband Low" @@ -742,6 +718,12 @@ "configurationGPSubxSbas": { "message": "Ground Assistance Type" }, + "configurationGPSAutoBaud": { + "message": "Auto Baud" + }, + "configurationGPSAutoConfig": { + "message": "Auto Config" + }, "configurationGPSHelp": { "message": "Note: Remember to configure a Serial Port (via Ports tab) when using GPS feature." }, @@ -756,10 +738,10 @@ }, "portsIdentifier": { - "message": "Port Identifier" + "message": "Identifier" }, "portsConfiguration": { - "message": "Configuration" + "message": "Configuration/MSP" }, "portsSerialRx": { "message": "Serial Rx" @@ -812,6 +794,18 @@ "portsFunction_TELEMETRY_SMARTPORT": { "message": "SmartPort" }, + "portsFunction_TELEMETRY_IBUS": { + "message": "iBUS" + }, + "portsFunction_TELEMETRY_JETIXBUS": { + "message": "JETIXBUS" + }, + "portsFunction_TELEMETRY_CRSF": { + "message": "CRSF" + }, + "portsFunction_TELEMETRY_SRXL": { + "message": "SRXL" + }, "portsFunction_ESC_SENSOR": { "message": "ESC" }, @@ -827,9 +821,6 @@ "portsFunction_IRC_TRAMP": { "message": "IRC Tramp" }, - "portsFunction_TELEMETRY_IBUS": { - "message": "iBUS Telemetry" - }, "pidTuningUpgradeFirmwareToChangePidController": { "message": "Changing PID controller disabled - you can change it via the CLI. You have firmware with API version $1, but this functionality requires requires $2." }, @@ -860,9 +851,6 @@ "receiverRcInterpolationIntervalHelp": { "message": "Interpolation interval for manual RC interpolation mode in milliseconds" }, - "receiverRcInterpolation": { - "message": "RC Interpolation" - }, "receiverRcInterpolationOff": { "message": "Off" }, @@ -984,11 +972,23 @@ "receiverThrottleExpo": { "message": "Throttle EXPO" }, - "receiverMidRc": { - "message": "Center value for RC channels" + "receiverStickMin": { + "message": "Stick Min" }, - "receiverMidRcHelp": { - "message": "This is the center value for all RC channels. Set this to the value that your transmitter sends when the stick is centered for a channel. To adjust the thrust at throttle mid position, change the 'Trottle MID' value on the PID Tuning tab." + "receiverHelpStickMin": { + "message": "The value (in us) used to determine if a stick is low." + }, + "receiverStickCenter": { + "message": "Stick Center" + }, + "receiverHelpStickCenter": { + "message": "The value (in us) used to determine if a stick is centered." + }, + "receiverStickMax": { + "message": "Stick Max" + }, + "receiverHelpStickMax": { + "message": "The value (in us) used to determine if a stick is high." }, "receiverDeadband": { "message": "RC Deadband" @@ -996,12 +996,18 @@ "receiverHelpDeadband": { "message": "These are values (in us) by how much RC input can be different before it's considered valid. For transmitters with jitter on outputs, this value can be increased if rc inputs twitch while idle." }, - "receiverHelpYawDeadband": { - "message": "These are values (in us) by how much RC input can be different before it's considered valid. For transmitters with jitter on outputs, this value can be increased if rc inputs twitch while idle. This setting is for Yaw only." - }, "receiverYawDeadband": { "message": "Yaw Deadband" }, + "receiverHelpYawDeadband": { + "message": "These are values (in us) by how much RC input can be different before it's considered valid. For transmitters with jitter on outputs, this value can be increased if rc inputs twitch while idle. This setting is for Yaw only." + }, + "recevier3dDeadbandThrottle": { + "message": "3D Throttle Deadband" + }, + "receiverHelp3dDeadbandThrottle": { + "message": "These are values (in us). To widen the neutral zone increased the value. This setting is for 3D throttle only." + }, "receiverChannelMap": { "message": "Channel Map" }, @@ -1185,24 +1191,48 @@ "transponderNotSupported": { "message": "Your flight controller's firmware does not support transponder functionality." }, - "transponderHelp": { - "message": "Configure your transponder code here. Note: Only valid codes will be recognised by race timing systems. Valid transponder codes can be obtained from Seriously Pro." - }, "transponderInformation": { "message": "Transponders systems allow race organizers to time your laps. The transponder is fitted to your aircraft and when your aircraft passes the timing gate the track-side receiver registers your code and records your laptime. When fitting an IR based transponder your should ensure that it points outward from your aircraft towards the track-side receivers and that the light beam is not obstructed by your airframe, battery-straps, cables, propellers, etc." }, - "transponderConfiguration": { - "message": "Configuration" + "transponderConfigurationType": { + "message": "Transponder type" }, - "transponderData": { + "transponderType0": { + "message": "None" + }, + "transponderType1": { + "message": "iLap" + }, + "transponderType2": { + "message": "aRCiTimer" + }, + "transponderConfiguration1": { + "message": "Configuration iLap" + }, + "transponderConfiguration2": { + "message": "Configuration aRCiTimer" + }, + "transponderData1": { "message": "Data" }, - "transponderDataHelp": { + "transponderData2": { + "message": "Transponder ID" + }, + "transponderDataHelp1": { "message": "Hexadecimal digits only, 0-9, A-F" }, + "transponderHelp1": { + "message": "Configure your transponder code here. Note: Only valid codes will be recognised by race timing systems. Valid transponder codes can be obtained from Seriously Pro." + }, + "transponderHelp2": { + "message": "For more information please visit aRCiTimer site" + }, "transponderButtonSave": { "message": "Save" }, + "transponderButtonSaveReboot": { + "message": "Save and Reboot" + }, "transponderDataInvalid": { "message": "Transponder data is invalid" }, @@ -1258,6 +1288,12 @@ "motorsGyroscopeReset": { "message": "[Reset]" }, + "motorsGyroscope": { + "message": "Gyroscope - " + }, + "motorsGyroscopeReset": { + "message": "[Reset]" + }, "gpsHead": { "message": "GPS" }, @@ -1861,6 +1897,226 @@ "failsafeKillSwitchHelp": { "message": "Set this option to make the failsafe switch, configured in the modes tab, act as a direct kill switch, bypassing the selected failsafe procedure. Note: Arming is blocked with the failsafe kill switch in the ON position" }, + + "powerButtonSave": { + "message": "Save" + }, + "powerFirmwareUpgradeRequired": { + "message": "Firmware upgrade required. Battery/Amperage/Voltage configurations using API < 1.22.0 is not supported." + }, + "powerBatteryVoltageMeterSource": { + "message": "Voltage Meter Source" + }, + "powerBatteryCurrentMeterSource": { + "message": "Current Meter Source" + }, + "powerBatteryMinimum": { + "message": "Minimum Cell Voltage" + }, + "powerBatteryMaximum": { + "message": "Maximum Cell Voltage" + }, + "powerBatteryWarning": { + "message": "Warning Cell Voltage" + }, + "powerVoltageHead": { + "message": "Voltage" + }, + "powerVoltageValue": { + "message": "$1 V" + }, + "powerAmperageValue": { + "message": "$1 A" + }, + "powerVoltageId10": { + "message": "Battery" + }, + "powerVoltageId20": { + "message": "5V" + }, + "powerVoltageId30": { + "message": "9V" + }, + "powerVoltageId40": { + "message": "12V" + }, + "powerVoltageId50": { + "message": "ESC Combined" + }, + "powerVoltageId60": { + "message": "ESC Motor 1" + }, + "powerVoltageId61": { + "message": "ESC Motor 2" + }, + "powerVoltageId62": { + "message": "ESC Motor 3" + }, + "powerVoltageId63": { + "message": "ESC Motor 4" + }, + "powerVoltageId64": { + "message": "ESC Motor 5" + }, + "powerVoltageId65": { + "message": "ESC Motor 6" + }, + "powerVoltageId66": { + "message": "ESC Motor 7" + }, + "powerVoltageId67": { + "message": "ESC Motor 8" + }, + "powerVoltageId68": { + "message": "ESC Motor 9" + }, + "powerVoltageId69": { + "message": "ESC Motor 10" + }, + "powerVoltageId70": { + "message": "ESC Motor 11" + }, + "powerVoltageId71": { + "message": "ESC Motor 12" + }, + "powerVoltageId80": { + "message": "Cell 1" + }, + "powerVoltageId81": { + "message": "Cell 2" + }, + "powerVoltageId82": { + "message": "Cell 3" + }, + "powerVoltageId83": { + "message": "Cell 4" + }, + "powerVoltageId84": { + "message": "Cell 5" + }, + "powerVoltageId85": { + "message": "Cell 6" + }, + + + "powerVoltageScale": { + "message": "Scale" + }, + "powerVoltageDivider": { + "message": "Divider Value" + }, + "powerVoltageMultiplier": { + "message": "Multiplier Value" + }, + + "powerAmperageHead": { + "message": "Amperage" + }, + "powerAmperageId10": { + "message": "Battery" + }, + "powerAmperageId50": { + "message": "ESC Combined" + }, + "powerAmperageId60": { + "message": "ESC Motor 1" + }, + "powerAmperageId61": { + "message": "ESC Motor 2" + }, + "powerAmperageId62": { + "message": "ESC Motor 3" + }, + "powerAmperageId63": { + "message": "ESC Motor 4" + }, + "powerAmperageId64": { + "message": "ESC Motor 5" + }, + "powerAmperageId65": { + "message": "ESC Motor 6" + }, + "powerAmperageId66": { + "message": "ESC Motor 7" + }, + "powerAmperageId67": { + "message": "ESC Motor 8" + }, + "powerAmperageId68": { + "message": "ESC Motor 9" + }, + "powerAmperageId69": { + "message": "ESC Motor 10" + }, + "powerAmperageId70": { + "message": "ESC Motor 11" + }, + "powerAmperageId71": { + "message": "ESC Motor 12" + }, + "powerAmperageId80": { + "message": "Virtual" + }, + "powerMahValue": { + "message": "$1 mAh" + }, + + "powerAmperageScale": { + "message": "Scale the output voltage to milliamps [1/10th mV/A]" + }, + "powerAmperageOffset": { + "message": "Offset in millivolt steps" + }, + + "powerBatteryHead": { + "message": "Battery" + }, + "powerBatteryConnected": { + "message": "Connected" + }, + "powerBatteryConnectedValueYes": { + "message": "Yes (Cells: $1)" + }, + "powerBatteryConnectedValueNo": { + "message": "No" + }, + "powerBatteryVoltage": { + "message": "Voltage" + }, + "powerBatteryCurrentDrawn": { + "message": "mAh used" + }, + "powerBatteryAmperage": { + "message": "Amperage" + }, + "powerBatteryCapacity": { + "message": "Capacity (mAh)" + }, + + "osdSetupHead": { + "message": "Info" + }, + "osdSetupVideoMode": { + "message": "Video Mode" + }, + "osdSetupCameraConnected": { + "message": "Camera Connected" + }, + "osdSetupCameraConnectedValueYes": { + "message": "Yes" + }, + "osdSetupCameraConnectedValueNo": { + "message": "No" + }, + + "osdSetupResetText": { + "message": "Reset OSD to default" + }, + "osdSetupButtonReset": { + "message": "Reset Settings" + }, + + "mainHelpArmed": { "message": "Motor Arming" }, @@ -1942,10 +2198,13 @@ "pidTuningRatesTip": { "message": "Play with the rates and see how those affect the stick curve" }, - "configurationMisc": { - "message": "Misc" + "configurationCamera": { + "message": "Camera" }, - "configurationVesselName": { + "configurationPersonalization": { + "message": "Personalization" + }, + "craftName": { "message": "Craft name" }, "configurationFpvCamAngleDegrees": { diff --git a/css/font-awesome/css/font-awesome.css b/css/font-awesome/css/font-awesome.css new file mode 100644 index 00000000..ee906a81 --- /dev/null +++ b/css/font-awesome/css/font-awesome.css @@ -0,0 +1,2337 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper-pp:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-resistance:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} +.fa-gitlab:before { + content: "\f296"; +} +.fa-wpbeginner:before { + content: "\f297"; +} +.fa-wpforms:before { + content: "\f298"; +} +.fa-envira:before { + content: "\f299"; +} +.fa-universal-access:before { + content: "\f29a"; +} +.fa-wheelchair-alt:before { + content: "\f29b"; +} +.fa-question-circle-o:before { + content: "\f29c"; +} +.fa-blind:before { + content: "\f29d"; +} +.fa-audio-description:before { + content: "\f29e"; +} +.fa-volume-control-phone:before { + content: "\f2a0"; +} +.fa-braille:before { + content: "\f2a1"; +} +.fa-assistive-listening-systems:before { + content: "\f2a2"; +} +.fa-asl-interpreting:before, +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; +} +.fa-deafness:before, +.fa-hard-of-hearing:before, +.fa-deaf:before { + content: "\f2a4"; +} +.fa-glide:before { + content: "\f2a5"; +} +.fa-glide-g:before { + content: "\f2a6"; +} +.fa-signing:before, +.fa-sign-language:before { + content: "\f2a7"; +} +.fa-low-vision:before { + content: "\f2a8"; +} +.fa-viadeo:before { + content: "\f2a9"; +} +.fa-viadeo-square:before { + content: "\f2aa"; +} +.fa-snapchat:before { + content: "\f2ab"; +} +.fa-snapchat-ghost:before { + content: "\f2ac"; +} +.fa-snapchat-square:before { + content: "\f2ad"; +} +.fa-pied-piper:before { + content: "\f2ae"; +} +.fa-first-order:before { + content: "\f2b0"; +} +.fa-yoast:before { + content: "\f2b1"; +} +.fa-themeisle:before { + content: "\f2b2"; +} +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3"; +} +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4"; +} +.fa-handshake-o:before { + content: "\f2b5"; +} +.fa-envelope-open:before { + content: "\f2b6"; +} +.fa-envelope-open-o:before { + content: "\f2b7"; +} +.fa-linode:before { + content: "\f2b8"; +} +.fa-address-book:before { + content: "\f2b9"; +} +.fa-address-book-o:before { + content: "\f2ba"; +} +.fa-vcard:before, +.fa-address-card:before { + content: "\f2bb"; +} +.fa-vcard-o:before, +.fa-address-card-o:before { + content: "\f2bc"; +} +.fa-user-circle:before { + content: "\f2bd"; +} +.fa-user-circle-o:before { + content: "\f2be"; +} +.fa-user-o:before { + content: "\f2c0"; +} +.fa-id-badge:before { + content: "\f2c1"; +} +.fa-drivers-license:before, +.fa-id-card:before { + content: "\f2c2"; +} +.fa-drivers-license-o:before, +.fa-id-card-o:before { + content: "\f2c3"; +} +.fa-quora:before { + content: "\f2c4"; +} +.fa-free-code-camp:before { + content: "\f2c5"; +} +.fa-telegram:before { + content: "\f2c6"; +} +.fa-thermometer-4:before, +.fa-thermometer:before, +.fa-thermometer-full:before { + content: "\f2c7"; +} +.fa-thermometer-3:before, +.fa-thermometer-three-quarters:before { + content: "\f2c8"; +} +.fa-thermometer-2:before, +.fa-thermometer-half:before { + content: "\f2c9"; +} +.fa-thermometer-1:before, +.fa-thermometer-quarter:before { + content: "\f2ca"; +} +.fa-thermometer-0:before, +.fa-thermometer-empty:before { + content: "\f2cb"; +} +.fa-shower:before { + content: "\f2cc"; +} +.fa-bathtub:before, +.fa-s15:before, +.fa-bath:before { + content: "\f2cd"; +} +.fa-podcast:before { + content: "\f2ce"; +} +.fa-window-maximize:before { + content: "\f2d0"; +} +.fa-window-minimize:before { + content: "\f2d1"; +} +.fa-window-restore:before { + content: "\f2d2"; +} +.fa-times-rectangle:before, +.fa-window-close:before { + content: "\f2d3"; +} +.fa-times-rectangle-o:before, +.fa-window-close-o:before { + content: "\f2d4"; +} +.fa-bandcamp:before { + content: "\f2d5"; +} +.fa-grav:before { + content: "\f2d6"; +} +.fa-etsy:before { + content: "\f2d7"; +} +.fa-imdb:before { + content: "\f2d8"; +} +.fa-ravelry:before { + content: "\f2d9"; +} +.fa-eercast:before { + content: "\f2da"; +} +.fa-microchip:before { + content: "\f2db"; +} +.fa-snowflake-o:before { + content: "\f2dc"; +} +.fa-superpowers:before { + content: "\f2dd"; +} +.fa-wpexplorer:before { + content: "\f2de"; +} +.fa-meetup:before { + content: "\f2e0"; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} diff --git a/css/font-awesome/css/font-awesome.min.css b/css/font-awesome/css/font-awesome.min.css new file mode 100644 index 00000000..540440ce --- /dev/null +++ b/css/font-awesome/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/css/font-awesome/fonts/FontAwesome.otf b/css/font-awesome/fonts/FontAwesome.otf new file mode 100644 index 00000000..401ec0f3 Binary files /dev/null and b/css/font-awesome/fonts/FontAwesome.otf differ diff --git a/css/font-awesome/fonts/fontawesome-webfont.eot b/css/font-awesome/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/css/font-awesome/fonts/fontawesome-webfont.eot differ diff --git a/css/font-awesome/fonts/fontawesome-webfont.svg b/css/font-awesome/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/css/font-awesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/css/font-awesome/fonts/fontawesome-webfont.ttf b/css/font-awesome/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/css/font-awesome/fonts/fontawesome-webfont.ttf differ diff --git a/css/font-awesome/fonts/fontawesome-webfont.woff b/css/font-awesome/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/css/font-awesome/fonts/fontawesome-webfont.woff differ diff --git a/css/font-awesome/fonts/fontawesome-webfont.woff2 b/css/font-awesome/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/css/font-awesome/fonts/fontawesome-webfont.woff2 differ diff --git a/eventPage.js b/eventPage.js index 2747f787..55e578a1 100755 --- a/eventPage.js +++ b/eventPage.js @@ -19,7 +19,7 @@ function startApplication() { // save connectionId in separate variable before createdWindow.contentWindow is destroyed var connectionId = createdWindow.contentWindow.serial.connectionId, valid_connection = createdWindow.contentWindow.CONFIGURATOR.connectionValid, - mincommand = createdWindow.contentWindow.MISC.mincommand; + mincommand = createdWindow.contentWindow.MOTOR_CONFIG.mincommand; if (connectionId && valid_connection) { // code below is handmade MSP message (without pretty JS wrapper), it behaves exactly like MSP.send_message diff --git a/images/icons/cf_icon_power_grey.svg b/images/icons/cf_icon_power_grey.svg new file mode 100644 index 00000000..2cb96635 --- /dev/null +++ b/images/icons/cf_icon_power_grey.svg @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/images/icons/cf_icon_power_white.svg b/images/icons/cf_icon_power_white.svg new file mode 100644 index 00000000..1af9f1f7 --- /dev/null +++ b/images/icons/cf_icon_power_white.svg @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/js/Features.js b/js/Features.js index cbe598cb..1a975c5a 100644 --- a/js/Features.js +++ b/js/Features.js @@ -35,7 +35,7 @@ var Features = function (config) { ); } - if (semver.gte(config.apiVersion, "1.15.0")) { + if (semver.gte(CONFIG.apiVersion, "1.15.0")) { features.push( {bit: 8, group: 'rxFailsafe', name: 'FAILSAFE', haveTip: true} ); @@ -45,21 +45,21 @@ var Features = function (config) { ); } - if (semver.gte(config.apiVersion, "1.16.0")) { + if (semver.gte(CONFIG.apiVersion, "1.16.0")) { features.push( {bit: 21, group: 'other', name: 'TRANSPONDER', haveTip: true} ); } if (config.flightControllerVersion !== '') { - if (semver.gte(config.flightControllerVersion, "2.8.0")) { + if (semver.gte(CONFIG.apiVersion, "1.16.0")) { features.push( {bit: 22, group: 'other', name: 'AIRMODE'} ); } - if (semver.gte(config.flightControllerVersion, "2.8.0")) { - if (!semver.gte(config.flightControllerVersion, "3.0.0")) { + if (semver.gte(CONFIG.apiVersion, "1.16.0")) { + if (semver.lt(CONFIG.apiVersion, "1.20.0")) { features.push( {bit: 23, group: 'pidTuning', name: 'SUPEREXPO_RATES'} ); @@ -70,13 +70,14 @@ var Features = function (config) { } } - if (semver.gte(config.flightControllerVersion, "3.0.0")) { + if (semver.gte(CONFIG.apiVersion, "1.20.0")) { features.push( - {bit: 18, group: 'other', name: 'OSD'} + {bit: 18, group: 'other', name: 'OSD'}, + {bit: 24, group: 'other', name: 'VTX'} ); } - if (semver.gte(config.flightControllerVersion, "3.1.0")) { + if (semver.gte(CONFIG.apiVersion, "1.31.0")) { features.push( {bit: 27, group: 'other', name: 'ESC_SENSOR'} ) diff --git a/js/RateCurve.js b/js/RateCurve.js index 291f93c1..dfcc2ac6 100755 --- a/js/RateCurve.js +++ b/js/RateCurve.js @@ -92,7 +92,7 @@ RateCurve.prototype.rcCommandRawToDegreesPerSecond = function (rcData, rate, rcR var expoPower; var rcRateConstant; - if (semver.gte(CONFIG.flightControllerVersion, "3.0.0")) { + if (semver.gte(CONFIG.apiVersion, "1.20.0")) { expoPower = 3; rcRateConstant = 200; } else { diff --git a/js/backup_restore.js b/js/backup_restore.js index 3de8d816..b1454ac8 100644 --- a/js/backup_restore.js +++ b/js/backup_restore.js @@ -22,9 +22,7 @@ function configuration_backup(callback) { ]; function update_profile_specific_data_list() { - if (semver.lt(CONFIG.apiVersion, "1.12.0")) { - profileSpecificData.push(MSPCodes.MSP_CHANNEL_FORWARDING); - } else { + if (semver.gt(CONFIG.apiVersion, "1.12.0")) { profileSpecificData.push(MSPCodes.MSP_SERVO_MIX_RULES); } if (semver.gte(CONFIG.apiVersion, "1.15.0")) { @@ -71,7 +69,7 @@ function configuration_backup(callback) { }); if (semver.gte(CONFIG.apiVersion, "1.15.0")) { - configuration.profiles[fetchingProfile].RCdeadband = jQuery.extend(true, {}, RC_deadband); + configuration.profiles[fetchingProfile].RCdeadband = jQuery.extend(true, {}, RC_DEADBAND_CONFIG); } codeKey = 0; fetchingProfile++; @@ -89,9 +87,7 @@ function configuration_backup(callback) { } var uniqueData = [ - MSPCodes.MSP_MISC, MSPCodes.MSP_RX_MAP, - MSPCodes.MSP_BF_CONFIG, MSPCodes.MSP_CF_SERIAL_CONFIG, MSPCodes.MSP_LED_STRIP_CONFIG, MSPCodes.MSP_LED_COLORS @@ -103,7 +99,7 @@ function configuration_backup(callback) { uniqueData.push(MSPCodes.MSP_ARMING_CONFIG); } if (semver.gte(CONFIG.apiVersion, "1.14.0")) { - uniqueData.push(MSPCodes.MSP_3D); + uniqueData.push(MSPCodes.MSP_MOTOR_3D_CONFIG); } if (semver.gte(CONFIG.apiVersion, "1.15.0")) { uniqueData.push(MSPCodes.MSP_SENSOR_ALIGNMENT); @@ -128,9 +124,7 @@ function configuration_backup(callback) { fetch_unique_data_item(); }); } else { - configuration.MISC = jQuery.extend(true, {}, MISC); configuration.RCMAP = jQuery.extend(true, [], RC_MAP); - configuration.BF_CONFIG = jQuery.extend(true, {}, BF_CONFIG); configuration.SERIAL_CONFIG = jQuery.extend(true, {}, SERIAL_CONFIG); configuration.LED_STRIP = jQuery.extend(true, [], LED_STRIP); configuration.LED_COLORS = jQuery.extend(true, [], LED_COLORS); @@ -143,7 +137,7 @@ function configuration_backup(callback) { configuration.ARMING_CONFIG = jQuery.extend(true, {}, ARMING_CONFIG); } if (semver.gte(CONFIG.apiVersion, "1.14.0")) { - configuration._3D = jQuery.extend(true, {}, _3D); + configuration.MOTOR_3D_CONFIG = jQuery.extend(true, {}, MOTOR_3D_CONFIG); } if (semver.gte(CONFIG.apiVersion, "1.15.0")) { configuration.SENSOR_ALIGNMENT = jQuery.extend(true, {}, SENSOR_ALIGNMENT); @@ -151,6 +145,10 @@ function configuration_backup(callback) { configuration.FAILSAFE_CONFIG = jQuery.extend(true, {}, FAILSAFE_CONFIG); configuration.RXFAIL_CONFIG = jQuery.extend(true, [], RXFAIL_CONFIG); } + if (semver.gte(CONFIG.apiVersion, "1.33.0")) { + configuration.RSSI_CONFIG = jQuery.extend(true, {}, RSSI_CONFIG); + configuration.FEATURE_CONFIG = jQuery.extend(true, {}, FEATURE_CONFIG); + } save(); } @@ -163,13 +161,17 @@ function configuration_backup(callback) { function save() { var chosenFileEntry = null; - var prefix = 'betaflight_backup'; + var prefix = 'backup'; var suffix = 'json'; var filename = generateFilename(prefix, suffix); + var accepts = [{ + extensions: [suffix] + }]; + // create or load the file - chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: filename, accepts: [{ extensions: [suffix] }]}, function (fileEntry) { + chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: filename, accepts: accepts}, function (fileEntry) { if (chrome.runtime.lastError) { console.error(chrome.runtime.lastError.message); return; @@ -328,7 +330,7 @@ function configuration_restore(callback) { if (!compareVersions(migratedVersion, '0.59.1')) { // variable was renamed - configuration.MISC.rssi_channel = configuration.MISC.rssi_aux_channel; + configuration.RSSI_CONFIG.channel = configuration.MISC.rssi_aux_channel; configuration.MISC.rssi_aux_channel = undefined; migratedVersion = '0.59.1'; @@ -527,11 +529,11 @@ function configuration_restore(callback) { if (compareVersions(migratedVersion, '0.66.0') && !compareVersions(configuration.apiVersion, '1.14.0')) { // api 1.14 exposes 3D configuration - if (configuration._3D == undefined) { - configuration._3D = { + if (configuration.MOTOR_3D_CONFIG == undefined) { + configuration.MOTOR_3D_CONFIG = { deadband3d_low: 1406, deadband3d_high: 1514, - neutral3d: 1460, + neutral: 1460, deadband3d_throttle: 50 }; } @@ -566,9 +568,9 @@ function configuration_restore(callback) { configuration.RX_CONFIG = { serialrx_provider: 0, spektrum_sat_bind: 0, - midrc: 1500, - mincheck: 1100, - maxcheck: 1900, + stick_center: 1500, + stick_min: 1100, + stick_max: 1900, rx_min_usec: 885, rx_max_usec: 2115 }; @@ -607,8 +609,8 @@ function configuration_restore(callback) { if (compareVersions(migratedVersion, '1.2.0')) { // old version of the configurator incorrectly had a 'disabled' option for GPS SBAS mode. - if (MISC.gps_ubx_sbas < 0) { - MISC.gps_ubx_sbas = 0; + if (GPS_CONFIG.ublox_sbas < 0) { + GPS_CONFIG.ublox_sbas = 0; } migratedVersion = '1.2.0'; @@ -681,7 +683,7 @@ function configuration_restore(callback) { SERVO_RULES = configuration.profiles[profile].ServoRules; MODE_RANGES = configuration.profiles[profile].ModeRanges; ADJUSTMENT_RANGES = configuration.profiles[profile].AdjustmentRanges; - RC_deadband = configuration.profiles[profile].RCdeadband; + RC_DEADBAND_CONFIG = configuration.profiles[profile].RCdeadband; } function upload_using_specific_commands() { @@ -729,9 +731,7 @@ function configuration_restore(callback) { var codeKey = 0; var uniqueData = [ - MSPCodes.MSP_SET_MISC, MSPCodes.MSP_SET_RX_MAP, - MSPCodes.MSP_SET_BF_CONFIG, MSPCodes.MSP_SET_CF_SERIAL_CONFIG ]; @@ -741,30 +741,41 @@ function configuration_restore(callback) { uniqueData.push(MSPCodes.MSP_SET_ARMING_CONFIG); } if (semver.gte(CONFIG.apiVersion, "1.14.0")) { - uniqueData.push(MSPCodes.MSP_SET_3D); + uniqueData.push(MSPCodes.MSP_SET_MOTOR_3D_CONFIG); } if (semver.gte(CONFIG.apiVersion, "1.15.0")) { uniqueData.push(MSPCodes.MSP_SET_SENSOR_ALIGNMENT); uniqueData.push(MSPCodes.MSP_SET_RX_CONFIG); uniqueData.push(MSPCodes.MSP_SET_FAILSAFE_CONFIG); } + if (semver.gte(CONFIG.apiVersion, "1.33.0")) { + uniqueData.push(MSPCodes.MSP_SET_FEATURE_CONFIG); + uniqueData.push(MSPCodes.MSP_SET_MOTOR_CONFIG); + uniqueData.push(MSPCodes.MSP_SET_GPS_CONFIG); + uniqueData.push(MSPCodes.MSP_SET_COMPASS_CONFIG); + uniqueData.push(MSPCodes.MSP_SET_RSSI_CONFIG); + } } function load_objects() { MISC = configuration.MISC; RC_MAP = configuration.RCMAP; - BF_CONFIG = configuration.BF_CONFIG; SERIAL_CONFIG = configuration.SERIAL_CONFIG; LED_STRIP = configuration.LED_STRIP; LED_COLORS = configuration.LED_COLORS; LED_MODE_COLORS = configuration.LED_MODE_COLORS; ARMING_CONFIG = configuration.ARMING_CONFIG; FC_CONFIG = configuration.FC_CONFIG; - _3D = configuration._3D; + MOTOR_3D_CONFIG = configuration.MOTOR_3D_CONFIG; SENSOR_ALIGNMENT = configuration.SENSOR_ALIGNMENT; RX_CONFIG = configuration.RX_CONFIG; FAILSAFE_CONFIG = configuration.FAILSAFE_CONFIG; RXFAIL_CONFIG = configuration.RXFAIL_CONFIG; + FEATURE_CONFIG = configuration.FEATURE_CONFIG; + MOTOR_CONFIG = configuration.MOTOR_CONFIG; + GPS_CONFIG = configuration.GPS_CONFIG; + COMPASS_CONFIG = configuration.COMPASS_CONFIG; + RSSI_CONFIG = configuration.RSSI_CONFIG; } function send_unique_data_item() { diff --git a/js/fc.js b/js/fc.js index 1e73ff49..0b10ffa7 100644 --- a/js/fc.js +++ b/js/fc.js @@ -2,7 +2,9 @@ // define all the global variables that are uses to hold FC state var CONFIG; -var BF_CONFIG; +var FEATURE_CONFIG; +var MIXER_CONFIG; +var BOARD_ALIGNMENT_CONFIG; var LED_STRIP; var LED_COLORS; var LED_MODE_COLORS; @@ -24,15 +26,25 @@ var MOTOR_DATA; var SERVO_DATA; var GPS_DATA; var ANALOG; +var VOLTAGE_METERS; +var VOLTAGE_METER_CONFIGS; +var CURRENT_METERS; +var CURRENT_METER_CONFIGS; +var BATTERY_STATE; +var BATTERY_CONFIG; var ARMING_CONFIG; var FC_CONFIG; -var MISC; -var _3D; +var MISC; // DEPRECATED +var MOTOR_CONFIG; +var GPS_CONFIG; +var COMPASS_CONFIG; +var RSSI_CONFIG; +var MOTOR_3D_CONFIG; var DATAFLASH; var SDCARD; var BLACKBOX; var TRANSPONDER; -var RC_deadband; +var RC_DEADBAND_CONFIG; var SENSOR_ALIGNMENT; var RX_CONFIG; var FAILSAFE_CONFIG; @@ -45,47 +57,50 @@ var SENSOR_CONFIG; var FC = { resetState: function() { CONFIG = { - apiVersion: "0.0.0", + apiVersion: "0.0.0", flightControllerIdentifier: '', - flightControllerVersion: '', - version: 0, - buildInfo: '', - multiType: 0, - msp_version: 0, // not specified using semantic versioning - capability: 0, - cycleTime: 0, - i2cError: 0, - activeSensors: 0, - mode: 0, - profile: 0, - uid: [0, 0, 0], - accelerometerTrims: [0, 0], - name: '', - numProfiles: 3, - rateProfile: 0 + flightControllerVersion: '', + version: 0, + buildInfo: '', + multiType: 0, + msp_version: 0, // not specified using semantic versioning + capability: 0, + cycleTime: 0, + i2cError: 0, + activeSensors: 0, + mode: 0, + profile: 0, + uid: [0, 0, 0], + accelerometerTrims: [0, 0], + name: '', + numProfiles: 3, + rateProfile: 0, + boardType: 0, }; - - BF_CONFIG = { - mixerConfiguration: 0, - features: new Features(CONFIG), - board_align_roll: 0, - board_align_pitch: 0, - board_align_yaw: 0, - currentscale: 0, - currentoffset: 0, - currentmetertype: 0, - batterycapacity: 0, + + FEATURE_CONFIG = { + features: 0, }; + + MIXER_CONFIG = { + mixer: 0, + }; - LED_STRIP = []; - LED_COLORS = []; - LED_MODE_COLORS = []; + BOARD_ALIGNMENT_CONFIG = { + roll: 0, + pitch: 0, + yaw: 0, + }; + + LED_STRIP = []; + LED_COLORS = []; + LED_MODE_COLORS = []; PID = { - controller: 0 + controller: 0 }; - PID_names = []; + PID_names = []; PIDs = new Array(10); for (var i = 0; i < 10; i++) { PIDs[i] = new Array(3); @@ -96,219 +111,248 @@ var FC = { // defaults // roll, pitch, yaw, throttle, aux 1, ... aux n RC = { - active_channels: 0, - channels: new Array(32) + active_channels: 0, + channels: new Array(32), }; RC_tuning = { - RC_RATE: 0, - RC_EXPO: 0, - roll_pitch_rate: 0, // pre 1.7 api only - roll_rate: 0, - pitch_rate: 0, - yaw_rate: 0, - dynamic_THR_PID: 0, - throttle_MID: 0, - throttle_EXPO: 0, - dynamic_THR_breakpoint: 0, - RC_YAW_EXPO: 0, - rcYawRate: 0 + RC_RATE: 0, + RC_EXPO: 0, + roll_pitch_rate: 0, // pre 1.7 api only + roll_rate: 0, + pitch_rate: 0, + yaw_rate: 0, + dynamic_THR_PID: 0, + throttle_MID: 0, + throttle_EXPO: 0, + dynamic_THR_breakpoint: 0, + RC_YAW_EXPO: 0, + rcYawRate: 0, }; - AUX_CONFIG = []; - AUX_CONFIG_IDS = []; + AUX_CONFIG = []; + AUX_CONFIG_IDS = []; - MODE_RANGES = []; - ADJUSTMENT_RANGES = []; + MODE_RANGES = []; + ADJUSTMENT_RANGES = []; - SERVO_CONFIG = []; - SERVO_RULES = []; + SERVO_CONFIG = []; + SERVO_RULES = []; SERIAL_CONFIG = { - ports: [], + ports: [], // pre 1.6 settings - mspBaudRate: 0, - gpsBaudRate: 0, - gpsPassthroughBaudRate: 0, - cliBaudRate: 0, + mspBaudRate: 0, + gpsBaudRate: 0, + gpsPassthroughBaudRate: 0, + cliBaudRate: 0, }; SENSOR_DATA = { - gyroscope: [0, 0, 0], - accelerometer: [0, 0, 0], - magnetometer: [0, 0, 0], - altitude: 0, - sonar: 0, - kinematics: [0.0, 0.0, 0.0], - debug: [0, 0, 0, 0] + gyroscope: [0, 0, 0], + accelerometer: [0, 0, 0], + magnetometer: [0, 0, 0], + altitude: 0, + sonar: 0, + kinematics: [0.0, 0.0, 0.0], + debug: [0, 0, 0, 0], }; - MOTOR_DATA = new Array(8); - SERVO_DATA = new Array(8); + MOTOR_DATA = new Array(8); + SERVO_DATA = new Array(8); GPS_DATA = { - fix: 0, - numSat: 0, - lat: 0, - lon: 0, - alt: 0, - speed: 0, - ground_course: 0, - distanceToHome: 0, - ditectionToHome: 0, - update: 0, + fix: 0, + numSat: 0, + lat: 0, + lon: 0, + alt: 0, + speed: 0, + ground_course: 0, + distanceToHome: 0, + ditectionToHome: 0, + update: 0, - // baseflight specific gps stuff - chn: [], - svid: [], - quality: [], - cno: [] + chn: [], + svid: [], + quality: [], + cno: [] }; ANALOG = { - voltage: 0, - mAhdrawn: 0, - rssi: 0, - amperage: 0, - last_received_timestamp: Date.now() + voltage: 0, + mAhdrawn: 0, + rssi: 0, + amperage: 0, + last_received_timestamp: Date.now() // FIXME this code lies, it's never been received at this point }; + VOLTAGE_METERS = []; + VOLTAGE_METER_CONFIGS = []; + CURRENT_METERS = []; + CURRENT_METER_CONFIGS = []; + + BATTERY_STATE = {}; + BATTERY_CONFIG = { + vbatmincellvoltage: 0, + vbatmaxcellvoltage: 0, + vbatwarningcellvoltage: 0, + capacity: 0, + voltageMeterSource: 0, + currentMeterSource: 0, + }; + ARMING_CONFIG = { - auto_disarm_delay: 0, - disarm_kill_switch: 0 + auto_disarm_delay: 0, + disarm_kill_switch: 0, }; FC_CONFIG = { - loopTime: 0 + loopTime: 0 }; - + MISC = { - minthrottle: 0, - maxthrottle: 0, - mincommand: 0, - failsafe_throttle: 0, - gps_type: 0, - gps_baudrate: 0, - gps_ubx_sbas: 0, - multiwiicurrentoutput: 0, - rssi_channel: 0, - placeholder2: 0, - mag_declination: 0, // not checked - vbatscale: 0, - vbatmincellvoltage: 0, - vbatmaxcellvoltage: 0, - vbatwarningcellvoltage: 0, - batterymetertype: 1, // 1=ADC, 2=ESC + // DEPRECATED = only used to store values that are written back to the fc as-is, do NOT use for any other purpose + failsafe_throttle: 0, + gps_baudrate: 0, + multiwiicurrentoutput: 0, + placeholder2: 0, + vbatscale: 0, + vbatmincellvoltage: 0, + vbatmaxcellvoltage: 0, + vbatwarningcellvoltage: 0, + }; + MOTOR_CONFIG = { + minthrottle: 0, + maxthrottle: 0, + mincommand: 0, + }; + + GPS_CONFIG = { + provider: 0, + ublox_sbas: 0, + auto_config: 0, + auto_baud: 0, + }; + + COMPASS_CONFIG = { + mag_declination: 0, }; - _3D = { - deadband3d_low: 0, - deadband3d_high: 0, - neutral3d: 0, - deadband3d_throttle: 0 + RSSI_CONFIG = { + channel: 0, + }; + + MOTOR_3D_CONFIG = { + deadband3d_low: 0, + deadband3d_high: 0, + neutral: 0, }; DATAFLASH = { - ready: false, - supported: false, - sectors: 0, - totalSize: 0, - usedSize: 0 + ready: false, + supported: false, + sectors: 0, + totalSize: 0, + usedSize: 0 }; SDCARD = { - supported: false, - state: 0, - filesystemLastError: 0, - freeSizeKB: 0, - totalSizeKB: 0, + supported: false, + state: 0, + filesystemLastError: 0, + freeSizeKB: 0, + totalSizeKB: 0, }; BLACKBOX = { - supported: false, - blackboxDevice: 0, - blackboxRateNum: 1, - blackboxRateDenom: 1 + supported: false, + blackboxDevice: 0, + blackboxRateNum: 1, + blackboxRateDenom: 1, }; TRANSPONDER = { - supported: false, - data: [] + supported: false, + data: [], + provider: 0, + providers: [], }; - RC_deadband = { - deadband: 0, - yaw_deadband: 0, - alt_hold_deadband: 0 + RC_DEADBAND_CONFIG = { + deadband: 0, + yaw_deadband: 0, + alt_hold_deadband: 0, + deadband3d_throttle: 0, }; SENSOR_ALIGNMENT = { - align_gyro: 0, - align_acc: 0, - align_mag: 0 + align_gyro: 0, + align_acc: 0, + align_mag: 0, }; PID_ADVANCED_CONFIG = { - gyro_sync_denom: 0, - pid_process_denom: 0, - use_unsyncedPwm: 0, - fast_pwm_protocol: 0, - motor_pwm_rate: 0, - digitalIdlePercent: 0, - gyroUse32kHz: 0 + gyro_sync_denom: 0, + pid_process_denom: 0, + use_unsyncedPwm: 0, + fast_pwm_protocol: 0, + motor_pwm_rate: 0, + digitalIdlePercent: 0, + gyroUse32kHz: 0, }; FILTER_CONFIG = { - gyro_soft_lpf_hz: 0, - dterm_lpf_hz: 0, - yaw_lpf_hz: 0, - gyro_soft_notch_hz_1: 0, - gyro_soft_notch_cutoff_1: 0, - dterm_notch_hz: 0, - dterm_notch_cutoff: 0, - gyro_soft_notch_hz_2: 0, - gyro_soft_notch_cutoff_2: 0 + gyro_soft_lpf_hz: 0, + dterm_lpf_hz: 0, + yaw_lpf_hz: 0, + gyro_soft_notch_hz_1: 0, + gyro_soft_notch_cutoff_1: 0, + dterm_notch_hz: 0, + dterm_notch_cutoff: 0, + gyro_soft_notch_hz_2: 0, + gyro_soft_notch_cutoff_2: 0, }; ADVANCED_TUNING = { - rollPitchItermIgnoreRate: 0, - yawItermIgnoreRate: 0, - yaw_p_limit: 0, - deltaMethod: 0, - vbatPidCompensation: 0, - ptermSetpointWeight: 0, - dtermSetpointWeight: 0, - toleranceBand: 0, - toleranceBandReduction: 0, - itermThrottleGain: 0, - pidMaxVelocity: 0, - pidMaxVelocityYaw: 0, - levelAngleLimit: 0, - levelSensitivity: 0 + rollPitchItermIgnoreRate: 0, + yawItermIgnoreRate: 0, + yaw_p_limit: 0, + deltaMethod: 0, + vbatPidCompensation: 0, + ptermSetpointWeight: 0, + dtermSetpointWeight: 0, + toleranceBand: 0, + toleranceBandReduction: 0, + itermThrottleGain: 0, + pidMaxVelocity: 0, + pidMaxVelocityYaw: 0, + levelAngleLimit: 0, + levelSensitivity: 0, }; SENSOR_CONFIG = { - acc_hardware: 0, - baro_hardware: 0, - mag_hardware: 0 + acc_hardware: 0, + baro_hardware: 0, + mag_hardware: 0, }; RX_CONFIG = { - serialrx_provider: 0, - maxcheck: 0, - midrc: 0, - mincheck: 0, - spektrum_sat_bind: 0, - rx_min_usec: 0, - rx_max_usec: 0, - rcInterpolation: 0, - rcInterpolationInterval:0, - airModeActivateThreshold: 0, - rxSpiProtocol: 0, - rxSpiId: 0, - rxSpiRfChannelCount: 0, - fpvCamAngleDegrees: 0 + serialrx_provider: 0, + stick_max: 0, + stick_center: 0, + stick_min: 0, + spektrum_sat_bind: 0, + rx_min_usec: 0, + rx_max_usec: 0, + rcInterpolation: 0, + rcInterpolationInterval: 0, + airModeActivateThreshold: 0, + rxSpiProtocol: 0, + rxSpiId: 0, + rxSpiRfChannelCount: 0, + fpvCamAngleDegrees: 0, }; FAILSAFE_CONFIG = { @@ -317,7 +361,7 @@ var FC = { failsafe_throttle: 0, failsafe_kill_switch: 0, failsafe_throttle_low_delay: 0, - failsafe_procedure: 0 + failsafe_procedure: 0. }; RXFAIL_CONFIG = []; diff --git a/js/gui.js b/js/gui.js index bd28f75d..78606af2 100644 --- a/js/gui.js +++ b/js/gui.js @@ -1,3 +1,4 @@ + 'use strict'; var TABS = {}; // filled by individual tab js file @@ -12,15 +13,18 @@ var GUI_control = function () { this.operating_system; this.interval_array = []; this.timeout_array = []; + this.defaultAllowedTabsWhenDisconnected = [ 'landing', 'firmware_flasher', 'help' ]; - this.defaultAllowedTabsWhenConnected = [ + this.defaultAllowedFCTabsWhenConnected = [ + 'setup', 'failsafe', 'transponder', 'osd', + 'power', 'adjustments', 'auxiliary', 'cli', @@ -36,7 +40,13 @@ var GUI_control = function () { 'receiver', 'sensors', 'servos', - 'setup' + ]; + this.defaultAllowedOSDTabsWhenConnected = [ + 'setup_osd', + 'osd', + 'power', + 'sensors', + 'transponder', ]; this.allowedTabs = this.defaultAllowedTabsWhenDisconnected; diff --git a/js/model.js b/js/model.js index 8f80deb9..9492b674 100644 --- a/js/model.js +++ b/js/model.js @@ -47,7 +47,7 @@ var Model = function (wrapper, canvas) { this.renderer.setSize(this.wrapper.width() * 2, this.wrapper.height() * 2); // load the model including materials - var model_file = useWebGLRenderer ? mixerList[BF_CONFIG.mixerConfiguration - 1].model : 'fallback'; + var model_file = useWebGLRenderer ? mixerList[MIXER_CONFIG.mixer - 1].model : 'fallback'; // Temporary workaround for 'custom' model until akfreak's custom model is merged. if (model_file == 'custom') { model_file = 'fallback'; } diff --git a/js/msp.js b/js/msp.js index ab7c4121..ba44b46f 100755 --- a/js/msp.js +++ b/js/msp.js @@ -148,6 +148,9 @@ var MSP = { this.listeners = []; }, send_message: function (code, data, callback_sent, callback_msp, callback_onerror) { + if (code === undefined) { + debugger; + } var bufferOut, bufView; diff --git a/js/msp/MSPCodes.js b/js/msp/MSPCodes.js index ce272c2d..89b49a16 100644 --- a/js/msp/MSPCodes.js +++ b/js/msp/MSPCodes.js @@ -11,21 +11,26 @@ var MSPCodes = { MSP_NAME: 10, MSP_SET_NAME: 11, - MSP_CHANNEL_FORWARDING: 32, - MSP_SET_CHANNEL_FORWARDING: 33, + MSP_BATTERY_CONFIG: 32, + MSP_SET_BATTERY_CONFIG: 33, MSP_MODE_RANGES: 34, MSP_SET_MODE_RANGE: 35, - + MSP_FEATURE_CONFIG: 36, + MSP_SET_FEATURE_CONFIG: 37, + MSP_BOARD_ALIGNMENT_CONFIG: 38, + MSP_SET_BOARD_ALIGNMENT_CONFIG: 39, MSP_CURRENT_METER_CONFIG: 40, MSP_SET_CURRENT_METER_CONFIG: 41, - + MSP_MIXER_CONFIG: 42, + MSP_SET_MIXER_CONFIG: 43, MSP_RX_CONFIG: 44, MSP_SET_RX_CONFIG: 45, MSP_LED_COLORS: 46, MSP_SET_LED_COLORS: 47, MSP_LED_STRIP_CONFIG: 48, MSP_SET_LED_STRIP_CONFIG: 49, - + MSP_RSSI_CONFIG: 50, + MSP_SET_RSSI_CONFIG: 51, MSP_ADJUSTMENT_RANGES: 52, MSP_SET_ADJUSTMENT_RANGE: 53, MSP_CF_SERIAL_CONFIG: 54, @@ -39,8 +44,8 @@ var MSPCodes = { MSP_SET_ARMING_CONFIG: 62, MSP_RX_MAP: 64, MSP_SET_RX_MAP: 65, - MSP_BF_CONFIG: 66, - MSP_SET_BF_CONFIG: 67, + MSP_BF_CONFIG: 66, // DEPRECATED + MSP_SET_BF_CONFIG: 67, // DEPRECATED MSP_SET_REBOOT: 68, MSP_BF_BUILD_INFO: 69, // Not used MSP_DATAFLASH_SUMMARY: 70, @@ -71,9 +76,9 @@ var MSPCodes = { MSP_SET_PID_ADVANCED: 95, MSP_SENSOR_CONFIG: 96, MSP_SET_SENSOR_CONFIG: 97, - // MSP_SPECIAL_PARAMETERS: 98, removed - //MSP_SET_SPECIAL_PARAMETERS: 99, removed - MSP_IDENT: 100, // Not used + //MSP_SPECIAL_PARAMETERS: 98, // DEPRECATED + //MSP_SET_SPECIAL_PARAMETERS: 99, // DEPRECATED + //MSP_IDENT: 100, // DEPRECTED MSP_STATUS: 101, MSP_RAW_IMU: 102, MSP_SERVO: 103, @@ -86,19 +91,25 @@ var MSPCodes = { MSP_ANALOG: 110, MSP_RC_TUNING: 111, MSP_PID: 112, - MSP_BOX: 113, // Not used - MSP_MISC: 114, - MSP_MOTOR_PINS: 115, // Not used + //MSP_BOX: 113, // DEPRECATED + MSP_MISC: 114, // DEPRECATED MSP_BOXNAMES: 116, MSP_PIDNAMES: 117, MSP_WP: 118, // Not used MSP_BOXIDS: 119, MSP_SERVO_CONFIGURATIONS: 120, - MSP_3D: 124, + MSP_MOTOR_3D_CONFIG: 124, MSP_RC_DEADBAND: 125, MSP_SENSOR_ALIGNMENT: 126, MSP_LED_STRIP_MODECOLOR: 127, + MSP_VOLTAGE_METERS: 128, + MSP_CURRENT_METERS: 129, + MSP_BATTERY_STATE: 130, + MSP_MOTOR_CONFIG: 131, + MSP_GPS_CONFIG: 132, + MSP_COMPASS_CONFIG: 133, + MSP_STATUS_EX: 150, MSP_UID: 160, @@ -109,22 +120,25 @@ var MSPCodes = { MSP_SET_RAW_RC: 200, MSP_SET_RAW_GPS: 201, // Not used MSP_SET_PID: 202, - MSP_SET_BOX: 203, + //MSP_SET_BOX: 203, // DEPRECATED MSP_SET_RC_TUNING: 204, MSP_ACC_CALIBRATION: 205, MSP_MAG_CALIBRATION: 206, - MSP_SET_MISC: 207, + MSP_SET_MISC: 207, // DEPRECATED MSP_RESET_CONF: 208, MSP_SET_WP: 209, // Not used MSP_SELECT_SETTING: 210, - MSP_SET_HEAD: 211, // Not used + MSP_SET_HEADING: 211, // Not used MSP_SET_SERVO_CONFIGURATION: 212, MSP_SET_MOTOR: 214, - MSP_SET_3D: 217, + MSP_SET_MOTOR_3D_CONFIG: 217, MSP_SET_RC_DEADBAND: 218, MSP_SET_RESET_CURR_PID: 219, MSP_SET_SENSOR_ALIGNMENT: 220, MSP_SET_LED_STRIP_MODECOLOR: 221, + MSP_SET_MOTOR_CONFIG: 222, + MSP_SET_GPS_CONFIG: 223, + MSP_SET_COMPASS_CONFIG: 224, MSP_SET_ACC_TRIM: 239, MSP_ACC_TRIM: 240, diff --git a/js/msp/MSPHelper.js b/js/msp/MSPHelper.js index 43245b12..20fb594f 100644 --- a/js/msp/MSPHelper.js +++ b/js/msp/MSPHelper.js @@ -52,6 +52,9 @@ MspHelper.prototype.process_data = function(dataHandler) { var data = dataHandler.dataView; // DataView (allowing us to view arrayBuffer as struct/union) var code = dataHandler.code; + if (code === 0) { + debugger; + } var crcError = dataHandler.crcError; if (!crcError) { if (!dataHandler.unsupported) switch (code) { @@ -75,7 +78,7 @@ MspHelper.prototype.process_data = function(dataHandler) { CONFIG.mode = data.readU32(); CONFIG.profile = data.readU8(); CONFIG.cpuload = data.readU16(); - if (semver.gt(CONFIG.flightControllerVersion, "2.9.1")) { + if (semver.gte(CONFIG.apiVersion, "1.16.0")) { CONFIG.numProfiles = data.readU8(); CONFIG.rateProfile = data.readU8(); @@ -154,6 +157,92 @@ MspHelper.prototype.process_data = function(dataHandler) { ANALOG.rssi = data.readU16(); // 0-1023 ANALOG.amperage = data.read16() / 100; // A ANALOG.last_received_timestamp = Date.now(); + break; + case MSPCodes.MSP_VOLTAGE_METERS: + VOLTAGE_METERS = []; + var voltageMeterLength = 2; + for (var i = 0; i < (data.byteLength / voltageMeterLength); i++) { + var voltageMeter = {}; + voltageMeter.id = data.readU8(); + voltageMeter.voltage = data.readU8() / 10.0; + + VOLTAGE_METERS.push(voltageMeter) + } + break; + case MSPCodes.MSP_CURRENT_METERS: + CURRENT_METERS = []; + var currentMeterLength = 5; + for (var i = 0; i < (data.byteLength / currentMeterLength); i++) { + var currentMeter = {}; + currentMeter.id = data.readU8(); + currentMeter.mAhDrawn = data.readU16(); // mAh + currentMeter.amperage = data.readU16() / 1000; // A + + CURRENT_METERS.push(currentMeter); + } + break; + case MSPCodes.MSP_BATTERY_STATE: + BATTERY_STATE.cellCount = data.readU8(); + BATTERY_STATE.capacity = data.readU16(); // mAh + + BATTERY_STATE.voltage = data.readU8() / 10.0; // V + BATTERY_STATE.mAhDrawn = data.readU16(); // mAh + BATTERY_STATE.amperage = data.readU16() / 100; // A + break; + + case MSPCodes.MSP_VOLTAGE_METER_CONFIG: + VOLTAGE_METER_CONFIGS = []; + var voltage_meter_count = data.readU8(); + + for (var i = 0; i < voltage_meter_count; i++) { + var subframe_length = data.readU8(); + if (subframe_length != 5) { + for (var j = 0; j < subframe_length; j++) { + data.readU8(); + } + } else { + var voltageMeterConfig = {}; + voltageMeterConfig.id = data.readU8(); + voltageMeterConfig.sensorType = data.readU8(); + voltageMeterConfig.vbatscale = data.readU8(); + voltageMeterConfig.vbatresdivval = data.readU8(); + voltageMeterConfig.vbatresdivmultiplier = data.readU8(); + + VOLTAGE_METER_CONFIGS.push(voltageMeterConfig); + } + } + break; + case MSPCodes.MSP_CURRENT_METER_CONFIG: + var offset = 0; + CURRENT_METER_CONFIGS = []; + var current_meter_count = data.readU8(); + for (var i = 0; i < current_meter_count; i++) { + var currentMeterConfig = {}; + var subframe_length = data.readU8(); + + if (subframe_length != 6) { + for (var j = 0; j < subframe_length; j++) { + data.readU8(); + } + } else { + currentMeterConfig.id = data.readU8(); + currentMeterConfig.sensorType = data.readU8(); + currentMeterConfig.scale = data.readU16(); + currentMeterConfig.offset = data.readU16(); + + CURRENT_METER_CONFIGS.push(currentMeterConfig); + } + } + break; + + case MSPCodes.MSP_BATTERY_CONFIG: + BATTERY_CONFIG.vbatmincellvoltage = data.readU8() / 10; // 10-50 + BATTERY_CONFIG.vbatmaxcellvoltage = data.readU8() / 10; // 10-50 + BATTERY_CONFIG.vbatwarningcellvoltage = data.readU8() / 10; // 10-50 + BATTERY_CONFIG.capacity = data.readU16(); + BATTERY_CONFIG.voltageMeterSource = data.readU8(); + BATTERY_CONFIG.currentMeterSource = data.readU8(); + break; case MSPCodes.MSP_RC_TUNING: RC_tuning.RC_RATE = parseFloat((data.readU8() / 100).toFixed(2)); @@ -178,7 +267,7 @@ MspHelper.prototype.process_data = function(dataHandler) { } if (semver.gte(CONFIG.apiVersion, "1.10.0")) { RC_tuning.RC_YAW_EXPO = parseFloat((data.readU8() / 100).toFixed(2)); - if (semver.gte(CONFIG.flightControllerVersion, "2.9.1")) { + if (semver.gte(CONFIG.apiVersion, "1.16.0")) { RC_tuning.rcYawRate = parseFloat((data.readU8() / 100).toFixed(2)); } else { RC_tuning.rcYawRate = 0; @@ -210,46 +299,50 @@ MspHelper.prototype.process_data = function(dataHandler) { break; case MSPCodes.MSP_MISC: // 22 bytes RX_CONFIG.midrc = data.readU16(); - MISC.minthrottle = data.readU16(); // 0-2000 - MISC.maxthrottle = data.readU16(); // 0-2000 - MISC.mincommand = data.readU16(); // 0-2000 + MOTOR_CONFIG.minthrottle = data.readU16(); // 0-2000 + MOTOR_CONFIG.maxthrottle = data.readU16(); // 0-2000 + MOTOR_CONFIG.mincommand = data.readU16(); // 0-2000 MISC.failsafe_throttle = data.readU16(); // 1000-2000 - MISC.gps_type = data.readU8(); + GPS_CONFIG.provider = data.readU8(); MISC.gps_baudrate = data.readU8(); - MISC.gps_ubx_sbas = data.readU8(); + GPS_CONFIG.ublox_sbas = data.readU8(); MISC.multiwiicurrentoutput = data.readU8(); - MISC.rssi_channel = data.readU8(); + RSSI_CONFIG.channel = data.readU8(); MISC.placeholder2 = data.readU8(); if (semver.lt(CONFIG.apiVersion, "1.18.0")) - MISC.mag_declination = data.read16() / 10; // -1800-1800 + COMPASS_CONFIG.mag_declination = data.read16() / 10; // -1800-1800 else - MISC.mag_declination = data.read16() / 100; // -18000-18000 - MISC.vbatscale = data.readU8(); // 10-200 + COMPASS_CONFIG.mag_declination = data.read16() / 100; // -18000-18000 + MISC.vbatscale = data.readU8(); // was MISC.vbatscale - 10-200 MISC.vbatmincellvoltage = data.readU8() / 10; // 10-50 MISC.vbatmaxcellvoltage = data.readU8() / 10; // 10-50 MISC.vbatwarningcellvoltage = data.readU8() / 10; // 10-50 + break; + case MSPCodes.MSP_MOTOR_CONFIG: + MOTOR_CONFIG.minthrottle = data.readU16(); // 0-2000 + MOTOR_CONFIG.maxthrottle = data.readU16(); // 0-2000 + MOTOR_CONFIG.mincommand = data.readU16(); // 0-2000 break; - case MSPCodes.MSP_VOLTAGE_METER_CONFIG: - MISC.vbatscale = data.readU8(); // 10-200 - MISC.vbatmincellvoltage = data.readU8() / 10; // 10-50 - MISC.vbatmaxcellvoltage = data.readU8() / 10; // 10-50 - MISC.vbatwarningcellvoltage = data.readU8() / 10; // 10-50 - if (semver.gte(CONFIG.apiVersion, "1.23.0")) { - MISC.batterymetertype = data.readU8(); + case MSPCodes.MSP_COMPASS_CONFIG: + COMPASS_CONFIG.mag_declination = data.read16() / 100; // -18000-18000 + break; + case MSPCodes.MSP_GPS_CONFIG: + GPS_CONFIG.provider = data.readU8(); + GPS_CONFIG.ublox_sbas = data.readU8(); + if (semver.gte(CONFIG.apiVersion, "1.34.0")) { + GPS_CONFIG.auto_config = data.readU8(); + GPS_CONFIG.auto_baud = data.readU8(); } break; - case MSPCodes.MSP_CURRENT_METER_CONFIG: - BF_CONFIG.currentscale = data.read16(); - BF_CONFIG.currentoffset = data.read16(); - BF_CONFIG.currentmetertype = data.readU8(); - BF_CONFIG.batterycapacity = data.readU16(); + case MSPCodes.MSP_RSSI_CONFIG: + RSSI_CONFIG.channel = data.readU8(); break; - case MSPCodes.MSP_3D: - _3D.deadband3d_low = data.readU16(); - _3D.deadband3d_high = data.readU16(); - _3D.neutral3d = data.readU16(); + case MSPCodes.MSP_MOTOR_3D_CONFIG: + MOTOR_3D_CONFIG.deadband3d_low = data.readU16(); + MOTOR_3D_CONFIG.deadband3d_high = data.readU16(); + MOTOR_3D_CONFIG.neutral = data.readU16(); if (semver.lt(CONFIG.apiVersion, "1.17.0")) { - _3D.deadband3d_throttle = data.readU16(); + RC_DEADBAND_CONFIG.deadband3d_throttle = data.readU16(); } break; case MSPCodes.MSP_BOXNAMES: @@ -296,8 +389,24 @@ MspHelper.prototype.process_data = function(dataHandler) { case MSPCodes.MSP_SERVO_CONFIGURATIONS: SERVO_CONFIG = []; // empty the array as new data is coming in + if (semver.gte(CONFIG.apiVersion, "1.33.0")) { + if (data.byteLength % 12 == 0) { + for (var i = 0; i < data.byteLength; i += 12) { + var arr = { + 'min': data.readU16(), + 'max': data.readU16(), + 'middle': data.readU16(), + 'rate': data.read8(), + 'angleAtMin': -90, + 'angleAtMax': 90, + 'indexOfChannelToForward': data.readU8(), + 'reversedInputSources': data.readU32() + }; - if (semver.gte(CONFIG.apiVersion, "1.12.0")) { + SERVO_CONFIG.push(arr); + } + } + } else if (semver.gte(CONFIG.apiVersion, "1.12.0")) { if (data.byteLength % 14 == 0) { for (var i = 0; i < data.byteLength; i += 14) { var arr = { @@ -341,12 +450,12 @@ MspHelper.prototype.process_data = function(dataHandler) { } break; case MSPCodes.MSP_RC_DEADBAND: - RC_deadband.deadband = data.readU8(); - RC_deadband.yaw_deadband = data.readU8(); - RC_deadband.alt_hold_deadband = data.readU8(); + RC_DEADBAND_CONFIG.deadband = data.readU8(); + RC_DEADBAND_CONFIG.yaw_deadband = data.readU8(); + RC_DEADBAND_CONFIG.alt_hold_deadband = data.readU8(); if (semver.gte(CONFIG.apiVersion, "1.17.0")) { - _3D.deadband3d_throttle = data.readU16(); + RC_DEADBAND_CONFIG.deadband3d_throttle = data.readU16(); } break; case MSPCodes.MSP_SENSOR_ALIGNMENT: @@ -355,7 +464,6 @@ MspHelper.prototype.process_data = function(dataHandler) { SENSOR_ALIGNMENT.align_mag = data.readU8(); break; case MSPCodes.MSP_DISPLAYPORT: - console.log('Received \'MSP_DISPLAYPORT\' message, ignored.'); break; case MSPCodes.MSP_SET_RAW_RC: break; @@ -371,8 +479,17 @@ MspHelper.prototype.process_data = function(dataHandler) { case MSPCodes.MSP_MAG_CALIBRATION: console.log('Mag calibration executed'); break; - case MSPCodes.MSP_SET_MISC: - console.log('MISC Configuration saved'); + case MSPCodes.MSP_SET_MOTOR_CONFIG: + console.log('Motor Configuration saved'); + break; + case MSPCodes.MSP_SET_GPS_CONFIG: + console.log('GPS Configuration saved'); + break; + case MSPCodes.MSP_SET_RSSI_CONFIG: + console.log('RSSI Configuration saved'); + break; + case MSPCodes.MSP_SET_FEATURE_CONFIG: + console.log('Features saved'); break; case MSPCodes.MSP_RESET_CONF: console.log('Settings Reset'); @@ -387,7 +504,7 @@ MspHelper.prototype.process_data = function(dataHandler) { console.log('Settings Saved in EEPROM'); break; case MSPCodes.MSP_SET_CURRENT_METER_CONFIG: - console.log('Current Settings saved'); + console.log('Amperage Settings saved'); break; case MSPCodes.MSP_SET_VOLTAGE_METER_CONFIG: console.log('Voltage config saved'); @@ -433,21 +550,23 @@ MspHelper.prototype.process_data = function(dataHandler) { case MSPCodes.MSP_SET_RX_MAP: console.log('RCMAP saved'); break; - case MSPCodes.MSP_BF_CONFIG: - BF_CONFIG.mixerConfiguration = data.readU8(); - BF_CONFIG.features.setMask(data.readU32()); - RX_CONFIG.serialrx_provider = data.readU8(); - BF_CONFIG.board_align_roll = data.read16(); // -180 - 360 - BF_CONFIG.board_align_pitch = data.read16(); // -180 - 360 - BF_CONFIG.board_align_yaw = data.read16(); // -180 - 360 - BF_CONFIG.currentscale = data.read16(); - BF_CONFIG.currentoffset = data.read16(); - - updateTabList(BF_CONFIG.features); - + + case MSPCodes.MSP_MIXER_CONFIG: + MIXER_CONFIG.mixer = data.readU8(); break; - case MSPCodes.MSP_SET_BF_CONFIG: + + case MSPCodes.MSP_FEATURE_CONFIG: + FEATURE_CONFIG.features.setMask(data.readU32()); + + updateTabList(FEATURE_CONFIG.features); break; + + case MSPCodes.MSP_BOARD_ALIGNMENT_CONFIG: + BOARD_ALIGNMENT_CONFIG.roll = data.read16(); // -180 - 360 + BOARD_ALIGNMENT_CONFIG.pitch = data.read16(); // -180 - 360 + BOARD_ALIGNMENT_CONFIG.yaw = data.read16(); // -180 - 360 + break; + case MSPCodes.MSP_SET_REBOOT: console.log('Reboot request accepted'); break; @@ -491,6 +610,12 @@ MspHelper.prototype.process_data = function(dataHandler) { } CONFIG.boardIdentifier = identifier; CONFIG.boardVersion = data.readU16(); + if (semver.gte(CONFIG.apiVersion, "1.35.0")) { + CONFIG.boardType = data.readU8(); + } else { + CONFIG.boardType = 0; + } + break; case MSPCodes.MSP_NAME: @@ -582,22 +707,11 @@ MspHelper.prototype.process_data = function(dataHandler) { } break; - case MSPCodes.MSP_CHANNEL_FORWARDING: - for (var i = 0; i < data.byteLength && i < SERVO_CONFIG.length; i ++) { - var channelIndex = data.readU8(); - if (channelIndex < 255) { - SERVO_CONFIG[i].indexOfChannelToForward = channelIndex; - } else { - SERVO_CONFIG[i].indexOfChannelToForward = undefined; - } - } - break; - case MSPCodes.MSP_RX_CONFIG: RX_CONFIG.serialrx_provider = data.readU8(); - RX_CONFIG.maxcheck = data.readU16(); - RX_CONFIG.midrc = data.readU16(); - RX_CONFIG.mincheck = data.readU16(); + RX_CONFIG.stick_max = data.readU16(); + RX_CONFIG.stick_center = data.readU16(); + RX_CONFIG.stick_min = data.readU16(); RX_CONFIG.spektrum_sat_bind = data.readU8(); RX_CONFIG.rx_min_usec = data.readU16(); RX_CONFIG.rx_max_usec = data.readU16(); @@ -685,7 +799,7 @@ MspHelper.prototype.process_data = function(dataHandler) { ADVANCED_TUNING.yaw_p_limit = data.readU16(); ADVANCED_TUNING.deltaMethod = data.readU8(); ADVANCED_TUNING.vbatPidCompensation = data.readU8(); - if (semver.gte(CONFIG.flightControllerVersion, "3.0.0")) { + if (semver.gte(CONFIG.apiVersion, "1.20.0")) { ADVANCED_TUNING.ptermSetpointWeight = data.readU8(); ADVANCED_TUNING.dtermSetpointWeight = data.readU8(); ADVANCED_TUNING.toleranceBand = data.readU8(); @@ -875,9 +989,38 @@ MspHelper.prototype.process_data = function(dataHandler) { console.log("Blackbox config saved"); break; case MSPCodes.MSP_TRANSPONDER_CONFIG: - TRANSPONDER.supported = (data.readU8() & 1) != 0; + var bytesRemaining = data.byteLength; + if (semver.gte(CONFIG.apiVersion, "1.33.0")) { + var providerCount = data.readU8(); + bytesRemaining--; + + TRANSPONDER.supported = providerCount > 0; + TRANSPONDER.providers = []; + + for (var i = 0; i < providerCount; i++) { + var provider = { + id: data.readU8(), + dataLength: data.readU8() + }; + bytesRemaining -= 2; + + TRANSPONDER.providers.push(provider); + } + TRANSPONDER.provider = data.readU8(); + bytesRemaining--; + + } else { + TRANSPONDER.supported = (data.readU8() & 1) != 0; + bytesRemaining--; + + // only ILAP was supported prior to 1.33.0 + TRANSPONDER.providers = [{ + id: 1, // ILAP + dataLength: 6 + }]; + TRANSPONDER.provider = TRANSPONDER.providers[0].id; + } TRANSPONDER.data = []; - var bytesRemaining = data.byteLength - 1; for (var i = 0; i < bytesRemaining; i++) { TRANSPONDER.data.push(data.readU8()); } @@ -907,9 +1050,12 @@ MspHelper.prototype.process_data = function(dataHandler) { case MSPCodes.MSP_SET_RESET_CURR_PID: console.log('Current PID profile reset'); break; - case MSPCodes.MSP_SET_3D: + case MSPCodes.MSP_SET_MOTOR_3D_CONFIG: console.log('3D settings saved'); break; + case MSPCodes.MSP_SET_MIXER_CONFIG: + console.log('Mixer config saved'); + break; case MSPCodes.MSP_SET_RC_DEADBAND: console.log('Rc controls settings saved'); break; @@ -985,16 +1131,17 @@ MspHelper.prototype.crunch = function(code) { var buffer = []; var self = this; switch (code) { - case MSPCodes.MSP_SET_BF_CONFIG: - var featureMask = BF_CONFIG.features.getMask(); - buffer.push8(BF_CONFIG.mixerConfiguration) - .push32(featureMask) - .push8(RX_CONFIG.serialrx_provider) - .push16(BF_CONFIG.board_align_roll) - .push16(BF_CONFIG.board_align_pitch) - .push16(BF_CONFIG.board_align_yaw) - .push16(BF_CONFIG.currentscale) - .push16(BF_CONFIG.currentoffset); + case MSPCodes.MSP_SET_FEATURE_CONFIG: + var featureMask = FEATURE_CONFIG.features.getMask(); + buffer.push32(featureMask); + break; + case MSPCodes.MSP_SET_MIXER_CONFIG: + buffer.push8(MIXER_CONFIG.mixer) + break; + case MSPCodes.MSP_SET_BOARD_ALIGNMENT_CONFIG: + buffer.push16(BOARD_ALIGNMENT_CONFIG.roll) + .push16(BOARD_ALIGNMENT_CONFIG.pitch) + .push16(BOARD_ALIGNMENT_CONFIG.yaw); break; case MSPCodes.MSP_SET_PID_CONTROLLER: buffer.push8(PID.controller); @@ -1024,7 +1171,7 @@ MspHelper.prototype.crunch = function(code) { } if (semver.gte(CONFIG.apiVersion, "1.10.0")) { buffer.push8(Math.round(RC_tuning.RC_YAW_EXPO * 100)); - if (semver.gte(CONFIG.flightControllerVersion, "2.9.1")) { + if (semver.gte(CONFIG.apiVersion, "1.16.0")) { buffer.push8(Math.round(RC_tuning.rcYawRate * 100)); } } @@ -1047,46 +1194,74 @@ MspHelper.prototype.crunch = function(code) { break; case MSPCodes.MSP_SET_MISC: buffer.push16(RX_CONFIG.midrc) - .push16(MISC.minthrottle) - .push16(MISC.maxthrottle) - .push16(MISC.mincommand) + .push16(MOTOR_CONFIG.minthrottle) + .push16(MOTOR_CONFIG.maxthrottle) + .push16(MOTOR_CONFIG.mincommand) .push16(MISC.failsafe_throttle) - .push8(MISC.gps_type) + .push8(GPS_CONFIG.provider) .push8(MISC.gps_baudrate) - .push8(MISC.gps_ubx_sbas) + .push8(GPS_CONFIG.ublox_sbas) .push8(MISC.multiwiicurrentoutput) - .push8(MISC.rssi_channel) + .push8(RSSI_CONFIG.channel) .push8(MISC.placeholder2); if (semver.lt(CONFIG.apiVersion, "1.18.0")) { - buffer.push16(Math.round(MISC.mag_declination * 10)); + buffer.push16(Math.round(COMPASS_CONFIG.mag_declination * 10)); } else { - buffer.push16(Math.round(MISC.mag_declination * 100)); + buffer.push16(Math.round(COMPASS_CONFIG.mag_declination * 100)); } buffer.push8(MISC.vbatscale) .push8(Math.round(MISC.vbatmincellvoltage * 10)) .push8(Math.round(MISC.vbatmaxcellvoltage * 10)) .push8(Math.round(MISC.vbatwarningcellvoltage * 10)); break; - case MSPCodes.MSP_SET_VOLTAGE_METER_CONFIG: - buffer.push8(MISC.vbatscale) - .push8(Math.round(MISC.vbatmincellvoltage * 10)) - .push8(Math.round(MISC.vbatmaxcellvoltage * 10)) - .push8(Math.round(MISC.vbatwarningcellvoltage * 10)); - if (semver.gte(CONFIG.apiVersion, "1.23.0")) { - buffer.push8(MISC.batterymetertype); - } + case MSPCodes.MSP_SET_MOTOR_CONFIG: + buffer.push16(MOTOR_CONFIG.minthrottle) + .push16(MOTOR_CONFIG.maxthrottle) + .push16(MOTOR_CONFIG.mincommand); + break; + case MSPCodes.MSP_SET_GPS_CONFIG: + buffer.push8(GPS_CONFIG.provider) + .push8(GPS_CONFIG.ublox_sbas); + if (semver.gte(CONFIG.apiVersion, "1.34.0")) { + buffer.push8(GPS_CONFIG.auto_config) + .push8(GPS_CONFIG.auto_baud); + } break; - case MSPCodes.MSP_SET_CURRENT_METER_CONFIG: - buffer.push16(BF_CONFIG.currentscale) - .push16(BF_CONFIG.currentoffset) - .push8(BF_CONFIG.currentmetertype) - .push16(BF_CONFIG.batterycapacity) + case MSPCodes.MSP_SET_COMPASS_CONFIG: + buffer.push16(Math.round(COMPASS_CONFIG.mag_declination * 100)); break; + case MSPCodes.MSP_SET_RSSI_CONFIG: + buffer.push8(RSSI_CONFIG.channel); + break; + case MSPCodes.MSP_SET_BATTERY_CONFIG: + buffer.push8(Math.round(BATTERY_CONFIG.vbatmincellvoltage * 10)) + .push8(Math.round(BATTERY_CONFIG.vbatmaxcellvoltage * 10)) + .push8(Math.round(BATTERY_CONFIG.vbatwarningcellvoltage * 10)) + .push16(BATTERY_CONFIG.capacity) + .push8(BATTERY_CONFIG.voltageMeterSource) + .push8(BATTERY_CONFIG.currentMeterSource); + break; +// FIXME - Needs updating before it can be used. +// case MSPCodes.MSP_SET_VOLTAGE_METER_CONFIG: +// buffer.push8(MISC.vbatscale) +// .push8(Math.round(BATTERY_CONFIG.vbatmincellvoltage * 10)) +// .push8(Math.round(BATTERY_CONFIG.vbatmaxcellvoltage * 10)) +// .push8(Math.round(BATTERY_CONFIG.vbatwarningcellvoltage * 10)); +// if (semver.gte(CONFIG.apiVersion, "1.23.0")) { +// buffer.push8(BATTERY_CONFIG.voltageMeterSource); +// } +// break; +// case MSPCodes.MSP_SET_CURRENT_METER_CONFIG: +// buffer.push16(BF_CONFIG.currentscale) +// .push16(BF_CONFIG.currentoffset) +// .push8(BATTERY_CONFIG.currentMeterSource) +// .push16(BF_CONFIG.batterycapacity) +// break; case MSPCodes.MSP_SET_RX_CONFIG: buffer.push8(RX_CONFIG.serialrx_provider) - .push16(RX_CONFIG.maxcheck) - .push16(RX_CONFIG.midrc) - .push16(RX_CONFIG.mincheck) + .push16(RX_CONFIG.stick_max) + .push16(RX_CONFIG.stick_center) + .push16(RX_CONFIG.stick_min) .push8(RX_CONFIG.spektrum_sat_bind) .push16(RX_CONFIG.rx_min_usec) .push16(RX_CONFIG.rx_max_usec); @@ -1116,6 +1291,9 @@ MspHelper.prototype.crunch = function(code) { break; case MSPCodes.MSP_SET_TRANSPONDER_CONFIG: + if (semver.gte(CONFIG.apiVersion, "1.33.0")) { + buffer.push8(TRANSPONDER.provider); // + } for (var i = 0; i < TRANSPONDER.data.length; i++) { buffer.push8(TRANSPONDER.data[i]); } @@ -1156,21 +1334,21 @@ MspHelper.prototype.crunch = function(code) { } break; - case MSPCodes.MSP_SET_3D: - buffer.push16(_3D.deadband3d_low) - .push16(_3D.deadband3d_high) - .push16(_3D.neutral3d); + case MSPCodes.MSP_SET_MOTOR_3D_CONFIG: + buffer.push16(MOTOR_3D_CONFIG.deadband3d_low) + .push16(MOTOR_3D_CONFIG.deadband3d_high) + .push16(MOTOR_3D_CONFIG.neutral); if (semver.lt(CONFIG.apiVersion, "1.17.0")) { - buffer.push16(_3D.deadband3d_throttle); + buffer.push16(RC_DEADBAND_CONFIG.deadband3d_throttle); } break; case MSPCodes.MSP_SET_RC_DEADBAND: - buffer.push8(RC_deadband.deadband) - .push8(RC_deadband.yaw_deadband) - .push8(RC_deadband.alt_hold_deadband); + buffer.push8(RC_DEADBAND_CONFIG.deadband) + .push8(RC_DEADBAND_CONFIG.yaw_deadband) + .push8(RC_DEADBAND_CONFIG.alt_hold_deadband); if (semver.gte(CONFIG.apiVersion, "1.17.0")) { - buffer.push16(_3D.deadband3d_throttle); + buffer.push16(RC_DEADBAND_CONFIG.deadband3d_throttle); } break; @@ -1209,7 +1387,7 @@ MspHelper.prototype.crunch = function(code) { } break; case MSPCodes.MSP_SET_PID_ADVANCED: - if (semver.gte(CONFIG.flightControllerVersion, "3.0.0")) { + if (semver.gte(CONFIG.apiVersion, "1.20.0")) { buffer.push16(ADVANCED_TUNING.rollPitchItermIgnoreRate) .push16(ADVANCED_TUNING.yawItermIgnoreRate) .push16(ADVANCED_TUNING.yaw_p_limit) @@ -1284,7 +1462,7 @@ MspHelper.prototype.setRawRx = function(channels) { MspHelper.prototype.dataflashRead = function(address, blockSize, onDataCallback) { var outData = [address & 0xFF, (address >> 8) & 0xFF, (address >> 16) & 0xFF, (address >> 24) & 0xFF]; - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { + if (semver.gte(CONFIG.apiVersion, "1.31.0")) { outData = outData.concat([blockSize & 0xFF, (blockSize >> 8) & 0xFF]); } @@ -1295,7 +1473,7 @@ MspHelper.prototype.dataflashRead = function(address, blockSize, onDataCallback) var headerSize = 4; var dataSize = response.data.buffer.byteLength - headerSize; var dataCompressionType = 0; - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { + if (semver.gte(CONFIG.apiVersion, "1.31.0")) { headerSize = headerSize + 3; dataSize = response.data.readU16(); dataCompressionType = response.data.readU8(); @@ -1355,9 +1533,12 @@ MspHelper.prototype.sendServoConfigurations = function(onCompleteCallback) { .push16(servoConfiguration.min) .push16(servoConfiguration.max) .push16(servoConfiguration.middle) - .push8(servoConfiguration.rate) - .push8(servoConfiguration.angleAtMin) - .push8(servoConfiguration.angleAtMax); + .push8(servoConfiguration.rate); + + if (semver.gte(CONFIG.apiVersion, "1.33.0")) { + buffer.push8(servoConfiguration.angleAtMin) + .push8(servoConfiguration.angleAtMax); + } var out = servoConfiguration.indexOfChannelToForward; if (out == undefined) { diff --git a/js/serial.js b/js/serial.js index 4407289b..da3aefec 100644 --- a/js/serial.js +++ b/js/serial.js @@ -1,6 +1,7 @@ 'use strict'; var serial = { + connected: false, connectionId: false, openRequested: false, openCanceled: false, @@ -38,6 +39,7 @@ var serial = { } if (connectionInfo && !self.openCanceled) { + self.connected = true; self.connectionId = connectionInfo.connectionId; self.bitrate = connectionInfo.bitrate; self.bytesReceived = 0; @@ -187,6 +189,7 @@ var serial = { console.log('onConnectedCallback', result) if(result == 0) { + self.connected = true; chrome.sockets.tcp.setNoDelay(createInfo.socketId, true, function (noDelayResult){ if (chrome.runtime.lastError) { console.error('setNoDelay', chrome.runtime.lastError.message); @@ -221,7 +224,6 @@ var serial = { }); console.log(self.logHead + 'Connection opened with ID: ' + createInfo.socketId + ', url: ' + self.connectionIP + ':' + self.connectionPort); - if (callback) callback(createInfo); }); } else { @@ -235,6 +237,7 @@ var serial = { }, disconnect: function (callback) { var self = this; + self.connected = false; if (self.connectionId) { self.emptyOutputBuffer(); @@ -300,9 +303,27 @@ var serial = { // store inside separate variables in case array gets destroyed var data = self.outputBuffer[0].data, callback = self.outputBuffer[0].callback; + + if (!self.connected) { + console.log('attempting to send when disconnected'); + if (callback) callback({ + bytesSent: 0, + error: 'undefined' + }); + return; + } var sendFn = (self.connectionType == 'serial') ? chrome.serial.send : chrome.sockets.tcp.send; sendFn(self.connectionId, data, function (sendInfo) { + if (sendInfo === undefined) { + console.log('undefined send error'); + if (callback) callback({ + bytesSent: 0, + error: 'undefined' + }); + return; + } + // tcp send error if (self.connectionType == 'tcp' && sendInfo.resultCode < 0) { var error = 'system_error'; diff --git a/js/serial_backend.js b/js/serial_backend.js index 6bbbb1db..7f1337b2 100755 --- a/js/serial_backend.js +++ b/js/serial_backend.js @@ -61,12 +61,11 @@ $(document).ready(function () { GUI.tab_switch_cleanup(); GUI.tab_switch_in_progress = false; + var wasConnected = CONFIGURATOR.connectionValid; + serial.disconnect(onClosed); - var wasConnected = CONFIGURATOR.connectionValid; - GUI.connected_to = false; - CONFIGURATOR.connectionValid = false; GUI.allowedTabs = GUI.defaultAllowedTabsWhenDisconnected.slice(); MSP.disconnect_cleanup(); PortUsage.reset(); @@ -74,7 +73,7 @@ $(document).ready(function () { // Reset various UI elements $('span.i2c-error').text(0); $('span.cycle-time').text(0); - if (CONFIG.flightControllerVersion !== '' && semver.gte(CONFIG.flightControllerVersion, "3.0.0")) + if (semver.gte(CONFIG.apiVersion, "1.20.0")) $('span.cpu-load').text(''); // unlock port select & baud @@ -211,7 +210,7 @@ function onOpen(openInfo) { // continue as usually CONFIGURATOR.connectionValid = true; - GUI.allowedTabs = GUI.defaultAllowedTabsWhenConnected.slice(); + GUI.allowedTabs = GUI.defaultAllowedFCTabsWhenConnected.slice(); if (semver.lt(CONFIG.apiVersion, "1.4.0")) { GUI.allowedTabs.splice(GUI.allowedTabs.indexOf('led_strip'), 1); } @@ -263,31 +262,47 @@ function onConnect() { GUI.timeout_remove('connecting'); // kill connecting timer $('div#connectbutton a.connect_state').text(chrome.i18n.getMessage('disconnect')).addClass('active'); $('div#connectbutton a.connect').addClass('active'); + $('#tabs ul.mode-disconnected').hide(); $('#tabs ul.mode-connected-cli').show(); + + // show only appropriate tabs + $('#tabs ul.mode-connected li').hide(); + $('#tabs ul.mode-connected li').filter(function (index) { + var classes = $(this).attr("class").split(/\s+/); + var found = false; + $.each(GUI.allowedTabs, function (index, value) { + var tabName = "tab_" + value; + if ($.inArray(tabName, classes) >= 0) { + found = true; + } + }); + + if (CONFIG.boardType == 0) { + if (classes.indexOf("osd-required") >= 0) { + found = false; + } + } + + return found; + }).show(); + if (CONFIG.flightControllerVersion !== '') { - BF_CONFIG.features = new Features(CONFIG); + FEATURE_CONFIG.features = new Features(CONFIG); $('#tabs ul.mode-connected').show(); - if (semver.gte(CONFIG.flightControllerVersion, "2.9.1")) { - MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false); - } else { - MSP.send_message(MSPCodes.MSP_STATUS, false, false); - - if (semver.gte(CONFIG.flightControllerVersion, "2.4.0")) { - CONFIG.numProfiles = 2; - $('.tab-pid_tuning select[name="profile"] .profile3').hide(); - } else { - CONFIG.numProfiles = 3; - $('.tab-pid_tuning select[name="rate_profile"]').hide(); - } + MSP.send_message(MSPCodes.MSP_FEATURE_CONFIG, false, false); + if (semver.gte(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_BATTERY_CONFIG, false, false); } - + MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false); MSP.send_message(MSPCodes.MSP_DATAFLASH_SUMMARY, false, false); - startLiveDataRefreshTimer(); + if (CONFIG.boardType == 0 || CONFIG.boardType == 2) { + startLiveDataRefreshTimer(); + } } var sensor_state = $('#sensor-status'); @@ -324,6 +339,10 @@ function onClosed(result) { battery.hide(); MSP.clearListeners(); + + CONFIGURATOR.connectionValid = false; + CONFIGURATOR.cliValid = false; + CONFIGURATOR.cliActive = false; } function read_serial(info) { @@ -359,7 +378,7 @@ function sensor_status(sensors_detected) { $('.accicon', e_sensor_status).removeClass('active'); } - if (true) { // Gyro status is not reported by FC + if (CONFIG.boardType == 0 || CONFIG.boardType == 2) { // Gyro status is not reported by FC $('.gyro', e_sensor_status).addClass('on'); $('.gyroicon', e_sensor_status).addClass('active'); } else { @@ -460,10 +479,10 @@ function update_live_status() { if (GUI.active_tab != 'cli') { MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false); - if (semver.gte(CONFIG.flightControllerVersion, "2.9.1")) - MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false); + if (semver.gte(CONFIG.apiVersion, "1.32.0")) + MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false); else - MSP.send_message(MSPCodes.MSP_STATUS, false, false); + MSP.send_message(MSPCodes.MSP_STATUS, false, false); MSP.send_message(MSPCodes.MSP_ANALOG, false, false); } @@ -492,13 +511,13 @@ function update_live_status() { } } if (ANALOG != undefined) { - var nbCells = Math.floor(ANALOG.voltage / MISC.vbatmaxcellvoltage) + 1; + var nbCells = Math.floor(ANALOG.voltage / BATTERY_CONFIG.vbatmaxcellvoltage) + 1; if (ANALOG.voltage == 0) nbCells = 1; - var min = MISC.vbatmincellvoltage * nbCells; - var max = MISC.vbatmaxcellvoltage * nbCells; - var warn = MISC.vbatwarningcellvoltage * nbCells; + var min = BATTERY_CONFIG.vbatmincellvoltage * nbCells; + var max = BATTERY_CONFIG.vbatmaxcellvoltage * nbCells; + var warn = BATTERY_CONFIG.vbatwarningcellvoltage * nbCells; $(".battery-status").css({ width: ((ANALOG.voltage - min) / (max - min) * 100) + "%", diff --git a/main.css b/main.css index 5255facc..2a12dc87 100644 --- a/main.css +++ b/main.css @@ -811,6 +811,19 @@ li.active .ic_transponder { background-image: url(images/icons/icon_osd_white.svg); } +.ic_power { + background-image: url(images/icons/cf_icon_power_grey.svg); + background-position-y: 9px; +} + +.ic_power:hover { + background-image: url(images/icons/cf_icon_power_white.svg); +} + +li.active .ic_power { + background-image: url(images/icons/cf_icon_power_white.svg); +} + /* SPARE Tab-Icons */ .ic_failsafe { background-image: url(images/icons/cf_icon_failsafe_grey.svg); @@ -1456,7 +1469,7 @@ dialog { /* fixing padding for all Tabs*/ .tab-setup, .tab-landing, .tab-adjustments, .tab-auxiliary, .tab-cli, .tab-configuration, .tab-failsafe, .tab-onboard_logging, .tab-firmware_flasher, .tab-gps, .tab-help, .tab-led-strip, .tab-logging, .tab-modes, .tab-motors, .tab-pid_tuning, - .tab-ports, .tab-receiver, .tab-sensors, .tab-servos, .tab-osd { + .tab-ports, .tab-receiver, .tab-sensors, .tab-servos, .tab-osd, .tab-power { height: 100%; position: relative; } diff --git a/main.html b/main.html index 8937488d..f941f6db 100755 --- a/main.html +++ b/main.html @@ -9,6 +9,7 @@ + @@ -27,7 +28,9 @@ + + @@ -69,6 +72,7 @@ + @@ -87,6 +91,7 @@ + @@ -213,9 +218,13 @@ - +
diff --git a/main.js b/main.js index d69325ed..0fbd6947 100644 --- a/main.js +++ b/main.js @@ -149,9 +149,16 @@ $(document).ready(function () { case 'osd': TABS.osd.initialize(content_ready); break; + case 'power': + TABS.power.initialize(content_ready); + break; case 'setup': TABS.setup.initialize(content_ready); break; + case 'setup_osd': + TABS.setup_osd.initialize(content_ready); + break; + case 'configuration': TABS.configuration.initialize(content_ready); break; @@ -228,8 +235,8 @@ $(document).ready(function () { chrome.storage.local.set({'permanentExpertMode': checked}); $('input[name="expertModeCheckbox"]').prop('checked', checked).change(); - if (BF_CONFIG) { - updateTabList(BF_CONFIG.features); + if (FEATURE_CONFIG) { + updateTabList(FEATURE_CONFIG.features); } }).change(); @@ -362,8 +369,8 @@ $(document).ready(function () { } $('input[name="expertModeCheckbox"]').change(function () { - if (BF_CONFIG) { - updateTabList(BF_CONFIG.features); + if (FEATURE_CONFIG) { + updateTabList(FEATURE_CONFIG.features); } }).change(); }); @@ -463,7 +470,6 @@ function updateTabList(features) { } else { $('#tabs ul.mode-connected li.tab_transponder').hide(); } - if (features.isEnabled('OSD')) { $('#tabs ul.mode-connected li.tab_osd').show(); } else { @@ -485,8 +491,13 @@ function generateFilename(prefix, suffix) { var date = new Date(); var filename = prefix; - if (CONFIG && CONFIG.name && CONFIG.name.trim() !== '') { - filename = filename + '_' + CONFIG.name.trim().replace(' ', '_'); + if (CONFIG) { + if (CONFIG.flightControllerIdentifier) { + filename = CONFIG.flightControllerIdentifier + '_' + filename; + } + if(CONFIG.name && CONFIG.name.trim() !== '') { + filename = filename + '_' + CONFIG.name.trim().replace(' ', '_'); + } } filename = filename + '_' + date.getFullYear() diff --git a/tabs/adjustments.js b/tabs/adjustments.js index 12eeebe7..21e750c0 100644 --- a/tabs/adjustments.js +++ b/tabs/adjustments.js @@ -273,7 +273,7 @@ TABS.adjustments.cleanup = function (callback) { TABS.adjustments.adjust_template = function () { var availableFunctionCount; - if (semver.lt(CONFIG.flightControllerVersion, '3.1.0')) { + if (semver.lt(CONFIG.apiVersion, "1.31.0")) { availableFunctionCount = 21; // Available in betaflight 2.9 } else { availableFunctionCount = 24; // RC rate Yaw / D setpoint / D setpoint transition added to 3.1.0 diff --git a/tabs/cli.js b/tabs/cli.js index 58a27955..5cdd3935 100644 --- a/tabs/cli.js +++ b/tabs/cli.js @@ -208,7 +208,7 @@ TABS.cli.sendLine = function (line, callback) { } TABS.cli.cleanup = function (callback) { - if (!CONFIGURATOR.connectionValid || !CONFIGURATOR.cliValid) { + if (!(CONFIGURATOR.connectionValid && CONFIGURATOR.cliValid && CONFIGURATOR.cliActive)) { if (callback) callback(); return; } diff --git a/tabs/configuration.css b/tabs/configuration.css index 755f5ce8..43b3a040 100644 --- a/tabs/configuration.css +++ b/tabs/configuration.css @@ -292,7 +292,7 @@ width: 150px; } -.tab-configuration .currentmetertype { +.tab-configuration .currentMeterSource { border: 1px solid silver; margin-right: 5px; float: left; diff --git a/tabs/configuration.html b/tabs/configuration.html index 4c704450..a872dd61 100644 --- a/tabs/configuration.html +++ b/tabs/configuration.html @@ -121,7 +121,8 @@
-
+ +
@@ -179,8 +180,6 @@
-
-
@@ -199,50 +198,47 @@
-
-
-
+
+
-
-
-
- - -
-
-
-
-

-
-
- - -
-
-
-
-
-
+
- - - - - + + + + + - +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
@@ -306,6 +302,32 @@
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
@@ -331,106 +353,59 @@
-
-
+
+ + +
+
-
+
-
- - - - - - - - - - - -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
+
+ +
-
-
-
-
-
-
- - - - - - - - - - - -
-
- -
-
- -
-
- -
-
- -
-
-
- +
+
+
+

-
+ +
-
+
+
+
+
+
+
+
+
+ + + + + + + + + + + +
+
+
+
+
+ +
+
@@ -467,6 +442,22 @@
+
+
+ +
+ +
+
+
+ +
+ +
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-
-
-
-
- -
-
- -
-
-
-
diff --git a/tabs/configuration.js b/tabs/configuration.js index 26b74fcc..a91b8184 100644 --- a/tabs/configuration.js +++ b/tabs/configuration.js @@ -12,43 +12,73 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } function load_config() { - MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, load_serial_config); + MSP.send_message(MSPCodes.MSP_FEATURE_CONFIG, false, false, load_serial_config); } function load_serial_config() { - var next_callback = load_rc_map; - if (semver.lt(CONFIG.apiVersion, "1.6.0")) { - MSP.send_message(MSPCodes.MSP_CF_SERIAL_CONFIG, false, false, next_callback); + MSP.send_message(MSPCodes.MSP_CF_SERIAL_CONFIG, false, false, load_board_alignment_config); + } + + function load_board_alignment_config() { + MSP.send_message(MSPCodes.MSP_BOARD_ALIGNMENT_CONFIG, false, false, load_rc_map); + } + + function load_rc_map() { + MSP.send_message(MSPCodes.MSP_RX_MAP, false, false, load_mixer_config); + } + + function load_mixer_config() { + MSP.send_message(MSPCodes.MSP_MIXER_CONFIG, false, false, load_rssi_config); + } + + function load_rssi_config() { + MSP.send_message(MSPCodes.MSP_RSSI_CONFIG, false, false, load_motor_config); + } + + function load_motor_config() { + var next_callback = load_compass_config; + if(semver.gte(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_MOTOR_CONFIG, false, false, next_callback); } else { next_callback(); } } - - function load_rc_map() { - MSP.send_message(MSPCodes.MSP_RX_MAP, false, false, load_misc); + + function load_compass_config() { + var next_callback = load_gps_config; + if(semver.gte(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_COMPASS_CONFIG, false, false, load_gps_config); + } else { + next_callback(); + } } - - function load_misc() { - MSP.send_message(MSPCodes.MSP_MISC, false, false, load_acc_trim); + + function load_gps_config() { + var next_callback = load_acc_trim; + if(semver.gte(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_GPS_CONFIG, false, false, load_acc_trim); + } else { + next_callback(); + } } function load_acc_trim() { - MSP.send_message(MSPCodes.MSP_ACC_TRIM, false, false, load_arming_config); + MSP.send_message(MSPCodes.MSP_ACC_TRIM, false, false, load_misc); } - function load_arming_config() { - var next_callback = load_loop_time; - if (semver.gte(CONFIG.apiVersion, "1.8.0")) { - MSP.send_message(MSPCodes.MSP_ARMING_CONFIG, false, false, next_callback); + function load_misc() { + var next_callback = load_arming_config; + if (semver.lt(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_MISC, false, false, next_callback); } else { next_callback(); } } - - function load_loop_time() { + + function load_arming_config() { var next_callback = load_3d; if (semver.gte(CONFIG.apiVersion, "1.8.0")) { - MSP.send_message(MSPCodes.MSP_LOOP_TIME, false, false, next_callback); + MSP.send_message(MSPCodes.MSP_ARMING_CONFIG, false, false, next_callback); } else { next_callback(); } @@ -57,7 +87,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) { function load_3d() { var next_callback = load_rc_deadband; if (semver.gte(CONFIG.apiVersion, "1.14.0")) { - MSP.send_message(MSPCodes.MSP_3D, false, false, next_callback); + MSP.send_message(MSPCodes.MSP_MOTOR_3D_CONFIG, false, false, next_callback); } else { next_callback(); } @@ -74,7 +104,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) { function esc_protocol() { var next_callback = sensor_config; - if (semver.gte(CONFIG.flightControllerVersion, "2.8.1")) { + if (semver.gte(CONFIG.apiVersion, "1.16.0")) { MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, next_callback); } else { next_callback(); @@ -83,7 +113,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) { function sensor_config() { var next_callback = load_sensor_alignment; - if (semver.gte(CONFIG.flightControllerVersion, "2.8.2")) { + if (semver.gte(CONFIG.apiVersion, "1.16.0")) { MSP.send_message(MSPCodes.MSP_SENSOR_CONFIG, false, false, next_callback); } else { next_callback(); @@ -100,28 +130,14 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } function load_name() { - var next_callback = load_battery; - if (semver.gte(CONFIG.flightControllerVersion, "3.0.0")) { + var next_callback = load_rx_config; + if (semver.gte(CONFIG.apiVersion, "1.20.0")) { MSP.send_message(MSPCodes.MSP_NAME, false, false, next_callback); } else { next_callback(); } } - function load_battery() { - var next_callback = load_current; - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { - MSP.send_message(MSPCodes.MSP_VOLTAGE_METER_CONFIG, false, false, next_callback); - } else { - next_callback(); - } - } - - function load_current() { - var next_callback = load_rx_config; - MSP.send_message(MSPCodes.MSP_CURRENT_METER_CONFIG, false, false, next_callback); - } - function load_rx_config() { var next_callback = load_html; if (semver.gte(CONFIG.apiVersion, "1.31.0")) { @@ -131,14 +147,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } } - //Update Analog/Battery Data - function load_analog() { - MSP.send_message(MSPCodes.MSP_ANALOG, false, false, function () { - $('input[name="batteryvoltage"]').val([ANALOG.voltage.toFixed(1)]); - $('input[name="batterycurrent"]').val([ANALOG.amperage.toFixed(2)]); - }); - } - function load_html() { $('#content').load("./tabs/configuration.html", process_html); } @@ -158,17 +166,17 @@ TABS.configuration.initialize = function (callback, scrollPosition) { mixer_list_e.change(function () { var val = parseInt($(this).val()); - BF_CONFIG.mixerConfiguration = val; + MIXER_CONFIG.mixer = val; $('.mixerPreview img').attr('src', './resources/motor_order/' + mixerList[val - 1].image + '.svg'); }); // select current mixer configuration - mixer_list_e.val(BF_CONFIG.mixerConfiguration).change(); + mixer_list_e.val(MIXER_CONFIG.mixer).change(); var features_e = $('.tab-configuration .features'); - BF_CONFIG.features.generateElements(features_e); + FEATURE_CONFIG.features.generateElements(features_e); // translate to user-selected language localize(); @@ -209,11 +217,11 @@ TABS.configuration.initialize = function (callback, scrollPosition) { 'MULTISHOT' ]; - if (semver.gte(CONFIG.flightControllerVersion, "3.0.0")) { + if (semver.gte(CONFIG.apiVersion, "1.20.0")) { escprotocols.push('BRUSHED'); } - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { + if (semver.gte(CONFIG.apiVersion, "1.31.0")) { escprotocols.push('DSHOT150'); escprotocols.push('DSHOT300'); escprotocols.push('DSHOT600'); @@ -343,17 +351,17 @@ TABS.configuration.initialize = function (callback, scrollPosition) { $('input[id="magHardwareSwitch"]').prop('checked', SENSOR_CONFIG.mag_hardware !== 1); // Only show these sections for supported FW - if (semver.lt(CONFIG.flightControllerVersion, "2.8.1")) { + if (semver.lt(CONFIG.apiVersion, "1.16.0")) { $('.selectProtocol').hide(); $('.checkboxPwm').hide(); $('.selectPidProcessDenom').hide(); } - if (semver.lt(CONFIG.flightControllerVersion, "2.8.2")) { + if (semver.lt(CONFIG.apiVersion, "1.16.0")) { $('.hardwareSelection').hide(); } - $('input[name="vesselName"]').val(CONFIG.name); + $('input[name="craftName"]').val(CONFIG.name); if (semver.gte(CONFIG.apiVersion, "1.31.0")) { @@ -362,7 +370,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) { $('div.fpvCamAngleDegrees').hide(); } - if (semver.lt(CONFIG.flightControllerVersion, "3.0.0")) { + if (semver.lt(CONFIG.apiVersion, "1.20.0")) { $('.miscSettings').hide(); } @@ -395,11 +403,20 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } gps_protocol_e.change(function () { - MISC.gps_type = parseInt($(this).val()); + GPS_CONFIG.provider = parseInt($(this).val()); }); - gps_protocol_e.val(MISC.gps_type); + gps_protocol_e.val(GPS_CONFIG.provider); + $('input[name="gps_auto_baud"]').prop('checked', GPS_CONFIG.auto_baud == 1); + $('input[name="gps_auto_config"]').prop('checked', GPS_CONFIG.auto_config == 1); + if (semver.gte(CONFIG.apiVersion, "1.34.0")) { + $('.select.gps_auto_baud').show(); + $('.select.gps_auto_config').show(); + } else { + $('.select.gps_auto_baud').hide(); + $('.select.gps_auto_config').hide(); + } var gps_baudrate_e = $('select.gps_baudrate'); for (var i = 0; i < gpsBaudRates.length; i++) { @@ -423,10 +440,10 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } gps_ubx_sbas_e.change(function () { - MISC.gps_ubx_sbas = parseInt($(this).val()); + GPS_CONFIG.ublox_sbas = parseInt($(this).val()); }); - gps_ubx_sbas_e.val(MISC.gps_ubx_sbas); + gps_ubx_sbas_e.val(GPS_CONFIG.ublox_sbas); // generate serial RX @@ -444,11 +461,12 @@ TABS.configuration.initialize = function (callback, scrollPosition) { serialRXtypes.push('IBUS'); } - if (semver.gte(CONFIG.flightControllerVersion, "2.6.0")) { + if ((CONFIG.flightControllerIdentifier === 'BTFL' && semver.gte(CONFIG.flightControllerVersion, "2.6.0")) || + (CONFIG.flightControllerIdentifier === 'CLFL' && semver.gte(CONFIG.apiVersion, "1.31.0"))) { serialRXtypes.push('JETIEXBUS'); } - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { + if (semver.gte(CONFIG.apiVersion, "1.31.0")) { serialRXtypes.push('CRSF'); } @@ -460,6 +478,10 @@ TABS.configuration.initialize = function (callback, scrollPosition) { serialRXtypes.push('TARGET_CUSTOM'); } + if (semver.gte(CONFIG.apiVersion, "1.35.0")) { + serialRXtypes.push('TARGET_CUSTOM'); + } + var serialRX_e = $('select.serialRX'); for (var i = 0; i < serialRXtypes.length; i++) { serialRX_e.append(''); @@ -478,16 +500,16 @@ TABS.configuration.initialize = function (callback, scrollPosition) { $('#content').scrollTop((scrollPosition) ? scrollPosition : 0); // fill board alignment - $('input[name="board_align_roll"]').val(BF_CONFIG.board_align_roll); - $('input[name="board_align_pitch"]').val(BF_CONFIG.board_align_pitch); - $('input[name="board_align_yaw"]').val(BF_CONFIG.board_align_yaw); + $('input[name="board_align_roll"]').val(BOARD_ALIGNMENT_CONFIG.roll); + $('input[name="board_align_pitch"]').val(BOARD_ALIGNMENT_CONFIG.pitch); + $('input[name="board_align_yaw"]').val(BOARD_ALIGNMENT_CONFIG.yaw); // fill accel trims $('input[name="roll"]').val(CONFIG.accelerometerTrims[1]); $('input[name="pitch"]').val(CONFIG.accelerometerTrims[0]); // fill magnetometer - $('input[name="mag_declination"]').val(MISC.mag_declination.toFixed(2)); + $('input[name="mag_declination"]').val(COMPASS_CONFIG.mag_declination.toFixed(2)); //fill motor disarm params and FC loop time if(semver.gte(CONFIG.apiVersion, "1.8.0")) { @@ -499,75 +521,22 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } // fill throttle - $('input[name="minthrottle"]').val(MISC.minthrottle); - $('input[name="maxthrottle"]').val(MISC.maxthrottle); - $('input[name="mincommand"]').val(MISC.mincommand); - - // fill battery - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { - var batteryMeterTypes = [ - 'Onboard ADC', - 'ESC Sensor' - ]; - - var batteryMeterType_e = $('select.batterymetertype'); - for (i = 0; i < batteryMeterTypes.length; i++) { - batteryMeterType_e.append(''); - } - - batteryMeterType_e.change(function () { - MISC.batterymetertype = parseInt($(this).val()); - checkUpdateVbatControls(); - }); - batteryMeterType_e.val(MISC.batterymetertype).change(); - } else { - $('div.batterymetertype').hide(); - } - - $('input[name="mincellvoltage"]').val(MISC.vbatmincellvoltage); - $('input[name="maxcellvoltage"]').val(MISC.vbatmaxcellvoltage); - $('input[name="warningcellvoltage"]').val(MISC.vbatwarningcellvoltage); - $('input[name="voltagescale"]').val(MISC.vbatscale); - - // fill current - var currentMeterTypes = [ - 'None', - 'Onboard ADC', - 'Virtual' - ]; - - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { - currentMeterTypes.push('ESC Sensor'); - } - - var currentMeterType_e = $('select.currentmetertype'); - for (i = 0; i < currentMeterTypes.length; i++) { - currentMeterType_e.append(''); - } - - currentMeterType_e.change(function () { - BF_CONFIG.currentmetertype = parseInt($(this).val()); - checkUpdateCurrentControls(); - }); - currentMeterType_e.val(BF_CONFIG.currentmetertype).change(); - - $('input[name="currentscale"]').val(BF_CONFIG.currentscale); - $('input[name="currentoffset"]').val(BF_CONFIG.currentoffset); - $('input[name="multiwiicurrentoutput"]').prop('checked', MISC.multiwiicurrentoutput !== 0); + $('input[name="minthrottle"]').val(MOTOR_CONFIG.minthrottle); + $('input[name="maxthrottle"]').val(MOTOR_CONFIG.maxthrottle); + $('input[name="mincommand"]').val(MOTOR_CONFIG.mincommand); //fill 3D if (semver.lt(CONFIG.apiVersion, "1.14.0")) { $('.tab-configuration ._3d').hide(); } else { - $('input[name="3ddeadbandlow"]').val(_3D.deadband3d_low); - $('input[name="3ddeadbandhigh"]').val(_3D.deadband3d_high); - $('input[name="3dneutral"]').val(_3D.neutral3d); - $('input[name="3ddeadbandthrottle"]').val(_3D.deadband3d_throttle); + $('input[name="3ddeadbandlow"]').val(MOTOR_3D_CONFIG.deadband3d_low); + $('input[name="3ddeadbandhigh"]').val(MOTOR_3D_CONFIG.deadband3d_high); + $('input[name="3dneutral"]').val(MOTOR_3D_CONFIG.neutral); } // UI hooks function checkShowDisarmDelay() { - if (BF_CONFIG.features.isEnabled('MOTOR_STOP')) { + if (FEATURE_CONFIG.features.isEnabled('MOTOR_STOP')) { $('div.disarmdelay').show(); } else { $('div.disarmdelay').hide(); @@ -575,55 +544,15 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } function checkShowSerialRxBox() { - if (BF_CONFIG.features.isEnabled('RX_SERIAL')) { + if (FEATURE_CONFIG.features.isEnabled('RX_SERIAL')) { $('div.serialRXBox').show(); } else { $('div.serialRXBox').hide(); } } - function checkUpdateVbatControls() { - if (BF_CONFIG.features.isEnabled('VBAT')) { - $('.vbatmonitoring').show(); - - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { - $('select.batterymetertype').show(); - - if (MISC.batterymetertype !== 0) { - $('.vbatCalibration').hide(); - } - } else { - $('select.batterymetertype').hide(); - } - } else { - $('.vbatmonitoring').hide(); - } - } - - function checkUpdateCurrentControls() { - if (BF_CONFIG.features.isEnabled('CURRENT_METER')) { - $('.currentMonitoring').show(); - - switch(BF_CONFIG.currentmetertype) { - case 0: - $('.currentCalibration').hide(); - $('.currentOutput').hide(); - - break; - case 3: - $('.currentCalibration').hide(); - } - - if (BF_CONFIG.currentmetertype !== 1 && BF_CONFIG.currentmetertype !== 2) { - $('.currentCalibration').hide(); - } - } else { - $('.currentMonitoring').hide(); - } - } - function checkUpdateGpsControls() { - if (BF_CONFIG.features.isEnabled('GPS')) { + if (FEATURE_CONFIG.features.isEnabled('GPS')) { $('.gpsSettings').show(); } else { $('.gpsSettings').hide(); @@ -631,7 +560,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } function checkUpdate3dControls() { - if (BF_CONFIG.features.isEnabled('3D')) { + if (FEATURE_CONFIG.features.isEnabled('3D')) { $('._3dSettings').show(); } else { $('._3dSettings').hide(); @@ -641,30 +570,22 @@ TABS.configuration.initialize = function (callback, scrollPosition) { $('input.feature', features_e).change(function () { var element = $(this); - BF_CONFIG.features.updateData(element); - updateTabList(BF_CONFIG.features); + FEATURE_CONFIG.features.updateData(element); + updateTabList(FEATURE_CONFIG.features); switch (element.attr('name')) { case 'MOTOR_STOP': checkShowDisarmDelay(); - break; - case 'VBAT': - checkUpdateVbatControls(); - break; - case 'CURRENT_METER': - checkUpdateCurrentControls(); - - break; case 'GPS': checkUpdateGpsControls(); - break; + case '3D': checkUpdate3dControls(); - break; + default: break; } @@ -673,8 +594,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) { $(features_e).filter('select').change(function () { var element = $(this); - BF_CONFIG.features.updateData(element); - updateTabList(BF_CONFIG.features); + FEATURE_CONFIG.features.updateData(element); + updateTabList(FEATURE_CONFIG.features); switch (element.attr('name')) { case 'rxMode': @@ -688,8 +609,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) { checkShowDisarmDelay(); checkShowSerialRxBox(); - checkUpdateVbatControls(); - checkUpdateCurrentControls(); checkUpdateGpsControls(); checkUpdate3dControls(); @@ -703,13 +622,13 @@ TABS.configuration.initialize = function (callback, scrollPosition) { $('a.save').click(function () { // gather data that doesn't have automatic change event bound - BF_CONFIG.board_align_roll = parseInt($('input[name="board_align_roll"]').val()); - BF_CONFIG.board_align_pitch = parseInt($('input[name="board_align_pitch"]').val()); - BF_CONFIG.board_align_yaw = parseInt($('input[name="board_align_yaw"]').val()); + BOARD_ALIGNMENT_CONFIG.roll = parseInt($('input[name="board_align_roll"]').val()); + BOARD_ALIGNMENT_CONFIG.pitch = parseInt($('input[name="board_align_pitch"]').val()); + BOARD_ALIGNMENT_CONFIG.yaw = parseInt($('input[name="board_align_yaw"]').val()); CONFIG.accelerometerTrims[1] = parseInt($('input[name="roll"]').val()); CONFIG.accelerometerTrims[0] = parseInt($('input[name="pitch"]').val()); - MISC.mag_declination = parseFloat($('input[name="mag_declination"]').val()); + COMPASS_CONFIG.mag_declination = parseFloat($('input[name="mag_declination"]').val()); // motor disarm if(semver.gte(CONFIG.apiVersion, "1.8.0")) { @@ -717,24 +636,14 @@ TABS.configuration.initialize = function (callback, scrollPosition) { ARMING_CONFIG.disarm_kill_switch = $('input[id="disarmkillswitch"]').is(':checked') ? 1 : 0; } - MISC.minthrottle = parseInt($('input[name="minthrottle"]').val()); - MISC.maxthrottle = parseInt($('input[name="maxthrottle"]').val()); - MISC.mincommand = parseInt($('input[name="mincommand"]').val()); - - MISC.vbatmincellvoltage = parseFloat($('input[name="mincellvoltage"]').val()); - MISC.vbatmaxcellvoltage = parseFloat($('input[name="maxcellvoltage"]').val()); - MISC.vbatwarningcellvoltage = parseFloat($('input[name="warningcellvoltage"]').val()); - MISC.vbatscale = parseInt($('input[name="voltagescale"]').val()); - - BF_CONFIG.currentscale = parseInt($('input[name="currentscale"]').val()); - BF_CONFIG.currentoffset = parseInt($('input[name="currentoffset"]').val()); - MISC.multiwiicurrentoutput = $('input[name="multiwiicurrentoutput"]').is(':checked') ? 1 : 0; + MOTOR_CONFIG.minthrottle = parseInt($('input[name="minthrottle"]').val()); + MOTOR_CONFIG.maxthrottle = parseInt($('input[name="maxthrottle"]').val()); + MOTOR_CONFIG.mincommand = parseInt($('input[name="mincommand"]').val()); if(semver.gte(CONFIG.apiVersion, "1.14.0")) { - _3D.deadband3d_low = parseInt($('input[name="3ddeadbandlow"]').val()); - _3D.deadband3d_high = parseInt($('input[name="3ddeadbandhigh"]').val()); - _3D.neutral3d = parseInt($('input[name="3dneutral"]').val()); - _3D.deadband3d_throttle = ($('input[name="3ddeadbandthrottle"]').val()); + MOTOR_3D_CONFIG.deadband3d_low = parseInt($('input[name="3ddeadbandlow"]').val()); + MOTOR_3D_CONFIG.deadband3d_high = parseInt($('input[name="3ddeadbandhigh"]').val()); + MOTOR_3D_CONFIG.neutral = parseInt($('input[name="3dneutral"]').val()); } SENSOR_ALIGNMENT.align_gyro = parseInt(orientation_gyro_e.val()); @@ -756,111 +665,113 @@ TABS.configuration.initialize = function (callback, scrollPosition) { } function save_serial_config() { - if (semver.lt(CONFIG.apiVersion, "1.6.0")) { - MSP.send_message(MSPCodes.MSP_SET_CF_SERIAL_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_CF_SERIAL_CONFIG), false, save_misc); - } else { - save_misc(); - } + var next_callback = save_feature_config; + MSP.send_message(MSPCodes.MSP_SET_CF_SERIAL_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_CF_SERIAL_CONFIG), false, next_callback); + } + + function save_feature_config() { + var next_callback = save_misc; + MSP.send_message(MSPCodes.MSP_SET_FEATURE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FEATURE_CONFIG), false, next_callback); } function save_misc() { - MSP.send_message(MSPCodes.MSP_SET_MISC, mspHelper.crunch(MSPCodes.MSP_SET_MISC), false, save_3d); - } - - function save_3d() { - var next_callback = save_rc_deadband; - if(semver.gte(CONFIG.apiVersion, "1.14.0")) { - MSP.send_message(MSPCodes.MSP_SET_3D, mspHelper.crunch(MSPCodes.MSP_SET_3D), false, next_callback); + var next_callback = save_mixer_config; + if(semver.lt(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_SET_MISC, mspHelper.crunch(MSPCodes.MSP_SET_MISC), false, next_callback); } else { next_callback(); } } + function save_mixer_config() { + var next_callback = save_board_alignment_config; + MSP.send_message(MSPCodes.MSP_SET_MIXER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_MIXER_CONFIG), false, next_callback); + } + + function save_board_alignment_config() { + var next_callback = save_motor_config; + MSP.send_message(MSPCodes.MSP_SET_BOARD_ALIGNMENT_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BOARD_ALIGNMENT_CONFIG), false, next_callback); + } + + function save_motor_config() { + var next_callback = save_gps_config; + if(semver.gte(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_SET_MOTOR_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_MOTOR_CONFIG), false, next_callback); + } else { + next_callback(); + } + } + + function save_gps_config() { + if (semver.gte(CONFIG.apiVersion, "1.34.0")) { + GPS_CONFIG.auto_baud = $('input[name="gps_auto_baud"]').is(':checked') ? 1 : 0; + GPS_CONFIG.auto_config = $('input[name="gps_auto_config"]').is(':checked') ? 1 : 0; + } + + var next_callback = save_compass_config; + if(semver.gte(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_SET_GPS_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_GPS_CONFIG), false, next_callback); + } else { + next_callback(); + } + } + + function save_compass_config() { + var next_callback = save_motor_3d_config; + if(semver.gte(CONFIG.apiVersion, "1.33.0")) { + MSP.send_message(MSPCodes.MSP_SET_COMPASS_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_COMPASS_CONFIG), false, next_callback); + } else { + next_callback(); + } + } + + function save_motor_3d_config() { + var next_callback = save_rc_deadband; + MSP.send_message(MSPCodes.MSP_SET_MOTOR_3D_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_MOTOR_3D_CONFIG), false, next_callback); + } + function save_rc_deadband() { var next_callback = save_sensor_alignment; - if(semver.gte(CONFIG.apiVersion, "1.17.0")) { - MSP.send_message(MSPCodes.MSP_SET_RC_DEADBAND, mspHelper.crunch(MSPCodes.MSP_SET_RC_DEADBAND), false, next_callback); - } else { - next_callback(); - } + MSP.send_message(MSPCodes.MSP_SET_RC_DEADBAND, mspHelper.crunch(MSPCodes.MSP_SET_RC_DEADBAND), false, next_callback); } function save_sensor_alignment() { var next_callback = save_esc_protocol; - if(semver.gte(CONFIG.apiVersion, "1.15.0")) { - MSP.send_message(MSPCodes.MSP_SET_SENSOR_ALIGNMENT, mspHelper.crunch(MSPCodes.MSP_SET_SENSOR_ALIGNMENT), false, next_callback); - } else { - next_callback(); - } + MSP.send_message(MSPCodes.MSP_SET_SENSOR_ALIGNMENT, mspHelper.crunch(MSPCodes.MSP_SET_SENSOR_ALIGNMENT), false, next_callback); } function save_esc_protocol() { var next_callback = save_acc_trim; - if (semver.gte(CONFIG.flightControllerVersion, "2.8.1")) { - MSP.send_message(MSPCodes.MSP_SET_ADVANCED_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ADVANCED_CONFIG), false, next_callback); - } else { - next_callback(); - } + MSP.send_message(MSPCodes.MSP_SET_ADVANCED_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ADVANCED_CONFIG), false, next_callback); } function save_acc_trim() { - MSP.send_message(MSPCodes.MSP_SET_ACC_TRIM, mspHelper.crunch(MSPCodes.MSP_SET_ACC_TRIM), false - , semver.gte(CONFIG.apiVersion, "1.8.0") ? save_arming_config : save_to_eeprom); + var next_callback = save_arming_config; + MSP.send_message(MSPCodes.MSP_SET_ACC_TRIM, mspHelper.crunch(MSPCodes.MSP_SET_ACC_TRIM), false, next_callback); } function save_arming_config() { - MSP.send_message(MSPCodes.MSP_SET_ARMING_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ARMING_CONFIG), false, save_looptime_config); + MSP.send_message(MSPCodes.MSP_SET_ARMING_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ARMING_CONFIG), false, save_sensor_config); } - function save_looptime_config() { - var next_callback = save_sensor_config; - if (semver.lt(CONFIG.flightControllerVersion, "2.8.1")) { - FC_CONFIG.loopTime = PID_ADVANCED_CONFIG.gyro_sync_denom * 125; - MSP.send_message(MSPCodes.MSP_SET_LOOP_TIME, mspHelper.crunch(MSPCodes.MSP_SET_LOOP_TIME), false, next_callback); - } else { - next_callback(); - } - } function save_sensor_config() { + SENSOR_CONFIG.acc_hardware = $('input[id="accHardwareSwitch"]').is(':checked') ? 0 : 1; + SENSOR_CONFIG.baro_hardware = $('input[id="baroHardwareSwitch"]').is(':checked') ? 0 : 1; + SENSOR_CONFIG.mag_hardware = $('input[id="magHardwareSwitch"]').is(':checked') ? 0 : 1; + var next_callback = save_name; - - if (semver.gte(CONFIG.flightControllerVersion, "2.8.2")) { - SENSOR_CONFIG.acc_hardware = $('input[id="accHardwareSwitch"]').is(':checked') ? 0 : 1; - SENSOR_CONFIG.baro_hardware = $('input[id="baroHardwareSwitch"]').is(':checked') ? 0 : 1; - SENSOR_CONFIG.mag_hardware = $('input[id="magHardwareSwitch"]').is(':checked') ? 0 : 1; - MSP.send_message(MSPCodes.MSP_SET_SENSOR_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_SENSOR_CONFIG), false, next_callback); - } else { - next_callback(); - } + MSP.send_message(MSPCodes.MSP_SET_SENSOR_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_SENSOR_CONFIG), false, next_callback); } function save_name() { - var next_callback = save_battery; - - if (semver.gte(CONFIG.flightControllerVersion, "3.0.0")) { - CONFIG.name = $.trim($('input[name="vesselName"]').val()); - MSP.send_message(MSPCodes.MSP_SET_NAME, mspHelper.crunch(MSPCodes.MSP_SET_NAME), false, next_callback); - } else { - next_callback(); - } - } - - function save_battery() { - var next_callback = save_current; - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { - MSP.send_message(MSPCodes.MSP_SET_VOLTAGE_METER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_VOLTAGE_METER_CONFIG), false, next_callback); - } else { - next_callback(); - } - } - - function save_current() { var next_callback = save_rx_config; - MSP.send_message(MSPCodes.MSP_SET_CURRENT_METER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_CURRENT_METER_CONFIG), false, next_callback); + + CONFIG.name = $.trim($('input[name="craftName"]').val()); + MSP.send_message(MSPCodes.MSP_SET_NAME, mspHelper.crunch(MSPCodes.MSP_SET_NAME), false, next_callback); } function save_rx_config() { var next_callback = save_to_eeprom; - if (semver.gte(CONFIG.apiVersion, "1.31.0")) { + if (semver.gte(CONFIG.apiVersion, "1.20.0")) { MSP.send_message(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG), false, next_callback); } else { next_callback(); @@ -897,16 +808,14 @@ TABS.configuration.initialize = function (callback, scrollPosition) { },1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts } } - - MSP.send_message(MSPCodes.MSP_SET_BF_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BF_CONFIG), false, save_serial_config); - + + save_serial_config(); }); // status data pulled via separate timer with static speed GUI.interval_add('status_pull', function status_pull() { MSP.send_message(MSPCodes.MSP_STATUS); }, 250, true); - GUI.interval_add('config_load_analog', load_analog, 250, true); // 4 fps GUI.content_ready(callback); } }; diff --git a/tabs/failsafe.html b/tabs/failsafe.html index 55e5a8c1..fb00ecdc 100644 --- a/tabs/failsafe.html +++ b/tabs/failsafe.html @@ -4,37 +4,14 @@
-
+

-
-
-

-

-
-
-
-
-
-
-
- - - - -
-
- -
-
-
-
+
@@ -52,7 +29,7 @@
-
+
@@ -65,7 +42,7 @@
-
+
diff --git a/tabs/failsafe.js b/tabs/failsafe.js index 28a9fcce..af914804 100644 --- a/tabs/failsafe.js +++ b/tabs/failsafe.js @@ -34,33 +34,31 @@ TABS.failsafe.initialize = function (callback, scrollPosition) { } function get_rc_data() { - MSP.send_message(MSPCodes.MSP_RC, false, false, load_config); + MSP.send_message(MSPCodes.MSP_RC, false, false, load_feature_config); } - // BEGIN Support for pre API version 1.15.0 - function load_config() { - MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, load_misc); + function load_feature_config() { + MSP.send_message(MSPCodes.MSP_FEATURE_CONFIG, false, false, load_motor_config); } - function load_misc() { - MSP.send_message(MSPCodes.MSP_MISC, false, false, load_html); + function load_motor_config() { + MSP.send_message(MSPCodes.MSP_MOTOR_CONFIG, false, false, load_compass_config); + } + + function load_compass_config() { + MSP.send_message(MSPCodes.MSP_COMPASS_CONFIG, false, false, load_gps_config); + } + + function load_gps_config() { + MSP.send_message(MSPCodes.MSP_GPS_CONFIG, false, false, load_html); } - // END (Support for pre API version 1.15.0 function load_html() { $('#content').load("./tabs/failsafe.html", process_html); } - var apiVersionGte1_15_0 = semver.gte(CONFIG.apiVersion, "1.15.0"); - // Uncomment next line for testing older functionality on newer API version - //apiVersionGte1_15_0 = false; - - if(apiVersionGte1_15_0) { - load_rx_config(); - } else { - load_config(); - } + load_rx_config(); function process_html() { // fill stage 2 fields @@ -72,244 +70,221 @@ TABS.failsafe.initialize = function (callback, scrollPosition) { } } - // Conditionally hide the old or the new control pane's - if(apiVersionGte1_15_0) { - var oldPane = $('div.oldpane'); - oldPane.prop("disabled", true); - oldPane.hide(); - } else { - var newPane = $('div.newpane'); - newPane.prop("disabled", true); - newPane.hide(); + // FIXME cleanup oldpane html and css + var oldPane = $('div.oldpane'); + oldPane.prop("disabled", true); + oldPane.hide(); + + // generate labels for assigned aux modes + var auxAssignment = [], + i, + element; + + for (var channelIndex = 0; channelIndex < RC.active_channels - 4; channelIndex++) { + auxAssignment.push(""); } - if (apiVersionGte1_15_0) { - // generate labels for assigned aux modes - var auxAssignment = [], - i, - element; + for (var modeIndex = 0; modeIndex < AUX_CONFIG.length; modeIndex++) { - for (var channelIndex = 0; channelIndex < RC.active_channels - 4; channelIndex++) { - auxAssignment.push(""); - } + var modeId = AUX_CONFIG_IDS[modeIndex]; - for (var modeIndex = 0; modeIndex < AUX_CONFIG.length; modeIndex++) { + // scan mode ranges to find assignments + for (var modeRangeIndex = 0; modeRangeIndex < MODE_RANGES.length; modeRangeIndex++) { + var modeRange = MODE_RANGES[modeRangeIndex]; - var modeId = AUX_CONFIG_IDS[modeIndex]; - - // scan mode ranges to find assignments - for (var modeRangeIndex = 0; modeRangeIndex < MODE_RANGES.length; modeRangeIndex++) { - var modeRange = MODE_RANGES[modeRangeIndex]; - - if (modeRange.id != modeId) { - continue; - } - - var range = modeRange.range; - if (!(range.start < range.end)) { - continue; // invalid! - } - - auxAssignment[modeRange.auxChannelIndex] += "" + AUX_CONFIG[modeIndex] + ""; + if (modeRange.id != modeId) { + continue; } - } - // generate full channel list - var channelNames = [ - chrome.i18n.getMessage('controlAxisRoll'), - chrome.i18n.getMessage('controlAxisPitch'), - chrome.i18n.getMessage('controlAxisYaw'), - chrome.i18n.getMessage('controlAxisThrottle') - ], - fullChannels_e = $('div.activechannellist'), - aux_index = 1, - aux_assignment_index = 0; - - for (i = 0; i < RXFAIL_CONFIG.length; i++) { - if (i < channelNames.length) { - fullChannels_e.append('\ -
\ -
\ - ' + channelNames[i] + '\ -
\ -
\ - \ -
\ -
\ - '); - } else { - fullChannels_e.append('\ -
\ -
\ - ' + chrome.i18n.getMessage("controlAxisAux" + (aux_index++)) + '\ - ' + auxAssignment[aux_assignment_index++] + '\ -
\ -
\ - \ -
\ -
\ -
\ - '); + var range = modeRange.range; + if (!(range.start < range.end)) { + continue; // invalid! } + + auxAssignment[modeRange.auxChannelIndex] += "" + AUX_CONFIG[modeIndex] + ""; } - - var channel_mode_array = []; - $('.number', fullChannels_e).each(function () { - channel_mode_array.push($('select.aux_set' , this)); - }); - - var channel_value_array = []; - $('.number', fullChannels_e).each(function () { - channel_value_array.push($('input[name="aux_value"]' , this)); - }); - - var channelMode = $('select.aux_set'); - var channelValue = $('input[name="aux_value"]'); - - // UI hooks - channelMode.change(function () { - var currentMode = parseInt($(this).val()); - var i = parseInt($(this).prop("id")); - RXFAIL_CONFIG[i].mode = currentMode; - if (currentMode == 2) { - channel_value_array[i].prop("disabled", false); - channel_value_array[i].show(); - } else { - channel_value_array[i].prop("disabled", true); - channel_value_array[i].hide(); - } - }); - - // UI hooks - channelValue.change(function () { - var i = parseInt($(this).prop("id")); - RXFAIL_CONFIG[i].value = parseInt($(this).val()); - }); - - // for some odd reason chrome 38+ changes scroll according to the touched select element - // i am guessing this is a bug, since this wasn't happening on 37 - // code below is a temporary fix, which we will be able to remove in the future (hopefully) - $('#content').scrollTop((scrollPosition) ? scrollPosition : 0); - - // fill stage 1 Valid Pulse Range Settings - $('input[name="rx_min_usec"]').val(RX_CONFIG.rx_min_usec); - $('input[name="rx_max_usec"]').val(RX_CONFIG.rx_max_usec); - - // fill fallback settings (mode and value) for all channels - for (i = 0; i < RXFAIL_CONFIG.length; i++) { - channel_value_array[i].val(RXFAIL_CONFIG[i].value); - channel_mode_array[i].val(RXFAIL_CONFIG[i].mode); - channel_mode_array[i].change(); - } - - BF_CONFIG.features.generateElements($('.tab-failsafe .featuresNew')); - - var failsafeFeature = $('input[name="FAILSAFE"]'); - failsafeFeature.change(function () { - toggleStage2($(this).is(':checked')); - }); - toggleStage2(BF_CONFIG.features.isEnabled('FAILSAFE')); - - $('input[name="failsafe_throttle"]').val(FAILSAFE_CONFIG.failsafe_throttle); - $('input[name="failsafe_off_delay"]').val(FAILSAFE_CONFIG.failsafe_off_delay); - $('input[name="failsafe_throttle_low_delay"]').val(FAILSAFE_CONFIG.failsafe_throttle_low_delay); - $('input[name="failsafe_delay"]').val(FAILSAFE_CONFIG.failsafe_delay); - - // set stage 2 failsafe procedure - $('input[type="radio"].procedure').change(function () { - var element = $(this), - checked = element.is(':checked'), - id = element.attr('id'); - switch(id) { - case 'drop': - if (checked) { - $('input[name="failsafe_throttle"]').prop("disabled", true); - $('input[name="failsafe_off_delay"]').prop("disabled", true); - } - break; - - case 'land': - if (checked) { - $('input[name="failsafe_throttle"]').prop("disabled", false); - $('input[name="failsafe_off_delay"]').prop("disabled", false); - } - break; - } - }); - - switch(FAILSAFE_CONFIG.failsafe_procedure) { - default: - case 0: - element = $('input[id="land"]') ; - element.prop('checked', true); - element.change(); - break; - case 1: - element = $('input[id="drop"]'); - element.prop('checked', true); - element.change(); - break; - } - - // set stage 2 kill switch option - $('input[name="failsafe_kill_switch"]').prop('checked', FAILSAFE_CONFIG.failsafe_kill_switch); - - } else { - BF_CONFIG.features.generateElements($('.tab-failsafe .featuresOld')); - // fill failsafe_throttle field (pre API 1.15.0) - $('input[name="failsafe_throttle_old"]').val(MISC.failsafe_throttle); } + // generate full channel list + var channelNames = [ + chrome.i18n.getMessage('controlAxisRoll'), + chrome.i18n.getMessage('controlAxisPitch'), + chrome.i18n.getMessage('controlAxisYaw'), + chrome.i18n.getMessage('controlAxisThrottle') + ], + fullChannels_e = $('div.activechannellist'), + aux_index = 1, + aux_assignment_index = 0; + + for (i = 0; i < RXFAIL_CONFIG.length; i++) { + if (i < channelNames.length) { + fullChannels_e.append('\ +
\ +
\ + ' + channelNames[i] + '\ +
\ +
\ + \ +
\ +
\ + '); + } else { + fullChannels_e.append('\ +
\ +
\ + ' + chrome.i18n.getMessage("controlAxisAux" + (aux_index++)) + '\ + ' + auxAssignment[aux_assignment_index++] + '\ +
\ +
\ + \ +
\ +
\ +
\ + '); + } + } + + var channel_mode_array = []; + $('.number', fullChannels_e).each(function () { + channel_mode_array.push($('select.aux_set' , this)); + }); + + var channel_value_array = []; + $('.number', fullChannels_e).each(function () { + channel_value_array.push($('input[name="aux_value"]' , this)); + }); + + var channelMode = $('select.aux_set'); + var channelValue = $('input[name="aux_value"]'); + + // UI hooks + channelMode.change(function () { + var currentMode = parseInt($(this).val()); + var i = parseInt($(this).prop("id")); + RXFAIL_CONFIG[i].mode = currentMode; + if (currentMode == 2) { + channel_value_array[i].prop("disabled", false); + channel_value_array[i].show(); + } else { + channel_value_array[i].prop("disabled", true); + channel_value_array[i].hide(); + } + }); + + // UI hooks + channelValue.change(function () { + var i = parseInt($(this).prop("id")); + RXFAIL_CONFIG[i].value = parseInt($(this).val()); + }); + + // for some odd reason chrome 38+ changes scroll according to the touched select element + // i am guessing this is a bug, since this wasn't happening on 37 + // code below is a temporary fix, which we will be able to remove in the future (hopefully) + $('#content').scrollTop((scrollPosition) ? scrollPosition : 0); + + // fill stage 1 Valid Pulse Range Settings + $('input[name="rx_min_usec"]').val(RX_CONFIG.rx_min_usec); + $('input[name="rx_max_usec"]').val(RX_CONFIG.rx_max_usec); + + // fill fallback settings (mode and value) for all channels + for (i = 0; i < RXFAIL_CONFIG.length; i++) { + channel_value_array[i].val(RXFAIL_CONFIG[i].value); + channel_mode_array[i].val(RXFAIL_CONFIG[i].mode); + channel_mode_array[i].change(); + } + + FEATURE_CONFIG.features.generateElements($('.tab-failsafe .featuresNew')); + + var failsafeFeature = $('input[name="FAILSAFE"]'); + failsafeFeature.change(function () { + toggleStage2($(this).is(':checked')); + }); + toggleStage2(FEATURE_CONFIG.features.isEnabled('FAILSAFE')); + + $('input[name="failsafe_throttle"]').val(FAILSAFE_CONFIG.failsafe_throttle); + $('input[name="failsafe_off_delay"]').val(FAILSAFE_CONFIG.failsafe_off_delay); + $('input[name="failsafe_throttle_low_delay"]').val(FAILSAFE_CONFIG.failsafe_throttle_low_delay); + $('input[name="failsafe_delay"]').val(FAILSAFE_CONFIG.failsafe_delay); + + // set stage 2 failsafe procedure + $('input[type="radio"].procedure').change(function () { + var element = $(this), + checked = element.is(':checked'), + id = element.attr('id'); + switch(id) { + case 'drop': + if (checked) { + $('input[name="failsafe_throttle"]').prop("disabled", true); + $('input[name="failsafe_off_delay"]').prop("disabled", true); + } + break; + + case 'land': + if (checked) { + $('input[name="failsafe_throttle"]').prop("disabled", false); + $('input[name="failsafe_off_delay"]').prop("disabled", false); + } + break; + } + }); + + switch(FAILSAFE_CONFIG.failsafe_procedure) { + default: + case 0: + element = $('input[id="land"]') ; + element.prop('checked', true); + element.change(); + break; + case 1: + element = $('input[id="drop"]'); + element.prop('checked', true); + element.change(); + break; + } + + // set stage 2 kill switch option + $('input[name="failsafe_kill_switch"]').prop('checked', FAILSAFE_CONFIG.failsafe_kill_switch); + + $('a.save').click(function () { // gather data that doesn't have automatic change event bound - BF_CONFIG.features.updateData($('input[name="FAILSAFE"]')); + FEATURE_CONFIG.features.updateData($('input[name="FAILSAFE"]')); - if(apiVersionGte1_15_0) { - RX_CONFIG.rx_min_usec = parseInt($('input[name="rx_min_usec"]').val()); - RX_CONFIG.rx_max_usec = parseInt($('input[name="rx_max_usec"]').val()); + RX_CONFIG.rx_min_usec = parseInt($('input[name="rx_min_usec"]').val()); + RX_CONFIG.rx_max_usec = parseInt($('input[name="rx_max_usec"]').val()); - FAILSAFE_CONFIG.failsafe_throttle = parseInt($('input[name="failsafe_throttle"]').val()); - FAILSAFE_CONFIG.failsafe_off_delay = parseInt($('input[name="failsafe_off_delay"]').val()); - FAILSAFE_CONFIG.failsafe_throttle_low_delay = parseInt($('input[name="failsafe_throttle_low_delay"]').val()); - FAILSAFE_CONFIG.failsafe_delay = parseInt($('input[name="failsafe_delay"]').val()); + FAILSAFE_CONFIG.failsafe_throttle = parseInt($('input[name="failsafe_throttle"]').val()); + FAILSAFE_CONFIG.failsafe_off_delay = parseInt($('input[name="failsafe_off_delay"]').val()); + FAILSAFE_CONFIG.failsafe_throttle_low_delay = parseInt($('input[name="failsafe_throttle_low_delay"]').val()); + FAILSAFE_CONFIG.failsafe_delay = parseInt($('input[name="failsafe_delay"]').val()); - if( $('input[id="land"]').is(':checked')) { - FAILSAFE_CONFIG.failsafe_procedure = 0; - } else if( $('input[id="drop"]').is(':checked')) { - FAILSAFE_CONFIG.failsafe_procedure = 1; - } - - FAILSAFE_CONFIG.failsafe_kill_switch = $('input[name="failsafe_kill_switch"]').is(':checked') ? 1 : 0; - } else { - // get failsafe_throttle field value (pre API 1.15.0) - MISC.failsafe_throttle = parseInt($('input[name="failsafe_throttle_old"]').val()); + if( $('input[id="land"]').is(':checked')) { + FAILSAFE_CONFIG.failsafe_procedure = 0; + } else if( $('input[id="drop"]').is(':checked')) { + FAILSAFE_CONFIG.failsafe_procedure = 1; } + FAILSAFE_CONFIG.failsafe_kill_switch = $('input[name="failsafe_kill_switch"]').is(':checked') ? 1 : 0; + function save_failssafe_config() { MSP.send_message(MSPCodes.MSP_SET_FAILSAFE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FAILSAFE_CONFIG), false, save_rxfail_config); } function save_rxfail_config() { - mspHelper.sendRxFailConfig(save_bf_config); + mspHelper.sendRxFailConfig(save_feature_config); } - function save_bf_config() { - MSP.send_message(MSPCodes.MSP_SET_BF_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BF_CONFIG), false, save_to_eeprom); + function save_feature_config() { + MSP.send_message(MSPCodes.MSP_SET_FEATURE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FEATURE_CONFIG), false, save_to_eeprom); } - // BEGIN pre API 1.15.0 save functions - function save_misc() { - MSP.send_message(MSPCodes.MSP_SET_MISC, mspHelper.crunch(MSPCodes.MSP_SET_MISC), false, save_to_eeprom); - } - // END pre API 1.15.0 save functions - function save_to_eeprom() { MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, reboot); } @@ -341,11 +316,7 @@ TABS.failsafe.initialize = function (callback, scrollPosition) { } } - if(apiVersionGte1_15_0) { - MSP.send_message(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG), false, save_failssafe_config); - } else { - MSP.send_message(MSPCodes.MSP_SET_BF_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BF_CONFIG), false, save_misc); - } + MSP.send_message(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG), false, save_failssafe_config); }); // translate to user-selected language diff --git a/tabs/logging.js b/tabs/logging.js index 25551776..a60b97af 100644 --- a/tabs/logging.js +++ b/tabs/logging.js @@ -229,8 +229,18 @@ TABS.logging.initialize = function (callback) { fileWriter = null; function prepare_file() { + + var prefix = 'log'; + var suffix = 'csv'; + + var filename = generateFilename(prefix, suffix); + + var accepts = [{ + extensions: [suffix], + }]; + // create or load the file - chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'betaflight_data_log', accepts: [{extensions: ['csv']}]}, function(entry) { + chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: filename, accepts: accepts}, function(entry) { if (!entry) { console.log('No file selected'); return; diff --git a/tabs/motors.js b/tabs/motors.js index 0f136db2..d8eeba0d 100644 --- a/tabs/motors.js +++ b/tabs/motors.js @@ -12,40 +12,29 @@ TABS.motors.initialize = function (callback) { self.armed = false; self.feature3DSupported = false; self.allowTestMode = true; + self.feature3DSupported = true; if (GUI.active_tab != 'motors') { GUI.active_tab = 'motors'; } function get_arm_status() { - MSP.send_message(MSPCodes.MSP_STATUS, false, false, load_config); + MSP.send_message(MSPCodes.MSP_STATUS, false, false, load_feature_config); } - function load_config() { - MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, load_3d); + function load_feature_config() { + MSP.send_message(MSPCodes.MSP_FEATURE_CONFIG, false, false, load_motor_3d_config); } - function load_3d() { - var next_callback = esc_protocol; - if (semver.gte(CONFIG.apiVersion, "1.14.0")) { - self.feature3DSupported = true; - MSP.send_message(MSPCodes.MSP_3D, false, false, next_callback); - } else { - next_callback(); - } + function load_motor_3d_config() { + MSP.send_message(MSPCodes.MSP_MOTOR_3D_CONFIG, false, false, load_esc_protocol); } - function esc_protocol() { - var next_callback = get_motor_data; - if (semver.gte(CONFIG.flightControllerVersion, "2.8.1")) { - MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, next_callback); - } else { - next_callback(); - } + function load_esc_protocol() { + MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, load_motor_data); } - function get_motor_data() { - update_arm_status(); + function load_motor_data() { MSP.send_message(MSPCodes.MSP_MOTOR, false, false, load_html); } @@ -53,7 +42,7 @@ TABS.motors.initialize = function (callback) { $('#content').load("./tabs/motors.html", process_html); } - MSP.send_message(MSPCodes.MSP_MISC, false, false, get_arm_status); + MSP.send_message(MSPCodes.MSP_MOTOR_CONFIG, false, false, get_arm_status); function update_arm_status() { self.armed = bit_check(CONFIG.mode, 0); @@ -185,8 +174,10 @@ TABS.motors.initialize = function (callback) { function process_html() { // translate to user-selected language localize(); + + update_arm_status(); - self.feature3DEnabled = BF_CONFIG.features.isEnabled('3D'); + self.feature3DEnabled = FEATURE_CONFIG.features.isEnabled('3D'); if (self.feature3DEnabled && !self.feature3DSupported) { self.allowTestMode = false; @@ -201,7 +192,7 @@ TABS.motors.initialize = function (callback) { $('#motorsEnableTestMode').prop('checked', false) .prop('disabled', true); - update_model(BF_CONFIG.mixerConfiguration); + update_model(MIXER_CONFIG.mixer); // Always start with default/empty sensor data array, clean slate all initSensorData(); @@ -330,19 +321,19 @@ TABS.motors.initialize = function (callback) { '); } - $('div.sliders input').prop('min', MISC.mincommand) - .prop('max', MISC.maxthrottle); - $('div.values li:not(:last)').text(MISC.mincommand); + $('div.sliders input').prop('min', MOTOR_CONFIG.mincommand) + .prop('max', MOTOR_CONFIG.maxthrottle); + $('div.values li:not(:last)').text(MOTOR_CONFIG.mincommand); if(self.feature3DEnabled && self.feature3DSupported) { //Arbitrary sanity checks //Note: values may need to be revisited - if(_3D.neutral3d > 1575 || _3D.neutral3d < 1425) - _3D.neutral3d = 1500; + if(MOTOR_3D_CONFIG.neutral > 1575 || MOTOR_3D_CONFIG.neutral < 1425) + MOTOR_3D_CONFIG.neutral = 1500; - $('div.sliders input').val(_3D.neutral3d); + $('div.sliders input').val(MOTOR_3D_CONFIG.neutral); } else { - $('div.sliders input').val(MISC.mincommand); + $('div.sliders input').val(MOTOR_CONFIG.mincommand); } if(self.allowTestMode){ @@ -397,9 +388,9 @@ TABS.motors.initialize = function (callback) { // change all values to default if (self.feature3DEnabled && self.feature3DSupported) { - $('div.sliders input').val(_3D.neutral3d); + $('div.sliders input').val(MOTOR_3D_CONFIG.neutral); } else { - $('div.sliders input').val(MISC.mincommand); + $('div.sliders input').val(MOTOR_CONFIG.mincommand); } $('div.sliders input').trigger('input'); @@ -411,11 +402,11 @@ TABS.motors.initialize = function (callback) { for (var i = 0; i < number_of_valid_outputs; i++) { if (!self.feature3DEnabled) { - if (MOTOR_DATA[i] > MISC.mincommand) { + if (MOTOR_DATA[i] > MOTOR_CONFIG.mincommand) { motors_running = true; } } else { - if ((MOTOR_DATA[i] < _3D.deadband3d_low) || (MOTOR_DATA[i] > _3D.deadband3d_high)) { + if ((MOTOR_DATA[i] < MOTOR_3D_CONFIG.deadband3d_low) || (MOTOR_DATA[i] > MOTOR_3D_CONFIG.deadband3d_high)) { motors_running = true; } } @@ -473,8 +464,8 @@ TABS.motors.initialize = function (callback) { full_block_scale = 1000; motorOffset = 1000; } else { - full_block_scale = MISC.maxthrottle - MISC.mincommand; - motorOffset = MISC.mincommand; + full_block_scale = MOTOR_CONFIG.maxthrottle - MOTOR_CONFIG.mincommand; + motorOffset = MOTOR_CONFIG.mincommand; } function update_ui() { diff --git a/tabs/onboard_logging.js b/tabs/onboard_logging.js index 2c0aa43a..47c474a9 100644 --- a/tabs/onboard_logging.js +++ b/tabs/onboard_logging.js @@ -4,7 +4,6 @@ var sdcardTimer; TABS.onboard_logging = { - available: false, blockSize: 128, BLOCK_SIZE: 4096, @@ -21,39 +20,17 @@ TABS.onboard_logging.initialize = function (callback) { } if (CONFIGURATOR.connectionValid) { - // Blackbox was introduced in 1.5.0, dataflash API was introduced in 1.8.0, BLACKBOX/SDCARD MSP APIs in 1.11.0 - TABS.onboard_logging.available = semver.gte(CONFIG.flightControllerVersion, "1.5.0"); - - if (!TABS.onboard_logging.available) { - load_html(); - return; - } - var load_name = function () { - var next_callback = load_html; - if (semver.gte(CONFIG.flightControllerVersion, "3.0.0")) { - MSP.send_message(MSPCodes.MSP_NAME, false, false, next_callback); - } else { - next_callback(); - } - }; - - MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, function() { - if (semver.gte(CONFIG.flightControllerVersion, "1.8.0")) { - MSP.send_message(MSPCodes.MSP_DATAFLASH_SUMMARY, false, false, function() { - if (semver.gte(CONFIG.flightControllerVersion, "1.11.0")) { - MSP.send_message(MSPCodes.MSP_SDCARD_SUMMARY, false, false, function() { - MSP.send_message(MSPCodes.MSP_BLACKBOX_CONFIG, false, false, function() { - MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, load_name); - }); + MSP.send_message(MSPCodes.MSP_FEATURE_CONFIG, false, false, function() { + MSP.send_message(MSPCodes.MSP_DATAFLASH_SUMMARY, false, false, function() { + MSP.send_message(MSPCodes.MSP_SDCARD_SUMMARY, false, false, function() { + MSP.send_message(MSPCodes.MSP_BLACKBOX_CONFIG, false, false, function() { + MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, function() { + MSP.send_message(MSPCodes.MSP_NAME, false, false, load_html); }); - } else { - load_html(); - } + }); }); - } else { - load_html(); - } + }); }); } @@ -109,11 +86,8 @@ TABS.onboard_logging.initialize = function (callback) { * * The best we can do on those targets is check the BLACKBOX feature bit to identify support for Blackbox instead. */ - if (BLACKBOX.supported || DATAFLASH.supported - || semver.gte(CONFIG.flightControllerVersion, "1.5.0") && semver.lte(CONFIG.flightControllerVersion, "1.10.0") && BF_CONFIG.features.isEnabled('BLACKBOX')) { + if ((BLACKBOX.supported || DATAFLASH.supported) && (semver.gte(CONFIG.apiVersion, "1.33.0") || FEATURE_CONFIG.features.isEnabled('BLACKBOX'))) { blackboxSupport = 'yes'; - } else if (semver.gte(CONFIG.flightControllerVersion, "1.5.0") && semver.lte(CONFIG.flightControllerVersion, "1.10.0")) { - blackboxSupport = 'maybe'; } else { blackboxSupport = 'no'; } @@ -175,15 +149,25 @@ TABS.onboard_logging.initialize = function (callback) { function populateDevices(deviceSelect) { deviceSelect.empty(); - - deviceSelect.append(''); - if (DATAFLASH.ready) { - deviceSelect.append(''); + + if (semver.gte(CONFIG.apiVersion, "1.33.0")) { + deviceSelect.append(''); + if (DATAFLASH.ready) { + deviceSelect.append(''); + } + if (SDCARD.supported) { + deviceSelect.append(''); + } + deviceSelect.append(''); + } else { + deviceSelect.append(''); + if (DATAFLASH.ready) { + deviceSelect.append(''); + } + if (SDCARD.supported) { + deviceSelect.append(''); + } } - if (SDCARD.supported) { - deviceSelect.append(''); - } - deviceSelect.append(''); deviceSelect.val(BLACKBOX.blackboxDevice); } @@ -348,7 +332,7 @@ TABS.onboard_logging.initialize = function (callback) { function flash_save_begin() { if (GUI.connected_to) { if (BOARD.find_board_definition(CONFIG.boardIdentifier).vcp) { - if (semver.gte(CONFIG.flightControllerVersion, "3.1.0")) { + if (semver.gte(CONFIG.apiVersion, "1.31.0")) { self.blockSize = self.VCP_BLOCK_SIZE; } else { self.blockSize = self.VCP_BLOCK_SIZE_3_0; @@ -408,8 +392,9 @@ TABS.onboard_logging.initialize = function (callback) { } function prepare_file(onComplete) { - var suffix = 'BFL'; + var prefix = 'BLACKBOX_LOG'; + var suffix = 'BBL'; var filename = generateFilename(prefix, suffix); diff --git a/tabs/osd.html b/tabs/osd.html index 578f5c3f..59eaa7f7 100755 --- a/tabs/osd.html +++ b/tabs/osd.html @@ -11,7 +11,7 @@

Note that some flight controllers have an onboard MinimOSD that can be flashed and configured with scarab-osd, however the MinimOSD cannot be configured through this interface.

-
+
-
+
Preview (drag to change position) @@ -42,7 +42,7 @@
-
+
Video Format @@ -52,7 +52,7 @@
- diff --git a/tabs/setup_osd.js b/tabs/setup_osd.js new file mode 100644 index 00000000..cf7d5af7 --- /dev/null +++ b/tabs/setup_osd.js @@ -0,0 +1,71 @@ +'use strict'; + +TABS.setup_osd = { +}; + +TABS.setup_osd.initialize = function (callback) { + var self = this; + + if (GUI.active_tab != 'setup_osd') { + GUI.active_tab = 'setup_osd'; + // Disabled on merge into betaflight-configurator + //googleAnalytics.sendAppView('Setup OSD'); + } + + function load_status() { + MSP.send_message(MSPCodes.MSP_STATUS, false, false, load_html); + } + + function load_html() { + $('#content').load("./tabs/setup_osd.html", process_html); + } + + load_status(); + + function process_html() { + + $('.tab-setup-osd .info').hide(); // requires an MSP update + + var osdVideoModes = [ + 'AUTO', + 'NTSC', + 'PAL' + ]; + + // translate to user-selected language + localize(); + + $('a.resetSettings').click(function () { + MSP.send_message(MSPCodes.MSP_RESET_CONF, false, false, function () { + GUI.log(chrome.i18n.getMessage('initialSetupSettingsRestored')); + + GUI.tab_switch_cleanup(function () { + TABS.setup_osd.initialize(); + }); + }); + }); + + function get_slow_data() { + /* FIXME requires MSP update + MSP.send_message(MSPCodes.MSP_OSD_VIDEO_STATUS, false, false, function () { + var element; + + element = $('.video-mode'); + var osdVideoMode = osdVideoModes[OSD_VIDEO_STATE.video_mode]; + element.text(osdVideoMode); + + element = $('.camera-connected'); + element.text(OSD_VIDEO_STATE.camera_connected ? chrome.i18n.getMessage('osdSetupCameraConnectedValueYes') : chrome.i18n.getMessage('osdSetupCameraConnectedValueNo')); + }); + */ + } + + GUI.interval_add('setup_data_pull_slow', get_slow_data, 250, true); // 4 fps + + GUI.content_ready(callback); + } +}; + +TABS.setup_osd.cleanup = function (callback) { + if (callback) callback(); +}; diff --git a/tabs/transponder.css b/tabs/transponder.css index 7465848e..f903c158 100644 --- a/tabs/transponder.css +++ b/tabs/transponder.css @@ -1,3 +1,7 @@ +#tab-transponder-templates { + display: none; +} + .tab-transponder .spacer_box { padding-bottom: 10px; float: left; @@ -73,3 +77,11 @@ .tab-transponder.transponder-supported .require-transponder-supported { display: block; } + +.textspacer-small { + margin-bottom: 15px; +} + +.tab-transponder select { + min-width: 100px; +} diff --git a/tabs/transponder.html b/tabs/transponder.html index 389b5854..d6910a18 100644 --- a/tabs/transponder.html +++ b/tabs/transponder.html @@ -1,10 +1,12 @@
+
Transponder
+
- +

@@ -12,41 +14,67 @@
- -
-
-

-
-
-
-
+
+
-
-
- +
+
+
- -
+ +
+
+
+
+

+
+
+
+
-
+ +
+ +
+
- +

- +
+
-
+
+ +
+
+ +
+
+
+
+
+
+
+
+ +
+
+
diff --git a/tabs/transponder.js b/tabs/transponder.js index 8135c4ab..a34af3b4 100644 --- a/tabs/transponder.js +++ b/tabs/transponder.js @@ -1,20 +1,56 @@ 'use strict'; + TABS.transponder = { available: false }; -TABS.transponder.initialize = function (callback, scrollPosition) { - var self = this; +TABS.transponder.initialize = function(callback, scrollPosition) { - if (GUI.active_tab != 'transponder') { + let _persistentInputValues = {}; + + let dataTypes = { + NONE: 0, + TEXT: 1, + LIST: 2, + }; + + // CONFIGURATION HERE FOR ADD NEW TRANSPONDER + let transponderConfigurations = { + 0: { + dataType: dataTypes.NONE // empty + }, //NONE + 1: { + dataType: dataTypes.TEXT // + }, //ilap + 2: { + dataType: dataTypes.LIST, // + dataOptions: { + 'ID 1': 'E00370FC0FFE07E0FF', + 'ID 2': '007C003EF800FC0FFE', + 'ID 3': 'F8811FF8811FFFC7FF', + 'ID 4': '007C003EF81F800FFE', + 'ID 5': 'F00FFF00FFF00FF0FF', + 'ID 6': '007CF0C1071F7C00F0', + 'ID 7': 'E003F03F00FF03F0C1', + 'ID 8': '00FC0FFE071F3E00FE', + 'ID 9': 'E083BFF00F9E38C0FF', + } + }, //arcitimer + }; + ///////////////////////////////////////////// + + if ( GUI.active_tab != 'transponder' ) { GUI.active_tab = 'transponder'; + // Disabled on merge into betaflight-configurator + //googleAnalytics.sendAppView('Transponder'); } - // transponder supported added in MSP API Version 1.16.0 - TABS.transponder.available = semver.gte(CONFIG.apiVersion, "1.16.0"); - - if (!TABS.transponder.available) { + if ( CONFIG ) { + TABS.transponder.available = semver.gte(CONFIG.apiVersion, "1.16.0"); + } + ////////////// + if ( !TABS.transponder.available ) { load_html(); return; } @@ -23,13 +59,14 @@ TABS.transponder.initialize = function (callback, scrollPosition) { $('#content').load("./tabs/transponder.html", process_html); } - // get the transponder data and a flag to see if transponder support is enabled on the FC - MSP.send_message(MSPCodes.MSP_TRANSPONDER_CONFIG, false, false, load_html); - + //HELPERS // Convert a hex string to a byte array function hexToBytes(hex) { - for (var bytes = [], c = 0; c < hex.length; c += 2) - bytes.push(~parseInt(hex.substr(c, 2), 16)); + var bytes = []; + for ( let c = 0; c < hex.length; c += 2 ) { + bytes.push(~parseInt(hex.substr(c, 2), 16)); + } + return bytes; } @@ -37,68 +74,202 @@ TABS.transponder.initialize = function (callback, scrollPosition) { n = n + ''; return n.length >= width ? n : new Array(width - n.length + 1).join('0') + n; } - + // Convert a byte array to a hex string function bytesToHex(bytes) { - for (var hex = [], i = 0; i < bytes.length; i++) { - hex.push(pad(((~bytes[i]) & 0xFF).toString(16),2)); + var hex = []; + for ( let i = 0; i < bytes.length; i++ ) { + hex.push(pad(((~bytes[i]) & 0xFF).toString(16), 2)); } return hex.join("").toUpperCase(); } - function process_html() { - // translate to user-selected language - localize(); - - $(".tab-transponder") - .toggleClass("transponder-supported", TABS.transponder.available && TRANSPONDER.supported); - - if (TABS.transponder.available) { - - var data = bytesToHex(TRANSPONDER.data); - - $('input[name="data"]').val(data); - $('input[name="data"]').prop('maxLength', data.length); - - $('a.save').click(function () { - - - // gather data that doesn't have automatic change event bound - - var dataString = $('input[name="data"]').val(); - var expectedLength = TRANSPONDER.data.length; - var hexRegExp = new RegExp('[0-9a-fA-F]{' + (expectedLength * 2) + '}', 'gi'); - if (!dataString.match(hexRegExp)) { - GUI.log(chrome.i18n.getMessage('transponderDataInvalid')); - return; + + ///////////// + + function fillByTransponderProviders(transponderProviders, transponderProviderID, toggleTransponderType) { + let transponderTypeSelect = $('#transponder_type_select'); + transponderTypeSelect.attr('data-defaultValue', transponderProviderID); + transponderTypeSelect.off('change').change(toggleTransponderType); + transponderTypeSelect.html(''); + + //build radio buttons + transponderTypeSelect.append( + $('