Merge remote-tracking branch 'multiwii/master'

Conflicts:
	README.md
	_locales/en/messages.json
	changelog.html
	js/backup_restore.js
	js/data_storage.js
	js/msp.js
	js/protocols/stm32.js
	js/serial_backend.js
	main.css
	main.html
	main.js
	manifest.json
	tabs/auxiliary_configuration.css
	tabs/default.css
	tabs/firmware_flasher.js
	tabs/initial_setup.css
	tabs/initial_setup.html
	tabs/initial_setup.js
	tabs/modes.html
	tabs/modes.js
	tabs/motor_outputs.css
	tabs/motors.html
	tabs/receiver.css
	tabs/servos.js
10.3.x-maintenance
Dominic Clifton 2014-12-18 22:38:55 +00:00
commit a8cf910f51
108 changed files with 12813 additions and 4551 deletions

View File

@ -32,6 +32,10 @@ How to use
-----------
You can find the Cleanflight - Configurator icon in your application tab "Apps"
WebGL
-----
Make sure Settings -> System -> "User hardware acceleration when available" is checked to achieve the best performance
Linux users
-----------
1. Dont forget to add your user into dialout group "sudo usermod -aG dialout YOUR_USERNAME" for serial access

View File

@ -13,6 +13,25 @@
"message": "Send anonymous usage data to the developer team"
},
"reviewHead": {
"message": "Application Review"
},
"reviewInitial": {
"message": "Do you like this app?"
},
"reviewStore": {
"message": "We are glad to hear that, would you like to send a review to make the application more popular?"
},
"reviewBug": {
"message": "We are sorry to hear that, would you like to submit a ticker and tell us what bothers you?"
},
"reviewYes": {
"message": "Yes"
},
"reviewNo": {
"message": "No"
},
"connect": {
"message": "Connect"
},
@ -31,41 +50,58 @@
"autoConnectDisabled": {
"message": "Auto-Connect: Disabled - User needs to select the correct serial port and click \"Connect\" button on its own"
},
"deviceRebooting": {
"message": "Device - <span style=\"color: red\">Rebooting</span>"
},
"deviceReady": {
"message": "Device - <span style=\"color: green\">Ready</span>"
},
"tab1": {
"message": "Initial Setup"
"backupFileIncompatible": {
"message": "Backup file provided was generated for older version of configurator and is incompatible with this version of configurator. Sorry"
},
"tab2": {
"message": "PID"
"tabSetup": {
"message": "Setup"
},
"tab3": {
"tabConfiguration": {
"message": "Configuration"
},
"tabPidTuning": {
"message": "PID Tuning"
},
"tabReceiver": {
"message": "Receiver"
},
"tab4": {
"message": "Auxiliary"
"tabModeSelection": {
"message": "Mode Selection"
},
"tab5": {
"message": "Adjustments"
},
"tab6": {
"tabServos": {
"message": "Servos"
},
"tab7": {
"tabGPS": {
"message": "GPS"
},
"tab8": {
"message": "Motors"
"tabMotorTesting": {
"message": "Motor Testing"
},
"tab9": {
"message": "Sensors"
"tabRawSensorData": {
"message": "Raw Sensor Data"
},
"tab10": {
"tabCLI": {
"message": "CLI"
},
"tab11": {
"tabLogging": {
"message": "Logging"
},
"tabAdjustments": {
"message": "Adjustments"
},
"tabAuxiliary": {
"message": "Auxiliary"
},
"serialPortOpened": {
"message": "Serial port <span style=\"color: green\">successfully</span> opened with ID: $1"
},
@ -160,19 +196,19 @@
"message": "Calibrate Accelerometer"
},
"initialSetupCalibrateAccelText": {
"message": "Place board or frame on <strong style=\"color: green\">leveled</strong> surface, proceed with calibration, ensure platform is <strong style=\"color: red\">not</strong> moving during calibration period."
"message": "Place board or frame on <strong>leveled</strong> surface, proceed with calibration, ensure platform is not moving during calibration period"
},
"initialSetupButtonCalibrateMag": {
"message": "Calibrate Magnetometer"
},
"initialSetupCalibrateMagText": {
"message": "Move multirotor atleast <strong>360</strong> degrees on all axis of rotation. You have <strong style=\"color: red\">30 seconds</strong> to perform this task."
"message": "Move multirotor atleast <strong>360</strong> degrees on all axis of rotation, you have 30 seconds to perform this task"
},
"initialSetupButtonReset": {
"message": "Reset Settings"
},
"initialSetupResetText": {
"message": "Restore <span style=\"color: red\">all</span> settings to <strong>default</strong>."
"message": "Restore settings to <strong>default</strong>"
},
"initialSetupButtonBackup": {
"message": "Backup"
@ -181,7 +217,13 @@
"message": "Restore"
},
"initialSetupBackupRestoreText": {
"message": "<strong>Backup</strong> your configuration in case of an accident. (<strong>CLI</strong> settings are <strong style=\"color: red\">not</strong> included)."
"message": "<strong>Backup</strong> your configuration in case of an accident, <strong>CLI</strong> settings are not included"
},
"initialSetupBackupSuccess": {
"message": "Backup saved <span style=\"color: green\">successfully</span>"
},
"initialSetupRestoreSuccess": {
"message": "Configuration restored <span style=\"color: green\">successfully</span>"
},
"initialSetupButtonResetZaxis": {
"message": "Reset Z axis, offset: 0 deg"
@ -189,6 +231,9 @@
"initialSetupButtonResetZaxisValue": {
"message": "Reset Z axis, offset: $1 deg"
},
"initialSetupMixerHead": {
"message": "Mixer Type"
},
"initialSetupThrottleHead": {
"message": "Throttle Settings"
},
@ -258,6 +303,9 @@
"initialSetupRSSIValue": {
"message": "$1 %"
},
"initialSetupGPSHead": {
"message": "GPS"
},
"initialSetupButtonSave": {
"message": "Save"
},
@ -286,6 +334,100 @@
"message": "EEPROM <span style=\"color: green\">saved</span>"
},
"configurationMixer": {
"message": "Mixer"
},
"configurationFeatures": {
"message": "Features"
},
"configurationBoardAlignment": {
"message": "Board Alignment"
},
"configurationBoardAlignmentRoll": {
"message": "Roll Adjustment [deg]"
},
"configurationBoardAlignmentPitch": {
"message": "Pitch Adjustment [deg]"
},
"configurationBoardAlignmentYaw": {
"message": "Yaw Adjustment [deg]"
},
"configurationAccelTrimMagDec": {
"message": "Accelerometer & Magnetometer"
},
"configurationAccelTrimRoll": {
"message": "Accelerometer Roll Trim"
},
"configurationAccelTrimPitch": {
"message": "Accelerometer Pitch Trim"
},
"configurationMagDeclination": {
"message": "Magnetometer Declination [deg]"
},
"configurationThrottle": {
"message": "Throttle"
},
"configurationThrottleMinimum": {
"message": "Minimum Throttle"
},
"configurationThrottleMid": {
"message": "Middle Throttle [RC inputs center value]"
},
"configurationThrottleMaximum": {
"message": "Maximum Throttle"
},
"configurationThrottleFailsafe": {
"message": "Failsafe Throttle"
},
"configurationThrottleMinimumCommand": {
"message": "Minimum Command"
},
"configurationBatteryVoltage": {
"message": "Battery Voltage"
},
"configurationBatteryMinimum": {
"message": "Minimum Cell Voltage"
},
"configurationBatteryMaximum": {
"message": "Maximum Cell Voltage"
},
"configurationBatteryScale": {
"message": "Voltage Scale"
},
"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"
},
"configurationGPS": {
"message": "GPS"
},
"configurationGPStype": {
"message": "Type"
},
"configurationGPSbaudrate": {
"message": "Baudrate"
},
"configurationGPSubxSbas": {
"message": "Ground Assistance Type"
},
"configurationSerialRX": {
"message": "Serial Receiver"
},
"configurationEepromSaved": {
"message": "EEPROM <span style=\"color: green\">saved</span>"
},
"configurationButtonSave": {
"message": "Save"
},
"pidTuningName": {
"message": "Name"
},
@ -338,6 +480,15 @@
"receiverRcExpo": {
"message": "RC Expo"
},
"receiverChannelMap": {
"message": "Channel Map"
},
"receiverChannelMapTitle": {
"message": "You can define your own channel map by clicking inside the box"
},
"receiverRssiAux": {
"message": "RSSI on AUX"
},
"receiverRefreshRateTitle": {
"message": "Graph refresh rate"
},
@ -618,23 +769,41 @@
"firmwareFlasherProgress": {
"message": "Progress:"
},
"firmwareFlasherNote": {
"message": "If you are flashing board with bootloader pins <strong>shorted/connected</strong>, check <strong>No reboot sequence</strong>.<br />If you want configuration data to be wiped, check <strong>Full Chip Erase</strong><br />If you are flashing via bluetooth adapter or using external usb to serial adapter, check <strong>Flash slowly</strong><br />"
"firmwareFlasherLoadFirmwareFile": {
"message": "Please load firmware file"
},
"firmwareFlasherNoReboot": {
"message": "No reboot sequence"
},
"firmwareFlasherOnlineReleasesDescription": {
"message": "Available online firmware releases"
},
"firmwareFlasherNoRebootDescription": {
"message": "Check if you are flashing board with bootloader pins shorted"
},
"firmwareFlasherFlashOnConnect": {
"message": "Flash on connect"
},
"firmwareFlasherFlashOnConnectDescription": {
"message": "Attempt to flash the board automatically (triggered by newly detected serial port)"
},
"firmwareFlasherFullChipErase": {
"message": "Full Chip Erase"
},
"firmwareFlasherFullChipEraseDescription": {
"message": "Wipes all configuration data currently stored on the board"
},
"firmwareFlasherFlashDevelopmentFirmware": {
"message": "Use Development Firmware"
},
"firmwareFlasherFlashDevelopmentFirmwareDescription": {
"message": "Flash most recent (untested) development firmware"
},
"firmwareFlasherFlashSlowly": {
"message": "Flash slowly"
},
"firmwareFlasherFlashSlowlyTitle": {
"message": "Use 115200 baudrate for flashing"
"firmwareFlasherFlashSlowlyDescription": {
"message": "Use 115200 baudrate for flashing (useful for flashing via bluetooth)"
},
"firmwareFlasherButtonLoadLocal": {
"message": "Load Firmware [Local]"
@ -654,6 +823,12 @@
"firmwareFlasherDate": {
"message": "Date:"
},
"firmwareFlasherHash": {
"message": "Hash:"
},
"firmwareFlasherUrl": {
"message": "Go to GitHub to review this commit..."
},
"firmwareFlasherMessage": {
"message": "Message:"
},

View File

@ -1,3 +1,61 @@
<span>2014.12.06 - 0.57</span>
<p>
- Firmware flasher now contains firmware builds picker<br />
- Implemented new and experimental review mechanism<br />
- Support for new A-tail Quad craft type<br />
- Firmware flasher flashing speed optimizations<br />
- Added specific 3D models for atail/vtail quad (norem)<br />
- Major bugfix for stuck UI after delayed port open procedure<br />
- Bugfix for GPS distance to home not displaying<br />
- Bugfix for backup/restore misbehaving (mostly on OSX)<br />
</p>
<span>2014.11.04 - 0.56</span>
<p>
- Added hex plus, hex X, tri, y4, y6 3D models (jef79m)<br />
- Bugfix for battery voltage saving sequence<br />
- Bugfix for fetching development firmware<br />
</p>
<span>2014.10.31 - 0.55</span>
<p>
- Minimum required Chrome version set to 38+<br />
- Minimum accepted firmware version set to 2.31<br />
- Support for flashing development firmware<br />
- Setup tab performance improvements, faster 3D model<br />
- Strongly improved amount of data stored in backups<br />
- Improved flash on connect in firmware flasher<br />
- Rearranged texts and options in firmware flasher<br />
- Bugfix for corrupted minimum window size on Windows 7<br />
- Bugfix for incorrect date &amp; time in firmware flasher<br />
- Bugfix for port handler firing before port being initialized<br />
</p>
<span>2014.10.06 - 0.54</span>
<p>
- Backup files now also contain servo settings<br />
- Pre 0.54 backup files are incompatible, save new ones<br />
- Bugfixes<br />
</p>
<span>2014.09.30 - 0.53</span>
<p>
- Enhanced 3D model (creyc)<br />
- Fallback 3D model for canvas renderer (creyc)<br />
- More predefined options for channel map<br />
- Display motor/servo signal value inside the bars<br />
- Bugfixes<br />
</p>
<span>2014.09.29. - 0.52</span>
<p>
- We recommend upgrading to the <strong>latest firmware</strong><br />
- Simplified Initial Setup tab and renamed it to Setup<br />
- Renamed Auxiliary Configuration to Mode selection<br />
- Implemented new Configuration tab (check it out)<br />
- Simplified meter UI in Receiver tab<br />
- Channel Map is now configurable in Receiver tab<br />
- Using new "real" 3D renderer for the 3D model<br />
- 3D model for Quad X (creyc)<br />
- Additional motor order diagrams (creyc)<br />
- Updated MSP layer with new custom Baseflight commands<br />
- Various optimizations and bugfixes<br />
</p>
<span>9.11.2014 - 0.51.3 cleanflight</span>
<p>
+ Add 'Adjustments' tab for configuring in-flight adjustment switches.<br />
@ -19,6 +77,13 @@
* Requires latest firmware.<br />
+ Support mode ranges on auxillary tab.<br />
</p>
<span>2014.09.09 - 0.51</span>
<p>
- Configurator userbase is over 9000 now :-)<br />
- Small global UI revamp to utilize space little bit better<br />
- Online Firmware can be saved locally<br />
- Added missing model information for custom model<br />
</p>
<span>09.04.2014 - 0.50.3 cleanflight</span>
<p>
- Update URLs.<br />
@ -32,7 +97,7 @@
- Ensure initialised data is not used when configuring aux channels.<br />
- Update sponsors for cleanflight specific sponsors.<br />
</p>
<span>08.31.2014 - 0.50</span>
<span>2014.08.31 - 0.50</span>
<p>
- Small UI revamp for Firmware Flasher<br />
- Added "Flash slowly" mode (bluetooth friendly)<br />
@ -48,9 +113,9 @@
- Additional motor order diagrams (creyc)<br />
- Bugfixes<br />
</p>
<span>07.27.2014 - 0.48</span>
<span>2014.07.27 - 0.48</span>
<p>
- Configurator reached 6000+ users on 07.26.2014<br />
- Configurator reached 6000+ users on 2014.07.26<br />
- Added motor order diagrams (creyc, Curtisbeef)<br />
- Flashing timeout bugfixes<br />
</p>
@ -58,12 +123,12 @@
<p>
- Fix auxiliary configuration tab when using parallel pwm.<br />
</p>
<span>07.17.2014 - 0.47</span>
<span>2014.07.17 - 0.47</span>
<p>
- Bugfixes related to Chrome 36+ release<br />
- Various optimizations and behavior improvements<br />
</p>
<span>07.11.2014 - 0.46</span>
<span>2014.07.11 - 0.46</span>
<p>
- Application will display a spinner while waiting for data<br />
- Bugfixes<br />
@ -71,20 +136,20 @@
<p>
- Servos tab updated to support Cleanflight's cleaner implementation of channel forwarding<br />
</p>
<span>07.04.2014 - 0.45</span>
<span>2014.07.04 - 0.45</span>
<p>
- Configurator reached 5000+ users on 07.03.2014<br />
- Configurator reached 5000+ users on 2014.07.03<br />
- Updated various text notes to make things clearer<br />
- UI polish<br />
- Various bugfixes<br />
</p>
<span>06.27.2014 - 0.44</span>
<span>2014.06.27 - 0.44</span>
<p>
- Added more scale factors in the motor testing tab<br />
- If application closes without disconnecting motors should spin down<br />
- Bugfixes for CLI, Motor Testing &amp; Logging tabs<br />
</p>
<span>06.26.2014 - 0.43</span>
<span>2014.06.26 - 0.43</span>
<p>
- Experimental passthrough support for logging<br />
- MSP_ANALOG support for logging<br />
@ -93,31 +158,31 @@
- Tiny cosmetic changes<br />
- Initial set of UI bugfixes for Chrome 36+<br />
</p>
<span>06.16.2014 - 0.42</span>
<span>2014.06.16 - 0.42</span>
<p>
- Added I2C Error indicator to status bar<br />
- Optimizations &amp; bugfixes<br />
</p>
<span>06.01.2014 - 0.41</span>
<span>2014.06.01 - 0.41</span>
<p>
- Configurator reached 4000+ users on 05.29.2014<br />
- Support for new current sensing code (latest firmware)<br />
</p>
<span>05.27.2014 - 0.40</span>
<span>2014.05.27 - 0.40</span>
<p>
- Added Logging tab (log various MSP data into CSV file)<br />
- Bugfix for CLI input area<br />
</p>
<span>05.08.2014 - 0.39</span>
<span>2014.05.08 - 0.39</span>
<p>
- UI enhancements for sensors tab<br />
</p>
<span>05.08.2014 - 0.38</span>
<span>2014.05.08 - 0.38</span>
<p>
- Bugfix for firmware flasher UI<br />
- Updating libraries<br />
</p>
<span>05.08.2014 - 0.37</span>
<span>2014.05.08 - 0.37</span>
<p>
- Window can be resized and maximized<br />
- Graphs will now properly scale to fill content area<br />
@ -125,26 +190,26 @@
- Small UI polish on all tabs<br />
- Bugfixes<br />
</p>
<span>05.03.2014 - 0.36</span>
<span>2014.05.03 - 0.36</span>
<p>
- Another bugfix for high dpi displays<br />
- PID names will now match PID names in firmware<br />
</p>
<span>05.03.2014 - 0.35</span>
<span>2014.05.03 - 0.35</span>
<p>
- Configurator reached 3000+ users on 05.03.2014<br />
- Configurator reached 3000+ users on 2014.05.03<br />
- Polished Welcome screen<br />
- Tiny UI bugfix for gps tab<br />
</p>
<span>04.29.2014 - 0.34</span>
<span>2014.04.29 - 0.34</span>
<p>
- Bugfix for wrong graph positions on high dpi displays<br />
</p>
<span>04.26.2014 - 0.33</span>
<span>2014.04.26 - 0.33</span>
<p>
- Bugfix for loading online firmware<br />
</p>
<span>04.22.2014 - 0.32</span>
<span>2014.04.22 - 0.32</span>
<p>
- Native application frame on Chrome 35+<br />
- Dedicated application options<br />
@ -152,14 +217,14 @@
- Small ui changes<br />
- Performance improvements<br />
</p>
<span>04.11.2014 - 0.31</span>
<span>2014.04.11 - 0.31</span>
<p>
- Bugfix for Sliders not properly updating<br />
- Bugfix for CLI line feed on ChromeOS<br />
</p>
<span>04.03.2014 - 0.30</span>
<span>2014.04.03 - 0.30</span>
<p>
- Configurator reached 2000+ users on 03.24.2014<br />
- Configurator reached 2000+ users on 2014.03.24<br />
- Initial work on translation support<br />
- Small UI rework in initial tab<br />
- UI rework in receiver tab, new plot<br />
@ -167,31 +232,31 @@
- Added info box in initial tab display voltage &amp; RSSI<br />
- Stability improvements, performance improvements, bugfixes<br />
</p>
<span>03.09.2014 - 0.29</span>
<span>2014.03.09 - 0.29</span>
<p>
- Motor Tab UI bugfixes<br />
- Added support for variable plot refresh rate in Receiver Tab<br />
- Bugfixes<br />
</p>
<span>03.01.2014 - 0.28</span>
<span>2014.03.01 - 0.28</span>
<p>
- Online Firmware now displays Github commit info<br />
- Stability improvements &amp; bugfixes<br />
</p>
<span>02.27.2014 - 0.27</span>
<span>2014.02.27 - 0.27</span>
<p>
- Sensor Tab UI bugfixes<br />
- Firmware Flasher functionality improvements<br />
- Added new "developer" functionality "flash on connect"<br />
- Major Version checking added<br />
</p>
<span>02.23.2014 - 0.26</span>
<span>2014.02.23 - 0.26</span>
<p>
- Motor tab UI / functionality changes<br />
- Backup settings IO bugfixes<br />
- Receiver / Aux config tab command collision bugfix<br />
</p>
<span>02.20.2014 - 0.25</span>
<span>2014.02.20 - 0.25</span>
<p>
- Running on new serial API (Chrome 33+)<br />
- Added Velocity in PID tab<br />
@ -206,39 +271,39 @@
- IHEX parser code rework<br />
- Stronger input field validation (for most numeric fields)<br />
</p>
<span>01.17.2014 - 0.24</span>
<span>2014.01.17 - 0.24</span>
<p>
- Added Battery warning / scale UI<br />
- Added Min Throttle, Failsafe Throttle UI<br />
- Stronger Input validation<br />
- Bugfixes<br />
</p>
<span>01.04.2014 - 0.23</span>
<span>2014.01.04 - 0.23</span>
<p>
- Various UI changes across the board<br />
</p>
<span>12.29.2013 - 0.22</span>
<span>2013.12.29 - 0.22</span>
<p>
- Added auto-connect feature (enabled by default)<br />
- Bugfixes<br />
</p>
<span>12.18.2013 - 0.21</span>
<span>2013.12.18 - 0.21</span>
<p>
- Handle small screen resolutions more gracefully<br />
- Bugfix for Servo tab save button &amp; CAMSTAB<br />
</p>
<span>12.16.2013 - 0.20</span>
<span>2013.12.16 - 0.20</span>
<p>
- Minor iprovements &amp; bugfixes<br />
</p>
<span>12.09.2013 - 0.19</span>
<span>2013.12.09 - 0.19</span>
<p>
- Added packet error counter in status bar<br />
- Servos tab now also shows servos that belong to servo_tilt<br />
- Potential bugfixes for STM32 flasher<br />
- Minor iprovements &amp; bugfixes<br />
</p>
<span>11.26.2013 - 0.18</span>
<span>2013.11.26 - 0.18</span>
<p>
- Removing Refresh button<br />
- Ports are automatically pulled in the background<br />
@ -246,38 +311,38 @@
- Small UI changes related to connect sequence<br />
- Added "error" user notifications if initial connect times out<br />
</p>
<span>11.17.2013 - 0.17</span>
<span>2013.11.17 - 0.17</span>
<p>
- Extensive work on Firmware Flasher &amp; STM32 protocol<br />
- Faster flashing speed (improvement of about 24%)<br />
- Using separate thread for hex file parsing (multithreading)<br />
- Bugfixes related to flashing gnu compiled .hex files<br />
</p>
<span>11.14.2013 - 0.16</span>
<span>2013.11.14 - 0.16</span>
<p>
- Minimum required Google Chrome / Chromium version is now 31<br />
- Polished Firmware Flasher UI<br />
- Bugfixes related to flashing rev5 naze boards<br />
</p>
<span>11.14.2013 - 0.15</span>
<span>2013.11.14 - 0.15</span>
<p>
- Added firmware flasher (currently supporting 2 modes)<br />
- 1 - "local flashing", from a .hex file<br />
- 2 - "online flashing", latest firmware is fetched from github.com<br />
</p>
<span>11.12.2013 - 0.14</span>
<span>2013.11.12 - 0.14</span>
<p>
- Re-Enabled Servos tab (hopefully with all problems sorted out)<br />
- Added support for "Motor Testing Mode" in Motor/Servo Outputs tab<br />
- Updated MSP<br />
- Utilizing notification API to promote new app version updates<br />
</p>
<span>11.10.2013 - 0.13</span>
<span>2013.11.10 - 0.13</span>
<p>
- Disabling Servos tab until all bugs are ironed out<br />
- Bugfixes<br />
</p>
<span>11.09.2013 - 0.12</span>
<span>2013.11.09 - 0.12</span>
<p>
- Bugfixes related to failing connect procedure<br />
- Bugfixes related to GPS data types<br />
@ -286,20 +351,20 @@
- Major MSP refactoring, improving reliability in some cases<br />
- Initial notify implementation for critical errors<br />
</p>
<span>11.02.2013 - 0.11</span>
<span>2013.11.02 - 0.11</span>
<p>
- Debug values are now displayed and plotted in Sensor tab (dade)<br />
- Command history in CLI tab (dade)<br />
- Bugfixes related to GPS tab<br />
</p>
<span>10.30.2013 - 0.10</span>
<span>2013.10.30 - 0.10</span>
<p>
- AUX Configuration now shows current AUX channel state<br />
- Polished couple of texts<br />
- Added changelog within the app<br />
- 3D view in Initial Setup now displays model type selected<br />
</p>
<span>10.16.2013 - 0.9</span>
<span>2013.10.16 - 0.9</span>
<p>
- Polished Auxiliary configuration tab<br />
- Polished Raw sensod data tab<br />

View File

@ -1,41 +1,36 @@
/*
If an id is also specified and a window with a matching id has been shown before, the remembered bounds of the window will be used instead.
Size calculation for innerBounds seems to be faulty, app was designed for 960x625
Bug was confirmed on Windows 7
OSX seems to be unaffected
Linux and cros is unknown
I am using arbitrary dimensions which fixes the Windows 7 problem, hopefully it will get resolved in future release so other OSs won't have to
use bigger dimensions by default.
*/
'use strict';
function start_app() {
function startApplication() {
var applicationStartTime = new Date().getTime();
chrome.app.window.create('main.html', {
id: 'main-window',
frame: 'chrome',
innerBounds: {
minWidth: 974,
minHeight: 632
minWidth: 960,
minHeight: 625
}
}, function (createdWindow) {
createdWindow.contentWindow.addEventListener('load', function () {
createdWindow.contentWindow.catch_startup_time(applicationStartTime);
});
createdWindow.onClosed.addListener(function () {
// connectionId is passed from the script side through the chrome.runtime.getBackgroundPage refference
// allowing us to automatically close the port when application shut down
// autoamtically close the port when application closes
// 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;
// save connectionId in separate variable before app_window is destroyed
var connectionId = app_window.serial.connectionId;
var valid_connection = app_window.CONFIGURATOR.connectionValid;
var mincommand = app_window.MISC.mincommand;
if (connectionId > 0 && valid_connection) {
if (connectionId && valid_connection) {
// code below is handmade MSP message (without pretty JS wrapper), it behaves exactly like MSP.send_message
// reset motors to default (mincommand)
var bufferOut = new ArrayBuffer(22);
var bufView = new Uint8Array(bufferOut);
var checksum = 0;
var bufferOut = new ArrayBuffer(22),
bufView = new Uint8Array(bufferOut),
checksum = 0;
bufView[0] = 36; // $
bufView[1] = 77; // M
@ -60,7 +55,7 @@ function start_app() {
console.log('SERIAL: Connection closed - ' + result);
});
});
} else if (connectionId > 0) {
} else if (connectionId) {
chrome.serial.disconnect(connectionId, function (result) {
console.log('SERIAL: Connection closed - ' + result);
});
@ -69,17 +64,15 @@ function start_app() {
});
}
chrome.app.runtime.onLaunched.addListener(function () {
start_app();
});
chrome.app.runtime.onLaunched.addListener(startApplication);
chrome.runtime.onInstalled.addListener(function (details) {
if (details.reason == 'update') {
var previousVersionArr = details.previousVersion.split('.');
var currentVersionArr = chrome.runtime.getManifest().version.split('.');
var previousVersionArr = details.previousVersion.split('.'),
currentVersionArr = chrome.runtime.getManifest().version.split('.');
// only fire up notification sequence when one of the major version numbers changed
if (currentVersionArr[0] != previousVersionArr[0] || currentVersionArr[1] != previousVersionArr[1]) {
if (currentVersionArr[0] > previousVersionArr[0] || currentVersionArr[1] > previousVersionArr[1]) {
chrome.storage.local.get('update_notify', function (result) {
if (result.update_notify === 'undefined' || result.update_notify) {
var manifest = chrome.runtime.getManifest();
@ -103,6 +96,6 @@ chrome.runtime.onInstalled.addListener(function (details) {
chrome.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) {
if (notificationId == 'baseflight_update') {
start_app();
startApplication();
}
});

4
extras/README.md Normal file
View File

@ -0,0 +1,4 @@
This folder contains source files for various graphic elements in Baseflight Configurator.
Keep in mind that they are usually licensed under the creator's name and cannot be used in a different
project without the author's permission.

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24">
<path d="M0 0h24v24h-24z" fill="none"/>
<path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65c-.03-.24-.24-.42-.49-.42h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-7.43 2.52c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 828 B

Binary file not shown.

View File

@ -1,124 +0,0 @@
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M933.79 610.25c-53.726-93.054-21.416-212.304 72.152-266.488l-100.626-174.292c-28.75 16.854-62.176 26.518-97.846 26.518-107.536 0-194.708-87.746-194.708-195.99l-201.258 0c0.266 33.41-8.074 67.282-25.958 98.252-53.724 93.056-173.156 124.702-266.862 70.758l-100.624 174.292c28.97 16.472 54.050 40.588 71.886 71.478 53.638 92.908 21.512 211.92-71.708 266.224l100.626 174.292c28.65-16.696 61.916-26.254 97.4-26.254 107.196 0 194.144 87.192 194.7 194.958h201.254c-0.086-33.074 8.272-66.57 25.966-97.218 53.636-92.906 172.776-124.594 266.414-71.012l100.626-174.29c-28.78-16.466-53.692-40.498-71.434-71.228zM512 719.332c-114.508 0-207.336-92.824-207.336-207.334 0-114.508 92.826-207.334 207.336-207.334 114.508 0 207.332 92.826 207.332 207.334-0.002 114.51-92.824 207.334-207.332 207.334z"
],
"tags": [
"cog",
"preferences",
"settings",
"gear",
"generate",
"control",
"options"
],
"grid": 16
},
"properties": {
"id": 142,
"order": 1,
"prevSize": 32,
"code": 58880,
"name": "cog",
"ligatures": ""
},
"setIdx": 0,
"iconIdx": 142
},
{
"icon": {
"paths": [
"M363.722 722.052l41.298-57.816-45.254-45.256-57.818 41.296c-10.722-5.994-22.204-10.774-34.266-14.192l-11.682-70.084h-64l-11.68 70.086c-12.062 3.418-23.544 8.198-34.266 14.192l-57.818-41.298-45.256 45.256 41.298 57.816c-5.994 10.72-10.774 22.206-14.192 34.266l-70.086 11.682v64l70.086 11.682c3.418 12.060 8.198 23.544 14.192 34.266l-41.298 57.816 45.254 45.256 57.818-41.296c10.722 5.994 22.204 10.774 34.266 14.192l11.682 70.084h64l11.68-70.086c12.062-3.418 23.544-8.198 34.266-14.192l57.818 41.296 45.254-45.256-41.298-57.816c5.994-10.72 10.774-22.206 14.192-34.266l70.088-11.68v-64l-70.086-11.682c-3.418-12.060-8.198-23.544-14.192-34.266zM224 864c-35.348 0-64-28.654-64-64s28.652-64 64-64 64 28.654 64 64-28.652 64-64 64zM1024 384v-64l-67.382-12.25c-1.242-8.046-2.832-15.978-4.724-23.79l57.558-37.1-24.492-59.128-66.944 14.468c-4.214-6.91-8.726-13.62-13.492-20.13l39.006-56.342-45.256-45.254-56.342 39.006c-6.512-4.766-13.22-9.276-20.13-13.494l14.468-66.944-59.128-24.494-37.1 57.558c-7.812-1.892-15.744-3.482-23.79-4.724l-12.252-67.382h-64l-12.252 67.382c-8.046 1.242-15.976 2.832-23.79 4.724l-37.098-57.558-59.128 24.492 14.468 66.944c-6.91 4.216-13.62 8.728-20.13 13.494l-56.342-39.006-45.254 45.254 39.006 56.342c-4.766 6.51-9.278 13.22-13.494 20.13l-66.944-14.468-24.492 59.128 57.558 37.1c-1.892 7.812-3.482 15.742-4.724 23.79l-67.384 12.252v64l67.382 12.25c1.242 8.046 2.832 15.978 4.724 23.79l-57.558 37.1 24.492 59.128 66.944-14.468c4.216 6.91 8.728 13.618 13.494 20.13l-39.006 56.342 45.254 45.256 56.342-39.006c6.51 4.766 13.22 9.276 20.13 13.492l-14.468 66.944 59.128 24.492 37.102-57.558c7.81 1.892 15.742 3.482 23.788 4.724l12.252 67.384h64l12.252-67.382c8.044-1.242 15.976-2.832 23.79-4.724l37.1 57.558 59.128-24.492-14.468-66.944c6.91-4.216 13.62-8.726 20.13-13.492l56.342 39.006 45.256-45.256-39.006-56.342c4.766-6.512 9.276-13.22 13.492-20.13l66.944 14.468 24.492-59.13-57.558-37.1c1.892-7.812 3.482-15.742 4.724-23.79l67.382-12.25zM672 491.2c-76.878 0-139.2-62.322-139.2-139.2 0-76.878 62.32-139.2 139.2-139.2s139.2 62.322 139.2 139.2c0 76.878-62.32 139.2-139.2 139.2z"
],
"tags": [
"cogs",
"settings",
"gears",
"generate",
"control",
"options"
],
"grid": 16
},
"properties": {
"id": 143,
"order": 2,
"prevSize": 32,
"code": 58881,
"name": "cogs",
"ligatures": ""
},
"setIdx": 0,
"iconIdx": 143
},
{
"icon": {
"paths": [
"M1024 608.094v-192.188l-146.774-24.462c-5.958-18.132-13.222-35.668-21.694-52.5l86.454-121.034-135.896-135.898-120.826 86.304c-16.91-8.554-34.538-15.888-52.768-21.902l-24.402-146.414h-192.188l-24.402 146.416c-18.23 6.014-35.858 13.348-52.766 21.902l-120.828-86.304-135.898 135.898 86.454 121.036c-8.47 16.83-15.734 34.366-21.692 52.498l-146.774 24.46v192.188l147.118 24.52c5.96 17.968 13.21 35.348 21.642 52.030l-86.748 121.448 135.898 135.896 121.654-86.894c16.602 8.35 33.89 15.528 51.764 21.434l24.578 147.472h192.188l24.578-147.474c17.874-5.906 35.162-13.084 51.766-21.432l121.652 86.892 135.896-135.896-86.744-121.446c8.432-16.682 15.678-34.062 21.64-52.032l147.118-24.518zM512 640c-70.692 0-128-57.306-128-128 0-70.692 57.308-128 128-128 70.694 0 128 57.308 128 128 0 70.694-57.306 128-128 128z"
],
"tags": [
"cog",
"preferences",
"settings",
"gear",
"generate",
"control",
"options"
],
"grid": 16
},
"properties": {
"id": 144,
"order": 3,
"prevSize": 32,
"code": 58882,
"name": "cog2",
"ligatures": ""
},
"setIdx": 0,
"iconIdx": 144
}
],
"height": 1024,
"metadata": {
"name": "icomoon"
},
"preferences": {
"fontPref": {
"prefix": "icon-",
"metadata": {
"fontFamily": "icomoon"
},
"showGlyphs": true,
"metrics": {
"emSize": 512,
"baseline": 6.25,
"whitespace": 50
},
"resetPoint": 58880,
"showQuickUse": true,
"quickUsageToken": false,
"showMetrics": true,
"showMetadata": false
},
"imagePref": {
"color": 0,
"height": 32,
"columns": 16,
"margin": 16,
"png": true,
"sprites": true
},
"historySize": 100,
"showCodes": true,
"gridSize": 16,
"showLiga": false,
"showGrid": true,
"showGlyphs": true,
"showQuickUse": true,
"search": ""
}
}

View File

@ -1,101 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "fill:none;stroke:#BF1B2C;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st2 "fill:none;stroke:#000000;stroke-miterlimit:10;">
<!ENTITY st3 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#666666;stroke-miterlimit:10;">
<!ENTITY st5 "fill:none;stroke:#8D198F;stroke-width:2.4379;stroke-miterlimit:10;">
<!ENTITY st6 "fill:none;stroke:#666666;stroke-width:2;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="AirplaneMix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="126.33px"
height="120.93px" viewBox="-14.5 -44.84 126.33 120.93" xml:space="preserve">
<g id="FrontArrow" transform="matrix(1.25,0,0,-1.25,-381.26404,917.36835)">
<path id="path5270" style="&st3;" d="M343.99,717.59v9.9"/>
<path id="path5274" style="&st0;" d="M351.42,725.31l-7.48,12.95l-7.48-12.95H351.42L351.42,725.31z"/>
</g>
<g id="AirplaneGraphic">
<polyline id="polyline3" style="&st4;" points="-4.2,22.63 -4.2,15.58 29,15.58 29,22.63 "/>
<polyline id="polyline5" style="&st4;" points="101.53,22.63 101.53,15.58 68.83,15.58 68.83,22.63 "/>
<path id="rect11_2_" style="&st6;" d="M-13.5,22.63c0,0,0-31.4,18.57-31.4h87.19c18.57,0,18.57,31.4,18.57,31.4H-13.5z"/>
<path id="polyline13_2_" style="&st2;" d="M37.73,22.63"/>
<path id="polyline13-4_2_" style="&st2;" d="M59.61,22.63"/>
<path id="polyline13-4_4_" style="&st6;" d="M46.42,72.99L15.96,71c0-18.32,15.88-15,30.44-18.67l-3.65-29.7"/>
<path id="polyline13-4_3_" style="&st6;" d="M54.58,22.63l-3.64,29.7C65.49,56,81.38,52.67,81.38,71l-30.46,1.99"/>
<line id="line34_1_" style="&st4;" x1="16.58" y1="65.45" x2="46.76" y2="67.03"/>
<line id="line36_1_" style="&st4;" x1="80.76" y1="65.45" x2="50.57" y2="67.03"/>
<path id="path38" style="&st4;" d="M50.92,73.57c0-2.09,0-5.78,0-10.99c0-8.56-2.25-8.81-2.25-8.81s-2.25,0.25-2.25,8.81
c0,8.56,0,13.01,0,13.01h4.5C50.92,75.6,50.92,74.92,50.92,73.57"/>
<polyline id="polyline420" style="&st6;" points="37.72,-8.77 37.72,-15.32 41,-22.39 56.33,-22.39 59.61,-15.32 59.61,-8.77 "/>
</g>
<g id="1and2" transform="matrix(1.25,0,0,-1.25,-378.9054,819.72049)">
<g>
<path d="M337.29,675.44c0-0.07-0.02-0.12-0.05-0.16c-0.04-0.04-0.09-0.06-0.15-0.06h-0.61c-0.06,0-0.11,0.02-0.15,0.07
c-0.04,0.04-0.05,0.1-0.05,0.16v7.04l-1.44-0.63c-0.06-0.02-0.11-0.03-0.15-0.03c-0.07,0-0.1,0.04-0.1,0.13v0.57
c0,0.06,0.04,0.11,0.11,0.15l1.69,0.8c0.09,0.05,0.17,0.07,0.24,0.07h0.46c0.06,0,0.11-0.02,0.15-0.06
c0.04-0.04,0.06-0.09,0.06-0.16v-7.89H337.29z"/>
<path d="M343.59,683.41c0-0.04,0-0.07-0.01-0.09l-2.53-7.88c-0.04-0.15-0.11-0.22-0.2-0.22h-0.63c-0.11,0-0.16,0.05-0.16,0.14
c0,0.04,0.01,0.09,0.02,0.14l2.53,7.82c0.04,0.15,0.11,0.22,0.19,0.22h0.63C343.54,683.54,343.59,683.5,343.59,683.41z"/>
<path d="M349.51,681.61c0-0.3-0.05-0.57-0.15-0.8c-0.1-0.24-0.25-0.46-0.46-0.67c-0.21-0.21-0.49-0.44-0.85-0.69l-1.07-0.73
c-0.4-0.27-0.72-0.53-0.95-0.77c-0.23-0.24-0.39-0.49-0.48-0.74c-0.09-0.25-0.13-0.54-0.13-0.88v-0.24h3.77
c0.15,0,0.22-0.06,0.22-0.19v-0.49c0-0.07-0.02-0.12-0.07-0.15c-0.04-0.03-0.1-0.05-0.16-0.05h-4.45c-0.06,0-0.11,0.02-0.16,0.06
c-0.05,0.04-0.07,0.09-0.07,0.15v0.91c0,0.39,0.06,0.76,0.18,1.11c0.12,0.35,0.3,0.67,0.56,0.98c0.25,0.3,0.58,0.59,0.98,0.86
l1.13,0.77c0.47,0.31,0.77,0.57,0.92,0.77c0.15,0.2,0.22,0.46,0.22,0.8c0,0.27-0.05,0.49-0.16,0.66c-0.1,0.17-0.26,0.29-0.47,0.38
c-0.21,0.09-0.47,0.12-0.79,0.12c-0.25,0-0.51-0.02-0.76-0.07c-0.26-0.05-0.51-0.1-0.77-0.17c-0.25-0.07-0.46-0.13-0.63-0.18
c-0.07-0.02-0.12-0.02-0.16,0.01c-0.04,0.03-0.06,0.08-0.06,0.14v0.38c0,0.07,0.01,0.12,0.04,0.15c0.02,0.03,0.07,0.06,0.13,0.08
c0.19,0.08,0.4,0.16,0.62,0.24c0.22,0.07,0.48,0.14,0.78,0.19s0.58,0.08,0.85,0.08c0.38,0,0.72-0.04,1.02-0.13
c0.3-0.09,0.55-0.21,0.74-0.37c0.19-0.16,0.34-0.37,0.45-0.62C349.46,682.25,349.51,681.95,349.51,681.61z"/>
</g>
<path id="path5318" style="&st5;" d="M353.75,679.1c0-6.38-5.17-11.57-11.57-11.57c-6.4,0-11.57,5.18-11.57,11.57
c0,6.39,5.17,11.57,11.57,11.57C348.58,690.67,353.75,685.48,353.75,679.1z"/>
</g>
<g id="3" transform="translate(-52.834,-63.500761)">
<path id="path5276-7" style="&st1;" d="M78.81,83.09H53.55V57.82h25.27L78.81,83.09L78.81,83.09z"/>
<path d="M65.65,75.33c-0.45,0-0.9-0.06-1.37-0.17c-0.47-0.11-0.86-0.23-1.18-0.36c-0.08-0.04-0.14-0.08-0.16-0.12
s-0.04-0.1-0.04-0.18v-0.48c0-0.19,0.09-0.25,0.28-0.2c0.55,0.15,1,0.26,1.34,0.33c0.34,0.07,0.71,0.11,1.1,0.11
c0.75,0,1.29-0.15,1.61-0.46s0.49-0.8,0.49-1.48v-0.29c0-0.27-0.05-0.53-0.15-0.8c-0.1-0.27-0.28-0.48-0.53-0.65
s-0.57-0.26-0.96-0.26h-2.54c-0.18,0-0.27-0.08-0.27-0.25V69.6c0-0.08,0.02-0.14,0.08-0.19c0.06-0.05,0.11-0.08,0.19-0.08h2.54
c0.42,0,0.75-0.08,0.99-0.25c0.24-0.17,0.41-0.37,0.51-0.63s0.14-0.52,0.14-0.8v-0.2c0-0.4-0.07-0.71-0.2-0.95
c-0.13-0.24-0.35-0.42-0.66-0.53s-0.72-0.17-1.24-0.17c-0.39,0-0.76,0.04-1.11,0.11c-0.35,0.07-0.79,0.18-1.32,0.32
c-0.19,0.05-0.28-0.01-0.28-0.2v-0.47c0-0.09,0.01-0.15,0.04-0.19c0.03-0.04,0.08-0.07,0.16-0.11c0.31-0.13,0.7-0.25,1.16-0.37
c0.46-0.12,0.93-0.17,1.39-0.17c1.11,0,1.94,0.21,2.51,0.62c0.57,0.41,0.85,1.12,0.85,2.11v0.2c0,0.24-0.03,0.47-0.09,0.68
c-0.06,0.21-0.14,0.41-0.26,0.6s-0.26,0.36-0.42,0.52s-0.36,0.28-0.57,0.39c0.46,0.22,0.79,0.53,1.01,0.92
c0.22,0.39,0.32,0.82,0.32,1.27v0.29c0,1.02-0.29,1.77-0.89,2.26C67.52,75.07,66.71,75.33,65.65,75.33z"/>
</g>
<g id="4">
<path id="path5276" style="&st1;" d="M96.78,19.86H71.51V-5.4h25.27V19.86L96.78,19.86z"/>
<path d="M87.55,8.71c0,0.08-0.03,0.14-0.08,0.18c-0.05,0.04-0.12,0.06-0.19,0.06h-1.22v2.5c0,0.08-0.02,0.14-0.07,0.2
c-0.04,0.05-0.1,0.08-0.17,0.08h-0.81c-0.16,0-0.24-0.09-0.24-0.28v-2.5h-4.05c-0.21,0-0.35-0.04-0.44-0.12s-0.13-0.22-0.13-0.42
V7.88c0-0.2,0.06-0.37,0.17-0.52l4.14-5.81c0.1-0.15,0.23-0.23,0.41-0.23h0.82c0.25,0,0.37,0.1,0.37,0.31v6.26h1.22
c0.08,0,0.14,0.02,0.19,0.07c0.05,0.05,0.08,0.11,0.08,0.18V8.71L87.55,8.71z M84.79,7.9V3.11c0-0.05-0.02-0.08-0.05-0.08h-0.01
c-0.04,0-0.07,0.03-0.11,0.08L81.39,7.7c-0.03,0.04-0.05,0.08-0.05,0.12c0,0.05,0.04,0.08,0.12,0.08H84.79z"/>
</g>
<g id="5">
<polyline id="polyline40" style="&st2;" points="48.67,65.33 28.26,44.49 17.37,44.49 "/>
<path id="path5276-7_1_" style="&st1;" d="M17.2,57.08H-8.07V31.81H17.2V57.08z"/>
<circle id="circle62" cx="48.67" cy="65.33" r="1.88"/>
<path d="M4.88,49.42c-0.45,0-0.91-0.06-1.38-0.17s-0.86-0.23-1.17-0.36c-0.09-0.05-0.14-0.09-0.17-0.12
c-0.03-0.03-0.04-0.09-0.04-0.17v-0.48c0-0.19,0.09-0.26,0.28-0.2c0.97,0.29,1.79,0.44,2.45,0.44c0.78,0,1.36-0.18,1.73-0.55
s0.55-0.92,0.55-1.65v-0.21c0-0.69-0.22-1.17-0.67-1.45s-1.2-0.42-2.25-0.42H2.53c-0.06,0-0.12-0.03-0.16-0.08
s-0.06-0.11-0.06-0.16v-0.01l0.39-4.66C2.71,39.1,2.74,39.04,2.8,39c0.06-0.04,0.12-0.06,0.18-0.06H7.8c0.08,0,0.14,0.02,0.2,0.06
s0.08,0.1,0.08,0.17v0.62c0,0.15-0.09,0.23-0.28,0.23H3.78l-0.23,3.02h0.66c0.91,0,1.68,0.09,2.29,0.27s1.09,0.49,1.43,0.92
c0.34,0.43,0.5,1.01,0.5,1.73v0.21c0,1.04-0.31,1.84-0.93,2.41C6.88,49.15,6.01,49.42,4.88,49.42z"/>
</g>
<g id="6">
<polyline id="polyline42" style="&st2;" points="61.83,69.6 71.55,44.45 83.02,44.45 "/>
<path id="path5276-7_2_" style="&st1;" d="M108.28,57.08H83.01V31.81h25.27V57.08z"/>
<circle id="circle64" cx="61.83" cy="69.59" r="1.66"/>
<path d="M96.61,38.73c0.86,0,1.7,0.17,2.52,0.52c0.08,0.03,0.14,0.06,0.16,0.1s0.04,0.1,0.04,0.19v0.51c0,0.18-0.09,0.25-0.28,0.19
c-0.59-0.15-1.04-0.27-1.34-0.34c-0.31-0.07-0.67-0.11-1.11-0.11c-0.68,0-1.19,0.13-1.54,0.38c-0.35,0.25-0.58,0.59-0.69,1.03
c-0.11,0.44-0.16,1-0.16,1.7v0.16c0.82-0.19,1.53-0.28,2.11-0.28c0.65,0,1.23,0.09,1.74,0.27c0.51,0.18,0.92,0.49,1.23,0.92
c0.31,0.43,0.46,1.01,0.46,1.73v0.08c0,0.75-0.13,1.39-0.38,1.91s-0.63,0.93-1.14,1.21c-0.51,0.28-1.14,0.42-1.9,0.42
c-0.53,0-1-0.08-1.42-0.24s-0.77-0.4-1.06-0.72c-0.29-0.32-0.52-0.73-0.67-1.24c-0.15-0.51-0.24-1.09-0.24-1.76V42.9
c0-0.99,0.14-1.79,0.41-2.4c0.27-0.61,0.68-1.06,1.22-1.34C95.13,38.87,95.8,38.73,96.61,38.73z M98.5,45.78V45.7
c0-0.47-0.1-0.86-0.3-1.15c-0.2-0.29-0.46-0.49-0.78-0.61c-0.32-0.12-0.69-0.18-1.09-0.18c-0.31,0-0.68,0.03-1.09,0.08
c-0.41,0.05-0.75,0.11-1.02,0.17v1.33c0,0.75,0.08,1.34,0.24,1.76s0.4,0.73,0.71,0.91c0.31,0.18,0.7,0.27,1.18,0.27
c0.33,0,0.63-0.05,0.9-0.14c0.27-0.09,0.49-0.23,0.68-0.42c0.19-0.19,0.33-0.45,0.43-0.78C98.45,46.62,98.5,46.23,98.5,45.78z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -1,102 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:#231F20;">
<!ENTITY st3 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="hex6p-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="113.34px"
height="127.02px" viewBox="5.62 7.63 113.34 127.02" xml:space="preserve">
<g id="M6">
<path id="path4002" style="&st2;" d="M65.66,116.45v-0.09c0-0.51-0.11-0.92-0.32-1.23c-0.21-0.31-0.49-0.53-0.84-0.66
c-0.35-0.13-0.73-0.19-1.17-0.19c-0.34,0-0.73,0.03-1.17,0.08c-0.44,0.06-0.81,0.12-1.09,0.19v1.43c0,0.8,0.09,1.43,0.26,1.89
c0.17,0.46,0.43,0.78,0.76,0.97c0.33,0.19,0.75,0.29,1.26,0.29c0.36,0,0.68-0.05,0.96-0.15c0.29-0.1,0.53-0.25,0.72-0.45
c0.2-0.2,0.35-0.48,0.46-0.84C65.61,117.36,65.66,116.94,65.66,116.45z M63.64,108.89c0.92,0,1.82,0.18,2.7,0.56
c0.09,0.03,0.15,0.07,0.18,0.11c0.03,0.04,0.04,0.11,0.04,0.21v0.54c0,0.19-0.1,0.26-0.3,0.21c-0.63-0.17-1.11-0.29-1.43-0.36
c-0.33-0.08-0.72-0.11-1.19-0.11c-0.73,0-1.28,0.13-1.66,0.4c-0.38,0.27-0.62,0.64-0.74,1.11c-0.11,0.47-0.17,1.07-0.17,1.82v0.17
c0.88-0.2,1.64-0.3,2.26-0.3c0.69,0,1.32,0.1,1.86,0.29c0.55,0.2,0.99,0.52,1.32,0.99c0.33,0.46,0.49,1.08,0.49,1.85v0.09
c0,0.8-0.14,1.49-0.41,2.05c-0.27,0.57-0.68,1-1.22,1.3c-0.54,0.3-1.22,0.45-2.03,0.45c-0.57,0-1.07-0.09-1.52-0.26
c-0.45-0.17-0.83-0.43-1.14-0.78s-0.55-0.79-0.72-1.33c-0.17-0.54-0.25-1.17-0.25-1.89v-2.63c0-1.06,0.15-1.92,0.44-2.57
c0.29-0.65,0.73-1.13,1.31-1.44C62.06,109.04,62.78,108.89,63.64,108.89L63.64,108.89z"/>
<path id="path5546" style="&st0;" d="M60.93,97.77c9.72-1.44,18.77,5.27,20.21,14.99c1.44,9.72-5.27,18.77-14.99,20.21
c-9.72,1.44-18.76-5.27-20.21-14.99C44.5,108.25,51.21,99.21,60.93,97.77L60.93,97.77z"/>
<path id="path5550" style="&st4;" d="M46.63,120.24l-3.31,10.44"/>
<path id="path5554" style="&st4;" d="M46.63,120.24l10.3,4.27"/>
</g>
<g id="M5">
<path id="path4000" style="&st2;" d="M61.72,32.75c-0.48,0-0.98-0.06-1.48-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.05-0.15-0.09-0.18-0.13c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.28,0.3-0.21c1.04,0.31,1.92,0.47,2.63,0.47
c0.84,0,1.45-0.2,1.85-0.59c0.39-0.4,0.59-0.98,0.59-1.76v-0.23c0-0.74-0.24-1.26-0.72-1.56c-0.48-0.3-1.29-0.45-2.41-0.45h-1.79
c-0.07,0-0.13-0.03-0.17-0.08c-0.05-0.06-0.07-0.11-0.07-0.17v-0.02l0.42-5c0.01-0.08,0.04-0.14,0.1-0.19
c0.06-0.05,0.13-0.07,0.2-0.07h5.16c0.08,0,0.15,0.02,0.21,0.07c0.06,0.05,0.09,0.11,0.09,0.19v0.66c0,0.16-0.1,0.24-0.3,0.24
h-4.31l-0.24,3.24H61c0.98,0,1.8,0.1,2.46,0.29c0.66,0.19,1.17,0.52,1.53,0.99c0.36,0.46,0.53,1.08,0.53,1.85v0.23
c0,1.11-0.33,1.97-0.99,2.58C63.86,32.45,62.93,32.75,61.72,32.75z"/>
<path id="path5498" style="&st0;" d="M43.72,26.92c0,9.83,7.96,17.79,17.79,17.79c9.83,0,17.79-7.96,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79C51.69,9.13,43.72,17.1,43.72,26.92z"/>
<path id="path5502" style="&st4;" d="M44.35,21.12l10.5-3.14"/>
<path id="path5506" style="&st4;" d="M44.35,21.12l-2.27-10.91"/>
</g>
<g id="M4">
<path id="path3994" style="&st2;" d="M28.69,51.01c0,0.08-0.03,0.15-0.08,0.2c-0.06,0.05-0.12,0.07-0.2,0.07h-1.3v2.67
c0,0.08-0.02,0.15-0.07,0.21c-0.05,0.06-0.11,0.09-0.19,0.09h-0.87c-0.17,0-0.26-0.1-0.26-0.3v-2.67h-4.34
c-0.22,0-0.38-0.04-0.47-0.13c-0.1-0.09-0.14-0.24-0.14-0.45v-0.57c0-0.21,0.06-0.4,0.18-0.56l4.44-6.22
c0.1-0.16,0.25-0.24,0.44-0.24h0.88c0.26,0,0.4,0.11,0.4,0.33v6.71h1.3c0.08,0,0.15,0.03,0.21,0.07c0.05,0.05,0.08,0.12,0.08,0.2
L28.69,51.01L28.69,51.01z M25.73,50.14v-5.13c0-0.06-0.02-0.09-0.06-0.09h-0.02c-0.04,0-0.08,0.03-0.12,0.09l-3.46,4.92
c-0.03,0.04-0.05,0.08-0.05,0.13c0,0.06,0.04,0.09,0.13,0.09L25.73,50.14L25.73,50.14z"/>
<path id="path5510" style="&st0;" d="M42.7,49.14c0,9.82-7.96,17.79-17.79,17.79c-9.83,0-17.79-7.97-17.79-17.79
c0-9.83,7.97-17.79,17.79-17.79S42.7,39.32,42.7,49.14z"/>
<path id="path5514" style="&st4;" d="M19.84,31.58L9.09,29.52"/>
<path id="path5518" style="&st4;" d="M19.84,31.58l-3.03,10.73"/>
</g>
<g id="M3">
<path id="path3996" style="&st2;" d="M26.08,98.15c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.04-0.15-0.08-0.18-0.12s-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
s0.76,0.12,1.18,0.12c0.81,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.85,0.52-1.58v-0.32c0-0.29-0.05-0.57-0.17-0.85
c-0.11-0.28-0.3-0.51-0.56-0.7c-0.27-0.19-0.61-0.28-1.03-0.28H23.8c-0.19,0-0.29-0.09-0.29-0.27v-0.52c0-0.08,0.03-0.15,0.08-0.21
c0.05-0.05,0.12-0.08,0.21-0.08h2.72c0.45,0,0.81-0.09,1.06-0.26c0.26-0.18,0.44-0.4,0.54-0.67c0.1-0.27,0.15-0.55,0.15-0.85v-0.21
c0-0.43-0.07-0.77-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.13-0.77-0.19-1.33-0.19c-0.42,0-0.82,0.04-1.19,0.12
c-0.38,0.08-0.85,0.19-1.41,0.34c-0.2,0.06-0.3-0.01-0.3-0.21v-0.51c0-0.09,0.01-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.17-0.11
c0.33-0.14,0.75-0.27,1.24-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67c0.61,0.44,0.91,1.19,0.91,2.26v0.21
c0,0.26-0.03,0.5-0.09,0.73c-0.06,0.23-0.15,0.44-0.27,0.65c-0.12,0.2-0.27,0.39-0.45,0.55c-0.18,0.17-0.38,0.31-0.61,0.42
c0.49,0.24,0.85,0.56,1.08,0.99c0.23,0.42,0.35,0.88,0.35,1.36v0.32c0,1.09-0.32,1.9-0.95,2.42C28.1,97.89,27.22,98.15,26.08,98.15
L26.08,98.15z"/>
<path id="path5558" style="&st0;" d="M35.48,107.66c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
c-8.29,5.27-10.74,16.27-5.46,24.56C16.19,110.49,27.19,112.93,35.48,107.66z"/>
<path id="path5562" style="&st4;" d="M20.21,109.83l-3.19-10.48"/>
<path id="path5566" style="&st4;" d="M20.21,109.83l-10.9,2.32"/>
</g>
<g id="M2">
<path id="path4014" style="&st2;" d="M103.91,44.47c0,0.4-0.07,0.76-0.2,1.07c-0.13,0.32-0.34,0.62-0.62,0.9
c-0.28,0.29-0.66,0.59-1.14,0.92l-1.43,0.97c-0.54,0.37-0.97,0.71-1.28,1.03c-0.31,0.32-0.53,0.65-0.64,0.99
c-0.12,0.34-0.18,0.73-0.18,1.17v0.31h5.05c0.2,0,0.3,0.08,0.3,0.26v0.66c0,0.09-0.03,0.15-0.09,0.2
c-0.06,0.05-0.13,0.07-0.21,0.07h-5.96c-0.08,0-0.15-0.03-0.21-0.08s-0.09-0.12-0.09-0.2v-1.22c0-0.52,0.08-1.02,0.24-1.48
c0.16-0.47,0.41-0.9,0.75-1.31s0.78-0.79,1.32-1.15l1.52-1.03c0.63-0.42,1.04-0.76,1.24-1.03c0.2-0.27,0.3-0.62,0.3-1.07
c0-0.36-0.07-0.66-0.21-0.88c-0.14-0.23-0.35-0.39-0.63-0.5c-0.28-0.11-0.63-0.16-1.06-0.16c-0.34,0-0.68,0.03-1.02,0.09
c-0.34,0.06-0.68,0.14-1.02,0.23c-0.34,0.1-0.62,0.18-0.85,0.24c-0.09,0.03-0.17,0.02-0.22-0.02c-0.05-0.04-0.08-0.1-0.08-0.19
v-0.51c0-0.09,0.02-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.18-0.11c0.26-0.11,0.54-0.22,0.84-0.32c0.3-0.1,0.65-0.18,1.04-0.25
c0.4-0.07,0.78-0.11,1.14-0.11c0.51,0,0.96,0.06,1.37,0.18c0.41,0.12,0.74,0.28,1,0.5c0.26,0.21,0.46,0.49,0.6,0.83
C103.84,43.62,103.91,44.02,103.91,44.47L103.91,44.47z"/>
<path id="path5522" style="&st0;" d="M107.01,63.36c-8.95,4.06-19.49,0.1-23.55-8.85c-4.06-8.95-0.1-19.49,8.85-23.55
c8.95-4.06,19.49-0.1,23.55,8.85C119.92,48.75,115.96,59.3,107.01,63.36z"/>
<path id="path5526" style="&st4;" d="M112.62,34.27l-3.36-10.43"/>
<path id="path5530" style="&st4;" d="M112.62,34.27l-10.86,2.5"/>
</g>
<g id="M1">
<path id="path3998" style="&st2;" d="M101.11,96.4c0,0.09-0.03,0.16-0.07,0.22c-0.05,0.06-0.11,0.08-0.2,0.08h-0.82
c-0.08,0-0.15-0.03-0.2-0.09s-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04c-0.09,0-0.13-0.06-0.13-0.17
v-0.76c0-0.08,0.05-0.14,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.09,0.32-0.09h0.61c0.08,0,0.15,0.03,0.2,0.08
c0.06,0.05,0.08,0.12,0.08,0.21V96.4L101.11,96.4z"/>
<path id="path5534" style="&st0;" d="M108.12,74.42c-8.64-4.67-19.44-1.46-24.11,7.19c-4.67,8.64-1.46,19.44,7.19,24.11
c8.64,4.67,19.44,1.46,24.11-7.19C119.98,89.89,116.77,79.1,108.12,74.42z"/>
<path id="path5538" style="&st4;" d="M108.41,105.56l-10.05-4.37"/>
<path id="path5542" style="&st4;" d="M108.41,105.56l-5.3,9.81"/>
</g>
<g id="FrontArrow">
<path id="path5224" style="&st3;" d="M62.83,84.18V71.8"/>
<path id="path5228" style="&st1;" d="M72.13,74.54l-9.35-16.19l-9.35,16.19H72.13z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -1,101 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:#231F20;">
<!ENTITY st3 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="hex6x-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="130.52px"
height="126.07px" viewBox="0.37 0.38 130.52 126.07" xml:space="preserve">
<g id="M6">
<path id="path4036" style="&st2;" d="M27.89,65.66v-0.09c0-0.51-0.11-0.92-0.32-1.23c-0.21-0.31-0.49-0.53-0.84-0.66
c-0.35-0.13-0.74-0.19-1.16-0.19c-0.34,0-0.73,0.03-1.17,0.08c-0.44,0.06-0.81,0.12-1.09,0.19v1.43c0,0.8,0.09,1.43,0.26,1.89
c0.17,0.46,0.43,0.78,0.76,0.97c0.33,0.19,0.75,0.29,1.26,0.29c0.36,0,0.68-0.05,0.96-0.15c0.29-0.1,0.53-0.25,0.72-0.45
s0.35-0.48,0.46-0.83C27.84,66.56,27.89,66.14,27.89,65.66z M25.87,58.1c0.92,0,1.82,0.18,2.7,0.56c0.09,0.03,0.15,0.07,0.18,0.11
c0.03,0.04,0.04,0.11,0.04,0.21v0.54c0,0.19-0.1,0.26-0.3,0.21c-0.63-0.17-1.11-0.29-1.43-0.36c-0.33-0.08-0.72-0.11-1.19-0.11
c-0.73,0-1.28,0.13-1.66,0.4c-0.38,0.27-0.62,0.64-0.73,1.11c-0.12,0.47-0.17,1.07-0.17,1.82v0.17c0.88-0.2,1.64-0.3,2.26-0.3
c0.69,0,1.32,0.1,1.86,0.29c0.55,0.2,0.99,0.53,1.32,0.99c0.33,0.46,0.49,1.08,0.49,1.85v0.09c0,0.8-0.14,1.48-0.41,2.05
c-0.27,0.57-0.68,1-1.22,1.3c-0.54,0.3-1.22,0.45-2.03,0.45c-0.57,0-1.07-0.09-1.52-0.26c-0.45-0.17-0.83-0.43-1.14-0.78
c-0.31-0.34-0.55-0.79-0.72-1.33c-0.17-0.54-0.25-1.17-0.25-1.89v-2.63c0-1.06,0.15-1.92,0.44-2.57c0.29-0.65,0.73-1.13,1.31-1.44
C24.28,58.25,25.01,58.1,25.87,58.1L25.87,58.1z"/>
<path id="path5486" style="&st0;" d="M35.48,78.97c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
C8.09,54.22,5.65,65.21,10.92,73.5C16.19,81.79,27.19,84.24,35.48,78.97z"/>
<path id="path5490" style="&st4;" d="M12.52,76.13l2.36-10.7"/>
<path id="path5494" style="&st4;" d="M12.52,76.13L1.87,72.81"/>
</g>
<g id="M5">
<path id="path3915" style="&st2;" d="M110.72,68.98c-0.48,0-0.98-0.06-1.48-0.18c-0.5-0.12-0.92-0.25-1.26-0.39
c-0.09-0.05-0.15-0.09-0.18-0.13c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.21,0.1-0.28,0.3-0.21c1.04,0.31,1.92,0.47,2.63,0.47
c0.84,0,1.46-0.2,1.85-0.59c0.39-0.39,0.59-0.98,0.59-1.76v-0.23c0-0.74-0.24-1.26-0.72-1.56c-0.48-0.3-1.29-0.45-2.41-0.45h-1.8
c-0.07,0-0.13-0.03-0.17-0.08c-0.05-0.06-0.07-0.11-0.07-0.17v-0.01l0.42-5c0.01-0.08,0.04-0.14,0.1-0.19
c0.06-0.05,0.13-0.07,0.2-0.07h5.16c0.08,0,0.15,0.02,0.21,0.07c0.06,0.05,0.09,0.11,0.09,0.19v0.66c0,0.16-0.1,0.24-0.3,0.24
h-4.31l-0.24,3.24h0.7c0.98,0,1.8,0.1,2.46,0.29c0.66,0.2,1.17,0.53,1.53,0.99s0.53,1.08,0.53,1.85v0.23
c0,1.11-0.33,1.97-0.99,2.58C112.86,68.68,111.92,68.98,110.72,68.98L110.72,68.98z"/>
<path id="path5450" style="&st0;" d="M118.95,80.26c-8.95,4.06-19.49,0.1-23.55-8.85c-4.06-8.95-0.1-19.49,8.85-23.55
c8.95-4.06,19.49-0.1,23.55,8.85C131.86,65.66,127.9,76.21,118.95,80.26z"/>
<path id="path5454" style="&st4;" d="M124.56,51.18l-3.36-10.43"/>
<path id="path5458" style="&st4;" d="M124.56,51.18l-10.86,2.5"/>
</g>
<g id="M4">
<path id="path4034" style="&st2;" d="M49.71,29.15c0,0.08-0.03,0.15-0.08,0.19c-0.06,0.05-0.12,0.07-0.2,0.07h-1.3v2.67
c0,0.08-0.02,0.15-0.07,0.21c-0.05,0.06-0.11,0.09-0.19,0.09h-0.87c-0.17,0-0.26-0.1-0.26-0.3v-2.67H42.4
c-0.22,0-0.38-0.04-0.47-0.13s-0.14-0.24-0.14-0.45v-0.57c0-0.21,0.06-0.39,0.18-0.56l4.44-6.23c0.1-0.16,0.25-0.24,0.44-0.24h0.88
c0.26,0,0.39,0.11,0.39,0.33v6.71h1.3c0.08,0,0.15,0.02,0.21,0.07s0.08,0.11,0.08,0.2V29.15L49.71,29.15z M46.75,28.28v-5.13
c0-0.06-0.02-0.09-0.06-0.09h-0.01c-0.04,0-0.08,0.03-0.12,0.09l-3.46,4.92c-0.03,0.04-0.05,0.08-0.05,0.13
c0,0.06,0.04,0.09,0.12,0.09H46.75z"/>
<path id="path5426" style="&st0;" d="M64.19,27.42c0,9.82-7.96,17.79-17.79,17.79c-9.83,0-17.79-7.96-17.79-17.79
c0-9.83,7.96-17.79,17.79-17.79C56.23,9.63,64.19,17.59,64.19,27.42z"/>
<path id="path5430" style="&st4;" d="M40.02,10.29L29.13,9.04"/>
<path id="path5434" style="&st4;" d="M40.02,10.29l-2.21,10.93"/>
</g>
<g id="M3">
<path id="path4042" style="&st2;" d="M46.42,105.65c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.04-0.15-0.08-0.18-0.12c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
c0.36,0.08,0.76,0.12,1.18,0.12c0.81,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.86,0.52-1.58v-0.31c0-0.29-0.05-0.57-0.17-0.85
c-0.11-0.28-0.3-0.52-0.56-0.7c-0.27-0.19-0.61-0.28-1.03-0.28h-2.72c-0.19,0-0.29-0.09-0.29-0.27V99.5c0-0.08,0.03-0.15,0.08-0.21
s0.12-0.08,0.21-0.08h2.73c0.45,0,0.8-0.09,1.06-0.26c0.26-0.18,0.44-0.4,0.54-0.67c0.1-0.27,0.15-0.55,0.15-0.85v-0.21
c0-0.42-0.07-0.76-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.12-0.77-0.19-1.33-0.19c-0.42,0-0.82,0.04-1.19,0.12
c-0.38,0.08-0.85,0.19-1.41,0.34c-0.2,0.06-0.3-0.01-0.3-0.21v-0.51c0-0.09,0.02-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.17-0.11
c0.33-0.14,0.75-0.27,1.25-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67c0.61,0.44,0.91,1.2,0.91,2.26v0.21
c0,0.26-0.03,0.5-0.09,0.73c-0.06,0.23-0.15,0.44-0.27,0.64c-0.12,0.2-0.27,0.39-0.45,0.55s-0.38,0.31-0.61,0.42
c0.49,0.24,0.85,0.56,1.08,0.98c0.23,0.42,0.35,0.88,0.35,1.37v0.31c0,1.09-0.32,1.9-0.95,2.42
C48.44,105.38,47.56,105.65,46.42,105.65L46.42,105.65z"/>
<path id="path5474" style="&st0;" d="M44.24,82.05c9.72-1.44,18.77,5.27,20.21,14.99c1.44,9.72-5.27,18.77-14.99,20.21
c-9.72,1.44-18.76-5.27-20.21-14.99C27.81,92.54,34.52,83.5,44.24,82.05z"/>
<path id="path5478" style="&st4;" d="M29.94,104.53l-3.31,10.44"/>
<path id="path5482" style="&st4;" d="M29.94,104.53l10.3,4.26"/>
</g>
<g id="M2">
<path id="path4040" style="&st2;" d="M92.89,23.3c0,0.4-0.07,0.76-0.2,1.07c-0.13,0.31-0.34,0.62-0.62,0.9
c-0.28,0.29-0.66,0.59-1.14,0.92l-1.44,0.97c-0.54,0.37-0.97,0.71-1.28,1.03s-0.53,0.65-0.64,0.99c-0.12,0.34-0.18,0.73-0.18,1.17
v0.32h5.05c0.2,0,0.3,0.08,0.3,0.26v0.66c0,0.09-0.03,0.16-0.09,0.2s-0.13,0.07-0.21,0.07H86.5c-0.08,0-0.15-0.03-0.21-0.08
c-0.06-0.06-0.09-0.12-0.09-0.2v-1.22c0-0.52,0.08-1.02,0.24-1.48c0.16-0.47,0.41-0.9,0.75-1.31c0.34-0.41,0.78-0.79,1.31-1.15
l1.52-1.02c0.63-0.42,1.04-0.76,1.24-1.03c0.2-0.27,0.3-0.62,0.3-1.07c0-0.36-0.07-0.66-0.21-0.88c-0.14-0.23-0.35-0.39-0.63-0.5
c-0.28-0.11-0.63-0.16-1.05-0.16c-0.34,0-0.68,0.03-1.02,0.09c-0.34,0.06-0.68,0.14-1.03,0.24c-0.34,0.1-0.62,0.17-0.85,0.24
c-0.09,0.03-0.17,0.03-0.22-0.01s-0.08-0.1-0.08-0.19V21.6c0-0.09,0.02-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.18-0.11
c0.26-0.11,0.54-0.22,0.83-0.32c0.3-0.1,0.64-0.18,1.04-0.25c0.4-0.07,0.78-0.11,1.14-0.11c0.51,0,0.96,0.06,1.37,0.18
c0.41,0.12,0.74,0.28,1,0.5s0.46,0.49,0.6,0.83C92.82,22.46,92.89,22.85,92.89,23.3L92.89,23.3z"/>
<path id="path5438" style="&st0;" d="M71.45,26.92c0,9.82,7.96,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79C79.41,9.13,71.45,17.1,71.45,26.92L71.45,26.92z"/>
<path id="path5442" style="&st4;" d="M86.17,9.07l7.76,7.73"/>
<path id="path5446" style="&st4;" d="M86.17,9.07l8.51-7.2"/>
</g>
<g id="M1">
<path id="path4038" style="&st2;" d="M91.09,103.92c0,0.09-0.03,0.16-0.07,0.22c-0.05,0.06-0.12,0.08-0.2,0.08H90
c-0.08,0-0.15-0.03-0.2-0.09s-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04c-0.09,0-0.13-0.06-0.13-0.17
v-0.76c0-0.08,0.05-0.15,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.1,0.32-0.1h0.62c0.08,0,0.14,0.03,0.2,0.08
c0.06,0.05,0.08,0.12,0.08,0.21L91.09,103.92L91.09,103.92z"/>
<path id="path5462" style="&st0;" d="M98.13,84.01c-8.64-4.67-19.44-1.46-24.11,7.19c-4.67,8.64-1.46,19.44,7.19,24.11
c8.64,4.68,19.44,1.46,24.11-7.18C109.99,99.47,106.77,88.68,98.13,84.01z"/>
<path id="path5466" style="&st4;" d="M98.41,115.14l-10.05-4.37"/>
<path id="path5470" style="&st4;" d="M98.41,115.14l-5.3,9.81"/>
</g>
<g id="FrontArrow">
<path id="path5248" style="&st3;" d="M68.03,76.99V64.61"/>
<path id="path5252" style="&st1;" d="M77.33,67.34l-9.35-16.19l-9.35,16.19H77.33z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -1,129 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:#231F20;">
<!ENTITY st3 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="octox-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="153.18px"
height="156.84px" viewBox="0 0 153.18 156.84" xml:space="preserve">
<g id="M8">
<path id="path4129" style="&st2;" d="M30.78,102.38c0,1.05-0.34,1.85-1.03,2.39c-0.69,0.54-1.56,0.82-2.62,0.82h-0.15
c-1.06,0-1.93-0.27-2.62-0.82c-0.69-0.54-1.03-1.34-1.03-2.39v-0.29c0-0.47,0.13-0.93,0.39-1.38s0.62-0.8,1.07-1.05
c-0.46-0.24-0.81-0.56-1.06-0.97c-0.25-0.41-0.37-0.86-0.37-1.36v-0.14c0-0.67,0.15-1.23,0.46-1.67c0.31-0.44,0.74-0.76,1.28-0.97
c0.54-0.21,1.17-0.32,1.88-0.32h0.15c0.71,0,1.33,0.11,1.88,0.32c0.54,0.21,0.97,0.53,1.28,0.97c0.31,0.44,0.46,0.99,0.46,1.67
v0.14c0,0.34-0.05,0.65-0.17,0.95c-0.11,0.3-0.27,0.56-0.48,0.79c-0.21,0.23-0.47,0.43-0.79,0.59c0.45,0.25,0.8,0.6,1.07,1.04
c0.26,0.44,0.39,0.91,0.39,1.39L30.78,102.38L30.78,102.38z M29.43,97.33v-0.14c0-0.59-0.2-1.04-0.59-1.36
c-0.4-0.32-0.96-0.48-1.71-0.48h-0.15c-0.74,0-1.31,0.16-1.71,0.48c-0.39,0.32-0.59,0.77-0.59,1.36v0.14
c0,0.51,0.16,0.94,0.47,1.29c0.31,0.34,0.79,0.52,1.44,0.52h0.93c0.64,0,1.12-0.17,1.43-0.52C29.27,98.27,29.43,97.84,29.43,97.33z
M29.41,102.38v-0.29c0-0.3-0.07-0.6-0.19-0.89c-0.13-0.29-0.34-0.53-0.62-0.72c-0.29-0.19-0.64-0.28-1.07-0.28h-0.93
c-0.42,0-0.78,0.09-1.07,0.28c-0.29,0.19-0.5,0.43-0.63,0.72c-0.13,0.29-0.2,0.59-0.2,0.89v0.29c0,0.65,0.2,1.16,0.6,1.53
c0.4,0.36,0.96,0.54,1.69,0.54h0.15c0.74,0,1.3-0.18,1.7-0.54S29.41,103.03,29.41,102.38z"/>
<path id="path5880" style="&st0;" d="M24.54,82c9.72-1.44,18.77,5.27,20.21,14.99c1.44,9.72-5.27,18.77-14.99,20.21
c-9.72,1.44-18.77-5.27-20.21-14.99C8.11,92.49,14.82,83.44,24.54,82z"/>
<path id="path5884" style="&st4;" d="M10.23,104.47l-3.31,10.44"/>
<path id="path5888" style="&st4;" d="M10.23,104.47l10.3,4.27"/>
</g>
<g id="M7">
<path id="path4144" style="&st2;" d="M105.39,126.1c0,0.25-0.07,0.51-0.2,0.78l-4.32,9.19c-0.08,0.15-0.19,0.23-0.33,0.23h-0.9
c-0.15,0-0.23-0.08-0.23-0.23c0-0.05,0.01-0.1,0.04-0.16l4.53-9.42c0.01-0.01,0.02-0.03,0.02-0.06c0-0.07-0.04-0.1-0.11-0.1h-5.11
c-0.2,0-0.3-0.09-0.3-0.26v-0.63c0-0.07,0.03-0.14,0.09-0.2s0.13-0.09,0.21-0.09h5.47c0.4,0,0.68,0.09,0.86,0.26
C105.3,125.6,105.39,125.83,105.39,126.1L105.39,126.1z"/>
<path id="path5808" style="&st0;" d="M99.42,112.82c9.72-1.44,18.77,5.27,20.21,14.99c1.44,9.72-5.27,18.77-14.99,20.21
c-9.72,1.44-18.77-5.27-20.21-14.99C82.99,123.31,89.7,114.26,99.42,112.82z"/>
<path id="path5812" style="&st4;" d="M85.12,135.29l-3.31,10.44"/>
<path id="path5816" style="&st4;" d="M85.12,135.29l10.3,4.27"/>
</g>
<g id="M6">
<path id="path4138" style="&st2;" d="M135.34,60.04v-0.09c0-0.51-0.11-0.92-0.32-1.23c-0.21-0.31-0.49-0.53-0.84-0.66
c-0.35-0.13-0.73-0.19-1.16-0.19c-0.34,0-0.73,0.03-1.17,0.08c-0.45,0.06-0.81,0.12-1.09,0.19v1.43c0,0.8,0.09,1.43,0.26,1.89
s0.43,0.78,0.76,0.97s0.75,0.29,1.26,0.29c0.36,0,0.68-0.05,0.96-0.15c0.29-0.1,0.53-0.25,0.73-0.45c0.2-0.2,0.35-0.48,0.46-0.83
C135.28,60.94,135.34,60.52,135.34,60.04L135.34,60.04z M133.31,52.48c0.92,0,1.82,0.19,2.7,0.56c0.09,0.03,0.15,0.07,0.18,0.11
s0.04,0.11,0.04,0.21v0.54c0,0.2-0.1,0.26-0.3,0.21c-0.63-0.17-1.11-0.29-1.44-0.36s-0.72-0.11-1.19-0.11
c-0.73,0-1.28,0.13-1.66,0.4c-0.38,0.27-0.62,0.64-0.74,1.1s-0.17,1.07-0.17,1.82v0.17c0.88-0.2,1.64-0.3,2.26-0.3
c0.69,0,1.32,0.1,1.86,0.29c0.55,0.2,0.99,0.52,1.32,0.99s0.49,1.08,0.49,1.85v0.09c0,0.8-0.13,1.49-0.41,2.05
c-0.27,0.57-0.68,1-1.22,1.3c-0.54,0.3-1.22,0.45-2.03,0.45c-0.57,0-1.07-0.09-1.52-0.26s-0.83-0.43-1.14-0.78
s-0.55-0.79-0.72-1.33c-0.17-0.54-0.25-1.17-0.25-1.89v-2.63c0-1.06,0.15-1.92,0.44-2.57c0.29-0.65,0.73-1.13,1.31-1.44
S132.45,52.48,133.31,52.48L133.31,52.48z"/>
<path id="path5760" style="&st0;" d="M140.86,75.11c-8.95,4.06-19.49,0.1-23.55-8.85c-4.06-8.95-0.1-19.49,8.85-23.55
c8.95-4.06,19.49-0.1,23.55,8.85C153.77,60.51,149.81,71.05,140.86,75.11z"/>
<path id="path5764" style="&st4;" d="M146.47,46.03l-3.36-10.43"/>
<path id="path5768" style="&st4;" d="M146.47,46.03l-10.86,2.5"/>
</g>
<g id="M5">
<path id="path4119" style="&st2;" d="M57.47,32.49c-0.48,0-0.98-0.06-1.48-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.05-0.15-0.09-0.18-0.13c-0.03-0.04-0.04-0.1-0.04-0.19V31.1c0-0.21,0.1-0.28,0.3-0.21c1.04,0.31,1.92,0.47,2.63,0.47
c0.84,0,1.46-0.2,1.85-0.59c0.39-0.4,0.59-0.98,0.59-1.77v-0.23c0-0.74-0.24-1.26-0.72-1.56c-0.48-0.3-1.29-0.45-2.41-0.45h-1.8
c-0.07,0-0.13-0.03-0.17-0.08c-0.05-0.06-0.07-0.11-0.07-0.17v-0.02l0.42-5c0.01-0.08,0.04-0.14,0.1-0.19
c0.06-0.05,0.12-0.07,0.2-0.07h5.16c0.08,0,0.15,0.02,0.21,0.07c0.06,0.05,0.09,0.11,0.09,0.19v0.66c0,0.16-0.1,0.24-0.3,0.24
h-4.31l-0.24,3.24h0.7c0.98,0,1.8,0.1,2.46,0.29c0.66,0.19,1.17,0.52,1.53,0.99c0.36,0.46,0.54,1.08,0.54,1.85V29
c0,1.11-0.33,1.97-0.99,2.58C59.61,32.19,58.68,32.49,57.47,32.49z"/>
<path id="path5712" style="&st0;" d="M76.33,27.41c0,9.83-7.96,17.79-17.79,17.79c-9.83,0-17.79-7.96-17.79-17.79
c0-9.82,7.96-17.79,17.79-17.79C68.36,9.62,76.33,17.59,76.33,27.41z"/>
<path id="path5716" style="&st4;" d="M52.15,10.29L41.27,9.04"/>
<path id="path5720" style="&st4;" d="M52.15,10.29l-2.21,10.93"/>
</g>
<g id="M4">
<path id="path4147" style="&st2;" d="M62.97,131c0,0.08-0.03,0.15-0.08,0.19c-0.06,0.05-0.12,0.07-0.2,0.07h-1.3v2.67
c0,0.08-0.02,0.15-0.07,0.21c-0.05,0.06-0.11,0.09-0.19,0.09h-0.87c-0.17,0-0.26-0.1-0.26-0.3v-2.67h-4.34
c-0.22,0-0.38-0.04-0.47-0.13c-0.1-0.09-0.14-0.24-0.14-0.45v-0.57c0-0.21,0.06-0.39,0.18-0.56l4.44-6.23
c0.1-0.16,0.25-0.24,0.44-0.24h0.88c0.26,0,0.4,0.11,0.4,0.33v6.71h1.3c0.08,0,0.15,0.03,0.21,0.07c0.05,0.05,0.08,0.12,0.08,0.2
L62.97,131L62.97,131z M60.01,130.13V125c0-0.06-0.02-0.09-0.06-0.09h-0.01c-0.04,0-0.08,0.03-0.12,0.09l-3.46,4.92
c-0.03,0.04-0.05,0.08-0.05,0.12c0,0.06,0.04,0.09,0.13,0.09H60.01z"/>
<path id="path5784" style="&st0;" d="M67,114.02c-8.64-4.67-19.44-1.46-24.11,7.18c-4.67,8.64-1.46,19.44,7.18,24.11
c8.64,4.67,19.44,1.46,24.11-7.18C78.86,129.49,75.64,118.7,67,114.02z"/>
<path id="path5788" style="&st4;" d="M67.29,145.16l-10.05-4.37"/>
<path id="path5792" style="&st4;" d="M67.29,145.16l-5.3,9.81"/>
</g>
<g id="M3">
<path id="path4141" style="&st2;" d="M132.42,105.51c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.04-0.15-0.09-0.18-0.13c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
s0.76,0.12,1.18,0.12c0.8,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.85,0.52-1.58v-0.31c0-0.29-0.06-0.57-0.16-0.85
c-0.11-0.28-0.3-0.51-0.56-0.7c-0.27-0.19-0.61-0.28-1.03-0.28h-2.72c-0.19,0-0.29-0.09-0.29-0.27v-0.52
c0-0.08,0.03-0.15,0.08-0.21c0.05-0.06,0.12-0.08,0.21-0.08h2.72c0.45,0,0.8-0.09,1.07-0.26c0.26-0.18,0.44-0.4,0.54-0.67
c0.1-0.27,0.15-0.56,0.15-0.85v-0.21c0-0.43-0.07-0.77-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.12-0.77-0.19-1.33-0.19
c-0.42,0-0.82,0.04-1.19,0.12c-0.38,0.08-0.85,0.19-1.41,0.34c-0.2,0.06-0.3-0.01-0.3-0.21v-0.51c0-0.09,0.02-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.17-0.11c0.33-0.14,0.75-0.27,1.25-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67
c0.61,0.44,0.91,1.2,0.91,2.26v0.21c0,0.26-0.03,0.5-0.09,0.73c-0.06,0.23-0.15,0.44-0.28,0.64s-0.27,0.39-0.46,0.55
c-0.18,0.17-0.38,0.3-0.61,0.42c0.49,0.24,0.85,0.56,1.08,0.99c0.23,0.42,0.35,0.88,0.35,1.37v0.32c0,1.09-0.31,1.89-0.95,2.42
C134.44,105.25,133.56,105.51,132.42,105.51L132.42,105.51z"/>
<path id="path5856" style="&st0;" d="M140.72,85.2c-8.64-4.67-19.44-1.46-24.11,7.18c-4.67,8.64-1.46,19.44,7.18,24.11
c8.64,4.67,19.44,1.46,24.11-7.18C152.58,100.67,149.37,89.87,140.72,85.2L140.72,85.2z"/>
<path id="path5860" style="&st4;" d="M141.01,116.33l-10.05-4.37"/>
<path id="path5864" style="&st4;" d="M141.01,116.33l-5.3,9.81"/>
</g>
<g id="M2">
<path id="path4135" style="&st2;" d="M105.06,23.31c0,0.4-0.07,0.76-0.2,1.07c-0.13,0.31-0.34,0.62-0.62,0.9
c-0.28,0.29-0.66,0.59-1.14,0.92l-1.44,0.97c-0.54,0.37-0.97,0.71-1.28,1.03c-0.31,0.32-0.53,0.65-0.65,0.99
c-0.12,0.34-0.18,0.73-0.18,1.17v0.31h5.05c0.2,0,0.3,0.08,0.3,0.26v0.66c0,0.09-0.03,0.15-0.09,0.2s-0.13,0.07-0.21,0.07h-5.95
c-0.08,0-0.15-0.03-0.21-0.08c-0.06-0.06-0.09-0.12-0.09-0.2v-1.22c0-0.52,0.08-1.02,0.24-1.48c0.16-0.47,0.41-0.9,0.75-1.31
c0.34-0.41,0.78-0.79,1.32-1.15l1.52-1.02c0.63-0.42,1.04-0.76,1.24-1.03c0.2-0.27,0.3-0.62,0.3-1.07c0-0.36-0.07-0.65-0.21-0.88
c-0.14-0.23-0.35-0.39-0.63-0.5c-0.28-0.11-0.63-0.16-1.05-0.16c-0.34,0-0.68,0.03-1.02,0.09c-0.34,0.06-0.69,0.14-1.03,0.23
c-0.34,0.1-0.62,0.18-0.85,0.24c-0.09,0.03-0.17,0.03-0.22-0.01s-0.08-0.1-0.08-0.19v-0.51c0-0.09,0.01-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.18-0.11c0.26-0.11,0.54-0.22,0.83-0.31c0.3-0.1,0.64-0.18,1.04-0.25c0.4-0.07,0.78-0.11,1.14-0.11
c0.51,0,0.96,0.06,1.37,0.18c0.41,0.12,0.74,0.28,1,0.5c0.26,0.21,0.46,0.49,0.6,0.83C104.99,22.46,105.06,22.85,105.06,23.31
L105.06,23.31z"/>
<path id="path5736" style="&st0;" d="M83.59,26.92c0,9.82,7.96,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.83-7.97-17.79-17.79-17.79C91.55,9.13,83.59,17.1,83.59,26.92L83.59,26.92z"/>
<path id="path5740" style="&st4;" d="M98.3,9.07l7.76,7.73"/>
<path id="path5744" style="&st4;" d="M98.3,9.07l8.51-7.2"/>
</g>
<g id="M1">
<path id="path4132" style="&st2;" d="M26.59,62.76c0,0.09-0.02,0.16-0.07,0.22c-0.05,0.06-0.12,0.08-0.2,0.08H25.5
c-0.08,0-0.15-0.03-0.2-0.09c-0.05-0.06-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04
c-0.09,0-0.13-0.06-0.13-0.17v-0.76c0-0.08,0.05-0.14,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.1,0.32-0.1h0.61
c0.08,0,0.15,0.02,0.2,0.08c0.06,0.05,0.08,0.12,0.08,0.21V62.76L26.59,62.76z"/>
<path id="path5832" style="&st0;" d="M35.48,72.67c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
c-8.29,5.27-10.74,16.27-5.46,24.56C16.19,75.5,27.19,77.95,35.48,72.67z"/>
<path id="path5836" style="&st4;" d="M12.52,69.84l2.36-10.7"/>
<path id="path5840" style="&st4;" d="M12.52,69.84L1.88,66.52"/>
</g>
<g id="FrontArrow">
<path id="path5690" style="&st3;" d="M80.46,89.9V77.53"/>
<path id="path5694" style="&st1;" d="M89.76,80.26l-9.35-16.19l-9.35,16.19H89.76z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:#231F20;">
<!ENTITY st3 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="quadp-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="114.93px"
height="124.07px" viewBox="4.37 2.5 114.93 124.07" xml:space="preserve">
<g id="M4">
<path id="path3908" style="&st2;" d="M64.72,23.41c0,0.08-0.03,0.15-0.08,0.19c-0.06,0.05-0.12,0.07-0.2,0.07h-1.3v2.67
c0,0.08-0.02,0.15-0.07,0.21c-0.05,0.06-0.11,0.09-0.19,0.09H62c-0.17,0-0.26-0.1-0.26-0.3v-2.67h-4.34
c-0.22,0-0.38-0.04-0.47-0.13c-0.09-0.09-0.14-0.24-0.14-0.45v-0.57c0-0.21,0.06-0.4,0.18-0.56l4.44-6.22
c0.1-0.16,0.25-0.24,0.44-0.24h0.88c0.26,0,0.4,0.11,0.4,0.33v6.71h1.3c0.08,0,0.15,0.03,0.21,0.07s0.08,0.12,0.08,0.2L64.72,23.41
L64.72,23.41z M61.76,22.54v-5.13c0-0.06-0.02-0.09-0.06-0.09h-0.02c-0.04,0-0.08,0.03-0.12,0.09l-3.46,4.92
c-0.03,0.04-0.05,0.08-0.05,0.13c0,0.06,0.04,0.09,0.13,0.09H61.76z"/>
<path id="path5342" style="&st0;" d="M79.68,22.37c0,9.82-7.96,17.79-17.79,17.79c-9.83,0-17.79-7.97-17.79-17.79
c0-9.83,7.96-17.79,17.79-17.79C71.72,4.58,79.68,12.55,79.68,22.37z"/>
<path id="path5346" style="&st4;" d="M55.51,5.24L44.63,4"/>
<path id="path5350" style="&st4;" d="M55.51,5.24L53.3,16.17"/>
</g>
<g id="M3">
<path id="path3906" style="&st2;" d="M26.56,70.49c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.04-0.15-0.08-0.18-0.12c-0.03-0.04-0.04-0.1-0.04-0.19V69.1c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
c0.36,0.08,0.75,0.12,1.17,0.12c0.81,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.86,0.52-1.58v-0.31c0-0.29-0.06-0.57-0.17-0.85
c-0.11-0.28-0.3-0.51-0.56-0.7c-0.27-0.19-0.61-0.28-1.03-0.28h-2.73c-0.19,0-0.29-0.09-0.29-0.27v-0.52
c0-0.08,0.03-0.15,0.08-0.21c0.05-0.05,0.12-0.08,0.2-0.08h2.73c0.45,0,0.8-0.09,1.06-0.26c0.26-0.18,0.44-0.4,0.54-0.67
c0.1-0.27,0.15-0.55,0.15-0.85v-0.21c0-0.42-0.07-0.76-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.13-0.77-0.19-1.33-0.19
c-0.42,0-0.82,0.04-1.19,0.12c-0.38,0.08-0.85,0.19-1.41,0.34c-0.2,0.06-0.3-0.01-0.3-0.21v-0.5c0-0.09,0.01-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.17-0.11c0.33-0.14,0.75-0.27,1.25-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67
c0.61,0.44,0.91,1.2,0.91,2.26v0.21c0,0.26-0.03,0.5-0.09,0.73s-0.15,0.44-0.27,0.65c-0.12,0.2-0.27,0.39-0.45,0.55
c-0.18,0.17-0.38,0.3-0.61,0.42c0.49,0.24,0.85,0.56,1.08,0.99c0.23,0.42,0.35,0.88,0.35,1.37v0.31c0,1.09-0.32,1.9-0.95,2.42
C28.58,70.22,27.7,70.49,26.56,70.49L26.56,70.49z"/>
<path id="path5354" style="&st0;" d="M44.27,64.99c0-9.82-7.96-17.79-17.79-17.79c-9.83,0-17.79,7.97-17.79,17.79
c0,9.83,7.96,17.79,17.79,17.79C36.31,82.78,44.27,74.82,44.27,64.99z"/>
<path id="path5358" style="&st4;" d="M17.02,80.06l-0.94-10.92"/>
<path id="path5362" style="&st4;" d="M17.02,80.06H5.87"/>
</g>
<g id="M1">
<path id="path3902" style="&st2;" d="M63.45,107.78c0,0.09-0.03,0.16-0.07,0.22c-0.05,0.06-0.12,0.08-0.2,0.08h-0.82
c-0.08,0-0.15-0.03-0.2-0.09c-0.05-0.06-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04
c-0.09,0-0.13-0.06-0.13-0.17v-0.76c0-0.08,0.05-0.14,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.1,0.32-0.1h0.61
c0.08,0,0.15,0.03,0.2,0.08c0.06,0.05,0.08,0.12,0.08,0.21L63.45,107.78L63.45,107.78z"/>
<path id="path5366" style="&st0;" d="M44.05,102.82c0-9.82,7.96-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C52.02,120.61,44.05,112.64,44.05,102.82z"/>
<path id="path5370" style="&st4;" d="M64.18,120.26l9.84,4.81"/>
<path id="path5374" style="&st4;" d="M64.18,120.26l5.73-9.56"/>
</g>
<g id="M2">
<path id="path3904" style="&st2;" d="M103.58,62.14c0,0.4-0.07,0.76-0.2,1.07c-0.13,0.31-0.34,0.61-0.62,0.9
c-0.28,0.29-0.66,0.59-1.14,0.92L100.19,66c-0.54,0.37-0.97,0.71-1.28,1.03c-0.31,0.32-0.53,0.65-0.65,0.99
c-0.12,0.34-0.18,0.73-0.18,1.17v0.32h5.05c0.2,0,0.3,0.09,0.3,0.26v0.66c0,0.09-0.03,0.15-0.09,0.2s-0.13,0.07-0.21,0.07h-5.95
c-0.08,0-0.15-0.03-0.21-0.08c-0.06-0.06-0.09-0.12-0.09-0.2V69.2c0-0.52,0.08-1.02,0.24-1.48c0.16-0.47,0.41-0.9,0.75-1.31
c0.34-0.41,0.78-0.79,1.32-1.15l1.52-1.02c0.63-0.42,1.04-0.76,1.24-1.03c0.2-0.26,0.3-0.62,0.3-1.06c0-0.36-0.07-0.66-0.21-0.88
c-0.14-0.23-0.35-0.39-0.63-0.5c-0.28-0.11-0.63-0.16-1.05-0.16c-0.34,0-0.68,0.03-1.02,0.09c-0.34,0.06-0.69,0.14-1.03,0.24
c-0.34,0.09-0.62,0.17-0.85,0.24c-0.09,0.03-0.17,0.03-0.22-0.01c-0.05-0.04-0.08-0.1-0.08-0.19v-0.51c0-0.09,0.02-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.18-0.11c0.26-0.11,0.54-0.22,0.83-0.32c0.3-0.1,0.64-0.18,1.04-0.25c0.4-0.07,0.78-0.11,1.14-0.11
c0.51,0,0.97,0.06,1.37,0.18c0.41,0.12,0.74,0.28,1,0.5s0.46,0.49,0.6,0.83C103.51,61.29,103.58,61.68,103.58,62.14L103.58,62.14z"
/>
<path id="path5378" style="&st0;" d="M82.23,65.6c0,9.83,7.97,17.79,17.79,17.79c9.83,0,17.79-7.96,17.79-17.79
c0-9.82-7.97-17.79-17.79-17.79C90.19,47.81,82.23,55.78,82.23,65.6z"/>
<path id="path5382" style="&st4;" d="M96.94,47.75l7.76,7.73"/>
<path id="path5386" style="&st4;" d="M96.94,47.75l8.52-7.2"/>
</g>
<g id="FrontArrow">
<path id="path5112" style="&st3;" d="M61.89,74.11V61.73"/>
<path id="path5116" style="&st1;" d="M71.19,64.46l-9.35-16.19l-9.35,16.19H71.19z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:#231F20;">
<!ENTITY st3 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="quadx-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="89.13px" height="96.6px"
viewBox="0 0 89.13 96.6" xml:space="preserve">
<g id="FrontArrow">
<path id="path5094" style="&st3;" d="M46.54,60.76V48.38"/>
<path id="path5098" style="&st1;" d="M55.84,51.12l-9.35-16.19l-9.35,16.19H55.84z"/>
</g>
<g id="M3">
<path id="path3488" style="&st2;" d="M22.69,77.97c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.04-0.15-0.08-0.18-0.12c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
c0.36,0.08,0.76,0.12,1.18,0.12c0.81,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.86,0.52-1.58v-0.31c0-0.29-0.06-0.57-0.17-0.85
c-0.11-0.28-0.3-0.51-0.56-0.7c-0.27-0.18-0.61-0.28-1.03-0.28h-2.72c-0.19,0-0.29-0.09-0.29-0.27v-0.52
c0-0.08,0.03-0.15,0.08-0.21s0.12-0.08,0.21-0.08h2.73c0.45,0,0.8-0.09,1.06-0.26c0.26-0.18,0.44-0.4,0.54-0.67
c0.1-0.27,0.15-0.55,0.15-0.85v-0.21c0-0.43-0.07-0.77-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.13-0.77-0.19-1.33-0.19
c-0.42,0-0.82,0.04-1.19,0.12c-0.38,0.08-0.85,0.19-1.41,0.34c-0.2,0.06-0.3-0.01-0.3-0.21v-0.51c0-0.09,0.02-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.17-0.11c0.33-0.14,0.75-0.27,1.25-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67
c0.61,0.45,0.91,1.2,0.91,2.26v0.21c0,0.26-0.03,0.5-0.09,0.73c-0.06,0.23-0.15,0.44-0.27,0.64c-0.12,0.2-0.27,0.39-0.45,0.55
c-0.18,0.17-0.38,0.31-0.61,0.42c0.49,0.24,0.85,0.56,1.08,0.98c0.23,0.42,0.35,0.88,0.35,1.37v0.31c0,1.09-0.32,1.9-0.95,2.42
C24.71,77.71,23.83,77.97,22.69,77.97L22.69,77.97z"/>
<path id="path5294" style="&st0;" d="M40.27,72.47c0-9.82-7.96-17.79-17.79-17.79c-9.83,0-17.79,7.97-17.79,17.79
c0,9.83,7.96,17.79,17.79,17.79C32.31,90.26,40.27,82.3,40.27,72.47z"/>
<path id="path5298" style="&st4;" d="M13.02,87.54l-0.94-10.92"/>
<path id="path5302" style="&st4;" d="M13.02,87.54H1.87"/>
</g>
<g id="M2">
<path id="path3486" style="&st2;" d="M73.02,22.94c0,0.4-0.07,0.76-0.2,1.07c-0.13,0.31-0.34,0.61-0.62,0.9
c-0.28,0.29-0.66,0.59-1.14,0.92l-1.44,0.97c-0.54,0.37-0.97,0.71-1.28,1.03c-0.31,0.32-0.52,0.65-0.64,0.99
c-0.12,0.34-0.18,0.73-0.18,1.17v0.32h5.05c0.2,0,0.3,0.09,0.3,0.26v0.66c0,0.09-0.03,0.16-0.09,0.2
c-0.06,0.05-0.13,0.07-0.21,0.07h-5.96c-0.08,0-0.15-0.03-0.21-0.08c-0.06-0.06-0.09-0.12-0.09-0.2v-1.22
c0-0.52,0.08-1.02,0.24-1.48c0.16-0.47,0.41-0.9,0.75-1.31s0.78-0.79,1.32-1.15l1.51-1.02c0.63-0.42,1.04-0.76,1.24-1.03
c0.2-0.27,0.3-0.62,0.3-1.06c0-0.36-0.07-0.66-0.21-0.88c-0.14-0.23-0.35-0.39-0.63-0.5c-0.28-0.11-0.63-0.16-1.06-0.16
c-0.34,0-0.68,0.03-1.02,0.09c-0.35,0.06-0.69,0.14-1.03,0.24c-0.34,0.09-0.62,0.17-0.85,0.24c-0.09,0.03-0.17,0.03-0.22-0.01
c-0.05-0.04-0.08-0.1-0.08-0.19v-0.51c0-0.09,0.02-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.18-0.11c0.26-0.11,0.54-0.22,0.84-0.32
c0.3-0.1,0.64-0.18,1.04-0.25c0.4-0.07,0.78-0.11,1.14-0.11c0.51,0,0.96,0.06,1.37,0.18c0.41,0.12,0.74,0.28,1,0.5
c0.26,0.21,0.46,0.49,0.6,0.83C72.95,22.1,73.02,22.49,73.02,22.94L73.02,22.94z"/>
<path id="path5306" style="&st0;" d="M51.67,26.92c0,9.82,7.96,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79C59.64,9.13,51.67,17.1,51.67,26.92z"/>
<path id="path5310" style="&st4;" d="M66.39,9.07l7.76,7.74"/>
<path id="path5314" style="&st4;" d="M66.39,9.07l8.51-7.19"/>
</g>
<g id="M4">
<path id="path3490" style="&st2;" d="M25.3,28.27c0,0.08-0.03,0.15-0.08,0.19c-0.06,0.05-0.12,0.07-0.2,0.07h-1.3v2.67
c0,0.08-0.02,0.15-0.07,0.21c-0.05,0.06-0.11,0.09-0.19,0.09h-0.87c-0.17,0-0.26-0.1-0.26-0.3v-2.67h-4.34
c-0.22,0-0.38-0.04-0.47-0.13c-0.09-0.09-0.14-0.24-0.14-0.45v-0.57c0-0.21,0.06-0.4,0.18-0.56L22,20.6
c0.1-0.16,0.25-0.24,0.44-0.24h0.88c0.26,0,0.4,0.11,0.4,0.33v6.71h1.3c0.08,0,0.15,0.02,0.21,0.07c0.05,0.05,0.08,0.11,0.08,0.2
L25.3,28.27L25.3,28.27z M22.34,27.39v-5.13c0-0.06-0.02-0.09-0.06-0.09h-0.02c-0.04,0-0.08,0.03-0.12,0.09l-3.46,4.92
c-0.03,0.04-0.05,0.08-0.05,0.12c0,0.06,0.04,0.09,0.13,0.09H22.34z"/>
<path id="path5318" style="&st0;" d="M40.27,26.92c0,9.82-7.96,17.79-17.79,17.79c-9.83,0-17.79-7.97-17.79-17.79
c0-9.83,7.96-17.79,17.79-17.79C32.31,9.13,40.27,17.1,40.27,26.92z"/>
<path id="path5322" style="&st4;" d="M16.1,9.8L5.21,8.55"/>
<path id="path5326" style="&st4;" d="M16.1,9.8l-2.21,10.93"/>
</g>
<g id="M1">
<path id="path3484" style="&st2;" d="M71.06,77.57c0,0.09-0.03,0.16-0.07,0.22s-0.11,0.08-0.2,0.08h-0.82
c-0.08,0-0.15-0.03-0.2-0.09c-0.05-0.06-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04
c-0.09,0-0.13-0.06-0.13-0.17v-0.76c0-0.08,0.05-0.14,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.09,0.32-0.09h0.62
c0.08,0,0.15,0.03,0.2,0.08c0.06,0.05,0.08,0.12,0.08,0.21V77.57L71.06,77.57z"/>
<path id="path5330" style="&st0;" d="M51.67,72.47c0-9.82,7.96-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C59.64,90.26,51.67,82.3,51.67,72.47z"/>
<path id="path5334" style="&st4;" d="M71.8,89.91l9.85,4.81"/>
<path id="path5338" style="&st4;" d="M71.8,89.91l5.73-9.56"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:none;stroke:#BF1B2C;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st3 "fill:#231F20;">
<!ENTITY st4 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st5 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="tri-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="116.97px"
height="110.58px" viewBox="0.37 0.38 116.97 110.58" xml:space="preserve">
<g id="S1">
<path id="path5276" style="&st2;" d="M111.94,102.17H86.67V76.9h25.27V102.17z"/>
<path id="path3952" style="&st3;" d="M99.14,91.95c0,0.84-0.27,1.56-0.82,2.13c-0.55,0.58-1.47,0.86-2.76,0.86
c-0.48,0-0.99-0.06-1.52-0.18c-0.54-0.12-0.98-0.27-1.33-0.43c-0.13-0.06-0.21-0.12-0.24-0.16c-0.03-0.04-0.05-0.13-0.05-0.24
v-0.62c0-0.19,0.1-0.25,0.3-0.18c0.44,0.15,0.92,0.28,1.44,0.39s1,0.17,1.43,0.17c0.51,0,0.92-0.07,1.24-0.21
c0.32-0.14,0.54-0.34,0.68-0.6c0.13-0.26,0.2-0.57,0.2-0.94c0-0.38-0.12-0.7-0.37-0.97c-0.24-0.27-0.72-0.62-1.42-1.04l-1.45-0.89
c-0.72-0.44-1.25-0.87-1.58-1.3c-0.33-0.43-0.5-0.93-0.5-1.51c0-0.58,0.14-1.07,0.4-1.47c0.27-0.4,0.65-0.7,1.15-0.89
c0.5-0.19,1.09-0.29,1.76-0.29c0.53,0,1.05,0.06,1.56,0.18c0.51,0.12,0.89,0.24,1.15,0.36c0.08,0.03,0.14,0.06,0.19,0.1
c0.05,0.04,0.07,0.09,0.07,0.17v0.76c0,0.18-0.1,0.24-0.29,0.18c-0.35-0.11-0.66-0.21-0.93-0.28c-0.27-0.07-0.56-0.13-0.86-0.18
c-0.3-0.05-0.6-0.07-0.89-0.07c-0.67,0-1.17,0.11-1.48,0.32c-0.31,0.21-0.46,0.58-0.46,1.1c0,0.34,0.12,0.64,0.36,0.89
c0.24,0.25,0.67,0.56,1.28,0.93l1.38,0.83c0.86,0.5,1.46,0.99,1.81,1.45C98.97,90.81,99.14,91.35,99.14,91.95L99.14,91.95z"/>
<path id="path3954" style="&st3;" d="M105.13,94.54c0,0.09-0.03,0.16-0.07,0.22c-0.05,0.06-0.11,0.08-0.2,0.08h-0.82
c-0.08,0-0.15-0.03-0.2-0.09s-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04c-0.09,0-0.13-0.06-0.13-0.17
v-0.76c0-0.08,0.05-0.14,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.1,0.32-0.1h0.62c0.08,0,0.14,0.03,0.2,0.08
c0.06,0.05,0.08,0.12,0.08,0.21L105.13,94.54L105.13,94.54z"/>
</g>
<g id="M3">
<path id="path3933" style="&st3;" d="M22.78,32.15c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.39
c-0.09-0.04-0.15-0.08-0.18-0.12c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
c0.36,0.08,0.76,0.12,1.18,0.12c0.81,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.85,0.52-1.58v-0.31c0-0.29-0.05-0.57-0.17-0.85
c-0.11-0.28-0.3-0.51-0.56-0.7c-0.27-0.19-0.61-0.28-1.03-0.28h-2.72c-0.19,0-0.29-0.09-0.29-0.27v-0.52
c0-0.08,0.03-0.15,0.08-0.21s0.12-0.08,0.21-0.08h2.72c0.45,0,0.81-0.09,1.07-0.26c0.26-0.18,0.44-0.4,0.54-0.67
c0.1-0.27,0.15-0.56,0.15-0.85v-0.21c0-0.42-0.07-0.77-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.12-0.77-0.19-1.33-0.19
c-0.42,0-0.82,0.04-1.19,0.12s-0.85,0.19-1.41,0.34c-0.2,0.06-0.3-0.01-0.3-0.21v-0.51c0-0.09,0.02-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.17-0.11c0.33-0.14,0.75-0.27,1.25-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67
c0.61,0.44,0.91,1.2,0.91,2.26v0.21c0,0.26-0.03,0.5-0.09,0.73c-0.06,0.23-0.15,0.44-0.28,0.65c-0.12,0.2-0.27,0.39-0.45,0.55
c-0.18,0.17-0.38,0.31-0.61,0.42c0.49,0.23,0.85,0.56,1.08,0.98c0.23,0.42,0.35,0.88,0.35,1.36v0.31c0,1.09-0.32,1.9-0.95,2.42
C24.81,31.89,23.92,32.15,22.78,32.15L22.78,32.15z"/>
<path id="path5390" style="&st0;" d="M40.27,27.02c0-9.82-7.96-17.79-17.79-17.79c-9.83,0-17.79,7.97-17.79,17.79
c0,9.83,7.96,17.79,17.79,17.79C32.31,44.81,40.27,36.85,40.27,27.02z"/>
<path id="path5394" style="&st5;" d="M13.02,42.09l-0.94-10.92"/>
<path id="path5398" style="&st5;" d="M13.02,42.09H1.87"/>
</g>
<g id="M2">
<path id="path3937" style="&st3;" d="M102.05,24.19c0,0.4-0.07,0.76-0.2,1.07s-0.34,0.62-0.62,0.9c-0.28,0.29-0.66,0.59-1.14,0.92
l-1.44,0.97c-0.54,0.37-0.97,0.71-1.28,1.03c-0.31,0.32-0.53,0.65-0.64,0.99c-0.12,0.34-0.18,0.73-0.18,1.17v0.31h5.05
c0.2,0,0.3,0.08,0.3,0.26v0.66c0,0.09-0.03,0.16-0.09,0.2c-0.06,0.05-0.13,0.07-0.21,0.07h-5.95c-0.08,0-0.15-0.03-0.21-0.08
c-0.06-0.06-0.09-0.12-0.09-0.2v-1.22c0-0.52,0.08-1.02,0.24-1.48c0.16-0.47,0.41-0.9,0.75-1.31c0.34-0.41,0.78-0.79,1.31-1.15
l1.52-1.02c0.63-0.42,1.04-0.76,1.24-1.03s0.3-0.62,0.3-1.07c0-0.36-0.07-0.65-0.21-0.88c-0.14-0.23-0.35-0.4-0.63-0.5
c-0.28-0.11-0.63-0.16-1.05-0.16c-0.34,0-0.68,0.03-1.02,0.09c-0.34,0.06-0.68,0.14-1.03,0.23c-0.34,0.1-0.62,0.17-0.85,0.24
c-0.09,0.03-0.17,0.02-0.22-0.02c-0.05-0.04-0.08-0.1-0.08-0.19v-0.51c0-0.09,0.01-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.18-0.11
c0.26-0.11,0.54-0.22,0.83-0.31c0.3-0.1,0.65-0.18,1.04-0.25c0.4-0.07,0.78-0.11,1.14-0.11c0.51,0,0.96,0.06,1.37,0.18
s0.74,0.28,1,0.5s0.46,0.49,0.6,0.83C101.98,23.34,102.05,23.74,102.05,24.19L102.05,24.19z"/>
<path id="path5402" style="&st0;" d="M80.27,26.92c0,9.83,7.96,17.79,17.79,17.79c9.83,0,17.79-7.96,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79C88.23,9.13,80.27,17.1,80.27,26.92z"/>
<path id="path5406" style="&st5;" d="M94.98,9.07l7.76,7.73"/>
<path id="path5410" style="&st5;" d="M94.98,9.07l8.52-7.19"/>
</g>
<g id="M1">
<path id="path3935" style="&st3;" d="M61.53,96.19c0,0.09-0.03,0.16-0.07,0.22c-0.05,0.06-0.11,0.08-0.2,0.08h-0.82
c-0.08,0-0.15-0.03-0.2-0.09c-0.05-0.06-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04
c-0.09,0-0.13-0.05-0.13-0.17v-0.76c0-0.08,0.05-0.15,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.1,0.32-0.1h0.62
c0.08,0,0.14,0.03,0.2,0.08c0.06,0.05,0.08,0.12,0.08,0.21L61.53,96.19L61.53,96.19z"/>
<path id="path5414" style="&st0;" d="M77.61,91.66c0-9.82-7.97-17.79-17.79-17.79c-9.83,0-17.79,7.97-17.79,17.79
c0,9.83,7.97,17.79,17.79,17.79C69.65,109.45,77.61,101.49,77.61,91.66z"/>
<path id="path5418" style="&st5;" d="M50.36,106.73l-0.94-10.92"/>
<path id="path5422" style="&st5;" d="M50.36,106.73H39.22"/>
</g>
<g id="FrontArrow">
<path id="path5270" style="&st4;" d="M62.02,60.69V48.31"/>
<path id="path5274" style="&st1;" d="M71.32,51.05l-9.35-16.19l-9.35,16.19H71.32z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:#231F20;">
<!ENTITY st3 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="Vtail-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="90.56px" height="85.29px"
viewBox="0.69 6.47 90.56 85.29" xml:space="preserve">
<g id="M4">
<path id="path3490" style="&st2;" d="M22.8,28.27c0,0.08-0.03,0.15-0.09,0.19c-0.06,0.05-0.12,0.07-0.2,0.07h-1.3v2.67
c0,0.08-0.02,0.15-0.07,0.21c-0.05,0.06-0.11,0.09-0.19,0.09h-0.87c-0.17,0-0.26-0.1-0.26-0.3v-2.67h-4.34
c-0.22,0-0.38-0.05-0.47-0.13c-0.1-0.09-0.14-0.23-0.14-0.44v-0.57c0-0.21,0.06-0.4,0.18-0.56l4.44-6.23
c0.1-0.16,0.25-0.24,0.44-0.24h0.88c0.26,0,0.39,0.11,0.39,0.33v6.71h1.3c0.08,0,0.15,0.02,0.21,0.07c0.05,0.05,0.08,0.11,0.08,0.2
V28.27L22.8,28.27L22.8,28.27z M19.84,27.4v-5.13c0-0.06-0.02-0.09-0.06-0.09h-0.01c-0.04,0-0.08,0.03-0.12,0.09l-3.46,4.92
c-0.03,0.04-0.05,0.08-0.05,0.12c0,0.06,0.04,0.09,0.13,0.09H19.84z"/>
<path id="path5318" style="&st0;" d="M37.77,26.92c0,9.82-7.96,17.79-17.79,17.79c-9.83,0-17.79-7.97-17.79-17.79
c0-9.82,7.96-17.79,17.79-17.79C29.81,9.13,37.77,17.1,37.77,26.92z"/>
<path id="path5322" style="&st4;" d="M13.6,9.79L2.71,8.55"/>
<path id="path5326" style="&st4;" d="M13.6,9.79l-2.21,10.93"/>
</g>
<g id="M3_1_">
<path id="path5330" style="&st0;" d="M41.67,72.47c0-9.82,7.97-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C49.64,90.26,41.67,82.3,41.67,72.47z"/>
<path id="path5334" style="&st4;" d="M69.01,87.25l10.96,0.15"/>
<path id="path5338" style="&st4;" d="M69.01,87.25l1.11-11.09"/>
<path id="path3488" style="&st2;" d="M59.35,77.97c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.05-0.15-0.09-0.18-0.12c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
c0.36,0.08,0.76,0.12,1.18,0.12c0.81,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.85,0.52-1.58v-0.31c0-0.29-0.06-0.57-0.17-0.85
c-0.11-0.28-0.3-0.52-0.56-0.7c-0.27-0.19-0.61-0.28-1.03-0.28h-2.73c-0.19,0-0.29-0.09-0.29-0.27v-0.52c0-0.08,0.03-0.15,0.08-0.2
c0.05-0.06,0.12-0.08,0.21-0.08h2.73c0.45,0,0.81-0.09,1.07-0.26c0.26-0.18,0.44-0.4,0.54-0.67c0.1-0.27,0.15-0.56,0.15-0.85v-0.21
c0-0.43-0.07-0.77-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.13-0.77-0.19-1.33-0.19c-0.42,0-0.82,0.04-1.19,0.12
s-0.85,0.19-1.41,0.35c-0.2,0.06-0.3-0.01-0.3-0.21V67.5c0-0.09,0.01-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.17-0.11
c0.33-0.14,0.75-0.27,1.24-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67c0.61,0.44,0.91,1.19,0.91,2.26v0.21
c0,0.26-0.03,0.5-0.09,0.73c-0.06,0.23-0.15,0.44-0.27,0.65c-0.12,0.2-0.27,0.39-0.46,0.55c-0.18,0.17-0.38,0.31-0.61,0.42
c0.49,0.23,0.85,0.56,1.08,0.98c0.23,0.42,0.35,0.88,0.35,1.37v0.31c0,1.09-0.32,1.9-0.95,2.42
C61.37,77.71,60.48,77.97,59.35,77.97L59.35,77.97z"/>
</g>
<g id="M2">
<path id="path3486" style="&st2;" d="M75.52,22.94c0,0.4-0.06,0.76-0.2,1.07c-0.13,0.31-0.34,0.61-0.62,0.9
c-0.28,0.29-0.66,0.59-1.14,0.92l-1.44,0.97c-0.54,0.37-0.97,0.71-1.28,1.03c-0.31,0.32-0.52,0.65-0.65,0.99s-0.18,0.73-0.18,1.17
v0.31h5.05c0.2,0,0.3,0.09,0.3,0.26v0.66c0,0.09-0.03,0.16-0.09,0.2c-0.06,0.05-0.13,0.07-0.21,0.07h-5.96
c-0.08,0-0.15-0.03-0.21-0.08c-0.06-0.06-0.09-0.12-0.09-0.2V30c0-0.52,0.08-1.02,0.24-1.48c0.16-0.47,0.41-0.9,0.75-1.31
c0.34-0.41,0.78-0.79,1.31-1.15l1.52-1.02c0.63-0.42,1.04-0.77,1.24-1.03c0.2-0.27,0.3-0.62,0.3-1.06c0-0.36-0.07-0.66-0.21-0.88
c-0.14-0.23-0.35-0.4-0.63-0.5c-0.28-0.1-0.63-0.16-1.06-0.16c-0.34,0-0.68,0.03-1.02,0.09c-0.35,0.06-0.69,0.14-1.02,0.23
c-0.34,0.1-0.62,0.17-0.85,0.24c-0.1,0.03-0.17,0.03-0.22-0.01c-0.05-0.04-0.08-0.1-0.08-0.19v-0.51c0-0.09,0.02-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.18-0.11c0.26-0.11,0.54-0.22,0.84-0.31c0.3-0.1,0.65-0.18,1.04-0.25c0.4-0.07,0.78-0.11,1.14-0.11
c0.51,0,0.97,0.06,1.37,0.18c0.41,0.12,0.74,0.28,1,0.5c0.26,0.21,0.46,0.49,0.6,0.83C75.45,22.1,75.52,22.49,75.52,22.94
L75.52,22.94z"/>
<path id="path5306" style="&st0;" d="M54.17,26.92c0,9.82,7.97,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79C62.14,9.13,54.17,17.1,54.17,26.92z"/>
<path id="path5310" style="&st4;" d="M78.24,9.93l2.84,10.58"/>
<path id="path5314" style="&st4;" d="M78.24,9.93l10.97-1.96"/>
</g>
<g id="M1">
<path id="path3484" style="&st2;" d="M34.29,77.57c0,0.09-0.02,0.16-0.07,0.22c-0.05,0.06-0.11,0.08-0.2,0.08H33.2
c-0.08,0-0.15-0.03-0.2-0.09c-0.05-0.06-0.07-0.13-0.07-0.21v-9.43l-1.94,0.84c-0.08,0.03-0.14,0.04-0.2,0.04
c-0.09,0-0.13-0.06-0.13-0.17v-0.76c0-0.08,0.05-0.14,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.09,0.32-0.09H34
c0.08,0,0.15,0.02,0.2,0.08s0.08,0.12,0.08,0.21L34.29,77.57L34.29,77.57L34.29,77.57z"/>
<path id="path5294" style="&st0;" d="M50.27,72.47c0-9.82-7.96-17.79-17.79-17.79s-17.79,7.97-17.79,17.79
c0,9.83,7.96,17.79,17.79,17.79S50.27,82.3,50.27,72.47z"/>
<path id="path5298" style="&st4;" d="M23.02,87.54l-0.94-10.92"/>
<path id="path5302" style="&st4;" d="M23.02,87.54H11.87"/>
</g>
<g id="FrontArrow">
<path id="path5094" style="&st3;" d="M46.02,53.94V41.56"/>
<path id="path5098" style="&st1;" d="M55.32,44.3l-9.35-16.19L36.62,44.3H55.32z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:#231F20;">
<!ENTITY st3 "fill:none;stroke:#293D9B;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st5 "fill:none;stroke:#293D9B;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st6 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="Y4-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="112.83px"
height="138.5px" viewBox="0.37 0.37 112.83 138.5" xml:space="preserve">
<g id="M4">
<path id="path3443" style="&st2;" d="M23.81,26.9c0,0.08-0.03,0.15-0.09,0.19c-0.06,0.05-0.12,0.07-0.2,0.07h-1.3v2.67
c0,0.08-0.02,0.15-0.07,0.21c-0.05,0.06-0.11,0.09-0.19,0.09h-0.87c-0.17,0-0.26-0.1-0.26-0.3v-2.67H16.5
c-0.22,0-0.38-0.04-0.47-0.13c-0.09-0.09-0.14-0.24-0.14-0.45v-0.57c0-0.21,0.06-0.4,0.18-0.56l4.44-6.23
c0.1-0.16,0.25-0.24,0.44-0.24h0.88c0.26,0,0.4,0.11,0.4,0.33v6.71h1.3c0.08,0,0.15,0.03,0.21,0.07c0.05,0.05,0.08,0.12,0.08,0.2
L23.81,26.9L23.81,26.9z M20.85,26.02v-5.13c0-0.06-0.02-0.09-0.06-0.09h-0.02c-0.04,0-0.08,0.03-0.12,0.09l-3.46,4.92
c-0.03,0.04-0.05,0.08-0.05,0.13c0,0.06,0.04,0.09,0.13,0.09L20.85,26.02L20.85,26.02z"/>
<path id="path5570" style="&st0;" d="M37.46,24.48c0,9.83-7.96,17.79-17.79,17.79c-9.83,0-17.79-7.96-17.79-17.79
c0-9.82,7.96-17.79,17.79-17.79S37.46,14.65,37.46,24.48z"/>
<path id="path5574" style="&st6;" d="M13.28,7.35L2.4,6.11"/>
<path id="path5578" style="&st6;" d="M13.28,7.35l-2.21,10.92"/>
</g>
<g id="M2">
<path id="path3986" style="&st2;" d="M96.8,23.47c0,0.4-0.07,0.76-0.2,1.07c-0.13,0.31-0.34,0.61-0.62,0.9
c-0.28,0.29-0.66,0.59-1.14,0.92l-1.43,0.97c-0.54,0.37-0.97,0.71-1.28,1.03c-0.31,0.32-0.52,0.65-0.65,0.99
c-0.12,0.34-0.18,0.73-0.18,1.17v0.31h5.05c0.2,0,0.3,0.08,0.3,0.26v0.66c0,0.09-0.03,0.15-0.09,0.2
c-0.06,0.05-0.13,0.07-0.21,0.07h-5.95c-0.08,0-0.15-0.03-0.21-0.09c-0.06-0.06-0.09-0.12-0.09-0.2v-1.22
c0-0.52,0.08-1.02,0.24-1.48c0.16-0.47,0.41-0.9,0.75-1.31c0.34-0.41,0.78-0.79,1.32-1.15l1.52-1.03c0.63-0.42,1.04-0.76,1.24-1.03
c0.2-0.27,0.3-0.62,0.3-1.07c0-0.36-0.07-0.66-0.21-0.88c-0.14-0.23-0.35-0.39-0.63-0.5c-0.28-0.11-0.63-0.16-1.05-0.16
c-0.34,0-0.68,0.03-1.02,0.09c-0.34,0.06-0.69,0.14-1.02,0.23c-0.34,0.1-0.62,0.18-0.85,0.24c-0.09,0.03-0.17,0.03-0.22-0.02
c-0.05-0.04-0.08-0.1-0.08-0.19v-0.51c0-0.09,0.02-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.18-0.11c0.26-0.11,0.54-0.22,0.84-0.31
c0.3-0.1,0.64-0.18,1.04-0.25c0.4-0.07,0.78-0.11,1.14-0.11c0.51,0,0.97,0.06,1.37,0.18c0.41,0.12,0.74,0.28,1,0.5
c0.26,0.21,0.46,0.49,0.6,0.83C96.73,22.62,96.8,23.02,96.8,23.47L96.8,23.47z"/>
<path id="path5582" style="&st0;" d="M76.12,26.92c0,9.83,7.97,17.79,17.79,17.79c9.83,0,17.79-7.96,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79C84.09,9.13,76.12,17.1,76.12,26.92z"/>
<path id="path5586" style="&st6;" d="M90.84,9.07l7.76,7.73"/>
<path id="path5590" style="&st6;" d="M90.84,9.07l8.52-7.2"/>
</g>
<g id="M3">
<path id="path3988" style="&st2;" d="M56.32,124.64c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.04-0.15-0.08-0.18-0.12s-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
s0.76,0.12,1.18,0.12c0.81,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.86,0.52-1.58v-0.32c0-0.29-0.05-0.57-0.17-0.85
c-0.11-0.28-0.3-0.51-0.56-0.7c-0.27-0.18-0.61-0.28-1.03-0.28h-2.73c-0.19,0-0.29-0.09-0.29-0.27v-0.52
c0-0.08,0.03-0.15,0.08-0.21s0.12-0.08,0.21-0.08h2.73c0.45,0,0.8-0.09,1.07-0.26c0.26-0.18,0.44-0.4,0.54-0.67
c0.1-0.27,0.15-0.56,0.15-0.85v-0.21c0-0.42-0.07-0.77-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.12-0.77-0.18-1.33-0.18
c-0.42,0-0.82,0.04-1.19,0.12c-0.38,0.08-0.85,0.19-1.41,0.34c-0.2,0.06-0.3-0.01-0.3-0.21v-0.5c0-0.09,0.02-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.17-0.11c0.33-0.14,0.75-0.27,1.25-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67
c0.61,0.44,0.91,1.2,0.91,2.26v0.21c0,0.26-0.03,0.5-0.09,0.73c-0.06,0.23-0.15,0.44-0.27,0.64c-0.12,0.2-0.27,0.39-0.46,0.55
c-0.18,0.17-0.38,0.31-0.61,0.42c0.49,0.23,0.85,0.56,1.08,0.98s0.35,0.88,0.35,1.37v0.32c0,1.09-0.32,1.9-0.95,2.42
C58.34,124.38,57.45,124.64,56.32,124.64L56.32,124.64z"/>
<path id="path5594" style="&st5;" d="M65.91,134.59c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
c-8.29,5.27-10.74,16.27-5.46,24.56C46.63,137.42,57.62,139.86,65.91,134.59z"/>
<path id="path5598" style="&st3;" d="M42.95,131.75l2.36-10.7"/>
<path id="path5602" style="&st3;" d="M42.95,131.75l-10.64-3.32"/>
</g>
<g id="M1">
<path id="path3441" style="&st2;" d="M58.95,94.78c0,0.09-0.02,0.16-0.07,0.22c-0.05,0.06-0.12,0.08-0.2,0.08h-0.82
c-0.08,0-0.15-0.03-0.2-0.09s-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04c-0.09,0-0.13-0.05-0.13-0.17
v-0.76c0-0.08,0.05-0.14,0.15-0.2l2.26-1.08c0.12-0.07,0.23-0.1,0.31-0.1h0.62c0.08,0,0.14,0.03,0.2,0.08
c0.06,0.05,0.08,0.12,0.08,0.21V94.78z"/>
<path id="path5678" style="&st0;" d="M49.85,105.15c-8.74-4.49-12.18-15.22-7.68-23.96c4.49-8.74,15.22-12.18,23.96-7.68
C74.87,78,78.3,88.73,73.81,97.46C69.32,106.2,58.59,109.64,49.85,105.15z"/>
<path id="path5682" style="&st6;" d="M76.14,91.49l6.08-9.11"/>
<path id="path5686" style="&st6;" d="M76.14,91.49l-8.71-6.96"/>
</g>
<g id="FrontArrow">
<path id="path5198" style="&st4;" d="M57.65,61.14V48.76"/>
<path id="path5202" style="&st1;" d="M66.95,51.5L57.6,35.3L48.25,51.5H66.95z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -1,104 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:#231F20;">
<!ENTITY st3 "fill:none;stroke:#293D9B;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#ED1C24;stroke-width:5;stroke-miterlimit:10;">
<!ENTITY st5 "fill:none;stroke:#293D9B;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st6 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="Y6-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="157.69px"
height="156.34px" viewBox="0.37 0.37 157.69 156.34" xml:space="preserve">
<g id="M4">
<path id="path4060" style="&st2;" d="M81.51,138.66c0,0.08-0.03,0.15-0.08,0.2c-0.06,0.05-0.12,0.07-0.2,0.07h-1.3v2.67
c0,0.08-0.02,0.15-0.07,0.21c-0.05,0.06-0.11,0.09-0.19,0.09H78.8c-0.17,0-0.26-0.1-0.26-0.3v-2.67H74.2
c-0.22,0-0.38-0.04-0.47-0.13c-0.09-0.09-0.14-0.24-0.14-0.45v-0.57c0-0.21,0.06-0.39,0.18-0.56l4.44-6.23
c0.1-0.16,0.25-0.24,0.44-0.24h0.88c0.26,0,0.4,0.11,0.4,0.33v6.71h1.3c0.08,0,0.15,0.03,0.21,0.07s0.08,0.11,0.08,0.2
L81.51,138.66L81.51,138.66z M78.55,137.79v-5.13c0-0.06-0.02-0.09-0.06-0.09h-0.01c-0.04,0-0.08,0.03-0.12,0.09l-3.46,4.92
c-0.03,0.04-0.05,0.08-0.05,0.13c0,0.06,0.04,0.09,0.13,0.09H78.55z"/>
<path id="path5606" style="&st5;" d="M92,126.47c6.05,7.74,4.68,18.92-3.06,24.97c-7.74,6.05-18.92,4.68-24.97-3.06
c-6.05-7.74-4.68-18.92,3.06-24.97C74.77,117.36,85.95,118.73,92,126.47z"/>
<path id="path5610" style="&st3;" d="M62.41,127.87l-9.34,5.72"/>
<path id="path5614" style="&st3;" d="M62.41,127.87l4.99,9.97"/>
</g>
<g id="M6">
<path id="path4064" style="&st2;" d="M28.21,28.06v-0.09c0-0.51-0.11-0.92-0.32-1.23s-0.49-0.53-0.84-0.65
c-0.35-0.13-0.73-0.19-1.16-0.19c-0.34,0-0.73,0.03-1.17,0.08c-0.44,0.06-0.81,0.12-1.09,0.19v1.43c0,0.8,0.09,1.43,0.26,1.89
c0.17,0.46,0.43,0.78,0.76,0.97c0.33,0.19,0.75,0.29,1.26,0.29c0.36,0,0.68-0.05,0.96-0.15c0.29-0.1,0.53-0.25,0.73-0.45
c0.2-0.2,0.35-0.48,0.46-0.83C28.16,28.96,28.21,28.54,28.21,28.06z M26.19,20.5c0.92,0,1.82,0.19,2.7,0.56
c0.09,0.03,0.15,0.07,0.18,0.11c0.03,0.04,0.04,0.1,0.04,0.21v0.54c0,0.19-0.1,0.26-0.3,0.21c-0.63-0.17-1.11-0.29-1.44-0.36
c-0.33-0.07-0.72-0.11-1.19-0.11c-0.73,0-1.28,0.13-1.65,0.4c-0.38,0.27-0.62,0.64-0.74,1.11c-0.11,0.47-0.17,1.07-0.17,1.82v0.17
c0.88-0.2,1.64-0.3,2.26-0.3c0.69,0,1.31,0.1,1.86,0.29c0.55,0.19,0.99,0.52,1.32,0.99c0.33,0.46,0.5,1.08,0.5,1.85v0.09
c0,0.8-0.14,1.49-0.41,2.05c-0.27,0.57-0.68,1-1.22,1.3c-0.54,0.3-1.22,0.45-2.03,0.45c-0.57,0-1.07-0.09-1.52-0.26
c-0.45-0.17-0.83-0.43-1.14-0.78c-0.31-0.34-0.55-0.79-0.72-1.33c-0.17-0.54-0.25-1.17-0.25-1.89v-2.63c0-1.06,0.15-1.92,0.44-2.57
s0.73-1.13,1.31-1.44C24.61,20.65,25.33,20.5,26.19,20.5L26.19,20.5z"/>
<path id="path5618" style="&st5;" d="M35.48,40.61c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
c-8.29,5.27-10.74,16.27-5.46,24.56C16.19,43.44,27.19,45.88,35.48,40.61z"/>
<path id="path5622" style="&st3;" d="M12.52,37.77l2.36-10.7"/>
<path id="path5626" style="&st3;" d="M12.52,37.77L1.87,34.45"/>
</g>
<g id="M5">
<path id="path4062" style="&st2;" d="M138.77,32.03c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.05-0.15-0.09-0.18-0.13c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.21,0.1-0.27,0.3-0.21c1.04,0.31,1.92,0.47,2.63,0.47
c0.84,0,1.46-0.2,1.85-0.59c0.39-0.4,0.59-0.98,0.59-1.77v-0.23c0-0.74-0.24-1.26-0.72-1.56c-0.48-0.3-1.29-0.45-2.41-0.45h-1.79
c-0.07,0-0.13-0.03-0.17-0.08c-0.05-0.06-0.07-0.11-0.07-0.17v-0.01l0.42-5c0.01-0.08,0.04-0.14,0.1-0.19s0.13-0.07,0.2-0.07h5.16
c0.08,0,0.15,0.02,0.21,0.07c0.06,0.05,0.09,0.11,0.09,0.19v0.66c0,0.16-0.1,0.24-0.3,0.24h-4.31l-0.24,3.24h0.7
c0.98,0,1.8,0.1,2.46,0.29c0.66,0.19,1.17,0.52,1.53,0.99c0.36,0.46,0.53,1.08,0.53,1.85v0.23c0,1.11-0.33,1.97-0.99,2.58
C140.91,31.73,139.97,32.03,138.77,32.03L138.77,32.03z"/>
<path id="path5630" style="&st5;" d="M121.01,25.41c-0.62,9.81,6.83,18.26,16.63,18.88c9.81,0.62,18.26-6.83,18.88-16.63
c0.62-9.81-6.83-18.26-16.63-18.88C130.09,8.15,121.64,15.6,121.01,25.41z"/>
<path id="path5634" style="&st3;" d="M136.83,8.52l7.26,8.21"/>
<path id="path5638" style="&st3;" d="M136.83,8.52l8.95-6.65"/>
</g>
<g id="M3">
<path id="path4066" style="&st2;" d="M44.1,47.87c-0.48,0-0.97-0.06-1.47-0.18c-0.5-0.12-0.92-0.25-1.26-0.38
c-0.09-0.04-0.15-0.09-0.18-0.13c-0.03-0.04-0.04-0.1-0.04-0.19v-0.51c0-0.2,0.1-0.27,0.3-0.21c0.59,0.16,1.07,0.27,1.43,0.35
c0.36,0.08,0.76,0.12,1.18,0.12c0.81,0,1.38-0.16,1.73-0.49c0.35-0.33,0.52-0.85,0.52-1.58v-0.31c0-0.29-0.05-0.57-0.16-0.85
c-0.11-0.28-0.3-0.51-0.56-0.7c-0.27-0.19-0.61-0.28-1.03-0.28h-2.72c-0.19,0-0.29-0.09-0.29-0.27v-0.52
c0-0.08,0.03-0.15,0.08-0.21c0.05-0.05,0.12-0.08,0.21-0.08h2.72c0.45,0,0.81-0.09,1.07-0.26c0.26-0.18,0.44-0.4,0.54-0.67
c0.1-0.27,0.15-0.56,0.15-0.85v-0.21c0-0.42-0.07-0.77-0.21-1.02c-0.14-0.26-0.38-0.45-0.71-0.57c-0.33-0.12-0.77-0.19-1.33-0.19
c-0.42,0-0.82,0.04-1.19,0.12c-0.38,0.08-0.85,0.19-1.41,0.34c-0.2,0.06-0.3-0.01-0.3-0.21V37.4c0-0.09,0.02-0.16,0.05-0.2
c0.03-0.04,0.09-0.08,0.17-0.11c0.33-0.14,0.75-0.27,1.25-0.39c0.5-0.12,0.99-0.18,1.49-0.18c1.19,0,2.08,0.22,2.69,0.67
c0.61,0.44,0.91,1.2,0.91,2.26v0.21c0,0.26-0.03,0.5-0.09,0.73c-0.06,0.23-0.15,0.44-0.27,0.65c-0.12,0.2-0.27,0.39-0.45,0.55
c-0.18,0.17-0.38,0.31-0.61,0.42c0.49,0.23,0.85,0.56,1.08,0.98c0.23,0.42,0.35,0.88,0.35,1.36v0.32c0,1.09-0.32,1.89-0.95,2.42
C46.12,47.61,45.24,47.87,44.1,47.87L44.1,47.87z"/>
<path id="path5642" style="&st0;" d="M44.65,59.83c-9.83,0-17.79-7.97-17.79-17.79c0-9.83,7.96-17.79,17.79-17.79
c9.82,0,17.79,7.96,17.79,17.79C62.44,51.86,54.47,59.82,44.65,59.83z"/>
<path id="path5646" style="&st6;" d="M61.78,35.65l1.24-10.89"/>
<path id="path5650" style="&st6;" d="M61.78,35.65l-10.92-2.21"/>
</g>
<g id="M2">
<path id="path4070" style="&st2;" d="M120.86,41.17c0,0.4-0.07,0.76-0.2,1.07c-0.13,0.31-0.34,0.62-0.62,0.9
c-0.28,0.29-0.66,0.59-1.14,0.92l-1.44,0.98c-0.54,0.37-0.97,0.71-1.28,1.03c-0.31,0.32-0.53,0.65-0.65,0.99
c-0.12,0.34-0.18,0.73-0.18,1.17v0.31h5.05c0.2,0,0.3,0.09,0.3,0.26v0.66c0,0.09-0.03,0.16-0.09,0.2
c-0.06,0.05-0.13,0.07-0.21,0.07h-5.95c-0.08,0-0.15-0.03-0.21-0.08c-0.06-0.06-0.09-0.12-0.09-0.2v-1.22
c0-0.52,0.08-1.02,0.24-1.48c0.16-0.47,0.41-0.9,0.75-1.31c0.34-0.41,0.78-0.79,1.32-1.15l1.52-1.02c0.63-0.42,1.04-0.76,1.24-1.03
c0.2-0.27,0.3-0.62,0.3-1.06c0-0.36-0.07-0.65-0.21-0.88c-0.14-0.23-0.35-0.4-0.63-0.5c-0.28-0.11-0.63-0.16-1.05-0.16
c-0.34,0-0.68,0.03-1.02,0.09c-0.34,0.06-0.68,0.14-1.03,0.23c-0.34,0.1-0.62,0.18-0.85,0.24c-0.09,0.03-0.17,0.02-0.22-0.02
c-0.05-0.04-0.08-0.1-0.08-0.19v-0.51c0-0.09,0.02-0.16,0.05-0.2c0.03-0.04,0.09-0.08,0.18-0.11c0.26-0.11,0.54-0.22,0.83-0.31
c0.3-0.1,0.64-0.18,1.04-0.25c0.4-0.07,0.78-0.11,1.14-0.11c0.51,0,0.97,0.06,1.37,0.18c0.41,0.12,0.74,0.28,1,0.5
c0.26,0.21,0.46,0.49,0.6,0.83S120.86,40.72,120.86,41.17L120.86,41.17z"/>
<path id="path5654" style="&st0;" d="M99.23,45.22c0-9.82,7.97-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.97,17.79-17.79,17.79C107.2,63.01,99.23,55.05,99.23,45.22z"/>
<path id="path5658" style="&st6;" d="M119.36,62.67l9.85,4.81"/>
<path id="path5662" style="&st6;" d="M119.36,62.67l5.73-9.56"/>
</g>
<g id="M1">
<path id="path4068" style="&st2;" d="M80.34,113.17c0,0.09-0.03,0.16-0.07,0.22c-0.05,0.06-0.12,0.08-0.2,0.08h-0.82
c-0.08,0-0.15-0.03-0.2-0.09s-0.07-0.13-0.07-0.21v-9.43l-1.93,0.84c-0.08,0.03-0.14,0.04-0.2,0.04c-0.09,0-0.13-0.06-0.13-0.17
v-0.76c0-0.08,0.05-0.14,0.15-0.2l2.26-1.08c0.12-0.06,0.23-0.1,0.32-0.1h0.61c0.08,0,0.15,0.03,0.2,0.08
c0.06,0.05,0.08,0.12,0.08,0.21L80.34,113.17L80.34,113.17z"/>
<path id="path5666" style="&st0;" d="M60.93,107.38c0,9.82,7.97,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79C68.9,89.59,60.93,97.56,60.93,107.38z"/>
<path id="path5670" style="&st6;" d="M75.65,89.53l7.76,7.73"/>
<path id="path5674" style="&st6;" d="M75.65,89.53l8.52-7.19"/>
</g>
<g id="FrontArrow">
<path id="path5134" style="&st4;" d="M80.85,77.66V65.28"/>
<path id="path5138" style="&st1;" d="M90.15,68.01L80.8,51.82l-9.35,16.19H90.15z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -1,41 +1,101 @@
'use strict';
function configuration_backup() {
// request configuration data (one by one)
// code below is highly experimental, although it runs fine on latest firmware
// the data inside nested objects needs to be verified if deep copy works properly
function configuration_backup(callback) {
var activeProfile = null,
profilesN = 3;
function get_ident_data() {
MSP.send_message(MSP_codes.MSP_IDENT, false, false, get_status_data);
var profileSpecificData = [
MSP_codes.MSP_PID,
MSP_codes.MSP_RC_TUNING,
MSP_codes.MSP_ACC_TRIM,
MSP_codes.MSP_SERVO_CONF
];
var uniqueData = [
MSP_codes.MSP_BOX,
MSP_codes.MSP_MISC,
MSP_codes.MSP_RCMAP,
MSP_codes.MSP_CONFIG
];
var configuration = {
'generatedBy': chrome.runtime.getManifest().version,
'profiles': []
};
MSP.send_message(MSP_codes.MSP_STATUS, false, false, function () {
activeProfile = CONFIG.profile;
select_profile();
});
function select_profile() {
if (activeProfile > 0) {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [0], false, fetch_specific_data);
} else {
fetch_specific_data();
}
}
function get_status_data() {
MSP.send_message(MSP_codes.MSP_STATUS, false, false, get_pid_data);
function fetch_specific_data() {
var fetchingProfile = 0,
codeKey = 0;
function query() {
if (fetchingProfile < profilesN) {
MSP.send_message(profileSpecificData[codeKey], false, false, function () {
codeKey++;
if (codeKey < profileSpecificData.length) {
query();
} else {
configuration.profiles.push({
'PID': jQuery.extend(true, [], PIDs),
'RC': jQuery.extend(true, {}, RC_tuning),
'AccTrim': jQuery.extend(true, [], CONFIG.accelerometerTrims),
'ServoConfig': jQuery.extend(true, [], SERVO_CONFIG)
});
codeKey = 0;
fetchingProfile++;
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [fetchingProfile], false, query);
}
});
} else {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [activeProfile], false, fetch_unique_data);
}
}
function get_pid_data() {
MSP.send_message(MSP_codes.MSP_PID, false, false, get_rc_tuning_data);
// start fetching
query();
}
function get_rc_tuning_data() {
MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, get_box_names_data);
function fetch_unique_data() {
var codeKey = 0;
function query() {
if (codeKey < uniqueData.length) {
MSP.send_message(uniqueData[codeKey], false, false, function () {
codeKey++;
query();
});
} else {
configuration.AUX = jQuery.extend(true, [], AUX_CONFIG_values);
configuration.MISC = jQuery.extend(true, {}, MISC);
configuration.RCMAP = jQuery.extend(true, [], RC_MAP);
configuration.BF_CONFIG = jQuery.extend(true, {}, BF_CONFIG);
save();
}
}
function get_box_names_data() {
MSP.send_message(MSP_codes.MSP_BOXNAMES, false, false, get_box_data);
// start fetching
query();
}
function get_box_data() {
MSP.send_message(MSP_codes.MSP_BOX, false, false, get_acc_trim_data);
}
function get_acc_trim_data() {
MSP.send_message(MSP_codes.MSP_ACC_TRIM, false, false, get_misc_data);
}
function get_misc_data() {
MSP.send_message(MSP_codes.MSP_MISC, false, false, backup);
}
function backup() {
function save() {
var chosenFileEntry = null;
var accepts = [{
@ -43,14 +103,18 @@ function configuration_backup() {
}];
// generate timestamp for the backup file
var d = new Date();
var now = d.getUTCFullYear() + '.' + d.getDate() + '.' + (d.getMonth() + 1) + '.' + d.getHours() + '.' + d.getMinutes();
var d = new Date(),
now = (d.getMonth() + 1) + '.' + d.getDate() + '.' + d.getFullYear() + '.' + d.getHours() + '.' + d.getMinutes();
// create or load the file
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'cleanflight_config_' + now, accepts: accepts}, function (fileEntry) {
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'baseflight_backup_' + now, accepts: accepts}, function (fileEntry) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
return;
}
if (!fileEntry) {
console.log('No file selected, backup aborted.');
return;
}
@ -68,17 +132,6 @@ function configuration_backup() {
if (isWritable) {
chosenFileEntry = fileEntryWritable;
// create config object that will be used to store all downloaded data
var configuration = {
'firmware_version': CONFIG.version,
'configurator_version': chrome.runtime.getManifest().version,
'PID': PIDs,
//'AUX_val': AUX_CONFIG_values,
'RC': RC_tuning,
'AccelTrim': CONFIG.accelerometerTrims,
'MISC': MISC
};
// crunch the config object
var serialized_config_object = JSON.stringify(configuration);
var blob = new Blob([serialized_config_object], {type: 'text/plain'}); // first parameter for Blob needs to be an array
@ -99,6 +152,7 @@ function configuration_backup() {
}
console.log('Write SUCCESSFUL');
if (callback) callback();
};
writer.write(blob);
@ -113,12 +167,9 @@ function configuration_backup() {
});
});
}
// begin fetching latest data
get_ident_data();
}
function configuration_restore() {
function configuration_restore(callback) {
var chosenFileEntry = null;
var accepts = [{
@ -127,9 +178,13 @@ function configuration_restore() {
// load up the file
chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function (fileEntry) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
return;
}
if (!fileEntry) {
console.log('No file selected, restore aborted.');
return;
}
@ -165,145 +220,165 @@ function configuration_restore() {
return;
}
// replacing "old configuration" with configuration from backup file
var configuration = deserialized_configuration_object;
// some configuration.VERSION code goes here? will see
PIDs = configuration.PID;
//AUX_CONFIG_values = configuration.AUX_val;
RC_tuning = configuration.RC;
CONFIG.accelerometerTrims = configuration.AccelTrim;
MISC = configuration.MISC;
// all of the arrays/objects are set, upload changes
configuration_upload();
configuration_upload(deserialized_configuration_object, callback);
}
};
reader.readAsText(file);
});
});
function configuration_upload(configuration, callback) {
function compareVersions(generated, required) {
var a = generated.split('.'),
b = required.split('.');
for (var i = 0; i < a.length; ++i) {
a[i] = Number(a[i]);
}
for (var i = 0; i < b.length; ++i) {
b[i] = Number(b[i]);
}
if (a.length == 2) {
a[2] = 0;
}
function configuration_upload() {
// this "cloned" function contains all the upload sequences for the respective array/objects
// that are currently scattered in separate tabs (ergo - pid_tuning.js/initial_setup.js/etc)
// for current purposes, this approach works, but its not really "valid" and this approach
// should be reworked in the future, so the same code won't be cloned over !!!
if (a[0] > b[0]) return true;
if (a[0] < b[0]) return false;
// PID section
var PID_buffer_out = new Array(),
PID_buffer_needle = 0;
if (a[1] > b[1]) return true;
if (a[1] < b[1]) return false;
for (var i = 0; i < PIDs.length; i++) {
switch (i) {
case 0:
case 1:
case 2:
case 3:
case 7:
case 8:
case 9:
PID_buffer_out[PID_buffer_needle] = parseInt(PIDs[i][0] * 10);
PID_buffer_out[PID_buffer_needle + 1] = parseInt(PIDs[i][1] * 1000);
PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2]);
break;
case 4:
PID_buffer_out[PID_buffer_needle] = parseInt(PIDs[i][0] * 100);
PID_buffer_out[PID_buffer_needle + 1] = parseInt(PIDs[i][1] * 100);
PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2]);
break;
case 5:
case 6:
PID_buffer_out[PID_buffer_needle] = parseInt(PIDs[i][0] * 10);
PID_buffer_out[PID_buffer_needle + 1] = parseInt(PIDs[i][1] * 100);
PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2] * 1000);
break;
if (a[2] > b[2]) return true;
if (a[2] < b[2]) return false;
return true;
}
PID_buffer_needle += 3;
function upload() {
var activeProfile = null,
profilesN = 3;
var profileSpecificData = [
MSP_codes.MSP_SET_PID,
MSP_codes.MSP_SET_RC_TUNING,
MSP_codes.MSP_SET_ACC_TRIM,
MSP_codes.MSP_SET_SERVO_CONF
];
var uniqueData = [
MSP_codes.MSP_SET_BOX,
MSP_codes.MSP_SET_MISC,
MSP_codes.MSP_SET_RCMAP,
MSP_codes.MSP_SET_CONFIG
];
MSP.send_message(MSP_codes.MSP_STATUS, false, false, function () {
activeProfile = CONFIG.profile;
select_profile();
});
function select_profile() {
if (activeProfile > 0) {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [0], false, upload_specific_data);
} else {
upload_specific_data();
}
}
// Send over the PID changes
MSP.send_message(MSP_codes.MSP_SET_PID, PID_buffer_out, false, rc_tuning);
function upload_specific_data() {
var savingProfile = 0,
codeKey = 0;
function rc_tuning() {
// RC Tuning section
var RC_tuning_buffer_out = new Array();
RC_tuning_buffer_out[0] = parseInt(RC_tuning.RC_RATE * 100);
RC_tuning_buffer_out[1] = parseInt(RC_tuning.RC_EXPO * 100);
RC_tuning_buffer_out[2] = parseInt(RC_tuning.roll_pitch_rate * 100);
RC_tuning_buffer_out[3] = parseInt(RC_tuning.yaw_rate * 100);
RC_tuning_buffer_out[4] = parseInt(RC_tuning.dynamic_THR_PID * 100);
RC_tuning_buffer_out[5] = parseInt(RC_tuning.throttle_MID * 100);
RC_tuning_buffer_out[6] = parseInt(RC_tuning.throttle_EXPO * 100);
// Send over the RC_tuning changes
MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, RC_tuning_buffer_out, false, aux);
function load_objects(profile) {
PIDs = configuration.profiles[profile].PID;
RC_tuning = configuration.profiles[profile].RC;
CONFIG.accelerometerTrims = configuration.profiles[profile].AccTrim;
SERVO_CONFIG = configuration.profiles[profile].ServoConfig;
}
function aux() {
/*
// AUX section
var AUX_val_buffer_out = new Array(),
needle = 0;
function query() {
MSP.send_message(profileSpecificData[codeKey], MSP.crunch(profileSpecificData[codeKey]), false, function () {
codeKey++;
for (var i = 0; i < AUX_CONFIG_values.length; i++) {
AUX_val_buffer_out[needle++] = lowByte(AUX_CONFIG_values[i]);
AUX_val_buffer_out[needle++] = highByte(AUX_CONFIG_values[i]);
}
if (codeKey < profileSpecificData.length) {
query();
} else {
codeKey = 0;
savingProfile++;
// Send over the AUX changes
MSP.send_message(MSP_codes.MSP_SET_BOX, AUX_val_buffer_out, false, trim);
*/
}
if (savingProfile < profilesN) {
load_objects(savingProfile);
// Trim section
function trim() {
var buffer_out = new Array();
buffer_out[0] = lowByte(CONFIG.accelerometerTrims[0]);
buffer_out[1] = highByte(CONFIG.accelerometerTrims[0]);
buffer_out[2] = lowByte(CONFIG.accelerometerTrims[1]);
buffer_out[3] = highByte(CONFIG.accelerometerTrims[1]);
// Send over the new trims
MSP.send_message(MSP_codes.MSP_SET_ACC_TRIM, buffer_out, false, misc);
}
function misc() {
// MISC
// we also have to fill the unsupported bytes
var buffer_out = new Array();
buffer_out[0] = 0; // powerfailmeter
buffer_out[1] = 0;
buffer_out[2] = lowByte(MISC.minthrottle);
buffer_out[3] = highByte(MISC.minthrottle);
buffer_out[4] = lowByte(MISC.maxthrottle);
buffer_out[5] = highByte(MISC.maxthrottle);
buffer_out[6] = lowByte(MISC.mincommand);
buffer_out[7] = highByte(MISC.mincommand);
buffer_out[8] = lowByte(MISC.failsafe_throttle);
buffer_out[9] = highByte(MISC.failsafe_throttle);
buffer_out[10] = 0;
buffer_out[11] = 0;
buffer_out[12] = 0;
buffer_out[13] = 0;
buffer_out[14] = 0;
buffer_out[15] = 0;
buffer_out[16] = lowByte(MISC.mag_declination);
buffer_out[17] = highByte(MISC.mag_declination);
buffer_out[18] = MISC.vbatscale;
buffer_out[19] = MISC.vbatmincellvoltage;
buffer_out[20] = MISC.vbatmaxcellvoltage;
buffer_out[21] = 0; // vbatlevel_crit (unused)
// Send ove the new MISC
MSP.send_message(MSP_codes.MSP_SET_MISC, buffer_out, false, function () {
// Save changes to EEPROM
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [savingProfile], false, query);
});
} else {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [activeProfile], false, upload_unique_data);
});
}
}
});
}
// start uploading
load_objects(0);
query();
}
function upload_unique_data() {
var codeKey = 0;
function load_objects() {
AUX_CONFIG_values = configuration.AUX;
MISC = configuration.MISC;
RC_MAP = configuration.RCMAP;
BF_CONFIG = configuration.BF_CONFIG;
}
function query() {
if (codeKey < uniqueData.length) {
MSP.send_message(uniqueData[codeKey], MSP.crunch(uniqueData[codeKey]), false, function () {
codeKey++;
query();
});
} else {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, reboot);
}
}
// start uploading
load_objects();
query();
}
function reboot() {
GUI.log(chrome.i18n.getMessage('eeprom_saved_ok'));
});
GUI.tab_switch_cleanup(function() {
MSP.send_message(MSP_codes.MSP_SET_REBOOT, false, false, reinitialize);
});
}
function reinitialize() {
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
GUI.log(chrome.i18n.getMessage('deviceReady'));
if (callback) callback();
});
}, 1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts
}
}
// validate
if (typeof configuration.generatedBy !== 'undefined' && compareVersions(configuration.generatedBy, CONFIGURATOR.backupFileMinVersionAccepted)) {
upload();
} else {
GUI.log(chrome.i18n.getMessage('backupFileIncompatible'));
}
}
}

View File

@ -1,10 +1,10 @@
'use strict';
var CONFIGURATOR = {
'releaseDate': 1415494669479, // 08.31.2014 - new Date().getTime()
'releaseDate': 1417875879820, // new Date().getTime() - 2014.12.06
'firmwareVersionAccepted': 2.3,
'backupFileMinVersionAccepted': '0.55', // chrome.runtime.getManifest().version is stored as string, so does this one
'connectionValid': false,
'mspPassThrough': false,
'cliActive': false,
'cliValid': false
};
@ -14,6 +14,7 @@ var CONFIG = {
flightControllerIdentifier: '',
flightControllerVersion: '',
version: 0,
buildInfo: '',
multiType: 0,
msp_version: 0,
capability: 0,
@ -22,17 +23,29 @@ var CONFIG = {
activeSensors: 0,
mode: 0,
profile: 0,
uid: [0, 0, 0],
accelerometerTrims: [0, 0]
};
var BF_CONFIG = {
mixerConfiguration: 0,
features: 0,
serialrx_type: 0,
board_align_roll: 0,
board_align_pitch: 0,
board_align_yaw: 0,
currentscale: 0,
currentoffset: 0
};
var PID_names = [];
var PIDs = new Array(10);
for (var i = 0; i < 10; i++) {
PIDs[i] = new Array(3);
}
var RC_MAP = [];
// defaults
// roll, pitch, yaw, throttle, aux 1, ... aux n
var RC = {
@ -47,11 +60,12 @@ var RC_tuning = {
yaw_rate: 0,
dynamic_THR_PID: 0,
throttle_MID: 0,
throttle_EXPO: 0,
throttle_EXPO: 0
};
var AUX_CONFIG = [];
var AUX_CONFIG_IDS = [];
var AUX_CONFIG_values = [];
var MODE_RANGES = [];
var ADJUSTMENT_RANGES = [];
@ -97,16 +111,20 @@ var ANALOG = {
};
var MISC = {
PowerTrigger1: 0, // intPowerTrigger1 (aka useless trash)
midrc: 0,
minthrottle: 0,
maxthrottle: 0,
mincommand: 0,
failsafe_throttle: 0,
plog0: 0, // plog useless shit
plog1: 0, // plog useless shit
gps_type: 0,
gps_baudrate: 0,
gps_ubx_sbas: 0,
multiwiicurrentoutput: 0,
rssi_aux_channel: 0,
placeholder2: 0,
mag_declination: 0, // not checked
vbatscale: 0,
vbatmincellvoltage: 0,
vbatmaxcellvoltage: 0,
empty: 0 // unknown
placeholder3: 0
};

View File

@ -6,8 +6,8 @@ var GUI_control = function () {
this.auto_connect = false;
this.connecting_to = false;
this.connected_to = false;
this.connect_lock = false;
this.active_tab;
this.active_tab_ref = false;
this.tab_switch_in_progress = false;
this.operating_system;
this.optional_usb_permissions = false; // controlled by usb permissions code
@ -198,7 +198,7 @@ GUI_control.prototype.tab_switch_cleanup = function (callback) {
MSP.callbacks_cleanup(); // we don't care about any old data that might or might not arrive
GUI.interval_kill_all(); // all intervals (mostly data pulling) needs to be removed on tab switch
this.active_tab_ref.cleanup(callback);
TABS[this.active_tab].cleanup(callback);
};
// initialize object into GUI variable

File diff suppressed because one or more lines are too long

View File

@ -1,78 +1,87 @@
(function() { var h,aa=aa||{},k=this,ba=function(){},ca=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&
!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},m=function(a){return"array"==ca(a)},da=function(a){var b=ca(a);return"array"==b||"object"==b&&"number"==typeof a.length},n=function(a){return"string"==typeof a},p=function(a){return"function"==ca(a)},ea=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b},fa=function(a,b,c){return a.call.apply(a.bind,arguments)},ga=function(a,b,c){if(!a)throw Error();
if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}},q=function(a,b,c){q=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?fa:ga;return q.apply(null,arguments)},ha=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);
return a.apply(this,b)}},r=Date.now||function(){return+new Date},s=function(a,b){var c=a.split("."),d=k;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d=d[e]?d[e]:d[e]={}:d[e]=b},t=function(a,b){function c(){}c.prototype=b.prototype;a.J=b.prototype;a.prototype=new c;a.vc=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};
Function.prototype.bind=Function.prototype.bind||function(a,b){if(1<arguments.length){var c=Array.prototype.slice.call(arguments,1);c.unshift(this,a);return q.apply(null,c)}return q(this,a)};var u=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,u);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};t(u,Error);u.prototype.name="CustomError";var ia=function(a,b){return a<b?-1:a>b?1:0};var ja=function(){};ja.prototype.Na=!1;ja.prototype.ra=function(){this.Na||(this.Na=!0,this.k())};ja.prototype.k=function(){if(this.ub)for(;this.ub.length;)this.ub.shift()()};var v=Array.prototype,ka=v.indexOf?function(a,b,c){return v.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(n(a))return n(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},la=v.forEach?function(a,b,c){v.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},ma=v.some?function(a,b,c){return v.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):
a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1},oa=function(a){var b;t:{b=na;for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){b=e;break t}b=-1}return 0>b?null:n(a)?a.charAt(b):a[b]},pa=function(a,b){var c=ka(a,b),d;(d=0<=c)&&v.splice.call(a,c,1);return d},qa=function(a){return v.concat.apply(v,arguments)};var ra=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)},sa=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},ta=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b},ua=function(a,b){var c;t:{for(c in a)if(b.call(void 0,a[c],c,a))break t;c=void 0}return c&&a[c]},va="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),wa=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<va.length;f++)c=
va[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};var w=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.P=!1;this.ab=!0};w.prototype.k=function(){};w.prototype.ra=function(){};w.prototype.preventDefault=function(){this.defaultPrevented=!0;this.ab=!1};var xa=function(a){xa[" "](a);return a};xa[" "]=ba;var x;t:{var ya=k.navigator;if(ya){var za=ya.userAgent;if(za){x=za;break t}}x=""}var y=function(a){return-1!=x.indexOf(a)};var Aa=y("Opera")||y("OPR"),z=y("Trident")||y("MSIE"),A=y("Gecko")&&-1==x.toLowerCase().indexOf("webkit")&&!(y("Trident")||y("MSIE")),B=-1!=x.toLowerCase().indexOf("webkit"),Ba=function(){var a=k.document;return a?a.documentMode:void 0},Ca=function(){var a="",b;if(Aa&&k.opera)return a=k.opera.version,p(a)?a():a;A?b=/rv\:([^\);]+)(\)|;)/:z?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:B&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(x))?a[1]:"");return z&&(b=Ba(),b>parseFloat(a))?String(b):a}(),Da={},C=function(a){var b;
if(!(b=Da[a])){b=0;for(var c=String(Ca).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),d=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),e=Math.max(c.length,d.length),f=0;0==b&&f<e;f++){var g=c[f]||"",l=d[f]||"",J=RegExp("(\\d*)(\\D*)","g"),F=RegExp("(\\d*)(\\D*)","g");do{var R=J.exec(g)||["","",""],S=F.exec(l)||["","",""];if(0==R[0].length&&0==S[0].length)break;b=ia(0==R[1].length?0:parseInt(R[1],10),0==S[1].length?0:parseInt(S[1],10))||ia(0==R[2].length,0==S[2].length)||ia(R[2],S[2])}while(0==
b)}b=Da[a]=0<=b}return b},Ea=k.document,Fa=Ea&&z?Ba()||("CSS1Compat"==Ea.compatMode?parseInt(Ca,10):5):void 0;var Ga=!z||z&&9<=Fa,Ha=z&&!C("9"),Ia=!B||C("528"),Ja=A&&C("1.9b")||z&&C("8")||Aa&&C("9.5")||B&&C("528"),Ka=A&&!C("8")||z&&!C("9");var D=function(a,b){w.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.pb=this.state=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(A){var e;t:{try{xa(d.nodeName);e=!0;break t}catch(f){}e=!1}e||(d=null)}}else"mouseover"==
c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=B||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=B||void 0!==a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=
a.metaKey;this.state=a.state;this.pb=a;a.defaultPrevented&&this.preventDefault()}};t(D,w);D.prototype.preventDefault=function(){D.J.preventDefault.call(this);var a=this.pb;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,Ha)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};D.prototype.k=function(){};var La="closure_listenable_"+(1E6*Math.random()|0),Ma=function(a){return!(!a||!a[La])},Na=0;var Oa=function(a,b,c,d,e){this.L=a;this.proxy=null;this.src=b;this.type=c;this.ja=!!d;this.ma=e;this.key=++Na;this.removed=this.ka=!1},Pa=function(a){a.removed=!0;a.L=null;a.proxy=null;a.src=null;a.ma=null};var E=function(a){this.src=a;this.h={};this.U=0};E.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.h[f];a||(a=this.h[f]=[],this.U++);var g=Qa(a,b,d,e);-1<g?(b=a[g],c||(b.ka=!1)):(b=new Oa(b,this.src,f,!!d,e),b.ka=c,a.push(b));return b};E.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.h))return!1;var e=this.h[a];b=Qa(e,b,c,d);return-1<b?(Pa(e[b]),v.splice.call(e,b,1),0==e.length&&(delete this.h[a],this.U--),!0):!1};
var Ra=function(a,b){var c=b.type;if(!(c in a.h))return!1;var d=pa(a.h[c],b);d&&(Pa(b),0==a.h[c].length&&(delete a.h[c],a.U--));return d};E.prototype.removeAll=function(a){a=a&&a.toString();var b=0,c;for(c in this.h)if(!a||c==a){for(var d=this.h[c],e=0;e<d.length;e++)++b,Pa(d[e]);delete this.h[c];this.U--}return b};E.prototype.T=function(a,b,c,d){a=this.h[a.toString()];var e=-1;a&&(e=Qa(a,b,c,d));return-1<e?a[e]:null};
var Qa=function(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.removed&&f.L==b&&f.ja==!!c&&f.ma==d)return e}return-1};var Sa="closure_lm_"+(1E6*Math.random()|0),Ta={},Ua=0,Va=function(a,b,c,d,e){if(m(b)){for(var f=0;f<b.length;f++)Va(a,b[f],c,d,e);return null}c=Wa(c);return Ma(a)?a.listen(b,c,d,e):Xa(a,b,c,!1,d,e)},Xa=function(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=!!e,l=Ya(a);l||(a[Sa]=l=new E(a));c=l.add(b,c,d,e,f);if(c.proxy)return c;d=Za();c.proxy=d;d.src=a;d.L=c;a.addEventListener?a.addEventListener(b.toString(),d,g):a.attachEvent($a(b.toString()),d);Ua++;return c},Za=function(){var a=ab,
b=Ga?function(c){return a.call(b.src,b.L,c)}:function(c){c=a.call(b.src,b.L,c);if(!c)return c};return b},bb=function(a,b,c,d,e){if(m(b)){for(var f=0;f<b.length;f++)bb(a,b[f],c,d,e);return null}c=Wa(c);return Ma(a)?a.Ta(b,c,d,e):Xa(a,b,c,!0,d,e)},cb=function(a,b,c,d,e){if(m(b))for(var f=0;f<b.length;f++)cb(a,b[f],c,d,e);else c=Wa(c),Ma(a)?a.Ma(b,c,d,e):a&&(a=Ya(a))&&(b=a.T(b,c,!!d,e))&&db(b)},db=function(a){if("number"==typeof a||!a||a.removed)return!1;var b=a.src;if(Ma(b))return Ra(b.w,a);var c=a.type,
d=a.proxy;b.removeEventListener?b.removeEventListener(c,d,a.ja):b.detachEvent&&b.detachEvent($a(c),d);Ua--;(c=Ya(b))?(Ra(c,a),0==c.U&&(c.src=null,b[Sa]=null)):Pa(a);return!0},$a=function(a){return a in Ta?Ta[a]:Ta[a]="on"+a},fb=function(a,b,c,d){var e=1;if(a=Ya(a))if(b=a.h[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.ja==c&&!f.removed&&(e&=!1!==eb(f,d))}return Boolean(e)},eb=function(a,b){var c=a.L,d=a.ma||a.src;a.ka&&db(a);return c.call(d,b)},ab=function(a,b){if(a.removed)return!0;
if(!Ga){var c;if(!(c=b))t:{c=["window","event"];for(var d=k,e;e=c.shift();)if(null!=d[e])d=d[e];else{c=null;break t}c=d}e=c;c=new D(e,this);d=!0;if(!(0>e.keyCode||void 0!=e.returnValue)){t:{var f=!1;if(0==e.keyCode)try{e.keyCode=-1;break t}catch(g){f=!0}if(f||void 0==e.returnValue)e.returnValue=!0}e=[];for(f=c.currentTarget;f;f=f.parentNode)e.push(f);for(var f=a.type,l=e.length-1;!c.P&&0<=l;l--)c.currentTarget=e[l],d&=fb(e[l],f,!0,c);for(l=0;!c.P&&l<e.length;l++)c.currentTarget=e[l],d&=fb(e[l],f,
!1,c)}return d}return eb(a,new D(b,this))},Ya=function(a){a=a[Sa];return a instanceof E?a:null},gb="__closure_events_fn_"+(1E9*Math.random()>>>0),Wa=function(a){if(p(a))return a;a[gb]||(a[gb]=function(b){return a.handleEvent(b)});return a[gb]};var G=function(){this.w=new E(this);this.Wb=this;this.Ha=null};t(G,ja);G.prototype[La]=!0;h=G.prototype;h.addEventListener=function(a,b,c,d){Va(this,a,b,c,d)};h.removeEventListener=function(a,b,c,d){cb(this,a,b,c,d)};
h.dispatchEvent=function(a){var b,c=this.Ha;if(c){b=[];for(var d=1;c;c=c.Ha)b.push(c),++d}c=this.Wb;d=a.type||a;if(n(a))a=new w(a,c);else if(a instanceof w)a.target=a.target||c;else{var e=a;a=new w(d,c);wa(a,e)}var e=!0,f;if(b)for(var g=b.length-1;!a.P&&0<=g;g--)f=a.currentTarget=b[g],e=hb(f,d,!0,a)&&e;a.P||(f=a.currentTarget=c,e=hb(f,d,!0,a)&&e,a.P||(e=hb(f,d,!1,a)&&e));if(b)for(g=0;!a.P&&g<b.length;g++)f=a.currentTarget=b[g],e=hb(f,d,!1,a)&&e;return e};
h.k=function(){G.J.k.call(this);this.w&&this.w.removeAll(void 0);this.Ha=null};h.listen=function(a,b,c,d){return this.w.add(String(a),b,!1,c,d)};h.Ta=function(a,b,c,d){return this.w.add(String(a),b,!0,c,d)};h.Ma=function(a,b,c,d){return this.w.remove(String(a),b,c,d)};var hb=function(a,b,c,d){b=a.w.h[String(b)];if(!b)return!0;b=b.concat();for(var e=!0,f=0;f<b.length;++f){var g=b[f];if(g&&!g.removed&&g.ja==c){var l=g.L,J=g.ma||g.src;g.ka&&Ra(a.w,g);e=!1!==l.call(J,d)&&e}}return e&&0!=d.ab};
G.prototype.T=function(a,b,c,d){return this.w.T(String(a),b,c,d)};var ib="StopIteration"in k?k.StopIteration:Error("StopIteration"),jb=function(){};jb.prototype.next=function(){throw ib;};jb.prototype.hc=function(){return this};var H=function(a,b){this.o={};this.b=[];this.fa=this.g=0;var c=arguments.length;if(1<c){if(c%2)throw Error("Uneven number of arguments");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else if(a){a instanceof H?(c=a.B(),d=a.p()):(c=ta(a),d=sa(a));for(var e=0;e<c.length;e++)this.set(c[e],d[e])}};H.prototype.p=function(){kb(this);for(var a=[],b=0;b<this.b.length;b++)a.push(this.o[this.b[b]]);return a};H.prototype.B=function(){kb(this);return this.b.concat()};
H.prototype.S=function(a){return I(this.o,a)};H.prototype.remove=function(a){return I(this.o,a)?(delete this.o[a],this.g--,this.fa++,this.b.length>2*this.g&&kb(this),!0):!1};var kb=function(a){if(a.g!=a.b.length){for(var b=0,c=0;b<a.b.length;){var d=a.b[b];I(a.o,d)&&(a.b[c++]=d);b++}a.b.length=c}if(a.g!=a.b.length){for(var e={},c=b=0;b<a.b.length;)d=a.b[b],I(e,d)||(a.b[c++]=d,e[d]=1),b++;a.b.length=c}};h=H.prototype;h.get=function(a,b){return I(this.o,a)?this.o[a]:b};
h.set=function(a,b){I(this.o,a)||(this.g++,this.b.push(a),this.fa++);this.o[a]=b};h.forEach=function(a,b){for(var c=this.B(),d=0;d<c.length;d++){var e=c[d],f=this.get(e);a.call(b,f,e,this)}};h.clone=function(){return new H(this)};h.vb=function(){kb(this);for(var a={},b=0;b<this.b.length;b++){var c=this.b[b];a[c]=this.o[c]}return a};
h.hc=function(a){kb(this);var b=0,c=this.b,d=this.o,e=this.fa,f=this,g=new jb;g.next=function(){for(;;){if(e!=f.fa)throw Error("The map has changed since the iterator was created");if(b>=c.length)throw ib;var g=c[b++];return a?g:d[g]}};return g};var I=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var lb,mb,nb={id:"hitType",name:"t",valueType:"text",maxLength:void 0,defaultValue:void 0},ob={id:"sessionControl",name:"sc",valueType:"text",maxLength:void 0,defaultValue:void 0},pb={id:"description",name:"cd",valueType:"text",maxLength:2048,defaultValue:void 0},qb={Wc:nb,wc:{id:"anonymizeIp",name:"aip",valueType:"boolean",maxLength:void 0,defaultValue:void 0},hd:{id:"queueTime",name:"qt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Cc:{id:"cacheBuster",name:"z",valueType:"text",maxLength:void 0,
defaultValue:void 0},od:ob,Ed:{id:"userId",name:"uid",valueType:"text",maxLength:void 0,defaultValue:void 0},ed:{id:"nonInteraction",name:"ni",valueType:"boolean",maxLength:void 0,defaultValue:void 0},Mc:pb,xd:{id:"title",name:"dt",valueType:"text",maxLength:1500,defaultValue:void 0},Nc:{id:"dimension",name:"cd[1-9][0-9]*",valueType:"text",maxLength:150,defaultValue:void 0},dd:{id:"metric",name:"cm[1-9][0-9]*",valueType:"integer",maxLength:void 0,defaultValue:void 0},yc:{id:"appId",name:"aid",valueType:"text",
maxLength:150,defaultValue:void 0},zc:{id:"appInstallerId",name:"aiid",valueType:"text",maxLength:150,defaultValue:void 0},Qc:{id:"eventCategory",name:"ec",valueType:"text",maxLength:150,defaultValue:void 0},Pc:{id:"eventAction",name:"ea",valueType:"text",maxLength:500,defaultValue:void 0},Rc:{id:"eventLabel",name:"el",valueType:"text",maxLength:500,defaultValue:void 0},Sc:{id:"eventValue",name:"ev",valueType:"integer",maxLength:void 0,defaultValue:void 0},qd:{id:"socialNetwork",name:"sn",valueType:"text",
maxLength:50,defaultValue:void 0},pd:{id:"socialAction",name:"sa",valueType:"text",maxLength:50,defaultValue:void 0},rd:{id:"socialTarget",name:"st",valueType:"text",maxLength:2048,defaultValue:void 0},Ad:{id:"transactionId",name:"ti",valueType:"text",maxLength:500,defaultValue:void 0},zd:{id:"transactionAffiliation",name:"ta",valueType:"text",maxLength:500,defaultValue:void 0},Bd:{id:"transactionRevenue",name:"tr",valueType:"currency",maxLength:void 0,defaultValue:void 0},Cd:{id:"transactionShipping",
name:"ts",valueType:"currency",maxLength:void 0,defaultValue:void 0},Dd:{id:"transactionTax",name:"tt",valueType:"currency",maxLength:void 0,defaultValue:void 0},Kc:{id:"currencyCode",name:"cu",valueType:"text",maxLength:10,defaultValue:void 0},$c:{id:"itemPrice",name:"ip",valueType:"currency",maxLength:void 0,defaultValue:void 0},ad:{id:"itemQuantity",name:"iq",valueType:"integer",maxLength:void 0,defaultValue:void 0},Yc:{id:"itemCode",name:"ic",valueType:"text",maxLength:500,defaultValue:void 0},
Zc:{id:"itemName",name:"in",valueType:"text",maxLength:500,defaultValue:void 0},Xc:{id:"itemCategory",name:"iv",valueType:"text",maxLength:500,defaultValue:void 0},Ic:{id:"campaignSource",name:"cs",valueType:"text",maxLength:100,defaultValue:void 0},Gc:{id:"campaignMedium",name:"cm",valueType:"text",maxLength:50,defaultValue:void 0},Hc:{id:"campaignName",name:"cn",valueType:"text",maxLength:100,defaultValue:void 0},Fc:{id:"campaignKeyword",name:"ck",valueType:"text",maxLength:500,defaultValue:void 0},
Dc:{id:"campaignContent",name:"cc",valueType:"text",maxLength:500,defaultValue:void 0},Ec:{id:"campaignId",name:"ci",valueType:"text",maxLength:100,defaultValue:void 0},Vc:{id:"gclid",name:"gclid",valueType:"text",maxLength:void 0,defaultValue:void 0},Lc:{id:"dclid",name:"dclid",valueType:"text",maxLength:void 0,defaultValue:void 0},gd:{id:"pageLoadTime",name:"plt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Oc:{id:"dnsTime",name:"dns",valueType:"integer",maxLength:void 0,defaultValue:void 0},
sd:{id:"tcpConnectTime",name:"tcp",valueType:"integer",maxLength:void 0,defaultValue:void 0},nd:{id:"serverResponseTime",name:"srt",valueType:"integer",maxLength:void 0,defaultValue:void 0},fd:{id:"pageDownloadTime",name:"pdt",valueType:"integer",maxLength:void 0,defaultValue:void 0},jd:{id:"redirectResponseTime",name:"rrt",valueType:"integer",maxLength:void 0,defaultValue:void 0},td:{id:"timingCategory",name:"utc",valueType:"text",maxLength:150,defaultValue:void 0},wd:{id:"timingVar",name:"utv",
valueType:"text",maxLength:500,defaultValue:void 0},vd:{id:"timingValue",name:"utt",valueType:"integer",maxLength:void 0,defaultValue:void 0},ud:{id:"timingLabel",name:"utl",valueType:"text",maxLength:500,defaultValue:void 0},Tc:{id:"exDescription",name:"exd",valueType:"text",maxLength:150,defaultValue:void 0},Uc:{id:"exFatal",name:"exf",valueType:"boolean",maxLength:void 0,defaultValue:"1"}};var rb=function(a){k.setTimeout(function(){throw a;},0)},sb,tb=function(){var a=k.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&(a=function(){var a=document.createElement("iframe");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+"//"+b.location.host,a=q(function(a){if(a.origin==
d||a.data==c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a){var b=new a,c={},d=c;b.port1.onmessage=function(){c=c.next;var a=c.rb;c.rb=null;a()};return function(a){d.next={rb:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("script")?function(a){var b=document.createElement("script");b.onreadystatechange=function(){b.onreadystatechange=
null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){k.setTimeout(a,0)}};var zb=function(a,b){ub||vb();wb||(ub(),wb=!0);xb.push(new yb(a,b))},ub,vb=function(){if(k.Promise&&k.Promise.resolve){var a=k.Promise.resolve();ub=function(){a.then(Ab)}}else ub=function(){var a=Ab;p(k.setImmediate)?k.setImmediate(a):(sb||(sb=tb()),sb(a))}},wb=!1,xb=[],Ab=function(){for(;xb.length;){var a=xb;xb=[];for(var b=0;b<a.length;b++){var c=a[b];try{c.ic.call(c.scope)}catch(d){rb(d)}}}wb=!1},yb=function(a,b){this.ic=a;this.scope=b};var Bb=function(a){a.prototype.then=a.prototype.then;a.prototype.$goog_Thenable=!0},Cb=function(a){if(!a)return!1;try{return!!a.$goog_Thenable}catch(b){return!1}};var L=function(a,b){this.l=0;this.t=void 0;this.m=this.n=null;this.oa=this.Ca=!1;try{var c=this;a.call(b,function(a){K(c,2,a)},function(a){K(c,3,a)})}catch(d){K(this,3,d)}};L.prototype.then=function(a,b,c){return Db(this,p(a)?a:null,p(b)?b:null,c)};Bb(L);L.prototype.cancel=function(a){0==this.l&&zb(function(){var b=new Eb(a);Fb(this,b)},this)};
var Fb=function(a,b){if(0==a.l)if(a.n){var c=a.n;if(c.m){for(var d=0,e=-1,f=0,g;g=c.m[f];f++)if(g=g.qa)if(d++,g==a&&(e=f),0<=e&&1<d)break;0<=e&&(0==c.l&&1==d?Fb(c,b):(d=c.m.splice(e,1)[0],Gb(c),d.Da(b)))}}else K(a,3,b)},Ib=function(a,b){a.m&&a.m.length||2!=a.l&&3!=a.l||Hb(a);a.m||(a.m=[]);a.m.push(b)},Db=function(a,b,c,d){var e={qa:null,$a:null,Da:null};e.qa=new L(function(a,g){e.$a=b?function(c){try{var e=b.call(d,c);a(e)}catch(F){g(F)}}:a;e.Da=c?function(b){try{var e=c.call(d,b);void 0===e&&b instanceof
Eb?g(b):a(e)}catch(F){g(F)}}:g});e.qa.n=a;Ib(a,e);return e.qa};L.prototype.kb=function(a){this.l=0;K(this,2,a)};L.prototype.lb=function(a){this.l=0;K(this,3,a)};
var K=function(a,b,c){if(0==a.l){if(a==c)b=3,c=new TypeError("Promise cannot resolve to itself");else{if(Cb(c)){a.l=1;c.then(a.kb,a.lb,a);return}if(ea(c))try{var d=c.then;if(p(d)){Jb(a,c,d);return}}catch(e){b=3,c=e}}a.t=c;a.l=b;Hb(a);3!=b||c instanceof Eb||Kb(a,c)}},Jb=function(a,b,c){a.l=1;var d=!1,e=function(b){d||(d=!0,a.kb(b))},f=function(b){d||(d=!0,a.lb(b))};try{c.call(b,e,f)}catch(g){f(g)}},Hb=function(a){a.Ca||(a.Ca=!0,zb(a.gc,a))};
L.prototype.gc=function(){for(;this.m&&this.m.length;){var a=this.m;this.m=[];for(var b=0;b<a.length;b++){var c=a[b],d=this.t;2==this.l?c.$a(d):(Gb(this),c.Da(d))}}this.Ca=!1};var Gb=function(a){for(;a&&a.oa;a=a.n)a.oa=!1},Kb=function(a,b){a.oa=!0;zb(function(){a.oa&&Lb.call(null,b)})},Lb=rb,Eb=function(a){u.call(this,a)};t(Eb,u);Eb.prototype.name="cancel";/*
(function() { var g,aa=aa||{},h=this,ba=function(){},ca=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&
!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},m=function(a){return"array"==ca(a)},da=function(a){var b=ca(a);return"array"==b||"object"==b&&"number"==typeof a.length},n=function(a){return"string"==typeof a},ea=function(a){return"number"==typeof a},p=function(a){return"function"==ca(a)},q=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b},fa=function(a,b,c){return a.call.apply(a.bind,
arguments)},ga=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}},r=function(a,b,c){r=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?fa:ga;return r.apply(null,arguments)},ha=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=
c.slice();b.push.apply(b,arguments);return a.apply(this,b)}},s=Date.now||function(){return+new Date},t=function(a,b){var c=a.split("."),d=h;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d=d[e]?d[e]:d[e]={}:d[e]=b},u=function(a,b){function c(){}c.prototype=b.prototype;a.L=b.prototype;a.prototype=new c;a.Pc=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};
Function.prototype.bind=Function.prototype.bind||function(a,b){if(1<arguments.length){var c=Array.prototype.slice.call(arguments,1);c.unshift(this,a);return r.apply(null,c)}return r(this,a)};var v=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,v);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};u(v,Error);v.prototype.name="CustomError";var ia=function(a,b){return a<b?-1:a>b?1:0};var w=Array.prototype,ja=w.indexOf?function(a,b,c){return w.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(n(a))return n(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},ka=w.forEach?function(a,b,c){w.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},la=w.some?function(a,b,c){return w.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):
a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1},ma=w.every?function(a,b,c){return w.every.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&!b.call(c,e[f],f,a))return!1;return!0},oa=function(a){var b;t:{b=na;for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){b=e;break t}b=-1}return 0>b?null:n(a)?a.charAt(b):a[b]},pa=function(a,b){var c=ja(a,b),d;(d=0<=c)&&w.splice.call(a,c,1);return d},qa=function(a){return w.concat.apply(w,
arguments)},ra=function(a,b,c){return 2>=arguments.length?w.slice.call(a,b):w.slice.call(a,b,c)};var sa="StopIteration"in h?h.StopIteration:Error("StopIteration"),ta=function(){};ta.prototype.next=function(){throw sa;};ta.prototype.vc=function(){return this};var ua=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)},va=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},wa=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b},xa=function(a,b){var c;t:{for(c in a)if(b.call(void 0,a[c],c,a))break t;c=void 0}return c&&a[c]},ya="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),za=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<ya.length;f++)c=
ya[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};var x=function(a,b){this.p={};this.b=[];this.oa=this.h=0;var c=arguments.length;if(1<c){if(c%2)throw Error("Uneven number of arguments");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else a&&this.ia(a)};x.prototype.t=function(){Aa(this);for(var a=[],b=0;b<this.b.length;b++)a.push(this.p[this.b[b]]);return a};x.prototype.F=function(){Aa(this);return this.b.concat()};x.prototype.Q=function(a){return y(this.p,a)};
x.prototype.remove=function(a){return y(this.p,a)?(delete this.p[a],this.h--,this.oa++,this.b.length>2*this.h&&Aa(this),!0):!1};var Aa=function(a){if(a.h!=a.b.length){for(var b=0,c=0;b<a.b.length;){var d=a.b[b];y(a.p,d)&&(a.b[c++]=d);b++}a.b.length=c}if(a.h!=a.b.length){for(var e={},c=b=0;b<a.b.length;)d=a.b[b],y(e,d)||(a.b[c++]=d,e[d]=1),b++;a.b.length=c}};g=x.prototype;g.get=function(a,b){return y(this.p,a)?this.p[a]:b};
g.set=function(a,b){y(this.p,a)||(this.h++,this.b.push(a),this.oa++);this.p[a]=b};g.ia=function(a){var b;a instanceof x?(b=a.F(),a=a.t()):(b=wa(a),a=va(a));for(var c=0;c<b.length;c++)this.set(b[c],a[c])};g.forEach=function(a,b){for(var c=this.F(),d=0;d<c.length;d++){var e=c[d],f=this.get(e);a.call(b,f,e,this)}};g.clone=function(){return new x(this)};g.Jb=function(){Aa(this);for(var a={},b=0;b<this.b.length;b++){var c=this.b[b];a[c]=this.p[c]}return a};
g.vc=function(a){Aa(this);var b=0,c=this.b,d=this.p,e=this.oa,f=this,k=new ta;k.next=function(){for(;;){if(e!=f.oa)throw Error("The map has changed since the iterator was created");if(b>=c.length)throw sa;var k=c[b++];return a?k:d[k]}};return k};var y=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var Ba,Ca,Da={id:"hitType",name:"t",valueType:"text",maxLength:void 0,defaultValue:void 0},Ea={id:"sessionControl",name:"sc",valueType:"text",maxLength:void 0,defaultValue:void 0},Fa={id:"description",name:"cd",valueType:"text",maxLength:2048,defaultValue:void 0},Ga={id:"eventCategory",name:"ec",valueType:"text",maxLength:150,defaultValue:void 0},Ha={id:"eventAction",name:"ea",valueType:"text",maxLength:500,defaultValue:void 0},Ia={id:"eventLabel",name:"el",valueType:"text",maxLength:500,defaultValue:void 0},
Ja={id:"eventValue",name:"ev",valueType:"integer",maxLength:void 0,defaultValue:void 0},Ka={pd:Da,Qc:{id:"anonymizeIp",name:"aip",valueType:"boolean",maxLength:void 0,defaultValue:void 0},Ad:{id:"queueTime",name:"qt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Wc:{id:"cacheBuster",name:"z",valueType:"text",maxLength:void 0,defaultValue:void 0},Gd:Ea,Wd:{id:"userId",name:"uid",valueType:"text",maxLength:void 0,defaultValue:void 0},xd:{id:"nonInteraction",name:"ni",valueType:"boolean",
maxLength:void 0,defaultValue:void 0},fd:Fa,Pd:{id:"title",name:"dt",valueType:"text",maxLength:1500,defaultValue:void 0},Sc:{id:"appId",name:"aid",valueType:"text",maxLength:150,defaultValue:void 0},Tc:{id:"appInstallerId",name:"aiid",valueType:"text",maxLength:150,defaultValue:void 0},jd:Ga,hd:Ha,kd:Ia,ld:Ja,Id:{id:"socialNetwork",name:"sn",valueType:"text",maxLength:50,defaultValue:void 0},Hd:{id:"socialAction",name:"sa",valueType:"text",maxLength:50,defaultValue:void 0},Jd:{id:"socialTarget",
name:"st",valueType:"text",maxLength:2048,defaultValue:void 0},Sd:{id:"transactionId",name:"ti",valueType:"text",maxLength:500,defaultValue:void 0},Rd:{id:"transactionAffiliation",name:"ta",valueType:"text",maxLength:500,defaultValue:void 0},Td:{id:"transactionRevenue",name:"tr",valueType:"currency",maxLength:void 0,defaultValue:void 0},Ud:{id:"transactionShipping",name:"ts",valueType:"currency",maxLength:void 0,defaultValue:void 0},Vd:{id:"transactionTax",name:"tt",valueType:"currency",maxLength:void 0,
defaultValue:void 0},dd:{id:"currencyCode",name:"cu",valueType:"text",maxLength:10,defaultValue:void 0},td:{id:"itemPrice",name:"ip",valueType:"currency",maxLength:void 0,defaultValue:void 0},ud:{id:"itemQuantity",name:"iq",valueType:"integer",maxLength:void 0,defaultValue:void 0},rd:{id:"itemCode",name:"ic",valueType:"text",maxLength:500,defaultValue:void 0},sd:{id:"itemName",name:"in",valueType:"text",maxLength:500,defaultValue:void 0},qd:{id:"itemCategory",name:"iv",valueType:"text",maxLength:500,
defaultValue:void 0},bd:{id:"campaignSource",name:"cs",valueType:"text",maxLength:100,defaultValue:void 0},$c:{id:"campaignMedium",name:"cm",valueType:"text",maxLength:50,defaultValue:void 0},ad:{id:"campaignName",name:"cn",valueType:"text",maxLength:100,defaultValue:void 0},Zc:{id:"campaignKeyword",name:"ck",valueType:"text",maxLength:500,defaultValue:void 0},Xc:{id:"campaignContent",name:"cc",valueType:"text",maxLength:500,defaultValue:void 0},Yc:{id:"campaignId",name:"ci",valueType:"text",maxLength:100,
defaultValue:void 0},od:{id:"gclid",name:"gclid",valueType:"text",maxLength:void 0,defaultValue:void 0},ed:{id:"dclid",name:"dclid",valueType:"text",maxLength:void 0,defaultValue:void 0},zd:{id:"pageLoadTime",name:"plt",valueType:"integer",maxLength:void 0,defaultValue:void 0},gd:{id:"dnsTime",name:"dns",valueType:"integer",maxLength:void 0,defaultValue:void 0},Kd:{id:"tcpConnectTime",name:"tcp",valueType:"integer",maxLength:void 0,defaultValue:void 0},Fd:{id:"serverResponseTime",name:"srt",valueType:"integer",
maxLength:void 0,defaultValue:void 0},yd:{id:"pageDownloadTime",name:"pdt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Bd:{id:"redirectResponseTime",name:"rrt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Ld:{id:"timingCategory",name:"utc",valueType:"text",maxLength:150,defaultValue:void 0},Od:{id:"timingVar",name:"utv",valueType:"text",maxLength:500,defaultValue:void 0},Nd:{id:"timingValue",name:"utt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Md:{id:"timingLabel",
name:"utl",valueType:"text",maxLength:500,defaultValue:void 0},md:{id:"exDescription",name:"exd",valueType:"text",maxLength:150,defaultValue:void 0},nd:{id:"exFatal",name:"exf",valueType:"boolean",maxLength:void 0,defaultValue:"1"}},La=function(a){if(1>a||200<a)throw Error("Expected dimension index range 1-200, but was : "+a);return{id:"dimension"+a,name:"cd"+a,valueType:"text",maxLength:150,defaultValue:void 0}},Ma=function(a){if(1>a||200<a)throw Error("Expected metric index range 1-200, but was : "+
a);return{id:"metric"+a,name:"cm"+a,valueType:"integer",maxLength:void 0,defaultValue:void 0}};var Na=function(a){if(1>a)return"0";if(3>a)return"1-2";a=Math.floor(Math.log(a-1)/Math.log(2));return Math.pow(2,a)+1+"-"+Math.pow(2,a+1)},Oa=function(a,b){for(var c=0,d=a.length-1,e=0;c<=d;){var f=Math.floor((c+d)/2),e=a[f];if(b<=e){d=0==f?0:a[f-1];if(b>d)return(d+1).toString()+"-"+e.toString();d=f-1}else if(b>e){if(f>=a.length-1)return(a[a.length-1]+1).toString()+"+";c=f+1}}return"<= 0"};var z=function(){this.ab=[]},Pa=function(){return new z};g=z.prototype;g.when=function(a){this.ab.push(a);return this};g.zb=function(a){var b=arguments;this.when(function(a){return 0<=ja(b,a.Gb())});return this};g.Oc=function(a,b){var c=ra(arguments,1);this.when(function(b){b=b.T().get(a);return 0<=ja(c,b)});return this};g.xb=function(a,b){if(q(this.e))throw Error("Filter has already been set.");this.e=q(b)?r(a,b):a;return this};
g.Ca=function(){if(0==this.ab.length)throw Error("Must specify at least one predicate using #when or a helper method.");if(!q(this.e))throw Error("Must specify a delegate filter using #applyFilter.");return r(function(a){ma(this.ab,function(b){return b(a)})&&this.e(a)},this)};var A=function(){this.Ab=!1;this.Bb="";this.qb=!1;this.za=null};A.prototype.wc=function(a){this.Ab=!0;this.Bb=a||" - ";return this};A.prototype.Nc=function(){this.qb=!0;return this};A.prototype.Ec=function(){return Qa(this,Na)};A.prototype.Fc=function(a){return Qa(this,ha(Oa,a))};
var Qa=function(a,b){if(null!=a.za)throw Error("LabelerBuilder: Only one labeling strategy may be used.");a.za=r(function(a){var d=a.T().get(Ja),e=a.T().get(Ia);ea(d)&&(d=b(d),null!=e&&this.Ab&&(d=e+this.Bb+d),a.T().set(Ia,d))},a);return a};A.prototype.Ca=function(){if(null==this.za)throw Error("LabelerBuilder: a labeling strategy must be specified prior to calling build().");return Pa().zb("event").xb(r(function(a){this.za(a);this.qb&&a.T().remove(Ja)},this)).Ca()};var Ra=function(a,b){var c=Array.prototype.slice.call(arguments),d=c.shift();if("undefined"==typeof d)throw Error("[goog.string.format] Template required");return d.replace(/%([0\-\ \+]*)(\d+)?(\.(\d+))?([%sfdiu])/g,function(a,b,d,l,N,J,U,V){if("%"==J)return"%";var Db=c.shift();if("undefined"==typeof Db)throw Error("[goog.string.format] Not enough arguments");arguments[0]=Db;return B[J].apply(null,arguments)})},B={s:function(a,b,c){return isNaN(c)||""==c||a.length>=c?a:a=-1<b.indexOf("-",0)?a+Array(c-
a.length+1).join(" "):Array(c-a.length+1).join(" ")+a},f:function(a,b,c,d,e){d=a.toString();isNaN(e)||""==e||(d=a.toFixed(e));var f;f=0>a?"-":0<=b.indexOf("+")?"+":0<=b.indexOf(" ")?" ":"";0<=a&&(d=f+d);if(isNaN(c)||d.length>=c)return d;d=isNaN(e)?Math.abs(a).toString():Math.abs(a).toFixed(e);a=c-d.length-f.length;return d=0<=b.indexOf("-",0)?f+d+Array(a+1).join(" "):f+Array(a+1).join(0<=b.indexOf("0",0)?"0":" ")+d},d:function(a,b,c,d,e,f,k,l){return B.f(parseInt(a,10),b,c,d,0,f,k,l)}};B.i=B.d;
B.u=B.d;var Sa=function(a){if("function"==typeof a.t)return a.t();if(n(a))return a.split("");if(da(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return va(a)},Ta=function(a,b){if("function"==typeof a.forEach)a.forEach(b,void 0);else if(da(a)||n(a))ka(a,b,void 0);else{var c;if("function"==typeof a.F)c=a.F();else if("function"!=typeof a.t)if(da(a)||n(a)){c=[];for(var d=a.length,e=0;e<d;e++)c.push(e)}else c=wa(a);else c=void 0;for(var d=Sa(a),e=d.length,f=0;f<e;f++)b.call(void 0,d[f],c&&c[f],
a)}};var C=function(a){this.B=new x;for(var b=arguments,c=0;c<b.length;c+=2)this.set(b[c],b[c+1])};C.prototype.set=function(a,b){this.B.set(a.name,{key:a,value:b})};C.prototype.remove=function(a){this.B.remove(a.name)};C.prototype.get=function(a){a=this.B.get(a.name,null);return null===a?null:a.value};C.prototype.ia=function(a){this.B.ia(a.B)};var Ua=function(a,b){ka(a.B.t(),function(a){b(a.key,a.value)})};C.prototype.Jb=function(){var a={};Ua(this,function(b,c){a[b.id]=c});return a};
C.prototype.clone=function(){var a=new C;a.B=this.B.clone();return a};C.prototype.toString=function(){var a={};Ua(this,function(b,c){a[b.id]=c});return JSON.stringify(a)};var D=function(a){this.e=a};g=D.prototype;g.xc=function(a){var b=new D(r(this.P,this));b.I=Ga;b.N=a;return b};g.action=function(a){var b=new D(r(this.P,this));b.I=Ha;b.N=a;return b};g.label=function(a){var b=new D(r(this.P,this));b.I=Ia;b.N=a;return b};g.value=function(a){var b=new D(r(this.P,this));b.I=Ja;b.N=a;return b};g.yc=function(a,b){var c=new D(r(this.P,this));c.I=La(a);c.N=b;return c};g.Dc=function(a,b){var c=new D(r(this.P,this));c.I=Ma(a);c.N=b;return c};
g.send=function(a){var b=new C;this.P(b);return a.send("event",b)};g.P=function(a){null!=this.I&&null!=this.N&&!a.B.Q(this.I.name)&&a.set(this.I,this.N);q(this.e)&&this.e(a)};var Va=new D(ba);var E=function(){this.Y=this.Y;this.Da=this.Da};E.prototype.Y=!1;E.prototype.xa=function(){this.Y||(this.Y=!0,this.l())};E.prototype.l=function(){if(this.Da)for(;this.Da.length;)this.Da.shift()()};var F=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.U=!1;this.kb=!0};F.prototype.l=function(){};F.prototype.xa=function(){};F.prototype.preventDefault=function(){this.defaultPrevented=!0;this.kb=!1};var Wa=function(a){Wa[" "](a);return a};Wa[" "]=ba;var G;t:{var Xa=h.navigator;if(Xa){var Ya=Xa.userAgent;if(Ya){G=Ya;break t}}G=""}var H=function(a){return-1!=G.indexOf(a)};var Za=H("Opera")||H("OPR"),I=H("Trident")||H("MSIE"),K=H("Gecko")&&-1==G.toLowerCase().indexOf("webkit")&&!(H("Trident")||H("MSIE")),L=-1!=G.toLowerCase().indexOf("webkit"),$a=function(){var a=h.document;return a?a.documentMode:void 0},ab=function(){var a="",b;if(Za&&h.opera)return a=h.opera.version,p(a)?a():a;K?b=/rv\:([^\);]+)(\)|;)/:I?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:L&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(G))?a[1]:"");return I&&(b=$a(),b>parseFloat(a))?String(b):a}(),bb={},M=function(a){var b;
if(!(b=bb[a])){b=0;for(var c=String(ab).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),d=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),e=Math.max(c.length,d.length),f=0;0==b&&f<e;f++){var k=c[f]||"",l=d[f]||"",N=RegExp("(\\d*)(\\D*)","g"),J=RegExp("(\\d*)(\\D*)","g");do{var U=N.exec(k)||["","",""],V=J.exec(l)||["","",""];if(0==U[0].length&&0==V[0].length)break;b=ia(0==U[1].length?0:parseInt(U[1],10),0==V[1].length?0:parseInt(V[1],10))||ia(0==U[2].length,0==V[2].length)||ia(U[2],V[2])}while(0==
b)}b=bb[a]=0<=b}return b},cb=h.document,db=cb&&I?$a()||("CSS1Compat"==cb.compatMode?parseInt(ab,10):5):void 0;var eb=!I||I&&9<=db,fb=I&&!M("9"),gb=!L||M("528"),hb=K&&M("1.9b")||I&&M("8")||Za&&M("9.5")||L&&M("528"),ib=K&&!M("8")||I&&!M("9");var O=function(a,b){F.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.Db=this.state=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(K){var e;t:{try{Wa(d.nodeName);e=!0;break t}catch(f){}e=!1}e||(d=null)}}else"mouseover"==
c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=L||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=L||void 0!==a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=
a.metaKey;this.state=a.state;this.Db=a;a.defaultPrevented&&this.preventDefault()}};u(O,F);O.prototype.preventDefault=function(){O.L.preventDefault.call(this);var a=this.Db;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,fb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};O.prototype.l=function(){};var jb="closure_listenable_"+(1E6*Math.random()|0),kb=function(a){return!(!a||!a[jb])},lb=0;var mb=function(a,b,c,d,e){this.O=a;this.proxy=null;this.src=b;this.type=c;this.pa=!!d;this.sa=e;this.key=++lb;this.removed=this.qa=!1},nb=function(a){a.removed=!0;a.O=null;a.proxy=null;a.src=null;a.sa=null};var P=function(a){this.src=a;this.j={};this.Z=0};P.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.j[f];a||(a=this.j[f]=[],this.Z++);var k=ob(a,b,d,e);-1<k?(b=a[k],c||(b.qa=!1)):(b=new mb(b,this.src,f,!!d,e),b.qa=c,a.push(b));return b};P.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.j))return!1;var e=this.j[a];b=ob(e,b,c,d);return-1<b?(nb(e[b]),w.splice.call(e,b,1),0==e.length&&(delete this.j[a],this.Z--),!0):!1};
var pb=function(a,b){var c=b.type;if(!(c in a.j))return!1;var d=pa(a.j[c],b);d&&(nb(b),0==a.j[c].length&&(delete a.j[c],a.Z--));return d};P.prototype.removeAll=function(a){a=a&&a.toString();var b=0,c;for(c in this.j)if(!a||c==a){for(var d=this.j[c],e=0;e<d.length;e++)++b,nb(d[e]);delete this.j[c];this.Z--}return b};P.prototype.X=function(a,b,c,d){a=this.j[a.toString()];var e=-1;a&&(e=ob(a,b,c,d));return-1<e?a[e]:null};
var ob=function(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.removed&&f.O==b&&f.pa==!!c&&f.sa==d)return e}return-1};var qb="closure_lm_"+(1E6*Math.random()|0),rb={},sb=0,tb=function(a,b,c,d,e){if(m(b)){for(var f=0;f<b.length;f++)tb(a,b[f],c,d,e);return null}c=ub(c);return kb(a)?a.listen(b,c,d,e):vb(a,b,c,!1,d,e)},vb=function(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var k=!!e,l=wb(a);l||(a[qb]=l=new P(a));c=l.add(b,c,d,e,f);if(c.proxy)return c;d=xb();c.proxy=d;d.src=a;d.O=c;a.addEventListener?a.addEventListener(b.toString(),d,k):a.attachEvent(yb(b.toString()),d);sb++;return c},xb=function(){var a=zb,
b=eb?function(c){return a.call(b.src,b.O,c)}:function(c){c=a.call(b.src,b.O,c);if(!c)return c};return b},Ab=function(a,b,c,d,e){if(m(b)){for(var f=0;f<b.length;f++)Ab(a,b[f],c,d,e);return null}c=ub(c);return kb(a)?a.bb(b,c,d,e):vb(a,b,c,!0,d,e)},Bb=function(a,b,c,d,e){if(m(b))for(var f=0;f<b.length;f++)Bb(a,b[f],c,d,e);else c=ub(c),kb(a)?a.Va(b,c,d,e):a&&(a=wb(a))&&(b=a.X(b,c,!!d,e))&&Cb(b)},Cb=function(a){if(ea(a)||!a||a.removed)return!1;var b=a.src;if(kb(b))return pb(b.A,a);var c=a.type,d=a.proxy;
b.removeEventListener?b.removeEventListener(c,d,a.pa):b.detachEvent&&b.detachEvent(yb(c),d);sb--;(c=wb(b))?(pb(c,a),0==c.Z&&(c.src=null,b[qb]=null)):nb(a);return!0},yb=function(a){return a in rb?rb[a]:rb[a]="on"+a},Fb=function(a,b,c,d){var e=1;if(a=wb(a))if(b=a.j[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.pa==c&&!f.removed&&(e&=!1!==Eb(f,d))}return Boolean(e)},Eb=function(a,b){var c=a.O,d=a.sa||a.src;a.qa&&Cb(a);return c.call(d,b)},zb=function(a,b){if(a.removed)return!0;if(!eb){var c;
if(!(c=b))t:{c=["window","event"];for(var d=h,e;e=c.shift();)if(null!=d[e])d=d[e];else{c=null;break t}c=d}e=c;c=new O(e,this);d=!0;if(!(0>e.keyCode||void 0!=e.returnValue)){t:{var f=!1;if(0==e.keyCode)try{e.keyCode=-1;break t}catch(k){f=!0}if(f||void 0==e.returnValue)e.returnValue=!0}e=[];for(f=c.currentTarget;f;f=f.parentNode)e.push(f);for(var f=a.type,l=e.length-1;!c.U&&0<=l;l--)c.currentTarget=e[l],d&=Fb(e[l],f,!0,c);for(l=0;!c.U&&l<e.length;l++)c.currentTarget=e[l],d&=Fb(e[l],f,!1,c)}return d}return Eb(a,
new O(b,this))},wb=function(a){a=a[qb];return a instanceof P?a:null},Gb="__closure_events_fn_"+(1E9*Math.random()>>>0),ub=function(a){if(p(a))return a;a[Gb]||(a[Gb]=function(b){return a.handleEvent(b)});return a[Gb]};var Q=function(){E.call(this);this.A=new P(this);this.kc=this;this.Qa=null};u(Q,E);Q.prototype[jb]=!0;g=Q.prototype;g.addEventListener=function(a,b,c,d){tb(this,a,b,c,d)};g.removeEventListener=function(a,b,c,d){Bb(this,a,b,c,d)};
g.dispatchEvent=function(a){var b,c=this.Qa;if(c){b=[];for(var d=1;c;c=c.Qa)b.push(c),++d}c=this.kc;d=a.type||a;if(n(a))a=new F(a,c);else if(a instanceof F)a.target=a.target||c;else{var e=a;a=new F(d,c);za(a,e)}var e=!0,f;if(b)for(var k=b.length-1;!a.U&&0<=k;k--)f=a.currentTarget=b[k],e=Hb(f,d,!0,a)&&e;a.U||(f=a.currentTarget=c,e=Hb(f,d,!0,a)&&e,a.U||(e=Hb(f,d,!1,a)&&e));if(b)for(k=0;!a.U&&k<b.length;k++)f=a.currentTarget=b[k],e=Hb(f,d,!1,a)&&e;return e};
g.l=function(){Q.L.l.call(this);this.A&&this.A.removeAll(void 0);this.Qa=null};g.listen=function(a,b,c,d){return this.A.add(String(a),b,!1,c,d)};g.bb=function(a,b,c,d){return this.A.add(String(a),b,!0,c,d)};g.Va=function(a,b,c,d){return this.A.remove(String(a),b,c,d)};var Hb=function(a,b,c,d){b=a.A.j[String(b)];if(!b)return!0;b=b.concat();for(var e=!0,f=0;f<b.length;++f){var k=b[f];if(k&&!k.removed&&k.pa==c){var l=k.O,N=k.sa||k.src;k.qa&&pb(a.A,k);e=!1!==l.call(N,d)&&e}}return e&&0!=d.kb};
Q.prototype.X=function(a,b,c,d){return this.A.X(String(a),b,c,d)};var Ib=function(a){h.setTimeout(function(){throw a;},0)},Jb,Kb=function(){var a=h.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&(a=function(){var a=document.createElement("iframe");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+"//"+b.location.host,a=r(function(a){if(a.origin==
d||a.data==c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a&&!H("Trident")&&!H("MSIE")){var b=new a,c={},d=c;b.port1.onmessage=function(){c=c.next;var a=c.Fb;c.Fb=null;a()};return function(a){d.next={Fb:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("script")?function(a){var b=document.createElement("script");b.onreadystatechange=
function(){b.onreadystatechange=null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){h.setTimeout(a,0)}};var Qb=function(a,b){Lb||Mb();Nb||(Lb(),Nb=!0);Ob.push(new Pb(a,b))},Lb,Mb=function(){if(h.Promise&&h.Promise.resolve){var a=h.Promise.resolve();Lb=function(){a.then(Rb)}}else Lb=function(){var a=Rb;!p(h.setImmediate)||h.Window&&h.Window.prototype.setImmediate==h.setImmediate?(Jb||(Jb=Kb()),Jb(a)):h.setImmediate(a)}},Nb=!1,Ob=[],Rb=function(){for(;Ob.length;){var a=Ob;Ob=[];for(var b=0;b<a.length;b++){var c=a[b];try{c.zc.call(c.scope)}catch(d){Ib(d)}}}Nb=!1},Pb=function(a,b){this.zc=a;this.scope=
b};var Sb=function(a){a.prototype.then=a.prototype.then;a.prototype.$goog_Thenable=!0},Tb=function(a){if(!a)return!1;try{return!!a.$goog_Thenable}catch(b){return!1}};var R=function(a,b){this.m=0;this.v=void 0;this.n=this.o=null;this.ua=this.La=!1;try{var c=this;a.call(b,function(a){Ub(c,2,a)},function(a){Ub(c,3,a)})}catch(d){Ub(this,3,d)}};R.prototype.then=function(a,b,c){return Vb(this,p(a)?a:null,p(b)?b:null,c)};Sb(R);R.prototype.cancel=function(a){0==this.m&&Qb(function(){var b=new Wb(a);Xb(this,b)},this)};
var Xb=function(a,b){if(0==a.m)if(a.o){var c=a.o;if(c.n){for(var d=0,e=-1,f=0,k;k=c.n[f];f++)if(k=k.wa)if(d++,k==a&&(e=f),0<=e&&1<d)break;0<=e&&(0==c.m&&1==d?Xb(c,b):(d=c.n.splice(e,1)[0],Yb(c),d.Ma(b)))}}else Ub(a,3,b)},$b=function(a,b){a.n&&a.n.length||2!=a.m&&3!=a.m||Zb(a);a.n||(a.n=[]);a.n.push(b)},Vb=function(a,b,c,d){var e={wa:null,jb:null,Ma:null};e.wa=new R(function(a,k){e.jb=b?function(c){try{var e=b.call(d,c);a(e)}catch(J){k(J)}}:a;e.Ma=c?function(b){try{var e=c.call(d,b);void 0===e&&b instanceof
Wb?k(b):a(e)}catch(J){k(J)}}:k});e.wa.o=a;$b(a,e);return e.wa};R.prototype.vb=function(a){this.m=0;Ub(this,2,a)};R.prototype.wb=function(a){this.m=0;Ub(this,3,a)};
var Ub=function(a,b,c){if(0==a.m){if(a==c)b=3,c=new TypeError("Promise cannot resolve to itself");else{if(Tb(c)){a.m=1;c.then(a.vb,a.wb,a);return}if(q(c))try{var d=c.then;if(p(d)){ac(a,c,d);return}}catch(e){b=3,c=e}}a.v=c;a.m=b;Zb(a);3!=b||c instanceof Wb||bc(a,c)}},ac=function(a,b,c){a.m=1;var d=!1,e=function(b){d||(d=!0,a.vb(b))},f=function(b){d||(d=!0,a.wb(b))};try{c.call(b,e,f)}catch(k){f(k)}},Zb=function(a){a.La||(a.La=!0,Qb(a.uc,a))};
R.prototype.uc=function(){for(;this.n&&this.n.length;){var a=this.n;this.n=[];for(var b=0;b<a.length;b++){var c=a[b],d=this.v;2==this.m?c.jb(d):(Yb(this),c.Ma(d))}}this.La=!1};var Yb=function(a){for(;a&&a.ua;a=a.o)a.ua=!1},bc=function(a,b){a.ua=!0;Qb(function(){a.ua&&cc.call(null,b)})},cc=Ib,Wb=function(a){v.call(this,a)};u(Wb,v);Wb.prototype.name="cancel";/*
Portions of this code are from MochiKit, received by
The Closure Authors under the MIT license. All other code is Copyright
2005-2009 The Closure Authors. All Rights Reserved.
*/
var M=function(a,b){this.da=[];this.Ya=a;this.Xa=b||null;this.R=this.C=!1;this.t=void 0;this.Ba=this.xb=this.Aa=!1;this.ea=0;this.n=null;this.za=0};M.prototype.cancel=function(a){if(this.C)this.t instanceof M&&this.t.cancel();else{if(this.n){var b=this.n;delete this.n;a?b.cancel(a):(b.za--,0>=b.za&&b.cancel())}this.Ya?this.Ya.call(this.Xa,this):this.Ba=!0;this.C||this.v(new Mb)}};M.prototype.Za=function(a,b){this.Aa=!1;Nb(this,a,b)};
var Nb=function(a,b,c){a.C=!0;a.t=c;a.R=!b;Ob(a)},Qb=function(a){if(a.C){if(!a.Ba)throw new Pb;a.Ba=!1}};M.prototype.F=function(a){Qb(this);Nb(this,!0,a)};M.prototype.v=function(a){Qb(this);Nb(this,!1,a)};M.prototype.H=function(a,b){return N(this,a,null,b)};var N=function(a,b,c,d){a.da.push([b,c,d]);a.C&&Ob(a);return a};M.prototype.then=function(a,b,c){var d,e,f=new L(function(a,b){d=a;e=b});N(this,d,function(a){a instanceof Mb?f.cancel():e(a)});return f.then(a,b,c)};Bb(M);
var Rb=function(a){var b=new M;N(a,b.F,b.v,b);return b},Tb=function(a){return ma(a.da,function(a){return p(a[1])})},Ob=function(a){if(a.ea&&a.C&&Tb(a)){var b=a.ea,c=Ub[b];c&&(k.clearTimeout(c.ga),delete Ub[b]);a.ea=0}a.n&&(a.n.za--,delete a.n);for(var b=a.t,d=c=!1;a.da.length&&!a.Aa;){var e=a.da.shift(),f=e[0],g=e[1],e=e[2];if(f=a.R?g:f)try{var l=f.call(e||a.Xa,b);void 0!==l&&(a.R=a.R&&(l==b||l instanceof Error),a.t=b=l);Cb(b)&&(d=!0,a.Aa=!0)}catch(J){b=J,a.R=!0,Tb(a)||(c=!0)}}a.t=b;d&&(l=q(a.Za,
a,!0),d=q(a.Za,a,!1),b instanceof M?(N(b,l,d),b.xb=!0):b.then(l,d));c&&(b=new Vb(b),Ub[b.ga]=b,a.ea=b.ga)},Wb=function(a){var b=new M;b.F(a);return b},Yb=function(){var a=Xb,b=new M;b.v(a);return b},Pb=function(){u.call(this)};t(Pb,u);Pb.prototype.message="Deferred has already fired";Pb.prototype.name="AlreadyCalledError";var Mb=function(){u.call(this)};t(Mb,u);Mb.prototype.message="Deferred was canceled";Mb.prototype.name="CanceledError";
var Vb=function(a){this.ga=k.setTimeout(q(this.bc,this),0);this.ba=a};Vb.prototype.bc=function(){delete Ub[this.ga];throw this.ba;};var Ub={};var Zb=function(a,b){var c=Array.prototype.slice.call(arguments),d=c.shift();if("undefined"==typeof d)throw Error("[goog.string.format] Template required");return d.replace(/%([0\-\ \+]*)(\d+)?(\.(\d+))?([%sfdiu])/g,function(a,b,d,l,J,F,R,S){if("%"==F)return"%";var Sb=c.shift();if("undefined"==typeof Sb)throw Error("[goog.string.format] Not enough arguments");arguments[0]=Sb;return O[F].apply(null,arguments)})},O={s:function(a,b,c){return isNaN(c)||""==c||a.length>=c?a:a=-1<b.indexOf("-",0)?a+Array(c-
a.length+1).join(" "):Array(c-a.length+1).join(" ")+a},f:function(a,b,c,d,e){d=a.toString();isNaN(e)||""==e||(d=a.toFixed(e));var f;f=0>a?"-":0<=b.indexOf("+")?"+":0<=b.indexOf(" ")?" ":"";0<=a&&(d=f+d);if(isNaN(c)||d.length>=c)return d;d=isNaN(e)?Math.abs(a).toString():Math.abs(a).toFixed(e);a=c-d.length-f.length;return d=0<=b.indexOf("-",0)?f+d+Array(a+1).join(" "):f+Array(a+1).join(0<=b.indexOf("0",0)?"0":" ")+d},d:function(a,b,c,d,e,f,g,l){return O.f(parseInt(a,10),b,c,d,0,f,g,l)}};O.i=O.d;
O.u=O.d;var $b=function(a){if("function"==typeof a.p)return a.p();if(n(a))return a.split("");if(da(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return sa(a)},ac=function(a,b){if("function"==typeof a.forEach)a.forEach(b,void 0);else if(da(a)||n(a))la(a,b,void 0);else{var c;if("function"==typeof a.B)c=a.B();else if("function"!=typeof a.p)if(da(a)||n(a)){c=[];for(var d=a.length,e=0;e<d;e++)c.push(e)}else c=ta(a);else c=void 0;for(var d=$b(a),e=d.length,f=0;f<e;f++)b.call(void 0,d[f],c&&c[f],
a)}};var P=function(a){this.O=new H;for(var b=arguments,c=0;c<b.length;c+=2)this.set(b[c],b[c+1])};P.prototype.set=function(a,b){this.O.set(a.name,{key:a,value:b})};P.prototype.remove=function(a){this.O.remove(a.name)};P.prototype.get=function(a){a=this.O.get(a.name,null);return null===a?null:a.value};var bc=function(a,b){la(a.O.p(),function(a){b(a.key,a.value)})};P.prototype.vb=function(){var a={};bc(this,function(b,c){a[b.id]=c});return a};
P.prototype.clone=function(){var a=new P;a.O=this.O.clone();return a};P.prototype.toString=function(){var a={};bc(this,function(b,c){a[b.id]=c});return JSON.stringify(a)};var cc=function(a){this.Sa=[];this.A=a};cc.prototype.N=function(a){if(!p(a))throw Error("Invalid filter. Must be a function.");this.Sa.push(a)};cc.prototype.send=function(a,b){for(var c=new Q(a,b),d=0;d<this.Sa.length&&(this.Sa[d](c),!c.Ra);d++);return c.Ra?Wb():this.A.send(a,b)};var Q=function(a,b){this.dc=a;this.cc=b;this.Ra=!1};Q.prototype.lc=function(){return this.dc};Q.prototype.mc=function(){return this.cc};Q.prototype.cancel=function(){this.Ra=!0};var dc=function(a,b){this.width=a;this.height=b};dc.prototype.clone=function(){return new dc(this.width,this.height)};dc.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};!A&&!z||z&&z&&9<=Fa||A&&C("1.9.1");z&&C("9");var ec={id:"apiVersion",name:"v",valueType:"text",maxLength:void 0,defaultValue:void 0},fc={id:"appName",name:"an",valueType:"text",maxLength:100,defaultValue:void 0},gc={id:"appVersion",name:"av",valueType:"text",maxLength:100,defaultValue:void 0},hc={id:"clientId",name:"cid",valueType:"text",maxLength:void 0,defaultValue:void 0},ic={id:"language",name:"ul",valueType:"text",maxLength:20,defaultValue:void 0},jc={id:"libVersion",name:"_v",valueType:"text",maxLength:void 0,defaultValue:void 0},kc={id:"sampleRateOverride",
name:"usro",valueType:"integer",maxLength:void 0,defaultValue:void 0},lc={id:"screenColors",name:"sd",valueType:"text",maxLength:20,defaultValue:void 0},mc={id:"screenResolution",name:"sr",valueType:"text",maxLength:20,defaultValue:void 0},nc={id:"trackingId",name:"tid",valueType:"text",maxLength:void 0,defaultValue:void 0},oc={id:"viewportSize",name:"vp",valueType:"text",maxLength:20,defaultValue:void 0},pc={xc:ec,Ac:fc,Bc:gc,Jc:hc,bd:ic,cd:jc,kd:kc,ld:lc,md:mc,yd:nc,Fd:oc},rc=function(a){if(!n(a))return a;
var b=qc(a,qb);if(ea(b))return b;b=qc(a,pc);if(ea(b))return b;b=/^dimension(\d+)$/.exec(a);if(null!==b)return{id:a,name:"cd"+b[1],valueType:"text",maxLength:150,defaultValue:void 0};b=/^metric(\d+)$/.exec(a);if(null!==b)return{id:a,name:"cm"+b[1],valueType:"integer",maxLength:void 0,defaultValue:void 0};throw Error(a+" is not a valid parameter name.");},qc=function(a,b){var c=ua(b,function(b){return b.id==a&&"metric"!=a&&"dimension"!=a});return ea(c)?c:null};var T=function(a,b){this.Kb=b;this.q=b.Ja();this.nb=new P;this.Qa=!1};h=T.prototype;h.set=function(a,b){var c=rc(a);this.nb.set(c,b)};h.N=function(a){this.Kb.N(a)};h.send=function(a,b){var c=this.nb.clone();b&&ra(b,function(a,b){null!=a&&c.set(rc(b),a)},this);this.Qa&&(this.Qa=!1,c.set(ob,"start"));return this.q.send(a,c)};h.oc=function(a){var b={description:a};this.set(pb,a);return this.send("appview",b)};
h.pc=function(a,b,c,d){return this.send("event",{eventCategory:a,eventAction:b,eventLabel:c,eventValue:d})};h.rc=function(a,b,c){return this.send("social",{socialNetwork:a,socialAction:b,socialTarget:c})};h.qc=function(a,b){return this.send("exception",{exDescription:a,exFatal:b})};h.ob=function(a,b,c,d,e){return this.send("timing",{timingCategory:a,timingVar:b,timingLabel:d,timingValue:c,sampleRateOverride:e})};h.jc=function(){this.Qa=!0};h.uc=function(a,b,c,d){return new sc(this,a,b,c,d)};
var sc=function(a,b,c,d,e){this.mb=a;this.Ob=b;this.Rb=c;this.Pb=d;this.Q=e;this.Qb=r()};sc.prototype.send=function(){var a=this.mb.ob(this.Ob,this.Rb,r()-this.Qb,this.Pb,this.Q);this.mb=null;return a};var U=function(a,b,c,d,e){this.Vb=a;this.Sb=b;this.Tb=c;this.j=d;this.Ub=e};U.prototype.nc=function(a){var b=new T(0,this.Ub.create());b.set(jc,this.Vb);b.set(ec,1);b.set(fc,this.Sb);b.set(gc,this.Tb);b.set(nc,a);a=window.navigator.language;b.set(ic,a);a=screen.colorDepth+"-bit";b.set(lc,a);a=[screen.width,screen.height].join("x");b.set(mc,a);a=window.document;a="CSS1Compat"==a.compatMode?a.documentElement:a.body;a=new dc(a.clientWidth,a.clientHeight);a=[a.width,a.height].join("x");b.set(oc,a);return b};
U.prototype.kc=function(){return Rb(this.j.ca)};var tc=function(a){this.ec=a};tc.prototype.send=function(a,b){this.ec.push({Eb:a,Fb:b});return Wb()};var uc=function(a,b,c){this.j=a;this.la=[];this.K={enabled:new tc(this.la),disabled:c};this.q=this.K.enabled;N(Rb(this.j.ca),ha(this.Bb,b),this.Ab,this)};uc.prototype.Bb=function(a){this.K.enabled=a();vc(this);la(this.la,function(a){this.send(a.Eb,a.Fb)},this);this.la=null;wc(this.j,q(this.Gb,this))};uc.prototype.Ab=function(){this.q=this.K.enabled=this.K.disabled;this.la=null};uc.prototype.send=function(a,b){return this.q.send(a,b)};var vc=function(a){a.q=a.j.pa()?a.K.enabled:a.K.disabled};
uc.prototype.Gb=function(a){switch(a){case "analytics.tracking-permitted":vc(this)}};var xc=function(a,b,c,d,e,f){M.call(this,e,f);this.Ea=a;this.Fa=[];this.bb=!!b;this.zb=!!c;this.yb=!!d;for(b=this.cb=0;b<a.length;b++)N(a[b],q(this.hb,this,b,!0),q(this.hb,this,b,!1));0!=a.length||this.bb||this.F(this.Fa)};t(xc,M);xc.prototype.hb=function(a,b,c){this.cb++;this.Fa[a]=[b,c];this.C||(this.bb&&b?this.F([a,c]):this.zb&&!b?this.v(c):this.cb==this.Ea.length&&this.F(this.Fa));this.yb&&!b&&(c=null);return c};xc.prototype.v=function(a){xc.J.v.call(this,a);for(a=0;a<this.Ea.length;a++)this.Ea[a].cancel()};
var yc=function(a){return(new xc(a,!1,!0)).H(function(a){for(var c=[],d=0;d<a.length;d++)c[d]=a[d][1];return c})};var V=function(a){this.G=a;this.Q=100;this.eb=[];this.Ga=this.ha=null;this.ca=zc(this);this.ca.H(function(){Va(this.G,"a",q(this.Db,this))},this)},zc=function(a){return Ac(a).H(function(){return this},a)},Ac=function(a){return yc([Bc(a),Cc(a)])};V.prototype.Db=function(){var a=this.ha,b=this.pa();Ac(this).H(function(){if(a!=this.ha)throw Error("User ID changed unexpectedly!");b!=this.pa()&&Dc(this)},this)};var wc=function(a,b){a.eb.push(b)};
V.prototype.tc=function(a){this.G.set("analytics.tracking-permitted",a).H(function(){this.Ga=a},this)};V.prototype.pa=function(){var a;if(a=this.Ga)a=k._gaUserPrefs,a=!(a&&a.ioo&&a.ioo());return a};
var Bc=function(a){return a.G.get("analytics.tracking-permitted").H(function(a){this.Ga=void 0!==a?a:!0},a)},Cc=function(a){return a.G.get("analytics.user-id").H(function(a){if(!a){a="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".split("");for(var c=0,d=a.length;c<d;c++)switch(a[c]){case "x":a[c]=Math.floor(16*Math.random()).toString(16);break;case "y":a[c]=(Math.floor(4*Math.random())+8).toString(16)}a=a.join("");this.G.set("analytics.user-id",a)}this.ha=a},a)};V.prototype.sc=function(a){this.Q=a};
var Dc=function(a){la(a.eb,function(a){a("analytics.tracking-permitted")})};var Ec=function(a){G.call(this);this.Oa=a;this.G=chrome.storage.local;chrome.storage.onChanged.addListener(q(this.$b,this))};t(Ec,G);Ec.prototype.$b=function(a){Fc(this,a)&&this.dispatchEvent("a")};var Fc=function(a,b){return ma(ta(b),function(a){return 0==a.lastIndexOf(this.Oa,0)},a)};Ec.prototype.get=function(a){var b=new M,c=this.Oa+"."+a;this.G.get(c,function(a){var e=chrome.runtime.lastError;e?b.v(e):b.F(a[c])});return b};
Ec.prototype.set=function(a,b){var c=new M,d={};d[this.Oa+"."+a]=b;this.G.set(d,function(){var a=chrome.runtime.lastError;a?c.v(a):c.F()});return c};var W=function(){};W.Ib=function(){return W.tb?W.tb:W.tb=new W};W.prototype.send=function(){return Wb()};var Gc=function(a,b){this.Pa=[];var c=q(function(){this.ta=new cc(b.Ja());la(this.Pa,function(a){this.ta.N(a)},this);this.Pa=null;return this.ta},this);this.q=new uc(a,c,W.Ib())};Gc.prototype.Ja=function(){return this.q};Gc.prototype.N=function(a){this.ta?this.ta.N(a):this.Pa.push(a)};var Hc=function(a,b){this.j=a;this.Zb=b};Hc.prototype.create=function(){return new Gc(this.j,this.Zb)};var Ic=function(a,b){G.call(this);this.sa=a||1;this.M=b||k;this.Ia=q(this.Yb,this);this.Ka=r()};t(Ic,G);h=Ic.prototype;h.enabled=!1;h.e=null;h.Yb=function(){if(this.enabled){var a=r()-this.Ka;0<a&&a<.8*this.sa?this.e=this.M.setTimeout(this.Ia,this.sa-a):(this.e&&(this.M.clearTimeout(this.e),this.e=null),this.dispatchEvent("tick"),this.enabled&&(this.e=this.M.setTimeout(this.Ia,this.sa),this.Ka=r()))}};h.start=function(){this.enabled=!0;this.e||(this.e=this.M.setTimeout(this.Ia,this.sa),this.Ka=r())};
h.stop=function(){this.enabled=!1;this.e&&(this.M.clearTimeout(this.e),this.e=null)};h.k=function(){Ic.J.k.call(this);this.stop();delete this.M};var Jc=function(a,b,c){if(p(a))c&&(a=q(a,c));else if(a&&"function"==typeof a.handleEvent)a=q(a.handleEvent,a);else throw Error("Invalid listener argument");return 2147483647<b?-1:k.setTimeout(a,b||0)};var X=function(a){this.La=a;this.b={}};t(X,ja);var Kc=[];X.prototype.listen=function(a,b,c,d){m(b)||(b&&(Kc[0]=b.toString()),b=Kc);for(var e=0;e<b.length;e++){var f=Va(a,b[e],c||this.handleEvent,d||!1,this.La||this);if(!f)break;this.b[f.key]=f}return this};X.prototype.Ta=function(a,b,c,d){return Lc(this,a,b,c,d)};var Lc=function(a,b,c,d,e,f){if(m(c))for(var g=0;g<c.length;g++)Lc(a,b,c[g],d,e,f);else{b=bb(b,c,d||a.handleEvent,e,f||a.La||a);if(!b)return a;a.b[b.key]=b}return a};
X.prototype.Ma=function(a,b,c,d,e){if(m(b))for(var f=0;f<b.length;f++)this.Ma(a,b[f],c,d,e);else c=c||this.handleEvent,e=e||this.La||this,c=Wa(c),d=!!d,b=Ma(a)?a.T(b,c,d,e):a?(a=Ya(a))?a.T(b,c,d,e):null:null,b&&(db(b),delete this.b[b.key]);return this};X.prototype.removeAll=function(){ra(this.b,db);this.b={}};X.prototype.k=function(){X.J.k.call(this);this.removeAll()};X.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};var Y=function(){G.call(this);this.na=new X(this);Ia&&(Ja?this.na.listen(Ka?document.body:window,["online","offline"],this.ib):(this.jb=Ia?navigator.onLine:!0,this.e=new Ic(250),this.na.listen(this.e,"tick",this.Nb),this.e.start()))};t(Y,G);Y.prototype.Nb=function(){var a=Ia?navigator.onLine:!0;a!=this.jb&&(this.jb=a,this.ib())};Y.prototype.ib=function(){this.dispatchEvent((Ia?navigator.onLine:1)?"online":"offline")};
Y.prototype.k=function(){Y.J.k.call(this);this.na.ra();this.na=null;this.e&&(this.e.ra(),this.e=null)};var Mc=function(a,b){this.j=a;this.A=b};Mc.prototype.send=function(a,b){b.set(hc,this.j.ha);return this.A.send(a,b)};var Nc=function(a){this.A=a};Nc.prototype.send=function(a,b){Oc(b);Pc(b);return this.A.send(a,b)};var Oc=function(a){bc(a,function(b,c){void 0!==b.maxLength&&"text"==b.valueType&&0<b.maxLength&&c.length>b.maxLength&&a.set(b,c.substring(0,b.maxLength))})},Pc=function(a){bc(a,function(b,c){void 0!==b.defaultValue&&c==b.defaultValue&&a.remove(b)})};var Xb={status:"device-offline",ua:void 0},Qc={status:"rate-limited",ua:void 0},Rc={status:"sampled-out",ua:void 0},Sc={status:"sent",ua:void 0};var Tc=function(a,b){this.Mb=a;this.A=b};Tc.prototype.send=function(a,b){var c;c=this.Mb;var d=c.gb(),e=Math.floor((d-c.fb)*c.Hb);0<e&&(c.V=Math.min(c.V+e,c.Jb),c.fb=d);1>c.V?c=!1:(c.V-=1,c=!0);return c||"item"==a||"transaction"==a?this.A.send(a,b):Wb(Qc)};var Uc=function(){this.V=60;this.Jb=500;this.Hb=5E-4;this.gb=function(){return(new Date).getTime()};this.fb=this.gb()};var Vc=function(a,b){this.j=a;this.A=b};Vc.prototype.send=function(a,b){var c=b.get(hc),c=parseInt(c.split("-")[1],16),d;"timing"!=a?d=this.j.Q:((d=b.get(kc))&&b.remove(kc),d||(d=this.j.Q));return c<655.36*d?this.A.send(a,b):Wb(Rc)};var Wc=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/,Xc=B,Yc=function(a,b){if(Xc){Xc=!1;var c=k.location;if(c){var d=c.href;if(d&&(d=(d=Yc(3,d))&&decodeURIComponent(d))&&d!=c.hostname)throw Xc=!0,Error();}}return b.match(Wc)[a]||null};var Zc=function(){};Zc.prototype.qb=null;var ad=function(a){var b;(b=a.qb)||(b={},$c(a)&&(b[0]=!0,b[1]=!0),b=a.qb=b);return b};var bd,cd=function(){};t(cd,Zc);var dd=function(a){return(a=$c(a))?new ActiveXObject(a):new XMLHttpRequest},$c=function(a){if(!a.sb&&"undefined"==typeof XMLHttpRequest&&"undefined"!=typeof ActiveXObject){for(var b=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],c=0;c<b.length;c++){var d=b[c];try{return new ActiveXObject(d),a.sb=d}catch(e){}}throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed");}return a.sb};bd=new cd;var Z=function(a){G.call(this);this.headers=new H;this.aa=a||null;this.D=!1;this.Y=this.a=null;this.X=this.wa="";this.I=this.va=this.W=this.ya=!1;this.$=0;this.Z=null;this.Ua="";this.xa=this.wb=!1};t(Z,G);var ed=/^https?$/i,fd=["POST","PUT"],gd=[],hd=function(a,b,c){var d=new Z;gd.push(d);b&&d.listen("complete",b);d.Ta("ready",d.fc);d.send(a,"POST",c,void 0)};Z.prototype.fc=function(){this.ra();pa(gd,this)};
Z.prototype.send=function(a,b,c,d){if(this.a)throw Error("[goog.net.XhrIo] Object is active with another request="+this.wa+"; newUri="+a);b=b?b.toUpperCase():"GET";this.wa=a;this.X="";this.ya=!1;this.D=!0;this.a=this.aa?dd(this.aa):dd(bd);this.Y=this.aa?ad(this.aa):ad(bd);this.a.onreadystatechange=q(this.Va,this);try{this.va=!0,this.a.open(b,String(a),!0),this.va=!1}catch(e){this.ba(5,e);return}a=c||"";var f=this.headers.clone();d&&ac(d,function(a,b){f.set(b,a)});d=oa(f.B());c=k.FormData&&a instanceof
k.FormData;!(0<=ka(fd,b))||d||c||f.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");f.forEach(function(a,b){this.a.setRequestHeader(b,a)},this);this.Ua&&(this.a.responseType=this.Ua);"withCredentials"in this.a&&(this.a.withCredentials=this.wb);try{id(this),0<this.$&&((this.xa=jd(this.a))?(this.a.timeout=this.$,this.a.ontimeout=q(this.Wa,this)):this.Z=Jc(this.Wa,this.$,this)),this.W=!0,this.a.send(a),this.W=!1}catch(g){this.ba(5,g)}};
var jd=function(a){return z&&C(9)&&"number"==typeof a.timeout&&void 0!==a.ontimeout},na=function(a){return"content-type"==a.toLowerCase()};Z.prototype.Wa=function(){"undefined"!=typeof aa&&this.a&&(this.X="Timed out after "+this.$+"ms, aborting",this.dispatchEvent("timeout"),this.abort(8))};Z.prototype.ba=function(a,b){this.D=!1;this.a&&(this.I=!0,this.a.abort(),this.I=!1);this.X=b;kd(this);ld(this)};var kd=function(a){a.ya||(a.ya=!0,a.dispatchEvent("complete"),a.dispatchEvent("error"))};
Z.prototype.abort=function(){this.a&&this.D&&(this.D=!1,this.I=!0,this.a.abort(),this.I=!1,this.dispatchEvent("complete"),this.dispatchEvent("abort"),ld(this))};Z.prototype.k=function(){this.a&&(this.D&&(this.D=!1,this.I=!0,this.a.abort(),this.I=!1),ld(this,!0));Z.J.k.call(this)};Z.prototype.Va=function(){this.Na||(this.va||this.W||this.I?md(this):this.Xb())};Z.prototype.Xb=function(){md(this)};
var md=function(a){if(a.D&&"undefined"!=typeof aa&&(!a.Y[1]||4!=nd(a)||2!=od(a)))if(a.W&&4==nd(a))Jc(a.Va,0,a);else if(a.dispatchEvent("readystatechange"),4==nd(a)){a.D=!1;try{var b=od(a),c,d;t:switch(b){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:d=!0;break t;default:d=!1}if(!(c=d)){var e;if(e=0===b){var f=Yc(1,String(a.wa));if(!f&&self.location)var g=self.location.protocol,f=g.substr(0,g.length-1);e=!ed.test(f?f.toLowerCase():"")}c=e}if(c)a.dispatchEvent("complete"),a.dispatchEvent("success");
else{var l;try{l=2<nd(a)?a.a.statusText:""}catch(J){l=""}a.X=l+" ["+od(a)+"]";kd(a)}}finally{ld(a)}}},ld=function(a,b){if(a.a){id(a);var c=a.a,d=a.Y[0]?ba:null;a.a=null;a.Y=null;b||a.dispatchEvent("ready");try{c.onreadystatechange=d}catch(e){}}},id=function(a){a.a&&a.xa&&(a.a.ontimeout=null);"number"==typeof a.Z&&(k.clearTimeout(a.Z),a.Z=null)},nd=function(a){return a.a?a.a.readyState:0},od=function(a){try{return 2<nd(a)?a.a.status:-1}catch(b){return-1}};var pd=function(a,b,c){this.r=a||null;this.ac=!!c},qd=function(a){if(!a.c&&(a.c=new H,a.g=0,a.r))for(var b=a.r.split("&"),c=0;c<b.length;c++){var d=b[c].indexOf("="),e=null,f=null;0<=d?(e=b[c].substring(0,d),f=b[c].substring(d+1)):e=b[c];e=decodeURIComponent(e.replace(/\+/g," "));e=$(a,e);a.add(e,f?decodeURIComponent(f.replace(/\+/g," ")):"")}};h=pd.prototype;h.c=null;h.g=null;h.add=function(a,b){qd(this);this.r=null;a=$(this,a);var c=this.c.get(a);c||this.c.set(a,c=[]);c.push(b);this.g++;return this};
h.remove=function(a){qd(this);a=$(this,a);return this.c.S(a)?(this.r=null,this.g-=this.c.get(a).length,this.c.remove(a)):!1};h.S=function(a){qd(this);a=$(this,a);return this.c.S(a)};h.B=function(){qd(this);for(var a=this.c.p(),b=this.c.B(),c=[],d=0;d<b.length;d++)for(var e=a[d],f=0;f<e.length;f++)c.push(b[d]);return c};h.p=function(a){qd(this);var b=[];if(n(a))this.S(a)&&(b=qa(b,this.c.get($(this,a))));else{a=this.c.p();for(var c=0;c<a.length;c++)b=qa(b,a[c])}return b};
h.set=function(a,b){qd(this);this.r=null;a=$(this,a);this.S(a)&&(this.g-=this.c.get(a).length);this.c.set(a,[b]);this.g++;return this};h.get=function(a,b){var c=a?this.p(a):[];return 0<c.length?String(c[0]):b};h.toString=function(){if(this.r)return this.r;if(!this.c)return"";for(var a=[],b=this.c.B(),c=0;c<b.length;c++)for(var d=b[c],e=encodeURIComponent(String(d)),d=this.p(d),f=0;f<d.length;f++){var g=e;""!==d[f]&&(g+="="+encodeURIComponent(String(d[f])));a.push(g)}return this.r=a.join("&")};
h.clone=function(){var a=new pd;a.r=this.r;this.c&&(a.c=this.c.clone(),a.g=this.g);return a};var $=function(a,b){var c=String(b);a.ac&&(c=c.toLowerCase());return c};var rd=function(a,b){this.Lb=a;this.ia=b};rd.prototype.send=function(a,b){if(Ia&&!navigator.onLine)return Yb();var c=new M,d=sd(a,b);d.length>this.ia?c.v({status:"payload-too-big",ua:Zb("Encoded hit length == %s, but should be <= %s.",d.length,this.ia)}):hd(this.Lb,function(){c.F(Sc)},d);return c};var sd=function(a,b){var c=new pd;c.add(nb.name,a);bc(b,function(a,b){c.add(a.name,b.toString())});return c.toString()};var td=function(a,b,c){this.j=a;this.Cb=b;this.ia=c};td.prototype.Ja=function(){if(!this.q){var a=this.j;if(!Rb(a.ca).C)throw Error("Cannot construct shared channel prior to settings being ready.");new Y;var b=new Nc(new rd(this.Cb,this.ia)),c=new Uc;this.q=new Mc(a,new Vc(a,new Tc(c,b)))}return this.q};var ud=new H,vd=function(){if(!lb){var a=new Ec("google-analytics");lb=new V(a)}return lb};s("goog.async.Deferred",M);s("goog.async.Deferred.prototype.addCallback",M.prototype.H);s("goog.events.EventTarget",G);s("goog.events.EventTarget.prototype.listen",G.prototype.listen);s("analytics.getService",function(a){var b=ud.get(a,null);if(null===b){var b=chrome.runtime.getManifest().version,c=vd();if(!mb){var d=vd();mb=new Hc(d,new td(d,"https://www.google-analytics.com/collect",8192))}b=new U("ca1.5.0",a,b,c,mb);ud.set(a,b)}return b});s("analytics.internal.GoogleAnalyticsService",U);
s("analytics.internal.GoogleAnalyticsService.prototype.getTracker",U.prototype.nc);s("analytics.internal.GoogleAnalyticsService.prototype.getConfig",U.prototype.kc);s("analytics.internal.ServiceSettings",V);s("analytics.internal.ServiceSettings.prototype.setTrackingPermitted",V.prototype.tc);s("analytics.internal.ServiceSettings.prototype.isTrackingPermitted",V.prototype.pa);s("analytics.internal.ServiceSettings.prototype.setSampleRate",V.prototype.sc);s("analytics.internal.ServiceTracker",T);
s("analytics.internal.ServiceTracker.prototype.send",T.prototype.send);s("analytics.internal.ServiceTracker.prototype.sendAppView",T.prototype.oc);s("analytics.internal.ServiceTracker.prototype.sendEvent",T.prototype.pc);s("analytics.internal.ServiceTracker.prototype.sendSocial",T.prototype.rc);s("analytics.internal.ServiceTracker.prototype.sendException",T.prototype.qc);s("analytics.internal.ServiceTracker.prototype.sendTiming",T.prototype.ob);
s("analytics.internal.ServiceTracker.prototype.startTiming",T.prototype.uc);s("analytics.internal.ServiceTracker.Timing",sc);s("analytics.internal.ServiceTracker.Timing.prototype.send",sc.prototype.send);s("analytics.internal.ServiceTracker.prototype.forceSessionStart",T.prototype.jc);s("analytics.internal.ServiceTracker.prototype.addFilter",T.prototype.N);s("analytics.internal.FilterChannel.Hit",Q);s("analytics.internal.FilterChannel.Hit.prototype.getHitType",Q.prototype.lc);
s("analytics.internal.FilterChannel.Hit.prototype.getParameters",Q.prototype.mc);s("analytics.internal.FilterChannel.Hit.prototype.cancel",Q.prototype.cancel);s("analytics.ParameterMap",P);s("analytics.ParameterMap.Entry",P.Entry);s("analytics.ParameterMap.prototype.set",P.prototype.set);s("analytics.ParameterMap.prototype.get",P.prototype.get);s("analytics.ParameterMap.prototype.remove",P.prototype.remove);s("analytics.ParameterMap.prototype.toObject",P.prototype.vb);
s("analytics.HitTypes.APPVIEW","appview");s("analytics.HitTypes.EVENT","event");s("analytics.HitTypes.SOCIAL","social");s("analytics.HitTypes.TRANSACTION","transaction");s("analytics.HitTypes.ITEM","item");s("analytics.HitTypes.TIMING","timing");s("analytics.HitTypes.EXCEPTION","exception");ra(qb,function(a){var b=a.id.replace(/[A-Z]/,"_$&").toUpperCase();s("analytics.Parameters."+b,a)}); })()
var S=function(a,b){this.ja=[];this.hb=a;this.gb=b||null;this.W=this.C=!1;this.v=void 0;this.Ka=this.Lb=this.Ja=!1;this.ka=0;this.o=null;this.Ia=0};S.prototype.cancel=function(a){if(this.C)this.v instanceof S&&this.v.cancel();else{if(this.o){var b=this.o;delete this.o;a?b.cancel(a):(b.Ia--,0>=b.Ia&&b.cancel())}this.hb?this.hb.call(this.gb,this):this.Ka=!0;this.C||this.w(new dc)}};S.prototype.ib=function(a,b){this.Ja=!1;ec(this,a,b)};
var ec=function(a,b,c){a.C=!0;a.v=c;a.W=!b;fc(a)},hc=function(a){if(a.C){if(!a.Ka)throw new gc;a.Ka=!1}};S.prototype.G=function(a){hc(this);ec(this,!0,a)};S.prototype.w=function(a){hc(this);ec(this,!1,a)};S.prototype.J=function(a,b){return ic(this,a,null,b)};var ic=function(a,b,c,d){a.ja.push([b,c,d]);a.C&&fc(a);return a};S.prototype.then=function(a,b,c){var d,e,f=new R(function(a,b){d=a;e=b});ic(this,d,function(a){a instanceof dc?f.cancel():e(a)});return f.then(a,b,c)};Sb(S);
var jc=function(a){var b=new S;ic(a,b.G,b.w,b);return b},kc=function(a){return la(a.ja,function(a){return p(a[1])})},fc=function(a){if(a.ka&&a.C&&kc(a)){var b=a.ka,c=lc[b];c&&(h.clearTimeout(c.ma),delete lc[b]);a.ka=0}a.o&&(a.o.Ia--,delete a.o);for(var b=a.v,d=c=!1;a.ja.length&&!a.Ja;){var e=a.ja.shift(),f=e[0],k=e[1],e=e[2];if(f=a.W?k:f)try{var l=f.call(e||a.gb,b);void 0!==l&&(a.W=a.W&&(l==b||l instanceof Error),a.v=b=l);Tb(b)&&(d=!0,a.Ja=!0)}catch(N){b=N,a.W=!0,kc(a)||(c=!0)}}a.v=b;d&&(l=r(a.ib,
a,!0),d=r(a.ib,a,!1),b instanceof S?(ic(b,l,d),b.Lb=!0):b.then(l,d));c&&(b=new mc(b),lc[b.ma]=b,a.ka=b.ma)},nc=function(a){var b=new S;b.G(a);return b},pc=function(){var a=oc,b=new S;b.w(a);return b},gc=function(){v.call(this)};u(gc,v);gc.prototype.message="Deferred has already fired";gc.prototype.name="AlreadyCalledError";var dc=function(){v.call(this)};u(dc,v);dc.prototype.message="Deferred was canceled";dc.prototype.name="CanceledError";
var mc=function(a){this.ma=h.setTimeout(r(this.pc,this),0);this.ga=a};mc.prototype.pc=function(){delete lc[this.ma];throw this.ga;};var lc={};var qc=function(a){this.$a=[];this.e=a};qc.prototype.S=function(a){if(!p(a))throw Error("Invalid filter. Must be a function.");this.$a.push(a)};qc.prototype.send=function(a,b){for(var c=new T(a,b),d=0;d<this.$a.length&&(this.$a[d](c),!c.Za);d++);return c.Za?nc():this.e.send(a,b)};var T=function(a,b){this.rc=a;this.qc=b;this.Za=!1};T.prototype.Gb=function(){return this.rc};T.prototype.T=function(){return this.qc};T.prototype.cancel=function(){this.Za=!0};var rc=function(a,b){this.width=a;this.height=b};rc.prototype.clone=function(){return new rc(this.width,this.height)};rc.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};!K&&!I||I&&I&&9<=db||K&&M("1.9.1");I&&M("9");var sc={id:"apiVersion",name:"v",valueType:"text",maxLength:void 0,defaultValue:void 0},tc={id:"appName",name:"an",valueType:"text",maxLength:100,defaultValue:void 0},uc={id:"appVersion",name:"av",valueType:"text",maxLength:100,defaultValue:void 0},vc={id:"clientId",name:"cid",valueType:"text",maxLength:void 0,defaultValue:void 0},wc={id:"language",name:"ul",valueType:"text",maxLength:20,defaultValue:void 0},xc={id:"libVersion",name:"_v",valueType:"text",maxLength:void 0,defaultValue:void 0},yc={id:"sampleRateOverride",
name:"usro",valueType:"integer",maxLength:void 0,defaultValue:void 0},zc={id:"screenColors",name:"sd",valueType:"text",maxLength:20,defaultValue:void 0},Ac={id:"screenResolution",name:"sr",valueType:"text",maxLength:20,defaultValue:void 0},Bc={id:"trackingId",name:"tid",valueType:"text",maxLength:void 0,defaultValue:void 0},Cc={id:"viewportSize",name:"vp",valueType:"text",maxLength:20,defaultValue:void 0},Dc={Rc:sc,Uc:tc,Vc:uc,cd:vc,vd:wc,wd:xc,Cd:yc,Dd:zc,Ed:Ac,Qd:Bc,Xd:Cc},Fc=function(a){if(!n(a))return a;
var b=Ec(a,Ka);if(q(b))return b;b=Ec(a,Dc);if(q(b))return b;b=/^dimension(\d+)$/.exec(a);if(null!==b)return La(parseInt(b[1],10));b=/^metric(\d+)$/.exec(a);if(null!==b)return Ma(parseInt(b[1],10));throw Error(a+" is not a valid parameter name.");},Ec=function(a,b){var c=xa(b,function(b){return b.id==a&&"metric"!=a&&"dimension"!=a});return q(c)?c:null};var W=function(a,b){this.Zb=b;this.q=b.Sa();this.sb=new C;this.Ya=!1};g=W.prototype;g.set=function(a,b){var c=Fc(a);this.sb.set(c,b)};g.S=function(a){this.Zb.S(a)};g.send=function(a,b){if(a instanceof D)return a.send(this);var c=this.sb.clone();b instanceof C?c.ia(b):q(b)&&ua(b,function(a,b){null!=a&&c.set(Fc(b),a)},this);this.Ya&&(this.Ya=!1,c.set(Ea,"start"));return this.q.send(a,c)};g.Gc=function(a){var b={description:a};this.set(Fa,a);return this.send("appview",b)};
g.Hc=function(a,b,c,d){return this.send("event",{eventCategory:a,eventAction:b,eventLabel:c,eventValue:d})};g.Jc=function(a,b,c){return this.send("social",{socialNetwork:a,socialAction:b,socialTarget:c})};g.Ic=function(a,b){return this.send("exception",{exDescription:a,exFatal:b})};g.Cb=function(a,b,c,d,e){return this.send("timing",{timingCategory:a,timingVar:b,timingLabel:d,timingValue:c,sampleRateOverride:e})};g.Ac=function(){this.Ya=!0};g.Mc=function(a,b,c,d){return new Gc(this,a,b,c,d)};
var Gc=function(a,b,c,d,e){this.yb=a;this.bc=b;this.ec=c;this.cc=d;this.V=e;this.dc=s()};Gc.prototype.send=function(){var a=this.yb.Cb(this.bc,this.ec,s()-this.dc,this.cc,this.V);this.yb=null;return a};var Hc=function(a,b,c,d,e){this.ic=a;this.fc=b;this.gc=c;this.k=d;this.hc=e};
Hc.prototype.Cc=function(a){var b=new W(0,this.hc.create());b.set(xc,this.ic);b.set(sc,1);b.set(tc,this.fc);b.set(uc,this.gc);b.set(Bc,a);a=window.navigator.language;b.set(wc,a);a=screen.colorDepth+"-bit";b.set(zc,a);a=[screen.width,screen.height].join("x");b.set(Ac,a);a=window.document;a="CSS1Compat"==a.compatMode?a.documentElement:a.body;a=new rc(a.clientWidth,a.clientHeight);a=[a.width,a.height].join("x");b.set(Cc,a);return b};Hc.prototype.Bc=function(){return jc(this.k.ha)};var Ic=function(a){this.sc=a};Ic.prototype.send=function(a,b){this.sc.push({Ub:a,Vb:b});return nc()};var Jc=function(a,b,c){this.k=a;this.ra=[];this.M={enabled:new Ic(this.ra),disabled:c};this.q=this.M.enabled;ic(jc(this.k.ha),ha(this.Pb,b),this.Ob,this)};Jc.prototype.Pb=function(a){this.M.enabled=a();Kc(this);ka(this.ra,function(a){this.send(a.Ub,a.Vb)},this);this.ra=null;Lc(this.k,r(this.Xb,this))};Jc.prototype.Ob=function(){this.q=this.M.enabled=this.M.disabled;this.ra=null};Jc.prototype.send=function(a,b){return this.q.send(a,b)};var Kc=function(a){a.q=a.k.va()?a.M.enabled:a.M.disabled};
Jc.prototype.Xb=function(a){switch(a){case "analytics.tracking-permitted":Kc(this)}};var Mc=function(a,b,c,d,e,f){S.call(this,e,f);this.Na=a;this.Oa=[];this.lb=!!b;this.Nb=!!c;this.Mb=!!d;for(b=this.mb=0;b<a.length;b++)ic(a[b],r(this.rb,this,b,!0),r(this.rb,this,b,!1));0!=a.length||this.lb||this.G(this.Oa)};u(Mc,S);Mc.prototype.rb=function(a,b,c){this.mb++;this.Oa[a]=[b,c];this.C||(this.lb&&b?this.G([a,c]):this.Nb&&!b?this.w(c):this.mb==this.Na.length&&this.G(this.Oa));this.Mb&&!b&&(c=null);return c};Mc.prototype.w=function(a){Mc.L.w.call(this,a);for(a=0;a<this.Na.length;a++)this.Na[a].cancel()};
var Nc=function(a){return(new Mc(a,!1,!0)).J(function(a){for(var c=[],d=0;d<a.length;d++)c[d]=a[d][1];return c})};var X=function(a){this.H=a;this.V=100;this.nb=[];this.Pa=this.la=null;this.ha=Oc(this);this.ha.J(function(){tb(this.H,"a",r(this.Rb,this))},this)},Oc=function(a){return Pc(a).J(function(){return this},a)},Pc=function(a){return Nc([Qc(a),Rc(a)])};X.prototype.Rb=function(){var a=this.la,b=this.va();Pc(this).J(function(){if(a!=this.la)throw Error("User ID changed unexpectedly!");b!=this.va()&&Sc(this)},this)};var Lc=function(a,b){a.nb.push(b)};
X.prototype.Lc=function(a){this.H.set("analytics.tracking-permitted",a).J(function(){this.Pa=a},this)};X.prototype.va=function(){var a;if(a=this.Pa)a=h._gaUserPrefs,a=!(a&&a.ioo&&a.ioo());return a};
var Qc=function(a){return a.H.get("analytics.tracking-permitted").J(function(a){this.Pa=void 0!==a?a:!0},a)},Rc=function(a){return a.H.get("analytics.user-id").J(function(a){if(!a){a="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".split("");for(var c=0,d=a.length;c<d;c++)switch(a[c]){case "x":a[c]=Math.floor(16*Math.random()).toString(16);break;case "y":a[c]=(Math.floor(4*Math.random())+8).toString(16)}a=a.join("");this.H.set("analytics.user-id",a)}this.la=a},a)};X.prototype.Kc=function(a){this.V=a};
var Sc=function(a){ka(a.nb,function(a){a("analytics.tracking-permitted")})};var Tc=function(a){Q.call(this);this.Wa=a;this.H=chrome.storage.local;chrome.storage.onChanged.addListener(r(this.nc,this))};u(Tc,Q);Tc.prototype.nc=function(a){Uc(this,a)&&this.dispatchEvent("a")};var Uc=function(a,b){return la(wa(b),function(a){return 0==a.lastIndexOf(this.Wa,0)},a)};Tc.prototype.get=function(a){var b=new S,c=this.Wa+"."+a;this.H.get(c,function(a){var e=chrome.runtime.lastError;e?b.w(e):b.G(a[c])});return b};
Tc.prototype.set=function(a,b){var c=new S,d={};d[this.Wa+"."+a]=b;this.H.set(d,function(){var a=chrome.runtime.lastError;a?c.w(a):c.G()});return c};var Y=function(){};Y.Yb=function(){return Y.Ib?Y.Ib:Y.Ib=new Y};Y.prototype.send=function(){return nc()};var Vc=function(a,b){this.Xa=[];var c=r(function(){this.Aa=new qc(b.Sa());ka(this.Xa,function(a){this.Aa.S(a)},this);this.Xa=null;return this.Aa},this);this.q=new Jc(a,c,Y.Yb())};Vc.prototype.Sa=function(){return this.q};Vc.prototype.S=function(a){this.Aa?this.Aa.S(a):this.Xa.push(a)};var Wc=function(a,b){this.k=a;this.mc=b};Wc.prototype.create=function(){return new Vc(this.k,this.mc)};var Xc=function(a,b){Q.call(this);this.ya=a||1;this.R=b||h;this.Ra=r(this.lc,this);this.Ta=s()};u(Xc,Q);g=Xc.prototype;g.enabled=!1;g.g=null;g.lc=function(){if(this.enabled){var a=s()-this.Ta;0<a&&a<.8*this.ya?this.g=this.R.setTimeout(this.Ra,this.ya-a):(this.g&&(this.R.clearTimeout(this.g),this.g=null),this.dispatchEvent("tick"),this.enabled&&(this.g=this.R.setTimeout(this.Ra,this.ya),this.Ta=s()))}};g.start=function(){this.enabled=!0;this.g||(this.g=this.R.setTimeout(this.Ra,this.ya),this.Ta=s())};
g.stop=function(){this.enabled=!1;this.g&&(this.R.clearTimeout(this.g),this.g=null)};g.l=function(){Xc.L.l.call(this);this.stop();delete this.R};var Yc=function(a,b,c){if(p(a))c&&(a=r(a,c));else if(a&&"function"==typeof a.handleEvent)a=r(a.handleEvent,a);else throw Error("Invalid listener argument");return 2147483647<b?-1:h.setTimeout(a,b||0)};var Z=function(a){E.call(this);this.Ua=a;this.b={}};u(Z,E);var Zc=[];Z.prototype.listen=function(a,b,c,d){m(b)||(b&&(Zc[0]=b.toString()),b=Zc);for(var e=0;e<b.length;e++){var f=tb(a,b[e],c||this.handleEvent,d||!1,this.Ua||this);if(!f)break;this.b[f.key]=f}return this};Z.prototype.bb=function(a,b,c,d){return $c(this,a,b,c,d)};var $c=function(a,b,c,d,e,f){if(m(c))for(var k=0;k<c.length;k++)$c(a,b,c[k],d,e,f);else{b=Ab(b,c,d||a.handleEvent,e,f||a.Ua||a);if(!b)return a;a.b[b.key]=b}return a};
Z.prototype.Va=function(a,b,c,d,e){if(m(b))for(var f=0;f<b.length;f++)this.Va(a,b[f],c,d,e);else c=c||this.handleEvent,e=e||this.Ua||this,c=ub(c),d=!!d,b=kb(a)?a.X(b,c,d,e):a?(a=wb(a))?a.X(b,c,d,e):null:null,b&&(Cb(b),delete this.b[b.key]);return this};Z.prototype.removeAll=function(){ua(this.b,Cb);this.b={}};Z.prototype.l=function(){Z.L.l.call(this);this.removeAll()};Z.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};var ad=function(){Q.call(this);this.ta=new Z(this);gb&&(hb?this.ta.listen(ib?document.body:window,["online","offline"],this.tb):(this.ub=gb?navigator.onLine:!0,this.g=new Xc(250),this.ta.listen(this.g,"tick",this.ac),this.g.start()))};u(ad,Q);ad.prototype.ac=function(){var a=gb?navigator.onLine:!0;a!=this.ub&&(this.ub=a,this.tb())};ad.prototype.tb=function(){this.dispatchEvent((gb?navigator.onLine:1)?"online":"offline")};
ad.prototype.l=function(){ad.L.l.call(this);this.ta.xa();this.ta=null;this.g&&(this.g.xa(),this.g=null)};var bd=function(a,b){this.k=a;this.e=b};bd.prototype.send=function(a,b){b.set(vc,this.k.la);return this.e.send(a,b)};var cd=function(a){this.e=a};cd.prototype.send=function(a,b){dd(b);ed(b);return this.e.send(a,b)};var dd=function(a){Ua(a,function(b,c){void 0!==b.maxLength&&"text"==b.valueType&&0<b.maxLength&&c.length>b.maxLength&&a.set(b,c.substring(0,b.maxLength))})},ed=function(a){Ua(a,function(b,c){void 0!==b.defaultValue&&c==b.defaultValue&&a.remove(b)})};var oc={status:"device-offline",Ba:void 0},fd={status:"rate-limited",Ba:void 0},gd={status:"sampled-out",Ba:void 0},hd={status:"sent",Ba:void 0};var id=function(a,b){this.Wb=a;this.e=b};id.prototype.send=function(a,b){var c;c=this.Wb;var d=c.pb(),e=Math.floor((d-c.ob)*c.Sb);0<e&&(c.$=Math.min(c.$+e,c.Tb),c.ob=d);1>c.$?c=!1:(c.$-=1,c=!0);return c||"item"==a||"transaction"==a?this.e.send(a,b):nc(fd)};var jd=function(){this.$=60;this.Tb=500;this.Sb=5E-4;this.pb=function(){return(new Date).getTime()};this.ob=this.pb()};var kd=function(a,b){this.k=a;this.e=b};kd.prototype.send=function(a,b){var c=b.get(vc),c=parseInt(c.split("-")[1],16),d;"timing"!=a?d=this.k.V:((d=b.get(yc))&&b.remove(yc),d||(d=this.k.V));return c<655.36*d?this.e.send(a,b):nc(gd)};var ld=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/,md=L,nd=function(a,b){if(md){md=!1;var c=h.location;if(c){var d=c.href;if(d&&(d=(d=nd(3,d))?decodeURI(d):d)&&d!=c.hostname)throw md=!0,Error();}}return b.match(ld)[a]||null};var od=function(){};od.prototype.Eb=null;var qd=function(a){var b;(b=a.Eb)||(b={},pd(a)&&(b[0]=!0,b[1]=!0),b=a.Eb=b);return b};var rd,sd=function(){};u(sd,od);var td=function(a){return(a=pd(a))?new ActiveXObject(a):new XMLHttpRequest},pd=function(a){if(!a.Hb&&"undefined"==typeof XMLHttpRequest&&"undefined"!=typeof ActiveXObject){for(var b=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],c=0;c<b.length;c++){var d=b[c];try{return new ActiveXObject(d),a.Hb=d}catch(e){}}throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed");}return a.Hb};rd=new sd;var $=function(a){Q.call(this);this.headers=new x;this.fa=a||null;this.D=!1;this.ca=this.a=null;this.ba=this.Fa="";this.K=this.Ea=this.aa=this.Ha=!1;this.ea=0;this.da=null;this.cb="";this.Ga=this.Kb=!1};u($,Q);var ud=/^https?$/i,vd=["POST","PUT"],wd=[],xd=function(a,b,c){var d=new $;wd.push(d);b&&d.listen("complete",b);d.bb("ready",d.tc);d.send(a,"POST",c,void 0)};$.prototype.tc=function(){this.xa();pa(wd,this)};
$.prototype.send=function(a,b,c,d){if(this.a)throw Error("[goog.net.XhrIo] Object is active with another request="+this.Fa+"; newUri="+a);b=b?b.toUpperCase():"GET";this.Fa=a;this.ba="";this.Ha=!1;this.D=!0;this.a=this.fa?td(this.fa):td(rd);this.ca=this.fa?qd(this.fa):qd(rd);this.a.onreadystatechange=r(this.eb,this);try{this.Ea=!0,this.a.open(b,String(a),!0),this.Ea=!1}catch(e){this.ga(5,e);return}a=c||"";var f=this.headers.clone();d&&Ta(d,function(a,b){f.set(b,a)});d=oa(f.F());c=h.FormData&&a instanceof
h.FormData;!(0<=ja(vd,b))||d||c||f.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");f.forEach(function(a,b){this.a.setRequestHeader(b,a)},this);this.cb&&(this.a.responseType=this.cb);"withCredentials"in this.a&&(this.a.withCredentials=this.Kb);try{yd(this),0<this.ea&&((this.Ga=zd(this.a))?(this.a.timeout=this.ea,this.a.ontimeout=r(this.fb,this)):this.da=Yc(this.fb,this.ea,this)),this.aa=!0,this.a.send(a),this.aa=!1}catch(k){this.ga(5,k)}};
var zd=function(a){return I&&M(9)&&ea(a.timeout)&&void 0!==a.ontimeout},na=function(a){return"content-type"==a.toLowerCase()};$.prototype.fb=function(){"undefined"!=typeof aa&&this.a&&(this.ba="Timed out after "+this.ea+"ms, aborting",this.dispatchEvent("timeout"),this.abort(8))};$.prototype.ga=function(a,b){this.D=!1;this.a&&(this.K=!0,this.a.abort(),this.K=!1);this.ba=b;Ad(this);Bd(this)};var Ad=function(a){a.Ha||(a.Ha=!0,a.dispatchEvent("complete"),a.dispatchEvent("error"))};
$.prototype.abort=function(){this.a&&this.D&&(this.D=!1,this.K=!0,this.a.abort(),this.K=!1,this.dispatchEvent("complete"),this.dispatchEvent("abort"),Bd(this))};$.prototype.l=function(){this.a&&(this.D&&(this.D=!1,this.K=!0,this.a.abort(),this.K=!1),Bd(this,!0));$.L.l.call(this)};$.prototype.eb=function(){this.Y||(this.Ea||this.aa||this.K?Cd(this):this.jc())};$.prototype.jc=function(){Cd(this)};
var Cd=function(a){if(a.D&&"undefined"!=typeof aa&&(!a.ca[1]||4!=Dd(a)||2!=Ed(a)))if(a.aa&&4==Dd(a))Yc(a.eb,0,a);else if(a.dispatchEvent("readystatechange"),4==Dd(a)){a.D=!1;try{var b=Ed(a),c,d;t:switch(b){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:d=!0;break t;default:d=!1}if(!(c=d)){var e;if(e=0===b){var f=nd(1,String(a.Fa));if(!f&&self.location)var k=self.location.protocol,f=k.substr(0,k.length-1);e=!ud.test(f?f.toLowerCase():"")}c=e}if(c)a.dispatchEvent("complete"),a.dispatchEvent("success");
else{var l;try{l=2<Dd(a)?a.a.statusText:""}catch(N){l=""}a.ba=l+" ["+Ed(a)+"]";Ad(a)}}finally{Bd(a)}}},Bd=function(a,b){if(a.a){yd(a);var c=a.a,d=a.ca[0]?ba:null;a.a=null;a.ca=null;b||a.dispatchEvent("ready");try{c.onreadystatechange=d}catch(e){}}},yd=function(a){a.a&&a.Ga&&(a.a.ontimeout=null);ea(a.da)&&(h.clearTimeout(a.da),a.da=null)},Dd=function(a){return a.a?a.a.readyState:0},Ed=function(a){try{return 2<Dd(a)?a.a.status:-1}catch(b){return-1}};var Fd=function(a,b,c){this.r=a||null;this.oc=!!c},Hd=function(a){if(!a.c&&(a.c=new x,a.h=0,a.r))for(var b=a.r.split("&"),c=0;c<b.length;c++){var d=b[c].indexOf("="),e=null,f=null;0<=d?(e=b[c].substring(0,d),f=b[c].substring(d+1)):e=b[c];e=decodeURIComponent(e.replace(/\+/g," "));e=Gd(a,e);a.add(e,f?decodeURIComponent(f.replace(/\+/g," ")):"")}};g=Fd.prototype;g.c=null;g.h=null;g.add=function(a,b){Hd(this);this.r=null;a=Gd(this,a);var c=this.c.get(a);c||this.c.set(a,c=[]);c.push(b);this.h++;return this};
g.remove=function(a){Hd(this);a=Gd(this,a);return this.c.Q(a)?(this.r=null,this.h-=this.c.get(a).length,this.c.remove(a)):!1};g.Q=function(a){Hd(this);a=Gd(this,a);return this.c.Q(a)};g.F=function(){Hd(this);for(var a=this.c.t(),b=this.c.F(),c=[],d=0;d<b.length;d++)for(var e=a[d],f=0;f<e.length;f++)c.push(b[d]);return c};g.t=function(a){Hd(this);var b=[];if(n(a))this.Q(a)&&(b=qa(b,this.c.get(Gd(this,a))));else{a=this.c.t();for(var c=0;c<a.length;c++)b=qa(b,a[c])}return b};
g.set=function(a,b){Hd(this);this.r=null;a=Gd(this,a);this.Q(a)&&(this.h-=this.c.get(a).length);this.c.set(a,[b]);this.h++;return this};g.get=function(a,b){var c=a?this.t(a):[];return 0<c.length?String(c[0]):b};g.toString=function(){if(this.r)return this.r;if(!this.c)return"";for(var a=[],b=this.c.F(),c=0;c<b.length;c++)for(var d=b[c],e=encodeURIComponent(String(d)),d=this.t(d),f=0;f<d.length;f++){var k=e;""!==d[f]&&(k+="="+encodeURIComponent(String(d[f])));a.push(k)}return this.r=a.join("&")};
g.clone=function(){var a=new Fd;a.r=this.r;this.c&&(a.c=this.c.clone(),a.h=this.h);return a};var Gd=function(a,b){var c=String(b);a.oc&&(c=c.toLowerCase());return c};var Id=function(a,b){this.$b=a;this.na=b};Id.prototype.send=function(a,b){if(gb&&!navigator.onLine)return pc();var c=new S,d=Jd(a,b);d.length>this.na?c.w({status:"payload-too-big",Ba:Ra("Encoded hit length == %s, but should be <= %s.",d.length,this.na)}):xd(this.$b,function(){c.G(hd)},d);return c};var Jd=function(a,b){var c=new Fd;c.add(Da.name,a);Ua(b,function(a,b){c.add(a.name,b.toString())});return c.toString()};var Kd=function(a,b,c){this.k=a;this.Qb=b;this.na=c};Kd.prototype.Sa=function(){if(!this.q){var a=this.k;if(!jc(a.ha).C)throw Error("Cannot construct shared channel prior to settings being ready.");new ad;var b=new cd(new Id(this.Qb,this.na)),c=new jd;this.q=new bd(a,new kd(a,new id(c,b)))}return this.q};var Ld=new x,Md=function(){if(!Ba){var a=new Tc("google-analytics");Ba=new X(a)}return Ba};t("goog.async.Deferred",S);t("goog.async.Deferred.prototype.addCallback",S.prototype.J);t("goog.events.EventTarget",Q);t("goog.events.EventTarget.prototype.listen",Q.prototype.listen);t("analytics.getService",function(a){var b=Ld.get(a,null);if(null===b){var b=chrome.runtime.getManifest().version,c=Md();if(!Ca){var d=Md();Ca=new Wc(d,new Kd(d,"https://www.google-analytics.com/collect",8192))}b=new Hc("ca1.5.2",a,b,c,Ca);Ld.set(a,b)}return b});t("analytics.internal.GoogleAnalyticsService",Hc);
t("analytics.internal.GoogleAnalyticsService.prototype.getTracker",Hc.prototype.Cc);t("analytics.internal.GoogleAnalyticsService.prototype.getConfig",Hc.prototype.Bc);t("analytics.internal.ServiceSettings",X);t("analytics.internal.ServiceSettings.prototype.setTrackingPermitted",X.prototype.Lc);t("analytics.internal.ServiceSettings.prototype.isTrackingPermitted",X.prototype.va);t("analytics.internal.ServiceSettings.prototype.setSampleRate",X.prototype.Kc);t("analytics.internal.ServiceTracker",W);
t("analytics.internal.ServiceTracker.prototype.send",W.prototype.send);t("analytics.internal.ServiceTracker.prototype.sendAppView",W.prototype.Gc);t("analytics.internal.ServiceTracker.prototype.sendEvent",W.prototype.Hc);t("analytics.internal.ServiceTracker.prototype.sendSocial",W.prototype.Jc);t("analytics.internal.ServiceTracker.prototype.sendException",W.prototype.Ic);t("analytics.internal.ServiceTracker.prototype.sendTiming",W.prototype.Cb);
t("analytics.internal.ServiceTracker.prototype.startTiming",W.prototype.Mc);t("analytics.internal.ServiceTracker.Timing",Gc);t("analytics.internal.ServiceTracker.Timing.prototype.send",Gc.prototype.send);t("analytics.internal.ServiceTracker.prototype.forceSessionStart",W.prototype.Ac);t("analytics.internal.ServiceTracker.prototype.addFilter",W.prototype.S);t("analytics.internal.FilterChannel.Hit",T);t("analytics.internal.FilterChannel.Hit.prototype.getHitType",T.prototype.Gb);
t("analytics.internal.FilterChannel.Hit.prototype.getParameters",T.prototype.T);t("analytics.internal.FilterChannel.Hit.prototype.cancel",T.prototype.cancel);t("analytics.ParameterMap",C);t("analytics.ParameterMap.Entry",C.Entry);t("analytics.ParameterMap.prototype.set",C.prototype.set);t("analytics.ParameterMap.prototype.get",C.prototype.get);t("analytics.ParameterMap.prototype.remove",C.prototype.remove);t("analytics.ParameterMap.prototype.toObject",C.prototype.Jb);
t("analytics.HitTypes.APPVIEW","appview");t("analytics.HitTypes.EVENT","event");t("analytics.HitTypes.SOCIAL","social");t("analytics.HitTypes.TRANSACTION","transaction");t("analytics.HitTypes.ITEM","item");t("analytics.HitTypes.TIMING","timing");t("analytics.HitTypes.EXCEPTION","exception");ua(Ka,function(a){var b=a.id.replace(/[A-Z]/,"_$&").toUpperCase();t("analytics.Parameters."+b,a)});t("analytics.filters.EventLabelerBuilder",A);
t("analytics.filters.EventLabelerBuilder.prototype.appendToExistingLabel",A.prototype.wc);t("analytics.filters.EventLabelerBuilder.prototype.stripValue",A.prototype.Nc);t("analytics.filters.EventLabelerBuilder.prototype.powersOfTwo",A.prototype.Ec);t("analytics.filters.EventLabelerBuilder.prototype.rangeBounds",A.prototype.Fc);t("analytics.filters.EventLabelerBuilder.prototype.build",A.prototype.Ca);t("analytics.filters.FilterBuilder",z);t("analytics.filters.FilterBuilder.builder",Pa);
t("analytics.filters.FilterBuilder.prototype.when",z.prototype.when);t("analytics.filters.FilterBuilder.prototype.whenHitType",z.prototype.zb);t("analytics.filters.FilterBuilder.prototype.whenValue",z.prototype.Oc);t("analytics.filters.FilterBuilder.prototype.applyFilter",z.prototype.xb);t("analytics.filters.FilterBuilder.prototype.build",z.prototype.Ca);t("analytics.EventBuilder",D);t("analytics.EventBuilder.builder",function(){return Va});t("analytics.EventBuilder.prototype.category",D.prototype.xc);
t("analytics.EventBuilder.prototype.action",D.prototype.action);t("analytics.EventBuilder.prototype.label",D.prototype.label);t("analytics.EventBuilder.prototype.value",D.prototype.value);t("analytics.EventBuilder.prototype.dimension",D.prototype.yc);t("analytics.EventBuilder.prototype.metric",D.prototype.Dc);t("analytics.EventBuilder.prototype.send",D.prototype.send); })()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,934 @@
/**
* @author mrdoob / http://mrdoob.com/
* @author supereggbert / http://www.paulbrunt.co.uk/
* @author julianwa / https://github.com/julianwa
*/
THREE.RenderableObject = function () {
this.id = 0;
this.object = null;
this.z = 0;
};
//
THREE.RenderableFace = function () {
this.id = 0;
this.v1 = new THREE.RenderableVertex();
this.v2 = new THREE.RenderableVertex();
this.v3 = new THREE.RenderableVertex();
this.normalModel = new THREE.Vector3();
this.vertexNormalsModel = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
this.vertexNormalsLength = 0;
this.color = new THREE.Color();
this.material = null;
this.uvs = [ new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2() ];
this.z = 0;
};
//
THREE.RenderableVertex = function () {
this.position = new THREE.Vector3();
this.positionWorld = new THREE.Vector3();
this.positionScreen = new THREE.Vector4();
this.visible = true;
};
THREE.RenderableVertex.prototype.copy = function ( vertex ) {
this.positionWorld.copy( vertex.positionWorld );
this.positionScreen.copy( vertex.positionScreen );
};
//
THREE.RenderableLine = function () {
this.id = 0;
this.v1 = new THREE.RenderableVertex();
this.v2 = new THREE.RenderableVertex();
this.vertexColors = [ new THREE.Color(), new THREE.Color() ];
this.material = null;
this.z = 0;
};
//
THREE.RenderableSprite = function () {
this.id = 0;
this.object = null;
this.x = 0;
this.y = 0;
this.z = 0;
this.rotation = 0;
this.scale = new THREE.Vector2();
this.material = null;
};
//
THREE.Projector = function () {
var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
_vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
_face, _faceCount, _facePool = [], _facePoolLength = 0,
_line, _lineCount, _linePool = [], _linePoolLength = 0,
_sprite, _spriteCount, _spritePool = [], _spritePoolLength = 0,
_renderData = { objects: [], lights: [], elements: [] },
_vA = new THREE.Vector3(),
_vB = new THREE.Vector3(),
_vC = new THREE.Vector3(),
_vector3 = new THREE.Vector3(),
_vector4 = new THREE.Vector4(),
_clipBox = new THREE.Box3( new THREE.Vector3( - 1, - 1, - 1 ), new THREE.Vector3( 1, 1, 1 ) ),
_boundingBox = new THREE.Box3(),
_points3 = new Array( 3 ),
_points4 = new Array( 4 ),
_viewMatrix = new THREE.Matrix4(),
_viewProjectionMatrix = new THREE.Matrix4(),
_modelMatrix,
_modelViewProjectionMatrix = new THREE.Matrix4(),
_normalMatrix = new THREE.Matrix3(),
_frustum = new THREE.Frustum(),
_clippedVertex1PositionScreen = new THREE.Vector4(),
_clippedVertex2PositionScreen = new THREE.Vector4();
//
this.projectVector = function ( vector, camera ) {
console.warn( 'THREE.Projector: .projectVector() is now vector.project().' );
vector.project( camera );
};
this.unprojectVector = function ( vector, camera ) {
console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );
vector.unproject( camera );
};
this.pickingRay = function ( vector, camera ) {
console.error( 'THREE.Projector: .pickingRay() has been removed.' );
};
//
var RenderList = function () {
var normals = [];
var uvs = [];
var object = null;
var material = null;
var normalMatrix = new THREE.Matrix3();
var setObject = function ( value ) {
object = value;
material = object.material;
normalMatrix.getNormalMatrix( object.matrixWorld );
normals.length = 0;
uvs.length = 0;
};
var projectVertex = function ( vertex ) {
var position = vertex.position;
var positionWorld = vertex.positionWorld;
var positionScreen = vertex.positionScreen;
positionWorld.copy( position ).applyMatrix4( _modelMatrix );
positionScreen.copy( positionWorld ).applyMatrix4( _viewProjectionMatrix );
var invW = 1 / positionScreen.w;
positionScreen.x *= invW;
positionScreen.y *= invW;
positionScreen.z *= invW;
vertex.visible = positionScreen.x >= - 1 && positionScreen.x <= 1 &&
positionScreen.y >= - 1 && positionScreen.y <= 1 &&
positionScreen.z >= - 1 && positionScreen.z <= 1;
};
var pushVertex = function ( x, y, z ) {
_vertex = getNextVertexInPool();
_vertex.position.set( x, y, z );
projectVertex( _vertex );
};
var pushNormal = function ( x, y, z ) {
normals.push( x, y, z );
};
var pushUv = function ( x, y ) {
uvs.push( x, y );
};
var checkTriangleVisibility = function ( v1, v2, v3 ) {
if ( v1.visible === true || v2.visible === true || v3.visible === true ) return true;
_points3[ 0 ] = v1.positionScreen;
_points3[ 1 ] = v2.positionScreen;
_points3[ 2 ] = v3.positionScreen;
return _clipBox.isIntersectionBox( _boundingBox.setFromPoints( _points3 ) );
};
var checkBackfaceCulling = function ( v1, v2, v3 ) {
return ( ( v3.positionScreen.x - v1.positionScreen.x ) *
( v2.positionScreen.y - v1.positionScreen.y ) -
( v3.positionScreen.y - v1.positionScreen.y ) *
( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
};
var pushLine = function ( a, b ) {
var v1 = _vertexPool[ a ];
var v2 = _vertexPool[ b ];
_line = getNextLineInPool();
_line.id = object.id;
_line.v1.copy( v1 );
_line.v2.copy( v2 );
_line.z = ( v1.positionScreen.z + v2.positionScreen.z ) / 2;
_line.material = object.material;
_renderData.elements.push( _line );
};
var pushTriangle = function ( a, b, c ) {
var v1 = _vertexPool[ a ];
var v2 = _vertexPool[ b ];
var v3 = _vertexPool[ c ];
if ( checkTriangleVisibility( v1, v2, v3 ) === false ) return;
if ( material.side === THREE.DoubleSide || checkBackfaceCulling( v1, v2, v3 ) === true ) {
_face = getNextFaceInPool();
_face.id = object.id;
_face.v1.copy( v1 );
_face.v2.copy( v2 );
_face.v3.copy( v3 );
_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
for ( var i = 0; i < 3; i ++ ) {
var offset = arguments[ i ] * 3;
var normal = _face.vertexNormalsModel[ i ];
normal.set( normals[ offset ], normals[ offset + 1 ], normals[ offset + 2 ] );
normal.applyMatrix3( normalMatrix ).normalize();
var offset2 = arguments[ i ] * 2;
var uv = _face.uvs[ i ];
uv.set( uvs[ offset2 ], uvs[ offset2 + 1 ] );
}
_face.vertexNormalsLength = 3;
_face.material = object.material;
_renderData.elements.push( _face );
}
};
return {
setObject: setObject,
projectVertex: projectVertex,
checkTriangleVisibility: checkTriangleVisibility,
checkBackfaceCulling: checkBackfaceCulling,
pushVertex: pushVertex,
pushNormal: pushNormal,
pushUv: pushUv,
pushLine: pushLine,
pushTriangle: pushTriangle
}
};
var renderList = new RenderList();
this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
_faceCount = 0;
_lineCount = 0;
_spriteCount = 0;
_renderData.elements.length = 0;
if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
if ( camera.parent === undefined ) camera.updateMatrixWorld();
_viewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) );
_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
_frustum.setFromMatrix( _viewProjectionMatrix );
//
_objectCount = 0;
_renderData.objects.length = 0;
_renderData.lights.length = 0;
scene.traverseVisible( function ( object ) {
if ( object instanceof THREE.Light ) {
_renderData.lights.push( object );
} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Sprite ) {
if ( object.material.visible === false ) return;
if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
_object = getNextObjectInPool();
_object.id = object.id;
_object.object = object;
if ( object.renderDepth !== null ) {
_object.z = object.renderDepth;
} else {
_vector3.setFromMatrixPosition( object.matrixWorld );
_vector3.applyProjection( _viewProjectionMatrix );
_object.z = _vector3.z;
}
_renderData.objects.push( _object );
}
}
} );
if ( sortObjects === true ) {
_renderData.objects.sort( painterSort );
}
//
for ( var o = 0, ol = _renderData.objects.length; o < ol; o ++ ) {
var object = _renderData.objects[ o ].object;
var geometry = object.geometry;
renderList.setObject( object );
_modelMatrix = object.matrixWorld;
_vertexCount = 0;
if ( object instanceof THREE.Mesh ) {
if ( geometry instanceof THREE.BufferGeometry ) {
var attributes = geometry.attributes;
var offsets = geometry.offsets;
if ( attributes.position === undefined ) continue;
var positions = attributes.position.array;
for ( var i = 0, l = positions.length; i < l; i += 3 ) {
renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
}
if ( attributes.normal !== undefined ) {
var normals = attributes.normal.array;
for ( var i = 0, l = normals.length; i < l; i += 3 ) {
renderList.pushNormal( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] );
}
}
if ( attributes.uv !== undefined ) {
var uvs = attributes.uv.array;
for ( var i = 0, l = uvs.length; i < l; i += 2 ) {
renderList.pushUv( uvs[ i ], uvs[ i + 1 ] );
}
}
if ( attributes.index !== undefined ) {
var indices = attributes.index.array;
if ( offsets.length > 0 ) {
for ( var o = 0; o < offsets.length; o ++ ) {
var offset = offsets[ o ];
var index = offset.index;
for ( var i = offset.start, l = offset.start + offset.count; i < l; i += 3 ) {
renderList.pushTriangle( indices[ i ] + index, indices[ i + 1 ] + index, indices[ i + 2 ] + index );
}
}
} else {
for ( var i = 0, l = indices.length; i < l; i += 3 ) {
renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
}
}
} else {
for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) {
renderList.pushTriangle( i, i + 1, i + 2 );
}
}
} else if ( geometry instanceof THREE.Geometry ) {
var vertices = geometry.vertices;
var faces = geometry.faces;
var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
_normalMatrix.getNormalMatrix( _modelMatrix );
var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
var objectMaterials = isFaceMaterial === true ? object.material : null;
for ( var v = 0, vl = vertices.length; v < vl; v ++ ) {
var vertex = vertices[ v ];
renderList.pushVertex( vertex.x, vertex.y, vertex.z );
}
for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
var face = faces[ f ];
var material = isFaceMaterial === true
? objectMaterials.materials[ face.materialIndex ]
: object.material;
if ( material === undefined ) continue;
var side = material.side;
var v1 = _vertexPool[ face.a ];
var v2 = _vertexPool[ face.b ];
var v3 = _vertexPool[ face.c ];
if ( material.morphTargets === true ) {
var morphTargets = geometry.morphTargets;
var morphInfluences = object.morphTargetInfluences;
var v1p = v1.position;
var v2p = v2.position;
var v3p = v3.position;
_vA.set( 0, 0, 0 );
_vB.set( 0, 0, 0 );
_vC.set( 0, 0, 0 );
for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
var influence = morphInfluences[ t ];
if ( influence === 0 ) continue;
var targets = morphTargets[ t ].vertices;
_vA.x += ( targets[ face.a ].x - v1p.x ) * influence;
_vA.y += ( targets[ face.a ].y - v1p.y ) * influence;
_vA.z += ( targets[ face.a ].z - v1p.z ) * influence;
_vB.x += ( targets[ face.b ].x - v2p.x ) * influence;
_vB.y += ( targets[ face.b ].y - v2p.y ) * influence;
_vB.z += ( targets[ face.b ].z - v2p.z ) * influence;
_vC.x += ( targets[ face.c ].x - v3p.x ) * influence;
_vC.y += ( targets[ face.c ].y - v3p.y ) * influence;
_vC.z += ( targets[ face.c ].z - v3p.z ) * influence;
}
v1.position.add( _vA );
v2.position.add( _vB );
v3.position.add( _vC );
renderList.projectVertex( v1 );
renderList.projectVertex( v2 );
renderList.projectVertex( v3 );
}
if ( renderList.checkTriangleVisibility( v1, v2, v3 ) === false ) continue;
var visible = renderList.checkBackfaceCulling( v1, v2, v3 );
if ( side !== THREE.DoubleSide ) {
if ( side === THREE.FrontSide && visible === false ) continue;
if ( side === THREE.BackSide && visible === true ) continue;
}
_face = getNextFaceInPool();
_face.id = object.id;
_face.v1.copy( v1 );
_face.v2.copy( v2 );
_face.v3.copy( v3 );
_face.normalModel.copy( face.normal );
if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
_face.normalModel.negate();
}
_face.normalModel.applyMatrix3( _normalMatrix ).normalize();
var faceVertexNormals = face.vertexNormals;
for ( var n = 0, nl = Math.min( faceVertexNormals.length, 3 ); n < nl; n ++ ) {
var normalModel = _face.vertexNormalsModel[ n ];
normalModel.copy( faceVertexNormals[ n ] );
if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
normalModel.negate();
}
normalModel.applyMatrix3( _normalMatrix ).normalize();
}
_face.vertexNormalsLength = faceVertexNormals.length;
var vertexUvs = faceVertexUvs[ f ];
if ( vertexUvs !== undefined ) {
for ( var u = 0; u < 3; u ++ ) {
_face.uvs[ u ].copy( vertexUvs[ u ] );
}
}
_face.color = face.color;
_face.material = material;
_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
_renderData.elements.push( _face );
}
}
} else if ( object instanceof THREE.Line ) {
if ( geometry instanceof THREE.BufferGeometry ) {
var attributes = geometry.attributes;
if ( attributes.position !== undefined ) {
var positions = attributes.position.array;
for ( var i = 0, l = positions.length; i < l; i += 3 ) {
renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
}
if ( attributes.index !== undefined ) {
var indices = attributes.index.array;
for ( var i = 0, l = indices.length; i < l; i += 2 ) {
renderList.pushLine( indices[ i ], indices[ i + 1 ] );
}
} else {
var step = object.mode === THREE.LinePieces ? 2 : 1;
for ( var i = 0, l = ( positions.length / 3 ) - 1; i < l; i += step ) {
renderList.pushLine( i, i + 1 );
}
}
}
} else if ( geometry instanceof THREE.Geometry ) {
_modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix );
var vertices = object.geometry.vertices;
if ( vertices.length === 0 ) continue;
v1 = getNextVertexInPool();
v1.positionScreen.copy( vertices[ 0 ] ).applyMatrix4( _modelViewProjectionMatrix );
// Handle LineStrip and LinePieces
var step = object.mode === THREE.LinePieces ? 2 : 1;
for ( var v = 1, vl = vertices.length; v < vl; v ++ ) {
v1 = getNextVertexInPool();
v1.positionScreen.copy( vertices[ v ] ).applyMatrix4( _modelViewProjectionMatrix );
if ( ( v + 1 ) % step > 0 ) continue;
v2 = _vertexPool[ _vertexCount - 2 ];
_clippedVertex1PositionScreen.copy( v1.positionScreen );
_clippedVertex2PositionScreen.copy( v2.positionScreen );
if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) {
// Perform the perspective divide
_clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
_clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
_line = getNextLineInPool();
_line.id = object.id;
_line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
_line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
_line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
_line.material = object.material;
if ( object.material.vertexColors === THREE.VertexColors ) {
_line.vertexColors[ 0 ].copy( object.geometry.colors[ v ] );
_line.vertexColors[ 1 ].copy( object.geometry.colors[ v - 1 ] );
}
_renderData.elements.push( _line );
}
}
}
} else if ( object instanceof THREE.Sprite ) {
_vector4.set( _modelMatrix.elements[ 12 ], _modelMatrix.elements[ 13 ], _modelMatrix.elements[ 14 ], 1 );
_vector4.applyMatrix4( _viewProjectionMatrix );
var invW = 1 / _vector4.w;
_vector4.z *= invW;
if ( _vector4.z >= - 1 && _vector4.z <= 1 ) {
_sprite = getNextSpriteInPool();
_sprite.id = object.id;
_sprite.x = _vector4.x * invW;
_sprite.y = _vector4.y * invW;
_sprite.z = _vector4.z;
_sprite.object = object;
_sprite.rotation = object.rotation;
_sprite.scale.x = object.scale.x * Math.abs( _sprite.x - ( _vector4.x + camera.projectionMatrix.elements[ 0 ] ) / ( _vector4.w + camera.projectionMatrix.elements[ 12 ] ) );
_sprite.scale.y = object.scale.y * Math.abs( _sprite.y - ( _vector4.y + camera.projectionMatrix.elements[ 5 ] ) / ( _vector4.w + camera.projectionMatrix.elements[ 13 ] ) );
_sprite.material = object.material;
_renderData.elements.push( _sprite );
}
}
}
if ( sortElements === true ) {
_renderData.elements.sort( painterSort );
}
return _renderData;
};
// Pools
function getNextObjectInPool() {
if ( _objectCount === _objectPoolLength ) {
var object = new THREE.RenderableObject();
_objectPool.push( object );
_objectPoolLength ++;
_objectCount ++;
return object;
}
return _objectPool[ _objectCount ++ ];
}
function getNextVertexInPool() {
if ( _vertexCount === _vertexPoolLength ) {
var vertex = new THREE.RenderableVertex();
_vertexPool.push( vertex );
_vertexPoolLength ++;
_vertexCount ++;
return vertex;
}
return _vertexPool[ _vertexCount ++ ];
}
function getNextFaceInPool() {
if ( _faceCount === _facePoolLength ) {
var face = new THREE.RenderableFace();
_facePool.push( face );
_facePoolLength ++;
_faceCount ++;
return face;
}
return _facePool[ _faceCount ++ ];
}
function getNextLineInPool() {
if ( _lineCount === _linePoolLength ) {
var line = new THREE.RenderableLine();
_linePool.push( line );
_linePoolLength ++;
_lineCount ++
return line;
}
return _linePool[ _lineCount ++ ];
}
function getNextSpriteInPool() {
if ( _spriteCount === _spritePoolLength ) {
var sprite = new THREE.RenderableSprite();
_spritePool.push( sprite );
_spritePoolLength ++;
_spriteCount ++
return sprite;
}
return _spritePool[ _spriteCount ++ ];
}
//
function painterSort( a, b ) {
if ( a.z !== b.z ) {
return b.z - a.z;
} else if ( a.id !== b.id ) {
return a.id - b.id;
} else {
return 0;
}
}
function clipLine( s1, s2 ) {
var alpha1 = 0, alpha2 = 1,
// Calculate the boundary coordinate of each vertex for the near and far clip planes,
// Z = -1 and Z = +1, respectively.
bc1near = s1.z + s1.w,
bc2near = s2.z + s2.w,
bc1far = - s1.z + s1.w,
bc2far = - s2.z + s2.w;
if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
// Both vertices lie entirely within all clip planes.
return true;
} else if ( ( bc1near < 0 && bc2near < 0 ) || ( bc1far < 0 && bc2far < 0 ) ) {
// Both vertices lie entirely outside one of the clip planes.
return false;
} else {
// The line segment spans at least one clip plane.
if ( bc1near < 0 ) {
// v1 lies outside the near plane, v2 inside
alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) );
} else if ( bc2near < 0 ) {
// v2 lies outside the near plane, v1 inside
alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) );
}
if ( bc1far < 0 ) {
// v1 lies outside the far plane, v2 inside
alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) );
} else if ( bc2far < 0 ) {
// v2 lies outside the far plane, v2 inside
alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) );
}
if ( alpha2 < alpha1 ) {
// The line segment spans two boundaries, but is outside both of them.
// (This can't happen when we're only clipping against just near/far but good
// to leave the check here for future usage if other clip planes are added.)
return false;
} else {
// Update the s1 and s2 vertices to match the clipped line segment.
s1.lerp( s2, alpha1 );
s2.lerp( s1, 1 - alpha2 );
return true;
}
}
}
};

814
js/libraries/three/three.min.js vendored Normal file

File diff suppressed because one or more lines are too long

408
js/msp.js
View File

@ -12,7 +12,6 @@ var MSP_codes = {
MSP_ADJUSTMENT_RANGES: 52,
MSP_SET_ADJUSTMENT_RANGE: 53,
// Multiwii MSP commands
MSP_IDENT: 100,
MSP_STATUS: 101,
@ -62,7 +61,15 @@ var MSP_codes = {
MSP_UID: 160, // Unique device ID
MSP_ACC_TRIM: 240, // get acc angle trim values
MSP_SET_ACC_TRIM: 239, // set acc angle trim values
MSP_GPSSVINFO: 164 // get Signal Strength (only U-Blox)
MSP_GPSSVINFO: 164, // get Signal Strength (only U-Blox)
// Additional private MSP for baseflight configurator (yes thats us \o/)
MSP_RCMAP: 64, // get channel map (also returns number of channels total)
MSP_SET_RCMAP: 65, // set rc map, numchannels to set comes from MSP_RCMAP
MSP_CONFIG: 66, // baseflight-specific settings that aren't covered elsewhere
MSP_SET_CONFIG: 67, // baseflight-specific settings save
MSP_SET_REBOOT: 68, // reboot settings
MSP_BUILDINFO: 69 // build date as well as some space for future expansion
};
var MSP = {
@ -78,23 +85,7 @@ var MSP = {
callbacks: [],
packet_error: 0,
callbacks_cleanup: function () {
for (var i = 0; i < this.callbacks.length; i++) {
clearInterval(this.callbacks[i].timer);
}
this.callbacks = [];
},
disconnect_cleanup: function () {
this.state = 0; // reset packet state for "clean" initial entry (this is only required if user hot-disconnects)
this.packet_error = 0; // reset CRC packet error counter for next session
this.callbacks_cleanup();
}
};
MSP.read = function (readInfo) {
read: function (readInfo) {
var data = new Uint8Array(readInfo.data);
for (var i = 0; i < data.length; i++) {
@ -135,9 +126,11 @@ MSP.read = function (readInfo) {
this.code = data[i];
this.message_checksum ^= data[i];
if (this.message_length_expected != 0) { // standard message
if (this.message_length_expected > 0) {
// process payload
this.state++;
} else { // MSP_ACC_CALIBRATION, etc...
} else {
// no payload
this.state += 2;
}
break;
@ -165,23 +158,16 @@ MSP.read = function (readInfo) {
this.message_length_received = 0;
this.state = 0;
break;
}
}
};
MSP.process_data = function(code, message_buffer, message_length) {
default:
console.log('Unknown state detected: ' + this.state);
}
}
},
process_data: function (code, message_buffer, message_length) {
var data = new DataView(message_buffer, 0); // DataView (allowing us to view arrayBuffer as struct/union)
switch (code) {
case MSP_codes.MSP_API_VERSION:
CONFIG.apiVersion = data.getUint8(1) + '.' + data.getUint8(2);
var identifier = '';
for (i = 0; i < 4; i++) {
identifier += String.fromCharCode(data.getUint8(3 + i));
}
CONFIG.flightControllerIdentifier = identifier;
CONFIG.flightControllerVersion = data.getUint8(7) + '.' + data.getUint8(8) + '.' + data.getUint8(9);
break;
case MSP_codes.MSP_IDENT:
CONFIG.version = parseFloat((data.getUint8(0) / 100).toFixed(2));
CONFIG.multiType = data.getUint8(1);
@ -306,57 +292,33 @@ MSP.process_data = function(code, message_buffer, message_length) {
}
}
break;
case MSP_codes.MSP_MODE_RANGES:
MODE_RANGES = []; // empty the array as new data is coming in
/*
case MSP_codes.MSP_BOX:
AUX_CONFIG_values = []; // empty the array as new data is coming in
var modeRangeCount = data.byteLength / 4; // 4 bytes per item.
var offset = 0;
for (var i = 0; offset < data.byteLength && i < modeRangeCount; i++) {
var modeRange = {
id: data.getUint8(offset++, 1),
auxChannelIndex: data.getUint8(offset++, 1),
range: {
start: 900 + (data.getUint8(offset++, 1) * 25),
end: 900 + (data.getUint8(offset++, 1) * 25)
}
};
MODE_RANGES.push(modeRange);
}
break;
case MSP_codes.MSP_ADJUSTMENT_RANGES:
ADJUSTMENT_RANGES = []; // empty the array as new data is coming in
var adjustmentRangeCount = data.byteLength / 6; // 6 bytes per item.
var offset = 0;
for (var i = 0; offset < data.byteLength && i < adjustmentRangeCount; i++) {
var adjustmentRange = {
slotIndex: data.getUint8(offset++, 1),
auxChannelIndex: data.getUint8(offset++, 1),
range: {
start: 900 + (data.getUint8(offset++, 1) * 25),
end: 900 + (data.getUint8(offset++, 1) * 25)
},
adjustmentFunction: data.getUint8(offset++, 1),
auxSwitchChannelIndex: data.getUint8(offset++, 1)
};
ADJUSTMENT_RANGES.push(adjustmentRange);
// fill in current data
for (var i = 0; i < data.byteLength; i += 2) { // + 2 because uint16_t = 2 bytes
AUX_CONFIG_values.push(data.getUint16(i, 1));
}
break;
*/
case MSP_codes.MSP_MISC: // 22 bytes
MISC.PowerTrigger1 = data.getInt16(0, 1);
MISC.midrc = data.getInt16(0, 1);
MISC.minthrottle = data.getUint16(2, 1); // 0-2000
MISC.maxthrottle = data.getUint16(4, 1); // 0-2000
MISC.mincommand = data.getUint16(6, 1); // 0-2000
MISC.failsafe_throttle = data.getUint16(8, 1); // 1000-2000
MISC.plog0 = data.getUint16(10, 1);
MISC.plog1 = data.getUint32(12, 1);
MISC.mag_declination = data.getInt16(16, 1); // -18000-18000
MISC.gps_type = data.getUint8(10);
MISC.gps_baudrate = data.getUint8(11);
MISC.gps_ubx_sbas = data.getInt8(12);
MISC.multiwiicurrentoutput = data.getUint8(13);
MISC.rssi_aux_channel = data.getUint8(14);
MISC.placeholder2 = data.getUint8(15);
MISC.mag_declination = data.getInt16(16, 1) / 10; // -18000-18000
MISC.vbatscale = data.getUint8(18, 1); // 10-200
MISC.vbatmincellvoltage = data.getUint8(19, 1) / 10; // 10-50
MISC.vbatmaxcellvoltage = data.getUint8(20, 1) / 10; // 10-50
MISC.empty = data.getUint8(21, 1);
MISC.placeholder3 = data.getUint8(21, 1);
break;
case MSP_codes.MSP_MOTOR_PINS:
console.log(data);
@ -415,11 +377,6 @@ MSP.process_data = function(code, message_buffer, message_length) {
SERVO_CONFIG.push(arr);
}
break;
case MSP_codes.MSP_CHANNEL_FORWARDING:
for (var i = 0; i < 8; i ++) {
SERVO_CONFIG[i].indexOfChannelToForward = data.getUint8(i);
}
break;
case MSP_codes.MSP_SET_RAW_RC:
break;
case MSP_codes.MSP_SET_RAW_GPS:
@ -427,15 +384,11 @@ MSP.process_data = function(code, message_buffer, message_length) {
case MSP_codes.MSP_SET_PID:
console.log('PID settings saved');
break;
case MSP_codes.MSP_SET_MODE_RANGE:
console.log('Mode range saved');
break;
case MSP_codes.MSP_SET_ADJUSTMENT_RANGE:
console.log('Adjustment range saved');
break;
/*
case MSP_codes.MSP_SET_BOX:
console.log('AUX Configuration saved');
break;
*/
case MSP_codes.MSP_SET_RC_TUNING:
console.log('RC Tuning saved');
break;
@ -450,19 +403,6 @@ MSP.process_data = function(code, message_buffer, message_length) {
break;
case MSP_codes.MSP_RESET_CONF:
console.log('Settings Reset');
// With new flight software settings in place, we have to re-pull
// latest values
MSP.send_message(MSP_codes.MSP_IDENT);
MSP.send_message(MSP_codes.MSP_STATUS);
MSP.send_message(MSP_codes.MSP_PID);
MSP.send_message(MSP_codes.MSP_RC_TUNING);
MSP.send_message(MSP_codes.MSP_BOXNAMES);
MSP.send_message(MSP_codes.MSP_BOX);
// baseflight specific
MSP.send_message(MSP_codes.MSP_UID);
MSP.send_message(MSP_codes.MSP_ACC_TRIM);
break;
case MSP_codes.MSP_SELECT_SETTING:
console.log('Profile selected');
@ -510,6 +450,107 @@ MSP.process_data = function(code, message_buffer, message_length) {
}
}
break;
// Additional private MSP for baseflight configurator
case MSP_codes.MSP_RCMAP:
RC_MAP = []; // empty the array as new data is coming in
for (var i = 0; i < data.byteLength; i++) {
RC_MAP.push(data.getUint8(i));
}
break;
case MSP_codes.MSP_SET_RCMAP:
console.log('RCMAP saved');
break;
case MSP_codes.MSP_CONFIG:
BF_CONFIG.mixerConfiguration = data.getUint8(0);
BF_CONFIG.features = data.getUint32(1, 1);
BF_CONFIG.serialrx_type = data.getUint8(5);
BF_CONFIG.board_align_roll = data.getInt16(6, 1);
BF_CONFIG.board_align_pitch = data.getInt16(8, 1);
BF_CONFIG.board_align_yaw = data.getInt16(10, 1);
BF_CONFIG.currentscale = data.getUint16(12, 1);
BF_CONFIG.currentoffset = data.getUint16(14, 1);
break;
case MSP_codes.MSP_SET_CONFIG:
break;
case MSP_codes.MSP_SET_REBOOT:
console.log('Reboot request accepted');
break;
case MSP_codes.MSP_BUILDINFO:
var buff = [];
for (var i = 0; i < data.byteLength; i++) {
buff.push(data.getUint8(i));
}
CONFIG.buildInfo = String.fromCharCode.apply(null, buff);
break;
//
// Cleanflight specific
//
case MSP_codes.MSP_API_VERSION:
CONFIG.apiVersion = data.getUint8(1) + '.' + data.getUint8(2);
var identifier = '';
for (i = 0; i < 4; i++) {
identifier += String.fromCharCode(data.getUint8(3 + i));
}
CONFIG.flightControllerIdentifier = identifier;
CONFIG.flightControllerVersion = data.getUint8(7) + '.' + data.getUint8(8) + '.' + data.getUint8(9);
break;
case MSP_codes.MSP_MODE_RANGES:
MODE_RANGES = []; // empty the array as new data is coming in
var modeRangeCount = data.byteLength / 4; // 4 bytes per item.
var offset = 0;
for (var i = 0; offset < data.byteLength && i < modeRangeCount; i++) {
var modeRange = {
id: data.getUint8(offset++, 1),
auxChannelIndex: data.getUint8(offset++, 1),
range: {
start: 900 + (data.getUint8(offset++, 1) * 25),
end: 900 + (data.getUint8(offset++, 1) * 25)
}
};
MODE_RANGES.push(modeRange);
}
break;
case MSP_codes.MSP_ADJUSTMENT_RANGES:
ADJUSTMENT_RANGES = []; // empty the array as new data is coming in
var adjustmentRangeCount = data.byteLength / 6; // 6 bytes per item.
var offset = 0;
for (var i = 0; offset < data.byteLength && i < adjustmentRangeCount; i++) {
var adjustmentRange = {
slotIndex: data.getUint8(offset++, 1),
auxChannelIndex: data.getUint8(offset++, 1),
range: {
start: 900 + (data.getUint8(offset++, 1) * 25),
end: 900 + (data.getUint8(offset++, 1) * 25)
},
adjustmentFunction: data.getUint8(offset++, 1),
auxSwitchChannelIndex: data.getUint8(offset++, 1)
};
ADJUSTMENT_RANGES.push(adjustmentRange);
}
break;
case MSP_codes.MSP_CHANNEL_FORWARDING:
for (var i = 0; i < 8; i ++) {
SERVO_CONFIG[i].indexOfChannelToForward = data.getUint8(i);
}
break;
case MSP_codes.MSP_SET_MODE_RANGE:
console.log('Mode range saved');
break;
case MSP_codes.MSP_SET_ADJUSTMENT_RANGE:
console.log('Adjustment range saved');
break;
default:
console.log('Unknown code detected: ' + code);
@ -531,16 +572,15 @@ MSP.process_data = function(code, message_buffer, message_length) {
if (callback) callback({'command': code, 'data': data, 'length': message_length});
}
}
};
MSP.send_message = function(code, data, callback_sent, callback_msp) {
var bufferOut;
var bufView;
},
send_message: function (code, data, callback_sent, callback_msp) {
var bufferOut,
bufView;
// always reserve 6 bytes for protocol overhead !
if (data) {
var size = data.length + 6;
var checksum = 0;
var size = data.length + 6,
checksum = 0;
bufferOut = new ArrayBuffer(size);
bufView = new Uint8Array(bufferOut);
@ -572,28 +612,174 @@ MSP.send_message = function(code, data, callback_sent, callback_msp) {
bufView[5] = bufView[3] ^ bufView[4]; // checksum
}
// utilizing callback/timeout system for all commands
// dev version 0.57 code below got recently changed due to the fact that queueing same MSP codes was unsupported
// and was causing trouble while backup/restoring configurations
// watch out if the recent change create any inconsistencies and then adjust accordingly
var obj = {'code': code, 'requestBuffer': bufferOut, 'callback': (callback_msp) ? callback_msp : false, 'timer': false};
var requestExists = false;
for (var i = 0; i < MSP.callbacks.length; i++) {
if (MSP.callbacks[i].code == code) {
// request already exist
return false; // skips the code below
// request already exist, we will just attach
requestExists = true;
break;
}
}
var obj = {'code': code, 'callback': (callback_msp) ? callback_msp : false};
if (!requestExists) {
obj.timer = setInterval(function () {
console.log('MSP data request timed-out: ' + code);
serial.send(bufferOut, function(sendInfo) {});
serial.send(bufferOut, false);
}, 1000); // we should be able to define timeout in the future
}
MSP.callbacks.push(obj);
// always send messages with data payload (even when there is a message already in the queue)
if (data || !requestExists) {
serial.send(bufferOut, function (sendInfo) {
if (sendInfo.bytesSent > 0) {
if (sendInfo.bytesSent == bufferOut.length) {
if (callback_sent) callback_sent();
}
});
}
return true;
},
callbacks_cleanup: function () {
for (var i = 0; i < this.callbacks.length; i++) {
clearInterval(this.callbacks[i].timer);
}
this.callbacks = [];
},
disconnect_cleanup: function () {
this.state = 0; // reset packet state for "clean" initial entry (this is only required if user hot-disconnects)
this.packet_error = 0; // reset CRC packet error counter for next session
this.callbacks_cleanup();
}
};
MSP.crunch = function (code) {
var buffer = [];
switch (code) {
case MSP_codes.MSP_SET_CONFIG:
buffer.push(BF_CONFIG.mixerConfiguration);
buffer.push(specificByte(BF_CONFIG.features, 0));
buffer.push(specificByte(BF_CONFIG.features, 1));
buffer.push(specificByte(BF_CONFIG.features, 2));
buffer.push(specificByte(BF_CONFIG.features, 3));
buffer.push(BF_CONFIG.serialrx_type);
buffer.push(specificByte(BF_CONFIG.board_align_roll, 0));
buffer.push(specificByte(BF_CONFIG.board_align_roll, 1));
buffer.push(specificByte(BF_CONFIG.board_align_pitch, 0));
buffer.push(specificByte(BF_CONFIG.board_align_pitch, 1));
buffer.push(specificByte(BF_CONFIG.board_align_yaw, 0));
buffer.push(specificByte(BF_CONFIG.board_align_yaw, 1));
buffer.push(lowByte(BF_CONFIG.currentscale));
buffer.push(highByte(BF_CONFIG.currentscale));
buffer.push(lowByte(BF_CONFIG.currentoffset));
buffer.push(highByte(BF_CONFIG.currentoffset));
break;
case MSP_codes.MSP_SET_PID:
for (var i = 0; i < PIDs.length; i++) {
switch (i) {
case 0:
case 1:
case 2:
case 3:
case 7:
case 8:
case 9:
buffer.push(parseInt(PIDs[i][0] * 10));
buffer.push(parseInt(PIDs[i][1] * 1000));
buffer.push(parseInt(PIDs[i][2]));
break;
case 4:
buffer.push(parseInt(PIDs[i][0] * 100));
buffer.push(parseInt(PIDs[i][1] * 100));
buffer.push(parseInt(PIDs[i][2]));
break;
case 5:
case 6:
buffer.push(parseInt(PIDs[i][0] * 10));
buffer.push(parseInt(PIDs[i][1] * 100));
buffer.push(parseInt(PIDs[i][2] * 1000));
break;
}
}
break;
case MSP_codes.MSP_SET_RC_TUNING:
buffer.push(parseInt(RC_tuning.RC_RATE * 100));
buffer.push(parseInt(RC_tuning.RC_EXPO * 100));
buffer.push(parseInt(RC_tuning.roll_pitch_rate * 100));
buffer.push(parseInt(RC_tuning.yaw_rate * 100));
buffer.push(parseInt(RC_tuning.dynamic_THR_PID * 100));
buffer.push(parseInt(RC_tuning.throttle_MID * 100));
buffer.push(parseInt(RC_tuning.throttle_EXPO * 100));
break;
case MSP_codes.MSP_SET_BOX:
for (var i = 0; i < AUX_CONFIG_values.length; i++) {
buffer.push(lowByte(AUX_CONFIG_values[i]));
buffer.push(highByte(AUX_CONFIG_values[i]));
}
break;
case MSP_codes.MSP_SET_RCMAP:
for (var i = 0; i < RC_MAP.length; i++) {
buffer.push(RC_MAP[i]);
}
break;
case MSP_codes.MSP_SET_ACC_TRIM:
buffer.push(lowByte(CONFIG.accelerometerTrims[0]));
buffer.push(highByte(CONFIG.accelerometerTrims[0]));
buffer.push(lowByte(CONFIG.accelerometerTrims[1]));
buffer.push(highByte(CONFIG.accelerometerTrims[1]));
break;
case MSP_codes.MSP_SET_MISC:
buffer.push(lowByte(MISC.midrc));
buffer.push(highByte(MISC.midrc));
buffer.push(lowByte(MISC.minthrottle));
buffer.push(highByte(MISC.minthrottle));
buffer.push(lowByte(MISC.maxthrottle));
buffer.push(highByte(MISC.maxthrottle));
buffer.push(lowByte(MISC.mincommand));
buffer.push(highByte(MISC.mincommand));
buffer.push(lowByte(MISC.failsafe_throttle));
buffer.push(highByte(MISC.failsafe_throttle));
buffer.push(MISC.gps_type);
buffer.push(MISC.gps_baudrate);
buffer.push(MISC.gps_ubx_sbas);
buffer.push(MISC.multiwiicurrentoutput);
buffer.push(MISC.rssi_aux_channel);
buffer.push(MISC.placeholder2);
buffer.push(lowByte(MISC.mag_declination * 10));
buffer.push(highByte(MISC.mag_declination * 10));
buffer.push(MISC.vbatscale);
buffer.push(MISC.vbatmincellvoltage * 10);
buffer.push(MISC.vbatmaxcellvoltage * 10);
buffer.push(MISC.placeholder3);
break;
case MSP_codes.MSP_SET_SERVO_CONF:
for (var i = 0; i < SERVO_CONFIG.length; i++) {
buffer.push(lowByte(SERVO_CONFIG[i].min));
buffer.push(highByte(SERVO_CONFIG[i].min));
buffer.push(lowByte(SERVO_CONFIG[i].max));
buffer.push(highByte(SERVO_CONFIG[i].max));
buffer.push(lowByte(SERVO_CONFIG[i].middle));
buffer.push(highByte(SERVO_CONFIG[i].middle));
buffer.push(lowByte(SERVO_CONFIG[i].rate));
}
break;
default:
return false;
}
return buffer;
};

View File

@ -111,7 +111,7 @@ PortHandler.check = function () {
if (GUI.active_tab != 'firmware_flasher') {
GUI.timeout_add('auto-connect_timeout', function () {
$('div#port-picker a.connect').click();
}, 50); // small timeout so we won't get any nasty connect errors due to system initializing the bus
}, 100); // timeout so bus have time to initialize after being detected by the system
}
}

View File

@ -13,11 +13,11 @@ var PortUsage = {
},
update: function() {
if (serial.bitrate) {
var port_usage_down = parseInt(((serial.bytes_received - this.previous_received) * 10 / serial.bitrate) * 100);
var port_usage_up = parseInt(((serial.bytes_sent - this.previous_sent) * 10 / serial.bitrate) * 100);
var port_usage_down = parseInt(((serial.bytesReceived - this.previous_received) * 10 / serial.bitrate) * 100);
var port_usage_up = parseInt(((serial.bytesSent - this.previous_sent) * 10 / serial.bitrate) * 100);
this.previous_received = serial.bytes_received;
this.previous_sent = serial.bytes_sent;
this.previous_received = serial.bytesReceived;
this.previous_sent = serial.bytesSent;
// update UI
$('span.port_usage_down').text(chrome.i18n.getMessage('statusbar_usage_download', [port_usage_down]));

View File

@ -8,7 +8,9 @@
'use strict';
var STM32_protocol = function () {
this.baud;
this.options = {};
this.callback; // ref
this.hex; // ref
this.verify_hex;
@ -47,15 +49,18 @@ var STM32_protocol = function () {
};
// no input parameters
STM32_protocol.prototype.connect = function (port, baud, hex, options) {
STM32_protocol.prototype.connect = function (port, baud, hex, options, callback) {
var self = this;
self.hex = hex;
self.baud = baud;
self.callback = callback;
// we will crunch the options here since doing it inside initialization routine would be too late / redundant
// we will crunch the options here since doing it inside initialization routine would be too late
self.options = {
no_reboot: false,
reboot_baud: false,
erase_chip: false
erase_chip: false,
flash_slowly: false
};
if (options.no_reboot) {
@ -68,8 +73,13 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options) {
self.options.erase_chip = true;
}
if (options.flash_slowly) {
self.options.flash_slowly = true;
self.baud = 115200;
}
if (self.options.no_reboot) {
serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
if (openInfo) {
// we are connected, disabling connect button in the UI
GUI.connect_lock = true;
@ -95,10 +105,11 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options) {
serial.send(bufferOut, function () {
serial.disconnect(function (result) {
if (result) {
serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
if (openInfo) {
self.initialize();
} else {
GUI.connect_lock = false;
GUI.log('<span style="color: red">Failed</span> to open serial port');
}
});
@ -122,7 +133,7 @@ STM32_protocol.prototype.initialize = function () {
self.receive_buffer = [];
self.verify_hex = [];
self.upload_time_start = microtime();
self.upload_time_start = new Date().getTime();
self.upload_process_alive = false;
// reset progress bar to initial state
@ -130,6 +141,9 @@ STM32_protocol.prototype.initialize = function () {
self.progress_bar_e.val(0);
self.progress_bar_e.removeClass('valid invalid');
// lock some UI elements TODO needs rework
$('select[name="release"]').prop('disabled', true);
serial.onReceive.addListener(function (info) {
self.read(info);
});
@ -139,7 +153,10 @@ STM32_protocol.prototype.initialize = function () {
self.upload_process_alive = false;
} else {
console.log('STM32 - timed out, programming failed ...');
GUI.log('STM32 - timed out, programming: <strong style="color: red">FAILED</strong>');
$('span.progressLabel').text('STM32 - timed out, programming: FAILED');
self.progress_bar_e.addClass('invalid');
googleAnalytics.sendEvent('Flashing', 'Programming', 'timeout');
// protocol got stuck, clear timer and disconnect
@ -218,8 +235,9 @@ STM32_protocol.prototype.send = function (Array, bytes_to_read, callback) {
// result = true/false
STM32_protocol.prototype.verify_response = function (val, data) {
if (val != data[0]) {
console.log('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]);
GUI.log('STM32 Communication <span style="color: red">failed</span>, wrong response, expected: ' + val + ' received: ' + data[0]);
console.error('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]);
$('span.progressLabel').text('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]);
self.progress_bar_e.addClass('invalid');
// disconnect
this.upload_procedure(99);
@ -327,7 +345,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
switch (step) {
case 1:
// initialize serial interface on the MCU side, auto baud rate settings
GUI.log('Contacting bootloader ...');
$('span.progressLabel').text('Contacting bootloader ...');
var send_counter = 0;
GUI.interval_add('stm32_initialize_mcu', function () { // 200 ms interval (just in case mcu was already initialized), we need to break the 2 bytes command requirement
@ -339,8 +357,10 @@ STM32_protocol.prototype.upload_procedure = function (step) {
// proceed to next step
self.upload_procedure(2);
} else {
$('span.progressLabel').text('Communication with bootloader failed');
self.progress_bar_e.addClass('invalid');
GUI.interval_remove('stm32_initialize_mcu');
GUI.log('Communication with bootloader <span style="color: red">failed</span>');
// disconnect
self.upload_procedure(99);
@ -350,7 +370,10 @@ STM32_protocol.prototype.upload_procedure = function (step) {
if (send_counter++ > 3) {
// stop retrying, its too late to get any response from MCU
console.log('STM32 - no response from bootloader, disconnecting');
GUI.log('No reponse from the bootloader, programming: <strong style="color: red">FAILED</strong>');
$('span.progressLabel').text('No response from the bootloader, programming: FAILED');
self.progress_bar_e.addClass('invalid');
GUI.interval_remove('stm32_initialize_mcu');
GUI.interval_remove('STM32_timeout');
@ -393,7 +416,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
break;
case 4:
// erase memory
GUI.log('Erasing ...');
$('span.progressLabel').text('Erasing ...');
if (self.options.erase_chip) {
console.log('Executing global chip erase');
@ -415,16 +438,18 @@ STM32_protocol.prototype.upload_procedure = function (step) {
self.send([self.command.erase, 0xBC], 1, function (reply) { // 0x43 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
// the bootloader receives one byte that contains N, the number of pages to be erased 1
var max_address = self.hex.data[self.hex.data.length - 1].address + self.hex.data[self.hex.data.length - 1].bytes - 0x8000000;
var erase_pages_n = Math.ceil(max_address / self.page_size);
var max_address = self.hex.data[self.hex.data.length - 1].address + self.hex.data[self.hex.data.length - 1].bytes - 0x8000000,
erase_pages_n = Math.ceil(max_address / self.page_size),
buff = [],
checksum = erase_pages_n - 1;
var buff = [];
buff.push(erase_pages_n - 1);
var checksum = buff[0];
for (var i = 0; i < erase_pages_n; i++) {
buff.push(i);
checksum ^= i;
}
buff.push(checksum);
self.send(buff, 1, function (reply) {
@ -441,14 +466,13 @@ STM32_protocol.prototype.upload_procedure = function (step) {
case 5:
// upload
console.log('Writing data ...');
GUI.log('Flashing ...');
$('span.progressLabel').text('Flashing ...');
var blocks = self.hex.data.length - 1;
var flashing_block = 0;
var address = self.hex.data[flashing_block].address;
var bytes_flashed = 0;
var bytes_flashed_total = 0; // used for progress bar
var blocks = self.hex.data.length - 1,
flashing_block = 0,
address = self.hex.data[flashing_block].address,
bytes_flashed = 0,
bytes_flashed_total = 0; // used for progress bar
var write = function () {
if (bytes_flashed < self.hex.data[flashing_block].bytes) {
@ -481,13 +505,13 @@ STM32_protocol.prototype.upload_procedure = function (step) {
self.send(array_out, 1, function (reply) {
if (self.verify_response(self.status.ACK, reply)) {
// update progress bar
self.progress_bar_e.val(bytes_flashed_total / (self.hex.bytes_total * 2) * 100);
// flash another page
write();
}
});
// update progress bar
self.progress_bar_e.val(Math.round(bytes_flashed_total / (self.hex.bytes_total * 2) * 100));
}
});
}
@ -517,14 +541,13 @@ STM32_protocol.prototype.upload_procedure = function (step) {
case 6:
// verify
console.log('Verifying data ...');
GUI.log('Verifying ...');
$('span.progressLabel').text('Verifying ...');
var blocks = self.hex.data.length - 1;
var reading_block = 0;
var address = self.hex.data[reading_block].address;
var bytes_verified = 0;
var bytes_verified_total = 0; // used for progress bar
var blocks = self.hex.data.length - 1,
reading_block = 0,
address = self.hex.data[reading_block].address,
bytes_verified = 0,
bytes_verified_total = 0; // used for progress bar
// initialize arrays
for (var i = 0; i <= blocks; i++) {
@ -557,14 +580,14 @@ STM32_protocol.prototype.upload_procedure = function (step) {
bytes_verified += bytes_to_read;
bytes_verified_total += bytes_to_read;
// update progress bar
self.progress_bar_e.val((self.hex.bytes_total + bytes_verified_total) / (self.hex.bytes_total * 2) * 100);
// verify another page
reading();
});
}
});
// update progress bar
self.progress_bar_e.val(Math.round((self.hex.bytes_total + bytes_verified_total) / (self.hex.bytes_total * 2) * 100));
}
});
}
@ -590,7 +613,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
if (verify) {
console.log('Programming: SUCCESSFUL');
GUI.log('Programming: <strong style="color: green">SUCCESSFUL</strong>');
$('span.progressLabel').text('Programming: SUCCESSFUL');
googleAnalytics.sendEvent('Flashing', 'Programming', 'success');
// update progress bar
@ -600,7 +623,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
self.upload_procedure(7);
} else {
console.log('Programming: FAILED');
GUI.log('Programming: <strong style="color: red">FAILED</strong>');
$('span.progressLabel').text('Programming: FAILED');
googleAnalytics.sendEvent('Flashing', 'Programming', 'fail');
// update progress bar
@ -623,9 +646,9 @@ STM32_protocol.prototype.upload_procedure = function (step) {
self.send([self.command.go, 0xDE], 1, function (reply) { // 0x21 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
var gt_address = 0x8000000;
var address = [(gt_address >> 24), (gt_address >> 16), (gt_address >> 8), gt_address];
var address_checksum = address[0] ^ address[1] ^ address[2] ^ address[3];
var gt_address = 0x8000000,
address = [(gt_address >> 24), (gt_address >> 16), (gt_address >> 8), gt_address],
address_checksum = address[0] ^ address[1] ^ address[2] ^ address[3];
self.send([address[0], address[1], address[2], address[3], address_checksum], 1, function (reply) {
if (self.verify_response(self.status.ACK, reply)) {
@ -640,18 +663,22 @@ STM32_protocol.prototype.upload_procedure = function (step) {
// disconnect
GUI.interval_remove('STM32_timeout'); // stop STM32 timeout timer (everything is finished now)
console.log('Script finished after: ' + (microtime() - self.upload_time_start).toFixed(4) + ' seconds');
// close connection
serial.disconnect(function (result) {
if (result) { // All went as expected
} else { // Something went wrong
}
PortUsage.reset();
// unlocking connect button
GUI.connect_lock = false;
// unlock some UI elements TODO needs rework
$('select[name="release"]').prop('disabled', false);
// handle timing
var timeSpent = new Date().getTime() - self.upload_time_start;
console.log('Script finished after: ' + (timeSpent / 1000) + ' seconds');
if (self.callback) self.callback();
});
break;
}

View File

@ -13,6 +13,7 @@
'use strict';
var STM32DFU_protocol = function () {
this.callback; // ref
this.hex; // ref
this.verify_hex;
@ -62,12 +63,13 @@ var STM32DFU_protocol = function () {
};
};
STM32DFU_protocol.prototype.connect = function (device, hex) {
STM32DFU_protocol.prototype.connect = function (device, hex, callback) {
var self = this;
self.hex = hex;
self.callback = callback;
// reset and set some variables before we start
self.upload_time_start = microtime();
self.upload_time_start = new Date().getTime();
self.verify_hex = [];
// reset progress bar to initial state
@ -466,9 +468,13 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
break;
case 99:
// cleanup
console.log('Script finished after: ' + (microtime() - self.upload_time_start).toFixed(4) + ' seconds');
self.releaseInterface(0);
var timeSpent = new Date().getTime() - self.upload_time_start;
console.log('Script finished after: ' + (timeSpent / 1000) + ' seconds');
if (self.callback) self.callback();
break;
}
};

143
js/review.js Normal file
View File

@ -0,0 +1,143 @@
'use strict';
$(document).ready(function () {
function Dialog(identifier, content, handler) {
var self = this;
this.block = $('<div />').css({
'position': 'fixed',
'top': 0,
'left': 0,
'width': '100%',
'height': '100%',
'background-color': 'rgba(0, 0, 0, 0.25)',
'z-index': 1000
});
$('body').append(this.block);
this.element = $('<div />').prop('id', 'dialog').addClass(identifier).load(content, function () {
// position the dialog
self.element.css({
'top': window.innerHeight / 3,
'left': (window.innerWidth - self.element.width()) / 2
});
// display content
self.element.fadeIn(100);
if (handler) handler(self);
});
$('body').append(this.element);
// handle window resize
var resizeHandler = function () {
self.element.css({
'top': window.innerHeight / 3,
'left': (window.innerWidth - self.element.width()) / 2
});
};
$(window).on('resize', resizeHandler);
// handle confirm/dismiss keys
var keyDownHandler = function (e) {
if (e.which == 13) {
// Enter
self.element.find('.yes').click();
} else if (e.which == 27) {
// ESC
self.element.find('.no').click();
}
};
$(document).on('keydown', keyDownHandler);
// cleanup routine
this.cleanup = function () {
$(window).off('resize', resizeHandler);
$(document).off('keydown', keyDownHandler);
self.element.empty().remove();
self.block.remove();
};
return this;
}
chrome.storage.sync.get('appReview', function (result) {
if (typeof result.appReview !== 'undefined') {
var data = result.appReview;
if (data.launched < 10) {
data.launched += 1;
chrome.storage.sync.set({'appReview': data});
return;
}
if ((data.firstStart + 604800000) < new Date().getTime()) {
if ((data.refused == 0 || (data.refused + 604800000) < new Date().getTime()) && !data.reviewed) { // needs verifying
var dialog = new Dialog('review', './tabs/review.html', function () {
localize();
$('.initial', dialog.element).show();
var stage = 0;
$(dialog.element).on('click', '.yes, .no', function () {
if (!stage) {
$('p', dialog.element).hide();
if ($(this).hasClass('yes')) {
$('.storeReview', dialog.element).show();
stage = 1;
googleAnalytics.sendEvent('Review', 'Likes App', true);
} else {
$('.bugTicket', dialog.element).show();
stage = 2
googleAnalytics.sendEvent('Review', 'Likes App', false);
}
return false;
}
if (stage == 1) {
if ($(this).hasClass('yes')) {
window.open('https://chrome.google.com/webstore/detail/baseflight-configurator/mppkgnedeapfejgfimkdoninnofofigk/reviews');
data.reviewed = new Date().getTime();
googleAnalytics.sendEvent('Review', 'Submits Review', true);
} else {
data.refused = new Date().getTime();
googleAnalytics.sendEvent('Review', 'Refused', true);
}
}
if (stage == 2) {
if ($(this).hasClass('yes')) {
window.open('https://chrome.google.com/webstore/detail/baseflight-configurator/mppkgnedeapfejgfimkdoninnofofigk/support');
data.refused = new Date().getTime();
googleAnalytics.sendEvent('Review', 'Submits Bug Ticket', true);
} else {
data.refused = new Date().getTime();
googleAnalytics.sendEvent('Review', 'Refused', true);
}
}
chrome.storage.sync.set({'appReview': data});
dialog.cleanup();
});
});
}
}
} else {
// object not in storage, initial setup
chrome.storage.sync.set({'appReview': {
'firstStart': new Date().getTime(),
'launched': 1,
'reviewed': 0,
'refused': 0
}});
}
});
});

View File

@ -1,26 +1,36 @@
'use strict';
var serial = {
connectionId: -1,
connectionId: false,
openRequested: false,
openCanceled: false,
bitrate: 0,
bytes_received: 0,
bytes_sent: 0,
bytesReceived: 0,
bytesSent: 0,
failed: 0,
transmitting: false,
output_buffer: [],
outputBuffer: [],
connect: function (path, options, callback) {
var self = this;
self.openRequested = true;
chrome.serial.connect(path, options, function (connectionInfo) {
if (connectionInfo) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}
if (connectionInfo && !self.openCanceled) {
self.connectionId = connectionInfo.connectionId;
self.bitrate = connectionInfo.bitrate;
self.bytes_received = 0;
self.bytes_sent = 0;
self.bytesReceived = 0;
self.bytesSent = 0;
self.failed = 0;
self.openRequested = false;
self.onReceive.addListener(function log_bytes_received(info) {
self.bytes_received += info.data.byteLength;
self.onReceive.addListener(function log_bytesReceived(info) {
self.bytesReceived += info.data.byteLength;
});
self.onReceiveError.addListener(function watch_for_on_receive_errors(info) {
@ -29,10 +39,15 @@ var serial = {
switch (info.error) {
case 'system_error': // we might be able to recover from this one
var crunch_status = function (info) {
if (!self.failed++) {
chrome.serial.setPaused(self.connectionId, false, function () {
self.getInfo(function (info) {
if (info) {
if (!info.paused) {
console.log('SERIAL: Connection recovered from last onReceiveError');
googleAnalytics.sendException('Serial: onReceiveError - recovered', false);
self.failed = 0;
} else {
console.log('SERIAL: Connection did not recover from last onReceiveError, disconnecting');
GUI.log('Unrecoverable <span style="color: red">failure</span> of serial connection, disconnecting...');
@ -44,11 +59,14 @@ var serial = {
self.disconnect();
}
}
} else {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}
}
chrome.serial.setPaused(self.connectionId, false, function () {
self.getInfo(crunch_status);
});
});
}
break;
case 'timeout':
// TODO
@ -65,7 +83,28 @@ var serial = {
console.log('SERIAL: Connection opened with ID: ' + connectionInfo.connectionId + ', Baud: ' + connectionInfo.bitrate);
if (callback) callback(connectionInfo);
} else if (connectionInfo && self.openCanceled) {
// connection opened, but this connect sequence was canceled
// we will disconnect without triggering any callbacks
self.connectionId = connectionInfo.connectionId;
console.log('SERIAL: Connection opened with ID: ' + connectionInfo.connectionId + ', but request was canceled, disconnecting');
// some bluetooth dongles/dongle drivers really doesn't like to be closed instantly, adding a small delay
setTimeout(function initialization() {
self.openRequested = false;
self.openCanceled = false;
self.disconnect(function resetUI() {
if (callback) callback(false);
});
}, 150);
} else if (self.openCanceled) {
// connection didn't open and sequence was canceled, so we will do nothing
console.log('SERIAL: Connection didn\'t open and request was canceled');
self.openRequested = false;
self.openCanceled = false;
if (callback) callback(false);
} else {
self.openRequested = false;
console.log('SERIAL: Failed to open serial port');
googleAnalytics.sendException('Serial: FailedToOpen', false);
if (callback) callback(false);
@ -75,7 +114,8 @@ var serial = {
disconnect: function (callback) {
var self = this;
self.empty_output_buffer();
if (self.connectionId) {
self.emptyOutputBuffer();
// remove listeners
for (var i = (self.onReceive.listeners.length - 1); i >= 0; i--) {
@ -87,20 +127,27 @@ var serial = {
}
chrome.serial.disconnect(this.connectionId, function (result) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}
if (result) {
console.log('SERIAL: Connection with ID: ' + self.connectionId + ' closed');
console.log('SERIAL: Connection with ID: ' + self.connectionId + ' closed, Sent: ' + self.bytesSent + ' bytes, Received: ' + self.bytesReceived + ' bytes');
} else {
console.log('SERIAL: Failed to close connection with ID: ' + self.connectionId + ' closed');
console.log('SERIAL: Failed to close connection with ID: ' + self.connectionId + ' closed, Sent: ' + self.bytesSent + ' bytes, Received: ' + self.bytesReceived + ' bytes');
googleAnalytics.sendException('Serial: FailedToClose', false);
}
console.log('SERIAL: Statistics - Sent: ' + self.bytes_sent + ' bytes, Received: ' + self.bytes_received + ' bytes');
self.connectionId = -1;
self.connectionId = false;
self.bitrate = 0;
if (callback) callback(result);
});
} else {
// connection wasn't opened, so we won't try to close anything
// instead we will rise canceled flag which will prevent connect from continueing further after being canceled
self.openCanceled = true;
}
},
getDevices: function (callback) {
chrome.serial.getDevices(function (devices_array) {
@ -123,44 +170,54 @@ var serial = {
},
send: function (data, callback) {
var self = this;
self.output_buffer.push({'data': data, 'callback': callback});
this.outputBuffer.push({'data': data, 'callback': callback});
if (!self.transmitting) {
self.transmitting = true;
var sending = function () {
function send() {
// store inside separate variables in case array gets destroyed
var data = self.output_buffer[0].data;
var callback = self.output_buffer[0].callback;
var data = self.outputBuffer[0].data,
callback = self.outputBuffer[0].callback;
chrome.serial.send(self.connectionId, data, function (sendInfo) {
callback(sendInfo);
self.output_buffer.shift();
// track sent bytes for statistics
self.bytesSent += sendInfo.bytesSent;
self.bytes_sent += sendInfo.bytesSent;
// fire callback
if (callback) callback(sendInfo);
if (self.output_buffer.length) {
// remove data for current transmission form the buffer
self.outputBuffer.shift();
// if there is any data in the queue fire send immediately, otherwise stop trasmitting
if (self.outputBuffer.length) {
// keep the buffer withing reasonable limits
while (self.output_buffer.length > 500) {
self.output_buffer.pop();
if (self.outputBuffer.length > 100) {
var counter = 0;
while (self.outputBuffer.length > 100) {
self.outputBuffer.pop();
counter++;
}
sending();
console.log('SERIAL: Send buffer overflowing, dropped: ' + counter + ' entries');
}
send();
} else {
self.transmitting = false;
}
});
};
}
sending();
if (!this.transmitting) {
this.transmitting = true;
send();
}
},
onReceive: {
listeners: [],
addListener: function (function_reference) {
var listener = chrome.serial.onReceive.addListener(function_reference);
chrome.serial.onReceive.addListener(function_reference);
this.listeners.push(function_reference);
},
removeListener: function (function_reference) {
@ -178,8 +235,7 @@ var serial = {
listeners: [],
addListener: function (function_reference) {
var listener = chrome.serial.onReceiveError.addListener(function_reference);
chrome.serial.onReceiveError.addListener(function_reference);
this.listeners.push(function_reference);
},
removeListener: function (function_reference) {
@ -193,8 +249,8 @@ var serial = {
}
}
},
empty_output_buffer: function() {
this.output_buffer = [];
emptyOutputBuffer: function () {
this.outputBuffer = [];
this.transmitting = false;
}
};

View File

@ -3,10 +3,9 @@
$(document).ready(function () {
$('div#port-picker a.connect').click(function () {
if (GUI.connect_lock != true) { // GUI control overrides the user control
var clicks = $(this).data('clicks');
var selected_port = String($('div#port-picker #port').val());
var selected_baud = parseInt($('div#port-picker #baud').val());
var clicks = $(this).data('clicks'),
selected_port = String($('div#port-picker #port').val()),
selected_baud = parseInt($('div#port-picker #baud').val());
if (selected_port != '0' && selected_port != 'DFU') {
if (!clicks) {
@ -27,31 +26,33 @@ $(document).ready(function () {
serial.disconnect(onClosed);
GUI.connected_to = false;
CONFIGURATOR.connectionValid = false;
MSP.disconnect_cleanup();
PortUsage.reset();
// Reset various UI elements
$('span.i2c-error').text(0);
$('span.cycle-time').text(0);
MSP.disconnect_cleanup();
PortUsage.reset();
CONFIGURATOR.connectionValid = false;
CONFIGURATOR.mspPassThrough = false;
// unlock port select & baud
$('div#port-picker #port').prop('disabled', false);
if (!GUI.auto_connect) $('div#port-picker #baud').prop('disabled', false);
// reset connect / disconnect button
$(this).text(chrome.i18n.getMessage('connect'));
$(this).removeClass('active');
sensor_status(0); // reset active sensor indicators
$('#tabs > ul li').removeClass('active'); // de-select any selected tabs
// reset active sensor indicators
sensor_status(0);
// de-select any selected tabs
$('#tabs > ul li').removeClass('active');
// detach listeners and remove element data
$('#content').empty();
// load default html
TABS.default.initialize();
TABS.landing.initialize();
}
$(this).data("clicks", !clicks);
@ -125,7 +126,6 @@ function onOpen(openInfo) {
serial.onReceive.addListener(read_serial);
if (!CONFIGURATOR.mspPassThrough) {
// disconnect after 10 seconds with error if we don't get IDENT data
GUI.timeout_add('connecting', function () {
if (!CONFIGURATOR.connectionValid) {
@ -141,28 +141,28 @@ function onOpen(openInfo) {
// request configuration data
MSP.send_message(MSP_codes.MSP_UID, false, false, function () {
GUI.log(chrome.i18n.getMessage('uniqueDeviceIdReceived', [CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16)]));
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
GUI.timeout_remove('connecting'); // kill connecting timer
GUI.log(chrome.i18n.getMessage('firmwareVersion', [CONFIG.version]));
GUI.log(chrome.i18n.getMessage('uniqueDeviceIdReceived', [CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16)]));
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
if (CONFIG.version >= CONFIGURATOR.firmwareVersionAccepted) {
MSP.send_message(MSP_codes.MSP_BUILDINFO, false, false, function () {
googleAnalytics.sendEvent('Firmware', 'Using', CONFIG.buildInfo);
GUI.log('Running firmware released on: <strong>' + CONFIG.buildInfo + '</strong>');
// continue as usually
CONFIGURATOR.connectionValid = true;
$('div#port-picker a.connect').text(chrome.i18n.getMessage('disconnect')).addClass('active');
$('#tabs li a:first').click();
});
} else {
GUI.log(chrome.i18n.getMessage('firmwareVersionNotSupported', [CONFIGURATOR.firmwareVersionAccepted]));
$('div#port-picker a.connect').click(); // disconnect
}
});
});
} else {
$('div#port-picker a.connect').text(chrome.i18n.getMessage('disconnect')).addClass('active');
GUI.log('Connection opened in <strong>pass-through</strong> mode');
}
} else {
console.log('Failed to open serial port');
GUI.log(chrome.i18n.getMessage('serialPortOpenFail'));
@ -187,12 +187,10 @@ function onClosed(result) {
}
function read_serial(info) {
if (!CONFIGURATOR.cliActive && !CONFIGURATOR.mspPassThrough) {
if (!CONFIGURATOR.cliActive) {
MSP.read(info);
} else if (CONFIGURATOR.cliActive) {
TABS.cli.read(info);
} else if (CONFIGURATOR.mspPassThrough) {
MSP.read(info);
}
}
@ -251,6 +249,10 @@ function lowByte(num) {
return 0x00FF & num;
}
function specificByte(num, pos) {
return 0x000000FF & (num >> (8 * pos));
}
function bit_check(num, bit) {
return ((num >> bit) % 2 != 0);
}

142
main.css
View File

@ -22,17 +22,8 @@ a:hover {
text-decoration: none;
}
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
display: block;
opacity: 1; /* required for chromium 33+ beta */
width: 15px;
background-image: url('../images/arrows.png');
background-repeat: no-repeat;
border-left: 1px solid silver;
margin-left: 5px;
}
.clear-both {
clear: both;
@ -44,16 +35,14 @@ input[type="number"]::-webkit-inner-spin-button {
float: right;
}
#main-wrapper {
margin: 10px auto 0 auto;
padding: 0 10px 0 10px;
height: calc(100% - 10px); /* - padding */
padding: 5px 5px 0 5px;
height: calc(100% - 5px);
}
#port-picker {
float: left;
height: 22px;
margin-bottom: 10px;
height: 20px;
margin-bottom: 5px;
}
#port-picker li {
float: left;
@ -63,7 +52,7 @@ input[type="number"]::-webkit-inner-spin-button {
line-height: 20px;
float: left;
margin-right: 10px;
margin-right: 5px;
border: 1px solid silver;
}
@ -116,37 +105,6 @@ input[type="number"]::-webkit-inner-spin-button {
margin: 3px 0 0 5px;
}
.modelPanel .model {
float: left;
height: 15px;
margin: 10px 0 0 10px;
font-weight: bold;
}
.modelPanel {
position: relative;
width:110px;
height: 150px;
float: left;
}
.modelPanel .modelMixDiagram {
position: absolute;
top: 32px;
left: 10px;
}
.modelPanel .modelMixAirplane { /* Position airplane correctly */
height: 35%;
padding-left: 0px;
}
.modelPanel .modelMixCustom { /* Position question mark correctly */
height: 20%; /* resize question mark */
padding-left: 25px;
}
#sensor-status {
float: right;
@ -170,34 +128,31 @@ input[type="number"]::-webkit-inner-spin-button {
border: 1px solid #c0c0c0;
border-right: 0;
background-color: #901515;
background-color: #e32424;
}
#sensor-status li:last-child {
border-right: 1px solid #c0c0c0;
}
#sensor-status .on {
background-color: #076b0c;
background-color: #b8cf02;
}
#options {
float: right;
margin-top: 1px;
width: 20px;
height: 20px;
background-image: url('./images/ic_settings_24px.svg');
background-position: -1px -1px;
background-repeat: no-repeat;
opacity: 0.6;
}
#options:before {
font-family: icons;
content: '\e600';
font-size: 18px;
}
#options:hover {
opacity: 0.70;
opacity: 0.7;
}
#options.active {
opacity: 0.70;
opacity: 0.7;
}
#options.active:hover {
opacity: 0.85;
@ -206,8 +161,8 @@ input[type="number"]::-webkit-inner-spin-button {
display: none;
position: fixed;
right: 10px;
top: 32px;
right: 30px;
top: 15px;
padding: 5px;
@ -223,9 +178,9 @@ input[type="number"]::-webkit-inner-spin-button {
margin-right: 5px;
}
#log {
margin-bottom: 10px;
margin-bottom: 4px;
height: 60px;
height: 65px;
border: 1px solid silver;
background-color: white;
@ -285,10 +240,10 @@ input[type="number"]::-webkit-inner-spin-button {
background-color: white;
}
#content {
margin-top: 37px;
margin-top: 31px;
padding: 10px;
height: calc(100% - 184px); /* - (port picker, log, tab, status bar) */
height: calc(100% - 171px); /* - (port picker, log, tab, status bar) */
background-color: white;
@ -304,7 +259,7 @@ input[type="number"]::-webkit-inner-spin-button {
bottom: 0px;
width: 100%;
width: calc(100% - 20px);
height: 20px;
line-height: 20px;
@ -321,6 +276,13 @@ input[type="number"]::-webkit-inner-spin-button {
border-right: 1px solid #7d7d79;
}
#status-bar .version {
float: right;
margin: 0;
padding: 0;
border: 0;
}
#cache {
display: none;
}
@ -332,7 +294,6 @@ input[type="number"]::-webkit-inner-spin-button {
background-repeat: no-repeat;
background-position: center 45%;
}
.data-loading p {
position: relative;
top: calc(45% + 45px);
@ -340,8 +301,47 @@ input[type="number"]::-webkit-inner-spin-button {
text-align: center;
font-weight: bold;
}
@font-face {
font-family: 'icons';
src: url('./images/icons/icomoon.woff');
#dialog {
position: fixed;
top: 0;
left: 0;
border: 1px solid silver;
background-color: white;
display: none;
z-index: 1001;
}
#dialog.review {
width: 300px;
}
#dialog.review .head {
line-height: 20px;
color: white;
font-weight: bold;
text-align: center;
border-bottom: 1px solid silver;
background-color: #3f4241;
}
#dialog.review .wrapper {
padding: 5px;
}
#dialog.review p {
display: none;
padding: 5px;
text-align: center;
}
#dialog.review .buttons {
float: right;
margin: 5px 0 0 0;
}
#dialog.review .yes,
#dialog.review .no {
display: block;
float: left;
margin: 0 0 0 5px;
height: 24px;
line-height: 24px;
padding: 0 10px 0 10px;
font-weight: bold;
border: 1px solid #dddddd;
background-color: #f1f1f1;
}

View File

@ -8,24 +8,30 @@
<link type="text/css" rel="stylesheet" href="./js/libraries/jquery.nouislider.min.css" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="./js/libraries/jquery.nouislider.pips.min.css" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="./tabs/default.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/initial_setup.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/landing.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/setup.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/configuration.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/pid_tuning.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/receiver.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/auxiliary_configuration.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/adjustments.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/modes.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/servos.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/gps.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/motor_outputs.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/motors.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/sensors.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/cli.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/logging.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/firmware_flasher.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/adjustments.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/auxiliary.css" media="all" />
<script type="text/javascript" src="./js/libraries/google-analytics-bundle.js"></script>
<script type="text/javascript" src="./js/libraries/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="./js/libraries/d3.min.js"></script>
<script type="text/javascript" src="./js/libraries/jquery.nouislider.all.min.js"></script>
<script type="text/javascript" src="./js/libraries/three/three.min.js"></script>
<script type="text/javascript" src="./js/libraries/three/Projector.js"></script>
<script type="text/javascript" src="./js/libraries/three/CanvasRenderer.js"></script>
<script type="text/javascript" src="./js/port_handler.js"></script>
<script type="text/javascript" src="./js/port_usage.js"></script>
<script type="text/javascript" src="./js/serial.js"></script>
@ -40,17 +46,21 @@
<script type="text/javascript" src="./js/protocols/stm32.js"></script>
<script type="text/javascript" src="./js/protocols/stm32usbdfu.js"></script>
<script type="text/javascript" src="./js/localization.js"></script>
<script type="text/javascript" src="./js/review.js"></script>
<script type="text/javascript" src="./main.js"></script>
<script type="text/javascript" src="./tabs/default.js"></script>
<script type="text/javascript" src="./tabs/initial_setup.js"></script>
<script type="text/javascript" src="./tabs/adjustments.js"></script>
<script type="text/javascript" src="./tabs/auxiliary.js"></script>
<script type="text/javascript" src="./tabs/landing.js"></script>
<script type="text/javascript" src="./tabs/setup.js"></script>
<script type="text/javascript" src="./tabs/configuration.js"></script>
<script type="text/javascript" src="./tabs/pid_tuning.js"></script>
<script type="text/javascript" src="./tabs/receiver.js"></script>
<script type="text/javascript" src="./tabs/auxiliary_configuration.js"></script>
<script type="text/javascript" src="./tabs/adjustments.js"></script>
<script type="text/javascript" src="./tabs/modes.js"></script>
<script type="text/javascript" src="./tabs/servos.js"></script>
<script type="text/javascript" src="./tabs/gps.js"></script>
<script type="text/javascript" src="./tabs/motor_outputs.js"></script>
<script type="text/javascript" src="./tabs/motors.js"></script>
<script type="text/javascript" src="./tabs/sensors.js"></script>
<script type="text/javascript" src="./tabs/cli.js"></script>
<script type="text/javascript" src="./tabs/logging.js"></script>
@ -106,17 +116,19 @@
</div>
<div id="tabs">
<ul>
<li class="tab_initial_setup"><a href="#" i18n="tab1"></a></li>
<li class="tab_pid_tuning"><a href="#" i18n="tab2"></a></li>
<li class="tab_receiver"><a href="#" i18n="tab3"></a></li>
<li class="tab_auxiliary_configuration"><a href="#" i18n="tab4"></a></li>
<li class="tab_adjustments"><a href="#" i18n="tab5"></a></li>
<li class="tab_servos"><a href="#" i18n="tab6"></a></li>
<li class="tab_gps"><a href="#" i18n="tab7"></a></li>
<li class="tab_motor_outputs"><a href="#" i18n="tab8"></a></li>
<li class="tab_sensors"><a href="#" i18n="tab9"></a></li>
<li class="tab_cli"><a href="#" i18n="tab10"></a></li>
<li class="tab_logging"><a href="#" i18n="tab11"></a></li>
<li class="tab_setup"><a href="#" i18n="tabSetup"></a></li>
<li class="tab_configuration"><a href="#" i18n="tabConfiguration"></a></li>
<li class="tab_pid_tuning"><a href="#" i18n="tabPidTuning"></a></li>
<li class="tab_receiver"><a href="#" i18n="tabReceiver"></a></li>
<li class="tab_modes"><a href="#" i18n="tabModeSelection"></a></li>
<li class="tab_auxiliary"><a href="#" i18n="tabAuxiliary"></a></li>
<li class="tab_adjustments"><a href="#" i18n="tabAdjustments"></a></li>
<li class="tab_servos"><a href="#" i18n="tabServos"></a></li>
<li class="tab_gps"><a href="#" i18n="tabGPS"></a></li>
<li class="tab_motors"><a href="#" i18n="tabMotorTesting"></a></li>
<li class="tab_sensors"><a href="#" i18n="tabRawSensorData"></a></li>
<li class="tab_logging"><a href="#" i18n="tabLogging"></a></li>
<li class="tab_cli"><a href="#" i18n="tabCLI"></a></li>
</ul>
<div class="clear-both"></div>
</div>
@ -136,6 +148,9 @@
<div>
<span i18n="statusbar_cycle_time"></span> <span class="cycle-time">0</span>
</div>
<div class="version">
<!-- configuration version generated here -->
</div>
</div>
<div id="cache">
<div class="data-loading">

94
main.js
View File

@ -1,13 +1,5 @@
'use strict';
// Get access to the background window object
// This object is used to pass variables between active page and background page
var backgroundPage;
chrome.runtime.getBackgroundPage(function (result) {
backgroundPage = result;
backgroundPage.app_window = window;
});
// Google Analytics
var googleAnalyticsService = analytics.getService('ice_cream_app');
var googleAnalytics = googleAnalyticsService.getTracker(atob("VUEtNTI4MjA5MjAtMQ=="));
@ -17,8 +9,6 @@ googleAnalyticsService.getConfig().addCallback(function (config) {
});
$(document).ready(function () {
googleAnalytics.sendAppView('Application Started');
// translate to user-selected language
localize();
@ -27,6 +17,8 @@ $(document).ready(function () {
'Chrome: <strong>' + window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/, "$1") + '</strong>, ' +
'Configurator: <strong>' + chrome.runtime.getManifest().version + '</strong>');
$('#status-bar .version').text(chrome.runtime.getManifest().version);
// notification messages for various operating systems
switch (GUI.operating_system) {
case 'Windows':
@ -43,10 +35,25 @@ $(document).ready(function () {
}
// check release time to inform people in case they are running old release
if (CONFIGURATOR.releaseDate < (new Date().getTime() - (86400000 * 60))) { // 1 day = 86400000 miliseconds, * 60 = 2 month window
if (CONFIGURATOR.releaseDate > (new Date().getTime() - (86400000 * 60))) { // 1 day = 86400000 miliseconds, * 60 = 2 month window
console.log('Application version is valid for another: ' + Math.round((CONFIGURATOR.releaseDate - (new Date().getTime() - (86400000 * 60))) / 86400000) + ' days');
} else {
console.log('Application version expired');
GUI.log('You\'re using an old version of ' + chrome.runtime.getManifest().name + '. Please update so you can benefit from recently added features and bugfixes.');
}
// log webgl capability
// it would seem the webgl "enabling" through advanced settings will be ignored in the future
// and webgl will be supported if gpu supports it by default (canary 40.0.2175.0), keep an eye on this one
var canvas = document.createElement('canvas');
if (window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))) {
googleAnalytics.sendEvent('Capability', 'WebGL', 'true');
} else {
googleAnalytics.sendEvent('Capability', 'WebGL', 'false');
}
// log library versions in console to make version tracking easier
console.log('Libraries: jQuery - ' + $.fn.jquery + ', d3 - ' + d3.version + ', three.js - ' + THREE.REVISION);
// Tabs
var ui_tabs = $('#tabs > ul');
@ -56,7 +63,7 @@ $(document).ready(function () {
tab = $(self).parent().prop('class');
// if there is no active connection, return
if (!CONFIGURATOR.connectionValid && tab != 'tab_logging') {
if (!CONFIGURATOR.connectionValid) {
GUI.log('You need to <strong>connect</strong> before you can view any of the tabs');
return;
}
@ -82,8 +89,18 @@ $(document).ready(function () {
}
switch (tab) {
case 'tab_initial_setup':
TABS.initial_setup.initialize(content_ready);
case 'tab_auxiliary':
TABS.auxiliary.initialize(content_ready);
break;
case 'tab_adjustments':
TABS.adjustments.initialize(content_ready);
break;
case 'tab_setup':
TABS.setup.initialize(content_ready);
break;
case 'tab_configuration':
TABS.configuration.initialize(content_ready);
break;
case 'tab_pid_tuning':
TABS.pid_tuning.initialize(content_ready);
@ -91,11 +108,8 @@ $(document).ready(function () {
case 'tab_receiver':
TABS.receiver.initialize(content_ready);
break;
case 'tab_auxiliary_configuration':
TABS.auxiliary_configuration.initialize(content_ready);
break;
case 'tab_adjustments':
TABS.adjustments.initialize(content_ready);
case 'tab_modes':
TABS.modes.initialize(content_ready);
break;
case 'tab_servos':
TABS.servos.initialize(content_ready);
@ -103,24 +117,27 @@ $(document).ready(function () {
case 'tab_gps':
TABS.gps.initialize(content_ready);
break;
case 'tab_motor_outputs':
TABS.motor_outputs.initialize(content_ready);
case 'tab_motors':
TABS.motors.initialize(content_ready);
break;
case 'tab_sensors':
TABS.sensors.initialize(content_ready);
break;
case 'tab_cli':
TABS.cli.initialize(content_ready);
break;
case 'tab_logging':
TABS.logging.initialize(content_ready);
break;
case 'tab_cli':
TABS.cli.initialize(content_ready);
break;
default:
console.log('Tab not found');
}
});
}
});
TABS.default.initialize();
TABS.landing.initialize();
// options
$('a#options').click(function () {
@ -138,13 +155,14 @@ $(document).ready(function () {
// if notifications are enabled, or wasn't set, check the notifications checkbox
chrome.storage.local.get('update_notify', function (result) {
if (result.update_notify === 'undefined' || result.update_notify) {
if (typeof result.update_notify === 'undefined' || result.update_notify) {
$('div.notifications input').prop('checked', true);
}
});
$('div.notifications input').change(function () {
var check = $(this).is(':checked');
googleAnalytics.sendEvent('Settings', 'Notifications', check);
chrome.storage.local.set({'update_notify': check});
});
@ -155,15 +173,16 @@ $(document).ready(function () {
}
$('div.statistics input').change(function () {
var result = $(this).is(':checked');
googleAnalyticsConfig.setTrackingPermitted(result);
var check = $(this).is(':checked');
googleAnalytics.sendEvent('Settings', 'GoogleAnalytics', check);
googleAnalyticsConfig.setTrackingPermitted(check);
});
function close_and_cleanup(e) {
if (e.type == 'click' && !$.contains($('div#options-window')[0], e.target) || e.type == 'keyup' && e.keyCode == 27) {
$(document).unbind('click keyup', close_and_cleanup);
$('div#options-window').slideUp(function () {
$('div#options-window').slideUp(250, function () {
el.removeClass('active');
$(this).empty().remove();
});
@ -172,7 +191,7 @@ $(document).ready(function () {
$(document).bind('click keyup', close_and_cleanup);
$(this).slideDown();
$(this).slideDown(250);
});
}
});
@ -214,6 +233,7 @@ $(document).ready(function () {
if (element.prop('min')) {
if (val < min) {
element.val(min);
val = min;
}
}
@ -221,18 +241,21 @@ $(document).ready(function () {
if (element.prop('max')) {
if (val > max) {
element.val(max);
val = max;
}
}
// if entered value is illegal use previous value instead
if (isNaN(val)) {
element.val(element.data('previousValue'));
val = element.data('previousValue');
}
// if step is not set or step is int and value is float use previous value instead
if (isNaN(step) || step % 1 === 0) {
if (val % 1 !== 0) {
element.val(element.data('previousValue'));
val = element.data('previousValue');
}
}
@ -249,6 +272,13 @@ $(document).ready(function () {
});
});
function catch_startup_time(startTime) {
var endTime = new Date().getTime(),
timeSpent = endTime - startTime;
googleAnalytics.sendTiming('Load Times', 'Application Startup', timeSpent);
}
function microtime() {
var now = new Date().getTime() / 1000;
@ -274,3 +304,7 @@ function bytesToSize(bytes) {
return bytes;
}
Number.prototype.clamp = function(min, max) {
return Math.min(Math.max(this, min), max);
};

View File

@ -1,7 +1,7 @@
{
"manifest_version": 2,
"minimum_chrome_version": "36",
"version": "0.51.3",
"minimum_chrome_version": "38",
"version": "0.57.0",
"author": "Hydra",
"name": "Cleanflight - Configurator",
"short_name": "cleanflight",
@ -22,6 +22,8 @@
"https://www.google-analytics.com/",
"https://*.github.com/",
"https://*.githubusercontent.com/",
"http://*.baseflight.net/",
"http://*.cleanflight.com/",
"serial",
"usb",
"storage",

View File

@ -0,0 +1,48 @@
{
"metadata" :
{
"license" : "Copyright Corey Schiller 2014. All rights reserved. Used with permission for Baseflight Configurator",
"formatVersion" : 3.1,
"generatedBy" : "Blender 2.7 Exporter",
"vertices" : 26,
"faces" : 24,
"normals" : 26,
"colors" : 0,
"uvs" : [54],
"materials" : 1,
"morphTargets" : 0,
"bones" : 0
},
"scale" : 1.000000,
"materials" : [ {
"DbgColor" : 15658734,
"DbgIndex" : 0,
"DbgName" : "default",
"vertexColors" : false
}],
"vertices" : [-8.94063e-08,-0.96,4.59196e-07,2.08615e-07,0.96,-7.57219e-07,-1.8,7.514e-14,1.719e-06,-4.95792e-06,-1.57361e-07,-3.6,1.8,-8.55616e-14,-1.95742e-06,5.04733e-06,1.57361e-07,3.6,-1.8,-0.96,2.65504e-06,5.16654e-06,-0.96,3.6,-1.79999,1.57361e-07,3.6,-5.34535e-06,-0.96,-3.6,-1.8,-1.57361e-07,-3.6,1.8,-0.96,-1.73664e-06,1.79999,-1.57361e-07,-3.6,1.80001,1.57361e-07,3.6,-1.8,0.96,6.6376e-07,4.98772e-06,0.96,3.6,-4.57049e-06,0.96,-3.6,1.8,0.96,-2.1782e-06,-1.79999,-0.96,3.6,-1.80001,-0.96,-3.6,1.79999,-0.96,-3.6,1.8,-0.96,3.6,-1.8,0.96,3.6,-1.8,0.96,-3.6,1.79999,0.96,-3.6,1.80001,0.96,3.6],
"morphTargets" : [],
"normals" : [0,-1,0,0,-0.707083,0.707083,-0.577349,-0.577349,0.577349,-0.707083,-0.707083,0,-0.577349,-0.577349,-0.577349,0,-0.707083,-0.707083,0.577349,-0.577349,-0.577349,0.707083,-0.707083,0,0.577349,-0.577349,0.577349,0,1,0,-0.707083,0.707083,0,-0.577349,0.577349,0.577349,0,0.707083,0.707083,0.577349,0.577349,0.577349,0.707083,0.707083,0,0.577349,0.577349,-0.577349,0,0.707083,-0.707083,-0.577349,0.577349,-0.577349,-1,0,0,-0.707083,0,0.707083,-0.707083,0,-0.707083,0,0,-1,0.707083,0,-0.707083,1,0,0,0.707083,0,0.707083,0,0,1],
"colors" : [],
"uvs" : [[0.141659,0.209166,0.141659,0.418225,0.071016,0.418225,0.071016,0.209166,0.071016,0.000108,0.141658,0.000108,0.212301,0.000108,0.212301,0.209166,0.212301,0.418224,0.929336,0.791362,0.858772,0.791362,0.858772,0.582741,0.929336,0.582741,0.999899,0.582741,0.999899,0.791362,0.999899,0.999983,0.929336,0.999983,0.858772,0.999983,0.535427,0.7908,0.535427,0.735249,0.677017,0.735249,0.677017,0.7908,0.677017,0.846351,0.535427,0.846351,0.393837,0.846351,0.393837,0.7908,0.393837,0.735249,0.929221,0.209323,0.929221,0.153864,0.999887,0.153864,0.999887,0.209323,0.999887,0.264782,0.929221,0.264782,0.858555,0.264782,0.858555,0.209323,0.858555,0.153864,0.141641,0.790803,0.141641,0.735254,0.28323,0.735254,0.28323,0.790803,0.28323,0.846351,0.141641,0.846351,5.2e-05,0.846351,5.2e-05,0.790803,5.2e-05,0.735254,0.535431,0.209376,0.535431,0.264723,0.464739,0.264723,0.464739,0.209376,0.464739,0.154029,0.535431,0.154029,0.606123,0.154029,0.606123,0.209376,0.606123,0.264723]],
"faces" : [43,0,7,18,6,0,0,1,2,3,0,1,2,3,43,0,6,19,9,0,0,3,4,5,0,3,4,5,43,0,9,20,11,0,0,5,6,7,0,5,6,7,43,0,11,21,7,0,0,7,8,1,0,7,8,1,43,1,14,22,15,0,9,10,11,12,9,10,11,12,43,1,15,25,17,0,9,12,13,14,9,12,13,14,43,1,17,24,16,0,9,14,15,16,9,14,15,16,43,1,16,23,14,0,9,16,17,10,9,16,17,10,43,2,6,18,8,0,18,19,20,21,18,3,2,19,43,2,8,22,14,0,18,21,22,23,18,19,11,10,43,2,14,23,10,0,18,23,24,25,18,10,17,20,43,2,10,19,6,0,18,25,26,19,18,20,4,3,43,3,9,19,10,0,27,28,29,30,21,5,4,20,43,3,10,23,16,0,27,30,31,32,21,20,17,16,43,3,16,24,12,0,27,32,33,34,21,16,15,22,43,3,12,20,9,0,27,34,35,28,21,22,6,5,43,4,11,20,12,0,36,37,38,39,23,7,6,22,43,4,12,24,17,0,36,39,40,41,23,22,15,14,43,4,17,25,13,0,36,41,42,43,23,14,13,24,43,4,13,21,11,0,36,43,44,37,23,24,8,7,43,5,15,22,8,0,45,46,47,48,25,12,11,19,43,5,8,18,7,0,45,48,49,50,25,19,2,1,43,5,7,21,13,0,45,50,51,52,25,1,8,24,43,5,13,25,15,0,45,52,53,46,25,24,13,12],
"bones" : [],
"skinIndices" : [],
"skinWeights" : [],
"animations" : []
}

File diff suppressed because one or more lines are too long

477
resources/models/hex_x.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

509
resources/models/y4.json Normal file

File diff suppressed because one or more lines are too long

653
resources/models/y6.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "fill:none;stroke:#BF1B2C;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st2 "fill:none;stroke:#000000;stroke-miterlimit:10;">
<!ENTITY st3 "fill:none;stroke:#8D198F;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:10;">
<!ENTITY st4 "font-family:'ArialMT';">
<!ENTITY st5 "fill:none;stroke:#666666;stroke-miterlimit:10;">
<!ENTITY st6 "font-size:18;">
<!ENTITY st7 "fill:none;stroke:#666666;stroke-width:2;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="AirplaneMix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="138px" height="125.03px"
viewBox="-20.34 -48.94 138 125.03" xml:space="preserve">
<polygon id="Front_Arrow" style="&st0;" points="48.66,-5.46 39.31,10.73 46.22,10.73 46.22,20.38 51.22,20.38 51.22,10.73
58.01,10.73 "/>
<g id="AirplaneGraphic">
<polyline id="ail-l" style="&st5;" points="-3.2,22.63 -3.2,15.58 30,15.58 30,22.63 "/>
<polyline id="ail-r" style="&st5;" points="100.53,22.63 100.53,15.58 67.83,15.58 67.83,22.63 "/>
<path id="wing" style="&st7;" d="M-19.34,22.63c0,0,0-31.4,20.31-31.4h95.38c20.31,0,20.31,31.4,20.31,31.4H-19.34z"/>
<path id="fuse-l" style="&st7;" d="M46.42,72.99L15.96,71c0-18.32,15.88-15,30.44-18.67l-3.65-29.7"/>
<path id="fuse-r" style="&st7;" d="M54.58,22.63l-3.64,29.7C65.49,56,81.38,52.67,81.38,71l-30.46,1.99"/>
<line id="elevator-l" style="&st5;" x1="16.58" y1="65.45" x2="46.76" y2="67.03"/>
<line id="elevator-r" style="&st5;" x1="80.76" y1="65.45" x2="50.57" y2="67.03"/>
<path id="rudder" style="&st5;" d="M50.92,73.57c0-2.09,0-5.78,0-10.99c0-8.56-2.25-8.81-2.25-8.81s-2.25,0.25-2.25,8.81
s0,13.01,0,13.01h4.5C50.92,75.6,50.92,74.92,50.92,73.57"/>
<polyline id="nose" style="&st7;" points="37.72,-8.77 37.72,-15.32 41,-22.39 56.33,-22.39 59.61,-15.32 59.61,-8.77 "/>
</g>
<g id="_x31_and2" transform="matrix(1.25,0,0,-1.25,-378.9054,819.72049)">
<text transform="matrix(0.8 0 0 -0.8 332.1708 675.5416)" style="&st4; &st6;">1/2</text>
<path id="path5318_1_" style="&st3;" d="M355.09,680.7c0-7.19-5.83-13.03-13.03-13.03s-13.03,5.84-13.03,13.03
c0,7.2,5.83,13.03,13.03,13.03S355.09,687.89,355.09,680.7z"/>
</g>
<g id="_x33_" transform="translate(-52.834,-63.500761)">
<path id="path5276-7" style="&st1;" d="M78.81,83.09H53.55V57.82h25.27L78.81,83.09L78.81,83.09z"/>
<text transform="matrix(1 0 0 1 60.9546 76.9026)" style="&st4; &st6;">3</text>
</g>
<g id="_x34_">
<path id="path5276" style="&st1;" d="M96.78,19.86H71.51V-5.4h25.27V19.86L96.78,19.86z"/>
<text transform="matrix(1 0 0 1 80.5186 13.4008)" style="&st4; &st6;">4</text>
</g>
<g id="_x35_">
<polyline id="polyline40" style="&st2;" points="48.67,65.33 28.26,44.49 17.37,44.49 "/>
<path id="path5276-7_1_" style="&st1;" d="M17.2,57.08H-8.07V31.81H17.2V57.08z"/>
<circle id="circle62" cx="48.67" cy="65.33" r="1.88"/>
<text transform="matrix(1 0 0 1 -0.4399 50.8921)" style="&st4; &st6;">5</text>
</g>
<g id="_x36_">
<polyline id="polyline42" style="&st2;" points="61.83,69.6 71.55,44.45 83.02,44.45 "/>
<path id="path5276-7_2_" style="&st1;" d="M108.28,57.08H83.01V31.81h25.27V57.08z"/>
<circle id="circle64" cx="61.83" cy="69.59" r="1.66"/>
<text transform="matrix(1 0 0 1 90.6397 50.8921)" style="&st4; &st6;">6</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "font-family:'ArialMT';">
<!ENTITY st2 "font-size:18;">
<!ENTITY st3 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="Vtail-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="90.56px" height="85.29px"
viewBox="0.69 6.47 90.56 85.29" xml:space="preserve">
<g id="M4">
<path id="path5318" style="&st3;" d="M37.77,26.92c0,9.82-7.96,17.79-17.79,17.79S2.19,36.74,2.19,26.92
c0-9.82,7.96-17.79,17.79-17.79S37.77,17.1,37.77,26.92z"/>
<path id="path5322" style="&st3;" d="M13.6,9.79L2.71,8.55"/>
<path id="path5326" style="&st3;" d="M13.6,9.79l-2.21,10.93"/>
<text transform="matrix(1 0 0 1 14.9749 31.7212)" style="&st1; &st2;">4</text>
</g>
<g id="M3_1_">
<path id="path5330" style="&st3;" d="M41.67,72.47c0-9.82,7.97-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C49.64,90.26,41.67,82.3,41.67,72.47z"/>
<path id="path5334" style="&st3;" d="M69.01,87.25l10.96,0.15"/>
<path id="path5338" style="&st3;" d="M69.01,87.25l1.11-11.09"/>
<text transform="matrix(1 0 0 1 54.4539 77.272)" style="&st1; &st2;">3</text>
</g>
<g id="M2">
<path id="path5306" style="&st3;" d="M54.17,26.92c0,9.82,7.97,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79C62.14,9.13,54.17,17.1,54.17,26.92z"/>
<path id="path5310" style="&st3;" d="M78.24,9.93l2.84,10.58"/>
<path id="path5314" style="&st3;" d="M78.24,9.93l10.97-1.96"/>
<text transform="matrix(1 0 0 1 66.9539 31.7212)" style="&st1; &st2;">2</text>
</g>
<g id="M1">
<path id="path5294" style="&st3;" d="M50.27,72.47c0-9.82-7.96-17.79-17.79-17.79s-17.79,7.97-17.79,17.79
c0,9.83,7.96,17.79,17.79,17.79S50.27,82.3,50.27,72.47z"/>
<path id="path5298" style="&st3;" d="M23.02,87.54l-0.94-10.92"/>
<path id="path5302" style="&st3;" d="M23.02,87.54H11.87"/>
<text transform="matrix(1 0 0 1 27.4749 77.272)" style="&st1; &st2;">1</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="55.32,44.3 45.97,28.11 36.62,44.3 43.52,44.3 43.52,53.94 48.52,53.94 48.52,44.3
"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#666666;">
<!ENTITY st1 "fill:none;stroke:#666666;stroke-width:2;">
<!ENTITY st2 "fill:#ED1C24;">
<!ENTITY st3 "fill:none;stroke:#BF1B2C;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st4 "fill:none;stroke:#000000;stroke-miterlimit:10;">
<!ENTITY st5 "fill:none;stroke:#8D198F;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:10;">
<!ENTITY st6 "font-family:'ArialMT';">
<!ENTITY st7 "font-size:18;">
]>
<svg version="1.1" baseProfile="basic"
id="FlyingWingMix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:version="0.48.4 r9939" sodipodi:docname="flyingwing.svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="125.3px" height="80.8px"
viewBox="296.37 388.68 125.3 80.8" xml:space="preserve">
<polygon id="Front_Arrow" style="&st2;" points="359.02,390.34 349.67,406.53 356.58,406.53 356.58,416.18 361.58,416.18
361.58,406.53 368.37,406.53 "/>
<g id="WingGraphic">
<line id="line_1_" style="&st0;" x1="348.58" y1="417.31" x2="348.58" y2="389.68"/>
<line id="line" style="&st0;" x1="369.46" y1="389.68" x2="369.47" y2="417.31"/>
<line id="elevon" style="&st0;" x1="369.47" y1="417.31" x2="420.67" y2="433.24"/>
<line id="elevon_1_" style="&st0;" x1="348.58" y1="417.31" x2="297.37" y2="433.24"/>
<polygon id="wing_outline" style="&st1;" points="348.58,389.68 297.37,420.85 297.37,438.76 345.86,423.83 348.58,417.31
369.47,417.31 372.18,423.83 420.67,438.76 420.67,420.85 369.46,389.68 "/>
</g>
<g id="_x34_">
<text transform="matrix(1 0 0 1 397.604 461.5044)" style="&st6; &st7;">4</text>
<g id="leader_1_">
<line id="line_3_" style="&st4;" x1="401.19" y1="429.74" x2="401.23" y2="442.71"/>
<circle id="dot_1_" cx="401.2" cy="429.75" r="1.66"/>
</g>
<path id="square" style="&st3;" d="M413.87,467.96H388.6V442.7h25.27V467.96L413.87,467.96z"/>
</g>
<g id="_x33_" transform="translate(-52.834,-63.500761)">
<text transform="matrix(1 0 0 1 364.4331 525.2874)" style="&st6; &st7;">3</text>
<g id="leader">
<line id="line_2_" style="&st4;" x1="369.62" y1="493.24" x2="369.66" y2="506.21"/>
<circle id="dot" cx="369.63" cy="493.25" r="1.66"/>
</g>
<path id="square_1_" style="&st3;" d="M382.29,531.48h-25.26v-25.27h25.27L382.29,531.48L382.29,531.48z"/>
</g>
<g id="_x31_and2" transform="matrix(1.25,0,0,-1.25,-378.9054,819.72049)">
<text transform="matrix(0.8 0 0 -0.8 580.4521 300.6838)" style="&st6; &st7;">1/2</text>
<path id="circle" style="&st5;" d="M603.37,305.84c0-7.19-5.83-13.03-13.03-13.03c-7.2,0-13.03,5.84-13.03,13.03
c0,7.2,5.83,13.03,13.03,13.03C597.54,318.87,603.37,313.03,603.37,305.84z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "font-family:'ArialMT';">
<!ENTITY st2 "font-size:18;">
<!ENTITY st3 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="hex6p-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="113.53px"
height="124.93px" viewBox="6.09 8.22 113.53 124.93" xml:space="preserve">
<g id="M6">
<path id="path5546" style="&st3;" d="M60.19,96.26c9.72-1.44,18.77,5.27,20.21,14.99c1.44,9.72-5.27,18.77-14.99,20.21
c-9.72,1.44-18.76-5.27-20.21-14.99C43.76,106.74,50.47,97.7,60.19,96.26L60.19,96.26z"/>
<path id="path5550" style="&st3;" d="M45.69,118.73l-3.31,10.44"/>
<path id="path5554" style="&st3;" d="M45.69,118.73l10.3,4.27"/>
<text transform="matrix(1 0 0 1 57.8567 120.3127)" style="&st1; &st2;">6</text>
</g>
<g id="M5">
<path id="path5498" style="&st3;" d="M45.01,27.51c0,9.83,7.96,17.79,17.79,17.79s17.79-7.96,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79C52.98,9.72,45.01,17.69,45.01,27.51z"/>
<path id="path5502" style="&st3;" d="M45.98,21.71l10.5-3.14"/>
<path id="path5506" style="&st3;" d="M45.98,21.71L43.71,10.8"/>
<text transform="matrix(1 0 0 1 57.7961 33.9592)" style="&st1; &st2;">5</text>
</g>
<g id="M4">
<path id="path5510" style="&st3;" d="M43.17,49.14c0,9.82-7.96,17.79-17.79,17.79S7.59,58.96,7.59,49.14
c0-9.83,7.97-17.79,17.79-17.79C35.21,31.34,43.17,39.31,43.17,49.14z"/>
<path id="path5514" style="&st3;" d="M20.31,32.08L9.56,30.02"/>
<path id="path5518" style="&st3;" d="M20.31,32.08l-3.03,10.73"/>
<text transform="matrix(1 0 0 1 20.3796 55.5842)" style="&st1; &st2;">4</text>
</g>
<g id="M3">
<path id="path5558" style="&st3;" d="M35.09,107.29c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
c-8.29,5.27-10.74,16.27-5.46,24.56C15.8,110.12,26.8,112.56,35.09,107.29z"/>
<path id="path5562" style="&st3;" d="M19.82,109.13l-3.19-10.48"/>
<path id="path5566" style="&st3;" d="M19.82,109.13l-10.9,2.32"/>
<text transform="matrix(1 0 0 1 20.5339 98.7659)" style="&st1; &st2;">3</text>
</g>
<g id="M2">
<path id="path5522" style="&st3;" d="M107.68,65.33c-8.95,4.06-19.49,0.1-23.55-8.85c-4.06-8.95-0.1-19.49,8.85-23.55
c8.95-4.06,19.49-0.1,23.55,8.85C120.59,50.72,116.63,61.28,107.68,65.33z"/>
<path id="path5526" style="&st3;" d="M113.29,36.94l-3.36-10.43"/>
<path id="path5530" style="&st3;" d="M113.29,36.94l-10.86,2.5"/>
<text transform="matrix(1 0 0 1 95.3293 55.5842)" style="&st1; &st2;">2</text>
</g>
<g id="M1">
<path id="path5534" style="&st3;" d="M108.79,76.67c-8.64-4.67-19.44-1.46-24.11,7.19c-4.67,8.64-1.46,19.44,7.19,24.11
c8.64,4.67,19.44,1.46,24.11-7.19C120.65,92.14,117.44,81.35,108.79,76.67z"/>
<path id="path5538" style="&st3;" d="M109.08,107.81l-10.05-4.37"/>
<path id="path5542" style="&st3;" d="M109.08,107.81l-5.3,9.81"/>
<text transform="matrix(1 0 0 1 95.3274 98.7659)" style="&st1; &st2;">1</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="72.13,74.54 62.78,58.35 53.43,74.54 60.33,74.54 60.33,84.18 65.33,84.18
65.33,74.54 "/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "font-family:'ArialMT';">
<!ENTITY st2 "font-size:18;">
<!ENTITY st3 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="hex6x-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="124.26px"
height="112.78px" viewBox="6.64 7.57 124.26 112.78" xml:space="preserve">
<g id="M6">
<path id="path5486" style="&st3;" d="M35.48,78.97c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
C8.09,54.22,5.65,65.21,10.92,73.5C16.19,81.79,27.19,84.24,35.48,78.97z"/>
<path id="path5490" style="&st3;" d="M20.93,81.03l-3.4-10.42"/>
<path id="path5494" style="&st3;" d="M20.93,81.03l-10.86,2.54"/>
<text transform="matrix(1 0 0 1 20.9268 70.3843)" style="&st1; &st2;">6</text>
</g>
<g id="M5">
<path id="path5450" style="&st3;" d="M118.95,80.16c-8.95,4.06-19.49,0.1-23.55-8.85c-4.06-8.95-0.1-19.49,8.85-23.55
c8.95-4.06,19.49-0.1,23.55,8.85C131.86,65.56,127.9,76.11,118.95,80.16z"/>
<path id="path5454" style="&st3;" d="M116.23,81.14l10.78,1.96"/>
<path id="path5458" style="&st3;" d="M116.23,81.14l2.92-10.75"/>
<text transform="matrix(1 0 0 1 106.5947 70.3843)" style="&st1; &st2;">5</text>
</g>
<g id="M4">
<path id="path5426" style="&st3;" d="M65.14,26.86c0,9.82-7.96,17.79-17.79,17.79s-17.79-7.96-17.79-17.79
c0-9.83,7.96-17.79,17.79-17.79S65.14,17.03,65.14,26.86z"/>
<path id="path5430" style="&st3;" d="M34.83,14.21l-10.47,3.23"/>
<path id="path5434" style="&st3;" d="M34.83,14.21l2.37,10.9"/>
<text transform="matrix(1 0 0 1 42.25 33.3042)" style="&st1; &st2;">4</text>
</g>
<g id="M3">
<path id="path5474" style="&st3;" d="M44.74,83.45c9.72-1.44,18.77,5.27,20.21,14.99c1.44,9.72-5.27,18.77-14.99,20.21
c-9.72,1.44-18.76-5.27-20.21-14.99C28.31,93.94,35.02,84.9,44.74,83.45z"/>
<path id="path5478" style="&st3;" d="M30.24,105.93l-3.31,10.44"/>
<path id="path5482" style="&st3;" d="M30.24,105.93l10.3,4.26"/>
<text transform="matrix(1 0 0 1 42.3423 107.5034)" style="&st1; &st2;">3</text>
</g>
<g id="M2">
<path id="path5438" style="&st3;" d="M72.4,26.86c0,9.82,7.96,17.79,17.79,17.79s17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79S72.4,17.04,72.4,26.86L72.4,26.86z"/>
<path id="path5442" style="&st3;" d="M103.28,14.82l-2.32,10.7"/>
<path id="path5446" style="&st3;" d="M103.28,14.82l10.65,3.28"/>
<text transform="matrix(1 0 0 1 85.1807 33.3042)" style="&st1; &st2;">2</text>
</g>
<g id="M1">
<path id="path5462" style="&st3;" d="M98.65,85.4c-8.64-4.67-19.44-1.46-24.11,7.19c-4.67,8.64-1.46,19.44,7.19,24.11
c8.64,4.68,19.44,1.46,24.11-7.18C110.51,100.86,107.29,90.07,98.65,85.4z"/>
<path id="path5466" style="&st3;" d="M107.52,105l-10,4.5"/>
<path id="path5470" style="&st3;" d="M107.52,105l3.69,10.52"/>
<text transform="matrix(1 0 0 1 85.1826 107.5034)" style="&st1; &st2;">1</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="77.33,67.34 67.98,51.15 58.63,67.34 65.53,67.34 65.53,76.99 70.53,76.99
70.53,67.34 "/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "font-family:'ArialMT';">
<!ENTITY st2 "font-size:18;">
<!ENTITY st3 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="octox-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="136.63px"
height="136.62px" viewBox="12.14 10.11 136.63 136.62" xml:space="preserve">
<g id="M8">
<path id="path5880" style="&st3;" d="M28.83,81.12c9.72-1.44,18.77,5.27,20.21,14.99c1.44,9.72-5.27,18.77-14.99,20.21
c-9.72,1.44-18.77-5.27-20.21-14.99C12.4,91.61,19.11,82.56,28.83,81.12z"/>
<path id="path5884" style="&st3;" d="M18.39,110.82l1.98,10.77"/>
<path id="path5888" style="&st3;" d="M18.39,110.82l11.1-1.07"/>
<text transform="matrix(1 0 0 1 26.4336 105.1724)" style="&st1; &st2;">8</text>
</g>
<g id="M7">
<path id="path5808" style="&st3;" d="M98.16,109.84c9.72-1.44,18.77,5.27,20.21,14.99c1.44,9.72-5.27,18.77-14.99,20.21
c-9.72,1.44-18.77-5.27-20.21-14.99C81.73,120.33,88.44,111.28,98.16,109.84z"/>
<path id="path5812" style="&st3;" d="M113.77,139.59l10.65-2.55"/>
<path id="path5816" style="&st3;" d="M113.77,139.59l-1.66-11.03"/>
<text transform="matrix(1 0 0 1 95.7622 133.8931)" style="&st1; &st2;">7</text>
</g>
<g id="M6">
<path id="path5760" style="&st3;" d="M136.83,74.31c-8.95,4.06-19.49,0.1-23.55-8.85c-4.06-8.95-0.1-19.49,8.85-23.55
c8.95-4.06,19.49-0.1,23.55,8.85S145.78,70.25,136.83,74.31z"/>
<path id="path5764" style="&st3;" d="M142.13,45.59l-3.36-10.43"/>
<path id="path5768" style="&st3;" d="M142.13,45.59l-10.86,2.5"/>
<text transform="matrix(1 0 0 1 124.4771 64.5562)" style="&st1; &st2;">6</text>
</g>
<g id="M5">
<path id="path5712" style="&st3;" d="M77.94,29.4c0,9.83-7.96,17.79-17.79,17.79S42.36,39.23,42.36,29.4
c0-9.82,7.96-17.79,17.79-17.79C69.97,11.6,77.94,19.58,77.94,29.4z"/>
<path id="path5716" style="&st3;" d="M48.68,15.79l-10.69,2.38"/>
<path id="path5720" style="&st3;" d="M48.68,15.79l1.49,11.05"/>
<text transform="matrix(1 0 0 1 55.1484 35.8433)" style="&st1; &st2;">5</text>
</g>
<g id="M4">
<path id="path5784" style="&st3;" d="M68.62,111.8c-8.64-4.67-19.44-1.46-24.11,7.18c-4.67,8.64-1.46,19.44,7.18,24.11
s19.44,1.46,24.11-7.18C80.48,127.27,77.26,116.48,68.62,111.8z"/>
<path id="path5788" style="&st3;" d="M47.39,139.84l1.68-10.83"/>
<path id="path5792" style="&st3;" d="M47.39,139.84l-10.83-2.64"/>
<text transform="matrix(1 0 0 1 55.1489 133.8931)" style="&st1; &st2;">4</text>
</g>
<g id="M3">
<path id="path5856" style="&st3;" d="M137.94,83.08c-8.64-4.67-19.44-1.46-24.11,7.18c-4.67,8.64-1.46,19.44,7.18,24.11
c8.64,4.67,19.44,1.46,24.11-7.18C149.81,98.55,146.6,87.75,137.94,83.08L137.94,83.08z"/>
<path id="path5860" style="&st3;" d="M140.97,112.3l-10.69-2.42"/>
<path id="path5864" style="&st3;" d="M140.97,112.3l-3.37,10.63"/>
<text transform="matrix(1 0 0 1 124.4771 105.1724)" style="&st1; &st2;">3</text>
</g>
<g id="M2">
<path id="path5736" style="&st3;" d="M82.98,29.4c0,9.82,7.96,17.79,17.79,17.79s17.79-7.97,17.79-17.79
c0-9.83-7.97-17.79-17.79-17.79C90.94,11.6,82.98,19.58,82.98,29.4L82.98,29.4z"/>
<path id="path5740" style="&st3;" d="M112.08,15.66l-0.83,10.92"/>
<path id="path5744" style="&st3;" d="M112.08,15.66l11,1.78"/>
<text transform="matrix(1 0 0 1 95.7622 35.8433)" style="&st1; &st2;">2</text>
</g>
<g id="M1">
<path id="path5832" style="&st3;" d="M40.99,73.12c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
c-8.29,5.27-10.74,16.27-5.46,24.56C21.7,75.95,32.7,78.4,40.99,73.12z"/>
<path id="path5836" style="&st3;" d="M19.19,45.21l10.74,2.19"/>
<path id="path5840" style="&st3;" d="M19.19,45.21l3.15-10.69"/>
<text transform="matrix(1 0 0 1 26.4336 64.5562)" style="&st1; &st2;">1</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="89.76,80.26 80.41,64.07 71.06,80.26 77.96,80.26 77.96,89.9 82.96,89.9
82.96,80.26 "/>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "fill:none;stroke:#293D9B;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
<!ENTITY st2 "fill:#FFFFFF;">
<!ENTITY st3 "font-family:'ArialMT';">
<!ENTITY st4 "font-size:18;">
<!ENTITY st5 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic" id="octox-mix"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="124.51px"
height="128.46px" viewBox="0 0 124.51 128.46" xml:space="preserve">
<polygon id="FrontArrow" style="&st0;" points="71.59,65.73 62.25,49.54 52.89,65.73 59.79,65.73 59.79,75.37 64.79,75.37
64.79,65.73 "/>
<g id="M8">
<path id="circle_6_" style="&st1;" d="M28.84,36.28c8.29-5.27,10.74-16.27,5.46-24.56C29.04,3.43,18.04,0.98,9.75,6.26
C1.46,11.53-1,22.53,4.29,30.82C9.55,39.11,20.55,41.55,28.84,36.28z"/>
<path id="line_13_" style="&st1;" d="M24,4.12l2.59,10.65"/>
<path id="line_12_" style="&st1;" d="M24,4.12l11.02-1.71"/>
<text transform="matrix(1 0 0 1 14.2876 27.7231)" style="&st3; &st4;">8</text>
</g>
<g id="M7">
<path id="circle_5_" style="&st1;" d="M33.3,96.23c6.05,7.74,4.68,18.92-3.06,24.97c-7.74,6.05-18.92,4.68-24.97-3.06
S0.59,99.22,8.33,93.17C16.08,87.12,27.25,88.49,33.3,96.23z"/>
<path id="line_10_" style="&st1;" d="M23.54,124.46l10.66,2.5"/>
<path id="line_11_" style="&st1;" d="M23.54,124.46l3.46-10.6"/>
<text transform="matrix(1 0 0 1 14.2876 113.6333)" style="&st3; &st4;">7</text>
</g>
<g id="M6">
<path id="circle_7_" style="&st1;" d="M119.22,10.32c6.05,7.74,4.68,18.92-3.06,24.97c-7.74,6.05-18.92,4.68-24.97-3.06
c-6.05-7.74-4.68-18.92,3.06-24.97C102,1.21,113.17,2.58,119.22,10.32z"/>
<path id="line_14_" style="&st1;" d="M100.96,4L90.29,1.5"/>
<path id="line_15_" style="&st1;" d="M100.96,4L97.5,14.6"/>
<text transform="matrix(1 0 0 1 100.2002 27.7231)" style="&st3; &st4;">6</text>
</g>
<g id="M5">
<path id="circle_1_" style="&st1;" d="M87.43,106.07c-0.6,9.81,6.84,18.25,16.65,18.89c9.82,0.6,18.25-6.84,18.89-16.65
c0.6-9.81-6.84-18.25-16.65-18.89C96.54,88.82,88.08,96.26,87.43,106.07z"/>
<path id="line_3_" style="&st1;" d="M100.49,124.34L97.9,113.7"/>
<path id="line_2_" style="&st1;" d="M100.49,124.34l-11.02,1.71"/>
<text transform="matrix(1 0 0 1 100.1943 113.6333)" style="&st3; &st4;">5</text>
</g>
<g id="M4">
<path id="circle_10_" style="&st2;" d="M56.54,41.45c0,9.82-7.96,17.79-17.79,17.79s-17.79-7.97-17.79-17.79
c0-9.83,7.96-17.79,17.79-17.79S56.54,31.63,56.54,41.45z"/>
<path id="circle_4_" style="&st5;" d="M56.54,41.45c0,9.82-7.96,17.79-17.79,17.79s-17.79-7.97-17.79-17.79
c0-9.83,7.96-17.79,17.79-17.79S56.54,31.63,56.54,41.45z"/>
<path id="line_8_" style="&st5;" d="M52.63,30.3l-2.2-10.74"/>
<path id="line_9_" style="&st5;" d="M52.63,30.3l-11.08,1.3"/>
<text transform="matrix(1 0 0 1 33.7446 47.8984)" style="&st3; &st4;">4</text>
</g>
<g id="M3">
<path id="circle_9_" style="&st2;" d="M56.54,87c0-9.82-7.96-17.79-17.79-17.79S20.96,77.18,20.96,87
c0,9.83,7.96,17.79,17.79,17.79S56.54,96.83,56.54,87z"/>
<path id="circle_8_" style="&st5;" d="M56.54,87c0-9.82-7.96-17.79-17.79-17.79S20.96,77.18,20.96,87
c0,9.83,7.96,17.79,17.79,17.79S56.54,96.83,56.54,87z"/>
<path id="line_4_" style="&st5;" d="M52.51,98.28l-10.93-0.82"/>
<path id="line_5_" style="&st5;" d="M52.51,98.28l-1.77,11"/>
<text transform="matrix(1 0 0 1 33.7446 93.4478)" style="&st3; &st4;">3</text>
</g>
<g id="M2">
<path id="circle_3_" style="&st2;" d="M67.95,41.45c0,9.82,7.96,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79C75.92,23.66,67.95,31.63,67.95,41.45z"/>
<path id="circle_2_" style="&st5;" d="M67.95,41.45c0,9.82,7.96,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79C75.92,23.66,67.95,31.63,67.95,41.45z"/>
<path id="line_6_" style="&st5;" d="M71.97,30.17l10.93,0.82"/>
<path id="line_7_" style="&st5;" d="M71.97,30.17l1.77-11"/>
<text transform="matrix(1 0 0 1 80.7354 47.8984)" style="&st3; &st4;">2</text>
</g>
<g id="M1">
<path id="circle_11_" style="&st2;" d="M67.95,87c0-9.82,7.96-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C75.92,104.79,67.95,96.83,67.95,87z"/>
<path id="circle" style="&st5;" d="M67.95,87c0-9.82,7.96-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C75.92,104.79,67.95,96.83,67.95,87z"/>
<path id="line" style="&st5;" d="M71.88,98.16l2.2,10.74"/>
<path id="line_1_" style="&st5;" d="M71.88,98.16l11.08-1.3"/>
<text transform="matrix(1 0 0 1 80.7021 93.4478)" style="&st3; &st4;">1</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "font-family:'ArialMT';">
<!ENTITY st2 "font-size:18;">
<!ENTITY st3 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="quadp-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="111.99px" height="112px"
viewBox="7.19 8.99 111.99 112" xml:space="preserve">
<g id="M4">
<path id="path5342" style="&st3;" d="M80.98,28.28c0,9.82-7.96,17.79-17.79,17.79c-9.83,0-17.79-7.97-17.79-17.79
c0-9.83,7.96-17.79,17.79-17.79C73.02,10.49,80.98,18.46,80.98,28.28z"/>
<path id="path5346" style="&st3;" d="M80.62,24.7l3-10.53"/>
<path id="path5350" style="&st3;" d="M80.62,24.7L70.2,20.74"/>
<text transform="matrix(1 0 0 1 58.1836 33.084)" style="&st1; &st2;">4</text>
</g>
<g id="M3">
<path id="path5354" style="&st3;" d="M44.27,64.99c0-9.82-7.96-17.79-17.79-17.79S8.69,55.17,8.69,64.99
c0,9.83,7.96,17.79,17.79,17.79S44.27,74.82,44.27,64.99z"/>
<path id="path5358" style="&st3;" d="M21.62,82.11l-3.96-10.22"/>
<path id="path5362" style="&st3;" d="M21.62,82.11l-10.7,3.12"/>
<text transform="matrix(1 0 0 1 21.4751 69.791)" style="&st1; &st2;">3</text>
</g>
<g id="M1">
<path id="path5366" style="&st3;" d="M45.4,101.7c0-9.82,7.96-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C53.37,119.49,45.4,111.52,45.4,101.7z"/>
<path id="path5370" style="&st3;" d="M45.81,105.51l-3.97,10.21"/>
<path id="path5374" style="&st3;" d="M45.81,105.51l10.01,4.91"/>
<text transform="matrix(1 0 0 1 58.1836 106.498)" style="&st1; &st2;">1</text>
</g>
<g id="M2">
<path id="path5378" style="&st3;" d="M82.1,64.99c0,9.83,7.97,17.79,17.79,17.79c9.83,0,17.79-7.96,17.79-17.79
c0-9.82-7.97-17.79-17.79-17.79C90.06,47.2,82.1,55.17,82.1,64.99z"/>
<path id="path5382" style="&st3;" d="M102.7,47.42l4.82,9.84"/>
<path id="path5386" style="&st3;" d="M102.7,47.42l10.4-4.03"/>
<text transform="matrix(1 0 0 1 94.8906 69.793)" style="&st1; &st2;">2</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="72.34,68.1 62.99,51.91 53.64,68.1 60.54,68.1 60.54,77.75 65.54,77.75 65.54,68.1
"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "font-family:'ArialMT';">
<!ENTITY st2 "font-size:18;">
<!ENTITY st3 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="quadx-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="86.03px" height="87.04px"
viewBox="2.72 7.03 86.03 87.04" xml:space="preserve">
<g id="M3">
<path id="path5294" style="&st3;" d="M40.27,73.9c0-9.82-7.96-17.79-17.79-17.79S4.69,64.08,4.69,73.9
c0,9.83,7.96,17.79,17.79,17.79S40.27,83.73,40.27,73.9z"/>
<path id="path5298" style="&st3;" d="M15.26,90.16l-2.48-10.68"/>
<path id="path5302" style="&st3;" d="M15.26,90.16L4.22,91.75"/>
<text transform="matrix(1 0 0 1 17.4753 78.7026)" style="&st1; &st2;">3</text>
</g>
<g id="M2">
<path id="path5306" style="&st3;" d="M51.67,26.92c0,9.82,7.96,17.79,17.79,17.79s17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79C59.64,9.13,51.67,17.1,51.67,26.92z"/>
<path id="path5310" style="&st3;" d="M75.88,10.3l2.66,10.63"/>
<path id="path5314" style="&st3;" d="M75.88,10.3l11-1.77"/>
<text transform="matrix(1 0 0 1 64.4543 31.7212)" style="&st1; &st2;">2</text>
</g>
<g id="M4">
<path id="path5318" style="&st3;" d="M40.27,26.92c0,9.82-7.96,17.79-17.79,17.79S4.69,36.74,4.69,26.92
c0-9.83,7.96-17.79,17.79-17.79S40.27,17.1,40.27,26.92z"/>
<path id="path5322" style="&st3;" d="M15.29,10.64L4.35,9.94"/>
<path id="path5326" style="&st3;" d="M15.29,10.64l-1.67,11.02"/>
<text transform="matrix(1 0 0 1 17.4753 31.7212)" style="&st1; &st2;">4</text>
</g>
<g id="M1">
<path id="path5330" style="&st3;" d="M51.67,73.9c0-9.82,7.96-17.79,17.79-17.79s17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C59.64,91.69,51.67,83.73,51.67,73.9z"/>
<path id="path5334" style="&st3;" d="M76.11,90.4l10.75,2.17"/>
<path id="path5338" style="&st3;" d="M76.11,90.4l3.13-10.7"/>
<text transform="matrix(1 0 0 1 64.4543 78.7026)" style="&st1; &st2;">1</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="55.32,51.57 45.97,35.38 36.62,51.57 43.52,51.57 43.52,61.22 48.52,61.22
48.52,51.57 "/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:none;stroke:#8D198F;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st1 "fill:#ED1C24;">
<!ENTITY st2 "fill:none;stroke:#BF1B2C;stroke-width:3;stroke-miterlimit:10;">
<!ENTITY st3 "font-family:'ArialMT';">
<!ENTITY st4 "font-size:18;">
<!ENTITY st5 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="tri-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="102.17px"
height="93.64px" viewBox="9.19 10.89 102.17 93.64" xml:space="preserve">
<g id="S1">
<path id="path5276" style="&st2;" d="M108.7,97.88H83.43V72.6h25.27L108.7,97.88L108.7,97.88L108.7,97.88z"/>
<text transform="matrix(1 0 0 1 85.0566 91.6897)" style="&st3; &st4;">S1</text>
</g>
<g id="M3">
<path id="path5390" style="&st0;" d="M46.27,30.18c0-9.82-7.96-17.79-17.79-17.79s-17.79,7.97-17.79,17.79
c0,9.83,7.96,17.79,17.79,17.79S46.27,40.01,46.27,30.18z"/>
<path id="path5394" style="&st5;" d="M36.26,14.18l2.11,10.75"/>
<path id="path5398" style="&st5;" d="M36.26,14.18l11.09-1.2"/>
<text transform="matrix(1 0 0 1 23.4707 36.6243)" style="&st3; &st4;">3</text>
</g>
<g id="M2">
<text transform="matrix(1 0 0 1 87.3926 36.6243)" style="&st3; &st4;">2</text>
<path id="path5402" style="&st0;" d="M74.27,30.18c0,9.83,7.96,17.79,17.79,17.79s17.79-7.96,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79S74.27,20.36,74.27,30.18z"/>
<path id="path5406" style="&st5;" d="M75.5,23.56l10.66-2.53"/>
<path id="path5410" style="&st5;" d="M75.5,23.56l-1.63-11.03"/>
</g>
<g id="M1">
<path id="path5414" style="&st0;" d="M78.06,85.24c0-9.82-7.97-17.79-17.79-17.79c-9.83,0-17.79,7.97-17.79,17.79
c0,9.83,7.97,17.79,17.79,17.79C70.1,103.03,78.06,95.07,78.06,85.24z"/>
<path id="path5418" style="&st5;" d="M42.54,83.83l9.24-5.89"/>
<path id="path5422" style="&st5;" d="M42.54,83.83l-5.16-9.88"/>
<text transform="matrix(1 0 0 1 55.2656 91.6897)" style="&st3; &st4;">1</text>
</g>
<polygon style="&st1;" points="69.57,51.05 60.22,34.86 50.87,51.05 57.77,51.05 57.77,60.69 62.77,60.69 62.77,51.05 "/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "font-family:'ArialMT';">
<!ENTITY st2 "font-size:18;">
<!ENTITY st3 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="Vtail-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="90.56px" height="85.29px"
viewBox="0.69 6.47 90.56 85.29" xml:space="preserve">
<g id="M4">
<path id="path5318" style="&st3;" d="M37.77,26.92c0,9.82-7.96,17.79-17.79,17.79S2.19,36.74,2.19,26.92
c0-9.82,7.96-17.79,17.79-17.79S37.77,17.1,37.77,26.92z"/>
<path id="path5322" style="&st3;" d="M13.6,9.79L2.71,8.55"/>
<path id="path5326" style="&st3;" d="M13.6,9.79l-2.21,10.93"/>
<text transform="matrix(1 0 0 1 14.9749 31.7212)" style="&st1; &st2;">4</text>
</g>
<g id="M3_1_">
<path id="path5330" style="&st3;" d="M41.67,72.47c0-9.82,7.97-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.96,17.79-17.79,17.79C49.64,90.26,41.67,82.3,41.67,72.47z"/>
<path id="path5334" style="&st3;" d="M69.01,87.25l10.96,0.15"/>
<path id="path5338" style="&st3;" d="M69.01,87.25l1.11-11.09"/>
<text transform="matrix(1 0 0 1 54.4539 77.272)" style="&st1; &st2;">1</text>
</g>
<g id="M2">
<path id="path5306" style="&st3;" d="M54.17,26.92c0,9.82,7.97,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79C62.14,9.13,54.17,17.1,54.17,26.92z"/>
<path id="path5310" style="&st3;" d="M78.24,9.93l2.84,10.58"/>
<path id="path5314" style="&st3;" d="M78.24,9.93l10.97-1.96"/>
<text transform="matrix(1 0 0 1 66.9539 31.7212)" style="&st1; &st2;">2</text>
</g>
<g id="M1">
<path id="path5294" style="&st3;" d="M50.27,72.47c0-9.82-7.96-17.79-17.79-17.79s-17.79,7.97-17.79,17.79
c0,9.83,7.96,17.79,17.79,17.79S50.27,82.3,50.27,72.47z"/>
<path id="path5298" style="&st3;" d="M23.02,87.54l-0.94-10.92"/>
<path id="path5302" style="&st3;" d="M23.02,87.54H11.87"/>
<text transform="matrix(1 0 0 1 27.4749 77.272)" style="&st1; &st2;">3</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="55.32,44.3 45.97,28.11 36.62,44.3 43.52,44.3 43.52,53.94 48.52,53.94 48.52,44.3
"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "fill:none;stroke:#293D9B;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
<!ENTITY st2 "fill:#FFFFFF;">
<!ENTITY st3 "font-family:'ArialMT';">
<!ENTITY st4 "font-size:18;">
<!ENTITY st5 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="Y4-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="98.02px"
height="117.85px" viewBox="8.18 10.46 98.02 117.85" xml:space="preserve">
<g id="M4">
<path id="path5570" style="&st5;" d="M45.26,29.75c0,9.83-7.96,17.79-17.79,17.79S9.68,39.58,9.68,29.75
c0-9.82,7.96-17.79,17.79-17.79S45.26,19.92,45.26,29.75z"/>
<path id="path5574" style="&st5;" d="M13.84,41.18l2.29,10.71"/>
<path id="path5578" style="&st5;" d="M13.84,41.18L24.9,39.8"/>
<text transform="matrix(1 0 0 1 22.4602 35.3977)" style="&st3; &st4;">4</text>
</g>
<g id="M2">
<path id="path5582" style="&st5;" d="M69.12,29.75c0,9.83,7.97,17.79,17.79,17.79c9.83,0,17.79-7.96,17.79-17.79
c0-9.82-7.96-17.79-17.79-17.79C77.09,11.96,69.12,19.93,69.12,29.75z"/>
<path id="path5586" style="&st5;" d="M100.12,41.67l-10.89-1.14"/>
<path id="path5590" style="&st5;" d="M100.12,41.67L98,52.63"/>
<text transform="matrix(1 0 0 1 81.9075 35.3977)" style="&st3; &st4;">2</text>
</g>
<g id="M3">
<path id="path5594" style="&st1;" d="M66.79,124.03c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
c-8.29,5.27-10.74,16.27-5.46,24.56C47.51,126.86,58.5,129.3,66.79,124.03z"/>
<path id="path5598" style="&st1;" d="M74.88,106.67l-8.04,7.45"/>
<path id="path5602" style="&st1;" d="M74.88,106.67l6.85,8.79"/>
<text transform="matrix(1 0 0 1 52.2317 114.6721)" style="&st3; &st4;">3</text>
</g>
<g id="M1">
<path id="path5678_1_" style="&st2;" d="M49.05,97.06c-8.74-4.49-12.18-15.22-7.68-23.96c4.49-8.74,15.22-12.18,23.96-7.68
c8.74,4.49,12.17,15.22,7.68,23.95C68.52,98.11,57.79,101.55,49.05,97.06z"/>
<path id="path5682" style="&st5;" d="M74.85,83.4l6.08-9.11"/>
<path id="path5686" style="&st5;" d="M74.85,83.4l-8.71-6.96"/>
<path id="path5678" style="&st5;" d="M49.05,97.06c-8.74-4.49-12.18-15.22-7.68-23.96c4.49-8.74,15.22-12.18,23.96-7.68
c8.74,4.49,12.17,15.22,7.68,23.95C68.52,98.11,57.79,101.55,49.05,97.06z"/>
<text transform="matrix(1 0 0 1 52.1829 86.8831)" style="&st3; &st4;">1</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="66.54,47.5 57.19,31.3 47.84,47.5 54.74,47.5 54.74,57.14 59.74,57.14 59.74,47.5
"/>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014. All rights reserved. Used with permission for Baseflight Configurator -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd" [
<!ENTITY st0 "fill:#ED1C24;">
<!ENTITY st1 "fill:none;stroke:#293D9B;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
<!ENTITY st2 "fill:#FFFFFF;">
<!ENTITY st3 "font-family:'ArialMT';">
<!ENTITY st4 "font-size:18;">
<!ENTITY st5 "fill:none;stroke:#8D198F;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;">
]>
<svg version="1.1" baseProfile="basic"
id="Y6-mix" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="151.51px"
height="136.81px" viewBox="5.05 13.08 151.51 136.81" xml:space="preserve">
<g id="M4">
<path id="path5606" style="&st1;" d="M94.63,119.65c6.05,7.74,4.68,18.92-3.06,24.97c-7.74,6.05-18.92,4.68-24.97-3.06
c-6.05-7.74-4.68-18.92,3.06-24.97C77.4,110.54,88.58,111.91,94.63,119.65z"/>
<path id="path5610" style="&st1;" d="M63.66,125.22l-7.82,7.67"/>
<path id="path5614" style="&st1;" d="M63.66,125.22l7.1,8.6"/>
<text transform="matrix(1 0 0 1 75.6128 137.0476)" style="&st3; &st4;">4</text>
</g>
<g id="M6">
<path id="path5618" style="&st1;" d="M33.9,47.88c8.29-5.27,10.74-16.27,5.46-24.56c-5.27-8.29-16.27-10.74-24.56-5.46
C6.51,23.13,4.06,34.13,9.34,42.42C14.61,50.71,25.61,53.15,33.9,47.88z"/>
<path id="path5622" style="&st1;" d="M31,16.37L33.67,27"/>
<path id="path5626" style="&st1;" d="M31,16.37l11.01-1.79"/>
<text transform="matrix(1 0 0 1 19.3428 37.0769)" style="&st3; &st4;">6</text>
</g>
<g id="M5">
<path id="path5630" style="&st1;" d="M119.52,31.79c-0.62,9.81,6.83,18.26,16.63,18.88c9.81,0.62,18.26-6.83,18.88-16.63
c0.62-9.81-6.83-18.26-16.63-18.88C128.6,14.53,120.15,21.98,119.52,31.79z"/>
<path id="path5634" style="&st1;" d="M121.03,25.65l10.72-2.28"/>
<path id="path5638" style="&st1;" d="M121.03,25.65l-1.39-11.06"/>
<text transform="matrix(1 0 0 1 132.2725 39.3621)" style="&st3; &st4;">5</text>
</g>
<g id="M3">
<path id="path5642_1_" style="&st2;" d="M49.06,64.93c-9.83,0-17.79-7.97-17.79-17.79c0-9.83,7.96-17.79,17.79-17.79
c9.82,0,17.79,7.96,17.79,17.79C66.85,56.96,58.88,64.92,49.06,64.93z"/>
<path id="path5642" style="&st5;" d="M49.06,64.93c-9.83,0-17.79-7.97-17.79-17.79c0-9.83,7.96-17.79,17.79-17.79
c9.82,0,17.79,7.96,17.79,17.79C66.85,56.96,58.88,64.92,49.06,64.93z"/>
<path id="path5646" style="&st5;" d="M61.3,34.23l-3.49-10.39"/>
<path id="path5650" style="&st5;" d="M61.3,34.23l-10.83,2.63"/>
<text transform="matrix(1 0 0 1 44.0503 53.5837)" style="&st3; &st4;">3</text>
</g>
<g id="M2">
<path id="path5654_1_" style="&st2;" d="M94.85,47.14c0-9.82,7.97-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.97,17.79-17.79,17.79S94.85,56.97,94.85,47.14z"/>
<path id="path5654" style="&st5;" d="M94.85,47.14c0-9.82,7.97-17.79,17.79-17.79c9.83,0,17.79,7.97,17.79,17.79
c0,9.83-7.97,17.79-17.79,17.79S94.85,56.97,94.85,47.14z"/>
<path id="path5658" style="&st5;" d="M109.29,29.67l-10.04-4.4"/>
<path id="path5662" style="&st5;" d="M109.29,29.67l-5.33,9.79"/>
<text transform="matrix(1 0 0 1 107.9717 53.5837)" style="&st3; &st4;">2</text>
</g>
<g id="M1">
<path id="path5666_1_" style="&st2;" d="M63.01,102.2c0,9.82,7.97,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79C70.98,84.41,63.01,92.38,63.01,102.2z"/>
<path id="path5666" style="&st5;" d="M63.01,102.2c0,9.82,7.97,17.79,17.79,17.79c9.83,0,17.79-7.97,17.79-17.79
c0-9.83-7.96-17.79-17.79-17.79C70.98,84.41,63.01,92.38,63.01,102.2z"/>
<path id="path5670" style="&st5;" d="M63.41,105.94l7.29-8.17"/>
<path id="path5674" style="&st5;" d="M63.41,105.94l-7.64-8.11"/>
<text transform="matrix(1 0 0 1 75.8457 108.6482)" style="&st3; &st4;">1</text>
</g>
<polygon id="Front_Arrow" style="&st0;" points="90.2,68.76 80.85,52.57 71.5,68.76 78.4,68.76 78.4,78.41 83.4,78.41 83.4,68.76
"/>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -1,6 +1,7 @@
'use strict';
TABS.adjustments = {};
TABS.adjustments.initialize = function (callback) {
GUI.active_tab_ref = this;
GUI.active_tab = 'adjustments';

166
tabs/auxiliary.css Normal file
View File

@ -0,0 +1,166 @@
.tab-auxiliary {
}
.tab-auxiliary .help {
padding: 10px;
background-color: #ffcb18;
margin-bottom: 10px;
}
.tab-auxiliary .range .marker,
.tab-auxiliary .channel-slider .noUi-connect {
background: #ffcb18;
}
.tab-auxiliary .mode.on .info {
background: #61B665;
}
.tab-auxiliary .mode.on:nth-child(odd) .info {
background: #BAE2BC;
}
.tab-auxiliary .mode.off .info {
background: #E86969;
}
.tab-auxiliary .mode.off:nth-child(odd) .info {
background: #E7AEAE;
}
#tab-auxiliary-templates {
display: none;
}
.tab-auxiliary .modes {
width: 100%;
border-spacing: 0px;
}
.tab-auxiliary .mode {
background-color: #ececec;
vertical-align: top;
}
.tab-auxiliary .mode:nth-child(odd) {
background-color: #ffffff;
}
.tab-auxiliary .mode .name {
min-height: 50px;
padding: 5px 0px;
}
.tab-auxiliary .mode.off .info,
.tab-auxiliary .mode.on .info {
color: white;
}
.tab-auxiliary .mode .info {
text-align: center;
width: 10%;
position: relative;
}
.tab-auxiliary .mode .info .name {
font-weight: bold;
font-size: 1.1em;
}
.tab-auxiliary .mode .info .buttons {
position: absolute;
bottom: 10px;
width: 100%;
}
.tab-auxiliary .mode .info .buttons a {
padding: 2px 5px;
}
.tab-auxiliary .ranges {
margin: 10px;
padding-top: 2px;
padding-bottom: 2px;
padding-right: 2px;
}
.tab-auxiliary .range {
position: relative;
height: 70px;
padding-top: 8px;
padding-left: 10px;
}
.tab-auxiliary .range > .buttons {
position: absolute;
top: 0px;
right: 0px;
}
.tab-auxiliary .range > .buttons .a {
padding: 2px;
}
.tab-auxiliary .range:nth-child(odd) {
}
.tab-auxiliary .mode .range .channelInfo {
display: inline-block;
float: left;
max-width: 100px;
text-align: center;
}
.tab-auxiliary .mode .range .channelInfo .limits {
padding: 10px 0px;
}
.tab-auxiliary .range .channel {
outline: 1px solid silver;
}
.tab-auxiliary .range .marker {
position: absolute;
left: 50%;
top: 27px;
height: 13px;
width: 6px;
margin-left: -3px;
}
.tab-auxiliary .range .channel-slider {
display: inline-block;
float: right;
width: 85%;
margin-right: 35px;
}
.tab-auxiliary .channel-slider {
}
.tab-auxiliary > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-auxiliary > .buttons a {
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
display: block;
}
.tab-auxiliary .buttons a {
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-auxiliary .buttons a:hover {
background-color: #dedcdc;
}

View File

@ -1,4 +1,4 @@
<div class="tab-auxiliary_configuration">
<div class="tab-auxiliary">
<div class="help">
<p i18n="auxiliaryHelp"></p>
</div>
@ -11,7 +11,7 @@
</div>
</div>
<div id="tab-auxiliary_configuration-templates">
<div id="tab-auxiliary-templates">
<table class="modes">
<tbody>
<tr class="mode">

View File

@ -1,10 +1,11 @@
'use strict';
TABS.auxiliary_configuration = {};
TABS.auxiliary_configuration.initialize = function (callback) {
TABS.auxiliary = {};
TABS.auxiliary.initialize = function (callback) {
GUI.active_tab_ref = this;
GUI.active_tab = 'auxiliary_configuration';
googleAnalytics.sendAppView('Auxiliary Configuration');
GUI.active_tab = 'auxiliary';
googleAnalytics.sendAppView('Auxiliary');
function get_mode_ranges() {
MSP.send_message(MSP_codes.MSP_MODE_RANGES, false, false, get_box_ids);
@ -19,13 +20,13 @@ TABS.auxiliary_configuration.initialize = function (callback) {
}
function load_html() {
$('#content').load("./tabs/auxiliary_configuration.html", process_html);
$('#content').load("./tabs/auxiliary.html", process_html);
}
MSP.send_message(MSP_codes.MSP_BOXNAMES, false, false, get_mode_ranges);
function createMode(modeIndex, modeId) {
var modeTemplate = $('#tab-auxiliary_configuration-templates .mode');
var modeTemplate = $('#tab-auxiliary-templates .mode');
var newMode = modeTemplate.clone();
var modeName = AUX_CONFIG[modeIndex];
@ -43,7 +44,7 @@ TABS.auxiliary_configuration.initialize = function (callback) {
function configureRangeTemplate(auxChannelCount) {
var rangeTemplate = $('#tab-auxiliary_configuration-templates .range');
var rangeTemplate = $('#tab-auxiliary-templates .range');
var channelList = $(rangeTemplate).find('.channel');
var channelOptionTemplate = $(channelList).find('option');
@ -72,7 +73,7 @@ TABS.auxiliary_configuration.initialize = function (callback) {
var rangeIndex = $(modeElement).find('.range').length;
var rangeElement = $('#tab-auxiliary_configuration-templates .range').clone();
var rangeElement = $('#tab-auxiliary-templates .range').clone();
rangeElement.attr('id', 'mode-' + modeIndex + '-range-' + rangeIndex);
modeElement.find('.ranges').append(rangeElement);
@ -115,7 +116,7 @@ TABS.auxiliary_configuration.initialize = function (callback) {
configureRangeTemplate(auxChannelCount);
var modeTableBodyElement = $('.tab-auxiliary_configuration .modes tbody')
var modeTableBodyElement = $('.tab-auxiliary .modes tbody')
for (var modeIndex = 0; modeIndex < AUX_CONFIG.length; modeIndex++) {
var modeId = AUX_CONFIG_IDS[modeIndex];
@ -312,6 +313,6 @@ TABS.auxiliary_configuration.initialize = function (callback) {
}
};
TABS.auxiliary_configuration.cleanup = function (callback) {
TABS.auxiliary.cleanup = function (callback) {
if (callback) callback();
};

View File

@ -1,166 +0,0 @@
.tab-auxiliary_configuration {
}
.tab-auxiliary_configuration .help {
padding: 10px;
background-color: #ffcb18;
margin-bottom: 10px;
}
.tab-auxiliary_configuration .range .marker,
.tab-auxiliary_configuration .channel-slider .noUi-connect {
background: #ffcb18;
}
.tab-auxiliary_configuration .mode.on .info {
background: #61B665;
}
.tab-auxiliary_configuration .mode.on:nth-child(odd) .info {
background: #BAE2BC;
}
.tab-auxiliary_configuration .mode.off .info {
background: #E86969;
}
.tab-auxiliary_configuration .mode.off:nth-child(odd) .info {
background: #E7AEAE;
}
#tab-auxiliary_configuration-templates {
display: none;
}
.tab-auxiliary_configuration .modes {
width: 100%;
border-spacing: 0px;
}
.tab-auxiliary_configuration .mode {
background-color: #ececec;
vertical-align: top;
}
.tab-auxiliary_configuration .mode:nth-child(odd) {
background-color: #ffffff;
}
.tab-auxiliary_configuration .mode .name {
min-height: 50px;
padding: 5px 0px;
}
.tab-auxiliary_configuration .mode.off .info,
.tab-auxiliary_configuration .mode.on .info {
color: white;
}
.tab-auxiliary_configuration .mode .info {
text-align: center;
width: 10%;
position: relative;
}
.tab-auxiliary_configuration .mode .info .name {
font-weight: bold;
font-size: 1.1em;
}
.tab-auxiliary_configuration .mode .info .buttons {
position: absolute;
bottom: 10px;
width: 100%;
}
.tab-auxiliary_configuration .mode .info .buttons a {
padding: 2px 5px;
}
.tab-auxiliary_configuration .ranges {
margin: 10px;
padding-top: 2px;
padding-bottom: 2px;
padding-right: 2px;
}
.tab-auxiliary_configuration .range {
position: relative;
height: 70px;
padding-top: 8px;
padding-left: 10px;
}
.tab-auxiliary_configuration .range > .buttons {
position: absolute;
top: 0px;
right: 0px;
}
.tab-auxiliary_configuration .range > .buttons .a {
padding: 2px;
}
.tab-auxiliary_configuration .range:nth-child(odd) {
}
.tab-auxiliary_configuration .mode .range .channelInfo {
display: inline-block;
float: left;
max-width: 100px;
text-align: center;
}
.tab-auxiliary_configuration .mode .range .channelInfo .limits {
padding: 10px 0px;
}
.tab-auxiliary_configuration .range .channel {
outline: 1px solid silver;
}
.tab-auxiliary_configuration .range .marker {
position: absolute;
left: 50%;
top: 27px;
height: 13px;
width: 6px;
margin-left: -3px;
}
.tab-auxiliary_configuration .range .channel-slider {
display: inline-block;
float: right;
width: 85%;
margin-right: 35px;
}
.tab-auxiliary_configuration .channel-slider {
}
.tab-auxiliary_configuration > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-auxiliary_configuration > .buttons a {
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
display: block;
}
.tab-auxiliary_configuration .buttons a {
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-auxiliary_configuration .buttons a:hover {
background-color: #dedcdc;
}

View File

@ -7,9 +7,11 @@ TABS.cli = {
TABS.cli.initialize = function (callback) {
var self = this;
GUI.active_tab_ref = this;
if (GUI.active_tab != 'cli') {
GUI.active_tab = 'cli';
googleAnalytics.sendAppView('CLI Page');
googleAnalytics.sendAppView('CLI');
}
$('#content').load("./tabs/cli.html", function () {
// translate to user-selected language
@ -23,7 +25,7 @@ TABS.cli.initialize = function (callback) {
bufView[0] = 0x23; // #
serial.send(bufferOut, function (writeInfo) {});
serial.send(bufferOut);
var textarea = $('.tab-cli textarea');
@ -93,7 +95,7 @@ TABS.cli.sendSlowly = function (out_arr, i, timeout_needle) {
bufView[out_arr[i].length] = 0x0D; // enter (\n)
serial.send(bufferOut, function (writeInfo) {});
serial.send(bufferOut);
}, timeout_needle * 5);
};
@ -178,7 +180,7 @@ TABS.cli.cleanup = function (callback) {
// (another approach is however much more complicated):
// we can setup an interval asking for data lets say every 200ms, when data arrives, callback will be triggered and tab switched
// we could probably implement this someday
GUI.timeout_add('waiting_for_bootup', function () {
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
CONFIGURATOR.cliActive = false;
CONFIGURATOR.cliValid = false;

137
tabs/configuration.css Normal file
View File

@ -0,0 +1,137 @@
.tab-configuration {
position: relative;
}
.tab-configuration .groupTitle {
padding: 0 0 5px 0;
margin: 0 0 10px 0;
font-size: 16px;
border-bottom: 1px solid #dddddd;
}
.tab-configuration .leftWrapper {
float: left;
width: 50%;
margin: 0 0 10px 0;
}
.tab-configuration .rightWrapper {
float: left;
width: calc(50% - 10px);
margin: 0 0 10px 10px;
}
.tab-configuration .mixerPreview {
width: 180px;
height: 180px;
}
.tab-configuration .mixerPreview img {
display: block;
width: calc(100% - 10px);
height: calc(100% - 10px);
padding: 5px;
border: 1px solid silver;
border-bottom: 0;
}
.tab-configuration select.mixerList {
width: calc(100% + 2px);
height: 20px;
font-weight: bold;
border: 1px solid silver;
}
.tab-configuration dl.features dt {
float: left;
width: 10px;
height: 18px;
line-height: 18px;
}
.tab-configuration dl.features dt input {
margin-top: 2px;
}
.tab-configuration dl.features dd {
margin: 0 0 0 20px;
height: 18px;
line-height: 18px;
}
.tab-configuration .number {
margin-bottom: 5px;
}
.tab-configuration .number input {
width: 60px;
height: 20px;
line-height: 20px;
text-align: right;
border: 1px solid silver;
}
.tab-configuration .number span {
margin-left: 10px;
line-height: 20px;
}
.tab-configuration .gps .line {
clear: left;
}
.tab-configuration .gps select {
float: left;
width: 100px;
height: 20px;
margin: 0 10px 5px 0;
border: 1px solid silver;
}
.tab-configuration .gps span {
line-height: 20px;
}
.tab-configuration .serialRX {
width: 125px;
border: 1px solid silver;
}
.tab-configuration .current .checkbox {
margin-top: 2px;
}
.tab-configuration .current .checkbox div {
float: left;
width: 60px;
}
.tab-configuration .current .checkbox div input {
display: block;
margin: 2px auto 0 auto;
}
.tab-configuration .current .checkbox span {
margin-left: 15px;
}
.tab-configuration .buttons {
position: fixed;
width: calc(100% - 20px);
bottom: 10px;
}
.tab-configuration .save {
display: block;
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-configuration .save:hover {
background-color: #dedcdc;
}

171
tabs/configuration.html Normal file
View File

@ -0,0 +1,171 @@
<div class="tab-configuration">
<div class="leftWrapper">
<div class="groupTitle" i18n="configurationMixer"></div>
<div class="mixerPreview">
<img src="./resources/motor_order/custom.svg" />
<select class="mixerList">
<!-- list generated here -->
</select>
</div>
</div>
<div class="rightWrapper">
<div class="groupTitle" i18n="configurationFeatures"></div>
<dl class="features">
<!-- list generated here -->
</dl>
</div>
<div class="clear-both"></div>
<div class="leftWrapper">
<div class="groupTitle" i18n="configurationThrottle"></div>
<div class="number">
<label>
<input type="number" name="minthrottle" min="0" max="2000" />
<span i18n="configurationThrottleMinimum"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="midthrottle" min="0" max="2000" />
<span i18n="configurationThrottleMid"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="maxthrottle" min="0" max="2000" />
<span i18n="configurationThrottleMaximum"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="failsafe_throttle" min="0" max="2000" />
<span i18n="configurationThrottleFailsafe"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="mincommand" min="0" max="2000" />
<span i18n="configurationThrottleMinimumCommand"></span>
</label>
</div>
</div>
<div class="rightWrapper">
<div class="groupTitle" i18n="configurationAccelTrimMagDec"></div>
<div class="number">
<label>
<input type="number" name="roll" min="-300" max="300" />
<span i18n="configurationAccelTrimRoll"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="pitch" min="-300" max="300" />
<span i18n="configurationAccelTrimPitch"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="mag_declination" step="0.1" min="-180" max="180" />
<span i18n="configurationMagDeclination"></span>
</label>
</div>
</div>
<div class="clear-both"></div>
<div class="leftWrapper">
<div class="groupTitle" i18n="configurationSerialRX"></div>
<select class="serialRX" size="4">
<!-- list generated here -->
</select>
</div>
<div class="rightWrapper gps">
<div class="groupTitle" i18n="configurationGPS"></div>
<div class="line">
<select class="gps_type">
<!-- list generated here -->
</select>
<span i18n="configurationGPStype"></span>
</div>
<div class="line">
<select class="gps_baudrate">
<!-- list generated here -->
</select>
<span i18n="configurationGPSbaudrate"></span>
</div>
<div class="line">
<select class="gps_ubx_sbas">
<!-- list generated here -->
</select>
<span i18n="configurationGPSubxSbas"></span>
</div>
</div>
<div class="clear-both"></div>
<div class="leftWrapper">
<div class="groupTitle" i18n="configurationBatteryVoltage"></div>
<div class="number">
<label>
<input type="number" name="mincellvoltage" step="0.1" min="1" max="5" />
<span i18n="configurationBatteryMinimum"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="maxcellvoltage" step="0.1" min="1" max="5" />
<span i18n="configurationBatteryMaximum"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="voltagescale" step="1" min="10" max="200" />
<span i18n="configurationBatteryScale"></span>
</label>
</div>
</div>
<div class="rightWrapper current">
<div class="groupTitle" i18n="configurationCurrent"></div>
<div class="number">
<label>
<input type="number" name="currentscale" step="1" min="1" max="1000" />
<span i18n="configurationCurrentScale"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="currentoffset" step="1" min="1" max="1000" />
<span i18n="configurationCurrentOffset"></span>
</label>
</div>
<div class="checkbox">
<label>
<div>
<input type="checkbox" name="multiwiicurrentoutput" />
</div>
<span i18n="configurationBatteryMultiwiiCurrent"></span>
</label>
</div>
</div>
<div class="clear-both"></div>
<div class="leftWrapper">
<div class="groupTitle" i18n="configurationBoardAlignment"></div>
<div class="number">
<label>
<input type="number" name="board_align_roll" step="1" min="-180" max="180" />
<span i18n="configurationBoardAlignmentRoll"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="board_align_pitch" step="1" min="-180" max="180" />
<span i18n="configurationBoardAlignmentPitch"></span>
</label>
</div>
<div class="number">
<label>
<input type="number" name="board_align_yaw" step="1" min="-180" max="180" />
<span i18n="configurationBoardAlignmentYaw"></span>
</label>
</div>
</div>
<div class="clear-both"></div>
<div class="buttons">
<a class="save" href="#" i18n="configurationButtonSave"></a>
</div>
</div>

305
tabs/configuration.js Normal file
View File

@ -0,0 +1,305 @@
'use strict';
TABS.configuration = {};
TABS.configuration.initialize = function (callback, scrollPosition) {
var self = this;
if (GUI.active_tab != 'configuration') {
GUI.active_tab = 'configuration';
googleAnalytics.sendAppView('Configuration');
}
function load_config() {
MSP.send_message(MSP_codes.MSP_CONFIG, false, false, load_rc_map);
}
function load_rc_map() {
MSP.send_message(MSP_codes.MSP_RCMAP, false, false, load_misc);
}
function load_misc() {
MSP.send_message(MSP_codes.MSP_MISC, false, false, load_acc_trim);
}
function load_acc_trim() {
MSP.send_message(MSP_codes.MSP_ACC_TRIM, false, false, load_html);
}
function load_html() {
$('#content').load("./tabs/configuration.html", process_html);
}
MSP.send_message(MSP_codes.MSP_IDENT, false, false, load_config);
function process_html() {
// translate to user-selected language
localize();
// generate mixer
var mixerList = [
{name: 'Tricopter', image: 'tri'},
{name: 'Quad +', image: 'quad_p'},
{name: 'Quad X', image: 'quad_x'},
{name: 'Bicopter', image: 'custom'},
{name: 'Gimbal', image: 'custom'},
{name: 'Y6', image: 'y6'},
{name: 'Hex +', image: 'hex_p'},
{name: 'Flying Wing', image: 'flying_wing'},
{name: 'Y4', image: 'y4'},
{name: 'Hex X', image: 'hex_x'},
{name: 'Octo X8', image: 'octo_x8'},
{name: 'Octo Flat +', image: 'custom'},
{name: 'Octo Flat X', image: 'octo_flat_x'},
{name: 'Airplane', image: 'airplane'},
{name: 'Heli 120', image: 'custom'},
{name: 'Heli 90', image: 'custom'},
{name: 'V-tail Quad', image: 'vtail_quad'},
{name: 'Hex H', image: 'custom'},
{name: 'PPM to SERVO', image: 'custom'},
{name: 'Dualcopter', image: 'custom'},
{name: 'Singlecopter', image: 'custom'},
{name: 'A-tail Quad', image: 'atail_quad'},
{name: 'Custom', image: 'custom'}
];
var mixer_list_e = $('select.mixerList');
for (var i = 0; i < mixerList.length; i++) {
mixer_list_e.append('<option value="' + (i + 1) + '">' + mixerList[i].name + '</option>');
}
mixer_list_e.change(function () {
var val = parseInt($(this).val());
BF_CONFIG.mixerConfiguration = 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();
// generate features
var featureNames = [
{name: 'PPM', description: 'Enable PPM input (and disable PWM input)'},
{name: 'VBAT', description: 'Enable Battery voltage monitoring'},
{name: 'INFLIGHT_ACC_CAL', description: 'Enable in-flight level calibration'},
{name: 'SERIALRX', description: 'Enable Serial-based receiver (SPEKSAT, SBUS, SUMD)'},
{name: 'MOTOR_STOP', description: 'Don\'t spin the motors when armed'},
{name: 'SERVO_TILT', description: 'Enable servo gimbal'},
{name: 'SOFTSERIAL', description: 'Enable 3rd serial port'},
{name: 'LED_RING', description: 'Enable LED ring support'},
{name: 'GPS', description: 'Enable GPS (PPM or 3rd serial port required)'},
{name: 'FAILSAFE', description: 'Enable failsafe settings on PPM/PWM signal loss'},
{name: 'SONAR', description: 'Enable sonar'},
{name: 'TELEMETRY', description: 'Enable FrSky- compatible telemetry output'},
{name: 'POWERMETER', description: 'Enable battery current monitoring'},
{name: 'VARIO', description: 'Enable VARIO'},
{name: '3D', description: 'Enable 3D mode (for use with reversible ESCs)'}
];
var features_e = $('.features');
for (var i = 0; i < featureNames.length; i++) {
var element = $('<dt><input id="feature-' + i + '" title="' + featureNames[i].name + '" type="checkbox" /></dt><dd><label for="feature-' + i + '">' + featureNames[i].description + '</label></dd>');
element.find('input').attr('checked', bit_check(BF_CONFIG.features, i));
features_e.append(element);
}
// generate GPS
var gpsTypes = [
'NMEA',
'UBLOX',
'MTK_NMEA',
'MTK_BINARY',
'MAG_BINARY'
];
var gpsBauds = [
'115200',
'57600',
'38400',
'19200',
'9600'
];
var gpsSbas = [
'Disabled',
'Auto-detect',
'European EGNOS',
'North American WAAS',
'Japanese MSAS',
'Indian GAGAN'
];
var gps_type_e = $('select.gps_type');
for (var i = 0; i < gpsTypes.length; i++) {
gps_type_e.append('<option value="' + i + '">' + gpsTypes[i] + '</option>');
}
gps_type_e.change(function () {
MISC.gps_type = parseInt($(this).val());
});
var gps_baudrate_e = $('select.gps_baudrate');
for (var i = 0; i < gpsBauds.length; i++) {
gps_baudrate_e.append('<option value="' + i + '">' + gpsBauds[i] + '</option>');
}
gps_baudrate_e.change(function () {
MISC.gps_baudrate = parseInt($(this).val());
});
var gps_ubx_sbas_e = $('select.gps_ubx_sbas');
for (var i = 0; i < gpsSbas.length; i++) {
gps_ubx_sbas_e.append('<option value="' + (i - 1) + '">' + gpsSbas[i] + '</option>');
}
gps_ubx_sbas_e.change(function () {
MISC.gps_ubx_sbas = parseInt($(this).val());
});
// select current gps configuration
gps_type_e.val(MISC.gps_type);
gps_baudrate_e.val(MISC.gps_baudrate);
gps_ubx_sbas_e.val(MISC.gps_ubx_sbas);
// generate serial RX
var serialRXtypes = [
'SPEKTRUM1024',
'SPEKTRUM2048',
'SBUS',
'SUMD',
'MSP'
];
var serialRX_e = $('select.serialRX');
for (var i = 0; i < serialRXtypes.length; i++) {
serialRX_e.append('<option value="' + i + '">' + serialRXtypes[i] + '</option>');
}
serialRX_e.change(function () {
BF_CONFIG.serialrx_type = parseInt($(this).val());
});
// select current serial RX type
serialRX_e.val(BF_CONFIG.serialrx_type);
// 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 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);
// 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);
// fill throttle
$('input[name="minthrottle"]').val(MISC.minthrottle);
$('input[name="midthrottle"]').val(MISC.midrc);
$('input[name="maxthrottle"]').val(MISC.maxthrottle);
$('input[name="failsafe_throttle"]').val(MISC.failsafe_throttle);
$('input[name="mincommand"]').val(MISC.mincommand);
// fill battery
$('input[name="mincellvoltage"]').val(MISC.vbatmincellvoltage);
$('input[name="maxcellvoltage"]').val(MISC.vbatmaxcellvoltage);
$('input[name="voltagescale"]').val(MISC.vbatscale);
// fill current
$('input[name="currentscale"]').val(BF_CONFIG.currentscale);
$('input[name="currentoffset"]').val(BF_CONFIG.currentoffset);
$('input[name="multiwiicurrentoutput"]').prop('checked', MISC.multiwiicurrentoutput);
// UI hooks
$('input', features_e).change(function () {
var element = $(this),
index = $('input', features_e).index(element),
state = element.is(':checked');
if (state) {
BF_CONFIG.features = bit_set(BF_CONFIG.features, index);
} else {
BF_CONFIG.features = bit_clear(BF_CONFIG.features, index);
}
});
$('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());
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());
MISC.minthrottle = parseInt($('input[name="minthrottle"]').val());
MISC.midrc = parseInt($('input[name="midthrottle"]').val());
MISC.maxthrottle = parseInt($('input[name="maxthrottle"]').val());
MISC.failsafe_throttle = parseInt($('input[name="failsafe_throttle"]').val());
MISC.mincommand = parseInt($('input[name="mincommand"]').val());
MISC.vbatmincellvoltage = parseFloat($('input[name="mincellvoltage"]').val());
MISC.vbatmaxcellvoltage = parseFloat($('input[name="maxcellvoltage"]').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'); // ~~ boolean to decimal conversion
function save_misc() {
MSP.send_message(MSP_codes.MSP_SET_MISC, MSP.crunch(MSP_codes.MSP_SET_MISC), false, save_acc_trim);
}
function save_acc_trim() {
MSP.send_message(MSP_codes.MSP_SET_ACC_TRIM, MSP.crunch(MSP_codes.MSP_SET_ACC_TRIM), false, save_to_eeprom);
}
function save_to_eeprom() {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, reboot);
}
function reboot() {
GUI.log(chrome.i18n.getMessage('configurationEepromSaved'));
GUI.tab_switch_cleanup(function() {
MSP.send_message(MSP_codes.MSP_SET_REBOOT, false, false, reinitialize);
});
}
function reinitialize() {
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
GUI.log(chrome.i18n.getMessage('deviceReady'));
TABS.configuration.initialize(false, $('#content').scrollTop());
});
}, 1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts
}
MSP.send_message(MSP_codes.MSP_SET_CONFIG, MSP.crunch(MSP_codes.MSP_SET_CONFIG), false, save_misc);
});
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function status_pull() {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);
if (callback) callback();
}
};
TABS.configuration.cleanup = function (callback) {
if (callback) callback();
};

View File

@ -1,171 +0,0 @@
.tab-default .left {
width: 60%;
}
.tab-default .right {
float: left;
margin-left: 10px;
width: calc(40% - 10px);
}
.tab-default .optional_permissions {
display: none;
margin-bottom: 10px;
border: 1px solid silver;
}
.tab-default .optional_permissions .title {
line-height: 20px;
text-align: center;
font-weight: bold;
color: white;
border-bottom: 1px solid silver;
background-color: #cd4c4c;
}
.tab-default .optional_permissions p {
padding: 5px;
}
.tab-default .optional_permissions a {
display: block;
float: left;
height: 28px;
line-height: 28px;
margin: 0 0 5px 5px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-default .optional_permissions a:hover {
background-color: #dedcdc;
}
.welcome {
margin-bottom: 10px;
padding: 5px;
border: 1px solid silver;
}
.welcome a {
font-weight: bold;
}
.welcome a:hover {
text-decoration: underline;
}
.changelog {
margin: 0 0 10px 0;
border: 1px solid silver;
}
.changelog .title {
line-height: 20px;
text-align: center;
font-weight: bold;
color: white;
border-bottom: 1px solid silver;
background-color: #3f4241;
}
.changelog .wrapper {
height: 150px;
padding: 5px;
overflow-y: scroll;
overflow-x: hidden;
-webkit-user-select: text;
}
.changelog .wrapper span {
font-weight: bold;
}
.changelog .wrapper p {
margin-bottom: 5px;
}
.donate {
padding: 0 0 5px 0;
border: 1px solid silver;
}
.donate .title {
line-height: 20px;
text-align: center;
font-weight: bold;
color: white;
border-bottom: 1px solid silver;
background-color: #3f4241;
}
.donate p {
padding: 5px;
}
.donate a {
display: block;
width: 74px;
height: 21px;
margin: auto;
}
.donate .buttons {
margin-left: auto;
margin-right: auto;
width: 160px;
}
.donate ul {
}
.donate li {
text-align: center;
display: inline-block;
}
.firmware_flasher {
display: block;
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.firmware_flasher:hover {
background-color: #dedcdc;
}
.tab-default .sponsors {
margin-top: 10px;
border: 1px solid silver;
}
.tab-default .sponsors .title {
line-height: 20px;
text-align: center;
font-weight: bold;
color: white;
border-bottom: 1px solid silver;
background-color: #3f4241;
}
.tab-default .sponsors p {
padding: 5px;
}
.tab-default .sponsors p a {
font-weight: bold;
}
.tab-default .sponsors p a:hover {
text-decoration: underline;
}

View File

@ -19,6 +19,12 @@
/* text-shadow: 1px 0px 2px rgba(0, 0, 0, 0.9);*/
}
.tab-firmware_flasher .info .progressLabel a {
color: white;
}
.tab-firmware_flasher .info .progressLabel a:hover {
text-decoration: underline;
}
.tab-firmware_flasher .info .progress {
width: 100%;
height: 26px;
@ -46,27 +52,42 @@
.tab-firmware_flasher .info .progress.invalid::-webkit-progress-value {
background-color: #A62E32;
}
.tab-firmware_flasher .note {
.tab-firmware_flasher .options {
position: relative;
margin-bottom: 10px;
padding: 5px;
line-height: 18px;
border: 1px dotted silver;
}
.tab-firmware_flasher .note p {
margin-bottom: 5px;
}
.tab-firmware_flasher .note label {
float: left;
}
.tab-firmware_flasher .note label input {
.tab-firmware_flasher .options label input {
float: left;
margin-top: 2px;
}
.tab-firmware_flasher .note label span {
.tab-firmware_flasher .options label span {
font-weight: bold;
margin-left: 6px;
}
.tab-firmware_flasher .note .flash_on_connect_wrapper {
.tab-firmware_flasher .options select {
width: 180px;
height: 20px;
border: 1px solid silver;
}
.tab-firmware_flasher .option.releases {
margin: 0 0 2px 0;
line-height: 20px;
}
.tab-firmware_flasher .options .description {
position: absolute;
left: 200px;
font-style: italic;
color: #818181;
}
.tab-firmware_flasher .options .flash_on_connect_wrapper {
display: none;
}
.tab-firmware_flasher .git_info {
@ -89,6 +110,12 @@
.tab-firmware_flasher .git_info p {
padding: 5px;
}
.tab-firmware_flasher .git_info p a {
font-weight: bold;
}
.tab-firmware_flasher .git_info p a:hover {
text-decoration: underline;
}
.warning {
border: 1px solid silver;
}

View File

@ -1,36 +1,49 @@
<div class="tab-firmware_flasher">
<div class="info">
<progress class="progress" value="0" min="0" max="100"></progress>
<span class="progressLabel">Please load firmware file</span>
<span class="progressLabel" i18n="firmwareFlasherLoadFirmwareFile"></span>
</div>
<div class="note">
<p i18n="firmwareFlasherNote">
</p>
<div class="options">
<div class="option releases">
<select name="release">
<option value="0">Loading ...</option>
</select>
<span class="description" i18n="firmwareFlasherOnlineReleasesDescription"></span>
</div>
<div class="option">
<label>
<input class="updating" type="checkbox" />
<span i18n="firmwareFlasherNoReboot"></span>
</label>
<div class="clear-both"></div>
<label class="flash_on_connect_wrapper">
<span class="description" i18n="firmwareFlasherNoRebootDescription"></span>
</div>
<div class="option flash_on_connect_wrapper">
<label>
<input class="flash_on_connect" type="checkbox" />
<span i18n="firmwareFlasherFlashOnConnect"></span><br />
<span i18n="firmwareFlasherFlashOnConnect"></span>
</label>
<div class="clear-both"></div>
<span class="description" i18n="firmwareFlasherFlashOnConnectDescription"></span>
</div>
<div class="option">
<label>
<input class="erase_chip" type="checkbox" />
<span i18n="firmwareFlasherFullChipErase"></span>
</label>
<div class="clear-both"></div>
<label i18n_title="firmwareFlasherFlashSlowlyTitle">
<span class="description" i18n="firmwareFlasherFullChipEraseDescription"></span>
</div>
<div class="option">
<label>
<input class="flash_slowly" type="checkbox" />
<span i18n="firmwareFlasherFlashSlowly"></span>
</label>
<div class="clear-both"></div>
<span class="description" i18n="firmwareFlasherFlashSlowlyDescription"></span>
</div>
</div>
<div class="clear-both"></div>
<div class="git_info">
<div class="title" i18n="firmwareFlasherGithubInfoHead"></div>
<p>
<strong i18n="firmwareFlasherHash"></strong> <a i18n_title="firmwareFlasherUrl" class="hash" href="#" target="_blank"></a><br />
<strong i18n="firmwareFlasherCommiter"></strong> <span class="committer"></span><br />
<strong i18n="firmwareFlasherDate"></strong> <span class="date"></span><br />
<strong i18n="firmwareFlasherMessage"></strong> <span class="message"></span>

View File

@ -2,9 +2,12 @@
TABS.firmware_flasher = {};
TABS.firmware_flasher.initialize = function (callback) {
GUI.active_tab_ref = this;
var self = this;
if (GUI.active_tab != 'firmware_flasher') {
GUI.active_tab = 'firmware_flasher';
googleAnalytics.sendAppView('Firmware Flasher');
}
var intel_hex = false, // standard intel hex in string format
parsed_hex = false; // parsed raw hex in array format
@ -13,12 +16,74 @@ TABS.firmware_flasher.initialize = function (callback) {
// translate to user-selected language
localize();
function parse_hex(str, callback) {
// parsing hex in different thread
var worker = new Worker('./js/workers/hex_parser.js');
// "callback"
worker.onmessage = function (event) {
callback(event.data);
};
// send data/string over for processing
worker.postMessage(str);
}
// Fetch Releases
$.get('http://firmware.baseflight.net/listing.json', function (data) {
var releases = [],
releases_e = $('select[name="release"]').empty(),
d, date, offset;
// filter out what we need
for (var i = 0; i < data.length; i++) {
if (data[i].target == 'NAZE') {
releases.push(data[i]);
}
}
// reorder the array by time, TODO needs more testing
releases.sort(function (a, b) {
// stable releases always go first
if (a.release > b.release) {
return -1;
} else if (a.release < b.release) {
return 1;
}
// sort by time
return b.time - a.time;
});
// populate select
for (var i = 0; i < releases.length; i++) {
d = new Date(releases[i].time * 1000);
date = d.getFullYear() + '.' + ('0' + (d.getMonth() + 1)).slice(-2) + '.' + ('0' + (d.getDate())).slice(-2);
date += ' - ' + ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2);
var element = $('<option value="' + i + '">' + (((releases[i].release) ? 'Stable' : 'Dev') + ' ' + date) + '</option>').data('obj', releases[i]);
releases_e.append(element);
}
// bind events
$('select[name="release"]').change(function() {
if (!GUI.connect_lock) {
$('.progress').val(0).removeClass('valid invalid');
$('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherLoadFirmwareFile'));
$('div.git_info').slideUp();
$('a.flash_firmware').addClass('locked');
}
});
}).fail(function () {
$('select[name="release"]').empty().append('<option value="0">Offline</option>')
});
// UI Hooks
$('a.load_file').click(function () {
chrome.fileSystem.chooseEntry({type: 'openFile', accepts: [{extensions: ['hex']}]}, function (fileEntry) {
if (!fileEntry) {
// no "valid" file selected/created, aborting
console.log('No valid file selected, aborting');
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
return;
}
@ -67,26 +132,33 @@ TABS.firmware_flasher.initialize = function (callback) {
});
$('a.load_remote_file').click(function () {
$.get('https://raw.githubusercontent.com/cleanflight/cleanflight/master/obj/cleanflight_NAZE.hex', function (data) {
function process_hex(data, obj) {
intel_hex = data;
parse_hex(intel_hex, function (data) {
parsed_hex = data;
if (parsed_hex) {
var url;
googleAnalytics.sendEvent('Flashing', 'Firmware', 'online');
$('span.progressLabel').text('Loaded Online Firmware: (' + parsed_hex.bytes_total + ' bytes)');
$('span.progressLabel').html('<a class="save_firmware" href="#" title="Save Firmware">Loaded Online Firmware: (' + parsed_hex.bytes_total + ' bytes)</a>');
$('a.flash_firmware').removeClass('locked');
$.get('https://api.github.com/repos/cleanflight/cleanflight/commits?page=1&per_page=1&path=obj/cleanflight_NAZE.hex', function (data) {
var data = data[0],
$.get('https://api.github.com/repos/cleanflight/cleanflight/commits/' + obj.commit, function (data) {
var data = data,
d = new Date(data.commit.author.date),
date = ('0' + (d.getMonth() + 1)).slice(-2) + '.' + ('0' + (d.getDate() + 1)).slice(-2) + '.' + d.getFullYear();
offset = d.getTimezoneOffset() / 60,
date;
date = d.getFullYear() + '.' + ('0' + (d.getMonth() + 1)).slice(-2) + '.' + ('0' + (d.getDate())).slice(-2);
date += ' @ ' + ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2);
date += (offset > 0) ? ' GMT+' + offset : ' GMT' + offset;
$('div.git_info .committer').text(data.commit.author.name);
$('div.git_info .date').text(date);
$('div.git_info .hash').text(data.sha.slice(0, 7)).prop('href', 'https://github.com/cleanflight/cleanflight/commit/' + data.sha);
$('div.git_info .message').text(data.commit.message);
$('div.git_info').slideDown();
@ -95,10 +167,22 @@ TABS.firmware_flasher.initialize = function (callback) {
$('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherHexCorrupted'));
}
});
}).fail(function () {
}
function failed_to_load() {
$('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherFailedToLoadOnlineFirmware'));
$('a.flash_firmware').addClass('locked');
});
}
var obj = $('select[name="release"] option:selected').data('obj');
if (obj) { // undefined while list is loading or while running offline
$.get('http://firmware.baseflight.net/' + obj.file, function (data) {
process_hex(data, obj);
}).fail(failed_to_load);
} else {
$('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherFailedToLoadOnlineFirmware'));
}
});
$('a.flash_firmware').click(function () {
@ -153,10 +237,55 @@ TABS.firmware_flasher.initialize = function (callback) {
}
});
$(document).on('click', 'span.progressLabel a.save_firmware', function () {
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'baseflight', accepts: [{extensions: ['hex']}]}, function (fileEntry) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
return;
}
chrome.fileSystem.getDisplayPath(fileEntry, function (path) {
console.log('Saving firmware to: ' + path);
// check if file is writable
chrome.fileSystem.isWritableEntry(fileEntry, function (isWritable) {
if (isWritable) {
var blob = new Blob([intel_hex], {type: 'text/plain'});
fileEntry.createWriter(function (writer) {
var truncated = false;
writer.onerror = function (e) {
console.error(e);
};
writer.onwriteend = function() {
if (!truncated) {
// onwriteend will be fired again when truncation is finished
truncated = true;
writer.truncate(blob.size);
return;
}
};
writer.write(blob);
}, function (e) {
console.error(e);
});
} else {
console.log('You don\'t have write permissions for this file, sorry.');
GUI.log('You don\'t have <span style="color: red">write permissions</span> for this file');
}
});
});
});
});
chrome.storage.local.get('no_reboot_sequence', function (result) {
if (result.no_reboot_sequence) {
$('input.updating').prop('checked', true);
$('label.flash_on_connect_wrapper').show();
$('.flash_on_connect_wrapper').show();
} else {
$('input.updating').prop('checked', false);
}
@ -166,10 +295,10 @@ TABS.firmware_flasher.initialize = function (callback) {
var status = $(this).is(':checked');
if (status) {
$('label.flash_on_connect_wrapper').show();
$('.flash_on_connect_wrapper').show();
} else {
$('input.flash_on_connect').prop('checked', false).change();
$('label.flash_on_connect_wrapper').hide();
$('.flash_on_connect_wrapper').hide();
}
chrome.storage.local.set({'no_reboot_sequence': status});
@ -187,43 +316,28 @@ TABS.firmware_flasher.initialize = function (callback) {
var status = $(this).is(':checked');
if (status) {
var flashing_port;
var catch_new_port = function () {
PortHandler.port_detected('flash_detected_device', function (result) {
var port = result[0];
var start = function () {
PortHandler.port_detected('flash_next_device', function (result) {
flashing_port = result[0];
GUI.log('Detected: <strong>' + flashing_port + '</strong> - triggering flash on connect');
console.log('Detected: ' + flashing_port + ' - triggering flash on connect');
if (!GUI.connect_lock) {
GUI.log('Detected: <strong>' + port + '</strong> - triggering flash on connect');
console.log('Detected: ' + port + ' - triggering flash on connect');
// Trigger regular Flashing sequence
GUI.timeout_add('initialization_timeout', function () {
$('a.flash_firmware').click();
}, 100); // timeout so bus have time to initialize after being detected by the system
} else {
GUI.log('Detected <strong>' + port + '</strong> - previous device still flashing, please replug to try again');
}
// Detect port removal to create a new callback
end();
// Since current port_detected request was consumed, create new one
catch_new_port();
}, false, true);
}
};
var end = function () {
PortHandler.port_removed('flashed_device_removed', function (result) {
for (var i = 0; i < result.length; i++) {
if (result[i] == flashing_port) {
// flashed device removed
GUI.log('Removed: <strong>' + flashing_port + '</strong> - ready for next device');
console.log('Removed: ' + flashing_port + ' - ready for next device');
flashing_port = false;
start();
return;
}
}
// different device removed, we need to retry
end();
}, false, true);
}
start();
catch_new_port();
} else {
PortHandler.flush_callbacks();
}
@ -269,7 +383,7 @@ TABS.firmware_flasher.initialize = function (callback) {
$('a.back').click(function () {
if (!GUI.connect_lock) { // button disabled while flashing is in progress
GUI.tab_switch_cleanup(function () {
TABS.default.initialize();
TABS.landing.initialize();
});
} else {
GUI.log(chrome.i18n.getMessage('firmwareFlasherWaitForFinish'));
@ -285,19 +399,7 @@ TABS.firmware_flasher.cleanup = function (callback) {
// unbind "global" events
$(document).unbind('keypress');
$(document).off('click', 'span.progressLabel a');
if (callback) callback();
};
function parse_hex(str, callback) {
// parsing hex in different thread
var worker = new Worker('./js/workers/hex_parser.js');
// "callback"
worker.onmessage = function (event) {
callback(event.data);
};
// send data/string over for processing
worker.postMessage(str);
}

View File

@ -43,82 +43,82 @@
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td><progress value="0" max="16"></progress></td>
<td><progress value="0" max="99"></progress></td>
</tr>
</table>
</div>

View File

@ -2,9 +2,12 @@
TABS.gps = {};
TABS.gps.initialize = function (callback) {
GUI.active_tab_ref = this;
var self = this;
if (GUI.active_tab != 'gps') {
GUI.active_tab = 'gps';
googleAnalytics.sendAppView('GPS Page');
googleAnalytics.sendAppView('GPS');
}
function load_html() {
$('#content').load("./tabs/gps.html", process_html);
@ -17,7 +20,11 @@ TABS.gps.initialize = function (callback) {
localize();
function get_raw_gps_data() {
MSP.send_message(MSP_codes.MSP_RAW_GPS, false, false, get_gpsvinfo_data);
MSP.send_message(MSP_codes.MSP_RAW_GPS, false, false, get_comp_gps_data);
}
function get_comp_gps_data() {
MSP.send_message(MSP_codes.MSP_COMP_GPS, false, false, get_gpsvinfo_data);
}
function get_gpsvinfo_data() {
@ -53,7 +60,7 @@ TABS.gps.initialize = function (callback) {
GUI.interval_add('gps_pull', get_raw_gps_data, 75, true);
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function () {
GUI.interval_add('status_pull', function status_pull() {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);

View File

@ -1,342 +0,0 @@
.tab-initial_setup {
}
.tab-initial_setup .section {
clear: both;
padding-bottom: 8px;
}
.tab-initial_setup .section a {
display: block;
float: left;
width: 170px;
height: 24px;
line-height: 24px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-initial_setup .section a:hover {
background-color: #dedcdc;
}
.tab-initial_setup .section a.calibrating {
background-color: #c1c1c1;
}
.tab-initial_setup .section a.calibrating:hover {
cursor: default;
background-color: #c1c1c1;
}
.tab-initial_setup .section a.backup {
width: 80px;
margin-right: 10px;
}
.tab-initial_setup .section a.restore {
width: 80px;
}
.tab-initial_setup .section p {
margin-left: 180px;
padding: 5px;
border: 1px dotted silver;
}
#interactive_block {
float: left;
position: relative;
height: 280px;
width: 400px;
border: 1px solid silver;
background-color: white;
}
#interactive_block .modelPanel {
position: absolute;
}
#interactive_block .heading {
float: right;
height: 15px;
margin: 10px 10px 0 0;
font-weight: bold;
}
#interactive_block a.reset {
position: absolute;
display: block;
bottom: 10px;
right: 10px;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
z-index: 100;
}
#interactive_block a.reset:hover {
background-color: #dedcdc;
}
#perspective {
-webkit-perspective: 800;
-webkit-perspective-origin: 50% 150px; /* 150px = (350px / 2) - 25px */
}
#cube {
position: relative;
top: 110px;
left: 150px; /* (916px / 2) - 50px */
height: 100px;
width: 100px;
-webkit-transform-style: preserve-3d;
}
#cubePITCH {
-webkit-transform-style: preserve-3d;
}
#cubeROLL {
-webkit-transform-style: preserve-3d;
}
#cube .face {
position: absolute;
color: white;
font-size: 25px;
text-align: center;
}
#cube .face.one {
width: 100px;
height: 200px;
line-height: 200px;
font-size: 20px;
-webkit-transform: rotateX(-90deg) translateZ(-50px);
background-color: purple;
}
#cube .face.two {
width: 100px;
height: 50px;
line-height: 50px;
-webkit-transform: translateZ(100px);
background-color: blue;
}
#cube .face.three {
width: 200px;
height: 50px;
line-height: 50px;
-webkit-transform: rotateY(90deg);
background-color: green;
}
#cube .face.four {
width: 100px;
height: 50px;
line-height: 50px;
-webkit-transform: rotateY(180deg) translateZ(100px);
background-color: black;
}
#cube .face.five {
width: 200px;
height: 50px;
line-height: 50px;
-webkit-transform: rotateY(-90deg) translateZ(100px);
background-color: red;
}
#cube .face.six {
width: 100px;
height: 200px;
line-height: 200px;
-webkit-transform: rotateX(90deg) translateZ(100px);
background-color: silver;
}
.tab-initial_setup .battery,
.tab-initial_setup .throttle,
.tab-initial_setup .acc-trim,
.tab-initial_setup .magnetometer,
.tab-initial_setup .info {
float: left;
display: block;
margin: 0 0 10px 10px;
border: 1px solid silver;
}
.tab-initial_setup .battery .head,
.tab-initial_setup .throttle .head,
.tab-initial_setup .acc-trim .head,
.tab-initial_setup .magnetometer .head,
.tab-initial_setup .info .head {
display: block;
text-align: center;
line-height: 20px;
font-weight: bold;
border-bottom: 1px solid silver;
background-color: #ececec;
}
.tab-initial_setup .battery .fields,
.tab-initial_setup .throttle .fields,
.tab-initial_setup .magnetometer .fields,
.tab-initial_setup .info .fields {
padding: 5px 5px 3px 5px;
}
.tab-initial_setup .acc-trim .fields {
padding: 5px 5px 3px 5px;
}
.tab-initial_setup .magnetometer .fields {
padding: 5px 5px 5px 5px;
}
.tab-initial_setup .battery dt {
float: left;
width: 105px;
height: 22px;
margin-bottom: 2px;
line-height: 22px;
}
.tab-initial_setup .battery dd {
height: 22px;
margin-left: 105px;
margin-bottom: 2px;
line-height: 22px;
}
.tab-initial_setup .battery input {
width: 60px;
height: 20px;
line-height: 20px;
border: 1px solid silver;
text-align: center;
}
.tab-initial_setup .throttle dt {
float: left;
width: 90px;
height: 22px;
margin-bottom: 2px;
line-height: 22px;
}
.tab-initial_setup .throttle dd {
height: 22px;
margin-left: 90px;
margin-bottom: 2px;
line-height: 22px;
}
.tab-initial_setup .throttle input {
width: 60px;
height: 20px;
line-height: 20px;
border: 1px solid silver;
text-align: center;
}
.tab-initial_setup .acc-trim dt {
float: left;
width: 65px;
height: 22px;
line-height: 22px;
margin-bottom: 2px;
}
.tab-initial_setup .acc-trim dd {
height: 22px;
margin-left: 65px;
margin-bottom: 2px;
}
.tab-initial_setup .acc-trim input {
width: 60px;
height: 20px;
line-height: 20px;
border: 1px solid silver;
text-align: center;
}
.tab-initial_setup .magnetometer dt {
float: left;
width: 90px;
height: 20px;
line-height: 22px;
margin-bottom: 2px;
}
.tab-initial_setup .magnetometer dd {
height: 20px;
line-height: 22px;
margin-left: 90px;
margin-bottom: 2px;
}
.tab-initial_setup .magnetometer input {
width: 60px;
height: 20px;
line-height: 20px;
border: 1px solid silver;
text-align: center;
}
.tab-initial_setup .info dt {
float: left;
width: 100px;
height: 20px;
line-height: 20px;
}
.tab-initial_setup .info dd {
width: 70px;
height: 20px;
line-height: 20px;
margin-left: 100px;
}
.tab-initial_setup .buttons {
width: calc(100% - 20px);
position: absolute;
bottom: 10px;
}
.tab-initial_setup .update {
display: block;
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-initial_setup .update:hover {
background-color: #dedcdc;
}

View File

@ -1,102 +0,0 @@
<div class="tab-initial_setup">
<div class="section">
<a class="calibrateAccel" href="#" i18n="initialSetupButtonCalibrateAccel"></a>
<p i18n="initialSetupCalibrateAccelText">
</p>
</div>
<div class="section">
<a class="calibrateMag" href="#" i18n="initialSetupButtonCalibrateMag"></a>
<p i18n="initialSetupCalibrateMagText">
</p>
</div>
<div class="section">
<a class="resetSettings" href="#" i18n="initialSetupButtonReset"></a>
<p i18n="initialSetupResetText">
</p>
</div>
<div class="section">
<a class="backup" href="#" i18n="initialSetupButtonBackup"></a>
<a class="restore" href="#" i18n="initialSetupButtonRestore"></a>
<p i18n="initialSetupBackupRestoreText">
</p>
</div>
<div id="interactive_block">
<div class="modelPanel">
<span class="model"></span>
<img class="modelMixDiagram" src="" alt="">
</div>
<span class="heading"></span>
<div class="clear-both"></div>
<a class="reset" href="#" i18n="initialSetupButtonResetZaxis"></a>
<div id="perspective">
<div id="cube">
<div id="cubePITCH">
<div id="cubeROLL">
<div class="face one">BOTTOM</div>
<div class="face two">BACK</div>
<div class="face three">RIGHT</div>
<div class="face four">FRONT</div>
<div class="face five">LEFT</div>
<div class="face six">TOP</div>
</div>
</div>
</div>
</div>
</div>
<div class="left">
<div class="throttle">
<span class="head" i18n="initialSetupThrottleHead"></span>
<div class="fields">
<dl>
<dt i18n="initialSetupMinimum"></dt><dd><input type="number" name="minthrottle" min="0" max="2000" /></dd>
<dt i18n="initialSetupMaximum"></dt><dd><input type="number" name="maxthrottle" min="0" max="2000" /></dd>
<dt i18n="initialSetupFailsafe"></dt><dd><input type="number" name="failsafe_throttle" min="1000" max="2000" /></dd>
<dt i18n="initialSetupMinCommand"></dt><dd><input type="number" name="mincommand" min="0" max="2000" /></dd>
</dl>
</div>
</div>
<div class="battery">
<span class="head" i18n="initialSetupBatteryHead"></span>
<div class="fields">
<dl>
<dt i18n="initialSetupMinCellV"></dt><dd><input type="number" name="mincellvoltage" step="0.1" min="1" max="5" /></dd>
<dt i18n="initialSetupMaxCellV"></dt><dd><input type="number" name="maxcellvoltage" step="0.1" min="1" max="5" /></dd>
<dt i18n="initialSetupVoltageScale"></dt><dd><input type="number" name="voltagescale" step="1" min="10" max="200" /></dd>
</dl>
</div>
</div>
<div class="acc-trim">
<span class="head" i18n="initialSetupAccelTrimsHead"></span>
<div class="fields">
<dl>
<dt i18n="initialSetupPitch"></dt><dd><input type="number" name="pitch" min="-300" max="300" /></dd>
<dt i18n="initialSetupRoll"></dt><dd><input type="number" name="roll" min="-300" max="300" /></dd>
</dl>
</div>
</div>
<div class="clear-both"></div>
<div class="magnetometer">
<span class="head" i18n="initialSetupMagHead"></span>
<div class="fields">
<dl>
<dt i18n="initialSetupDeclination"></dt><dd><input type="number" name="mag_declination" step="0.1" min="-180" max="180" /></dd>
</dl>
</div>
</div>
<div class="info">
<span class="head" i18n="initialSetupInfoHead"></span>
<div class="fields">
<dl>
<dt i18n="initialSetupBattery"></dt><dd class="bat-voltage">0 V</dd>
<dt i18n="initialSetupDrawn"></dt><dd class="bat-mah-drawn">0 mAh</dd>
<dt i18n="initialSetupDrawing"></dt><dd class="bat-mah-drawing">0 A</dd>
<dt i18n="initialSetupRSSI"></dt><dd class="rssi">0 %</dd>
</dl>
</div>
</div>
<div class="clear-both"></div>
</div>
<div class="buttons">
<a class="update" href="#" i18n="initialSetupButtonSave"></a>
</div>
</div>

View File

@ -1,218 +0,0 @@
'use strict';
TABS.initial_setup = {
yaw_fix: 0.0
};
TABS.initial_setup.initialize = function (callback) {
var self = this;
GUI.active_tab_ref = this;
GUI.active_tab = 'initial_setup';
googleAnalytics.sendAppView('Initial Setup');
function load_ident() {
MSP.send_message(MSP_codes.MSP_IDENT, false, false, load_misc_data);
}
function load_misc_data() {
MSP.send_message(MSP_codes.MSP_MISC, false, false, load_html);
}
function load_html() {
$('#content').load("./tabs/initial_setup.html", process_html);
}
MSP.send_message(MSP_codes.MSP_ACC_TRIM, false, false, load_ident);
function process_html() {
// translate to user-selected language
localize();
// Fill in misc stuff
$('input[name="mincellvoltage"]').val(MISC.vbatmincellvoltage);
$('input[name="maxcellvoltage"]').val(MISC.vbatmaxcellvoltage);
$('input[name="voltagescale"]').val(MISC.vbatscale);
$('input[name="minthrottle"]').val(MISC.minthrottle);
$('input[name="maxthrottle"]').val(MISC.maxthrottle);
$('input[name="failsafe_throttle"]').val(MISC.failsafe_throttle);
$('input[name="mincommand"]').val(MISC.mincommand);
$('input[name="mag_declination"]').val(MISC.mag_declination / 10);
// Fill in the accel trimms from CONFIG object
$('input[name="pitch"]').val(CONFIG.accelerometerTrims[0]);
$('input[name="roll"]').val(CONFIG.accelerometerTrims[1]);
update_model(CONFIG.multiType);
// Heading
$('span.heading').text(chrome.i18n.getMessage('initialSetupheading', [0]));
// UI Hooks
$('a.calibrateAccel').click(function () {
var self = $(this);
if (!self.hasClass('calibrating')) {
self.addClass('calibrating');
// During this period MCU won't be able to process any serial commands because its locked in a for/while loop
// until this operation finishes, sending more commands through data_poll() will result in serial buffer overflow
GUI.interval_pause('initial_setup_data_pull');
MSP.send_message(MSP_codes.MSP_ACC_CALIBRATION, false, false, function () {
GUI.log(chrome.i18n.getMessage('initialSetupAccelCalibStarted'));
});
GUI.timeout_add('button_reset', function () {
GUI.interval_resume('initial_setup_data_pull');
GUI.log(chrome.i18n.getMessage('initialSetupAccelCalibEnded'));
self.removeClass('calibrating');
}, 2000);
}
});
$('a.calibrateMag').click(function () {
var self = $(this);
if (!self.hasClass('calibrating')) {
self.addClass('calibrating');
MSP.send_message(MSP_codes.MSP_MAG_CALIBRATION, false, false, function () {
GUI.log(chrome.i18n.getMessage('initialSetupMagCalibStarted'));
});
GUI.timeout_add('button_reset', function () {
GUI.log(chrome.i18n.getMessage('initialSetupMagCalibEnded'));
self.removeClass('calibrating');
}, 30000);
}
});
$('a.resetSettings').click(function() {
MSP.send_message(MSP_codes.MSP_RESET_CONF, false, false, function () {
GUI.log(chrome.i18n.getMessage('initialSetupSettingsRestored'));
GUI.tab_switch_cleanup(function() {
TABS.initial_setup.initialize();
});
});
});
$('a.update').click(function () {
CONFIG.accelerometerTrims[0] = parseInt($('input[name="pitch"]').val());
CONFIG.accelerometerTrims[1] = parseInt($('input[name="roll"]').val());
var buffer_out = new Array();
buffer_out[0] = lowByte(CONFIG.accelerometerTrims[0]);
buffer_out[1] = highByte(CONFIG.accelerometerTrims[0]);
buffer_out[2] = lowByte(CONFIG.accelerometerTrims[1]);
buffer_out[3] = highByte(CONFIG.accelerometerTrims[1]);
// Send over the new trims
MSP.send_message(MSP_codes.MSP_SET_ACC_TRIM, buffer_out);
MISC.vbatmincellvoltage = parseFloat($('input[name="mincellvoltage"]').val()) * 10;
MISC.vbatmaxcellvoltage = parseFloat($('input[name="maxcellvoltage"]').val()) * 10;
MISC.vbatscale = parseInt($('input[name="voltagescale"]').val());
MISC.minthrottle = parseInt($('input[name="minthrottle"]').val());
MISC.maxthrottle = parseInt($('input[name="maxthrottle"]').val());
MISC.failsafe_throttle = parseInt($('input[name="failsafe_throttle"]').val());
MISC.mincommand = parseInt($('input[name="mincommand"]').val());
MISC.mag_declination = parseFloat($('input[name="mag_declination"]').val()) * 10;
// we also have to fill the unsupported bytes
var buffer_out = new Array();
buffer_out[0] = 0; // powerfailmeter
buffer_out[1] = 0;
buffer_out[2] = lowByte(MISC.minthrottle);
buffer_out[3] = highByte(MISC.minthrottle);
buffer_out[4] = lowByte(MISC.maxthrottle);
buffer_out[5] = highByte(MISC.maxthrottle);
buffer_out[6] = lowByte(MISC.mincommand);
buffer_out[7] = highByte(MISC.mincommand);
buffer_out[8] = lowByte(MISC.failsafe_throttle);
buffer_out[9] = highByte(MISC.failsafe_throttle);
buffer_out[10] = 0;
buffer_out[11] = 0;
buffer_out[12] = 0;
buffer_out[13] = 0;
buffer_out[14] = 0;
buffer_out[15] = 0;
buffer_out[16] = lowByte(MISC.mag_declination);
buffer_out[17] = highByte(MISC.mag_declination);
buffer_out[18] = MISC.vbatscale;
buffer_out[19] = MISC.vbatmincellvoltage;
buffer_out[20] = MISC.vbatmaxcellvoltage;
buffer_out[21] = 0; // vbatlevel_crit (unused)
// Send over new misc
MSP.send_message(MSP_codes.MSP_SET_MISC, buffer_out, false, save_to_eeprom);
function save_to_eeprom() {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
GUI.log(chrome.i18n.getMessage('initialSetupEepromSaved'));
});
}
});
// display current yaw fix value (important during tab re-initialization)
$('div#interactive_block > a.reset').text(chrome.i18n.getMessage('initialSetupButtonResetZaxisValue', [self.yaw_fix]));
// reset yaw button hook
$('div#interactive_block > a.reset').click(function () {
self.yaw_fix = SENSOR_DATA.kinematics[2] * - 1.0;
$(this).text(chrome.i18n.getMessage('initialSetupButtonResetZaxisValue', [self.yaw_fix]));
console.log('YAW reset to 0 deg, fix: ' + self.yaw_fix + ' deg');
});
$('#content .backup').click(configuration_backup);
$('#content .restore').click(configuration_restore);
// data pulling functions used inside interval timer
function get_analog_data() {
MSP.send_message(MSP_codes.MSP_ANALOG, false, false, get_attitude_data);
}
function get_attitude_data() {
MSP.send_message(MSP_codes.MSP_ATTITUDE, false, false, update_ui);
}
function update_ui() {
// Update voltage indicator
$('.bat-voltage').text(chrome.i18n.getMessage('initialSetupBatteryValue', [ANALOG.voltage]));
$('.bat-mah-drawn').text(chrome.i18n.getMessage('initialSetupBatteryMahValue', [ANALOG.mAhdrawn]));
$('.bat-mah-drawing').text(chrome.i18n.getMessage('initialSetupBatteryAValue', [ANALOG.amperage.toFixed(2)]));
$('.rssi').text(chrome.i18n.getMessage('initialSetupRSSIValue', [((ANALOG.rssi / 1023) * 100).toFixed(0)]));
// Update cube
var cube = $('div#cube');
cube.css('-webkit-transform', 'rotateY(' + ((SENSOR_DATA.kinematics[2] * -1.0) - self.yaw_fix) + 'deg)');
$('#cubePITCH', cube).css('-webkit-transform', 'rotateX(' + SENSOR_DATA.kinematics[1] + 'deg)');
$('#cubeROLL', cube).css('-webkit-transform', 'rotateZ(' + SENSOR_DATA.kinematics[0] + 'deg)');
// Update heading
$('span.heading').text(chrome.i18n.getMessage('initialSetupheading', [SENSOR_DATA.kinematics[2]]));
}
GUI.interval_add('initial_setup_data_pull', get_analog_data, 50, true);
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function () {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);
if (callback) callback();
}
};
TABS.initial_setup.cleanup = function (callback) {
if (callback) callback();
};

160
tabs/landing.css Normal file
View File

@ -0,0 +1,160 @@
.tab-landing .left {
width: 60%;
}
.tab-landing .right {
float: left;
margin-left: 10px;
width: calc(40% - 10px);
}
.tab-landing .optional_permissions {
display: none;
margin-bottom: 10px;
border: 1px solid silver;
}
.tab-landing .optional_permissions .title {
line-height: 20px;
text-align: center;
font-weight: bold;
color: white;
border-bottom: 1px solid silver;
background-color: #cd4c4c;
}
.tab-landing .optional_permissions p {
padding: 5px;
}
.tab-landing .optional_permissions a {
display: block;
float: left;
height: 28px;
line-height: 28px;
margin: 0 0 5px 5px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-landing .optional_permissions a:hover {
background-color: #dedcdc;
}
.welcome {
margin-bottom: 10px;
padding: 5px;
border: 1px solid silver;
}
.welcome a {
font-weight: bold;
}
.welcome a:hover {
text-decoration: underline;
}
.changelog {
margin: 0 0 10px 0;
border: 1px solid silver;
}
.changelog .title {
line-height: 20px;
text-align: center;
font-weight: bold;
color: white;
border-bottom: 1px solid silver;
background-color: #3f4241;
}
.changelog .wrapper {
height: 150px;
padding: 5px;
overflow-y: scroll;
overflow-x: hidden;
-webkit-user-select: text;
}
.changelog .wrapper span {
font-weight: bold;
}
.changelog .wrapper p {
margin-bottom: 5px;
}
.donate {
padding: 0 0 5px 0;
border: 1px solid silver;
}
.donate .title {
line-height: 20px;
text-align: center;
font-weight: bold;
color: white;
border-bottom: 1px solid silver;
background-color: #3f4241;
}
.donate p {
padding: 5px;
}
.donate a {
display: block;
width: 74px;
height: 21px;
margin: auto;
}
.firmware_flasher {
display: block;
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.firmware_flasher:hover {
background-color: #dedcdc;
}
.tab-landing .sponsors {
margin-top: 10px;
border: 1px solid silver;
}
.tab-landing .sponsors .title {
line-height: 20px;
text-align: center;
font-weight: bold;
color: white;
border-bottom: 1px solid silver;
background-color: #3f4241;
}
.tab-landing .sponsors p {
padding: 5px;
}
.tab-landing .sponsors p a {
font-weight: bold;
}
.tab-landing .sponsors p a:hover {
text-decoration: underline;
}

View File

@ -1,4 +1,4 @@
<div class="tab-default">
<div class="tab-landing">
<div class="left">
<div class="optional_permissions">
<div class="title" i18n="default_optional_permissions_head"></div>
@ -20,6 +20,9 @@
<p>
&bull; <a href="http://www.massiverc.com" title="www.massiverc.com" target="_blank">MassiveRC</a><br />
</p>
<p>
&bull; <a href="http://www.armattanquads.com/" title="www.armattanquads.com" target="_blank">Armattan Quads</a><br />
</p>
</div>
</div>
<div class="right">

View File

@ -1,11 +1,15 @@
'use strict';
TABS.default = {};
TABS.default.initialize = function (callback) {
GUI.active_tab_ref = this;
GUI.active_tab = 'default';
TABS.landing = {};
TABS.landing.initialize = function (callback) {
var self = this;
$('#content').load("./tabs/default.html", function () {
if (GUI.active_tab != 'landing') {
GUI.active_tab = 'landing';
googleAnalytics.sendAppView('Landing');
}
$('#content').load("./tabs/landing.html", function () {
//check_usb_permissions(); // temporary enabled in dev branch, should be commented out untill DFU support goes live
// translate to user-selected language
@ -27,6 +31,6 @@ TABS.default.initialize = function (callback) {
});
};
TABS.default.cleanup = function (callback) {
TABS.landing.cleanup = function (callback) {
if (callback) callback();
};

View File

@ -2,11 +2,17 @@
TABS.logging = {};
TABS.logging.initialize = function (callback) {
GUI.active_tab_ref = this;
var self = this;
if (GUI.active_tab != 'logging') {
GUI.active_tab = 'logging';
googleAnalytics.sendAppView('Logging');
}
var requested_properties = [];
var requested_properties = [],
samples = 0,
requests = 0,
log_buffer = [];
if (CONFIGURATOR.connectionValid) {
var get_motor_data = function () {
@ -18,20 +24,6 @@ TABS.logging.initialize = function (callback) {
}
MSP.send_message(MSP_codes.MSP_RC, false, false, get_motor_data);
} else {
CONFIGURATOR.mspPassThrough = true;
// we will initialize RC.channels array and MOTOR_DATA array manually
RC.active_channels = 8;
for (var i = 0; i < RC.active_channels; i++) {
RC.channels[i] = 0;
}
for (var i = 0; i < 8; i++) {
MOTOR_DATA[i] = 0;
}
$('#content').load("./tabs/logging.html", process_html);
}
function process_html() {
@ -68,12 +60,10 @@ TABS.logging.initialize = function (callback) {
}
// request new
if (!CONFIGURATOR.mspPassThrough) {
for (var i = 0; i < requested_properties.length; i++, requests++) {
MSP.send_message(MSP_codes[requested_properties[i]]);
}
}
}
GUI.interval_add('log_data_poll', log_data_poll, parseInt($('select.speed').val()), true); // refresh rate goes here
GUI.interval_add('write_data', function write_data() {
@ -111,22 +101,6 @@ TABS.logging.initialize = function (callback) {
}
});
if (CONFIGURATOR.mspPassThrough) {
$('a.back').show();
$('a.back').click(function() {
if (GUI.connected_to) {
$('a.connect').click();
} else {
GUI.tab_switch_cleanup(function () {
CONFIGURATOR.mspPassThrough = false;
$('#tabs > ul li').removeClass('active');
TABS.default.initialize();
});
}
});
}
chrome.storage.local.get('logging_file_entry', function (result) {
if (result.logging_file_entry) {
chrome.fileSystem.restoreEntry(result.logging_file_entry, function (entry) {
@ -201,10 +175,6 @@ TABS.logging.initialize = function (callback) {
append_to_file(head);
}
var samples = 0,
requests = 0,
log_buffer = [];
function crunch_data() {
var sample = millitime();

64
tabs/modes.css Normal file
View File

@ -0,0 +1,64 @@
.tab-modes .boxes {
width: 100%;
border-collapse: collapse;
}
.tab-modes .boxes th, .tab-modes .boxes td {
line-height: 22px;
text-align: center;
border: 1px solid #8b8b8b;
}
.tab-modes .boxes .heads {
background-color: #ececec;
}
.tab-modes .boxes .main {
background-color: #ececec;
}
.tab-modes .boxes .name {
text-align: center;
}
.tab-modes .boxes .on {
color: white;
background-color: #0d8b13;
}
.tab-modes .boxes .off {
color: white;
background-color: #be2222;
}
.tab-modes .boxes td input {
position: absolute;
margin-top: -6px;
margin-left: -6px;
}
.tab-modes .boxes .switches:nth-child(odd) {
background-color: #ececec;
}
.tab-modes .boxes .heads th:first-child {
border: 0;
background-color: white;
}
.tab-modes .buttons {
width: calc(100% - 20px);
position: absolute;
bottom: 10px;
}
.tab-modes .update {
display: block;
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-modes .update:hover {
background-color: #dedcdc;
}

13
tabs/modes.html Normal file
View File

@ -0,0 +1,13 @@
<div class="tab-modes">
<table class="boxes">
<tr class="heads">
<th style="width: 18%"></th>
</tr>
<tr class="main">
<th i18n="auxiliaryName"></th>
</tr>
</table>
<div class="buttons">
<a class="update" href="#" i18n="auxiliaryButtonSave"></a>
</div>
</div>

156
tabs/modes.js Normal file
View File

@ -0,0 +1,156 @@
'use strict';
TABS.modes = {};
TABS.modes.initialize = function (callback) {
var self = this;
if (GUI.active_tab != 'modes') {
GUI.active_tab = 'modes';
googleAnalytics.sendAppView('Modes');
}
function get_box_data() {
MSP.send_message(MSP_codes.MSP_BOX, false, false, get_box_ids);
}
function get_box_ids() {
MSP.send_message(MSP_codes.MSP_BOXIDS, false, false, get_rc_data);
}
function get_rc_data() {
MSP.send_message(MSP_codes.MSP_RC, false, false, load_html);
}
function load_html() {
$('#content').load("./tabs/modes.html", process_html);
}
MSP.send_message(MSP_codes.MSP_BOXNAMES, false, false, get_box_data);
function process_html() {
// generate heads according to RC count
var table_head = $('table.boxes .heads');
var main_head = $('table.boxes .main');
for (var i = 0; i < (RC.active_channels - 4); i++) {
table_head.append('<th colspan="3">AUX ' + (i + 1) + '</th>');
// 3 columns per aux channel (this might be requested to change to 6 in the future, so watch out)
main_head.append('\
<th i18n="auxiliaryLow"></th>\
<th i18n="auxiliaryMed"></th>\
<th i18n="auxiliaryHigh"></th>\
');
}
// translate to user-selected language
localize();
// generate table from the supplied AUX names and AUX data
for (var i = 0; i < AUX_CONFIG.length; i++) {
var line = '<tr class="switches">';
line += '<td class="name">' + AUX_CONFIG[i] + '</td>';
for (var j = 0; j < (RC.active_channels - 4) * 3; j++) {
if (bit_check(AUX_CONFIG_values[i], j)) {
line += '<td><input type="checkbox" checked="checked" /></td>';
} else {
line += '<td><input type="checkbox" /></td>';
}
}
line += '</tr>';
$('.boxes > tbody:last').append(line);
}
// UI Hooks
$('a.update').click(function () {
// catch the input changes
var main_needle = 0,
needle = 0;
$('.boxes input').each(function () {
if ($(this).is(':checked')) {
AUX_CONFIG_values[main_needle] = bit_set(AUX_CONFIG_values[main_needle], needle);
} else {
AUX_CONFIG_values[main_needle] = bit_clear(AUX_CONFIG_values[main_needle], needle);
}
needle++;
if (needle >= (RC.active_channels - 4) * 3) { // 1 aux * 3 checkboxes, 4 AUX = 12 bits per line
main_needle++;
needle = 0;
}
});
function save_to_eeprom() {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
GUI.log(chrome.i18n.getMessage('auxiliaryEepromSaved'));
});
}
MSP.send_message(MSP_codes.MSP_SET_BOX, MSP.crunch(MSP_codes.MSP_SET_BOX), false, save_to_eeprom);
});
// val = channel value
// aux_num = position of corresponding aux channel in the html table
var switches_e = $('table.boxes .switches');
function box_highlight(aux_num, val) {
var pos = 0; // < 1300
if (val > 1300 && val < 1700) {
pos = 1;
} else if (val > 1700) {
pos = 2;
}
var highlight_column = (aux_num * 3) + pos + 2; // +2 to skip name column and index starting on 1 instead of 0
var erase_columns = (aux_num * 3) + 2;
$('td:nth-child(n+' + erase_columns + '):nth-child(-n+' + (erase_columns + 2) + ')', switches_e).css('background-color', 'transparent');
$('td:nth-child(' + highlight_column + ')', switches_e).css('background-color', 'orange');
}
// data pulling functions used inside interval timer
function get_rc_data() {
MSP.send_message(MSP_codes.MSP_RC, false, false, update_ui);
}
function update_ui() {
for (var i = 0; i < AUX_CONFIG.length; i++) {
if (bit_check(CONFIG.mode, i)) {
$('td.name').eq(i).addClass('on').removeClass('off');
} else {
$('td.name').eq(i).removeClass('on').removeClass('off');
if (AUX_CONFIG_values[i] > 0) {
$('td.name').eq(i).addClass('off');
}
}
}
for (var i = 0; i < (RC.active_channels - 4); i++) {
box_highlight(i, RC.channels[i + 4]);
}
}
// update ui instantly on first load
update_ui();
// enable data pulling
GUI.interval_add('aux_data_pull', get_rc_data, 50);
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function status_pull() {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);
if (callback) callback();
}
};
TABS.modes.cleanup = function (callback) {
if (callback) callback();
};

View File

@ -1,193 +0,0 @@
.wrapper.accelAndModel .wrapper.accel {
float: left;
width: calc(100% - 110px);
}
.tab-motor_outputs .plot_control {
float: right;
width: 158px;
border: 1px solid silver;
}
.tab-motor_outputs .plot_control .title {
line-height: 20px;
font-weight: bold;
text-align: center;
border-bottom: 1px solid silver;
background-color: #ececec;
}
.tab-motor_outputs .plot_control .title a:hover {
text-decoration: underline;
}
.tab-motor_outputs .plot_control dl {
padding: 5px 5px 0 5px;
line-height: 22px;
}
.tab-motor_outputs .plot_control dt {
float: left;
width: 60px;
height: 22px;
font-weight: bold;
}
.tab-motor_outputs .plot_control dd {
height: 22px;
}
.tab-motor_outputs .plot_control select {
float: right;
width: 80px;
border: 1px solid silver;
}
.tab-motor_outputs .plot_control .x {
color: #00A8F0;
}
.tab-motor_outputs .plot_control .y {
color: #C0D800;
}
.tab-motor_outputs .plot_control .z {
color: #CB4B4B;
}
.tab-motor_outputs .plot_control .x, .tab-motor_outputs .plot_control .y, .tab-motor_outputs .plot_control .z {
text-align: right;
}
.tab-motor_outputs svg {
float: left;
width: calc(100% - 168px); /* - (plot control, margin)*/
height: 140px;
margin-bottom: 10px;
}
.tab-motor_outputs .grid .tick {
stroke: silver;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.tab-motor_outputs .grid path {
stroke-width: 0;
}
.tab-motor_outputs .data .line {
stroke-width: 2px;
fill: none;
}
.tab-motor_outputs .axis path, .tab-motor_outputs .axis line {
fill: none;
stroke: #000000;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.tab-motor_outputs .line:nth-child(1) {
stroke: #00A8F0;
}
.tab-motor_outputs .line:nth-child(2) {
stroke: #C0D800;
}
.tab-motor_outputs .line:nth-child(3) {
stroke: #CB4B4B;
}
.tab-motor_outputs .left.motors {
float: left;
width: calc(50% - 50px);
}
.tab-motor_outputs .right.servos {
float: right;
width: 50%;
}
.tab-motor_outputs .title {
padding-bottom: 2px;
text-align: center;
font-weight: bold;
}
.tab-motor_outputs .titles {
height: 20px;
}
.tab-motor_outputs .titles li {
float: left;
width: calc((100% / 9) - 10px);
margin-right: 10px;
text-align: center;
}
.tab-motor_outputs .servos .titles li {
float: right;
width: calc((100% / 8) - 10px);
margin: 0 0 0 10px;
}
.tab-motor_outputs .titles .active {
color: green;
}
.tab-motor_outputs .m-block {
float: left;
width: calc((100% / 9) - 12px);
height: 100px;
margin-right: 10px;
border: 1px solid silver;
background-color: #e9e9e9;
}
.tab-motor_outputs .servos .m-block {
float: right;
width: calc((100% / 8) - 12px);
margin: 0 0 0 10px;
}
.tab-motor_outputs .indicator {
float: left;
width: 100%;
}
.tab-motor_outputs .motor_testing {
display: none;
margin-top: 15px;
}
.tab-motor_outputs .motor_testing .left {
width: calc(50% - 50px);
}
.tab-motor_outputs .motor_testing .sliders input {
-webkit-appearance: slider-vertical;
width: calc((100% / 9) - 13px);
height: 100px;
margin-right: 10px;
}
.tab-motor_outputs .motor_testing .sliders input:first-child {
/* margin-left: 2px; */ /* seems to vary depending on chrome version O.o */
}
.tab-motor_outputs .motor_testing .values {
margin-top: 5px;
}
.tab-motor_outputs .motor_testing .values li {
float: left;
width: calc((100% / 9) - 10px);
margin-right: 10px;
text-align: center;
}
.tab-motor_outputs .motor_testing .notice {
float: right;
width: calc(50% - 22px);
padding: 5px;
border: 1px dotted silver;
}
.tab-motor_outputs .motor_testing .notice input[type="checkbox"] {
vertical-align: middle;
}

210
tabs/motors.css Normal file
View File

@ -0,0 +1,210 @@
.tab-motors .plot_control {
float: right;
width: 158px;
border: 1px solid silver;
}
.tab-motors .plot_control .title {
line-height: 20px;
font-weight: bold;
text-align: center;
border-bottom: 1px solid silver;
background-color: #ececec;
}
.tab-motors .plot_control .title a:hover {
text-decoration: underline;
}
.tab-motors .plot_control dl {
padding: 5px 5px 0 5px;
line-height: 22px;
}
.tab-motors .plot_control dt {
float: left;
width: 60px;
height: 22px;
font-weight: bold;
}
.tab-motors .plot_control dd {
height: 22px;
}
.tab-motors .plot_control select {
float: right;
width: 80px;
border: 1px solid silver;
}
.tab-motors .plot_control .x {
color: #00A8F0;
}
.tab-motors .plot_control .y {
color: #C0D800;
}
.tab-motors .plot_control .z {
color: #CB4B4B;
}
.tab-motors .plot_control .x, .tab-motors .plot_control .y, .tab-motors .plot_control .z {
text-align: right;
}
.tab-motors svg {
float: left;
width: calc(100% - 168px); /* - (plot control, margin)*/
height: 140px;
margin-bottom: 10px;
}
.tab-motors .grid .tick {
stroke: silver;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.tab-motors .grid path {
stroke-width: 0;
}
.tab-motors .data .line {
stroke-width: 2px;
fill: none;
}
.tab-motors .axis path, .tab-motors .axis line {
fill: none;
stroke: #000000;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.tab-motors .line:nth-child(1) {
stroke: #00A8F0;
}
.tab-motors .line:nth-child(2) {
stroke: #C0D800;
}
.tab-motors .line:nth-child(3) {
stroke: #CB4B4B;
}
.tab-motors .left.motors {
float: left;
width: calc(50% - 50px);
}
.tab-motors .right.servos {
float: right;
width: 50%;
}
.tab-motors .title {
padding-bottom: 2px;
text-align: center;
font-weight: bold;
}
.tab-motors .titles {
height: 20px;
}
.tab-motors .titles li {
float: left;
width: calc((100% / 9) - 10px);
margin-right: 10px;
text-align: center;
}
.tab-motors .servos .titles li {
float: right;
width: calc((100% / 8) - 10px);
margin: 0 0 0 10px;
}
.tab-motors .titles .active {
color: green;
}
.tab-motors .m-block {
float: left;
width: calc((100% / 9) - 12px);
height: 100px;
margin-right: 10px;
text-align: center;
border: 1px solid silver;
background-color: #f4f4f4;
}
.tab-motors .m-block .meter-bar {
position: relative;
width: 100%;
height: 100px;
}
.tab-motors .m-block .label {
position: absolute;
width: 100%;
bottom: 45px;
text-align: center;
font-weight: bold;
color: #474747;
}
.tab-motors .m-block .indicator .label {
color: white;
}
.tab-motors .servos .m-block {
float: right;
width: calc((100% / 8) - 12px);
margin: 0 0 0 10px;
}
.tab-motors .indicator {
position: absolute;
overflow: hidden;
width: 100%;
text-align: center;
}
.tab-motors .motor_testing {
margin-top: 15px;
}
.tab-motors .motor_testing .left {
width: calc(50% - 50px);
}
.tab-motors .motor_testing .sliders input {
-webkit-appearance: slider-vertical;
width: calc((100% / 9) - 13px);
height: 100px;
margin-right: 10px;
}
.tab-motors .motor_testing .sliders input:first-child {
/* margin-left: 2px; */ /* seems to vary depending on chrome version O.o */
}
.tab-motors .motor_testing .values {
margin-top: 5px;
}
.tab-motors .motor_testing .values li {
float: left;
width: calc((100% / 9) - 10px);
margin-right: 10px;
text-align: center;
}
.tab-motors .motor_testing .notice {
float: right;
width: calc(50% - 22px);
padding: 5px;
border: 1px dotted silver;
}
.tab-motors .motor_testing .notice input[type="checkbox"] {
vertical-align: middle;
}

View File

@ -1,9 +1,4 @@
<div class="tab-motor_outputs">
<div class="wrapper accelAndModel">
<div class="modelPanel">
<span class="model"></span>
<img class="modelMixDiagram" src="" alt="">
</div>
<div class="tab-motors">
<div class="wrapper accel">
<div class="plot_control">
<div class="title">Accelerometer - <a class="reset_accel_max" href="#" title="Reset overtime maximum">[Reset]</a></div>
@ -49,7 +44,6 @@
</svg>
<div class="clear-both"></div>
</div>
</div>
<div class="left motors">
<div class="title">Motors</div>
<ul class="titles">
@ -63,14 +57,6 @@
<li title="Motor - 8">8</li>
</ul>
<div class="bar-wrapper">
<div class="m-block motor-0"><div class="indicator"></div></div>
<div class="m-block motor-1"><div class="indicator"></div></div>
<div class="m-block motor-2"><div class="indicator"></div></div>
<div class="m-block motor-3"><div class="indicator"></div></div>
<div class="m-block motor-4"><div class="indicator"></div></div>
<div class="m-block motor-5"><div class="indicator"></div></div>
<div class="m-block motor-6"><div class="indicator"></div></div>
<div class="m-block motor-7"><div class="indicator"></div></div>
</div>
</div>
<div class="right servos">
@ -86,14 +72,6 @@
<li title="Servo - 1">1</li>
</ul>
<div class="bar-wrapper">
<div class="m-block servo-7"><div class="indicator"></div></div>
<div class="m-block servo-6"><div class="indicator"></div></div>
<div class="m-block servo-5"><div class="indicator"></div></div>
<div class="m-block servo-4"><div class="indicator"></div></div>
<div class="m-block servo-3"><div class="indicator"></div></div>
<div class="m-block servo-2"><div class="indicator"></div></div>
<div class="m-block servo-1"><div class="indicator"></div></div>
<div class="m-block servo-0"><div class="indicator"></div></div>
</div>
</div>
<div class="clear-both"></div>

View File

@ -1,10 +1,23 @@
'use strict';
TABS.motor_outputs = {};
TABS.motor_outputs.initialize = function (callback) {
GUI.active_tab_ref = this;
GUI.active_tab = 'motor_outputs';
googleAnalytics.sendAppView('Motor Outputs Page');
TABS.motors = {};
TABS.motors.initialize = function (callback) {
var self = this;
if (GUI.active_tab != 'motors') {
GUI.active_tab = 'motors';
googleAnalytics.sendAppView('Motors');
}
function get_motor_data() {
MSP.send_message(MSP_codes.MSP_MOTOR, false, false, load_html);
}
function load_html() {
$('#content').load("./tabs/motors.html", process_html);
}
MSP.send_message(MSP_codes.MSP_MISC, false, false, get_motor_data);
function initSensorData() {
for (var i = 0; i < 3; i++) {
@ -124,16 +137,6 @@ TABS.motor_outputs.initialize = function (callback) {
lines.attr('d', graphHelpers.line);
}
function get_motor_data() {
MSP.send_message(MSP_codes.MSP_MOTOR, false, false, load_html);
}
function load_html() {
$('#content').load("./tabs/motor_outputs.html", process_html);
}
MSP.send_message(MSP_codes.MSP_MISC, false, false, get_motor_data);
function process_html() {
// translate to user-selected language
localize();
@ -144,18 +147,19 @@ TABS.motor_outputs.initialize = function (callback) {
initSensorData();
// Setup variables
var samples_accel_i = 0;
var accel_data = initDataArray(3);
var accelHelpers = initGraphHelpers('#accel', samples_accel_i, [-2, 2]);
var accel_max_read = [0, 0, 0];
var accel_offset = [0, 0, 0];
var accel_offset_established = false;
var samples_accel_i = 0,
accel_data = initDataArray(3),
accelHelpers = initGraphHelpers('#accel', samples_accel_i, [-2, 2]),
accel_max_read = [0, 0, 0],
accel_offset = [0, 0, 0],
accel_offset_established = false;
var raw_data_text_ements = {
x: [],
y: [],
z: [],
z: []
};
$('.plot_control .x, .plot_control .y, .plot_control .z').each(function () {
var el = $(this);
if (el.hasClass('x')) {
@ -170,20 +174,20 @@ TABS.motor_outputs.initialize = function (callback) {
// set refresh speeds according to configuration saved in storage
chrome.storage.local.get('motors_tab_accel_settings', function (result) {
if (result.motors_tab_accel_settings) {
$('.tab-motor_outputs select[name="accel_refresh_rate"]').val(result.motors_tab_accel_settings.rate);
$('.tab-motor_outputs select[name="accel_scale"]').val(result.motors_tab_accel_settings.scale);
$('.tab-motors select[name="accel_refresh_rate"]').val(result.motors_tab_accel_settings.rate);
$('.tab-motors select[name="accel_scale"]').val(result.motors_tab_accel_settings.scale);
// start polling data by triggering refresh rate change event
$('.tab-motor_outputs .rate select:first').change();
$('.tab-motors .rate select:first').change();
} else {
// start polling immediatly (as there is no configuration saved in the storage)
$('.tab-motor_outputs .rate select:first').change();
$('.tab-motors .rate select:first').change();
}
});
$('.tab-motor_outputs .rate select, .tab-motor_outputs .scale select').change(function () {
var rate = parseInt($('.tab-motor_outputs select[name="accel_refresh_rate"]').val(), 10);
var scale = parseFloat($('.tab-motor_outputs select[name="accel_scale"]').val());
$('.tab-motors .rate select, .tab-motors .scale select').change(function () {
var rate = parseInt($('.tab-motors select[name="accel_refresh_rate"]').val(), 10);
var scale = parseFloat($('.tab-motors select[name="accel_scale"]').val());
// store current/latest refresh rates in the storage
chrome.storage.local.set({'motors_tab_accel_settings': {'rate': rate, 'scale': scale}});
@ -209,7 +213,7 @@ TABS.motor_outputs.initialize = function (callback) {
var accel_with_offset = [
accel_offset[0] + SENSOR_DATA.accelerometer[0],
accel_offset[1] + SENSOR_DATA.accelerometer[1],
accel_offset[2] + SENSOR_DATA.accelerometer[2],
accel_offset[2] + SENSOR_DATA.accelerometer[2]
];
updateGraphHelperSize(accelHelpers);
@ -231,16 +235,38 @@ TABS.motor_outputs.initialize = function (callback) {
accel_offset_established = false;
});
// if CAP_DYNBALANCE is true
if (bit_check(CONFIG.capability, 2)) {
$('div.motor_testing').show();
}
var number_of_valid_outputs = (MOTOR_DATA.indexOf(0) > -1) ? MOTOR_DATA.indexOf(0) : 8;
$('input.min').val(MISC.mincommand);
$('input.max').val(MISC.maxthrottle);
var motors_wrapper = $('.motors .bar-wrapper'),
servos_wrapper = $('.servos .bar-wrapper');
for (var i = 0; i < 8; i++) {
motors_wrapper.append('\
<div class="m-block motor-' + i + '">\
<div class="meter-bar">\
<div class="label"></div>\
<div class="indicator">\
<div class="label">\
<div class="label"></div>\
</div>\
</div>\
</div>\
</div>\
');
servos_wrapper.append('\
<div class="m-block servo-' + i + '">\
<div class="meter-bar">\
<div class="label"></div>\
<div class="indicator">\
<div class="label">\
<div class="label"></div>\
</div>\
</div>\
</div>\
</div>\
');
}
$('div.sliders input').prop('min', MISC.mincommand);
$('div.sliders input').prop('max', MISC.maxthrottle);
@ -356,24 +382,24 @@ TABS.motor_outputs.initialize = function (callback) {
var block_height = $('div.m-block:first').height();
for (var i = 0; i < MOTOR_DATA.length; i++) {
var data = MOTOR_DATA[i] - MISC.mincommand;
var margin_top = block_height - (data * (block_height / full_block_scale));
var height = (data * (block_height / full_block_scale));
var color = parseInt(data * 0.256);
var data = MOTOR_DATA[i] - MISC.mincommand,
margin_top = block_height - (data * (block_height / full_block_scale)).clamp(0, block_height),
height = (data * (block_height / full_block_scale)).clamp(0, block_height),
color = parseInt(data * 0.256);
$('.motor-' + i).prop('title', MOTOR_DATA[i] + ' us');
$('.motor-' + i + ' .indicator').css({'margin-top' : margin_top + 'px', 'height' : height + 'px', 'background-color' : 'rgb(' + color + ',0,0)'});
$('.motor-' + i + ' .label', motors_wrapper).text(MOTOR_DATA[i]);
$('.motor-' + i + ' .indicator', motors_wrapper).css({'margin-top' : margin_top + 'px', 'height' : height + 'px', 'background-color' : 'rgb(' + color + ',0,0)'});
}
// servo indicators are still using old (not flexible block scale), it will be changed in the future accordingly
for (var i = 0; i < SERVO_DATA.length; i++) {
var data = SERVO_DATA[i] - 1000;
var margin_top = block_height - (data * (block_height / 1000));
var height = (data * (block_height / 1000));
var color = parseInt(data * 0.256);
var data = SERVO_DATA[i] - 1000,
margin_top = block_height - (data * (block_height / 1000)).clamp(0, block_height),
height = (data * (block_height / 1000)).clamp(0, block_height),
color = parseInt(data * 0.256);
$('.servo-' + i).prop('title', SERVO_DATA[i] + ' us');
$('.servo-' + i + ' .indicator').css({'margin-top' : margin_top + 'px', 'height' : height + 'px', 'background-color' : 'rgb(' + color + ',0,0)'});
$('.servo-' + i + ' .label', servos_wrapper).text(SERVO_DATA[i]);
$('.servo-' + i + ' .indicator', servos_wrapper).css({'margin-top' : margin_top + 'px', 'height' : height + 'px', 'background-color' : 'rgb(' + color + ',0,0)'});
}
}
@ -381,7 +407,7 @@ TABS.motor_outputs.initialize = function (callback) {
GUI.interval_add('motor_pull', get_motor_data, 50, true);
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function get_status_data() {
GUI.interval_add('status_pull', function status_pull() {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);
@ -389,6 +415,6 @@ TABS.motor_outputs.initialize = function (callback) {
}
};
TABS.motor_outputs.cleanup = function (callback) {
TABS.motors.cleanup = function (callback) {
if (callback) callback();
};

View File

@ -28,11 +28,10 @@
.tab-pid_tuning table input {
display: block;
width: calc(100% - 10px);
width: 100%;
height: 20px;
line-height: 20px;
padding: 0 5px 0 5px;
text-align: right;
}
.tab-pid_tuning .profile {
@ -52,16 +51,11 @@
border-bottom: 1px solid #8b8b8b;
background-color: #ececec;
}
.tab-pid_tuning .profile input {
display: block;
width: calc(100% - 10px);
.tab-pid_tuning .profile select {
width: 100%;
padding-left: calc(100% - 35px);
height: 20px;
line-height: 20px;
padding: 0 5px 0 5px;
text-align: right;
}
.tab-pid_tuning .pid_tuning {
width: 60%;

View File

@ -79,7 +79,11 @@
<div class="clear-both"></div>
<div class="profile">
<span class="head" i18n="pidTuningProfileHead"></span>
<input type="number" name="profile" min="1" max="3" />
<select name="profile">
<option value="0">1</option>
<option value="1">2</option>
<option value="2">3</option>
</select>
</div>
<div class="buttons">
<a class="update" href="#" i18n="pidTuningButtonSave"></a>

View File

@ -2,9 +2,12 @@
TABS.pid_tuning = {};
TABS.pid_tuning.initialize = function (callback) {
GUI.active_tab_ref = this;
var self = this;
if (GUI.active_tab != 'pid_tuning') {
GUI.active_tab = 'pid_tuning';
googleAnalytics.sendAppView('PID Tuning');
}
function get_pid_names() {
MSP.send_message(MSP_codes.MSP_PIDNAMES, false, false, get_pid_data);
@ -179,13 +182,13 @@ TABS.pid_tuning.initialize = function (callback) {
$('.rate-tpa input[name="tpa"]').val(RC_tuning.dynamic_THR_PID.toFixed(2));
// Fill in currently selected profile
$('input[name="profile"]').val(CONFIG.profile + 1); // +1 because the range is 0-2
$('select[name="profile"]').val(CONFIG.profile);
// UI Hooks
$('input[name="profile"]').change(function () {
$('select[name="profile"]').change(function () {
var profile = parseInt($(this).val());
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [profile - 1], false, function () {
GUI.log(chrome.i18n.getMessage('pidTuningLoadedProfile', [profile]));
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [profile], false, function () {
GUI.log(chrome.i18n.getMessage('pidTuningLoadedProfile', [profile + 1]));
GUI.tab_switch_cleanup(function () {
TABS.pid_tuning.initialize();
@ -253,54 +256,13 @@ TABS.pid_tuning.initialize = function (callback) {
PIDs[8][i++] = parseFloat($(this).val());
});
var PID_buffer_out = new Array();
for (var i = 0, needle = 0; i < PIDs.length; i++, needle += 3) {
switch (i) {
case 0:
case 1:
case 2:
case 3:
case 7:
case 8:
case 9:
PID_buffer_out[needle] = parseInt(PIDs[i][0] * 10);
PID_buffer_out[needle + 1] = parseInt(PIDs[i][1] * 1000);
PID_buffer_out[needle + 2] = parseInt(PIDs[i][2]);
break;
case 4:
PID_buffer_out[needle] = parseInt(PIDs[i][0] * 100);
PID_buffer_out[needle + 1] = parseInt(PIDs[i][1] * 100);
PID_buffer_out[needle + 2] = parseInt(PIDs[i][2]);
break;
case 5:
case 6:
PID_buffer_out[needle] = parseInt(PIDs[i][0] * 10);
PID_buffer_out[needle + 1] = parseInt(PIDs[i][1] * 100);
PID_buffer_out[needle + 2] = parseInt(PIDs[i][2] * 1000);
break;
}
}
// Send over the PID changes
MSP.send_message(MSP_codes.MSP_SET_PID, PID_buffer_out, false, send_rc_tuning_changes);
function send_rc_tuning_changes() {
// catch RC_tuning changes
RC_tuning.roll_pitch_rate = parseFloat($('.rate-tpa input[name="roll-pitch"]').val());
RC_tuning.yaw_rate = parseFloat($('.rate-tpa input[name="yaw"]').val());
RC_tuning.dynamic_THR_PID = parseFloat($('.rate-tpa input[name="tpa"]').val());
var RC_tuning_buffer_out = new Array();
RC_tuning_buffer_out[0] = parseInt(RC_tuning.RC_RATE * 100);
RC_tuning_buffer_out[1] = parseInt(RC_tuning.RC_EXPO * 100);
RC_tuning_buffer_out[2] = parseInt(RC_tuning.roll_pitch_rate * 100);
RC_tuning_buffer_out[3] = parseInt(RC_tuning.yaw_rate * 100);
RC_tuning_buffer_out[4] = parseInt(RC_tuning.dynamic_THR_PID * 100);
RC_tuning_buffer_out[5] = parseInt(RC_tuning.throttle_MID * 100);
RC_tuning_buffer_out[6] = parseInt(RC_tuning.throttle_EXPO * 100);
// Send over the RC_tuning changes
MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, RC_tuning_buffer_out, false, save_to_eeprom);
function send_rc_tuning_changes() {
MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, MSP.crunch(MSP_codes.MSP_SET_RC_TUNING), false, save_to_eeprom);
}
function save_to_eeprom() {
@ -308,10 +270,12 @@ TABS.pid_tuning.initialize = function (callback) {
GUI.log(chrome.i18n.getMessage('pidTuningEepromSaved'));
});
}
MSP.send_message(MSP_codes.MSP_SET_PID, MSP.crunch(MSP_codes.MSP_SET_PID), false, send_rc_tuning_changes);
});
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function () {
GUI.interval_add('status_pull', function status_pull() {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);

View File

@ -11,42 +11,7 @@
}
.tab-receiver .bars ul {
margin-bottom: 5px;
}
.tab-receiver .bars ul:nth-of-type(1) {
color: #00A8F0;
}
.tab-receiver .bars ul:nth-of-type(2) {
color: #C0D800;
}
.tab-receiver .bars ul:nth-of-type(3) {
color: #f8921a;
}
.tab-receiver .bars ul:nth-of-type(4) {
color: #f02525;
}
.tab-receiver .bars ul:nth-of-type(5) {
color: #9440ED;
}
.tab-receiver .bars ul:nth-of-type(6) {
color: #45147a;
}
.tab-receiver .bars ul:nth-of-type(7) {
color: #cf7a26;
}
.tab-receiver .bars ul:nth-of-type(8) {
color: #147a66;
}
.tab-receiver .bars ul:nth-of-type(9) {
color: #0609a9;
}
.tab-receiver .bars ul:nth-of-type(10) {
color: #7a1445;
}
.tab-receiver .bars ul:nth-of-type(11) {
color: #267acf;
}
.tab-receiver .bars ul:nth-of-type(12) {
color: #7a6614;
clear: left;
}
.tab-receiver .bars li {
float: left;
@ -55,22 +20,82 @@
line-height: 20px;
}
.tab-receiver .bars .name {
width: 60px;
padding: 0 10px 0 0;
width: 40px;
text-align: right;
}
.tab-receiver .bars .meter {
width: 70%;
width: calc(100% - 50px);
}
.tab-receiver .bars .meter meter {
margin-top: 4px;
.tab-receiver .bars .meter-bar {
position: relative;
margin-top: 2px;
width: 100%;
height: 14px;
height: 15px;
border: 1px solid silver;
background-color: #f4f4f4;
}
.tab-receiver .bars .value {
.tab-receiver .bars .meter-bar .label {
position: absolute;
width: 50px;
margin-left: 10px;
height: 15px;
line-height: 15px;
text-align: center;
color: #474747;
}
.tab-receiver .bars .meter-bar .fill {
position: relative;
overflow: hidden;
width: 50%;
height: 15px;
background-color: green;
}
.tab-receiver .bars .meter-bar .fill .label {
color: white;
}
.tab-receiver .bars ul:nth-of-type(1) .fill {
background-color: #00A8F0;
}
.tab-receiver .bars ul:nth-of-type(2) .fill {
background-color: #C0D800;
}
.tab-receiver .bars ul:nth-of-type(3) .fill {
background-color: #f8921a;
}
.tab-receiver .bars ul:nth-of-type(4) .fill {
background-color: #f02525;
}
.tab-receiver .bars ul:nth-of-type(5) .fill {
background-color: #9440ED;
}
.tab-receiver .bars ul:nth-of-type(6) .fill {
background-color: #45147a;
}
.tab-receiver .bars ul:nth-of-type(7) .fill {
background-color: #cf7a26;
}
.tab-receiver .bars ul:nth-of-type(8) .fill {
background-color: #147a66;
}
.tab-receiver .bars ul:nth-of-type(9) .fill {
background-color: #0609a9;
}
.tab-receiver .bars ul:nth-of-type(10) .fill {
background-color: #7a1445;
}
.tab-receiver .bars ul:nth-of-type(11) .fill {
background-color: #267acf;
}
.tab-receiver .bars ul:nth-of-type(12) .fill {
background-color: #7a6614;
}
.tab-receiver .tunings {
float: right;
@ -79,7 +104,7 @@
border-collapse: collapse;
}
.tab-receiver .tunings .throttle {
margin-bottom: 22px;
margin-bottom: 10px;
}
.tab-receiver .tunings table, .tab-receiver .tunings table th, .tab-receiver .tunings table td {
padding: 4px;
@ -95,13 +120,77 @@
background-color: #ececec;
}
.tab-receiver .tunings table input {
width: 116px;
width: 100%;
height: 20px;
line-height: 20px;
padding: 0 5px 0 5px;
line-height: 20px;
text-align: right;
}
.tab-receiver .rssi_aux_wrapper {
float: right;
margin: 10px 0 0 0;
width: 126px;
border: 1px solid #8b8b8b;
border-left: 0;
}
.tab-receiver .rssi_aux_wrapper .head {
height: 15px;
padding: 4px;
text-align: center;
font-weight: bold;
border-bottom: 1px solid #8b8b8b;
background-color: #ececec;
}
.tab-receiver .rssi_aux_wrapper select {
width: 100%;
height: 22px;
padding-left: 5px;
}
.tab-receiver .rcmap_wrapper {
float: right;
position: relative;
margin: 10px 0 0 0;
width: 126px;
border: 1px solid #8b8b8b;
}
.tab-receiver .rcmap_wrapper .head {
height: 15px;
padding: 4px;
text-align: center;
font-weight: bold;
border-bottom: 1px solid #8b8b8b;
background-color: #ececec;
}
.tab-receiver .rcmap_wrapper .head span {
border-bottom: 1px dashed silver;
}
.tab-receiver .hybrid_element input {
position: absolute;
padding-left: 5px;
width: calc(100% - 24px);
height: 22px;
z-index: 2;
}
.tab-receiver .hybrid_element select {
width: 100%;
height: 22px;
z-index: 1;
}
.tab-receiver .curves {
float: right;
}
@ -197,7 +286,6 @@
.tab-receiver .refresh:hover {
background-color: #dedcdc;
}
/* SVG classes*/
.tab-receiver .grid .tick {
stroke: silver;

View File

@ -22,6 +22,29 @@
<td><input type="number" name="expo" step="0.01" min="0" max="1" /></td>
</tr>
</table>
<div class="rssi_aux_wrapper">
<div class="head" i18n="receiverRssiAux"></div>
<select name="rssi_aux_channel">
<option value="0">Disabled</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<div class="rcmap_wrapper">
<div class="head">
<span i18n="receiverChannelMap" i18n_title="receiverChannelMapTitle"></span>
</div>
<div class="hybrid_element">
<input type="text" name="rcmap" spellcheck="false" />
<select class="hybrid_helper" name="rcmap_helper">
<option value="AETR1234">Default</option>
<option value="AETR1234">Futaba / Hitec</option>
<option value="TAER1234">JR / Spektrum</option>
</select>
</div>
</div>
</div>
<div class="curves">
<div class="throttle_curve">

View File

@ -2,19 +2,30 @@
TABS.receiver = {};
TABS.receiver.initialize = function (callback) {
GUI.active_tab_ref = this;
var self = this;
if (GUI.active_tab != 'receiver') {
GUI.active_tab = 'receiver';
googleAnalytics.sendAppView('Receiver Page');
googleAnalytics.sendAppView('Receiver');
}
function get_misc_data() {
MSP.send_message(MSP_codes.MSP_MISC, false, false, get_rc_data);
}
function get_rc_data() {
MSP.send_message(MSP_codes.MSP_RC, false, false, load_html);
MSP.send_message(MSP_codes.MSP_RC, false, false, get_rc_map);
}
function get_rc_map() {
MSP.send_message(MSP_codes.MSP_RCMAP, false, false, load_html);
}
function load_html() {
$('#content').load("./tabs/receiver.html", process_html);
}
MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, get_rc_data);
MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, get_misc_data);
function process_html() {
// translate to user-selected language
@ -51,72 +62,181 @@ TABS.receiver.initialize = function (callback) {
bar_container.append('\
<ul>\
<li class="name">' + name + '</li>\
<li class="meter"><meter min="800" max="2200"></meter></li>\
<li class="value"></li>\
<li class="meter">\
<div class="meter-bar">\
<div class="label"></div>\
<div class="fill">\
<div class="label"></div>\
</div>\
</div>\
</li>\
</ul>\
<div class="clear-both"></div>\
');
}
var meter_array = [];
$('meter', bar_container).each(function () {
meter_array.push($(this));
// we could probably use min and max throttle for the range, will see
var meter_scale = {
'min': 800,
'max': 2200
};
var meter_fill_array = [];
$('.meter .fill', bar_container).each(function () {
meter_fill_array.push($(this));
});
var meter_values_array = [];
$('.value', bar_container).each(function () {
meter_values_array.push($(this));
var meter_label_array = [];
$('.meter', bar_container).each(function () {
meter_label_array.push($('.label' , this));
});
// correct inner label margin on window resize (i don't know how we could do this in css)
self.resize = function () {
var containerWidth = $('.meter:first', bar_container).width(),
labelWidth = $('.meter .label:first', bar_container).width(),
margin = (containerWidth / 2) - (labelWidth / 2);
for (var i = 0; i < meter_label_array.length; i++) {
meter_label_array[i].css('margin-left', margin);
}
};
$(window).on('resize', self.resize).resize(); // trigger so labels get correctly aligned on creation
// handle rcmap & rssi aux channel
var RC_MAP_Letters = ['A', 'E', 'R', 'T', '1', '2', '3', '4'];
var strBuffer = [];
for (var i = 0; i < RC_MAP.length; i++) {
strBuffer[RC_MAP[i]] = RC_MAP_Letters[i];
}
// reconstruct
var str = strBuffer.join('');
// set current value
$('input[name="rcmap"]').val(str);
// validation / filter
var last_valid = str;
$('input[name="rcmap"]').on('input', function () {
var val = $(this).val();
// limit length to max 8
if (val.length > 8) {
val = val.substr(0, 8);
$(this).val(val);
}
});
$('input[name="rcmap"]').focusout(function () {
var val = $(this).val(),
strBuffer = val.split(''),
duplicityBuffer = [];
if (val.length != 8) {
$(this).val(last_valid);
return false;
}
// check if characters inside are all valid, also check for duplicity
for (var i = 0; i < val.length; i++) {
if (RC_MAP_Letters.indexOf(strBuffer[i]) < 0) {
$(this).val(last_valid);
return false;
}
if (duplicityBuffer.indexOf(strBuffer[i]) < 0) {
duplicityBuffer.push(strBuffer[i]);
} else {
$(this).val(last_valid);
return false;
}
}
});
// handle helper
$('select[name="rcmap_helper"]').val(0); // go out of bounds
$('select[name="rcmap_helper"]').change(function () {
$('input[name="rcmap"]').val($(this).val());
});
// rssi aux
$('select[name="rssi_aux_channel"]').val(MISC.rssi_aux_channel);
// UI Hooks
// curves
$('.tunings .throttle input').change(function () {
setTimeout(function () {
var mid = parseFloat($('.tunings .throttle input[name="mid"]').val());
var expo = parseFloat($('.tunings .throttle input[name="expo"]').val());
$('.tunings .throttle input').on('input change', function () {
setTimeout(function () { // let global validation trigger and adjust the values first
var throttleMidE = $('.tunings .throttle input[name="mid"]'),
throttleExpoE = $('.tunings .throttle input[name="expo"]'),
mid = parseFloat(throttleMidE.val()),
expo = parseFloat(throttleExpoE.val()),
throttle_curve = $('.throttle_curve canvas').get(0),
context = throttle_curve.getContext("2d");
var throttle_curve = $('.throttle_curve canvas').get(0);
var context = throttle_curve.getContext("2d");
context.clearRect(0, 0, 220, 58);
// local validation to deal with input event
if (mid >= parseFloat(throttleMidE.prop('min')) &&
mid <= parseFloat(throttleMidE.prop('max')) &&
expo >= parseFloat(throttleExpoE.prop('min')) &&
expo <= parseFloat(throttleExpoE.prop('max'))) {
// continue
} else {
return;
}
// math magic by englishman
var midx = 220 * mid;
var midxl = midx * 0.5;
var midxr = (((220 - midx) * 0.5) + midx);
var midy = 58 - (midx * (58 / 220));
var midyl = 58 - ((58 - midy) * 0.5 *(expo + 1));
var midyr = (midy / 2) * (expo + 1);
var midx = 220 * mid,
midxl = midx * 0.5,
midxr = (((220 - midx) * 0.5) + midx),
midy = 58 - (midx * (58 / 220)),
midyl = 58 - ((58 - midy) * 0.5 *(expo + 1)),
midyr = (midy / 2) * (expo + 1);
// draw
context.clearRect(0, 0, 220, 58);
context.beginPath();
context.moveTo(0, 58);
context.quadraticCurveTo(midxl, midyl, midx, midy);
context.moveTo(midx, midy);
context.quadraticCurveTo(midxr, midyr, 220, 0);
context.lineWidth = 2;
context.stroke();
}, 0); // race condition, that should always trigger after all events are processed
}).change();
}, 0);
}).trigger('input');
$('.tunings .rate input').change(function () {
setTimeout(function () {
var rate = parseFloat($('.tunings .rate input[name="rate"]').val());
var expo = parseFloat($('.tunings .rate input[name="expo"]').val());
$('.tunings .rate input').on('input change', function () {
setTimeout(function () { // let global validation trigger and adjust the values first
var rateE = $('.tunings .rate input[name="rate"]'),
expoE = $('.tunings .rate input[name="expo"]'),
rate = parseFloat(rateE.val()),
expo = parseFloat(expoE.val()),
pitch_roll_curve = $('.pitch_roll_curve canvas').get(0),
context = pitch_roll_curve.getContext("2d");
var pitch_roll_curve = $('.pitch_roll_curve canvas').get(0);
var context = pitch_roll_curve.getContext("2d");
context.clearRect(0, 0, 220, 58);
// local validation to deal with input event
if (rate >= parseFloat(rateE.prop('min')) &&
rate <= parseFloat(rateE.prop('max')) &&
expo >= parseFloat(expoE.prop('min')) &&
expo <= parseFloat(expoE.prop('max'))) {
// continue
} else {
return;
}
// math magic by englishman
var ratey = 58 * rate;
// draw
context.clearRect(0, 0, 220, 58);
context.beginPath();
context.moveTo(0, 58);
context.quadraticCurveTo(110, 58 - ((ratey / 2) * (1 - expo)), 220, 58 - ratey);
context.lineWidth = 2;
context.stroke();
}, 0); // race condition, that should always trigger after all events are processed
}).change();
}, 0);
}).trigger('input');
$('a.refresh').click(function () {
MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, function () {
@ -143,23 +263,32 @@ TABS.receiver.initialize = function (callback) {
RC_tuning.RC_RATE = parseFloat($('.tunings .rate input[name="rate"]').val());
RC_tuning.RC_EXPO = parseFloat($('.tunings .rate input[name="expo"]').val());
var RC_tuning_buffer_out = new Array();
RC_tuning_buffer_out[0] = parseInt(RC_tuning.RC_RATE * 100, 10);
RC_tuning_buffer_out[1] = parseInt(RC_tuning.RC_EXPO * 100, 10);
RC_tuning_buffer_out[2] = parseInt(RC_tuning.roll_pitch_rate * 100, 10);
RC_tuning_buffer_out[3] = parseInt(RC_tuning.yaw_rate * 100, 10);
RC_tuning_buffer_out[4] = parseInt(RC_tuning.dynamic_THR_PID * 100, 10);
RC_tuning_buffer_out[5] = parseInt(RC_tuning.throttle_MID * 100, 10);
RC_tuning_buffer_out[6] = parseInt(RC_tuning.throttle_EXPO * 100, 10);
// catch rc map
var RC_MAP_Letters = ['A', 'E', 'R', 'T', '1', '2', '3', '4'];
var strBuffer = $('input[name="rcmap"]').val().split('');
// Send over the RC_tuning changes
MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, RC_tuning_buffer_out, false, save_to_eeprom);
for (var i = 0; i < RC_MAP.length; i++) {
RC_MAP[i] = strBuffer.indexOf(RC_MAP_Letters[i]);
}
// catch rssi aux
MISC.rssi_aux_channel = parseInt($('select[name="rssi_aux_channel"]').val());
function save_rc_map() {
MSP.send_message(MSP_codes.MSP_SET_RCMAP, MSP.crunch(MSP_codes.MSP_SET_RCMAP), false, save_misc);
}
function save_misc() {
MSP.send_message(MSP_codes.MSP_SET_MISC, MSP.crunch(MSP_codes.MSP_SET_MISC), false, save_to_eeprom);
}
function save_to_eeprom() {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
GUI.log(chrome.i18n.getMessage('receiverEepromSaved'));
});
}
MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, MSP.crunch(MSP_codes.MSP_SET_RC_TUNING), false, save_rc_map);
});
$('select[name="rx_refresh_rate"]').change(function () {
@ -195,8 +324,8 @@ TABS.receiver.initialize = function (callback) {
function update_ui() {
// update bars with latest data
for (var i = 0; i < RC.active_channels; i++) {
meter_array[i].val(RC.channels[i]);
meter_values_array[i].text('[ ' + RC.channels[i] + ' ]');
meter_fill_array[i].css('width', ((RC.channels[i] - meter_scale.min) / (meter_scale.max - meter_scale.min) * 100).clamp(0, 100) + '%');
meter_label_array[i].text(RC.channels[i]);
}
// push latest data to the main array
@ -267,7 +396,7 @@ TABS.receiver.initialize = function (callback) {
});
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function () {
GUI.interval_add('status_pull', function status_pull() {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);
@ -276,5 +405,7 @@ TABS.receiver.initialize = function (callback) {
};
TABS.receiver.cleanup = function (callback) {
$(window).off('resize', this.resize);
if (callback) callback();
};

11
tabs/review.html Normal file
View File

@ -0,0 +1,11 @@
<div class="head" i18n="reviewhead"></div>
<div class="wrapper">
<p class="initial" i18n="reviewInitial"></p>
<p class="storeReview" i18n="reviewStore"></p>
<p class="bugTicket" i18n="reviewBug"></p>
<div class="buttons">
<div class="yes" i18n="reviewYes"></div>
<div class="no" i18n="reviewNo"></div>
</div>
<div class="clear-both"></div>
</div>

View File

@ -2,9 +2,12 @@
TABS.sensors = {};
TABS.sensors.initialize = function (callback) {
GUI.active_tab_ref = this;
var self = this;
if (GUI.active_tab != 'sensors') {
GUI.active_tab = 'sensors';
googleAnalytics.sendAppView('Sensor Page');
googleAnalytics.sendAppView('Sensors');
}
function initSensorData(){
for (var i = 0; i < 3; i++) {
@ -257,7 +260,7 @@ TABS.sensors.initialize = function (callback) {
var raw_data_text_ements = {
x: [],
y: [],
z: [],
z: []
};
$('.plot_control .x, .plot_control .y, .plot_control .z').each(function () {
var el = $(this);
@ -405,7 +408,7 @@ TABS.sensors.initialize = function (callback) {
});
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function () {
GUI.interval_add('status_pull', function status_pull() {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);
@ -414,7 +417,7 @@ TABS.sensors.initialize = function (callback) {
};
TABS.sensors.cleanup = function (callback) {
serial.empty_output_buffer();
serial.emptyOutputBuffer();
if (callback) callback();
};

View File

@ -55,11 +55,9 @@
.tab-servos table input[type="number"] {
display: block;
width: calc(100% - 5px);
width: 100%;
height: 20px;
padding-right: 5px;
line-height: 20px;
text-align: right;

Some files were not shown because too many files have changed in this diff Show More