From b47892eca1342bc038c90db5d6d8092e26739463 Mon Sep 17 00:00:00 2001 From: cTn Date: Mon, 21 Jul 2014 03:48:35 +0200 Subject: [PATCH 01/54] lower the "contacting bootloader" timeout from buggy 4s to 1s --- js/stm32.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/js/stm32.js b/js/stm32.js index 95633489..5b632c23 100644 --- a/js/stm32.js +++ b/js/stm32.js @@ -352,9 +352,15 @@ 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: FAILED'); GUI.interval_remove('stm32_initialize_mcu'); + GUI.interval_remove('STM32_timeout'); + + // exit + self.upload_procedure(99); } - }, 200, true); + }, 250, true); break; case 2: // get version of the bootloader and supported commands From 8d678116440d4d3a3025362006f2e1a68b7793ca Mon Sep 17 00:00:00 2001 From: cTn Date: Mon, 21 Jul 2014 07:21:03 +0200 Subject: [PATCH 02/54] since erasing only needed pages appears to be working correctly, removing it from experimental --- js/stm32.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/stm32.js b/js/stm32.js index 5b632c23..d2a12df7 100644 --- a/js/stm32.js +++ b/js/stm32.js @@ -399,7 +399,6 @@ STM32_protocol.prototype.upload_procedure = function(step) { GUI.log('Erasing ...'); if (!$('input.erase_chip').is(':checked')) { - // EXPERIMENTAL console.log('Executing local erase (only needed pages)'); self.send([self.command.erase, 0xBC], 1, function(reply) { // 0x43 ^ 0xFF From 93ab8dfba3df6711d7cfbc1ad2d981cd6302cb54 Mon Sep 17 00:00:00 2001 From: cTn Date: Tue, 22 Jul 2014 13:20:26 +0200 Subject: [PATCH 03/54] move flashing protocols to separate folder --- js/{ => protocols}/stm32.js | 0 js/{stm32dfu.js => protocols/stm32usbdfu.js} | 0 main.html | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename js/{ => protocols}/stm32.js (100%) rename js/{stm32dfu.js => protocols/stm32usbdfu.js} (100%) diff --git a/js/stm32.js b/js/protocols/stm32.js similarity index 100% rename from js/stm32.js rename to js/protocols/stm32.js diff --git a/js/stm32dfu.js b/js/protocols/stm32usbdfu.js similarity index 100% rename from js/stm32dfu.js rename to js/protocols/stm32usbdfu.js diff --git a/main.html b/main.html index 57a9f141..9f208cfa 100644 --- a/main.html +++ b/main.html @@ -32,8 +32,8 @@ - - + + From 13d17e15283ec6b79badbd7173cdb8651e8cdcff Mon Sep 17 00:00:00 2001 From: cTn Date: Tue, 22 Jul 2014 14:16:09 +0200 Subject: [PATCH 04/54] stm32/stm32usbdfu parameters rework, removing UI options dependency --- js/protocols/stm32.js | 158 ++++++++++++++++++------------------ js/protocols/stm32usbdfu.js | 7 +- tabs/firmware_flasher.js | 36 +++++++- 3 files changed, 115 insertions(+), 86 deletions(-) diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index d2a12df7..48f2b0f3 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -2,9 +2,12 @@ STM32 F103 serial bus seems to properly initialize with quite a huge auto-baud range From 921600 down to 1200, i don't recommend getting any lower then that Official "specs" are from 115200 to 1200 + + popular choices - 921600, 460800, 256000, 230400, 153600, 128000, 115200, 57600, 38400, 28800, 19200 */ var STM32_protocol = function() { + this.options = {}; this.hex; // ref this.verify_hex; @@ -43,77 +46,70 @@ var STM32_protocol = function() { }; // no input parameters -STM32_protocol.prototype.connect = function(hex) { +STM32_protocol.prototype.connect = function(port, baud, hex, options) { var self = this; self.hex = hex; - var selected_port = String($('div#port-picker #port').val()); - var baud = parseInt($('div#port-picker #baud').val()); + // we will crunch the options here since doing it inside initialization routine would be too late / redundant + self.options = { + no_reboot: false, + reboot_baud: false, + erase_chip: false + }; - if (selected_port != '0') { - // popular choices - 921600, 460800, 256000, 230400, 153600, 128000, 115200, 57600, 38400, 28800, 19200 - var flashing_bitrate; - - switch (GUI.operating_system) { - case 'Windows': - case 'MacOS': - case 'ChromeOS': - case 'Linux': - case 'UNIX': - flashing_bitrate = 921600; - break; - - default: - flashing_bitrate = 115200; - } - - if (!$('input.updating').is(':checked')) { - serial.connect(selected_port, {bitrate: baud}, function(openInfo) { - if (openInfo) { - console.log('Sending ascii "R" to reboot'); - - // we are connected, disabling connect button in the UI - GUI.connect_lock = true; - - var bufferOut = new ArrayBuffer(1); - var bufferView = new Uint8Array(bufferOut); - - bufferView[0] = 0x52; - - serial.send(bufferOut, function() { - serial.disconnect(function(result) { - if (result) { - serial.connect(selected_port, {bitrate: flashing_bitrate, parityBit: 'even', stopBits: 'one'}, function(openInfo) { - if (openInfo) { - self.initialize(); - } else { - GUI.log('Failed to open serial port'); - } - }); - } else { - GUI.connect_lock = false; - } - }); - }); - } else { - GUI.log('Failed to open serial port'); - } - }); - } else { - serial.connect(selected_port, {bitrate: flashing_bitrate, parityBit: 'even', stopBits: 'one'}, function(openInfo) { - if (openInfo) { - // we are connected, disabling connect button in the UI - GUI.connect_lock = true; - - self.initialize(); - } else { - GUI.log('Failed to open serial port'); - } - }); - } + if (options.no_reboot) { + self.options.no_reboot = true; } else { - console.log('Please select valid serial port'); - GUI.log('Please select valid serial port'); + self.options.reboot_baud = options.reboot_baud; + } + + if (options.erase_chip) { + self.options.erase_chip = true; + } + + if (self.options.no_reboot) { + serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function(openInfo) { + if (openInfo) { + // we are connected, disabling connect button in the UI + GUI.connect_lock = true; + + self.initialize(); + } else { + GUI.log('Failed to open serial port'); + } + }); + } else { + serial.connect(port, {bitrate: self.options.reboot_baud}, function(openInfo) { + if (openInfo) { + console.log('Sending ascii "R" to reboot'); + + // we are connected, disabling connect button in the UI + GUI.connect_lock = true; + + var bufferOut = new ArrayBuffer(1); + var bufferView = new Uint8Array(bufferOut); + + bufferView[0] = 0x52; + + serial.send(bufferOut, function() { + serial.disconnect(function(result) { + if (result) { + serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function(openInfo) { + if (openInfo) { + self.initialize(); + } else { + GUI.log('Failed to open serial port'); + } + }); + } else { + GUI.connect_lock = false; + } + }); + }); + } else { + GUI.log('Failed to open serial port'); + } + }); } }; @@ -398,7 +394,21 @@ STM32_protocol.prototype.upload_procedure = function(step) { // erase memory GUI.log('Erasing ...'); - if (!$('input.erase_chip').is(':checked')) { + if (self.options.erase_chip) { + console.log('Executing global chip erase'); + + self.send([self.command.erase, 0xBC], 1, function(reply) { // 0x43 ^ 0xFF + if (self.verify_response(self.status.ACK, reply)) { + self.send([0xFF, 0x00], 1, function(reply) { + if (self.verify_response(self.status.ACK, reply)) { + console.log('Erasing: done'); + // proceed to next step + self.upload_procedure(5); + } + }); + } + }); + } else { console.log('Executing local erase (only needed pages)'); self.send([self.command.erase, 0xBC], 1, function(reply) { // 0x43 ^ 0xFF @@ -425,20 +435,6 @@ STM32_protocol.prototype.upload_procedure = function(step) { }); } }); - } else { - console.log('Executing global chip erase'); - - self.send([self.command.erase, 0xBC], 1, function(reply) { // 0x43 ^ 0xFF - if (self.verify_response(self.status.ACK, reply)) { - self.send([0xFF, 0x00], 1, function(reply) { - if (self.verify_response(self.status.ACK, reply)) { - console.log('Erasing: done'); - // proceed to next step - self.upload_procedure(5); - } - }); - } - }); } break; case 5: diff --git a/js/protocols/stm32usbdfu.js b/js/protocols/stm32usbdfu.js index 5cc6fe6d..a63c2d0d 100644 --- a/js/protocols/stm32usbdfu.js +++ b/js/protocols/stm32usbdfu.js @@ -61,7 +61,7 @@ var STM32DFU_protocol = function() { }; }; -STM32DFU_protocol.prototype.connect = function(hex) { +STM32DFU_protocol.prototype.connect = function(device, hex) { var self = this; self.hex = hex; @@ -74,13 +74,14 @@ STM32DFU_protocol.prototype.connect = function(hex) { self.progress_bar_e.val(0); self.progress_bar_e.removeClass('valid invalid'); - chrome.usb.getDevices(usbDevices.STM32DFU, function(result) { + chrome.usb.getDevices(device, function(result) { if (result.length) { console.log('USB DFU detected with ID: ' + result[0].device); self.openDevice(result[0]); } else { - // TODO: throw some error + console.log('USB DFU not found'); + GUI.log('USB DFU not found'); } }); }; diff --git a/tabs/firmware_flasher.js b/tabs/firmware_flasher.js index ab3c8438..538ace4d 100644 --- a/tabs/firmware_flasher.js +++ b/tabs/firmware_flasher.js @@ -108,9 +108,41 @@ tabs.firmware_flasher.initialize = function(callback) { if (!GUI.connect_lock) { // button disabled while flashing is in progress if (parsed_hex != false) { if (String($('div#port-picker #port').val()) != 'DFU') { - STM32.connect(parsed_hex); + if (String($('div#port-picker #port').val()) != '0') { + var options = {}; + var port = String($('div#port-picker #port').val()); + var baud; + + switch (GUI.operating_system) { + case 'Windows': + case 'MacOS': + case 'ChromeOS': + case 'Linux': + case 'UNIX': + baud = 921600; + break; + + default: + baud = 115200; + } + + if ($('input.updating').is(':checked')) { + options.no_reboot = true; + } else { + options.reboot_baud = parseInt($('div#port-picker #baud').val()); + } + + if ($('input.erase_chip').is(':checked')) { + options.erase_chip = true; + } + + STM32.connect(port, baud, parsed_hex, options); + } else { + console.log('Please select valid serial port'); + GUI.log('Please select valid serial port'); + } } else { - STM32DFU.connect(parsed_hex); + STM32DFU.connect(usbDevices.STM32DFU, parsed_hex); } } else { GUI.log(chrome.i18n.getMessage('firmwareFlasherFirmwareNotLoaded')); From aeb3036183f110a48ba6a98d1083ce4221d1da65 Mon Sep 17 00:00:00 2001 From: cTn Date: Thu, 24 Jul 2014 16:27:07 +0200 Subject: [PATCH 05/54] add motor order (motor mix) svg graphics from creyc, thanks --- images/motor_order/custom.svg | 71 +++++++++ images/motor_order/hex6p.svg | 226 ++++++++++++++++++++++++++++ images/motor_order/hex6x.svg | 227 ++++++++++++++++++++++++++++ images/motor_order/octox.svg | 275 ++++++++++++++++++++++++++++++++++ images/motor_order/quadp.svg | 179 ++++++++++++++++++++++ images/motor_order/quadx.svg | 178 ++++++++++++++++++++++ images/motor_order/tri.svg | 174 +++++++++++++++++++++ images/motor_order/y4.svg | 175 ++++++++++++++++++++++ images/motor_order/y6.svg | 227 ++++++++++++++++++++++++++++ 9 files changed, 1732 insertions(+) create mode 100644 images/motor_order/custom.svg create mode 100644 images/motor_order/hex6p.svg create mode 100644 images/motor_order/hex6x.svg create mode 100644 images/motor_order/octox.svg create mode 100644 images/motor_order/quadp.svg create mode 100644 images/motor_order/quadx.svg create mode 100644 images/motor_order/tri.svg create mode 100644 images/motor_order/y4.svg create mode 100644 images/motor_order/y6.svg diff --git a/images/motor_order/custom.svg b/images/motor_order/custom.svg new file mode 100644 index 00000000..3fab0592 --- /dev/null +++ b/images/motor_order/custom.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/images/motor_order/hex6p.svg b/images/motor_order/hex6p.svg new file mode 100644 index 00000000..8d662b92 --- /dev/null +++ b/images/motor_order/hex6p.svg @@ -0,0 +1,226 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/hex6x.svg b/images/motor_order/hex6x.svg new file mode 100644 index 00000000..c80a2e2e --- /dev/null +++ b/images/motor_order/hex6x.svg @@ -0,0 +1,227 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/octox.svg b/images/motor_order/octox.svg new file mode 100644 index 00000000..3dafffe7 --- /dev/null +++ b/images/motor_order/octox.svg @@ -0,0 +1,275 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/quadp.svg b/images/motor_order/quadp.svg new file mode 100644 index 00000000..0798885a --- /dev/null +++ b/images/motor_order/quadp.svg @@ -0,0 +1,179 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/quadx.svg b/images/motor_order/quadx.svg new file mode 100644 index 00000000..39013824 --- /dev/null +++ b/images/motor_order/quadx.svg @@ -0,0 +1,178 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/tri.svg b/images/motor_order/tri.svg new file mode 100644 index 00000000..2b8e6a30 --- /dev/null +++ b/images/motor_order/tri.svg @@ -0,0 +1,174 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/y4.svg b/images/motor_order/y4.svg new file mode 100644 index 00000000..265daf88 --- /dev/null +++ b/images/motor_order/y4.svg @@ -0,0 +1,175 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/y6.svg b/images/motor_order/y6.svg new file mode 100644 index 00000000..c6a646a8 --- /dev/null +++ b/images/motor_order/y6.svg @@ -0,0 +1,227 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 8b73b9dc3d1fbc510ab06cb38804674b45edfddb Mon Sep 17 00:00:00 2001 From: creyc Date: Thu, 24 Jul 2014 10:57:09 -0400 Subject: [PATCH 06/54] exported as plain SVG --- images/motor_order/custom.svg | 45 ++-------- images/motor_order/hex6p.svg | 140 +++++++++--------------------- images/motor_order/hex6x.svg | 143 +++++++++---------------------- images/motor_order/octox.svg | 155 +++++++++------------------------- images/motor_order/quadp.svg | 103 ++++++---------------- images/motor_order/quadx.svg | 112 +++++++----------------- images/motor_order/tri.svg | 102 ++++++---------------- images/motor_order/y4.svg | 146 +++++++++++--------------------- images/motor_order/y6.svg | 143 +++++++++---------------------- 9 files changed, 294 insertions(+), 795 deletions(-) diff --git a/images/motor_order/custom.svg b/images/motor_order/custom.svg index 3fab0592..ab982007 100644 --- a/images/motor_order/custom.svg +++ b/images/motor_order/custom.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="43.828125" height="95" - id="svg3971" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-custom.svg"> + id="svg3971"> - @@ -47,25 +21,20 @@ image/svg+xml - + + transform="translate(-353.46478,-451.46461)" + id="layer1"> + id="Custom_Mix"> + style="font-size:128px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#bdbcbc;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Nyala;-inkscape-font-specification:Nyala-Regular" /> diff --git a/images/motor_order/hex6p.svg b/images/motor_order/hex6p.svg index 8d662b92..3cb6bd7b 100644 --- a/images/motor_order/hex6p.svg +++ b/images/motor_order/hex6p.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="119.33031" height="135.03146" - id="svg4419" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-hex6p.svg"> + id="svg4419"> - @@ -47,178 +21,142 @@ image/svg+xml - + + transform="translate(-315.33485,-443.45501)" + id="layer1"> + id="Hexa-Plus"> + id="MotorOrderGraphic"> + id="FrontArrow"> + style="fill:none;stroke:#ed1c24;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:#ed1c24;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + id="M5"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M4"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M2"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M6"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M3"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> diff --git a/images/motor_order/hex6x.svg b/images/motor_order/hex6x.svg index c80a2e2e..9c28f41f 100644 --- a/images/motor_order/hex6x.svg +++ b/images/motor_order/hex6x.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="131.27087" height="126.82063" - id="svg4235" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-hex6x.svg"> + id="svg4235"> - @@ -47,179 +21,142 @@ image/svg+xml - + + transform="translate(-309.36456,-449.17394)" + id="layer1"> + id="Hexa-X"> + id="MotorOrderGraphic"> + id="FrontArrow"> + style="fill:none;stroke:#ed1c24;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:#ed1c24;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + id="M4"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M2"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M5"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M1"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M3"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M6"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> diff --git a/images/motor_order/octox.svg b/images/motor_order/octox.svg index 3dafffe7..d8b6adf4 100644 --- a/images/motor_order/octox.svg +++ b/images/motor_order/octox.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="153.17989" height="156.83775" - id="svg4069" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-octox.svg"> + id="svg4069"> - @@ -47,227 +21,180 @@ image/svg+xml - + + transform="translate(-298.41006,-439.84159)" + id="layer1"> + id="Octo-X"> + id="MotorOrderGraphic"> + style="fill:none;stroke:#ed1c24;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:#ed1c24;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> diff --git a/images/motor_order/quadp.svg b/images/motor_order/quadp.svg index 0798885a..346037ff 100644 --- a/images/motor_order/quadp.svg +++ b/images/motor_order/quadp.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="123.68313" height="130.94138" - id="svg3581" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-quadp.svg"> + id="svg3581"> - @@ -47,131 +21,104 @@ image/svg+xml - + + transform="translate(-313.15844,-448.10506)" + id="layer1"> + id="QuadCopter-Plus"> + id="MotorOrderGraphic"> + style="fill:none;stroke:#ed1c24;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:#ed1c24;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> diff --git a/images/motor_order/quadx.svg b/images/motor_order/quadx.svg index 39013824..ecadef9a 100644 --- a/images/motor_order/quadx.svg +++ b/images/motor_order/quadx.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="89.126129" height="96.596001" - id="svg3387" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-quadx.svg"> + id="svg3387"> - @@ -47,130 +21,104 @@ image/svg+xml + + transform="translate(-331.63693,-454.24951)" + id="layer1"> + id="QuadCopter-X"> + id="MotorOrderGraphic"> + id="FrontArrow"> + style="fill:none;stroke:#ed1c24;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:#ed1c24;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + id="M3"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M2"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M4"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M1"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> diff --git a/images/motor_order/tri.svg b/images/motor_order/tri.svg index 2b8e6a30..f635b61f 100644 --- a/images/motor_order/tri.svg +++ b/images/motor_order/tri.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="117.72237" height="111.32775" - id="svg3742" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-tri.svg"> + id="svg3742"> - @@ -47,126 +21,100 @@ image/svg+xml - + + transform="translate(-316.13881,-449.29394)" + id="layer1"> + id="TriCopter"> + id="MotorOrderGraphic"> + style="fill:none;stroke:#ed1c24;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:#ed1c24;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + style="fill:none;stroke:#bf1b2c;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> diff --git a/images/motor_order/y4.svg b/images/motor_order/y4.svg index 265daf88..c79637a4 100644 --- a/images/motor_order/y4.svg +++ b/images/motor_order/y4.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="113.57825" height="139.24809" - id="svg3882" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-y4.svg"> + id="svg3882"> - @@ -47,128 +21,102 @@ image/svg+xml - + + transform="translate(-318.21087,-449.76084)" + id="layer1"> + id="Y4"> + id="FrontArrow"> + style="fill:none;stroke:#ed1c24;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:#ed1c24;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + id="M4"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M2"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M3"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M1"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> diff --git a/images/motor_order/y6.svg b/images/motor_order/y6.svg index c6a646a8..5db6237f 100644 --- a/images/motor_order/y6.svg +++ b/images/motor_order/y6.svg @@ -7,38 +7,12 @@ 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" width="158.43581" height="157.09412" - id="svg4602" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="motor-order-y6.svg"> + id="svg4602"> - @@ -47,179 +21,142 @@ image/svg+xml - + + transform="translate(-295.7821,-441.82894)" + id="layer1"> + id="Y6"> + id="MotorOrderGraphic"> + id="FrontArrow"> + style="fill:none;stroke:#ed1c24;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:#ed1c24;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + id="M4"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M6"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M5"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#293d9b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M3"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M2"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + id="M1"> + style="font-size:12px;font-variant:normal;font-weight:normal;font-stretch:normal;writing-mode:lr-tb;fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:UTM Neo Sans Intel;-inkscape-font-specification:UTM Neo Sans Intel" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#8d198f;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> From d379cdfcf2550ea4003cf82e1268a221bb9cff6c Mon Sep 17 00:00:00 2001 From: CurtisFissel Date: Thu, 24 Jul 2014 23:26:11 -0400 Subject: [PATCH 07/54] Added Motor Mix Diagrams --- tabs/initial_setup.css | 15 ++++++++++ tabs/initial_setup.html | 1 + tabs/initial_setup.js | 62 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/tabs/initial_setup.css b/tabs/initial_setup.css index aec0b29c..20c07910 100644 --- a/tabs/initial_setup.css +++ b/tabs/initial_setup.css @@ -60,6 +60,21 @@ font-weight: bold; } + + #interactive_block .modelMixDiagram { + position: absolute; + + top: 32px; + left: 10px; + + height: 30%; /* interactive_block height set to inherit */ + } + + #interactive_block .modelMixCustom { /* Position question mark correctly */ + height: 20%; /* resize question mark */ + padding-left: 25px; + } + #interactive_block .heading { float: right; height: 15px; diff --git a/tabs/initial_setup.html b/tabs/initial_setup.html index fd2e1d2b..fe226ee2 100644 --- a/tabs/initial_setup.html +++ b/tabs/initial_setup.html @@ -22,6 +22,7 @@
+
diff --git a/tabs/initial_setup.js b/tabs/initial_setup.js index 59296674..61ed1884 100644 --- a/tabs/initial_setup.js +++ b/tabs/initial_setup.js @@ -100,12 +100,72 @@ tabs.initial_setup.initialize = function(callback) { case 20: // Dualcopter str = 'Dualcopter'; break; - case 21: // + case 21: // Singlecopter str = 'Singlecopter'; break; } $('span.model').text(chrome.i18n.getMessage('initialSetupModel', [str])); + + // Model Mix Diagram selection + switch (CONFIG.multiType) { + case 1: // TRI + $(".modelMixDiagram").attr("src","./images/motor_order/tri.svg"); // Change image + $(".modelMixDiagram").addClass( 'modelMixTri' ); //Set specific class per model type + break; + case 2: // QUAD + + $(".modelMixDiagram").attr("src","./images/motor_order/quadp.svg"); + $(".modelMixDiagram").addClass( 'modelMixQuadP' ); + break; + case 3: // QUAD X + $(".modelMixDiagram").attr("src","./images/motor_order/quadx.svg"); + $(".modelMixDiagram").addClass( 'modelMixQuadX' ); + break; + case 6: // Y6 + $(".modelMixDiagram").attr("src","./images/motor_order/y6.svg"); + $(".modelMixDiagram").addClass( 'modelMixY6' ); + break; + case 7: // HEX 6 + $(".modelMixDiagram").attr("src","./images/motor_order/hex6p.svg"); + $(".modelMixDiagram").addClass( 'modelMixHex6P' ); + break; + case 9: // Y4 + $(".modelMixDiagram").attr("src","./images/motor_order/y4.svg"); + $(".modelMixDiagram").addClass( 'modelMixY4' ); + break; + case 10: // HEX6 X + $(".modelMixDiagram").attr("src","./images/motor_order/hex6x.svg"); + $(".modelMixDiagram").addClass( 'modelMixHex6X' ); + break; + case 11: // OCTO X8 + case 12: + case 13: + $(".modelMixDiagram").attr("src","./images/motor_order/octox.svg"); + $(".modelMixDiagram").addClass( 'modelMixOctoX' ); + break; + + case 4: // BI + case 5: // GIMBAL + case 8: // FLYING_WING + case 14: // AIRPLANE + case 15: // Heli 120 + case 16: // Heli 90 + case 17: // Vtail + case 18: // HEX6 H + case 19: // PPM to SERVO + case 20: // Dualcopter + case 21: // Singlecopter + $(".modelMixDiagram").attr("src","./images/motor_order/custom.svg"); + $(".modelMixDiagram").addClass( 'modelMixCustom' ); + break; + + default: + $(".modelMixDiagram").attr("src","./images/motor_order/custom.svg"); + $(".modelMixDiagram").addClass( 'modelMixCustom' ); + break; + } + + // Heading $('span.heading').text(chrome.i18n.getMessage('initialSetupheading', [0])); // UI Hooks From c30e883e163a98af80261a9940978302698bf877 Mon Sep 17 00:00:00 2001 From: cTn Date: Fri, 25 Jul 2014 14:20:09 +0200 Subject: [PATCH 08/54] chain changes, cleanup and fix style --- tabs/initial_setup.js | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/tabs/initial_setup.js b/tabs/initial_setup.js index 61ed1884..b9eb129b 100644 --- a/tabs/initial_setup.js +++ b/tabs/initial_setup.js @@ -106,42 +106,34 @@ tabs.initial_setup.initialize = function(callback) { } $('span.model').text(chrome.i18n.getMessage('initialSetupModel', [str])); - + // Model Mix Diagram selection switch (CONFIG.multiType) { case 1: // TRI - $(".modelMixDiagram").attr("src","./images/motor_order/tri.svg"); // Change image - $(".modelMixDiagram").addClass( 'modelMixTri' ); //Set specific class per model type + $(".modelMixDiagram").attr("src","./images/motor_order/tri.svg").addClass('modelMixTri'); break; case 2: // QUAD + - $(".modelMixDiagram").attr("src","./images/motor_order/quadp.svg"); - $(".modelMixDiagram").addClass( 'modelMixQuadP' ); + $(".modelMixDiagram").attr("src","./images/motor_order/quadp.svg").addClass('modelMixQuadP'); break; case 3: // QUAD X - $(".modelMixDiagram").attr("src","./images/motor_order/quadx.svg"); - $(".modelMixDiagram").addClass( 'modelMixQuadX' ); + $(".modelMixDiagram").attr("src","./images/motor_order/quadx.svg").addClass('modelMixQuadX'); break; case 6: // Y6 - $(".modelMixDiagram").attr("src","./images/motor_order/y6.svg"); - $(".modelMixDiagram").addClass( 'modelMixY6' ); + $(".modelMixDiagram").attr("src","./images/motor_order/y6.svg").addClass('modelMixY6'); break; case 7: // HEX 6 - $(".modelMixDiagram").attr("src","./images/motor_order/hex6p.svg"); - $(".modelMixDiagram").addClass( 'modelMixHex6P' ); + $(".modelMixDiagram").attr("src","./images/motor_order/hex6p.svg").addClass('modelMixHex6P'); break; case 9: // Y4 - $(".modelMixDiagram").attr("src","./images/motor_order/y4.svg"); - $(".modelMixDiagram").addClass( 'modelMixY4' ); + $(".modelMixDiagram").attr("src","./images/motor_order/y4.svg").addClass('modelMixY4'); break; case 10: // HEX6 X - $(".modelMixDiagram").attr("src","./images/motor_order/hex6x.svg"); - $(".modelMixDiagram").addClass( 'modelMixHex6X' ); + $(".modelMixDiagram").attr("src","./images/motor_order/hex6x.svg").addClass('modelMixHex6X'); break; case 11: // OCTO X8 case 12: case 13: - $(".modelMixDiagram").attr("src","./images/motor_order/octox.svg"); - $(".modelMixDiagram").addClass( 'modelMixOctoX' ); + $(".modelMixDiagram").attr("src","./images/motor_order/octox.svg").addClass('modelMixOctoX'); break; case 4: // BI @@ -155,13 +147,11 @@ tabs.initial_setup.initialize = function(callback) { case 19: // PPM to SERVO case 20: // Dualcopter case 21: // Singlecopter - $(".modelMixDiagram").attr("src","./images/motor_order/custom.svg"); - $(".modelMixDiagram").addClass( 'modelMixCustom' ); + $(".modelMixDiagram").attr("src","./images/motor_order/custom.svg").addClass('modelMixCustom'); break; - default: - $(".modelMixDiagram").attr("src","./images/motor_order/custom.svg"); - $(".modelMixDiagram").addClass( 'modelMixCustom' ); + default: + $(".modelMixDiagram").attr("src","./images/motor_order/custom.svg").addClass('modelMixCustom'); break; } From 471a38d7ce795db0171ddf9e921ade875d238f42 Mon Sep 17 00:00:00 2001 From: creyc Date: Fri, 25 Jul 2014 09:23:15 -0400 Subject: [PATCH 09/54] Reduced filesize, include proper licensing --- images/motor_order/custom.svg | 64 +++--- images/motor_order/hex6p.svg | 288 ++++++++++++--------------- images/motor_order/hex6x.svg | 291 ++++++++++++--------------- images/motor_order/octox.svg | 362 +++++++++++++++------------------- images/motor_order/quadp.svg | 213 +++++++++----------- images/motor_order/quadx.svg | 212 ++++++++------------ images/motor_order/tri.svg | 214 +++++++++----------- images/motor_order/y4.svg | 207 ++++++++----------- images/motor_order/y6.svg | 292 ++++++++++++--------------- 9 files changed, 921 insertions(+), 1222 deletions(-) diff --git a/images/motor_order/custom.svg b/images/motor_order/custom.svg index ab982007..2086558f 100644 --- a/images/motor_order/custom.svg +++ b/images/motor_order/custom.svg @@ -1,40 +1,26 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - + + + + + + + + diff --git a/images/motor_order/hex6p.svg b/images/motor_order/hex6p.svg index 3cb6bd7b..59700daf 100644 --- a/images/motor_order/hex6p.svg +++ b/images/motor_order/hex6p.svg @@ -1,164 +1,126 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/hex6x.svg b/images/motor_order/hex6x.svg index 9c28f41f..e4a3a72a 100644 --- a/images/motor_order/hex6x.svg +++ b/images/motor_order/hex6x.svg @@ -1,164 +1,129 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/octox.svg b/images/motor_order/octox.svg index d8b6adf4..1cf08940 100644 --- a/images/motor_order/octox.svg +++ b/images/motor_order/octox.svg @@ -1,202 +1,162 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/quadp.svg b/images/motor_order/quadp.svg index 346037ff..aad058d3 100644 --- a/images/motor_order/quadp.svg +++ b/images/motor_order/quadp.svg @@ -1,126 +1,89 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/quadx.svg b/images/motor_order/quadx.svg index ecadef9a..fea375d8 100644 --- a/images/motor_order/quadx.svg +++ b/images/motor_order/quadx.svg @@ -1,126 +1,88 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/tri.svg b/images/motor_order/tri.svg index f635b61f..bbbe1f23 100644 --- a/images/motor_order/tri.svg +++ b/images/motor_order/tri.svg @@ -1,122 +1,94 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/y4.svg b/images/motor_order/y4.svg index c79637a4..b8a3542d 100644 --- a/images/motor_order/y4.svg +++ b/images/motor_order/y4.svg @@ -1,123 +1,86 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/y6.svg b/images/motor_order/y6.svg index 5db6237f..80c5affd 100644 --- a/images/motor_order/y6.svg +++ b/images/motor_order/y6.svg @@ -1,164 +1,130 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 54d1c4f61452a2ff13b1a5865932711da20aee3b Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 26 Jul 2014 23:02:23 +0200 Subject: [PATCH 10/54] updating manifest, changelog, note about 6k users --- changelog.html | 6 ++++++ manifest.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/changelog.html b/changelog.html index 5896ea1c..18dc1434 100644 --- a/changelog.html +++ b/changelog.html @@ -1,3 +1,9 @@ +xx.xx.2014 - 0.48 +

+ - Configurator reached 6000+ users on 07.26.2014
+ - Added motor order diagrams (creyc, Curtisbeef)
+ - Flashing timeout bugfixes
+

07.17.2014 - 0.47

- Bugfixes related to Chrome 36+ release
diff --git a/manifest.json b/manifest.json index a59a29af..1190c9f1 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "minimum_chrome_version": "36", - "version": "0.47.1", + "version": "0.48", "author": "cTn", "name": "Baseflight - Configurator", From 81cceba005b8642a2869cfeae808970bf681011b Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 27 Jul 2014 19:03:39 +0200 Subject: [PATCH 11/54] release --- changelog.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.html b/changelog.html index 18dc1434..6ea8dfa7 100644 --- a/changelog.html +++ b/changelog.html @@ -1,4 +1,4 @@ -xx.xx.2014 - 0.48 +07.27.2014 - 0.48

- Configurator reached 6000+ users on 07.26.2014
- Added motor order diagrams (creyc, Curtisbeef)
From b7e880678e68bb8fbdf303932cbed99f97cb4be3 Mon Sep 17 00:00:00 2001 From: cTn Date: Wed, 30 Jul 2014 19:53:33 +0200 Subject: [PATCH 12/54] converting background page to eventPage --- background.js => eventPage.js | 0 manifest.json | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename background.js => eventPage.js (100%) diff --git a/background.js b/eventPage.js similarity index 100% rename from background.js rename to eventPage.js diff --git a/manifest.json b/manifest.json index 1190c9f1..d25bf25f 100644 --- a/manifest.json +++ b/manifest.json @@ -14,7 +14,8 @@ "app": { "background": { - "scripts": [ "background.js" ] + "scripts": ["eventPage.js"], + "persistent": false } }, From 026f01434a4c3fe0e8b33628c21f87a9e738f831 Mon Sep 17 00:00:00 2001 From: cTn Date: Wed, 6 Aug 2014 15:11:11 +0200 Subject: [PATCH 13/54] moving backers to sponsors block --- _locales/en/messages.json | 2 +- tabs/default.css | 25 ++++++++++++++++++++++++- tabs/default.html | 8 ++++++++ tabs/default.js | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index d1be0c84..fd8b1642 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -136,7 +136,7 @@ "message": "Request Optional Permissions" }, "defaultWelcomeText": { - "message": "Welcome to Baseflight - Configurator, utility designed to simplify updating, configuring and tuning of your flight controller.
Application supports complete family of Baseflight hardware (acro naze, naze32, naze32pro and afromini).

Official Resellers & Backers
AbuseMark - International (Japan)
Multirotor Superstore - International (United States)

Latest CP210x Drivers can be downloaded from here
" + "message": "Welcome to Baseflight - Configurator, utility designed to simplify updating, configuring and tuning of your flight controller.
Application supports complete family of Baseflight hardware (acro naze, naze32, naze32pro and afromini).

• Latest CP210x Drivers can be downloaded from here
" }, "defaultChangelogHead": { "message": "Configurator - Changelog" diff --git a/tabs/default.css b/tabs/default.css index 259ed23d..5b1145c3 100644 --- a/tabs/default.css +++ b/tabs/default.css @@ -134,4 +134,27 @@ } .firmware_flasher:hover { background-color: #dedcdc; - } \ No newline at end of file + } + .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; + } \ No newline at end of file diff --git a/tabs/default.html b/tabs/default.html index 548425c2..40ccf9bf 100644 --- a/tabs/default.html +++ b/tabs/default.html @@ -15,6 +15,13 @@

Paypal
+
+
Sponsors
+

+ • AbuseMark - International (Japan)
+ • Multirotor Superstore - International (United States)
+

+
@@ -24,4 +31,5 @@
+
\ No newline at end of file diff --git a/tabs/default.js b/tabs/default.js index 05be4aea..941f67f5 100644 --- a/tabs/default.js +++ b/tabs/default.js @@ -17,7 +17,7 @@ tabs.default.initialize = function(callback) { tabs.firmware_flasher.initialize(); }); - $('div.welcome a').click(function() { + $('div.welcome a, div.sponsors a').click(function() { googleAnalytics.sendEvent('ExternalUrls', 'Click', $(this).prop('href')); }); From 36f456d2e7f1472736d7980a27736510d94dd97b Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 9 Aug 2014 19:38:46 +0200 Subject: [PATCH 14/54] turning on strict mode for various js files --- js/backup_restore.js | 2 + js/data_storage.js | 2 + js/gui.js | 2 + js/localization.js | 2 + js/msp.js | 17 ++++---- js/port_handler.js | 2 + js/port_usage.js | 2 + js/request_balancer.js | 8 ++-- js/serial.js | 92 +++++++++++++++++++++--------------------- js/serial_backend.js | 4 +- js/usb.js | 12 ++++-- main.js | 92 +++++++++++++++++++++++++----------------- 12 files changed, 139 insertions(+), 98 deletions(-) diff --git a/js/backup_restore.js b/js/backup_restore.js index f0343f97..9c655aa1 100644 --- a/js/backup_restore.js +++ b/js/backup_restore.js @@ -1,3 +1,5 @@ +'use strict'; + function configuration_backup() { // request configuration data (one by one) diff --git a/js/data_storage.js b/js/data_storage.js index 11cc9e1b..ffe498aa 100644 --- a/js/data_storage.js +++ b/js/data_storage.js @@ -1,3 +1,5 @@ +'use strict'; + var firmware_version_accepted = 2.3; var CONFIG = { diff --git a/js/gui.js b/js/gui.js index 27f453c5..311511f0 100644 --- a/js/gui.js +++ b/js/gui.js @@ -1,3 +1,5 @@ +'use strict'; + var tabs = {}; // filled by individual tab js file var GUI_control = function() { diff --git a/js/localization.js b/js/localization.js index 8ceba49a..a0a11391 100644 --- a/js/localization.js +++ b/js/localization.js @@ -1,3 +1,5 @@ +'use strict'; + function localize() { var localized = 0; diff --git a/js/msp.js b/js/msp.js index 25e2b6a6..2ee94edf 100644 --- a/js/msp.js +++ b/js/msp.js @@ -1,3 +1,5 @@ +'use strict'; + // MSP_codes needs to be re-integrated inside MSP object var MSP_codes = { MSP_IDENT: 100, @@ -53,7 +55,7 @@ var MSP_codes = { var MSP = { state: 0, - message_status: 1, + message_direction: 1, code: 0, message_length_expected: 0, message_length_received: 0, @@ -64,7 +66,7 @@ var MSP = { callbacks: [], packet_error: 0, - callbacks_cleanup: function() { + callbacks_cleanup: function () { for (var i = 0; i < this.callbacks.length; i++) { clearInterval(this.callbacks[i].timer); } @@ -72,7 +74,7 @@ var MSP = { this.callbacks = []; }, - disconnect_cleanup: function() { + 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 @@ -80,7 +82,7 @@ var MSP = { } }; -MSP.read = function(readInfo) { +MSP.read = function (readInfo) { var data = new Uint8Array(readInfo.data); for (var i = 0; i < data.length; i++) { @@ -99,9 +101,9 @@ MSP.read = function(readInfo) { break; case 2: // direction (should be >) if (data[i] == 62) { // > - message_status = 1; - } else { // unknown - message_status = 0; + this.message_direction = 1; + } else { // < + this.message_direction = 0; } this.state++; @@ -156,6 +158,7 @@ MSP.read = function(readInfo) { }; MSP.process_data = function(code, message_buffer, message_length) { + 'use strict'; var data = new DataView(message_buffer, 0); // DataView (allowing us to view arrayBuffer as struct/union) switch (code) { diff --git a/js/port_handler.js b/js/port_handler.js index f685b203..c77aef1a 100644 --- a/js/port_handler.js +++ b/js/port_handler.js @@ -1,3 +1,5 @@ +'use strict'; + function port_handler() { this.main_timeout_reference; this.initial_ports = false; diff --git a/js/port_usage.js b/js/port_usage.js index a9678a58..45d753f2 100644 --- a/js/port_usage.js +++ b/js/port_usage.js @@ -1,3 +1,5 @@ +'use strict'; + var PortUsage = { previous_received: 0, previous_sent: 0, diff --git a/js/request_balancer.js b/js/request_balancer.js index 490ddee7..b79722d5 100644 --- a/js/request_balancer.js +++ b/js/request_balancer.js @@ -1,18 +1,20 @@ +'use strict'; + function request_delay_balancer(refresh_period) { this.balance_to = refresh_period; this.request_t = 0; this.finished_t = 0; } -request_delay_balancer.prototype.requested = function() { +request_delay_balancer.prototype.requested = function () { this.request_t = millitime(); }; -request_delay_balancer.prototype.finished = function() { +request_delay_balancer.prototype.finished = function () { this.finished_t = millitime(); }; -request_delay_balancer.prototype.estimate = function() { +request_delay_balancer.prototype.estimate = function () { var estimate = this.balance_to - (this.finished_t - this.request_t); return (estimate > 0) ? estimate : 0; }; \ No newline at end of file diff --git a/js/serial.js b/js/serial.js index 7b2e2c77..33157e16 100644 --- a/js/serial.js +++ b/js/serial.js @@ -1,3 +1,5 @@ +'use strict'; + var serial = { connectionId: -1, bitrate: 0, @@ -25,30 +27,30 @@ var serial = { console.error(info); googleAnalytics.sendException('Serial: ' + info.error, false); + function get_status() { + self.getInfo(crunch_status); + } + + function crunch_status(info) { + if (!info.paused) { + console.log('SERIAL: Connection recovered from last onReceiveError'); + googleAnalytics.sendException('Serial: onReceiveError - recovered', false); + } else { + console.log('SERIAL: Connection did not recover from last onReceiveError, disconnecting'); + GUI.log('Unrecoverable failure of serial connection, disconnecting...'); + googleAnalytics.sendException('Serial: onReceiveError - unrecoverable', false); + + if (GUI.connected_to || GUI.connecting_to) { + $('a.connect').click(); + } else { + self.disconnect(); + } + } + } + switch (info.error) { case 'system_error': // we might be able to recover from this one chrome.serial.setPaused(self.connectionId, false, get_status); - - function get_status() { - self.getInfo(crunch_status); - } - - function crunch_status(info) { - if (!info.paused) { - console.log('SERIAL: Connection recovered from last onReceiveError'); - googleAnalytics.sendException('Serial: onReceiveError - recovered', false); - } else { - console.log('SERIAL: Connection did not recover from last onReceiveError, disconnecting'); - GUI.log('Unrecoverable failure of serial connection, disconnecting...'); - googleAnalytics.sendException('Serial: onReceiveError - unrecoverable', false); - - if (GUI.connected_to || GUI.connecting_to) { - $('a.connect').click(); - } else { - self.disconnect(); - } - } - } break; case 'timeout': // TODO @@ -125,33 +127,33 @@ var serial = { var self = this; self.output_buffer.push({'data': data, 'callback': callback}); + function sending() { + // store inside separate variables in case array gets destroyed + var data = self.output_buffer[0].data; + var callback = self.output_buffer[0].callback; + + chrome.serial.send(self.connectionId, data, function(sendInfo) { + callback(sendInfo); + self.output_buffer.shift(); + + self.bytes_sent += sendInfo.bytesSent; + + if (self.output_buffer.length) { + // keep the buffer withing reasonable limits + while (self.output_buffer.length > 500) { + self.output_buffer.pop(); + } + + sending(); + } else { + self.transmitting = false; + } + }); + }; + if (!self.transmitting) { self.transmitting = true; - function sending() { - // store inside separate variables in case array gets destroyed - var data = self.output_buffer[0].data; - var callback = self.output_buffer[0].callback; - - chrome.serial.send(self.connectionId, data, function(sendInfo) { - callback(sendInfo); - self.output_buffer.shift(); - - self.bytes_sent += sendInfo.bytesSent; - - if (self.output_buffer.length) { - // keep the buffer withing reasonable limits - while (self.output_buffer.length > 500) { - self.output_buffer.pop(); - } - - sending(); - } else { - self.transmitting = false; - } - }); - }; - sending(); } }, diff --git a/js/serial_backend.js b/js/serial_backend.js index aae51687..0a9e3f87 100644 --- a/js/serial_backend.js +++ b/js/serial_backend.js @@ -1,3 +1,5 @@ +'use strict'; + var configuration_received = false; $(document).ready(function() { @@ -44,7 +46,7 @@ $(document).ready(function() { $(this).text(chrome.i18n.getMessage('connect')); $(this).removeClass('active'); - sensor_status(sensors_detected = 0); // reset active sensor indicators + sensor_status(0); // reset active sensor indicators $('#tabs > ul li').removeClass('active'); // de-select any selected tabs // detach listeners and remove element data diff --git a/js/usb.js b/js/usb.js index 1134658a..4833cce4 100644 --- a/js/usb.js +++ b/js/usb.js @@ -1,10 +1,12 @@ +'use strict'; + var usbDevices = { STM32DFU: {'vendorId': 1155, 'productId': 57105} }; var usbPermissions = {permissions: [{'usbDevices': [usbDevices.STM32DFU]}]}; function check_usb_permissions(callback) { - chrome.permissions.contains(usbPermissions, function(result) { + chrome.permissions.contains(usbPermissions, function (result) { if (result) { GUI.optional_usb_permissions = true; } else { @@ -15,8 +17,8 @@ function check_usb_permissions(callback) { $('div.optional_permissions').show(); // UI hooks - document.getElementById("requestOptionalPermissions").addEventListener('click', function() { - chrome.permissions.request(usbPermissions, function(result) { + document.getElementById("requestOptionalPermissions").addEventListener('click', function () { + chrome.permissions.request(usbPermissions, function (result) { if (result) { GUI.log(chrome.i18n.getMessage('usb_permissions_granted')); $('div.optional_permissions').hide(); @@ -27,6 +29,8 @@ function check_usb_permissions(callback) { }); } - if (callback) callback(); + if (callback) { + callback(); + } }); } \ No newline at end of file diff --git a/main.js b/main.js index dcf917ca..3e5aa81b 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,9 @@ +'use strict'; + // Get access to the background window object // This object is used to pass variables between active page and background page -chrome.runtime.getBackgroundPage(function(result) { +var backgroundPage; +chrome.runtime.getBackgroundPage(function (result) { backgroundPage = result; backgroundPage.app_window = window; }); @@ -9,11 +12,11 @@ chrome.runtime.getBackgroundPage(function(result) { var googleAnalyticsService = analytics.getService('ice_cream_app'); var googleAnalytics = googleAnalyticsService.getTracker('UA-32728876-6'); var googleAnalyticsConfig = false; -googleAnalyticsService.getConfig().addCallback(function(config) { +googleAnalyticsService.getConfig().addCallback(function (config) { googleAnalyticsConfig = config; }); -$(document).ready(function() { +$(document).ready(function () { googleAnalytics.sendAppView('Application Started'); // translate to user-selected language @@ -21,7 +24,7 @@ $(document).ready(function() { // alternative - window.navigator.appVersion.match(/Chrome\/([0-9.]*)/)[1]; GUI.log('Running - OS: ' + GUI.operating_system + ', ' + - 'Chrome: ' + window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/,"$1") + ', ' + + 'Chrome: ' + window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/, "$1") + ', ' + 'Configurator: ' + chrome.runtime.getManifest().version + ''); // notification messages for various operating systems @@ -41,11 +44,10 @@ $(document).ready(function() { // Tabs var ui_tabs = $('#tabs > ul'); - $('a', ui_tabs).click(function() { + $('a', ui_tabs).click(function () { if ($(this).parent().hasClass('active') == false && !GUI.tab_switch_in_progress) { // only initialize when the tab isn't already active - var self = this; - var index = $(self).parent().index(); - var tab = $(self).parent().prop('class'); + var self = this, + tab = $(self).parent().prop('class'); // if there is no active connection, return if (!configuration_received && tab != 'tab_logging') { @@ -55,7 +57,7 @@ $(document).ready(function() { GUI.tab_switch_in_progress = true; - GUI.tab_switch_cleanup(function() { + GUI.tab_switch_cleanup(function () { // disable previously active tab highlight $('li', ui_tabs).removeClass('active'); @@ -69,6 +71,10 @@ $(document).ready(function() { // display loading screen $('#cache .data-loading').clone().appendTo(content); + function content_ready() { + GUI.tab_switch_in_progress = false; + } + switch (tab) { case 'tab_initial_setup': tabs.initial_setup.initialize(content_ready); @@ -101,10 +107,6 @@ $(document).ready(function() { tabs.logging.initialize(content_ready); break; } - - function content_ready() { - GUI.tab_switch_in_progress = false; - } }); } }); @@ -112,27 +114,27 @@ $(document).ready(function() { tabs.default.initialize(); // options - $('a#options').click(function() { + $('a#options').click(function () { var el = $(this); if (!el.hasClass('active')) { el.addClass('active'); el.after('
'); - $('div#options-window').load('./tabs/options.html', function() { + $('div#options-window').load('./tabs/options.html', function () { googleAnalytics.sendAppView('Options'); // translate to user-selected language localize(); // if notifications are enabled, or wasn't set, check the notifications checkbox - chrome.storage.local.get('update_notify', function(result) { - if (typeof result.update_notify === 'undefined' || result.update_notify) { + chrome.storage.local.get('update_notify', function (result) { + if (result.update_notify === 'undefined' || result.update_notify) { $('div.notifications input').prop('checked', true); } }); - $('div.notifications input').change(function() { + $('div.notifications input').change(function () { var check = $(this).is(':checked'); chrome.storage.local.set({'update_notify': check}); @@ -143,7 +145,7 @@ $(document).ready(function() { $('div.statistics input').prop('checked', true); } - $('div.statistics input').change(function() { + $('div.statistics input').change(function () { var result = $(this).is(':checked'); googleAnalyticsConfig.setTrackingPermitted(result); }); @@ -152,7 +154,7 @@ $(document).ready(function() { 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(function () { el.removeClass('active'); $(this).empty().remove(); }); @@ -167,16 +169,16 @@ $(document).ready(function() { }); // listen to all input change events and adjust the value within limits if necessary - $("#content").on('focus', 'input[type="number"]', function() { - var element = $(this); - var val = element.val(); + $("#content").on('focus', 'input[type="number"]', function () { + var element = $(this), + val = element.val(); if (!isNaN(val)) { element.data('previousValue', parseFloat(val)); } }); - $("#content").on('keydown', 'input[type="number"]', function(e) { + $("#content").on('keydown', 'input[type="number"]', function (e) { // whitelist all that we need for numeric control var whitelist = [ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, // numpad and standard number keypad @@ -186,24 +188,31 @@ $(document).ready(function() { 37, 38, 39, 40, 13 // arrows and enter ]; - if (whitelist.indexOf(e.keyCode) == -1) e.preventDefault(); + if (whitelist.indexOf(e.keyCode) == -1) { + e.preventDefault(); + } }); - $("#content").on('change', 'input[type="number"]', function() { - var element = $(this); - var min = parseFloat(element.prop('min')); - var max = parseFloat(element.prop('max')); - var step = parseFloat(element.prop('step')); - var val = parseFloat(element.val()); + $("#content").on('change', 'input[type="number"]', function () { + var element = $(this), + min = parseFloat(element.prop('min')), + max = parseFloat(element.prop('max')), + step = parseFloat(element.prop('step')), + val = parseFloat(element.val()), + decimal_places; // only adjust minimal end if bound is set if (element.prop('min')) { - if (val < min) element.val(min); + if (val < min) { + element.val(min); + } } // only adjust maximal end if bound is set if (element.prop('max')) { - if (val > max) element.val(max); + if (val > max) { + element.val(max); + } } // if entered value is illegal use previous value instead @@ -220,7 +229,7 @@ $(document).ready(function() { // if step is set and is float and value is int, convert to float, keep decimal places in float according to step *experimental* if (!isNaN(step) && step % 1 !== 0) { - var decimal_places = String(step).split('.')[1].length; + decimal_places = String(step).split('.')[1].length; if (val % 1 === 0) { element.val(val.toFixed(decimal_places)); @@ -244,10 +253,17 @@ function millitime() { } function bytesToSize(bytes) { - if (bytes < 1024) return bytes + ' Bytes'; - else if (bytes < 1048576) return(bytes / 1024).toFixed(3) + ' KB'; - else if (bytes < 1073741824) return(bytes / 1048576).toFixed(3) + ' MB'; - else return (bytes / 1073741824).toFixed(3) + ' GB'; + if (bytes < 1024) { + bytes = bytes + ' Bytes'; + } else if (bytes < 1048576) { + bytes = (bytes / 1024).toFixed(3) + ' KB'; + } else if (bytes < 1073741824) { + bytes = (bytes / 1048576).toFixed(3) + ' MB'; + } else { + bytes = (bytes / 1073741824).toFixed(3) + ' GB'; + } + + return bytes; } /* From 20e6ad0074b96f528107b0767d14200a9207f398 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 9 Aug 2014 20:01:17 +0200 Subject: [PATCH 15/54] enable strict mode in couple more files --- tabs/auxiliary_configuration.js | 2 ++ tabs/cli.js | 2 ++ tabs/default.js | 2 ++ tabs/gps.js | 2 ++ tabs/initial_setup.js | 2 ++ tabs/motor_outputs.js | 4 +++- tabs/pid_tuning.js | 2 ++ tabs/receiver.js | 2 ++ tabs/sensors.js | 4 +++- tabs/servos.js | 1 + 10 files changed, 21 insertions(+), 2 deletions(-) diff --git a/tabs/auxiliary_configuration.js b/tabs/auxiliary_configuration.js index 94ef608f..fafbfbe7 100644 --- a/tabs/auxiliary_configuration.js +++ b/tabs/auxiliary_configuration.js @@ -1,3 +1,5 @@ +'use strict'; + // TODO: rework box_highlight & update_ui to accept flexible amount of aux channels tabs.auxiliary_configuration = {}; tabs.auxiliary_configuration.initialize = function(callback) { diff --git a/tabs/cli.js b/tabs/cli.js index 73d9b680..cdaff5e7 100644 --- a/tabs/cli.js +++ b/tabs/cli.js @@ -1,3 +1,5 @@ +'use strict'; + var CLI_active = false; var CLI_valid = false; diff --git a/tabs/default.js b/tabs/default.js index 941f67f5..125ebd1c 100644 --- a/tabs/default.js +++ b/tabs/default.js @@ -1,3 +1,5 @@ +'use strict'; + tabs.default = {}; tabs.default.initialize = function(callback) { GUI.active_tab_ref = this; diff --git a/tabs/gps.js b/tabs/gps.js index c4ec546c..777d3579 100644 --- a/tabs/gps.js +++ b/tabs/gps.js @@ -1,3 +1,5 @@ +'use strict'; + tabs.gps = {}; tabs.gps.initialize = function(callback) { GUI.active_tab_ref = this; diff --git a/tabs/initial_setup.js b/tabs/initial_setup.js index b9eb129b..2ef932f3 100644 --- a/tabs/initial_setup.js +++ b/tabs/initial_setup.js @@ -1,3 +1,5 @@ +'use strict'; + tabs.initial_setup = { yaw_fix: 0.0 }; diff --git a/tabs/motor_outputs.js b/tabs/motor_outputs.js index 8438df31..37af7738 100644 --- a/tabs/motor_outputs.js +++ b/tabs/motor_outputs.js @@ -1,3 +1,5 @@ +'use strict'; + tabs.motor_outputs = {}; tabs.motor_outputs.initialize = function(callback) { GUI.active_tab_ref = this; @@ -99,7 +101,7 @@ tabs.motor_outputs.initialize = function(callback) { } function drawGraph(graphHelpers, data, sampleNumber) { - svg = d3.select(graphHelpers.selector); + var svg = d3.select(graphHelpers.selector); if (graphHelpers.dynamicHeightDomain) { var limits = []; diff --git a/tabs/pid_tuning.js b/tabs/pid_tuning.js index f839f729..d641d134 100644 --- a/tabs/pid_tuning.js +++ b/tabs/pid_tuning.js @@ -1,3 +1,5 @@ +'use strict'; + tabs.pid_tuning = {}; tabs.pid_tuning.initialize = function(callback) { GUI.active_tab_ref = this; diff --git a/tabs/receiver.js b/tabs/receiver.js index 125f81d1..9bfa8541 100644 --- a/tabs/receiver.js +++ b/tabs/receiver.js @@ -1,3 +1,5 @@ +'use strict'; + tabs.receiver = {}; tabs.receiver.initialize = function(callback) { GUI.active_tab_ref = this; diff --git a/tabs/sensors.js b/tabs/sensors.js index 47ebe7b4..3f4e526b 100644 --- a/tabs/sensors.js +++ b/tabs/sensors.js @@ -1,3 +1,5 @@ +'use strict'; + tabs.sensors = {}; tabs.sensors.initialize = function(callback) { GUI.active_tab_ref = this; @@ -102,7 +104,7 @@ tabs.sensors.initialize = function(callback) { } function drawGraph(graphHelpers, data, sampleNumber) { - svg = d3.select(graphHelpers.selector); + var svg = d3.select(graphHelpers.selector); if (graphHelpers.dynamicHeightDomain) { var limits = []; diff --git a/tabs/servos.js b/tabs/servos.js index 09c21377..1ccb5828 100644 --- a/tabs/servos.js +++ b/tabs/servos.js @@ -4,6 +4,7 @@ from multiwii is so horrible, obstructive and non dynamic, not to mention it doesn't make any sense that there was just no other way around this then hardcoding/implementing each model separately. */ +'use strict'; tabs.servos = {}; tabs.servos.initialize = function(callback) { From f16b3a479acc067bc30455b5da806571276e833c Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 9 Aug 2014 20:40:40 +0200 Subject: [PATCH 16/54] corrections of inline functions --- js/msp.js | 1 - js/serial.js | 90 ++++++++++++++++++++++++++-------------------------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/js/msp.js b/js/msp.js index 2ee94edf..8323d621 100644 --- a/js/msp.js +++ b/js/msp.js @@ -158,7 +158,6 @@ MSP.read = function (readInfo) { }; MSP.process_data = function(code, message_buffer, message_length) { - 'use strict'; var data = new DataView(message_buffer, 0); // DataView (allowing us to view arrayBuffer as struct/union) switch (code) { diff --git a/js/serial.js b/js/serial.js index 33157e16..68411162 100644 --- a/js/serial.js +++ b/js/serial.js @@ -27,30 +27,30 @@ var serial = { console.error(info); googleAnalytics.sendException('Serial: ' + info.error, false); - function get_status() { - self.getInfo(crunch_status); - } - - function crunch_status(info) { - if (!info.paused) { - console.log('SERIAL: Connection recovered from last onReceiveError'); - googleAnalytics.sendException('Serial: onReceiveError - recovered', false); - } else { - console.log('SERIAL: Connection did not recover from last onReceiveError, disconnecting'); - GUI.log('Unrecoverable failure of serial connection, disconnecting...'); - googleAnalytics.sendException('Serial: onReceiveError - unrecoverable', false); - - if (GUI.connected_to || GUI.connecting_to) { - $('a.connect').click(); - } else { - self.disconnect(); - } - } - } - switch (info.error) { case 'system_error': // we might be able to recover from this one chrome.serial.setPaused(self.connectionId, false, get_status); + + var get_status = function () { + self.getInfo(crunch_status); + } + + var crunch_status = function (info) { + if (!info.paused) { + console.log('SERIAL: Connection recovered from last onReceiveError'); + googleAnalytics.sendException('Serial: onReceiveError - recovered', false); + } else { + console.log('SERIAL: Connection did not recover from last onReceiveError, disconnecting'); + GUI.log('Unrecoverable failure of serial connection, disconnecting...'); + googleAnalytics.sendException('Serial: onReceiveError - unrecoverable', false); + + if (GUI.connected_to || GUI.connecting_to) { + $('a.connect').click(); + } else { + self.disconnect(); + } + } + } break; case 'timeout': // TODO @@ -127,33 +127,33 @@ var serial = { var self = this; self.output_buffer.push({'data': data, 'callback': callback}); - function sending() { - // store inside separate variables in case array gets destroyed - var data = self.output_buffer[0].data; - var callback = self.output_buffer[0].callback; - - chrome.serial.send(self.connectionId, data, function(sendInfo) { - callback(sendInfo); - self.output_buffer.shift(); - - self.bytes_sent += sendInfo.bytesSent; - - if (self.output_buffer.length) { - // keep the buffer withing reasonable limits - while (self.output_buffer.length > 500) { - self.output_buffer.pop(); - } - - sending(); - } else { - self.transmitting = false; - } - }); - }; - if (!self.transmitting) { self.transmitting = true; + var sending = function () { + // store inside separate variables in case array gets destroyed + var data = self.output_buffer[0].data; + var callback = self.output_buffer[0].callback; + + chrome.serial.send(self.connectionId, data, function(sendInfo) { + callback(sendInfo); + self.output_buffer.shift(); + + self.bytes_sent += sendInfo.bytesSent; + + if (self.output_buffer.length) { + // keep the buffer withing reasonable limits + while (self.output_buffer.length > 500) { + self.output_buffer.pop(); + } + + sending(); + } else { + self.transmitting = false; + } + }); + }; + sending(); } }, From fc0fff017e28c414efe78cedb619985e364757ab Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 9 Aug 2014 20:47:07 +0200 Subject: [PATCH 17/54] more strict --- js/protocols/stm32.js | 5 +++-- js/protocols/stm32usbdfu.js | 13 +++++++------ js/workers/hex_parser.js | 2 ++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index 48f2b0f3..abfa1422 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -5,6 +5,7 @@ popular choices - 921600, 460800, 256000, 230400, 153600, 128000, 115200, 57600, 38400, 28800, 19200 */ +'use strict'; var STM32_protocol = function() { this.options = {}; @@ -449,7 +450,7 @@ STM32_protocol.prototype.upload_procedure = function(step) { var bytes_flashed = 0; var bytes_flashed_total = 0; // used for progress bar - function write() { + var write = function () { if (bytes_flashed < self.hex.data[flashing_block].bytes) { var bytes_to_write = ((bytes_flashed + 256) <= self.hex.data[flashing_block].bytes) ? 256 : (self.hex.data[flashing_block].bytes - bytes_flashed); @@ -530,7 +531,7 @@ STM32_protocol.prototype.upload_procedure = function(step) { self.verify_hex.push([]); } - function reading() { + var reading = function () { if (bytes_verified < self.hex.data[reading_block].bytes) { var bytes_to_read = ((bytes_verified + 256) <= self.hex.data[reading_block].bytes) ? 256 : (self.hex.data[reading_block].bytes - bytes_verified); diff --git a/js/protocols/stm32usbdfu.js b/js/protocols/stm32usbdfu.js index a63c2d0d..45bbd736 100644 --- a/js/protocols/stm32usbdfu.js +++ b/js/protocols/stm32usbdfu.js @@ -10,6 +10,7 @@ that being said, it seems that certain level of CLRSTATUS is required before running another type of operation for example switching from DNLOAD to UPLOAD, etc, clearning the state so device is in dfuIDLE is highly recommended. */ +'use strict'; var STM32DFU_protocol = function() { this.hex; // ref @@ -135,7 +136,7 @@ STM32DFU_protocol.prototype.resetDevice = function(callback) { }); }; -STM32DFU_protocol.prototype.controlTransfer = function(direction, request, value, interface, length, data, callback) { +STM32DFU_protocol.prototype.controlTransfer = function(direction, request, value, _interface, length, data, callback) { if (direction == 'in') { // data is ignored chrome.usb.controlTransfer(this.handle, { @@ -144,7 +145,7 @@ STM32DFU_protocol.prototype.controlTransfer = function(direction, request, value 'requestType': 'class', 'request': request, 'value': value, - 'index': interface, + 'index': _interface, 'length': length }, function(result) { if (result.resultCode) console.log(result.resultCode); @@ -168,7 +169,7 @@ STM32DFU_protocol.prototype.controlTransfer = function(direction, request, value 'requestType': 'class', 'request': request, 'value': value, - 'index': interface, + 'index': _interface, 'data': arrayBuf }, function(result) { if (result.resultCode) console.log(result.resultCode); @@ -296,7 +297,7 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { // start self.loadAddress(address, write); - function write() { + var write = function () { if (bytes_flashed < self.hex.data[flashing_block].bytes) { var bytes_to_write = ((bytes_flashed + 2048) <= self.hex.data[flashing_block].bytes) ? 2048 : (self.hex.data[flashing_block].bytes - bytes_flashed); @@ -376,7 +377,7 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { }); }); - function read() { + var read = function () { if (bytes_verified < self.hex.data[reading_block].bytes) { var bytes_to_read = ((bytes_verified + 2048) <= self.hex.data[reading_block].bytes) ? 2048 : (self.hex.data[reading_block].bytes - bytes_verified); @@ -452,7 +453,7 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { self.loadAddress(address, leave); }); - function leave() { + var leave = function () { self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, 0, function() { self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { self.upload_procedure(99); diff --git a/js/workers/hex_parser.js b/js/workers/hex_parser.js index bf23ae12..d75fd347 100644 --- a/js/workers/hex_parser.js +++ b/js/workers/hex_parser.js @@ -1,3 +1,5 @@ +'use strict'; + // input = string // result = if hex file is valid, result is an object // if hex file wasn't valid (crc check failed on any of the lines), result will be false From 9043358348882235016075f5ab673d4c720502f4 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 9 Aug 2014 20:51:06 +0200 Subject: [PATCH 18/54] enabling strict in last 2 tabs --- tabs/firmware_flasher.js | 56 +++++++++++++++++++++------------------- tabs/logging.js | 8 +++--- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/tabs/firmware_flasher.js b/tabs/firmware_flasher.js index 538ace4d..d4229bbc 100644 --- a/tabs/firmware_flasher.js +++ b/tabs/firmware_flasher.js @@ -1,5 +1,7 @@ +'use strict'; + tabs.firmware_flasher = {}; -tabs.firmware_flasher.initialize = function(callback) { +tabs.firmware_flasher.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'firmware_flasher'; googleAnalytics.sendAppView('Firmware Flasher'); @@ -7,13 +9,13 @@ tabs.firmware_flasher.initialize = function(callback) { var intel_hex = false; // standard intel hex in string format var parsed_hex = false; // parsed raw hex in array format - $('#content').load("./tabs/firmware_flasher.html", function() { + $('#content').load("./tabs/firmware_flasher.html", function () { // translate to user-selected language localize(); // UI Hooks - $('a.load_file').click(function() { - chrome.fileSystem.chooseEntry({type: 'openFile', accepts: [{extensions: ['hex']}]}, function(fileEntry) { + $('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'); @@ -23,14 +25,14 @@ tabs.firmware_flasher.initialize = function(callback) { // hide github info (if it exists) $('div.git_info').slideUp(); - chrome.fileSystem.getDisplayPath(fileEntry, function(path) { + chrome.fileSystem.getDisplayPath(fileEntry, function (path) { console.log('Loading file from: ' + path); $('span.path').html(path); - fileEntry.file(function(file) { + fileEntry.file(function (file) { var reader = new FileReader(); - reader.onprogress = function(e) { + reader.onprogress = function (e) { if (e.total > 1048576) { // 1 MB // dont allow reading files bigger then 1 MB console.log('File limit (1 MB) exceeded, aborting'); @@ -44,7 +46,7 @@ tabs.firmware_flasher.initialize = function(callback) { intel_hex = e.target.result; - parse_hex(intel_hex, function(data) { + parse_hex(intel_hex, function (data) { parsed_hex = data; if (parsed_hex) { @@ -66,11 +68,11 @@ tabs.firmware_flasher.initialize = function(callback) { }); }); - $('a.load_remote_file').click(function() { - $.get('https://raw.githubusercontent.com/multiwii/baseflight/master/obj/baseflight.hex', function(data) { + $('a.load_remote_file').click(function () { + $.get('https://raw.githubusercontent.com/multiwii/baseflight/master/obj/baseflight.hex', function (data) { intel_hex = data; - parse_hex(intel_hex, function(data) { + parse_hex(intel_hex, function (data) { parsed_hex = data; if (parsed_hex) { @@ -84,12 +86,12 @@ tabs.firmware_flasher.initialize = function(callback) { GUI.log(chrome.i18n.getMessage('firmwareFlasherHexCorrupted')); } }); - }).fail(function() { + }).fail(function () { GUI.log(chrome.i18n.getMessage('firmwareFlasherFailedToLoadOnlineFirmware')); $('a.flash_firmware').addClass('locked'); }); - $.get('https://api.github.com/repos/multiwii/baseflight/commits?page=1&per_page=1&path=obj/baseflight.hex', function(data) { + $.get('https://api.github.com/repos/multiwii/baseflight/commits?page=1&per_page=1&path=obj/baseflight.hex', function (data) { var data = data[0]; var d = new Date(data.commit.author.date); var date = ('0' + (d.getMonth() + 1)).slice(-2) + '.' + ('0' + (d.getDate() + 1)).slice(-2) + '.' + d.getFullYear(); @@ -103,7 +105,7 @@ tabs.firmware_flasher.initialize = function(callback) { }); }); - $('a.flash_firmware').click(function() { + $('a.flash_firmware').click(function () { if (!$(this).hasClass('locked')) { if (!GUI.connect_lock) { // button disabled while flashing is in progress if (parsed_hex != false) { @@ -151,7 +153,7 @@ tabs.firmware_flasher.initialize = function(callback) { } }); - chrome.storage.local.get('no_reboot_sequence', function(result) { + 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(); @@ -174,21 +176,21 @@ tabs.firmware_flasher.initialize = function(callback) { }); }); - chrome.storage.local.get('flash_on_connect', function(result) { + chrome.storage.local.get('flash_on_connect', function (result) { if (result.flash_on_connect) { $('input.flash_on_connect').prop('checked', true); } else { $('input.flash_on_connect').prop('checked', false); } - $('input.flash_on_connect').change(function() { + $('input.flash_on_connect').change(function () { var status = $(this).is(':checked'); if (status) { var flashing_port; - function start() { - PortHandler.port_detected('flash_next_device', function(result) { + var start = function () { + PortHandler.port_detected('flash_next_device', function (result) { flashing_port = result[0]; GUI.log('Detected: ' + flashing_port + ' - triggering flash on connect'); console.log('Detected: ' + flashing_port + ' - triggering flash on connect'); @@ -201,8 +203,8 @@ tabs.firmware_flasher.initialize = function(callback) { }, false, true); } - function end() { - PortHandler.port_removed('flashed_device_removed', function(result) { + 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 @@ -230,7 +232,7 @@ tabs.firmware_flasher.initialize = function(callback) { }).change(); }); - chrome.storage.local.get('erase_chip', function(result) { + chrome.storage.local.get('erase_chip', function (result) { if (result.erase_chip) { $('input.erase_chip').prop('checked', true); } else { @@ -238,14 +240,14 @@ tabs.firmware_flasher.initialize = function(callback) { } // bind UI hook so the status is saved on change - $('input.erase_chip').change(function() { + $('input.erase_chip').change(function () { var status = $(this).is(':checked'); chrome.storage.local.set({'erase_chip': status}); }); }); - $(document).keypress(function(e) { + $(document).keypress(function (e) { if (e.which == 13) { // enter // Trigger regular Flashing sequence $('a.flash_firmware').click(); @@ -253,9 +255,9 @@ tabs.firmware_flasher.initialize = function(callback) { }); // back button - $('a.back').click(function() { + $('a.back').click(function () { if (!GUI.connect_lock) { // button disabled while flashing is in progress - GUI.tab_switch_cleanup(function() { + GUI.tab_switch_cleanup(function () { tabs.default.initialize(); }); } else { @@ -267,7 +269,7 @@ tabs.firmware_flasher.initialize = function(callback) { }); }; -tabs.firmware_flasher.cleanup = function(callback) { +tabs.firmware_flasher.cleanup = function (callback) { PortHandler.flush_callbacks(); // unbind "global" events diff --git a/tabs/logging.js b/tabs/logging.js index 4c00e4cf..ed661c10 100644 --- a/tabs/logging.js +++ b/tabs/logging.js @@ -1,3 +1,5 @@ +'use strict'; + var MSP_pass_through = false; tabs.logging = {}; @@ -11,11 +13,11 @@ tabs.logging.initialize = function(callback) { if (configuration_received) { MSP.send_message(MSP_codes.MSP_RC, false, false, get_motor_data); - function get_motor_data() { + var get_motor_data = function () { MSP.send_message(MSP_codes.MSP_MOTOR, false, false, load_html); } - function load_html() { + var load_html = function () { $('#content').load("./tabs/logging.html", process_html); } } else { @@ -61,7 +63,7 @@ tabs.logging.initialize = function(callback) { // print header for the csv file print_head(); - function log_data_poll() { + var log_data_poll = function () { if (requests) { // save current data (only after everything is initialized) crunch_data(); From 42e25fbb02750563f68f7d15346018f8c65c6f8c Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 9 Aug 2014 20:59:15 +0200 Subject: [PATCH 19/54] updating d3 library --- js/libraries/d3.min.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/libraries/d3.min.js b/js/libraries/d3.min.js index 8d7b343a..88550ae5 100644 --- a/js/libraries/d3.min.js +++ b/js/libraries/d3.min.js @@ -1,5 +1,5 @@ !function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null!=n&&!isNaN(n)}function e(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function r(n){return n.length}function u(n){for(var t=1;n*t%1;)t*=10;return t}function i(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function o(){}function a(n){return ia+n in this}function c(n){return n=ia+n,n in this&&delete this[n]}function s(){var n=[];return this.forEach(function(t){n.push(t)}),n}function l(){var n=0;for(var t in this)t.charCodeAt(0)===oa&&++n;return n}function f(){for(var n in this)if(n.charCodeAt(0)===oa)return!1;return!0}function h(){}function g(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function p(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=aa.length;r>e;++e){var u=aa[e]+t;if(u in n)return u}}function v(){}function d(){}function m(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function U(n){return sa(n,da),n}function j(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.substring(0,a));var s=ya.get(n);return s&&(n=s,c=Y),a?t?u:r:t?v:i}function O(n,t){return function(e){var r=Zo.event;Zo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Zo.event=r}}}function Y(n,t){var e=O(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function I(){var n=".dragsuppress-"+ ++Ma,t="click"+n,e=Zo.select(Wo).on("touchmove"+n,y).on("dragstart"+n,y).on("selectstart"+n,y);if(xa){var r=Bo.style,u=r[xa];r[xa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),xa&&(r[xa]=u),i&&(e.on(t,function(){y(),o()},!0),setTimeout(o,0))}}function Z(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>_a&&(Wo.scrollX||Wo.scrollY)){e=Zo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();_a=!(u.f||u.e),e.remove()}return _a?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function V(){return Zo.event.changedTouches[0].identifier}function X(){return Zo.event.target}function $(){return Wo}function B(n){return n>0?1:0>n?-1:0}function W(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function J(n){return n>1?0:-1>n?ba:Math.acos(n)}function G(n){return n>1?Sa:-1>n?-Sa:Math.asin(n)}function K(n){return((n=Math.exp(n))-1/n)/2}function Q(n){return((n=Math.exp(n))+1/n)/2}function nt(n){return((n=Math.exp(2*n))-1)/(n+1)}function tt(n){return(n=Math.sin(n/2))*n}function et(){}function rt(n,t,e){return this instanceof rt?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof rt?new rt(n.h,n.s,n.l):mt(""+n,yt,rt):new rt(n,t,e)}function ut(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new gt(u(n+120),u(n),u(n-120))}function it(n,t,e){return this instanceof it?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof it?new it(n.h,n.c,n.l):n instanceof at?st(n.l,n.a,n.b):st((n=xt((n=Zo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new it(n,t,e)}function ot(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new at(e,Math.cos(n*=Aa)*t,Math.sin(n)*t)}function at(n,t,e){return this instanceof at?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof at?new at(n.l,n.a,n.b):n instanceof it?ot(n.l,n.c,n.h):xt((n=gt(n)).r,n.g,n.b):new at(n,t,e)}function ct(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=lt(u)*ja,r=lt(r)*Ha,i=lt(i)*Fa,new gt(ht(3.2404542*u-1.5371385*r-.4985314*i),ht(-.969266*u+1.8760108*r+.041556*i),ht(.0556434*u-.2040259*r+1.0572252*i))}function st(n,t,e){return n>0?new it(Math.atan2(e,t)*Ca,Math.sqrt(t*t+e*e),n):new it(0/0,0/0,n)}function lt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function ft(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function ht(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function gt(n,t,e){return this instanceof gt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof gt?new gt(n.r,n.g,n.b):mt(""+n,gt,ut):new gt(n,t,e)}function pt(n){return new gt(n>>16,255&n>>8,255&n)}function vt(n){return pt(n)+""}function dt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(_t(u[0]),_t(u[1]),_t(u[2]))}return(i=Ia.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.substring(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function yt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new rt(r,u,c)}function xt(n,t,e){n=Mt(n),t=Mt(t),e=Mt(e);var r=ft((.4124564*n+.3575761*t+.1804375*e)/ja),u=ft((.2126729*n+.7151522*t+.072175*e)/Ha),i=ft((.0193339*n+.119192*t+.9503041*e)/Fa);return at(116*u-16,500*(r-u),200*(u-i))}function Mt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function _t(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function bt(n){return"function"==typeof n?n:function(){return n}}function wt(n){return n}function St(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),kt(t,e,n,r)}}function kt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Zo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Wo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Zo.event;Zo.event=n;try{o.progress.call(i,c)}finally{Zo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Xo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Zo.rebind(i,o,"on"),null==r?i:i.get(Et(r))}function Et(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function At(){var n=Ct(),t=Nt()-n;t>24?(isFinite(t)&&(clearTimeout($a),$a=setTimeout(At,t)),Xa=0):(Xa=1,Wa(At))}function Ct(){var n=Date.now();for(Ba=Za;Ba;)n>=Ba.t&&(Ba.f=Ba.c(n-Ba.t)),Ba=Ba.n;return n}function Nt(){for(var n,t=Za,e=1/0;t;)t.f?t=n?n.n=t.n:Za=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:wt;return function(n){var e=Ga.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=Ka.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Zo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function Rt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Dt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new nc(e-1)),1),e}function i(n,e){return t(n=new nc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{nc=Rt;var r=new Rt;return r._=n,o(r,t,e)}finally{nc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Pt(n);return c.floor=c,c.round=Pt(r),c.ceil=Pt(u),c.offset=Pt(i),c.range=a,n}function Pt(n){return function(t,e){try{nc=Rt;var r=new Rt;return r._=t,n(r,e)._}finally{nc=Date}}}function Ut(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in ec?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{nc=Rt;var t=new nc;return t._=n,r(t)}finally{nc=Date}}var r=t(n);return e.parse=function(n){try{nc=Rt;var t=r.parse(n);return t&&t._}finally{nc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=re;var x=Zo.map(),M=Ht(v),_=Ft(v),b=Ht(d),w=Ft(d),S=Ht(m),k=Ft(m),E=Ht(y),A=Ft(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return jt(n.getDate(),t,2)},e:function(n,t){return jt(n.getDate(),t,2)},H:function(n,t){return jt(n.getHours(),t,2)},I:function(n,t){return jt(n.getHours()%12||12,t,2)},j:function(n,t){return jt(1+Qa.dayOfYear(n),t,3)},L:function(n,t){return jt(n.getMilliseconds(),t,3)},m:function(n,t){return jt(n.getMonth()+1,t,2)},M:function(n,t){return jt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return jt(n.getSeconds(),t,2)},U:function(n,t){return jt(Qa.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return jt(Qa.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return jt(n.getFullYear()%100,t,2)},Y:function(n,t){return jt(n.getFullYear()%1e4,t,4)},Z:te,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Wt,e:Wt,H:Gt,I:Gt,j:Jt,L:ne,m:Bt,M:Kt,p:l,S:Qt,U:Yt,w:Ot,W:It,x:c,X:s,y:Vt,Y:Zt,Z:Xt,"%":ee};return t}function jt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Ht(n){return new RegExp("^(?:"+n.map(Zo.requote).join("|")+")","i")}function Ft(n){for(var t=new o,e=-1,r=n.length;++e68?1900:2e3)}function Bt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Wt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Jt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Gt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Kt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Qt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ne(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function te(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(ua(t)/60),u=ua(t)%60;return e+jt(r,"0",2)+jt(u,"0",2)}function ee(n,t,e){uc.lastIndex=0;var r=uc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function re(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);lc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;fc.point=function(o,a){fc.point=n,r=(t=o)*Aa,u=Math.cos(a=(e=a)*Aa/2+ba/4),i=Math.sin(a)},fc.lineEnd=function(){n(t,e)}}function le(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function fe(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function he(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function ge(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function pe(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function ve(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function de(n){return[Math.atan2(n[1],n[0]),G(n[2])]}function me(n,t){return ua(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new Ee(e,n,null,!0),s=new Ee(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Ee(r,n,null,!1),s=new Ee(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),ke(i),ke(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ke(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ce))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Zo.merge(g);var n=Le(m,p);g.length?(_||(i.polygonStart(),_=!0),Se(g,ze,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ne(),M=t(x),_=!1;return y}}function Ce(n){return n.length>1}function Ne(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:v,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function ze(n,t){return((n=n.x)[0]<0?n[1]-Sa-ka:Sa-n[1])-((t=t.x)[0]<0?t[1]-Sa-ka:Sa-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;lc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+ba/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+ba/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>ba,k=p*x;if(lc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*wa:_,S^h>=e^m>=e){var E=he(le(f),le(n));ve(E);var A=he(u,E);ve(A);var C=(S^_>=0?-1:1)*G(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-ka>i||ka>i&&0>lc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?ba:-ba,c=ua(i-e);ua(c-ba)0?Sa:-Sa),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=ba&&(ua(e-u)ka?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Re(n,t,e,r){var u;if(null==n)u=e*Sa,r.point(-ba,u),r.point(0,u),r.point(ba,u),r.point(ba,0),r.point(ba,-u),r.point(0,-u),r.point(-ba,-u),r.point(-ba,0),r.point(-ba,u);else if(ua(n[0]-t[0])>ka){var i=n[0]i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?ba:-ba),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(me(e,g)||me(p,g))&&(p[0]+=ka,p[1]+=ka,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&me(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=le(n),u=le(t),o=[1,0,0],a=he(r,u),c=fe(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=he(o,a),p=pe(o,f),v=pe(a,h);ge(p,v);var d=g,m=fe(p,d),y=fe(d,d),x=m*m-y*(fe(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=pe(d,(-m-M)/y);if(ge(_,p),_=de(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ua(A-ba)A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ua(_[0]-w)ba^(w<=_[0]&&_[0]<=S)){var z=pe(d,(-m+M)/y);return ge(z,p),[_,de(z)]}}}function u(t,e){var r=o?n:ba-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ua(i)>ka,c=sr(n,6*Aa);return Ae(t,e,c,o?[0,-n]:[-ba,n-ba])}function Pe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Ue(n,t,e,r){function u(r,u){return ua(r[0]-n)0?0:3:ua(r[0]-e)0?2:1:ua(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&W(s,i,n)>0&&++t:i[1]<=r&&W(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-kc,Math.min(kc,n)),t=Math.max(-kc,Math.min(kc,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ne(),C=Pe(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Zo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&Se(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function je(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function He(n){var t=0,e=ba/3,r=tr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ba/180,e=n[1]*ba/180):[180*(t/ba),180*(e/ba)]},u}function Fe(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,G((i-(n*n+e*e)*u*u)/(2*u))]},e}function Oe(){function n(n,t){Ac+=u*n-r*t,r=n,u=t}var t,e,r,u;Tc.point=function(i,o){Tc.point=n,t=r=i,e=u=o},Tc.lineEnd=function(){n(t,e)}}function Ye(n,t){Cc>n&&(Cc=n),n>zc&&(zc=n),Nc>t&&(Nc=t),t>Lc&&(Lc=t)}function Ie(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ze(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ze(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ze(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ve(n,t){pc+=n,vc+=t,++dc}function Xe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);mc+=o*(t+n)/2,yc+=o*(e+r)/2,xc+=o,Ve(t=n,e=r)}var t,e;Rc.point=function(r,u){Rc.point=n,Ve(t=r,e=u)}}function $e(){Rc.point=Ve}function Be(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);mc+=o*(r+n)/2,yc+=o*(u+t)/2,xc+=o,o=u*n-r*t,Mc+=o*(r+n),_c+=o*(u+t),bc+=3*o,Ve(r=n,u=t)}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,Ve(t=r=i,e=u=o)},Rc.lineEnd=function(){n(t,e)}}function We(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,wa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:v};return a}function Je(n){function t(n){return(a?r:e)(n)}function e(t){return Qe(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=le([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ua(ua(w)-1)i||ua((y*z+x*L)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Aa),a=16; return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Ge(n){var t=Je(function(t,e){return n([t*Ca,e*Ca])});return function(n){return er(t(n))}}function Ke(n){this.stream=n}function Qe(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function nr(n){return tr(function(){return n})()}function tr(n){function t(n){return n=a(n[0]*Aa,n[1]*Aa),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*Ca,n[1]*Ca]}function r(){a=je(o=ir(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=Je(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Sc,_=wt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=er(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Sc):De((b=+n)*Aa),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Ue(n[0][0],n[0][1],n[1][0],n[1][1]):wt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Aa,d=n[1]%360*Aa,r()):[v*Ca,d*Ca]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Aa,y=n[1]%360*Aa,x=n.length>2?n[2]%360*Aa:0,r()):[m*Ca,y*Ca,x*Ca]},Zo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function er(n){return Qe(n,function(t,e){n.point(t*Aa,e*Aa)})}function rr(n,t){return[n,t]}function ur(n,t){return[n>ba?n-wa:-ba>n?n+wa:n,t]}function ir(n,t,e){return n?t||e?je(ar(n),cr(t,e)):ar(n):t||e?cr(t,e):ur}function or(n){return function(t,e){return t+=n,[t>ba?t-wa:-ba>t?t+wa:t,e]}}function ar(n){var t=or(n);return t.invert=or(-n),t}function cr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),G(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),G(l*r-a*u)]},e}function sr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=lr(e,u),i=lr(e,i),(o>0?i>u:u>i)&&(u+=o*wa)):(u=n+o*wa,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=de([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function lr(n,t){var e=le(t);e[0]-=n,ve(e);var r=J(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-ka)%(2*Math.PI)}function fr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function hr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function gr(n){return n.source}function pr(n){return n.target}function vr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(tt(r-t)+u*o*tt(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ca,Math.atan2(o,Math.sqrt(r*r+u*u))*Ca]}:function(){return[n*Ca,t*Ca]};return p.distance=h,p}function dr(){function n(n,u){var i=Math.sin(u*=Aa),o=Math.cos(u),a=ua((n*=Aa)-t),c=Math.cos(a);Dc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Pc.point=function(u,i){t=u*Aa,e=Math.sin(i*=Aa),r=Math.cos(i),Pc.point=n},Pc.lineEnd=function(){Pc.point=Pc.lineEnd=v}}function mr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function yr(n,t){function e(n,t){o>0?-Sa+ka>t&&(t=-Sa+ka):t>Sa-ka&&(t=Sa-ka);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(ba/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=B(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Sa]},e):Mr}function xr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ua(u)u;u++){for(;r>1&&W(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function Er(n,t){return n[0]-t[0]||n[1]-t[1]}function Ar(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Cr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Nr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function zr(){Gr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Bc.pop()||new zr;return t.site=n,t}function Tr(n){Yr(n),Vc.remove(n),Bc.push(n),Gr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&ua(e-c.circle.x)l;++l)s=a[l],c=a[l-1],Br(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Xr(c.site,s.site,null,u),Or(c),Or(s)}function Rr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Vc._;a;)if(r=Dr(a,o)-i,r>ka)a=a.L;else{if(u=i-Pr(a,o),!(u>ka)){r>-ka?(t=a.P,e=a):u>-ka?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if(Vc.insert(t,c),t||e){if(t===e)return Yr(t),e=Lr(t.site),Vc.insert(c,e),c.edge=e.edge=Xr(t.site,c.site),Or(t),Or(e),void 0;if(!e)return c.edge=Xr(t.site,c.site),void 0;Yr(t),Yr(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};Br(e.edge,s,p,M),c.edge=Xr(s,n,null,M),e.edge=Xr(n,p,null,M),Or(t),Or(e)}}function Dr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Pr(n,t){var e=n.N;if(e)return Dr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ur(n){this.site=n,this.edges=[]}function jr(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Zc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(ua(r-t)>ka||ua(u-e)>ka)&&(a.splice(o,0,new Wr($r(i.site,l,ua(r-f)ka?{x:f,y:ua(t-f)ka?{x:ua(e-p)ka?{x:h,y:ua(t-h)ka?{x:ua(e-g)=-Ea)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Wc.pop()||new Fr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=$c._;x;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi&&(u=t.substring(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:lu(e,r)})),i=Kc.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function hu(n,t){for(var e,r=Zo.interpolators.length;--r>=0&&!(e=Zo.interpolators[r](n,t)););return e}function gu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(hu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function pu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function vu(n){return function(t){return 1-n(1-t)}}function du(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function mu(n){return n*n}function yu(n){return n*n*n}function xu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Mu(n){return function(t){return Math.pow(t,n)}}function _u(n){return 1-Math.cos(n*Sa)}function bu(n){return Math.pow(2,10*(n-1))}function wu(n){return 1-Math.sqrt(1-n*n)}function Su(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/wa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*wa/t)}}function ku(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Eu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Au(n,t){n=Zo.hcl(n),t=Zo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Zo.hsl(n),t=Zo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ut(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){n=Zo.lab(n),t=Zo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function zu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(Ru(e,t,-u))||0;t[0]*e[1]180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:lu(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:lu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:lu(g[0],p[0])},{i:e-2,x:lu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i=0;)e.push(u[r])}function Bu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++oe;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ii(n){return n.reduce(oi,0)}function oi(n,t){return n+t[1]}function ai(n,t){return ci(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ci(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function si(n){return[Zo.min(n),Zo.max(n)]}function li(n,t){return n.value-t.value}function fi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function hi(n,t){n._pack_next=t,t._pack_prev=n}function gi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function pi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(vi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],yi(r,u,i),t(i),fi(r,i),r._pack_prev=i,fi(i,u),u=r._pack_next,o=3;s>o;o++){yi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(gi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!gi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(di)}}function vi(n){n._pack_next=n._pack_prev=n}function di(n){delete n._pack_next,delete n._pack_prev}function mi(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Si(n,t,e){return n.a.parent===t.parent?n.a:e}function ki(n){return 1+Zo.max(n,function(n){return n.y})}function Ei(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ai(n){var t=n.children;return t&&t.length?Ai(t[0]):n}function Ci(n){var t,e=n.children;return e&&(t=e.length)?Ci(e[t-1]):n}function Ni(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function zi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Li(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ti(n){return n.rangeExtent?n.rangeExtent():Li(n.range())}function qi(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Ri(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Di(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ss}function Pi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Pi:qi,c=r?Uu:Pu;return o=u(n,t,c,e),a=u(t,n,c,hu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(zu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Oi(n,t)},i.tickFormat=function(t,e){return Yi(n,t,e)},i.nice=function(t){return Hi(n,t),u()},i.copy=function(){return Ui(n,t,e,r)},u()}function ji(n,t){return Zo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Hi(n,t){return Ri(n,Di(Fi(n,t)[2]))}function Fi(n,t){null==t&&(t=10);var e=Li(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Oi(n,t){return Zo.range.apply(Zo,Fi(n,t))}function Yi(n,t,e){var r=Fi(n,t);if(e){var u=Ga.exec(e);if(u.shift(),"s"===u[8]){var i=Zo.formatPrefix(Math.max(ua(r[0]),ua(r[1])));return u[7]||(u[7]="."+Ii(i.scale(r[2]))),u[8]="f",e=Zo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Zi(u[8],r)),e=u.join("")}else e=",."+Ii(r[2])+"f";return Zo.format(e)}function Ii(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Zi(n,t){var e=Ii(t[2]);return n in ls?Math.abs(e-Ii(Math.max(ua(t[0]),ua(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Vi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Ri(r.map(u),e?Math:hs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Li(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++0;h--)o.push(i(s)*h);for(s=0;o[s]c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return fs;arguments.length<2?t=fs:"function"!=typeof t&&(t=Zo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Vi(n.copy(),t,e,r)},ji(o,n)}function Xi(n,t,e){function r(t){return n(u(t))}var u=$i(t),i=$i(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Oi(e,n)},r.tickFormat=function(n,t){return Yi(e,n,t)},r.nice=function(n){return r.domain(Hi(e,n))},r.exponent=function(o){return arguments.length?(u=$i(t=o),i=$i(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Xi(n.copy(),t,e)},ji(r,n)}function $i(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Bi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Zo.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new o;for(var i,a=-1,c=r.length;++an?[0/0,0/0]:[n>0?o[n-1]:e[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ji(n,t,e)},u()}function Gi(n,t){function e(e){return e>=e?t[Zo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Gi(n,t)},e}function Ki(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Oi(n,t)},t.tickFormat=function(t,e){return Yi(n,t,e)},t.copy=function(){return Ki(n)},t}function Qi(n){return n.innerRadius}function no(n){return n.outerRadius}function to(n){return n.startAngle}function eo(n){return n.endAngle}function ro(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=bt(e),p=bt(r);++f1&&u.push("H",r[0]),u.join("")}function ao(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function So(n){return n.length<3?uo(n):n[0]+ho(n,wo(n))}function ko(n){for(var t,e,r,u=-1,i=n.length;++ue?s():(u.active=e,i.event&&i.event.start.call(n,l,t),i.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Zo.timer(function(){return p.c=c(r||1)?we:c,1},0,a),void 0)}function c(r){if(u.active!==e)return s();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a); -return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ba,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Uo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function jo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Ho(n){return n.toISOString()}function Fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Zo.bisect(Us,u);return i==Us.length?[t.year,Fi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Us[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Oo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Oo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Li(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Oo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Fo(n.copy(),t,e)},ji(r,n)}function Oo(n){return new Date(n)}function Yo(n){return JSON.parse(n.responseText)}function Io(n){var t=$o.createRange();return t.selectNode($o.body),t.createContextualFragment(n.responseText)}var Zo={version:"3.4.9"};Date.now||(Date.now=function(){return+new Date});var Vo=[].slice,Xo=function(n){return Vo.call(n)},$o=document,Bo=$o.documentElement,Wo=window;try{Xo(Bo.childNodes)[0].nodeType}catch(Jo){Xo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{$o.createElement("div").style.setProperty("opacity",0,"")}catch(Go){var Ko=Wo.Element.prototype,Qo=Ko.setAttribute,na=Ko.setAttributeNS,ta=Wo.CSSStyleDeclaration.prototype,ea=ta.setProperty;Ko.setAttribute=function(n,t){Qo.call(this,n,t+"")},Ko.setAttributeNS=function(n,t,e){na.call(this,n,t,e+"")},ta.setProperty=function(n,t,e){ea.call(this,n,t+"",e)}}Zo.ascending=n,Zo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Zo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ur&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r)}return e},Zo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ue&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ue&&(e=r)}return e},Zo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=e);)e=u=void 0;for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=e);)e=void 0;for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},Zo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i1&&(e=e.map(r)),e=e.filter(t),e.length?Zo.quantile(e.sort(n),.5):void 0};var ra=e(n);Zo.bisectLeft=ra.left,Zo.bisect=Zo.bisectRight=ra.right,Zo.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Zo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Zo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Zo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Zo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Zo.min(arguments,r),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ua=Math.abs;Zo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(ua(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++g=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Zo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Zo.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ia+n]=!0,n},remove:function(n){return n=ia+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1))}}),Zo.behavior={},Zo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Zo.event=null,Zo.requote=function(n){return n.replace(ca,"\\$&")};var ca=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},la=function(n,t){return t.querySelector(n)},fa=function(n,t){return t.querySelectorAll(n)},ha=Bo.matches||Bo[p(Bo,"matchesSelector")],ga=function(n,t){return ha.call(n,t)};"function"==typeof Sizzle&&(la=function(n,t){return Sizzle(n,t)[0]||null},fa=Sizzle,ga=Sizzle.matchesSelector),Zo.selection=function(){return ma};var pa=Zo.selection.prototype=[];pa.select=function(n){var t,e,r,u,i=[];n=b(n);for(var o=-1,a=this.length;++o=0&&(e=n.substring(0,t),n=n.substring(t+1)),va.hasOwnProperty(e)?{space:va[e],local:n}:n}},pa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Zo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},pa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(z(e,n[e],t));return this}if(2>r)return Wo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(z(n,t,e))},pa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},pa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},pa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},pa.append=function(n){return n=T(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},pa.insert=function(n,t){return n=T(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},pa.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},pa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new o,y=new o,x=[];for(r=-1;++rr;++r)p[r]=q(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return _(u)},pa.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},pa.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},pa.size=function(){var n=0;return this.each(function(){++n}),n};var da=[];Zo.selection.enter=U,Zo.selection.enter.prototype=da,da.append=pa.append,da.empty=pa.empty,da.node=pa.node,da.call=pa.call,da.size=pa.size,da.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ya=Zo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ya.forEach(function(n){"on"+n in $o&&ya.remove(n)});var xa="onselectstart"in $o?null:p(Bo.style,"userSelect"),Ma=0;Zo.mouse=function(n){return Z(n,x())};var _a=/WebKit/.test(Wo.navigator.userAgent)?-1:0;Zo.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Xo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Zo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Zo.event.target===f),g({type:"dragend"}))}var s,l=this,f=Zo.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Zo.select(u()).on(i+d,a).on(o+d,c),y=I(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Zo.mouse,$,"mousemove","mouseup"),i=t(V,Zo.touch,X,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Zo.rebind(n,e,"on")};var ba=Math.PI,wa=2*ba,Sa=ba/2,ka=1e-6,Ea=ka*ka,Aa=ba/180,Ca=180/ba,Na=Math.SQRT2,za=2,La=4;Zo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(za*h)*(e*nt(Na*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Na*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Na*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+La*f)/(2*i*za*h),p=(c*c-i*i-La*f)/(2*c*za*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Na;return e.duration=1e3*y,e},Zo.behavior.zoom=function(){function n(n){n.on(A,s).on(Ra+".zoom",f).on(C,h).on("dblclick.zoom",g).on(z,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Zo.mouse(r),g),a(s)}function e(){f.on(C,Wo===r?h:null).on(N,null),p(l&&Zo.event.target===i),c(s)}var r=this,i=Zo.event.target,s=L.of(r,arguments),l=0,f=Zo.select(Wo).on(C,n).on(N,e),g=t(Zo.mouse(r)),p=I();H.call(r),o(s)}function l(){function n(){var n=Zo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Zo.event.target;Zo.select(t).on(M,i).on(_,f),b.push(t);for(var e=Zo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var s=n(),l=Date.now();if(1===s.length){if(500>l-m){var h=s[0],g=v[h.identifier];r(2*S.k),u(h,g),y(),a(p)}m=l}else if(s.length>1){var h=s[0],x=s[1],w=h[0]-x[0],k=h[1]-x[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Zo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=d&&Math.sqrt(l/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Zo.event.touches.length){for(var t=Zo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Zo.selectAll(b).on(x,null),w.on(A,s).on(z,l),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,x=".zoom-"+Zo.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=[],w=Zo.select(g).on(A,null).on(z,e),k=I();H.call(g),e(),o(p)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y();var e=v||Zo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ta())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=L.of(this,arguments),e=Zo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Zo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=qa,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Ss?Zo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Zo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?qa:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,x=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Zo.rebind(n,L,"on")};var Ta,qa=[0,1/0],Ra="onwheel"in $o?(Ta=function(){return-Zo.event.deltaY*(Zo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in $o?(Ta=function(){return Zo.event.wheelDelta},"mousewheel"):(Ta=function(){return-Zo.event.detail},"MozMousePixelScroll");Zo.color=et,et.prototype.toString=function(){return this.rgb()+""},Zo.hsl=rt;var Da=rt.prototype=new et;Da.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,this.l/n)},Da.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,n*this.l)},Da.rgb=function(){return ut(this.h,this.s,this.l)},Zo.hcl=it;var Pa=it.prototype=new et;Pa.brighter=function(n){return new it(this.h,this.c,Math.min(100,this.l+Ua*(arguments.length?n:1)))},Pa.darker=function(n){return new it(this.h,this.c,Math.max(0,this.l-Ua*(arguments.length?n:1)))},Pa.rgb=function(){return ot(this.h,this.c,this.l).rgb()},Zo.lab=at;var Ua=18,ja=.95047,Ha=1,Fa=1.08883,Oa=at.prototype=new et;Oa.brighter=function(n){return new at(Math.min(100,this.l+Ua*(arguments.length?n:1)),this.a,this.b)},Oa.darker=function(n){return new at(Math.max(0,this.l-Ua*(arguments.length?n:1)),this.a,this.b)},Oa.rgb=function(){return ct(this.l,this.a,this.b)},Zo.rgb=gt;var Ya=gt.prototype=new et;Ya.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new gt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new gt(u,u,u)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new gt(n*this.r,n*this.g,n*this.b)},Ya.hsl=function(){return yt(this.r,this.g,this.b)},Ya.toString=function(){return"#"+dt(this.r)+dt(this.g)+dt(this.b)};var Ia=Zo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ia.forEach(function(n,t){Ia.set(n,pt(t))}),Zo.functor=bt,Zo.xhr=St(wt),Zo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=kt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new h,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Zo.csv=Zo.dsv(",","text/csv"),Zo.tsv=Zo.dsv(" ","text/tab-separated-values"),Zo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Za,Va,Xa,$a,Ba,Wa=Wo[p(Wo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Zo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Va?Va.n=i:Za=i,Va=i,Xa||($a=clearTimeout($a),Xa=1,Wa(At))},Zo.timer.flush=function(){Ct(),Nt()},Zo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ja=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Zo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Zo.round(n,zt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),Ja[8+e/3]};var Ga=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Ka=Zo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Zo.round(n,zt(n,t))).toFixed(Math.max(0,Math.min(20,zt(n*(1+1e-15),t))))}}),Qa=Zo.time={},nc=Date;Rt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){tc.setUTCDate.apply(this._,arguments)},setDay:function(){tc.setUTCDay.apply(this._,arguments)},setFullYear:function(){tc.setUTCFullYear.apply(this._,arguments)},setHours:function(){tc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){tc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){tc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){tc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){tc.setUTCSeconds.apply(this._,arguments)},setTime:function(){tc.setTime.apply(this._,arguments)}};var tc=Date.prototype;Qa.year=Dt(function(n){return n=Qa.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Qa.years=Qa.year.range,Qa.years.utc=Qa.year.utc.range,Qa.day=Dt(function(n){var t=new nc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Qa.days=Qa.day.range,Qa.days.utc=Qa.day.utc.range,Qa.dayOfYear=function(n){var t=Qa.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=Qa[n]=Dt(function(n){return(n=Qa.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Qa[n+"s"]=e.range,Qa[n+"s"].utc=e.utc.range,Qa[n+"OfYear"]=function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)}}),Qa.week=Qa.sunday,Qa.weeks=Qa.sunday.range,Qa.weeks.utc=Qa.sunday.utc.range,Qa.weekOfYear=Qa.sundayOfYear;var ec={"-":"",_:" ",0:"0"},rc=/^\s*\d+/,uc=/^%/;Zo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Ut(n)}};var ic=Zo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Zo.format=ic.numberFormat,Zo.geo={},ue.prototype={s:0,t:0,add:function(n){ie(n,this.t,oc),ie(oc.s,this.s,this),this.s?this.t+=oc.t:this.s=oc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var oc=new ue;Zo.geo.stream=function(n,t){n&&ac.hasOwnProperty(n.type)?ac[n.type](n,t):oe(n,t)};var ac={Feature:function(n,t){oe(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*ba+n:n,fc.lineStart=fc.lineEnd=fc.point=v}};Zo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=le([t*Aa,e*Aa]);if(m){var u=he(m,r),i=[u[1],-u[0],0],o=he(i,u);ve(o),o=de(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ca*s,d=ua(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ca;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ca;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ua(r)>180?r+(r>0?360:-360):r}else v=n,d=e;fc.point(n,e),t(n,e)}function i(){fc.lineStart()}function o(){u(v,d),fc.lineEnd(),ua(y)>ka&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nlc?(l=-(h=180),f=-(g=90)):y>ka?g=90:-ka>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Zo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e); -for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Zo.geo.centroid=function(n){hc=gc=pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,wc);var t=Mc,e=_c,r=bc,u=t*t+e*e+r*r;return Ea>u&&(t=mc,e=yc,r=xc,ka>gc&&(t=pc,e=vc,r=dc),u=t*t+e*e+r*r,Ea>u)?[0/0,0/0]:[Math.atan2(e,t)*Ca,G(r/Math.sqrt(u))*Ca]};var hc,gc,pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc={sphere:v,point:ye,lineStart:Me,lineEnd:_e,polygonStart:function(){wc.lineStart=be},polygonEnd:function(){wc.lineStart=Me}},Sc=Ae(we,Te,Re,[-ba,-ba/2]),kc=1e9;Zo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ue(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Zo.geo.conicEqualArea=function(){return He(Fe)}).raw=Fe,Zo.geo.albers=function(){return Zo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Zo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Zo.geo.albers(),o=Zo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Zo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+ka,f+.12*s+ka],[l-.214*s-ka,f+.234*s-ka]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+ka,f+.166*s+ka],[l-.115*s-ka,f+.234*s-ka]]).stream(c).point,n},n.scale(1070)};var Ec,Ac,Cc,Nc,zc,Lc,Tc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){Ac=0,Tc.lineStart=Oe},polygonEnd:function(){Tc.lineStart=Tc.lineEnd=Tc.point=v,Ec+=ua(Ac/2)}},qc={point:Ye,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Rc={point:Ve,lineStart:Xe,lineEnd:$e,polygonStart:function(){Rc.lineStart=Be},polygonEnd:function(){Rc.point=Ve,Rc.lineStart=Xe,Rc.lineEnd=$e}};Zo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Zo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ec=0,Zo.geo.stream(n,u(Tc)),Ec},n.centroid=function(n){return pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,u(Rc)),bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:dc?[pc/dc,vc/dc]:[0/0,0/0]},n.bounds=function(n){return zc=Lc=-(Cc=Nc=1/0),Zo.geo.stream(n,u(qc)),[[Cc,Nc],[zc,Lc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Ge(n):wt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ie:new We(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Zo.geo.albersUsa()).context(null)},Zo.geo.transform=function(n){return{stream:function(t){var e=new Ke(t);for(var r in n)e[r]=n[r];return e}}},Ke.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Zo.geo.projection=nr,Zo.geo.projectionMutator=tr,(Zo.geo.equirectangular=function(){return nr(rr)}).raw=rr.invert=rr,Zo.geo.rotation=function(n){function t(t){return t=n(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t}return n=ir(n[0]%360*Aa,n[1]*Aa,n.length>2?n[2]*Aa:0),t.invert=function(t){return t=n.invert(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t},t},ur.invert=rr,Zo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ir(-n[0]*Aa,-n[1]*Aa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ca,n[1]*=Ca}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=sr((t=+r)*Aa,u*Aa),n):t},n.precision=function(r){return arguments.length?(e=sr(t*Aa,(u=+r)*Aa),n):u},n.angle(90)},Zo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Aa,u=n[1]*Aa,i=t[1]*Aa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Zo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Zo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Zo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Zo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ua(n%d)>ka}).map(l)).concat(Zo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ua(n%m)>ka}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=fr(a,o,90),f=hr(r,e,y),h=fr(s,c,90),g=hr(i,u,y),n):y},n.majorExtent([[-180,-90+ka],[180,90-ka]]).minorExtent([[-180,-80-ka],[180,80+ka]])},Zo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=gr,u=pr;return n.distance=function(){return Zo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Zo.geo.interpolate=function(n,t){return vr(n[0]*Aa,n[1]*Aa,t[0]*Aa,t[1]*Aa)},Zo.geo.length=function(n){return Dc=0,Zo.geo.stream(n,Pc),Dc};var Dc,Pc={sphere:v,point:v,lineStart:dr,lineEnd:v,polygonStart:v,polygonEnd:v},Uc=mr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Zo.geo.azimuthalEqualArea=function(){return nr(Uc)}).raw=Uc;var jc=mr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},wt);(Zo.geo.azimuthalEquidistant=function(){return nr(jc)}).raw=jc,(Zo.geo.conicConformal=function(){return He(yr)}).raw=yr,(Zo.geo.conicEquidistant=function(){return He(xr)}).raw=xr;var Hc=mr(function(n){return 1/n},Math.atan);(Zo.geo.gnomonic=function(){return nr(Hc)}).raw=Hc,Mr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Sa]},(Zo.geo.mercator=function(){return _r(Mr)}).raw=Mr;var Fc=mr(function(){return 1},Math.asin);(Zo.geo.orthographic=function(){return nr(Fc)}).raw=Fc;var Oc=mr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Zo.geo.stereographic=function(){return nr(Oc)}).raw=Oc,br.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Sa]},(Zo.geo.transverseMercator=function(){var n=_r(br),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=br,Zo.geom={},Zo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=bt(e),i=bt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(Er),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=kr(a),l=kr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/ka)*ka,y:Math.round(o(n,t)/ka)*ka,i:t}})}var r=wr,u=Sr,i=r,o=u,a=Jc;return n?t(n):(t.links=function(n){return tu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return tu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Hr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=ou()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=bt(a),M=bt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.xm&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=ou();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){au(n,k,v,d,m,y)},g=-1,null==t){for(;++g=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ns.get(e)||Qc,r=ts.get(r)||wt,pu(r(e.apply(null,Vo.call(arguments,1))))},Zo.interpolateHcl=Au,Zo.interpolateHsl=Cu,Zo.interpolateLab=Nu,Zo.interpolateRound=zu,Zo.transform=function(n){var t=$o.createElementNS(Zo.ns.prefix.svg,"g");return(Zo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:es)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var es={a:1,b:0,c:0,d:1,e:0,f:0};Zo.interpolateTransform=Du,Zo.layout={},Zo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Zo.event.x,n.py=Zo.event.y,a.resume()}var e,r,u,i,o,a={},c=Zo.dispatch("start","tick","end"),s=[1,1],l=.9,f=rs,h=us,g=-30,p=is,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Vu(t=Zo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Zo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Zo.behavior.drag().origin(wt).on("dragstart.force",Ou).on("drag.force",t).on("dragend.force",Yu)),arguments.length?(this.on("mouseover.force",Iu).on("mouseout.force",Zu).call(e),void 0):e},Zo.rebind(a,c,"on")};var rs=20,us=1,is=1/0;Zo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(s=e.call(n,i,i.depth))&&(c=s.length)){for(var c,s,l;--c>=0;)o.push(l=s[c]),l.parent=i,l.depth=i.depth+1;r&&(i.value=0),i.children=s}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Bu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=Gu,e=Wu,r=Ju;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&($u(t,function(n){n.children&&(n.value=0)}),Bu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Zo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++sg;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=wt,e=ei,r=ri,u=ti,i=Qu,o=ni;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:as.get(t)||ei,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:cs.get(t)||ri,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var as=Zo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ui),i=n.map(ii),o=Zo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Zo.range(n.length).reverse()},"default":ei}),cs=Zo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ri});Zo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=l[0]&&a<=l[1]&&(o=c[Zo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=si,u=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=bt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ci(n,t)}:bt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Zo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Bu(a,function(n){n.r=+l(n.value)}),Bu(a,pi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Bu(a,function(n){n.r+=f}),Bu(a,pi),Bu(a,function(n){n.r-=f})}return mi(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Zo.layout.hierarchy().sort(li),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Xu(n,e)},Zo.layout.tree=function(){function n(n,u){var l=o.call(this,n,u),f=l[0],h=t(f);if(Bu(h,e),h.parent.m=-h.z,$u(h,r),s)$u(f,i);else{var g=f,p=f,v=f;$u(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);$u(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return l}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){wi(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],s=u.m,l=i.m,f=o.m,h=c.m;o=_i(o),u=Mi(u),o&&u;)c=Mi(c),i=_i(i),i.a=n,r=o.z+f-u.z-s+a(o._,u._),r>0&&(bi(Si(o,n,e),n,r),s+=r,l+=r),f+=o.m,s+=u.m,h+=c.m,l+=i.m;o&&!_i(i)&&(i.t=o,i.m+=f-l),u&&!Mi(c)&&(c.t=u,c.m+=s-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Zo.layout.hierarchy().sort(null).value(null),a=xi,c=[1,1],s=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(s=null==(c=t)?i:null,n):s?null:c},n.nodeSize=function(t){return arguments.length?(s=null==(c=t)?null:i,n):s?c:null},Xu(n,o)},Zo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Bu(c,function(n){var t=n.children;t&&t.length?(n.x=Ei(t),n.y=ki(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ai(c),f=Ci(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Bu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Zo.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Xu(n,t)},Zo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++ie.dx)&&(l=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Zo.random.normal.apply(Zo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Zo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Zo.scale={};var ss={floor:wt,ceil:wt};Zo.scale.linear=function(){return Ui([0,1],[0,1],hu,!1)};var ls={s:1,g:1,p:1,r:1,e:1};Zo.scale.log=function(){return Vi(Zo.scale.linear().domain([0,1]),10,!0,[1,10])};var fs=Zo.format(".0e"),hs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Zo.scale.pow=function(){return Xi(Zo.scale.linear(),1,[0,1])},Zo.scale.sqrt=function(){return Zo.scale.pow().exponent(.5)},Zo.scale.ordinal=function(){return Bi([],{t:"range",a:[[]]})},Zo.scale.category10=function(){return Zo.scale.ordinal().range(gs)},Zo.scale.category20=function(){return Zo.scale.ordinal().range(ps)},Zo.scale.category20b=function(){return Zo.scale.ordinal().range(vs)},Zo.scale.category20c=function(){return Zo.scale.ordinal().range(ds)};var gs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(vt),ps=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(vt),vs=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(vt),ds=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(vt);Zo.scale.quantile=function(){return Wi([],[])},Zo.scale.quantize=function(){return Ji(0,1,[0,1])},Zo.scale.threshold=function(){return Gi([.5],[0,1])},Zo.scale.identity=function(){return Ki([0,1])},Zo.svg={},Zo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ms,a=u.apply(this,arguments)+ms,c=(o>a&&(c=o,o=a,a=c),a-o),s=ba>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a); -return c>=ys?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=Qi,e=no,r=to,u=eo;return n.innerRadius=function(e){return arguments.length?(t=bt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=bt(t),n):e},n.startAngle=function(t){return arguments.length?(r=bt(t),n):r},n.endAngle=function(t){return arguments.length?(u=bt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ms;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ms=-Sa,ys=wa-ka;Zo.svg.line=function(){return ro(wt)};var xs=Zo.map({linear:uo,"linear-closed":io,step:oo,"step-before":ao,"step-after":co,basis:po,"basis-open":vo,"basis-closed":mo,bundle:yo,cardinal:fo,"cardinal-open":so,"cardinal-closed":lo,monotone:So});xs.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Ms=[0,2/3,1/3,0],_s=[0,1/3,2/3,0],bs=[0,1/6,2/3,1/6];Zo.svg.line.radial=function(){var n=ro(ko);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},ao.reverse=co,co.reverse=ao,Zo.svg.area=function(){return Eo(wt)},Zo.svg.area.radial=function(){var n=Eo(ko);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Zo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ms,l=s.call(n,u,r)+ms;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>ba)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=gr,o=pr,a=Ao,c=to,s=eo;return n.radius=function(t){return arguments.length?(a=bt(t),n):a},n.source=function(t){return arguments.length?(i=bt(t),n):i},n.target=function(t){return arguments.length?(o=bt(t),n):o},n.startAngle=function(t){return arguments.length?(c=bt(t),n):c},n.endAngle=function(t){return arguments.length?(s=bt(t),n):s},n},Zo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=gr,e=pr,r=Co;return n.source=function(e){return arguments.length?(t=bt(e),n):t},n.target=function(t){return arguments.length?(e=bt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Zo.svg.diagonal.radial=function(){var n=Zo.svg.diagonal(),t=Co,e=n.projection;return n.projection=function(n){return arguments.length?e(No(t=n)):t},n},Zo.svg.symbol=function(){function n(n,r){return(ws.get(t.call(this,n,r))||To)(e.call(this,n,r))}var t=Lo,e=zo;return n.type=function(e){return arguments.length?(t=bt(e),n):t},n.size=function(t){return arguments.length?(e=bt(t),n):e},n};var ws=Zo.map({circle:To,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*As)),e=t*As;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Zo.svg.symbolTypes=ws.keys();var Ss,ks,Es=Math.sqrt(3),As=Math.tan(30*Aa),Cs=[],Ns=0;Cs.call=pa.call,Cs.empty=pa.empty,Cs.node=pa.node,Cs.size=pa.size,Zo.transition=function(n){return arguments.length?Ss?n.transition():n:ma.transition()},Zo.transition.prototype=Cs,Cs.select=function(n){var t,e,r,u=this.id,i=[];n=b(n);for(var o=-1,a=this.length;++oi;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return qo(u,this.id)},Cs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Cs.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Du:hu,a=Zo.ns.qualify(n);return Ro(this,"attr."+n,t,a.local?i:u)},Cs.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Zo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Cs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Wo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=hu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Ro(this,"style."+n,t,u)},Cs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Wo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Cs.text=function(n){return Ro(this,"text",n,Do)},Cs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Cs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Zo.ease.apply(Zo,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Cs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Cs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Cs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=ks,u=Ss;Ss=e,P(this,function(t,r,u){ks=t.__transition__[e],n.call(t,t.__data__,r,u)}),ks=r,Ss=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Zo.dispatch("start","end"))).on(n,t)});return this},Cs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ns,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Po(e,s,i,r)),n.push(e)}return qo(o,i)},Zo.svg.axis=function(){function n(n){n.each(function(){var n,s=Zo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):wt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",ka),d=Zo.transition(p.exit()).style("opacity",ka).remove(),m=Zo.transition(p.order()).style("opacity",1),y=Ti(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Zo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Uo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Uo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=jo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=jo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Zo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Ls?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",Ls={top:1,right:1,bottom:1,left:1};Zo.svg.brush=function(){function n(i){i.each(function(){var i=Zo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,wt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Zo.transition(i),h=Zo.transition(o);c&&(l=Ti(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ti(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Zo.event.keyCode&&(C||(x=null,z[0]-=l[1],z[1]-=f[1],C=2),y())}function p(){32==Zo.event.keyCode&&2==C&&(z[0]+=l[1],z[1]+=f[1],C=0,y())}function v(){var n=Zo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Zo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),z[0]=l[+(n[0]p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Zo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Zo.select(Zo.event.target),w=a.of(_,arguments),S=Zo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=I(),z=Zo.mouse(_),L=Zo.select(Wo).on("keydown.brush",u).on("keyup.brush",p);if(Zo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=l[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);M=[l[1-T]-z[0],f[1-q]-z[1]],z[0]=l[T],z[1]=f[q]}else Zo.event.altKey&&(x=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Zo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=qs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ss?Zo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=gu(l,t.x),r=gu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=qs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=qs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Zo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},qs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Rs=Qa.format=ic.timeFormat,Ds=Rs.utc,Ps=Ds("%Y-%m-%dT%H:%M:%S.%LZ");Rs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ho:Ps,Ho.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ho.toString=Ps.toString,Qa.second=Dt(function(n){return new nc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Qa.seconds=Qa.second.range,Qa.seconds.utc=Qa.second.utc.range,Qa.minute=Dt(function(n){return new nc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Qa.minutes=Qa.minute.range,Qa.minutes.utc=Qa.minute.utc.range,Qa.hour=Dt(function(n){var t=n.getTimezoneOffset()/60;return new nc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Qa.hours=Qa.hour.range,Qa.hours.utc=Qa.hour.utc.range,Qa.month=Dt(function(n){return n=Qa.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Qa.months=Qa.month.range,Qa.months.utc=Qa.month.utc.range;var Us=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],js=[[Qa.second,1],[Qa.second,5],[Qa.second,15],[Qa.second,30],[Qa.minute,1],[Qa.minute,5],[Qa.minute,15],[Qa.minute,30],[Qa.hour,1],[Qa.hour,3],[Qa.hour,6],[Qa.hour,12],[Qa.day,1],[Qa.day,2],[Qa.week,1],[Qa.month,1],[Qa.month,3],[Qa.year,1]],Hs=Rs.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",we]]),Fs={range:function(n,t,e){return Zo.range(Math.ceil(n/e)*e,+t,e).map(Oo)},floor:wt,ceil:wt};js.year=Qa.year,Qa.scale=function(){return Fo(Zo.scale.linear(),js,Hs)};var Os=js.map(function(n){return[n[0].utc,n[1]]}),Ys=Ds.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",we]]);Os.year=Qa.year.utc,Qa.scale.utc=function(){return Fo(Zo.scale.linear(),Os,Ys)},Zo.text=St(function(n){return n.responseText}),Zo.json=function(n,t){return kt(n,"application/json",Yo,t)},Zo.html=function(n,t){return kt(n,"text/html",Io,t)},Zo.xml=St(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Zo):"object"==typeof module&&module.exports?module.exports=Zo:this.d3=Zo}(); \ No newline at end of file +return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ba,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Uo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function jo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Ho(n){return n.toISOString()}function Fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Zo.bisect(Us,u);return i==Us.length?[t.year,Fi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Us[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Oo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Oo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Li(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Oo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Fo(n.copy(),t,e)},ji(r,n)}function Oo(n){return new Date(n)}function Yo(n){return JSON.parse(n.responseText)}function Io(n){var t=$o.createRange();return t.selectNode($o.body),t.createContextualFragment(n.responseText)}var Zo={version:"3.4.11"};Date.now||(Date.now=function(){return+new Date});var Vo=[].slice,Xo=function(n){return Vo.call(n)},$o=document,Bo=$o.documentElement,Wo=window;try{Xo(Bo.childNodes)[0].nodeType}catch(Jo){Xo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{$o.createElement("div").style.setProperty("opacity",0,"")}catch(Go){var Ko=Wo.Element.prototype,Qo=Ko.setAttribute,na=Ko.setAttributeNS,ta=Wo.CSSStyleDeclaration.prototype,ea=ta.setProperty;Ko.setAttribute=function(n,t){Qo.call(this,n,t+"")},Ko.setAttributeNS=function(n,t,e){na.call(this,n,t,e+"")},ta.setProperty=function(n,t,e){ea.call(this,n,t+"",e)}}Zo.ascending=n,Zo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Zo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ur&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r)}return e},Zo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ue&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ue&&(e=r)}return e},Zo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=e);)e=u=void 0;for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=e);)e=void 0;for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},Zo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i1&&(e=e.map(r)),e=e.filter(t),e.length?Zo.quantile(e.sort(n),.5):void 0};var ra=e(n);Zo.bisectLeft=ra.left,Zo.bisect=Zo.bisectRight=ra.right,Zo.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Zo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Zo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Zo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Zo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Zo.min(arguments,r),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ua=Math.abs;Zo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(ua(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++g=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Zo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Zo.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ia+n]=!0,n},remove:function(n){return n=ia+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1))}}),Zo.behavior={},Zo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Zo.event=null,Zo.requote=function(n){return n.replace(ca,"\\$&")};var ca=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},la=function(n,t){return t.querySelector(n)},fa=function(n,t){return t.querySelectorAll(n)},ha=Bo.matches||Bo[p(Bo,"matchesSelector")],ga=function(n,t){return ha.call(n,t)};"function"==typeof Sizzle&&(la=function(n,t){return Sizzle(n,t)[0]||null},fa=Sizzle,ga=Sizzle.matchesSelector),Zo.selection=function(){return ma};var pa=Zo.selection.prototype=[];pa.select=function(n){var t,e,r,u,i=[];n=b(n);for(var o=-1,a=this.length;++o=0&&(e=n.substring(0,t),n=n.substring(t+1)),va.hasOwnProperty(e)?{space:va[e],local:n}:n}},pa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Zo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},pa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(z(e,n[e],t));return this}if(2>r)return Wo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(z(n,t,e))},pa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},pa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},pa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},pa.append=function(n){return n=T(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},pa.insert=function(n,t){return n=T(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},pa.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},pa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new o,y=new o,x=[];for(r=-1;++rr;++r)p[r]=q(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return _(u)},pa.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},pa.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},pa.size=function(){var n=0;return this.each(function(){++n}),n};var da=[];Zo.selection.enter=U,Zo.selection.enter.prototype=da,da.append=pa.append,da.empty=pa.empty,da.node=pa.node,da.call=pa.call,da.size=pa.size,da.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ya=Zo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ya.forEach(function(n){"on"+n in $o&&ya.remove(n)});var xa="onselectstart"in $o?null:p(Bo.style,"userSelect"),Ma=0;Zo.mouse=function(n){return Z(n,x())};var _a=/WebKit/.test(Wo.navigator.userAgent)?-1:0;Zo.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Xo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Zo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Zo.event.target===f),g({type:"dragend"}))}var s,l=this,f=Zo.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Zo.select(u()).on(i+d,a).on(o+d,c),y=I(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Zo.mouse,$,"mousemove","mouseup"),i=t(V,Zo.touch,X,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Zo.rebind(n,e,"on")};var ba=Math.PI,wa=2*ba,Sa=ba/2,ka=1e-6,Ea=ka*ka,Aa=ba/180,Ca=180/ba,Na=Math.SQRT2,za=2,La=4;Zo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(za*h)*(e*nt(Na*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Na*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Na*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+La*f)/(2*i*za*h),p=(c*c-i*i-La*f)/(2*c*za*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Na;return e.duration=1e3*y,e},Zo.behavior.zoom=function(){function n(n){n.on(A,s).on(Ra+".zoom",f).on("dblclick.zoom",h).on(z,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Zo.mouse(r),h),a(s)}function e(){f.on(C,null).on(N,null),g(l&&Zo.event.target===i),c(s)}var r=this,i=Zo.event.target,s=L.of(r,arguments),l=0,f=Zo.select(Wo).on(C,n).on(N,e),h=t(Zo.mouse(r)),g=I();H.call(r),o(s)}function l(){function n(){var n=Zo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Zo.event.target;Zo.select(t).on(M,i).on(_,f),b.push(t);for(var e=Zo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var s=n(),l=Date.now();if(1===s.length){if(500>l-m){var h=s[0],g=v[h.identifier];r(2*S.k),u(h,g),y(),a(p)}m=l}else if(s.length>1){var h=s[0],x=s[1],w=h[0]-x[0],k=h[1]-x[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Zo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=d&&Math.sqrt(l/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Zo.event.touches.length){for(var t=Zo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Zo.selectAll(b).on(x,null),w.on(A,s).on(z,l),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,x=".zoom-"+Zo.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=[],w=Zo.select(g).on(A,null).on(z,e),k=I();H.call(g),e(),o(p)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Zo.mouse(this)),H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y(),r(Math.pow(2,.002*Ta())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Zo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Zo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=qa,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Ss?Zo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Zo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?qa:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,x=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Zo.rebind(n,L,"on")};var Ta,qa=[0,1/0],Ra="onwheel"in $o?(Ta=function(){return-Zo.event.deltaY*(Zo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in $o?(Ta=function(){return Zo.event.wheelDelta},"mousewheel"):(Ta=function(){return-Zo.event.detail},"MozMousePixelScroll");Zo.color=et,et.prototype.toString=function(){return this.rgb()+""},Zo.hsl=rt;var Da=rt.prototype=new et;Da.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,this.l/n)},Da.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,n*this.l)},Da.rgb=function(){return ut(this.h,this.s,this.l)},Zo.hcl=it;var Pa=it.prototype=new et;Pa.brighter=function(n){return new it(this.h,this.c,Math.min(100,this.l+Ua*(arguments.length?n:1)))},Pa.darker=function(n){return new it(this.h,this.c,Math.max(0,this.l-Ua*(arguments.length?n:1)))},Pa.rgb=function(){return ot(this.h,this.c,this.l).rgb()},Zo.lab=at;var Ua=18,ja=.95047,Ha=1,Fa=1.08883,Oa=at.prototype=new et;Oa.brighter=function(n){return new at(Math.min(100,this.l+Ua*(arguments.length?n:1)),this.a,this.b)},Oa.darker=function(n){return new at(Math.max(0,this.l-Ua*(arguments.length?n:1)),this.a,this.b)},Oa.rgb=function(){return ct(this.l,this.a,this.b)},Zo.rgb=gt;var Ya=gt.prototype=new et;Ya.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new gt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new gt(u,u,u)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new gt(n*this.r,n*this.g,n*this.b)},Ya.hsl=function(){return yt(this.r,this.g,this.b)},Ya.toString=function(){return"#"+dt(this.r)+dt(this.g)+dt(this.b)};var Ia=Zo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ia.forEach(function(n,t){Ia.set(n,pt(t))}),Zo.functor=bt,Zo.xhr=St(wt),Zo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=kt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new h,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Zo.csv=Zo.dsv(",","text/csv"),Zo.tsv=Zo.dsv(" ","text/tab-separated-values"),Zo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Za,Va,Xa,$a,Ba,Wa=Wo[p(Wo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Zo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Va?Va.n=i:Za=i,Va=i,Xa||($a=clearTimeout($a),Xa=1,Wa(At))},Zo.timer.flush=function(){Ct(),Nt()},Zo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ja=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Zo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Zo.round(n,zt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),Ja[8+e/3]};var Ga=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Ka=Zo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Zo.round(n,zt(n,t))).toFixed(Math.max(0,Math.min(20,zt(n*(1+1e-15),t))))}}),Qa=Zo.time={},nc=Date;Rt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){tc.setUTCDate.apply(this._,arguments)},setDay:function(){tc.setUTCDay.apply(this._,arguments)},setFullYear:function(){tc.setUTCFullYear.apply(this._,arguments)},setHours:function(){tc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){tc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){tc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){tc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){tc.setUTCSeconds.apply(this._,arguments)},setTime:function(){tc.setTime.apply(this._,arguments)}};var tc=Date.prototype;Qa.year=Dt(function(n){return n=Qa.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Qa.years=Qa.year.range,Qa.years.utc=Qa.year.utc.range,Qa.day=Dt(function(n){var t=new nc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Qa.days=Qa.day.range,Qa.days.utc=Qa.day.utc.range,Qa.dayOfYear=function(n){var t=Qa.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=Qa[n]=Dt(function(n){return(n=Qa.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Qa[n+"s"]=e.range,Qa[n+"s"].utc=e.utc.range,Qa[n+"OfYear"]=function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)}}),Qa.week=Qa.sunday,Qa.weeks=Qa.sunday.range,Qa.weeks.utc=Qa.sunday.utc.range,Qa.weekOfYear=Qa.sundayOfYear;var ec={"-":"",_:" ",0:"0"},rc=/^\s*\d+/,uc=/^%/;Zo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Ut(n)}};var ic=Zo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Zo.format=ic.numberFormat,Zo.geo={},ue.prototype={s:0,t:0,add:function(n){ie(n,this.t,oc),ie(oc.s,this.s,this),this.s?this.t+=oc.t:this.s=oc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var oc=new ue;Zo.geo.stream=function(n,t){n&&ac.hasOwnProperty(n.type)?ac[n.type](n,t):oe(n,t)};var ac={Feature:function(n,t){oe(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*ba+n:n,fc.lineStart=fc.lineEnd=fc.point=v}};Zo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=le([t*Aa,e*Aa]);if(m){var u=he(m,r),i=[u[1],-u[0],0],o=he(i,u);ve(o),o=de(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ca*s,d=ua(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ca;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ca;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ua(r)>180?r+(r>0?360:-360):r}else v=n,d=e;fc.point(n,e),t(n,e)}function i(){fc.lineStart()}function o(){u(v,d),fc.lineEnd(),ua(y)>ka&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nlc?(l=-(h=180),f=-(g=90)):y>ka?g=90:-ka>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Zo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e); +for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Zo.geo.centroid=function(n){hc=gc=pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,wc);var t=Mc,e=_c,r=bc,u=t*t+e*e+r*r;return Ea>u&&(t=mc,e=yc,r=xc,ka>gc&&(t=pc,e=vc,r=dc),u=t*t+e*e+r*r,Ea>u)?[0/0,0/0]:[Math.atan2(e,t)*Ca,G(r/Math.sqrt(u))*Ca]};var hc,gc,pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc={sphere:v,point:ye,lineStart:Me,lineEnd:_e,polygonStart:function(){wc.lineStart=be},polygonEnd:function(){wc.lineStart=Me}},Sc=Ae(we,Te,Re,[-ba,-ba/2]),kc=1e9;Zo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ue(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Zo.geo.conicEqualArea=function(){return He(Fe)}).raw=Fe,Zo.geo.albers=function(){return Zo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Zo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Zo.geo.albers(),o=Zo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Zo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+ka,f+.12*s+ka],[l-.214*s-ka,f+.234*s-ka]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+ka,f+.166*s+ka],[l-.115*s-ka,f+.234*s-ka]]).stream(c).point,n},n.scale(1070)};var Ec,Ac,Cc,Nc,zc,Lc,Tc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){Ac=0,Tc.lineStart=Oe},polygonEnd:function(){Tc.lineStart=Tc.lineEnd=Tc.point=v,Ec+=ua(Ac/2)}},qc={point:Ye,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Rc={point:Ve,lineStart:Xe,lineEnd:$e,polygonStart:function(){Rc.lineStart=Be},polygonEnd:function(){Rc.point=Ve,Rc.lineStart=Xe,Rc.lineEnd=$e}};Zo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Zo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ec=0,Zo.geo.stream(n,u(Tc)),Ec},n.centroid=function(n){return pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,u(Rc)),bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:dc?[pc/dc,vc/dc]:[0/0,0/0]},n.bounds=function(n){return zc=Lc=-(Cc=Nc=1/0),Zo.geo.stream(n,u(qc)),[[Cc,Nc],[zc,Lc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Ge(n):wt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ie:new We(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Zo.geo.albersUsa()).context(null)},Zo.geo.transform=function(n){return{stream:function(t){var e=new Ke(t);for(var r in n)e[r]=n[r];return e}}},Ke.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Zo.geo.projection=nr,Zo.geo.projectionMutator=tr,(Zo.geo.equirectangular=function(){return nr(rr)}).raw=rr.invert=rr,Zo.geo.rotation=function(n){function t(t){return t=n(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t}return n=ir(n[0]%360*Aa,n[1]*Aa,n.length>2?n[2]*Aa:0),t.invert=function(t){return t=n.invert(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t},t},ur.invert=rr,Zo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ir(-n[0]*Aa,-n[1]*Aa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ca,n[1]*=Ca}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=sr((t=+r)*Aa,u*Aa),n):t},n.precision=function(r){return arguments.length?(e=sr(t*Aa,(u=+r)*Aa),n):u},n.angle(90)},Zo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Aa,u=n[1]*Aa,i=t[1]*Aa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Zo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Zo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Zo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Zo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ua(n%d)>ka}).map(l)).concat(Zo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ua(n%m)>ka}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=fr(a,o,90),f=hr(r,e,y),h=fr(s,c,90),g=hr(i,u,y),n):y},n.majorExtent([[-180,-90+ka],[180,90-ka]]).minorExtent([[-180,-80-ka],[180,80+ka]])},Zo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=gr,u=pr;return n.distance=function(){return Zo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Zo.geo.interpolate=function(n,t){return vr(n[0]*Aa,n[1]*Aa,t[0]*Aa,t[1]*Aa)},Zo.geo.length=function(n){return Dc=0,Zo.geo.stream(n,Pc),Dc};var Dc,Pc={sphere:v,point:v,lineStart:dr,lineEnd:v,polygonStart:v,polygonEnd:v},Uc=mr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Zo.geo.azimuthalEqualArea=function(){return nr(Uc)}).raw=Uc;var jc=mr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},wt);(Zo.geo.azimuthalEquidistant=function(){return nr(jc)}).raw=jc,(Zo.geo.conicConformal=function(){return He(yr)}).raw=yr,(Zo.geo.conicEquidistant=function(){return He(xr)}).raw=xr;var Hc=mr(function(n){return 1/n},Math.atan);(Zo.geo.gnomonic=function(){return nr(Hc)}).raw=Hc,Mr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Sa]},(Zo.geo.mercator=function(){return _r(Mr)}).raw=Mr;var Fc=mr(function(){return 1},Math.asin);(Zo.geo.orthographic=function(){return nr(Fc)}).raw=Fc;var Oc=mr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Zo.geo.stereographic=function(){return nr(Oc)}).raw=Oc,br.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Sa]},(Zo.geo.transverseMercator=function(){var n=_r(br),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=br,Zo.geom={},Zo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=bt(e),i=bt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(Er),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=kr(a),l=kr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/ka)*ka,y:Math.round(o(n,t)/ka)*ka,i:t}})}var r=wr,u=Sr,i=r,o=u,a=Jc;return n?t(n):(t.links=function(n){return tu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return tu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Hr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=ou()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=bt(a),M=bt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.xm&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=ou();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){au(n,k,v,d,m,y)},g=-1,null==t){for(;++g=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ns.get(e)||Qc,r=ts.get(r)||wt,pu(r(e.apply(null,Vo.call(arguments,1))))},Zo.interpolateHcl=Au,Zo.interpolateHsl=Cu,Zo.interpolateLab=Nu,Zo.interpolateRound=zu,Zo.transform=function(n){var t=$o.createElementNS(Zo.ns.prefix.svg,"g");return(Zo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:es)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var es={a:1,b:0,c:0,d:1,e:0,f:0};Zo.interpolateTransform=Du,Zo.layout={},Zo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Zo.event.x,n.py=Zo.event.y,a.resume()}var e,r,u,i,o,a={},c=Zo.dispatch("start","tick","end"),s=[1,1],l=.9,f=rs,h=us,g=-30,p=is,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Vu(t=Zo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Zo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Zo.behavior.drag().origin(wt).on("dragstart.force",Ou).on("drag.force",t).on("dragend.force",Yu)),arguments.length?(this.on("mouseover.force",Iu).on("mouseout.force",Zu).call(e),void 0):e},Zo.rebind(a,c,"on")};var rs=20,us=1,is=1/0;Zo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(s=e.call(n,i,i.depth))&&(c=s.length)){for(var c,s,l;--c>=0;)o.push(l=s[c]),l.parent=i,l.depth=i.depth+1;r&&(i.value=0),i.children=s}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Bu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=Gu,e=Wu,r=Ju;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&($u(t,function(n){n.children&&(n.value=0)}),Bu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Zo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++sg;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=wt,e=ei,r=ri,u=ti,i=Qu,o=ni;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:as.get(t)||ei,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:cs.get(t)||ri,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var as=Zo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ui),i=n.map(ii),o=Zo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Zo.range(n.length).reverse()},"default":ei}),cs=Zo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ri});Zo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=l[0]&&a<=l[1]&&(o=c[Zo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=si,u=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=bt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ci(n,t)}:bt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Zo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Bu(a,function(n){n.r=+l(n.value)}),Bu(a,pi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Bu(a,function(n){n.r+=f}),Bu(a,pi),Bu(a,function(n){n.r-=f})}return mi(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Zo.layout.hierarchy().sort(li),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Xu(n,e)},Zo.layout.tree=function(){function n(n,u){var l=o.call(this,n,u),f=l[0],h=t(f);if(Bu(h,e),h.parent.m=-h.z,$u(h,r),s)$u(f,i);else{var g=f,p=f,v=f;$u(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);$u(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return l}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){wi(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],s=u.m,l=i.m,f=o.m,h=c.m;o=_i(o),u=Mi(u),o&&u;)c=Mi(c),i=_i(i),i.a=n,r=o.z+f-u.z-s+a(o._,u._),r>0&&(bi(Si(o,n,e),n,r),s+=r,l+=r),f+=o.m,s+=u.m,h+=c.m,l+=i.m;o&&!_i(i)&&(i.t=o,i.m+=f-l),u&&!Mi(c)&&(c.t=u,c.m+=s-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Zo.layout.hierarchy().sort(null).value(null),a=xi,c=[1,1],s=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(s=null==(c=t)?i:null,n):s?null:c},n.nodeSize=function(t){return arguments.length?(s=null==(c=t)?null:i,n):s?c:null},Xu(n,o)},Zo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Bu(c,function(n){var t=n.children;t&&t.length?(n.x=Ei(t),n.y=ki(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ai(c),f=Ci(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Bu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Zo.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Xu(n,t)},Zo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++ie.dx)&&(l=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Zo.random.normal.apply(Zo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Zo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Zo.scale={};var ss={floor:wt,ceil:wt};Zo.scale.linear=function(){return Ui([0,1],[0,1],hu,!1)};var ls={s:1,g:1,p:1,r:1,e:1};Zo.scale.log=function(){return Vi(Zo.scale.linear().domain([0,1]),10,!0,[1,10])};var fs=Zo.format(".0e"),hs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Zo.scale.pow=function(){return Xi(Zo.scale.linear(),1,[0,1])},Zo.scale.sqrt=function(){return Zo.scale.pow().exponent(.5)},Zo.scale.ordinal=function(){return Bi([],{t:"range",a:[[]]})},Zo.scale.category10=function(){return Zo.scale.ordinal().range(gs)},Zo.scale.category20=function(){return Zo.scale.ordinal().range(ps)},Zo.scale.category20b=function(){return Zo.scale.ordinal().range(vs)},Zo.scale.category20c=function(){return Zo.scale.ordinal().range(ds)};var gs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(vt),ps=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(vt),vs=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(vt),ds=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(vt);Zo.scale.quantile=function(){return Wi([],[])},Zo.scale.quantize=function(){return Ji(0,1,[0,1])},Zo.scale.threshold=function(){return Gi([.5],[0,1])},Zo.scale.identity=function(){return Ki([0,1])},Zo.svg={},Zo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ms,a=u.apply(this,arguments)+ms,c=(o>a&&(c=o,o=a,a=c),a-o),s=ba>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a); +return c>=ys?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=Qi,e=no,r=to,u=eo;return n.innerRadius=function(e){return arguments.length?(t=bt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=bt(t),n):e},n.startAngle=function(t){return arguments.length?(r=bt(t),n):r},n.endAngle=function(t){return arguments.length?(u=bt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ms;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ms=-Sa,ys=wa-ka;Zo.svg.line=function(){return ro(wt)};var xs=Zo.map({linear:uo,"linear-closed":io,step:oo,"step-before":ao,"step-after":co,basis:po,"basis-open":vo,"basis-closed":mo,bundle:yo,cardinal:fo,"cardinal-open":so,"cardinal-closed":lo,monotone:So});xs.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Ms=[0,2/3,1/3,0],_s=[0,1/3,2/3,0],bs=[0,1/6,2/3,1/6];Zo.svg.line.radial=function(){var n=ro(ko);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},ao.reverse=co,co.reverse=ao,Zo.svg.area=function(){return Eo(wt)},Zo.svg.area.radial=function(){var n=Eo(ko);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Zo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ms,l=s.call(n,u,r)+ms;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>ba)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=gr,o=pr,a=Ao,c=to,s=eo;return n.radius=function(t){return arguments.length?(a=bt(t),n):a},n.source=function(t){return arguments.length?(i=bt(t),n):i},n.target=function(t){return arguments.length?(o=bt(t),n):o},n.startAngle=function(t){return arguments.length?(c=bt(t),n):c},n.endAngle=function(t){return arguments.length?(s=bt(t),n):s},n},Zo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=gr,e=pr,r=Co;return n.source=function(e){return arguments.length?(t=bt(e),n):t},n.target=function(t){return arguments.length?(e=bt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Zo.svg.diagonal.radial=function(){var n=Zo.svg.diagonal(),t=Co,e=n.projection;return n.projection=function(n){return arguments.length?e(No(t=n)):t},n},Zo.svg.symbol=function(){function n(n,r){return(ws.get(t.call(this,n,r))||To)(e.call(this,n,r))}var t=Lo,e=zo;return n.type=function(e){return arguments.length?(t=bt(e),n):t},n.size=function(t){return arguments.length?(e=bt(t),n):e},n};var ws=Zo.map({circle:To,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*As)),e=t*As;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Zo.svg.symbolTypes=ws.keys();var Ss,ks,Es=Math.sqrt(3),As=Math.tan(30*Aa),Cs=[],Ns=0;Cs.call=pa.call,Cs.empty=pa.empty,Cs.node=pa.node,Cs.size=pa.size,Zo.transition=function(n){return arguments.length?Ss?n.transition():n:ma.transition()},Zo.transition.prototype=Cs,Cs.select=function(n){var t,e,r,u=this.id,i=[];n=b(n);for(var o=-1,a=this.length;++oi;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return qo(u,this.id)},Cs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Cs.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Du:hu,a=Zo.ns.qualify(n);return Ro(this,"attr."+n,t,a.local?i:u)},Cs.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Zo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Cs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Wo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=hu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Ro(this,"style."+n,t,u)},Cs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Wo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Cs.text=function(n){return Ro(this,"text",n,Do)},Cs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Cs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Zo.ease.apply(Zo,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Cs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Cs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Cs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=ks,u=Ss;Ss=e,P(this,function(t,r,u){ks=t.__transition__[e],n.call(t,t.__data__,r,u)}),ks=r,Ss=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Zo.dispatch("start","end"))).on(n,t)});return this},Cs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ns,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Po(e,s,i,r)),n.push(e)}return qo(o,i)},Zo.svg.axis=function(){function n(n){n.each(function(){var n,s=Zo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):wt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",ka),d=Zo.transition(p.exit()).style("opacity",ka).remove(),m=Zo.transition(p.order()).style("opacity",1),y=Ti(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Zo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Uo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Uo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=jo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=jo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Zo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Ls?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",Ls={top:1,right:1,bottom:1,left:1};Zo.svg.brush=function(){function n(i){i.each(function(){var i=Zo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,wt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Zo.transition(i),h=Zo.transition(o);c&&(l=Ti(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ti(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Zo.event.keyCode&&(C||(x=null,z[0]-=l[1],z[1]-=f[1],C=2),y())}function p(){32==Zo.event.keyCode&&2==C&&(z[0]+=l[1],z[1]+=f[1],C=0,y())}function v(){var n=Zo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Zo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),z[0]=l[+(n[0]p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Zo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Zo.select(Zo.event.target),w=a.of(_,arguments),S=Zo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=I(),z=Zo.mouse(_),L=Zo.select(Wo).on("keydown.brush",u).on("keyup.brush",p);if(Zo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=l[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);M=[l[1-T]-z[0],f[1-q]-z[1]],z[0]=l[T],z[1]=f[q]}else Zo.event.altKey&&(x=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Zo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=qs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ss?Zo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=gu(l,t.x),r=gu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=qs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=qs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Zo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},qs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Rs=Qa.format=ic.timeFormat,Ds=Rs.utc,Ps=Ds("%Y-%m-%dT%H:%M:%S.%LZ");Rs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ho:Ps,Ho.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ho.toString=Ps.toString,Qa.second=Dt(function(n){return new nc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Qa.seconds=Qa.second.range,Qa.seconds.utc=Qa.second.utc.range,Qa.minute=Dt(function(n){return new nc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Qa.minutes=Qa.minute.range,Qa.minutes.utc=Qa.minute.utc.range,Qa.hour=Dt(function(n){var t=n.getTimezoneOffset()/60;return new nc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Qa.hours=Qa.hour.range,Qa.hours.utc=Qa.hour.utc.range,Qa.month=Dt(function(n){return n=Qa.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Qa.months=Qa.month.range,Qa.months.utc=Qa.month.utc.range;var Us=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],js=[[Qa.second,1],[Qa.second,5],[Qa.second,15],[Qa.second,30],[Qa.minute,1],[Qa.minute,5],[Qa.minute,15],[Qa.minute,30],[Qa.hour,1],[Qa.hour,3],[Qa.hour,6],[Qa.hour,12],[Qa.day,1],[Qa.day,2],[Qa.week,1],[Qa.month,1],[Qa.month,3],[Qa.year,1]],Hs=Rs.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",we]]),Fs={range:function(n,t,e){return Zo.range(Math.ceil(n/e)*e,+t,e).map(Oo)},floor:wt,ceil:wt};js.year=Qa.year,Qa.scale=function(){return Fo(Zo.scale.linear(),js,Hs)};var Os=js.map(function(n){return[n[0].utc,n[1]]}),Ys=Ds.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",we]]);Os.year=Qa.year.utc,Qa.scale.utc=function(){return Fo(Zo.scale.linear(),Os,Ys)},Zo.text=St(function(n){return n.responseText}),Zo.json=function(n,t){return kt(n,"application/json",Yo,t)},Zo.html=function(n,t){return kt(n,"text/html",Io,t)},Zo.xml=St(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Zo):"object"==typeof module&&module.exports&&(module.exports=Zo),this.d3=Zo}(); \ No newline at end of file From 377853b58a86bf232d27c639a58be7b9afcdf603 Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 10 Aug 2014 06:01:21 +0200 Subject: [PATCH 20/54] recovery bugfix --- js/serial.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/js/serial.js b/js/serial.js index 68411162..cabac688 100644 --- a/js/serial.js +++ b/js/serial.js @@ -29,12 +29,6 @@ var serial = { switch (info.error) { case 'system_error': // we might be able to recover from this one - chrome.serial.setPaused(self.connectionId, false, get_status); - - var get_status = function () { - self.getInfo(crunch_status); - } - var crunch_status = function (info) { if (!info.paused) { console.log('SERIAL: Connection recovered from last onReceiveError'); @@ -51,6 +45,10 @@ var serial = { } } } + + chrome.serial.setPaused(self.connectionId, false, function () { + self.getInfo(crunch_status); + }); break; case 'timeout': // TODO From ec44b77ff2f0e9acb683e8a431098254cd5a0dd2 Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 10 Aug 2014 06:01:44 +0200 Subject: [PATCH 21/54] lots of work on removing global variables --- eventPage.js | 22 ++--- js/backup_restore.js | 26 +++--- js/data_storage.js | 8 +- js/gui.js | 24 +++--- js/serial_backend.js | 26 +++--- main.js | 113 +------------------------ tabs/cli.js | 190 +++++++++++++++++++++---------------------- tabs/logging.js | 12 ++- 8 files changed, 156 insertions(+), 265 deletions(-) diff --git a/eventPage.js b/eventPage.js index 85b97414..2d4d7b62 100644 --- a/eventPage.js +++ b/eventPage.js @@ -18,14 +18,14 @@ function start_app() { minWidth: 974, minHeight: 632 } - }, function(createdWindow) { - createdWindow.onClosed.addListener(function() { + }, function (createdWindow) { + 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 // save connectionId in separate variable before app_window is destroyed var connectionId = app_window.serial.connectionId; - var valid_connection = app_window.configuration_received; + var valid_connection = app_window.CONFIGURATOR.connectionValid; var mincommand = app_window.MISC.mincommand; if (connectionId > 0 && valid_connection) { @@ -53,13 +53,13 @@ function start_app() { bufView[5 + 16] = checksum; - chrome.serial.send(connectionId, bufferOut, function(sendInfo) { - chrome.serial.disconnect(connectionId, function(result) { + chrome.serial.send(connectionId, bufferOut, function (sendInfo) { + chrome.serial.disconnect(connectionId, function (result) { console.log('SERIAL: Connection closed - ' + result); }); }); } else if (connectionId > 0) { - chrome.serial.disconnect(connectionId, function(result) { + chrome.serial.disconnect(connectionId, function (result) { console.log('SERIAL: Connection closed - ' + result); }); } @@ -67,18 +67,18 @@ function start_app() { }); } -chrome.app.runtime.onLaunched.addListener(function() { +chrome.app.runtime.onLaunched.addListener(function () { start_app(); }); -chrome.runtime.onInstalled.addListener(function(details) { +chrome.runtime.onInstalled.addListener(function (details) { if (details.reason == 'update') { var previousVersionArr = details.previousVersion.split('.'); var 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]) { - chrome.storage.local.get('update_notify', function(result) { + chrome.storage.local.get('update_notify', function (result) { if (typeof result.update_notify === 'undefined' || result.update_notify) { var manifest = chrome.runtime.getManifest(); var options = { @@ -90,7 +90,7 @@ chrome.runtime.onInstalled.addListener(function(details) { buttons: [{'title': chrome.i18n.getMessage('notifications_click_here_to_start_app')}] }; - chrome.notifications.create('baseflight_update', options, function(notificationId) { + chrome.notifications.create('baseflight_update', options, function (notificationId) { // empty }); } @@ -99,7 +99,7 @@ chrome.runtime.onInstalled.addListener(function(details) { } }); -chrome.notifications.onButtonClicked.addListener(function(notificationId, buttonIndex) { +chrome.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) { if (notificationId == 'baseflight_update') { start_app(); } diff --git a/js/backup_restore.js b/js/backup_restore.js index 9c655aa1..72cfaa8a 100644 --- a/js/backup_restore.js +++ b/js/backup_restore.js @@ -47,7 +47,7 @@ function configuration_backup() { var now = d.getUTCFullYear() + '.' + d.getDate() + '.' + (d.getMonth() + 1) + '.' + d.getHours() + '.' + d.getMinutes(); // create or load the file - chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'bf_mw_backup_' + now, accepts: accepts}, function(fileEntry) { + chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'bf_mw_backup_' + now, accepts: accepts}, function (fileEntry) { if (!fileEntry) { console.log('No file selected, backup aborted.'); @@ -57,14 +57,14 @@ function configuration_backup() { chosenFileEntry = fileEntry; // echo/console log path specified - chrome.fileSystem.getDisplayPath(chosenFileEntry, function(path) { + chrome.fileSystem.getDisplayPath(chosenFileEntry, function (path) { console.log('Backup file path: ' + path); }); // change file entry from read only to read/write - chrome.fileSystem.getWritableEntry(chosenFileEntry, function(fileEntryWritable) { + chrome.fileSystem.getWritableEntry(chosenFileEntry, function (fileEntryWritable) { // check if file is writable - chrome.fileSystem.isWritableEntry(fileEntryWritable, function(isWritable) { + chrome.fileSystem.isWritableEntry(fileEntryWritable, function (isWritable) { if (isWritable) { chosenFileEntry = fileEntryWritable; @@ -83,13 +83,13 @@ function configuration_backup() { 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 - chosenFileEntry.createWriter(function(writer) { + chosenFileEntry.createWriter(function (writer) { writer.onerror = function (e) { console.error(e); }; var truncated = false; - writer.onwriteend = function() { + writer.onwriteend = function () { if (!truncated) { // onwriteend will be fired again when truncation is finished truncated = true; @@ -126,7 +126,7 @@ function configuration_restore() { }]; // load up the file - chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(fileEntry) { + chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function (fileEntry) { if (!fileEntry) { console.log('No file selected, restore aborted.'); @@ -136,15 +136,15 @@ function configuration_restore() { chosenFileEntry = fileEntry; // echo/console log path specified - chrome.fileSystem.getDisplayPath(chosenFileEntry, function(path) { + chrome.fileSystem.getDisplayPath(chosenFileEntry, function (path) { console.log('Restore file path: ' + path); }); // read contents into variable - chosenFileEntry.file(function(file) { + chosenFileEntry.file(function (file) { var reader = new FileReader(); - reader.onprogress = function(e) { + reader.onprogress = function (e) { if (e.total > 1048576) { // 1 MB // dont allow reading files bigger then 1 MB console.log('File limit (1 MB) exceeded, aborting'); @@ -152,7 +152,7 @@ function configuration_restore() { } }; - reader.onloadend = function(e) { + reader.onloadend = function (e) { if (e.total != 0 && e.total == e.loaded) { console.log('Read SUCCESSFUL'); @@ -295,9 +295,9 @@ function configuration_upload() { buffer_out[21] = 0; // vbatlevel_crit (unused) // Send ove the new MISC - MSP.send_message(MSP_codes.MSP_SET_MISC, buffer_out, false, function() { + 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_EEPROM_WRITE, false, false, function () { GUI.log(chrome.i18n.getMessage('eeprom_saved_ok')); }); }); diff --git a/js/data_storage.js b/js/data_storage.js index ffe498aa..aec6aafd 100644 --- a/js/data_storage.js +++ b/js/data_storage.js @@ -1,6 +1,12 @@ 'use strict'; -var firmware_version_accepted = 2.3; +var CONFIGURATOR = { + 'firmwareVersionAccepted': 2.3, + 'connectionValid': false, + 'mspPassThrough': false, + 'cliActive': false, + 'cliValid': false +}; var CONFIG = { version: 0, diff --git a/js/gui.js b/js/gui.js index 311511f0..95e7137a 100644 --- a/js/gui.js +++ b/js/gui.js @@ -2,7 +2,7 @@ var tabs = {}; // filled by individual tab js file -var GUI_control = function() { +var GUI_control = function () { this.auto_connect = false; this.connecting_to = false; this.connected_to = false; @@ -29,7 +29,7 @@ var GUI_control = function() { // code = function reference (code to be executed) // interval = time interval in miliseconds // first = true/false if code should be ran initially before next timer interval hits -GUI_control.prototype.interval_add = function(name, code, interval, first) { +GUI_control.prototype.interval_add = function (name, code, interval, first) { var data = {'name': name, 'timer': undefined, 'code': code, 'interval': interval, 'fired': 0, 'paused': false}; if (first == true) { @@ -50,7 +50,7 @@ GUI_control.prototype.interval_add = function(name, code, interval, first) { }; // name = string -GUI_control.prototype.interval_remove = function(name) { +GUI_control.prototype.interval_remove = function (name) { for (var i = 0; i < this.interval_array.length; i++) { if (this.interval_array[i].name == name) { clearInterval(this.interval_array[i].timer); // stop timer @@ -65,7 +65,7 @@ GUI_control.prototype.interval_remove = function(name) { }; // name = string -GUI_control.prototype.interval_pause = function(name) { +GUI_control.prototype.interval_pause = function (name) { for (var i = 0; i < this.interval_array.length; i++) { if (this.interval_array[i].name == name) { clearInterval(this.interval_array[i].timer); @@ -79,7 +79,7 @@ GUI_control.prototype.interval_pause = function(name) { }; // name = string -GUI_control.prototype.interval_resume = function(name) { +GUI_control.prototype.interval_resume = function (name) { for (var i = 0; i < this.interval_array.length; i++) { if (this.interval_array[i].name == name && this.interval_array[i].paused) { var obj = this.interval_array[i]; @@ -101,14 +101,14 @@ GUI_control.prototype.interval_resume = function(name) { // input = array of timers thats meant to be kept, or nothing // return = returns timers killed in last call -GUI_control.prototype.interval_kill_all = function(keep_array) { +GUI_control.prototype.interval_kill_all = function (keep_array) { var self = this; var timers_killed = 0; for (var i = (this.interval_array.length - 1); i >= 0; i--) { // reverse iteration var keep = false; if (keep_array) { // only run through the array if it exists - keep_array.forEach(function(name) { + keep_array.forEach(function (name) { if (self.interval_array[i].name == name) { keep = true; } @@ -130,7 +130,7 @@ GUI_control.prototype.interval_kill_all = function(keep_array) { // name = string // code = function reference (code to be executed) // timeout = timeout in miliseconds -GUI_control.prototype.timeout_add = function(name, code, timeout) { +GUI_control.prototype.timeout_add = function (name, code, timeout) { var self = this; var data = {'name': name, 'timer': undefined, 'timeout': timeout}; @@ -149,7 +149,7 @@ GUI_control.prototype.timeout_add = function(name, code, timeout) { }; // name = string -GUI_control.prototype.timeout_remove = function(name) { +GUI_control.prototype.timeout_remove = function (name) { for (var i = 0; i < this.timeout_array.length; i++) { if (this.timeout_array[i].name == name) { clearTimeout(this.timeout_array[i].timer); // stop timer @@ -165,7 +165,7 @@ GUI_control.prototype.timeout_remove = function(name) { // no input paremeters // return = returns timers killed in last call -GUI_control.prototype.timeout_kill_all = function() { +GUI_control.prototype.timeout_kill_all = function () { var timers_killed = 0; for (var i = 0; i < this.timeout_array.length; i++) { @@ -180,7 +180,7 @@ GUI_control.prototype.timeout_kill_all = function() { }; // message = string -GUI_control.prototype.log = function(message) { +GUI_control.prototype.log = function (message) { var command_log = $('div#log'); var d = new Date(); var time = ((d.getHours() < 10) ? '0' + d.getHours(): d.getHours()) @@ -194,7 +194,7 @@ GUI_control.prototype.log = function(message) { // Method is called every time a valid tab change event is received // callback = code to run when cleanup is finished // default switch doesn't require callback to be set -GUI_control.prototype.tab_switch_cleanup = function(callback) { +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 diff --git a/js/serial_backend.js b/js/serial_backend.js index 0a9e3f87..4e66a764 100644 --- a/js/serial_backend.js +++ b/js/serial_backend.js @@ -1,7 +1,5 @@ 'use strict'; -var configuration_received = false; - $(document).ready(function() { $('div#port-picker a.connect').click(function() { if (GUI.connect_lock != true) { // GUI control overrides the user control @@ -36,8 +34,8 @@ $(document).ready(function() { MSP.disconnect_cleanup(); PortUsage.reset(); - configuration_received = false; // reset valid config received variable (used to block tabs while not connected properly) - MSP_pass_through = false; + CONFIGURATOR.connectionValid = false; + CONFIGURATOR.mspPassThrough = false; // unlock port select & baud $('div#port-picker #port').prop('disabled', false); @@ -127,10 +125,10 @@ function onOpen(openInfo) { serial.onReceive.addListener(read_serial); - if (!MSP_pass_through) { + if (!CONFIGURATOR.mspPassThrough) { // disconnect after 10 seconds with error if we don't get IDENT data GUI.timeout_add('connecting', function() { - if (!configuration_received) { + if (!CONFIGURATOR.connectionValid) { GUI.log(chrome.i18n.getMessage('noConfigurationReceived')); $('div#port-picker a.connect').click(); // disconnect @@ -145,13 +143,13 @@ function onOpen(openInfo) { GUI.log(chrome.i18n.getMessage('firmwareVersion', [CONFIG.version])); - if (CONFIG.version >= firmware_version_accepted) { - configuration_received = true; + if (CONFIG.version >= CONFIGURATOR.firmwareVersionAccepted) { + 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', [firmware_version_accepted])); + GUI.log(chrome.i18n.getMessage('firmwareVersionNotSupported', [CONFIGURATOR.firmwareVersionAccepted])); $('div#port-picker a.connect').click(); // disconnect } }); @@ -184,18 +182,18 @@ function onClosed(result) { } function read_serial(info) { - if (!CLI_active && !MSP_pass_through) { + if (!CONFIGURATOR.cliActive && !CONFIGURATOR.mspPassThrough) { MSP.read(info); - } else if (CLI_active) { - handle_CLI(info); - } else if (MSP_pass_through) { // needs to be verified, might be removed after pass_through is 100% deployed + } else if (CONFIGURATOR.cliActive) { + tabs.cli.read(info); + } else if (CONFIGURATOR.mspPassThrough) { MSP.read(info); } } function sensor_status(sensors_detected) { // initialize variable (if it wasn't) - if (typeof sensor_status.previous_sensors_detected == 'undefined') { + if (sensor_status.previous_sensors_detected === 'undefined') { sensor_status.previous_sensors_detected = 0; } diff --git a/main.js b/main.js index 3e5aa81b..c01daf65 100644 --- a/main.js +++ b/main.js @@ -50,7 +50,7 @@ $(document).ready(function () { tab = $(self).parent().prop('class'); // if there is no active connection, return - if (!configuration_received && tab != 'tab_logging') { + if (!CONFIGURATOR.connectionValid && tab != 'tab_logging') { GUI.log('You need to connect before you can view any of the tabs'); return; } @@ -264,113 +264,4 @@ function bytesToSize(bytes) { } return bytes; -} - -/* -function add_custom_spinners() { - var spinner_element = '
'; - - $('input[type="number"]').each(function() { - var input = $(this); - - // only add new spinner if one doesn't already exist - if (!input.next().hasClass('spinner')) { - var isInt = true; - if (input.prop('step') == '') { - isInt = true; - } else { - if (input.prop('step').indexOf('.') == -1) { - isInt = true; - } else { - isInt = false; - } - } - - // make space for spinner - input.width(input.width() - 16); - - // add spinner - input.after(spinner_element); - - // get spinner refference - var spinner = input.next(); - - // bind UI hooks to spinner - $('.up', spinner).click(function() { - up(); - }); - - $('.up', spinner).mousedown(function() { - GUI.timeout_add('spinner', function() { - GUI.interval_add('spinner', function() { - up(); - }, 100, true); - }, 250); - }); - - $('.up', spinner).mouseup(function() { - GUI.timeout_remove('spinner'); - GUI.interval_remove('spinner'); - }); - - $('.up', spinner).mouseleave(function() { - GUI.timeout_remove('spinner'); - GUI.interval_remove('spinner'); - }); - - - $('.down', spinner).click(function() { - down(); - }); - - $('.down', spinner).mousedown(function() { - GUI.timeout_add('spinner', function() { - GUI.interval_add('spinner', function() { - down(); - }, 100, true); - }, 250); - }); - - $('.down', spinner).mouseup(function() { - GUI.timeout_remove('spinner'); - GUI.interval_remove('spinner'); - }); - - $('.down', spinner).mouseleave(function() { - GUI.timeout_remove('spinner'); - GUI.interval_remove('spinner'); - }); - - var up = function() { - if (isInt) { - var current_value = parseInt(input.val()); - input.val(current_value + 1); - } else { - var current_value = parseFloat(input.val()); - var step = parseFloat(input.prop('step')); - var step_decimals = input.prop('step').length - 2; - - input.val((current_value + step).toFixed(step_decimals)); - } - - input.change(); - }; - - var down = function() { - if (isInt) { - var current_value = parseInt(input.val()); - input.val(current_value - 1); - } else { - var current_value = parseFloat(input.val()); - var step = parseFloat(input.prop('step')); - var step_decimals = input.prop('step').length - 2; - - input.val((current_value - step).toFixed(step_decimals)); - } - - input.change(); - }; - } - }); -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/tabs/cli.js b/tabs/cli.js index cdaff5e7..2db1aef9 100644 --- a/tabs/cli.js +++ b/tabs/cli.js @@ -1,9 +1,10 @@ 'use strict'; -var CLI_active = false; -var CLI_valid = false; +tabs.cli = { + 'validateText': "", + 'sequenceElements': 0 +}; -tabs.cli = {}; tabs.cli.initialize = function(callback) { var self = this; GUI.active_tab_ref = this; @@ -14,7 +15,7 @@ tabs.cli.initialize = function(callback) { // translate to user-selected language localize(); - CLI_active = true; + CONFIGURATOR.cliActive = true; // Enter CLI mode var bufferOut = new ArrayBuffer(1); @@ -26,7 +27,7 @@ tabs.cli.initialize = function(callback) { var textarea = $('.tab-cli textarea'); - textarea.keypress(function(event) { + textarea.keypress(function (event) { if (event.which == 13) { // enter event.preventDefault(); // prevent the adding of new line @@ -36,7 +37,7 @@ tabs.cli.initialize = function(callback) { var timeout_needle = 0; for (var i = 0; i < out_arr.length; i++) { - send_slowly(out_arr, i, timeout_needle++); + self.sendSlowly(out_arr, i, timeout_needle++); } textarea.val(''); @@ -65,19 +66,100 @@ tabs.cli.history = { index: 0 }; -tabs.cli.history.add = function(str) { +tabs.cli.history.add = function (str) { this.history.push(str); this.index = this.history.length; }; -tabs.cli.history.prev = function() { +tabs.cli.history.prev = function () { if (this.index > 0) this.index -= 1; return this.history[this.index]; }; -tabs.cli.history.next = function() { +tabs.cli.history.next = function () { if (this.index < this.history.length) this.index += 1; return this.history[this.index - 1]; }; +tabs.cli.sendSlowly = function (out_arr, i, timeout_needle) { + GUI.timeout_add('CLI_send_slowly', function () { + var bufferOut = new ArrayBuffer(out_arr[i].length + 1); + var bufView = new Uint8Array(bufferOut); + + for (var c_key = 0; c_key < out_arr[i].length; c_key++) { + bufView[c_key] = out_arr[i].charCodeAt(c_key); + } + + bufView[out_arr[i].length] = 0x0D; // enter (\n) + + serial.send(bufferOut, function (writeInfo) {}); + }, timeout_needle * 5); +}; + +tabs.cli.read = function (readInfo) { + /* Some info about handling line feeds and carriage return + + line feed = LF = \n = 0x0A = 10 + carriage return = CR = \r = 0x0D = 13 + + MAC only understands CR + Linux and Unix only understand LF + Windows understands (both) CRLF + Chrome OS currenty unknown + */ + var data = new Uint8Array(readInfo.data), + text = ""; + + for (var i = 0; i < data.length; i++) { + if (CONFIGURATOR.cliValid) { + if (data[i] == 27 || this.sequenceElements > 0) { // ESC + other + this.sequenceElements++; + + // delete previous space + if (this.sequenceElements == 1) { + text = text.substring(0, text.length -1); + } + + // Reset + if (this.sequenceElements >= 5) { + this.sequenceElements = 0; + } + } + + if (this.sequenceElements == 0) { + switch (data[i]) { + case 10: // line feed + if (GUI.operating_system != "MacOS") { + text += "
"; + } + break; + case 13: // carriage return + if (GUI.operating_system == "MacOS") { + text += "
"; + } + break; + default: + text += String.fromCharCode(data[i]); + } + } + } else { + // try to catch part of valid CLI enter message + this.validateText += String.fromCharCode(data[i]); + } + } + + if (!CONFIGURATOR.cliValid && this.validateText.indexOf('CLI') != -1) { + CONFIGURATOR.cliValid = true; + this.validateText = ""; + + text = "Entering CLI Mode, type 'exit' to return, or 'help'

# "; + } + + $('.tab-cli .window .wrapper').append(text); + $('.tab-cli .window').scrollTop($('.tab-cli .window .wrapper').height()); + + // there seems to be some sort of initial rendering glitch in 33+, we will force redraw/refill + $('.tab-cli .window .wrapper').css('webkitTransform', 'scale(1)'); +}; + tabs.cli.cleanup = function(callback) { var bufferOut = new ArrayBuffer(5); var bufView = new Uint8Array(bufferOut); @@ -94,94 +176,10 @@ tabs.cli.cleanup = function(callback) { // 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() { - CLI_active = false; - CLI_valid = false; + CONFIGURATOR.cliActive = false; + CONFIGURATOR.cliValid = false; if (callback) callback(); }, 5000); // if we dont allow enough time to reboot, CRC of "first" command sent will fail, keep an eye for this one }); -}; - -function send_slowly(out_arr, i, timeout_needle) { - GUI.timeout_add('CLI_send_slowly', function() { - var bufferOut = new ArrayBuffer(out_arr[i].length + 1); - var bufView = new Uint8Array(bufferOut); - - for (var c_key = 0; c_key < out_arr[i].length; c_key++) { - bufView[c_key] = out_arr[i].charCodeAt(c_key); - } - - bufView[out_arr[i].length] = 0x0D; // enter (\n) - - serial.send(bufferOut, function(writeInfo) {}); - }, timeout_needle * 5); -} - -/* Some info about handling line feeds and carriage return - - line feed = LF = \n = 0x0A = 10 - carriage return = CR = \r = 0x0D = 13 - - MAC only understands CR - Linux and Unix only understand LF - Windows understands (both) CRLF - Chrome OS currenty unknown -*/ - -var sequence_elements = 0; -var CLI_validate_text = ""; -function handle_CLI(readInfo) { - var data = new Uint8Array(readInfo.data); - var text = ""; - - for (var i = 0; i < data.length; i++) { - if (CLI_valid) { - if (data[i] == 27 || sequence_elements > 0) { // ESC + other - sequence_elements++; - - // delete previous space - if (sequence_elements == 1) { - text = text.substring(0, text.length -1); - } - - // Reset - if (sequence_elements >= 5) { - sequence_elements = 0; - } - } - - if (sequence_elements == 0) { - switch (data[i]) { - case 10: // line feed - if (GUI.operating_system != "MacOS") { - text += "
"; - } - break; - case 13: // carriage return - if (GUI.operating_system == "MacOS") { - text += "
"; - } - break; - default: - text += String.fromCharCode(data[i]); - } - } - } else { - // try to catch part of valid CLI enter message - CLI_validate_text += String.fromCharCode(data[i]); - } - } - - if (!CLI_valid && CLI_validate_text.indexOf('CLI') != -1) { - CLI_valid = true; - CLI_validate_text = ""; - - text = "Entering CLI Mode, type 'exit' to return, or 'help'

# "; - } - - $('.tab-cli .window .wrapper').append(text); - $('.tab-cli .window').scrollTop($('.tab-cli .window .wrapper').height()); - - // there seems to be some sort of initial rendering glitch in 33+, we will force redraw/refill - $('.tab-cli .window .wrapper').css('webkitTransform', 'scale(1)'); -} +}; \ No newline at end of file diff --git a/tabs/logging.js b/tabs/logging.js index ed661c10..c458e275 100644 --- a/tabs/logging.js +++ b/tabs/logging.js @@ -1,7 +1,5 @@ 'use strict'; -var MSP_pass_through = false; - tabs.logging = {}; tabs.logging.initialize = function(callback) { GUI.active_tab_ref = this; @@ -10,7 +8,7 @@ tabs.logging.initialize = function(callback) { var requested_properties = []; - if (configuration_received) { + if (CONFIGURATOR.connectionValid) { MSP.send_message(MSP_codes.MSP_RC, false, false, get_motor_data); var get_motor_data = function () { @@ -21,7 +19,7 @@ tabs.logging.initialize = function(callback) { $('#content').load("./tabs/logging.html", process_html); } } else { - MSP_pass_through = true; + CONFIGURATOR.mspPassThrough = true; // we will initialize RC.channels array and MOTOR_DATA array manually RC.active_channels = 8; @@ -70,7 +68,7 @@ tabs.logging.initialize = function(callback) { } // request new - if (!MSP_pass_through) { + if (!CONFIGURATOR.mspPassThrough) { for (var i = 0; i < requested_properties.length; i++, requests++) { MSP.send_message(MSP_codes[requested_properties[i]]); } @@ -113,7 +111,7 @@ tabs.logging.initialize = function(callback) { } }); - if (MSP_pass_through) { + if (CONFIGURATOR.mspPassThrough) { $('a.back').show(); $('a.back').click(function() { @@ -121,7 +119,7 @@ tabs.logging.initialize = function(callback) { $('a.connect').click(); } else { GUI.tab_switch_cleanup(function() { - MSP_pass_through = false; + CONFIGURATOR.mspPassThrough = false; $('#tabs > ul li').removeClass('active'); tabs.default.initialize(); }); From e27a194ec7120a49a43d5ff7cdfd415c1f9997d9 Mon Sep 17 00:00:00 2001 From: cTn Date: Tue, 12 Aug 2014 15:51:31 +0200 Subject: [PATCH 22/54] another refactor for global variables, bugfixes for logging tab initialization in strict mode --- js/gui.js | 2 +- js/serial_backend.js | 4 ++-- main.js | 22 +++++++++++----------- tabs/auxiliary_configuration.js | 6 +++--- tabs/cli.js | 18 +++++++++--------- tabs/default.js | 8 ++++---- tabs/firmware_flasher.js | 8 ++++---- tabs/gps.js | 6 +++--- tabs/initial_setup.js | 8 ++++---- tabs/logging.js | 12 ++++++------ tabs/motor_outputs.js | 6 +++--- tabs/pid_tuning.js | 10 +++++----- tabs/receiver.js | 6 +++--- tabs/sensors.js | 10 +++------- tabs/servos.js | 6 +++--- 15 files changed, 64 insertions(+), 68 deletions(-) diff --git a/js/gui.js b/js/gui.js index 95e7137a..788534fd 100644 --- a/js/gui.js +++ b/js/gui.js @@ -1,6 +1,6 @@ 'use strict'; -var tabs = {}; // filled by individual tab js file +var TABS = {}; // filled by individual tab js file var GUI_control = function () { this.auto_connect = false; diff --git a/js/serial_backend.js b/js/serial_backend.js index 4e66a764..bb3bd090 100644 --- a/js/serial_backend.js +++ b/js/serial_backend.js @@ -51,7 +51,7 @@ $(document).ready(function() { $('#content').empty(); // load default html - tabs.default.initialize(); + TABS.default.initialize(); } $(this).data("clicks", !clicks); @@ -185,7 +185,7 @@ function read_serial(info) { if (!CONFIGURATOR.cliActive && !CONFIGURATOR.mspPassThrough) { MSP.read(info); } else if (CONFIGURATOR.cliActive) { - tabs.cli.read(info); + TABS.cli.read(info); } else if (CONFIGURATOR.mspPassThrough) { MSP.read(info); } diff --git a/main.js b/main.js index c01daf65..a6fde8b8 100644 --- a/main.js +++ b/main.js @@ -77,41 +77,41 @@ $(document).ready(function () { switch (tab) { case 'tab_initial_setup': - tabs.initial_setup.initialize(content_ready); + TABS.initial_setup.initialize(content_ready); break; case 'tab_pid_tuning': - tabs.pid_tuning.initialize(content_ready); + TABS.pid_tuning.initialize(content_ready); break; case 'tab_receiver': - tabs.receiver.initialize(content_ready); + TABS.receiver.initialize(content_ready); break; case 'tab_auxiliary_configuration': - tabs.auxiliary_configuration.initialize(content_ready); + TABS.auxiliary_configuration.initialize(content_ready); break; case 'tab_servos': - tabs.servos.initialize(content_ready); + TABS.servos.initialize(content_ready); break; case 'tab_gps': - tabs.gps.initialize(content_ready); + TABS.gps.initialize(content_ready); break; case 'tab_motor_outputs': - tabs.motor_outputs.initialize(content_ready); + TABS.motor_outputs.initialize(content_ready); break; case 'tab_sensors': - tabs.sensors.initialize(content_ready); + TABS.sensors.initialize(content_ready); break; case 'tab_cli': - tabs.cli.initialize(content_ready); + TABS.cli.initialize(content_ready); break; case 'tab_logging': - tabs.logging.initialize(content_ready); + TABS.logging.initialize(content_ready); break; } }); } }); - tabs.default.initialize(); + TABS.default.initialize(); // options $('a#options').click(function () { diff --git a/tabs/auxiliary_configuration.js b/tabs/auxiliary_configuration.js index fafbfbe7..a093f547 100644 --- a/tabs/auxiliary_configuration.js +++ b/tabs/auxiliary_configuration.js @@ -1,8 +1,8 @@ 'use strict'; // TODO: rework box_highlight & update_ui to accept flexible amount of aux channels -tabs.auxiliary_configuration = {}; -tabs.auxiliary_configuration.initialize = function(callback) { +TABS.auxiliary_configuration = {}; +TABS.auxiliary_configuration.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'auxiliary_configuration'; googleAnalytics.sendAppView('Auxiliary Configuration'); @@ -157,6 +157,6 @@ tabs.auxiliary_configuration.initialize = function(callback) { } }; -tabs.auxiliary_configuration.cleanup = function(callback) { +TABS.auxiliary_configuration.cleanup = function(callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/cli.js b/tabs/cli.js index 2db1aef9..ebaa5d1a 100644 --- a/tabs/cli.js +++ b/tabs/cli.js @@ -1,11 +1,11 @@ 'use strict'; -tabs.cli = { +TABS.cli = { 'validateText': "", 'sequenceElements': 0 }; -tabs.cli.initialize = function(callback) { +TABS.cli.initialize = function(callback) { var self = this; GUI.active_tab_ref = this; GUI.active_tab = 'cli'; @@ -61,25 +61,25 @@ tabs.cli.initialize = function(callback) { }); }; -tabs.cli.history = { +TABS.cli.history = { history: [], index: 0 }; -tabs.cli.history.add = function (str) { +TABS.cli.history.add = function (str) { this.history.push(str); this.index = this.history.length; }; -tabs.cli.history.prev = function () { +TABS.cli.history.prev = function () { if (this.index > 0) this.index -= 1; return this.history[this.index]; }; -tabs.cli.history.next = function () { +TABS.cli.history.next = function () { if (this.index < this.history.length) this.index += 1; return this.history[this.index - 1]; }; -tabs.cli.sendSlowly = function (out_arr, i, timeout_needle) { +TABS.cli.sendSlowly = function (out_arr, i, timeout_needle) { GUI.timeout_add('CLI_send_slowly', function () { var bufferOut = new ArrayBuffer(out_arr[i].length + 1); var bufView = new Uint8Array(bufferOut); @@ -94,7 +94,7 @@ tabs.cli.sendSlowly = function (out_arr, i, timeout_needle) { }, timeout_needle * 5); }; -tabs.cli.read = function (readInfo) { +TABS.cli.read = function (readInfo) { /* Some info about handling line feeds and carriage return line feed = LF = \n = 0x0A = 10 @@ -160,7 +160,7 @@ tabs.cli.read = function (readInfo) { $('.tab-cli .window .wrapper').css('webkitTransform', 'scale(1)'); }; -tabs.cli.cleanup = function(callback) { +TABS.cli.cleanup = function(callback) { var bufferOut = new ArrayBuffer(5); var bufView = new Uint8Array(bufferOut); diff --git a/tabs/default.js b/tabs/default.js index 125ebd1c..0d8b6ed7 100644 --- a/tabs/default.js +++ b/tabs/default.js @@ -1,7 +1,7 @@ 'use strict'; -tabs.default = {}; -tabs.default.initialize = function(callback) { +TABS.default = {}; +TABS.default.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'default'; @@ -16,7 +16,7 @@ tabs.default.initialize = function(callback) { // UI Hooks $('a.firmware_flasher').click(function() { - tabs.firmware_flasher.initialize(); + TABS.firmware_flasher.initialize(); }); $('div.welcome a, div.sponsors a').click(function() { @@ -27,6 +27,6 @@ tabs.default.initialize = function(callback) { }); }; -tabs.default.cleanup = function(callback) { +TABS.default.cleanup = function(callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/firmware_flasher.js b/tabs/firmware_flasher.js index d4229bbc..d8daf285 100644 --- a/tabs/firmware_flasher.js +++ b/tabs/firmware_flasher.js @@ -1,7 +1,7 @@ 'use strict'; -tabs.firmware_flasher = {}; -tabs.firmware_flasher.initialize = function (callback) { +TABS.firmware_flasher = {}; +TABS.firmware_flasher.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'firmware_flasher'; googleAnalytics.sendAppView('Firmware Flasher'); @@ -258,7 +258,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.default.initialize(); }); } else { GUI.log(chrome.i18n.getMessage('firmwareFlasherWaitForFinish')); @@ -269,7 +269,7 @@ tabs.firmware_flasher.initialize = function (callback) { }); }; -tabs.firmware_flasher.cleanup = function (callback) { +TABS.firmware_flasher.cleanup = function (callback) { PortHandler.flush_callbacks(); // unbind "global" events diff --git a/tabs/gps.js b/tabs/gps.js index 777d3579..75440945 100644 --- a/tabs/gps.js +++ b/tabs/gps.js @@ -1,7 +1,7 @@ 'use strict'; -tabs.gps = {}; -tabs.gps.initialize = function(callback) { +TABS.gps = {}; +TABS.gps.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'gps'; googleAnalytics.sendAppView('GPS Page'); @@ -61,6 +61,6 @@ tabs.gps.initialize = function(callback) { } }; -tabs.gps.cleanup = function(callback) { +TABS.gps.cleanup = function(callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/initial_setup.js b/tabs/initial_setup.js index 2ef932f3..5e2f3db1 100644 --- a/tabs/initial_setup.js +++ b/tabs/initial_setup.js @@ -1,9 +1,9 @@ 'use strict'; -tabs.initial_setup = { +TABS.initial_setup = { yaw_fix: 0.0 }; -tabs.initial_setup.initialize = function(callback) { +TABS.initial_setup.initialize = function(callback) { var self = this; GUI.active_tab_ref = this; GUI.active_tab = 'initial_setup'; @@ -206,7 +206,7 @@ tabs.initial_setup.initialize = function(callback) { GUI.log(chrome.i18n.getMessage('initialSetupSettingsRestored')); GUI.tab_switch_cleanup(function() { - tabs.initial_setup.initialize(); + TABS.initial_setup.initialize(); }); }); }); @@ -324,6 +324,6 @@ tabs.initial_setup.initialize = function(callback) { } }; -tabs.initial_setup.cleanup = function(callback) { +TABS.initial_setup.cleanup = function(callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/logging.js b/tabs/logging.js index c458e275..56f00ea8 100644 --- a/tabs/logging.js +++ b/tabs/logging.js @@ -1,7 +1,7 @@ 'use strict'; -tabs.logging = {}; -tabs.logging.initialize = function(callback) { +TABS.logging = {}; +TABS.logging.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'logging'; googleAnalytics.sendAppView('Logging'); @@ -9,8 +9,6 @@ tabs.logging.initialize = function(callback) { var requested_properties = []; if (CONFIGURATOR.connectionValid) { - MSP.send_message(MSP_codes.MSP_RC, false, false, get_motor_data); - var get_motor_data = function () { MSP.send_message(MSP_codes.MSP_MOTOR, false, false, load_html); } @@ -18,6 +16,8 @@ tabs.logging.initialize = function(callback) { var load_html = function () { $('#content').load("./tabs/logging.html", process_html); } + + MSP.send_message(MSP_codes.MSP_RC, false, false, get_motor_data); } else { CONFIGURATOR.mspPassThrough = true; @@ -121,7 +121,7 @@ tabs.logging.initialize = function(callback) { GUI.tab_switch_cleanup(function() { CONFIGURATOR.mspPassThrough = false; $('#tabs > ul li').removeClass('active'); - tabs.default.initialize(); + TABS.default.initialize(); }); } }); @@ -337,6 +337,6 @@ tabs.logging.initialize = function(callback) { } }; -tabs.logging.cleanup = function(callback) { +TABS.logging.cleanup = function(callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/motor_outputs.js b/tabs/motor_outputs.js index 37af7738..b1f5790a 100644 --- a/tabs/motor_outputs.js +++ b/tabs/motor_outputs.js @@ -1,7 +1,7 @@ 'use strict'; -tabs.motor_outputs = {}; -tabs.motor_outputs.initialize = function(callback) { +TABS.motor_outputs = {}; +TABS.motor_outputs.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'motor_outputs'; googleAnalytics.sendAppView('Motor Outputs Page'); @@ -373,6 +373,6 @@ tabs.motor_outputs.initialize = function(callback) { } }; -tabs.motor_outputs.cleanup = function(callback) { +TABS.motor_outputs.cleanup = function(callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/pid_tuning.js b/tabs/pid_tuning.js index d641d134..e1b04d8f 100644 --- a/tabs/pid_tuning.js +++ b/tabs/pid_tuning.js @@ -1,7 +1,7 @@ 'use strict'; -tabs.pid_tuning = {}; -tabs.pid_tuning.initialize = function(callback) { +TABS.pid_tuning = {}; +TABS.pid_tuning.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'pid_tuning'; googleAnalytics.sendAppView('PID Tuning'); @@ -188,7 +188,7 @@ tabs.pid_tuning.initialize = function(callback) { GUI.log(chrome.i18n.getMessage('pidTuningLoadedProfile', [profile])); GUI.tab_switch_cleanup(function() { - tabs.pid_tuning.initialize(); + TABS.pid_tuning.initialize(); }); }); }); @@ -197,7 +197,7 @@ tabs.pid_tuning.initialize = function(callback) { GUI.tab_switch_cleanup(function() { GUI.log(chrome.i18n.getMessage('pidTuningDataRefreshed')); - tabs.pid_tuning.initialize(); + TABS.pid_tuning.initialize(); }); }); @@ -319,6 +319,6 @@ tabs.pid_tuning.initialize = function(callback) { } }; -tabs.pid_tuning.cleanup = function(callback) { +TABS.pid_tuning.cleanup = function(callback) { if (callback) callback(); } \ No newline at end of file diff --git a/tabs/receiver.js b/tabs/receiver.js index 9bfa8541..151363d9 100644 --- a/tabs/receiver.js +++ b/tabs/receiver.js @@ -1,7 +1,7 @@ 'use strict'; -tabs.receiver = {}; -tabs.receiver.initialize = function(callback) { +TABS.receiver = {}; +TABS.receiver.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'receiver'; googleAnalytics.sendAppView('Receiver Page'); @@ -275,6 +275,6 @@ tabs.receiver.initialize = function(callback) { } }; -tabs.receiver.cleanup = function(callback) { +TABS.receiver.cleanup = function(callback) { if (callback) callback(); }; diff --git a/tabs/sensors.js b/tabs/sensors.js index 3f4e526b..23319553 100644 --- a/tabs/sensors.js +++ b/tabs/sensors.js @@ -1,7 +1,7 @@ 'use strict'; -tabs.sensors = {}; -tabs.sensors.initialize = function(callback) { +TABS.sensors = {}; +TABS.sensors.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'sensors'; googleAnalytics.sendAppView('Sensor Page'); @@ -414,12 +414,8 @@ tabs.sensors.initialize = function(callback) { }); }; -tabs.sensors.cleanup = function(callback) { +TABS.sensors.cleanup = function(callback) { serial.empty_output_buffer(); - // sensor data tab uses scrollbars, emptying the content before loading another tab - // prevents scrollbar exposure to any of the tabs while new content is loaded in - $('#content').empty(); - if (callback) callback(); }; diff --git a/tabs/servos.js b/tabs/servos.js index 1ccb5828..eda42891 100644 --- a/tabs/servos.js +++ b/tabs/servos.js @@ -6,8 +6,8 @@ */ 'use strict'; -tabs.servos = {}; -tabs.servos.initialize = function(callback) { +TABS.servos = {}; +TABS.servos.initialize = function(callback) { GUI.active_tab_ref = this; GUI.active_tab = 'servos'; googleAnalytics.sendAppView('Servos'); @@ -303,6 +303,6 @@ tabs.servos.initialize = function(callback) { } }; -tabs.servos.cleanup = function(callback) { +TABS.servos.cleanup = function(callback) { if (callback) callback(); }; \ No newline at end of file From 2753f354e096665b49b87233aba95e674aa91736 Mon Sep 17 00:00:00 2001 From: cTn Date: Tue, 12 Aug 2014 16:05:22 +0200 Subject: [PATCH 23/54] polishing run --- tabs/auxiliary_configuration.js | 12 ++++++------ tabs/cli.js | 23 +++++++++++++---------- tabs/default.js | 10 +++++----- tabs/gps.js | 6 +++--- tabs/initial_setup.js | 28 ++++++++++++++-------------- 5 files changed, 41 insertions(+), 38 deletions(-) diff --git a/tabs/auxiliary_configuration.js b/tabs/auxiliary_configuration.js index a093f547..246d3743 100644 --- a/tabs/auxiliary_configuration.js +++ b/tabs/auxiliary_configuration.js @@ -2,7 +2,7 @@ // TODO: rework box_highlight & update_ui to accept flexible amount of aux channels TABS.auxiliary_configuration = {}; -TABS.auxiliary_configuration.initialize = function(callback) { +TABS.auxiliary_configuration.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'auxiliary_configuration'; googleAnalytics.sendAppView('Auxiliary Configuration'); @@ -62,11 +62,11 @@ TABS.auxiliary_configuration.initialize = function(callback) { } // UI Hooks - $('a.update').click(function() { + $('a.update').click(function () { // catch the input changes var main_needle = 0; var needle = 0; - $('.boxes input').each(function() { + $('.boxes input').each(function () { if ($(this).is(':checked')) { AUX_CONFIG_values[main_needle] = bit_set(AUX_CONFIG_values[main_needle], needle); } else { @@ -93,7 +93,7 @@ TABS.auxiliary_configuration.initialize = function(callback) { MSP.send_message(MSP_codes.MSP_SET_BOX, AUX_val_buffer_out, false, save_to_eeprom); function save_to_eeprom() { - MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function() { + MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () { GUI.log(chrome.i18n.getMessage('auxiliaryEepromSaved')); }); } @@ -149,7 +149,7 @@ TABS.auxiliary_configuration.initialize = function(callback) { 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() { + GUI.interval_add('status_pull', function () { MSP.send_message(MSP_codes.MSP_STATUS); }, 250, true); @@ -157,6 +157,6 @@ TABS.auxiliary_configuration.initialize = function(callback) { } }; -TABS.auxiliary_configuration.cleanup = function(callback) { +TABS.auxiliary_configuration.cleanup = function (callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/cli.js b/tabs/cli.js index ebaa5d1a..5c0e88c1 100644 --- a/tabs/cli.js +++ b/tabs/cli.js @@ -5,13 +5,13 @@ TABS.cli = { 'sequenceElements': 0 }; -TABS.cli.initialize = function(callback) { +TABS.cli.initialize = function (callback) { var self = this; GUI.active_tab_ref = this; GUI.active_tab = 'cli'; googleAnalytics.sendAppView('CLI Page'); - $('#content').load("./tabs/cli.html", function() { + $('#content').load("./tabs/cli.html", function () { // translate to user-selected language localize(); @@ -23,7 +23,7 @@ TABS.cli.initialize = function(callback) { bufView[0] = 0x23; // # - serial.send(bufferOut, function(writeInfo) {}); + serial.send(bufferOut, function (writeInfo) {}); var textarea = $('.tab-cli textarea'); @@ -44,14 +44,17 @@ TABS.cli.initialize = function(callback) { } }); - textarea.keyup(function(event) { - var keyUp = { 38: true }, keyDown = { 40: true }; + textarea.keyup(function (event) { + var keyUp = {38: true}, + keyDown = {40: true}; - if (event.keyCode in keyUp) + if (event.keyCode in keyUp) { textarea.val(self.history.prev()); + } - if (event.keyCode in keyDown) + if (event.keyCode in keyDown) { textarea.val(self.history.next()); + } }); // give input element user focus @@ -160,7 +163,7 @@ TABS.cli.read = function (readInfo) { $('.tab-cli .window .wrapper').css('webkitTransform', 'scale(1)'); }; -TABS.cli.cleanup = function(callback) { +TABS.cli.cleanup = function (callback) { var bufferOut = new ArrayBuffer(5); var bufView = new Uint8Array(bufferOut); @@ -170,12 +173,12 @@ TABS.cli.cleanup = function(callback) { bufView[3] = 0x74; // t bufView[4] = 0x0D; // enter - serial.send(bufferOut, function(writeInfo) { + serial.send(bufferOut, function (writeInfo) { // we could handle this "nicely", but this will do for now // (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 () { CONFIGURATOR.cliActive = false; CONFIGURATOR.cliValid = false; diff --git a/tabs/default.js b/tabs/default.js index 0d8b6ed7..16968f47 100644 --- a/tabs/default.js +++ b/tabs/default.js @@ -1,11 +1,11 @@ 'use strict'; TABS.default = {}; -TABS.default.initialize = function(callback) { +TABS.default.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'default'; - $('#content').load("./tabs/default.html", function() { + $('#content').load("./tabs/default.html", function () { //check_usb_permissions(); // temporary enabled in dev branch, should be commented out untill DFU support goes live // translate to user-selected language @@ -15,11 +15,11 @@ TABS.default.initialize = function(callback) { $('div.changelog.configurator .wrapper').load('./changelog.html'); // UI Hooks - $('a.firmware_flasher').click(function() { + $('a.firmware_flasher').click(function () { TABS.firmware_flasher.initialize(); }); - $('div.welcome a, div.sponsors a').click(function() { + $('div.welcome a, div.sponsors a').click(function () { googleAnalytics.sendEvent('ExternalUrls', 'Click', $(this).prop('href')); }); @@ -27,6 +27,6 @@ TABS.default.initialize = function(callback) { }); }; -TABS.default.cleanup = function(callback) { +TABS.default.cleanup = function (callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/gps.js b/tabs/gps.js index 75440945..b84cb40c 100644 --- a/tabs/gps.js +++ b/tabs/gps.js @@ -1,7 +1,7 @@ 'use strict'; TABS.gps = {}; -TABS.gps.initialize = function(callback) { +TABS.gps.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'gps'; googleAnalytics.sendAppView('GPS Page'); @@ -53,7 +53,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 () { MSP.send_message(MSP_codes.MSP_STATUS); }, 250, true); @@ -61,6 +61,6 @@ TABS.gps.initialize = function(callback) { } }; -TABS.gps.cleanup = function(callback) { +TABS.gps.cleanup = function (callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/initial_setup.js b/tabs/initial_setup.js index 5e2f3db1..b38ac895 100644 --- a/tabs/initial_setup.js +++ b/tabs/initial_setup.js @@ -3,7 +3,8 @@ TABS.initial_setup = { yaw_fix: 0.0 }; -TABS.initial_setup.initialize = function(callback) { + +TABS.initial_setup.initialize = function (callback) { var self = this; GUI.active_tab_ref = this; GUI.active_tab = 'initial_setup'; @@ -137,7 +138,6 @@ TABS.initial_setup.initialize = function(callback) { case 13: $(".modelMixDiagram").attr("src","./images/motor_order/octox.svg").addClass('modelMixOctoX'); break; - case 4: // BI case 5: // GIMBAL case 8: // FLYING_WING @@ -161,7 +161,7 @@ TABS.initial_setup.initialize = function(callback) { $('span.heading').text(chrome.i18n.getMessage('initialSetupheading', [0])); // UI Hooks - $('a.calibrateAccel').click(function() { + $('a.calibrateAccel').click(function () { var self = $(this); if (!self.hasClass('calibrating')) { @@ -170,11 +170,11 @@ TABS.initial_setup.initialize = function(callback) { // 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() { + MSP.send_message(MSP_codes.MSP_ACC_CALIBRATION, false, false, function () { GUI.log(chrome.i18n.getMessage('initialSetupAccelCalibStarted')); }); - GUI.timeout_add('button_reset', function() { + GUI.timeout_add('button_reset', function () { GUI.interval_resume('initial_setup_data_pull'); GUI.log(chrome.i18n.getMessage('initialSetupAccelCalibEnded')); @@ -184,17 +184,17 @@ TABS.initial_setup.initialize = function(callback) { } }); - $('a.calibrateMag').click(function() { + $('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() { + MSP.send_message(MSP_codes.MSP_MAG_CALIBRATION, false, false, function () { GUI.log(chrome.i18n.getMessage('initialSetupMagCalibStarted')); }); - GUI.timeout_add('button_reset', function() { + GUI.timeout_add('button_reset', function () { GUI.log(chrome.i18n.getMessage('initialSetupMagCalibEnded')); self.removeClass('calibrating'); }, 30000); @@ -202,7 +202,7 @@ TABS.initial_setup.initialize = function(callback) { }); $('a.resetSettings').click(function() { - MSP.send_message(MSP_codes.MSP_RESET_CONF, false, false, function() { + MSP.send_message(MSP_codes.MSP_RESET_CONF, false, false, function () { GUI.log(chrome.i18n.getMessage('initialSetupSettingsRestored')); GUI.tab_switch_cleanup(function() { @@ -212,7 +212,7 @@ TABS.initial_setup.initialize = function(callback) { }); - $('a.update').click(function() { + $('a.update').click(function () { CONFIG.accelerometerTrims[0] = parseInt($('input[name="pitch"]').val()); CONFIG.accelerometerTrims[1] = parseInt($('input[name="roll"]').val()); @@ -265,7 +265,7 @@ TABS.initial_setup.initialize = function(callback) { 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() { + MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () { GUI.log(chrome.i18n.getMessage('initialSetupEepromSaved')); }); } @@ -275,7 +275,7 @@ TABS.initial_setup.initialize = function(callback) { $('div#interactive_block > a.reset').text(chrome.i18n.getMessage('initialSetupButtonResetZaxisValue', [self.yaw_fix])); // reset yaw button hook - $('div#interactive_block > a.reset').click(function() { + $('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])); @@ -316,7 +316,7 @@ TABS.initial_setup.initialize = function(callback) { 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() { + GUI.interval_add('status_pull', function () { MSP.send_message(MSP_codes.MSP_STATUS); }, 250, true); @@ -324,6 +324,6 @@ TABS.initial_setup.initialize = function(callback) { } }; -TABS.initial_setup.cleanup = function(callback) { +TABS.initial_setup.cleanup = function (callback) { if (callback) callback(); }; \ No newline at end of file From 932a58d3556f4e850b13dfda7d83ecb321308aeb Mon Sep 17 00:00:00 2001 From: cTn Date: Tue, 12 Aug 2014 16:20:26 +0200 Subject: [PATCH 24/54] pretty pretty pretty --- tabs/logging.js | 35 +++++++++++++------------ tabs/motor_outputs.js | 30 +++++++++++----------- tabs/pid_tuning.js | 60 +++++++++++++++++++++---------------------- tabs/receiver.js | 60 +++++++++++++++++++++---------------------- tabs/sensors.js | 53 +++++++++++++++++++------------------- tabs/servos.js | 18 ++++++------- 6 files changed, 128 insertions(+), 128 deletions(-) diff --git a/tabs/logging.js b/tabs/logging.js index 56f00ea8..5ffcb9ba 100644 --- a/tabs/logging.js +++ b/tabs/logging.js @@ -1,7 +1,7 @@ 'use strict'; TABS.logging = {}; -TABS.logging.initialize = function(callback) { +TABS.logging.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'logging'; googleAnalytics.sendAppView('Logging'); @@ -41,7 +41,7 @@ TABS.logging.initialize = function(callback) { // UI hooks $('a.log_file').click(prepare_file); - $('a.logging').click(function() { + $('a.logging').click(function () { if (GUI.connected_to) { if (fileEntry != null) { var clicks = $(this).data('clicks'); @@ -53,7 +53,7 @@ TABS.logging.initialize = function(callback) { log_buffer = []; requested_properties = []; - $('.properties input:checked').each(function() { + $('.properties input:checked').each(function () { requested_properties.push($(this).prop('name')); }); @@ -118,7 +118,7 @@ TABS.logging.initialize = function(callback) { if (GUI.connected_to) { $('a.connect').click(); } else { - GUI.tab_switch_cleanup(function() { + GUI.tab_switch_cleanup(function () { CONFIGURATOR.mspPassThrough = false; $('#tabs > ul li').removeClass('active'); TABS.default.initialize(); @@ -127,9 +127,9 @@ TABS.logging.initialize = function(callback) { }); } - chrome.storage.local.get('logging_file_entry', function(result) { + chrome.storage.local.get('logging_file_entry', function (result) { if (result.logging_file_entry) { - chrome.fileSystem.restoreEntry(result.logging_file_entry, function(entry) { + chrome.fileSystem.restoreEntry(result.logging_file_entry, function (entry) { fileEntry = entry; prepare_writer(true); }); @@ -201,9 +201,10 @@ TABS.logging.initialize = function(callback) { append_to_file(head); } - var samples = 0; - var requests = 0; - var log_buffer = []; + var samples = 0, + requests = 0, + log_buffer = []; + function crunch_data() { var sample = millitime(); @@ -255,8 +256,8 @@ TABS.logging.initialize = function(callback) { } // IO related methods - var fileEntry = null; - var fileWriter = null; + var fileEntry = null, + fileWriter = null; function prepare_file() { // create or load the file @@ -296,29 +297,29 @@ TABS.logging.initialize = function(callback) { } function prepare_writer(retaining) { - fileEntry.createWriter(function(writer) { + fileEntry.createWriter(function (writer) { fileWriter = writer; - fileWriter.onerror = function(e) { + fileWriter.onerror = function (e) { console.error(e); // stop logging if the procedure was/is still running if ($('a.logging').data('clicks')) $('a.logging').click(); }; - fileWriter.onwriteend = function() { + fileWriter.onwriteend = function () { $('.size').text(bytesToSize(fileWriter.length)); }; if (retaining) { - chrome.fileSystem.getDisplayPath(fileEntry, function(path) { + chrome.fileSystem.getDisplayPath(fileEntry, function (path) { GUI.log(chrome.i18n.getMessage('loggingAutomaticallyRetained', [path])); }); } // update log size in UI on fileWriter creation $('.size').text(bytesToSize(fileWriter.length)); - }, function(e) { + }, function (e) { // File is not readable or does not exist! console.error(e); @@ -337,6 +338,6 @@ TABS.logging.initialize = function(callback) { } }; -TABS.logging.cleanup = function(callback) { +TABS.logging.cleanup = function (callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/motor_outputs.js b/tabs/motor_outputs.js index b1f5790a..f5d17228 100644 --- a/tabs/motor_outputs.js +++ b/tabs/motor_outputs.js @@ -1,7 +1,7 @@ 'use strict'; TABS.motor_outputs = {}; -TABS.motor_outputs.initialize = function(callback) { +TABS.motor_outputs.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'motor_outputs'; googleAnalytics.sendAppView('Motor Outputs Page'); @@ -85,17 +85,17 @@ TABS.motor_outputs.initialize = function(callback) { .scale(helpers.widthScale) .ticks(5) .orient("bottom") - .tickFormat(function(d) {return d;}); + .tickFormat(function (d) {return d;}); helpers.yAxis = d3.svg.axis() .scale(helpers.heightScale) .ticks(5) .orient("left") - .tickFormat(function(d) {return d;}); + .tickFormat(function (d) {return d;}); helpers.line = d3.svg.line() - .x(function(d) { return helpers.widthScale(d[0]); }) - .y(function(d) { return helpers.heightScale(d[1]); }); + .x(function (d) { return helpers.widthScale(d[0]); }) + .y(function (d) { return helpers.heightScale(d[1]); }); return helpers; } @@ -105,7 +105,7 @@ TABS.motor_outputs.initialize = function(callback) { if (graphHelpers.dynamicHeightDomain) { var limits = []; - $.each(data, function(idx, datum) { + $.each(data, function (idx, datum) { limits.push(datum.min); limits.push(datum.max); }); @@ -119,7 +119,7 @@ TABS.motor_outputs.initialize = function(callback) { svg.select(".y.axis").call(graphHelpers.yAxis); var group = svg.select("g.data"); - var lines = group.selectAll("path").data(data, function(d, i) { return i; }); + var lines = group.selectAll("path").data(data, function (d, i) {return i;}); var newLines = lines.enter().append("path").attr("class", "line"); lines.attr('d', graphHelpers.line); } @@ -154,7 +154,7 @@ TABS.motor_outputs.initialize = function(callback) { y: [], z: [], }; - $('.plot_control .x, .plot_control .y, .plot_control .z').each(function() { + $('.plot_control .x, .plot_control .y, .plot_control .z').each(function () { var el = $(this); if (el.hasClass('x')) { raw_data_text_ements.x.push(el); @@ -166,7 +166,7 @@ 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) { + 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); @@ -179,7 +179,7 @@ TABS.motor_outputs.initialize = function(callback) { } }); - $('.tab-motor_outputs .rate select, .tab-motor_outputs .scale select').change(function() { + $('.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()); @@ -224,7 +224,7 @@ TABS.motor_outputs.initialize = function(callback) { } }); - $('a.reset_accel_max').click(function() { + $('a.reset_accel_max').click(function () { accel_max_read = [0, 0, 0]; accel_offset_established = false; }); @@ -246,7 +246,7 @@ TABS.motor_outputs.initialize = function(callback) { $('div.values li:not(:last)').html(MISC.mincommand); // UI hooks - $('div.sliders input:not(.master)').on('input', function() { + $('div.sliders input:not(.master)').on('input', function () { var index = $(this).index(); $('div.values li').eq(index).html($(this).val()); @@ -264,7 +264,7 @@ TABS.motor_outputs.initialize = function(callback) { MSP.send_message(MSP_codes.MSP_SET_MOTOR, buffer_out); }); - $('div.sliders input.master').on('input', function() { + $('div.sliders input.master').on('input', function () { var val = $(this).val(); $('div.sliders input:not(:disabled, :last)').val(val); @@ -272,7 +272,7 @@ TABS.motor_outputs.initialize = function(callback) { $('div.sliders input:not(:last):first').trigger('input'); }); - $('div.notice input[type="checkbox"]').change(function() { + $('div.notice input[type="checkbox"]').change(function () { if ($(this).is(':checked')) { $('div.sliders input').slice(0, number_of_valid_outputs).prop('disabled', false); @@ -373,6 +373,6 @@ TABS.motor_outputs.initialize = function(callback) { } }; -TABS.motor_outputs.cleanup = function(callback) { +TABS.motor_outputs.cleanup = function (callback) { if (callback) callback(); }; \ No newline at end of file diff --git a/tabs/pid_tuning.js b/tabs/pid_tuning.js index e1b04d8f..faf88bc3 100644 --- a/tabs/pid_tuning.js +++ b/tabs/pid_tuning.js @@ -1,7 +1,7 @@ 'use strict'; TABS.pid_tuning = {}; -TABS.pid_tuning.initialize = function(callback) { +TABS.pid_tuning.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'pid_tuning'; googleAnalytics.sendAppView('PID Tuning'); @@ -44,7 +44,7 @@ TABS.pid_tuning.initialize = function(callback) { // Fill in the data from PIDs array var i = 0; - $('.pid_tuning .ROLL input').each(function() { + $('.pid_tuning .ROLL input').each(function () { switch (i) { case 0: $(this).val(PIDs[0][i++].toFixed(1)); @@ -59,7 +59,7 @@ TABS.pid_tuning.initialize = function(callback) { }); i = 0; - $('.pid_tuning .PITCH input').each(function() { + $('.pid_tuning .PITCH input').each(function () { switch (i) { case 0: $(this).val(PIDs[1][i++].toFixed(1)); @@ -74,7 +74,7 @@ TABS.pid_tuning.initialize = function(callback) { }); i = 0; - $('.pid_tuning .YAW input').each(function() { + $('.pid_tuning .YAW input').each(function () { switch (i) { case 0: $(this).val(PIDs[2][i++].toFixed(1)); @@ -89,7 +89,7 @@ TABS.pid_tuning.initialize = function(callback) { }); i = 0; - $('.pid_tuning .ALT input').each(function() { + $('.pid_tuning .ALT input').each(function () { switch (i) { case 0: $(this).val(PIDs[3][i++].toFixed(1)); @@ -104,12 +104,12 @@ TABS.pid_tuning.initialize = function(callback) { }); i = 0; - $('.pid_tuning .Pos input').each(function() { + $('.pid_tuning .Pos input').each(function () { $(this).val(PIDs[4][i++].toFixed(2)); }); i = 0; - $('.pid_tuning .PosR input').each(function() { + $('.pid_tuning .PosR input').each(function () { switch (i) { case 0: $(this).val(PIDs[5][i++].toFixed(1)); @@ -124,7 +124,7 @@ TABS.pid_tuning.initialize = function(callback) { }); i = 0; - $('.pid_tuning .NavR input').each(function() { + $('.pid_tuning .NavR input').each(function () { switch (i) { case 0: $(this).val(PIDs[6][i++].toFixed(1)); @@ -139,7 +139,7 @@ TABS.pid_tuning.initialize = function(callback) { }); i = 0; - $('.pid_tuning .LEVEL input').each(function() { + $('.pid_tuning .LEVEL input').each(function () { switch (i) { case 0: $(this).val(PIDs[7][i++].toFixed(1)); @@ -154,12 +154,12 @@ TABS.pid_tuning.initialize = function(callback) { }); i = 0; - $('.pid_tuning .MAG input').each(function() { + $('.pid_tuning .MAG input').each(function () { $(this).val(PIDs[8][i++].toFixed(1)); }); i = 0; - $('.pid_tuning .Vario input').each(function() { + $('.pid_tuning .Vario input').each(function () { switch (i) { case 0: $(this).val(PIDs[9][i++].toFixed(1)); @@ -182,74 +182,74 @@ TABS.pid_tuning.initialize = function(callback) { $('input[name="profile"]').val(CONFIG.profile + 1); // +1 because the range is 0-2 // UI Hooks - $('input[name="profile"]').change(function() { + $('input[name="profile"]').change(function () { var profile = parseInt($(this).val()); - MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [profile - 1], false, function() { + MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [profile - 1], false, function () { GUI.log(chrome.i18n.getMessage('pidTuningLoadedProfile', [profile])); - GUI.tab_switch_cleanup(function() { + GUI.tab_switch_cleanup(function () { TABS.pid_tuning.initialize(); }); }); }); - $('a.refresh').click(function() { - GUI.tab_switch_cleanup(function() { + $('a.refresh').click(function () { + GUI.tab_switch_cleanup(function () { GUI.log(chrome.i18n.getMessage('pidTuningDataRefreshed')); TABS.pid_tuning.initialize(); }); }); - $('a.update').click(function() { + $('a.update').click(function () { // Catch all the changes and stuff the inside PIDs array var i = 0; - $('table.pid_tuning tr.ROLL input').each(function() { + $('table.pid_tuning tr.ROLL input').each(function () { PIDs[0][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.PITCH input').each(function() { + $('table.pid_tuning tr.PITCH input').each(function () { PIDs[1][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.YAW input').each(function() { + $('table.pid_tuning tr.YAW input').each(function () { PIDs[2][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.ALT input').each(function() { + $('table.pid_tuning tr.ALT input').each(function () { PIDs[3][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.Vario input').each(function() { + $('table.pid_tuning tr.Vario input').each(function () { PIDs[9][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.Pos input').each(function() { + $('table.pid_tuning tr.Pos input').each(function () { PIDs[4][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.PosR input').each(function() { + $('table.pid_tuning tr.PosR input').each(function () { PIDs[5][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.NavR input').each(function() { + $('table.pid_tuning tr.NavR input').each(function () { PIDs[6][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.LEVEL input').each(function() { + $('table.pid_tuning tr.LEVEL input').each(function () { PIDs[7][i++] = parseFloat($(this).val()); }); i = 0; - $('table.pid_tuning tr.MAG input').each(function() { + $('table.pid_tuning tr.MAG input').each(function () { PIDs[8][i++] = parseFloat($(this).val()); }); @@ -304,14 +304,14 @@ TABS.pid_tuning.initialize = function(callback) { } function save_to_eeprom() { - MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function() { + MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () { GUI.log(chrome.i18n.getMessage('pidTuningEepromSaved')); }); } }); // status data pulled via separate timer with static speed - GUI.interval_add('status_pull', function() { + GUI.interval_add('status_pull', function () { MSP.send_message(MSP_codes.MSP_STATUS); }, 250, true); @@ -319,6 +319,6 @@ TABS.pid_tuning.initialize = function(callback) { } }; -TABS.pid_tuning.cleanup = function(callback) { +TABS.pid_tuning.cleanup = function (callback) { if (callback) callback(); } \ No newline at end of file diff --git a/tabs/receiver.js b/tabs/receiver.js index 151363d9..2247693e 100644 --- a/tabs/receiver.js +++ b/tabs/receiver.js @@ -1,7 +1,7 @@ 'use strict'; TABS.receiver = {}; -TABS.receiver.initialize = function(callback) { +TABS.receiver.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'receiver'; googleAnalytics.sendAppView('Receiver Page'); @@ -27,7 +27,7 @@ TABS.receiver.initialize = function(callback) { $('.tunings .rate input[name="rate"]').val(RC_tuning.RC_RATE.toFixed(2)); $('.tunings .rate input[name="expo"]').val(RC_tuning.RC_EXPO.toFixed(2)); - chrome.storage.local.get('rx_refresh_rate', function(result) { + chrome.storage.local.get('rx_refresh_rate', function (result) { if (typeof result.rx_refresh_rate != 'undefined') { $('select[name="rx_refresh_rate"]').val(result.rx_refresh_rate).change(); } else { @@ -36,9 +36,9 @@ TABS.receiver.initialize = function(callback) { }); // generate bars - var bar_names = ['Roll', 'Pitch', 'Yaw', 'Throttle']; - var bar_container = $('.tab-receiver .bars'); - var aux_index = 1; + var bar_names = ['Roll', 'Pitch', 'Yaw', 'Throttle'], + bar_container = $('.tab-receiver .bars'), + aux_index = 1; for (var i = 0; i < RC.active_channels; i++) { var name; @@ -59,19 +59,19 @@ TABS.receiver.initialize = function(callback) { } var meter_array = []; - $('meter', bar_container).each(function() { + $('meter', bar_container).each(function () { meter_array.push($(this)); }); var meter_values_array = []; - $('.value', bar_container).each(function() { + $('.value', bar_container).each(function () { meter_values_array.push($(this)); }); // UI Hooks // curves - $('.tunings .throttle input').change(function() { - setTimeout(function() { + $('.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()); @@ -98,8 +98,8 @@ TABS.receiver.initialize = function(callback) { }, 0); // race condition, that should always trigger after all events are processed }).change(); - $('.tunings .rate input').change(function() { - setTimeout(function() { + $('.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()); @@ -118,8 +118,8 @@ TABS.receiver.initialize = function(callback) { }, 0); // race condition, that should always trigger after all events are processed }).change(); - $('a.refresh').click(function() { - MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, function() { + $('a.refresh').click(function () { + MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, function () { GUI.log(chrome.i18n.getMessage('receiverDataRefreshed')); // fill in data from RC_tuning @@ -135,7 +135,7 @@ TABS.receiver.initialize = function(callback) { }); }); - $('a.update').click(function() { + $('a.update').click(function () { // catch RC_tuning changes RC_tuning.throttle_MID = parseFloat($('.tunings .throttle input[name="mid"]').val()); RC_tuning.throttle_EXPO = parseFloat($('.tunings .throttle input[name="expo"]').val()); @@ -156,13 +156,13 @@ TABS.receiver.initialize = function(callback) { MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, RC_tuning_buffer_out, false, save_to_eeprom); function save_to_eeprom() { - MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function() { + MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () { GUI.log(chrome.i18n.getMessage('receiverEepromSaved')); }); } }); - $('select[name="rx_refresh_rate"]').change(function() { + $('select[name="rx_refresh_rate"]').change(function () { var plot_update_rate = parseInt($(this).val(), 10); // save update rate @@ -178,12 +178,12 @@ TABS.receiver.initialize = function(callback) { RX_plot_data[i] = []; } - var samples = 0; - var svg = d3.select("svg"); + var samples = 0, + svg = d3.select("svg"), + RX_plot_e = $('#RX_plot'), + margin = {top: 20, right: 0, bottom: 10, left: 40}, + width, height, widthScale, heightScale; - var RX_plot_e = $('#RX_plot'); - var margin = {top: 20, right: 0, bottom: 10, left: 40}; - var width, height, widthScale, heightScale; function update_receiver_plot_size() { width = RX_plot_e.width() - margin.left - margin.right; height = RX_plot_e.height() - margin.top - margin.bottom; @@ -235,25 +235,25 @@ TABS.receiver.initialize = function(callback) { var xAxis = d3.svg.axis(). scale(widthScale). orient("bottom"). - tickFormat(function(d) {return d;}); + tickFormat(function (d) {return d;}); var yAxis = d3.svg.axis(). scale(heightScale). orient("left"). - tickFormat(function(d) {return d;}); + tickFormat(function (d) {return d;}); var line = d3.svg.line(). - x(function(d) {return widthScale(d[0]);}). - y(function(d) {return heightScale(d[1]);}); + x(function (d) {return widthScale(d[0]);}). + y(function (d) {return heightScale(d[1]);}); svg.select(".x.grid").call(xGrid); svg.select(".y.grid").call(yGrid); svg.select(".x.axis").call(xAxis); svg.select(".y.axis").call(yAxis); - var data = svg.select("g.data"); - var lines = data.selectAll("path").data(RX_plot_data, function(d, i) { return i; }); - var newLines = lines.enter().append("path").attr("class", "line"); + var data = svg.select("g.data"), + lines = data.selectAll("path").data(RX_plot_data, function (d, i) {return i;}), + newLines = lines.enter().append("path").attr("class", "line"); lines.attr('d', line); samples++; @@ -267,7 +267,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 () { MSP.send_message(MSP_codes.MSP_STATUS); }, 250, true); @@ -275,6 +275,6 @@ TABS.receiver.initialize = function(callback) { } }; -TABS.receiver.cleanup = function(callback) { +TABS.receiver.cleanup = function (callback) { if (callback) callback(); }; diff --git a/tabs/sensors.js b/tabs/sensors.js index 23319553..3dda5942 100644 --- a/tabs/sensors.js +++ b/tabs/sensors.js @@ -1,7 +1,7 @@ 'use strict'; TABS.sensors = {}; -TABS.sensors.initialize = function(callback) { +TABS.sensors.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'sensors'; googleAnalytics.sendAppView('Sensor Page'); @@ -88,17 +88,17 @@ TABS.sensors.initialize = function(callback) { .scale(helpers.widthScale) .ticks(5) .orient("bottom") - .tickFormat(function(d) {return d;}); + .tickFormat(function (d) {return d;}); helpers.yAxis = d3.svg.axis() .scale(helpers.heightScale) .ticks(5) .orient("left") - .tickFormat(function(d) {return d;}); + .tickFormat(function (d) {return d;}); helpers.line = d3.svg.line() - .x(function(d) { return helpers.widthScale(d[0]); }) - .y(function(d) { return helpers.heightScale(d[1]); }); + .x(function (d) {return helpers.widthScale(d[0]);}) + .y(function (d) {return helpers.heightScale(d[1]);}); return helpers; } @@ -108,7 +108,7 @@ TABS.sensors.initialize = function(callback) { if (graphHelpers.dynamicHeightDomain) { var limits = []; - $.each(data, function(idx, datum) { + $.each(data, function (idx, datum) { limits.push(datum.min); limits.push(datum.max); }); @@ -122,7 +122,7 @@ TABS.sensors.initialize = function(callback) { svg.select(".y.axis").call(graphHelpers.yAxis); var group = svg.select("g.data"); - var lines = group.selectAll("path").data(data, function(d, i) { return i; }); + var lines = group.selectAll("path").data(data, function (d, i) {return i;}); var newLines = lines.enter().append("path").attr("class", "line"); lines.attr('d', graphHelpers.line); } @@ -180,7 +180,7 @@ TABS.sensors.initialize = function(callback) { checkboxes.eq(2).prop('disabled', true); } - $('.tab-sensors .info .checkboxes input').change(function() { + $('.tab-sensors .info .checkboxes input').change(function () { var enable = $(this).prop('checked'); var index = $(this).parent().index(); @@ -203,7 +203,7 @@ TABS.sensors.initialize = function(callback) { } var checkboxes = []; - $('.tab-sensors .info .checkboxes input').each(function() { + $('.tab-sensors .info .checkboxes input').each(function () { checkboxes.push($(this).prop('checked')); }); @@ -212,7 +212,7 @@ TABS.sensors.initialize = function(callback) { chrome.storage.local.set({'graphs_enabled': checkboxes}); }); - chrome.storage.local.get('graphs_enabled', function(result) { + chrome.storage.local.get('graphs_enabled', function (result) { if (result.graphs_enabled) { var checkboxes = $('.tab-sensors .info .checkboxes input'); for (var i = 0; i < result.graphs_enabled.length; i++) { @@ -227,17 +227,16 @@ TABS.sensors.initialize = function(callback) { initSensorData(); // Setup variables - var samples_gyro_i = 0; - var samples_accel_i = 0; - var samples_mag_i = 0; - var samples_baro_i = 0; - var samples_debug_i = 0; - - var gyro_data = initDataArray(3); - var accel_data = initDataArray(3); - var mag_data = initDataArray(3); - var baro_data = initDataArray(1); - var debug_data = [ + var samples_gyro_i = 0, + samples_accel_i = 0, + samples_mag_i = 0, + samples_baro_i = 0, + samples_debug_i = 0, + gyro_data = initDataArray(3), + accel_data = initDataArray(3), + mag_data = initDataArray(3), + baro_data = initDataArray(1), + debug_data = [ initDataArray(1), initDataArray(1), initDataArray(1), @@ -260,7 +259,7 @@ TABS.sensors.initialize = function(callback) { y: [], z: [], }; - $('.plot_control .x, .plot_control .y, .plot_control .z').each(function() { + $('.plot_control .x, .plot_control .y, .plot_control .z').each(function () { var el = $(this); if (el.hasClass('x')) { raw_data_text_ements.x.push(el); @@ -272,7 +271,7 @@ TABS.sensors.initialize = function(callback) { }); // set refresh speeds according to configuration saved in storage - chrome.storage.local.get('sensor_settings', function(result) { + chrome.storage.local.get('sensor_settings', function (result) { if (result.sensor_settings) { $('.tab-sensors select[name="gyro_refresh_rate"]').val(result.sensor_settings.rates.gyro); $('.tab-sensors select[name="gyro_scale"]').val(result.sensor_settings.scales.gyro); @@ -294,7 +293,7 @@ TABS.sensors.initialize = function(callback) { } }); - $('.tab-sensors .rate select, .tab-sensors .scale select').change(function() { + $('.tab-sensors .rate select, .tab-sensors .scale select').change(function () { // if any of the select fields change value, all of the select values are grabbed // and timers are re-initialized with the new settings var rates = { @@ -327,7 +326,7 @@ TABS.sensors.initialize = function(callback) { // fetch currently enabled plots var checkboxes = []; - $('.tab-sensors .info .checkboxes input').each(function() { + $('.tab-sensors .info .checkboxes input').each(function () { checkboxes.push($(this).prop('checked')); }); @@ -406,7 +405,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 () { MSP.send_message(MSP_codes.MSP_STATUS); }, 250, true); @@ -414,7 +413,7 @@ TABS.sensors.initialize = function(callback) { }); }; -TABS.sensors.cleanup = function(callback) { +TABS.sensors.cleanup = function (callback) { serial.empty_output_buffer(); if (callback) callback(); diff --git a/tabs/servos.js b/tabs/servos.js index eda42891..d1bc55ed 100644 --- a/tabs/servos.js +++ b/tabs/servos.js @@ -7,7 +7,7 @@ 'use strict'; TABS.servos = {}; -TABS.servos.initialize = function(callback) { +TABS.servos.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'servos'; googleAnalytics.sendAppView('Servos'); @@ -111,7 +111,7 @@ TABS.servos.initialize = function(callback) { $('div.tab-servos table.fields tr:last').data('info', {'obj': obj}); // UI hooks - $('div.tab-servos table.fields tr:last td.channel input').click(function() { + $('div.tab-servos table.fields tr:last td.channel input').click(function () { if($(this).is(':checked')) { $(this).parent().parent().find('td.middle input').prop('disabled', true); $(this).parent().parent().find('.channel input').not($(this)).prop('checked', false); @@ -123,7 +123,7 @@ TABS.servos.initialize = function(callback) { function servos_update(save_to_eeprom) { // update bitfields - $('div.tab-servos table.directions tr:not(".main")').each(function() { + $('div.tab-servos table.directions tr:not(".main")').each(function () { var info = $('select', this).data('info'); var val = parseInt($('select', this).val()); @@ -133,7 +133,7 @@ TABS.servos.initialize = function(callback) { }); // update the rest - $('div.tab-servos table.fields tr:not(".main")').each(function() { + $('div.tab-servos table.fields tr:not(".main")').each(function () { var info = $(this).data('info'); if ($('.middle input', this).is(':disabled')) { @@ -182,7 +182,7 @@ TABS.servos.initialize = function(callback) { if (save_to_eeprom) { // Save changes to EEPROM - MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function() { + MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () { GUI.log(chrome.i18n.getMessage('servosEepromSave')); }); } @@ -280,14 +280,14 @@ TABS.servos.initialize = function(callback) { } // UI hooks for dynamically generated elements - $('table.directions select, table.directions input, table.fields select, table.fields input').change(function() { + $('table.directions select, table.directions input, table.fields select, table.fields input').change(function () { if ($('div.live input').is(':checked')) { // apply small delay as there seems to be some funky update business going wrong GUI.timeout_add('servos_update', servos_update, 10); } }); - $('a.update').click(function() { + $('a.update').click(function () { // standard check for supported_models + custom implementation for feature servo_tilt if (supported_models.indexOf(CONFIG.multiType) != -1 || AUX_CONFIG.indexOf('CAMSTAB') > -1 || AUX_CONFIG.indexOf('CAMTRIG') > -1) { servos_update(true); @@ -295,7 +295,7 @@ TABS.servos.initialize = function(callback) { }); // status data pulled via separate timer with static speed - GUI.interval_add('status_pull', function() { + GUI.interval_add('status_pull', function () { MSP.send_message(MSP_codes.MSP_STATUS); }, 250, true); @@ -303,6 +303,6 @@ TABS.servos.initialize = function(callback) { } }; -TABS.servos.cleanup = function(callback) { +TABS.servos.cleanup = function (callback) { if (callback) callback(); }; \ No newline at end of file From d36d0af270504665b878db067ea23d5758aed064 Mon Sep 17 00:00:00 2001 From: cTn Date: Wed, 13 Aug 2014 13:12:39 +0200 Subject: [PATCH 25/54] polish --- js/port_handler.js | 22 +++++++++++----------- main.css | 1 - 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/js/port_handler.js b/js/port_handler.js index c77aef1a..c652568f 100644 --- a/js/port_handler.js +++ b/js/port_handler.js @@ -8,12 +8,12 @@ function port_handler() { this.port_removed_callbacks = []; } -port_handler.prototype.initialize = function() { +port_handler.prototype.initialize = function () { // start listening, check after 250ms this.check(); }; -port_handler.prototype.check = function() { +port_handler.prototype.check = function () { var self = this; serial.getDevices(function(current_ports) { @@ -60,7 +60,7 @@ port_handler.prototype.check = function() { // auto-select last used port (only during initialization) if (!self.initial_ports) { - chrome.storage.local.get('last_used_port', function(result) { + chrome.storage.local.get('last_used_port', function (result) { // if last_used_port was set, we try to select it if (result.last_used_port) { current_ports.forEach(function(port) { @@ -109,7 +109,7 @@ port_handler.prototype.check = function() { if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to) { // we need firmware flasher protection over here if (GUI.active_tab != 'firmware_flasher') { - GUI.timeout_add('auto-connect_timeout', function() { + 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 } @@ -137,13 +137,13 @@ port_handler.prototype.check = function() { check_usb_devices(); } - self.main_timeout_reference = setTimeout(function() { + self.main_timeout_reference = setTimeout(function () { self.check(); }, 250); }); function check_usb_devices() { - chrome.usb.getDevices(usbDevices.STM32DFU, function(result) { + chrome.usb.getDevices(usbDevices.STM32DFU, function (result) { if (result.length) { if (!$("div#port-picker #port [value='DFU']").length) { $('div#port-picker #port').append(''); @@ -158,7 +158,7 @@ port_handler.prototype.check = function() { } }; -port_handler.prototype.update_port_select = function(ports) { +port_handler.prototype.update_port_select = function (ports) { $('div#port-picker #port').html(''); // drop previous one if (ports.length > 0) { @@ -195,12 +195,12 @@ port_handler.prototype.port_detected = function(name, code, timeout, ignore_time return obj; }; -port_handler.prototype.port_removed = function(name, code, timeout, ignore_timeout) { +port_handler.prototype.port_removed = function (name, code, timeout, ignore_timeout) { var self = this; var obj = {'name': name, 'code': code, 'timeout': (timeout) ? timeout : 10000}; if (!ignore_timeout) { - obj.timer = setTimeout(function() { + obj.timer = setTimeout(function () { console.log('PortHandler - timeout - ' + obj.name); // trigger callback @@ -221,7 +221,7 @@ port_handler.prototype.port_removed = function(name, code, timeout, ignore_timeo }; // accepting single level array with "value" as key -port_handler.prototype.array_difference = function(firstArray, secondArray) { +port_handler.prototype.array_difference = function (firstArray, secondArray) { var cloneArray = []; // create hardcopy @@ -238,7 +238,7 @@ port_handler.prototype.array_difference = function(firstArray, secondArray) { return cloneArray; }; -port_handler.prototype.flush_callbacks = function() { +port_handler.prototype.flush_callbacks = function () { var killed = 0; for (var i = this.port_detected_callbacks.length - 1; i >= 0; i--) { diff --git a/main.css b/main.css index 00ea28fa..7fd7d071 100644 --- a/main.css +++ b/main.css @@ -12,7 +12,6 @@ body { font-family: sans-serif; font-size: 12px; color: #303030; - -webkit-text-size-adjust: 100%; background-color: #dfddd0; } a { From 4bd113f28f6b2a3bb7e96a8a6ad9fae5a51e1224 Mon Sep 17 00:00:00 2001 From: cTn Date: Wed, 13 Aug 2014 13:29:55 +0200 Subject: [PATCH 26/54] dumb down port handler implementation --- js/port_handler.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/js/port_handler.js b/js/port_handler.js index c652568f..8ac763fa 100644 --- a/js/port_handler.js +++ b/js/port_handler.js @@ -1,6 +1,6 @@ 'use strict'; -function port_handler() { +var PortHandler = new function () { this.main_timeout_reference; this.initial_ports = false; @@ -8,12 +8,12 @@ function port_handler() { this.port_removed_callbacks = []; } -port_handler.prototype.initialize = function () { +PortHandler.initialize = function () { // start listening, check after 250ms this.check(); }; -port_handler.prototype.check = function () { +PortHandler.check = function () { var self = this; serial.getDevices(function(current_ports) { @@ -158,7 +158,7 @@ port_handler.prototype.check = function () { } }; -port_handler.prototype.update_port_select = function (ports) { +PortHandler.update_port_select = function (ports) { $('div#port-picker #port').html(''); // drop previous one if (ports.length > 0) { @@ -170,7 +170,7 @@ port_handler.prototype.update_port_select = function (ports) { } }; -port_handler.prototype.port_detected = function(name, code, timeout, ignore_timeout) { +PortHandler.port_detected = function(name, code, timeout, ignore_timeout) { var self = this; var obj = {'name': name, 'code': code, 'timeout': (timeout) ? timeout : 10000}; @@ -195,7 +195,7 @@ port_handler.prototype.port_detected = function(name, code, timeout, ignore_time return obj; }; -port_handler.prototype.port_removed = function (name, code, timeout, ignore_timeout) { +PortHandler.port_removed = function (name, code, timeout, ignore_timeout) { var self = this; var obj = {'name': name, 'code': code, 'timeout': (timeout) ? timeout : 10000}; @@ -221,7 +221,7 @@ port_handler.prototype.port_removed = function (name, code, timeout, ignore_time }; // accepting single level array with "value" as key -port_handler.prototype.array_difference = function (firstArray, secondArray) { +PortHandler.array_difference = function (firstArray, secondArray) { var cloneArray = []; // create hardcopy @@ -238,7 +238,7 @@ port_handler.prototype.array_difference = function (firstArray, secondArray) { return cloneArray; }; -port_handler.prototype.flush_callbacks = function () { +PortHandler.flush_callbacks = function () { var killed = 0; for (var i = this.port_detected_callbacks.length - 1; i >= 0; i--) { @@ -256,6 +256,4 @@ port_handler.prototype.flush_callbacks = function () { } return killed; -}; - -var PortHandler = new port_handler(); \ No newline at end of file +}; \ No newline at end of file From 6138c06fa4ddbb52f2ecf4bd8c8e96f00f0622d0 Mon Sep 17 00:00:00 2001 From: cTn Date: Thu, 14 Aug 2014 15:49:26 +0200 Subject: [PATCH 27/54] updating analytics --- js/libraries/google-analytics-bundle.js | 141 ++++++++++++------------ 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/js/libraries/google-analytics-bundle.js b/js/libraries/google-analytics-bundle.js index 7b4fa909..ab4e495d 100644 --- a/js/libraries/google-analytics-bundle.js +++ b/js/libraries/google-analytics-bundle.js @@ -1,77 +1,78 @@ (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(2b?1:0};var v=Array.prototype,ja=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(;cb?null:n(a)?a.charAt(b):a[b]},oa=function(a,b){var c=ja(a,b),d;(d=0<=c)&&v.splice.call(a,c,1);return d},pa=function(a){return v.concat.apply(v,arguments)};var qa="StopIteration"in k?k.StopIteration:Error("StopIteration"),ra=function(){};ra.prototype.next=function(){throw qa;};ra.prototype.$b=function(){return this};var sa=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)},ta=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},ua=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b},va=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]},wa="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),xa=function(a,b){for(var c,d,e=1;e2*this.g&&ya(this),!0):!1};var ya=function(a){if(a.g!=a.b.length){for(var b=0,c=0;b=c.length)throw qa;var g=c[b++];return a?g:d[g]}};return g};var x=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var za={id:"hitType",name:"t",valueType:"text",maxLength:void 0,defaultValue:void 0},Aa={id:"sessionControl",name:"sc",valueType:"text",maxLength:void 0,defaultValue:void 0},Ba={id:"description",name:"cd",valueType:"text",maxLength:2048,defaultValue:void 0},Ca={Pc:za,pc:{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},vc:{id:"cacheBuster",name:"z",valueType:"text",maxLength:void 0, -defaultValue:void 0},gd:Aa,xd:{id:"userId",name:"uid",valueType:"text",maxLength:void 0,defaultValue:void 0},Yc:{id:"nonInteraction",name:"ni",valueType:"boolean",maxLength:void 0,defaultValue:void 0},Fc:Ba,qd:{id:"title",name:"dt",valueType:"text",maxLength:1500,defaultValue:void 0},Gc:{id:"dimension",name:"cd[1-9][0-9]*",valueType:"text",maxLength:150,defaultValue:void 0},Xc:{id:"metric",name:"cm[1-9][0-9]*",valueType:"integer",maxLength:void 0,defaultValue:void 0},rc:{id:"appId",name:"aid",valueType:"text", -maxLength:150,defaultValue:void 0},sc:{id:"appInstallerId",name:"aiid",valueType:"text",maxLength:150,defaultValue:void 0},Jc:{id:"eventCategory",name:"ec",valueType:"text",maxLength:150,defaultValue:void 0},Ic:{id:"eventAction",name:"ea",valueType:"text",maxLength:500,defaultValue:void 0},Kc:{id:"eventLabel",name:"el",valueType:"text",maxLength:500,defaultValue:void 0},Lc:{id:"eventValue",name:"ev",valueType:"integer",maxLength:void 0,defaultValue:void 0},jd:{id:"socialNetwork",name:"sn",valueType:"text", -maxLength:50,defaultValue:void 0},hd:{id:"socialAction",name:"sa",valueType:"text",maxLength:50,defaultValue:void 0},kd:{id:"socialTarget",name:"st",valueType:"text",maxLength:2048,defaultValue:void 0},td:{id:"transactionId",name:"ti",valueType:"text",maxLength:500,defaultValue:void 0},sd:{id:"transactionAffiliation",name:"ta",valueType:"text",maxLength:500,defaultValue:void 0},ud:{id:"transactionRevenue",name:"tr",valueType:"currency",maxLength:void 0,defaultValue:void 0},vd:{id:"transactionShipping", -name:"ts",valueType:"currency",maxLength:void 0,defaultValue:void 0},wd:{id:"transactionTax",name:"tt",valueType:"currency",maxLength:void 0,defaultValue:void 0},Dc:{id:"currencyCode",name:"cu",valueType:"text",maxLength:10,defaultValue:void 0},Tc:{id:"itemPrice",name:"ip",valueType:"currency",maxLength:void 0,defaultValue:void 0},Uc:{id:"itemQuantity",name:"iq",valueType:"integer",maxLength:void 0,defaultValue:void 0},Rc:{id:"itemCode",name:"ic",valueType:"text",maxLength:500,defaultValue:void 0}, -Sc:{id:"itemName",name:"in",valueType:"text",maxLength:500,defaultValue:void 0},Qc:{id:"itemCategory",name:"iv",valueType:"text",maxLength:500,defaultValue:void 0},Bc:{id:"campaignSource",name:"cs",valueType:"text",maxLength:100,defaultValue:void 0},zc:{id:"campaignMedium",name:"cm",valueType:"text",maxLength:50,defaultValue:void 0},Ac:{id:"campaignName",name:"cn",valueType:"text",maxLength:100,defaultValue:void 0},yc:{id:"campaignKeyword",name:"ck",valueType:"text",maxLength:500,defaultValue:void 0}, -wc:{id:"campaignContent",name:"cc",valueType:"text",maxLength:500,defaultValue:void 0},xc:{id:"campaignId",name:"ci",valueType:"text",maxLength:100,defaultValue:void 0},Oc:{id:"gclid",name:"gclid",valueType:"text",maxLength:void 0,defaultValue:void 0},Ec:{id:"dclid",name:"dclid",valueType:"text",maxLength:void 0,defaultValue:void 0},$c:{id:"pageLoadTime",name:"plt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Hc:{id:"dnsTime",name:"dns",valueType:"integer",maxLength:void 0,defaultValue:void 0}, -ld:{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},Zc:{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},md:{id:"timingCategory",name:"utc",valueType:"text",maxLength:150,defaultValue:void 0},pd:{id:"timingVar",name:"utv", -valueType:"text",maxLength:500,defaultValue:void 0},od:{id:"timingValue",name:"utt",valueType:"integer",maxLength:void 0,defaultValue:void 0},nd:{id:"timingLabel",name:"utl",valueType:"text",maxLength:500,defaultValue:void 0},Mc:{id:"exDescription",name:"exd",valueType:"text",maxLength:150,defaultValue:void 0},Nc:{id:"exFatal",name:"exf",valueType:"boolean",maxLength:void 0,defaultValue:"1"}};var Da=function(a,b){this.width=a;this.height=b};Da.prototype.clone=function(){return new Da(this.width,this.height)};Da.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};var y;t:{var Ea=k.navigator;if(Ea){var Fa=Ea.userAgent;if(Fa){y=Fa;break t}}y=""}var z=function(a){return-1!=y.indexOf(a)};var Ga=z("Opera")||z("OPR"),A=z("Trident")||z("MSIE"),B=z("Gecko")&&-1==y.toLowerCase().indexOf("webkit")&&!(z("Trident")||z("MSIE")),C=-1!=y.toLowerCase().indexOf("webkit"),Ha=function(){var a=k.document;return a?a.documentMode:void 0},Ia=function(){var a="",b;if(Ga&&k.opera)return a=k.opera.version,p(a)?a():a;B?b=/rv\:([^\);]+)(\)|;)/:A?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:C&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(y))?a[1]:"");return A&&(b=Ha(),b>parseFloat(a))?String(b):a}(),Ja={},D=function(a){var b; -if(!(b=Ja[a])){b=0;for(var c=String(Ia).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=a.keyCode)a.keyCode=-1}catch(b){}};G.prototype.j=function(){};var Ta="closure_listenable_"+(1E6*Math.random()|0),Ua=function(a){return!(!a||!a[Ta])},Va=0;var Wa=function(a,b,c,d,e){this.K=a;this.proxy=null;this.src=b;this.type=c;this.ga=!!d;this.ia=e;this.key=++Va;this.removed=this.ha=!1},Xa=function(a){a.removed=!0;a.K=null;a.proxy=null;a.src=null;a.ia=null};var H=function(a){this.src=a;this.h={};this.T=0};H.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.h[f];a||(a=this.h[f]=[],this.T++);var g=Ya(a,b,d,e);-1e.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.N&&0<=l;l--)c.currentTarget=e[l],d&=nb(e[l],f,!0,c);for(l=0;!c.N&&l>>0),db=function(a){if(p(a))return a;a[ob]||(a[ob]=function(b){return a.handleEvent(b)});return a[ob]};var J=function(){this.v=new H(this);this.Lb=this;this.Fa=null};t(J,Ma);J.prototype[Ta]=!0;h=J.prototype;h.addEventListener=function(a,b,c,d){cb(this,a,b,c,d)};h.removeEventListener=function(a,b,c,d){kb(this,a,b,c,d)}; -h.dispatchEvent=function(a){var b,c=this.Fa;if(c){b=[];for(var d=1;c;c=c.Fa)b.push(c),++d}c=this.Lb;d=a.type||a;if(n(a))a=new E(a,c);else if(a instanceof E)a.target=a.target||c;else{var e=a;a=new E(d,c);xa(a,e)}var e=!0,f;if(b)for(var g=b.length-1;!a.N&&0<=g;g--)f=a.currentTarget=b[g],e=pb(f,d,!0,a)&&e;a.N||(f=a.currentTarget=c,e=pb(f,d,!0,a)&&e,a.N||(e=pb(f,d,!1,a)&&e));if(b)for(g=0;!a.N&&gb?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(;cb?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;eparseFloat(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=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);-1e.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>>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&&g2*this.g&&kb(this),!0):!1};var kb=function(a){if(a.g!=a.b.length){for(var b=0,c=0;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=b.va&&b.cancel())}this.Ta?this.Ta.call(this.Sa,this):this.xa=!0;this.G||this.t(new Nb)}};O.prototype.Ua=function(a,b){this.wa=!1;Ob(this,a,b)}; -var Ob=function(a,b,c){a.G=!0;a.r=c;a.P=!b;Pb(a)},Sb=function(a){if(a.G){if(!a.xa)throw new Rb;a.xa=!1}};O.prototype.C=function(a){Sb(this);Ob(this,!0,a)};O.prototype.t=function(a){Sb(this);Ob(this,!1,a)};O.prototype.F=function(a,b){return P(this,a,null,b)};var P=function(a,b,c,d){a.ba.push([b,c,d]);a.G&&Pb(a);return a};O.prototype.then=function(a,b,c){var d,e,f=new N(function(a,b){d=a;e=b});P(this,d,function(a){a instanceof Nb?f.cancel():e(a)});return f.then(a,b,c)};Cb(O); -var Tb=function(a){var b=new O;P(a,b.C,b.t,b);return b},Ub=function(a){return la(a.ba,function(a){return p(a[1])})},Pb=function(a){if(a.ca&&a.G&&Ub(a)){var b=a.ca,c=Vb[b];c&&(k.clearTimeout(c.da),delete Vb[b]);a.ca=0}a.n&&(a.n.va--,delete a.n);for(var b=a.r,d=c=!1;a.ba.length&&!a.wa;){var e=a.ba.shift(),f=e[0],g=e[1],e=e[2];if(f=a.P?g:f)try{var l=f.call(e||a.Sa,b);void 0!==l&&(a.P=a.P&&(l==b||l instanceof Error),a.r=b=l);Db(b)&&(d=!0,a.wa=!0)}catch(I){b=I,a.P=!0,Ub(a)||(c=!0)}}a.r=b;d&&(l=q(a.Ua, -a,!0),d=q(a.Ua,a,!1),b instanceof O?(P(b,l,d),b.tb=!0):b.then(l,d));c&&(b=new Wb(b),Vb[b.da]=b,a.ca=b.da)},Xb=function(a){var b=new O;b.C(a);return b},Zb=function(){var a=Yb,b=new O;b.t(a);return b},Rb=function(){u.call(this)};t(Rb,u);Rb.prototype.message="Deferred has already fired";Rb.prototype.name="AlreadyCalledError";var Nb=function(){u.call(this)};t(Nb,u);Nb.prototype.message="Deferred was canceled";Nb.prototype.name="CanceledError"; -var Wb=function(a){this.da=k.setTimeout(q(this.Ub,this),0);this.aa=a};Wb.prototype.Ub=function(){delete Vb[this.da];throw this.aa;};var Vb={};var $b=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,I,F,S,T){if("%"==F)return"%";var Qb=c.shift();if("undefined"==typeof Qb)throw Error("[goog.string.format] Not enough arguments");arguments[0]=Qb;return Q[F].apply(null,arguments)})},Q={s:function(a,b,c){return isNaN(c)||""==c||a.length>=c?a:a=-1a?"-":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 Q.f(parseInt(a,10),b,c,d,0,f,g,l)}};Q.i=Q.d; -Q.u=Q.d;var ac=function(a){if("function"==typeof a.q)return a.q();if(n(a))return a.split("");if(da(a)){for(var b=[],c=a.length,d=0;db.maxLength&&a.set(b,c.substring(0,b.maxLength))})},vc=function(a){cc(a,function(b,c){void 0!==b.defaultValue&&c==b.defaultValue&&a.remove(b)})};var Yb={status:"device-offline",qa:void 0},wc={status:"rate-limited",qa:void 0},xc={status:"sampled-out",qa:void 0},yc={status:"sent",qa:void 0};var zc=function(a,b){this.Eb=a;this.w=b};zc.prototype.send=function(a,b){var c;c=this.Eb;var d=c.ab(),e=Math.floor((d-c.$a)*c.Bb);0c.U?c=!1:(c.U-=1,c=!0);return c||"item"==a||"transaction"==a?this.w.send(a,b):Xb(wc)};var Ac=function(a){this.Wb=a};Ac.prototype.send=function(a,b){this.Wb.push({zb:a,Ab:b});return Xb()};var Bc=function(a,b,c){this.k=a;this.la=[];this.J={enabled:new Ac(this.la),disabled:c};this.R=this.J.enabled;P(Tb(this.k.ya),ha(this.yb,b),this.xb,this)};Bc.prototype.yb=function(a){this.J.enabled=a(this.k);Cc(this);ka(this.la,function(a){this.send(a.zb,a.Ab)},this);this.la=null;Dc(this.k,q(this.Db,this))};Bc.prototype.xb=function(){this.R=this.J.enabled=this.J.disabled;this.la=null};Bc.prototype.send=function(a,b){return this.R.send(a,b)};var Cc=function(a){a.R=a.k.pa()?a.J.enabled:a.J.disabled}; -Bc.prototype.Db=function(a){switch(a){case "analytics.tracking-permitted":Cc(this)}};var W=function(a,b){this.R=a;this.Ma=b;this.kb=new R;this.Na=!1};h=W.prototype;h.set=function(a,b){var c=qc(a);this.kb.set(c,b)};h.send=function(a,b){var c=this.kb.clone();b&&sa(b,function(a,b){null!=a&&c.set(qc(b),a)},this);this.Na&&(this.Na=!1,c.set(Aa,"start"));return this.R.send(a,c)};h.hc=function(a){var b={description:a};this.set(Ba,a);return this.send("appview",b)};h.ic=function(a,b,c,d){return this.send("event",{eventCategory:a,eventAction:b,eventLabel:c,eventValue:d})}; -h.kc=function(a,b,c){return this.send("social",{socialNetwork:a,socialAction:b,socialTarget:c})};h.jc=function(a,b){return this.send("exception",{exDescription:a,exFatal:b})};h.jb=function(a,b,c,d,e){return this.send("timing",{timingCategory:a,timingVar:b,timingLabel:d,timingValue:c,sampleRateOverride:e})};h.bc=function(){this.Na=!0};h.nc=function(a,b,c,d){return new Ec(this,a,b,c,d)};h.dc=function(){return this.Ma}; -var Ec=function(a,b,c,d,e){this.ib=a;this.Hb=b;this.Kb=c;this.Ib=d;this.O=e;this.Jb=r()};Ec.prototype.send=function(){var a=this.ib.jb(this.Hb,this.Kb,r()-this.Jb,this.Ib,this.O);this.ib=null;return a};var Fc=function(){this.U=60;this.Cb=500;this.Bb=5E-4;this.ab=function(){return(new Date).getTime()};this.$a=this.ab()};var Gc=function(a,b){this.k=a;this.w=b};Gc.prototype.send=function(a,b){var c=b.get(gc),c=parseInt(c.split("-")[1],16),d;"timing"!=a?d=this.k.O:((d=b.get(jc))&&b.remove(jc),d||(d=this.k.O));return c<655.36*d?this.w.send(a,b):Xb(xc)};var Hc=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/,Ic=C,Jc=function(a,b){if(Ic){Ic=!1;var c=k.location;if(c){var d=c.href;if(d&&(d=(d=Jc(3,d))&&decodeURIComponent(d))&&d!=c.hostname)throw Ic=!0,Error();}}return b.match(Hc)[a]||null};var Kc=function(){};Kc.prototype.nb=null;var Mc=function(a){var b;(b=a.nb)||(b={},Lc(a)&&(b[0]=!0,b[1]=!0),b=a.nb=b);return b};var Nc,Oc=function(){};t(Oc,Kc);var Pc=function(a){return(a=Lc(a))?new ActiveXObject(a):new XMLHttpRequest},Lc=function(a){if(!a.pb&&"undefined"==typeof XMLHttpRequest&&"undefined"!=typeof ActiveXObject){for(var b=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],c=0;cthis.fb?c.t({status:"payload-too-big",qa:$b("Encoded hit length == %s, but should be <= %s.",d.length,this.fb)}):Tc(this.Gb,function(){c.C(yc)},d);return c};var cd=function(a,b){var c=new ad;c.add(za.name,a);cc(b,function(a,b){c.add(a.name,b.toString())});return c.toString()};var dd=function(a,b,c,d){this.Qb=a;this.Ob=b;this.Pb=c;this.k=d},ed;dd.prototype.gc=function(a){var b=new J,b=new W(fd(this,b),b);b.set(ic,this.Qb);b.set(dc,1);b.set(ec,this.Ob);b.set(fc,this.Pb);b.set(mc,a);a=window.navigator.language;b.set(hc,a);a=screen.colorDepth+"-bit";b.set(kc,a);a=[screen.width,screen.height].join("x");b.set(lc,a);a=window.document;a="CSS1Compat"==a.compatMode?a.documentElement:a.body;a=new Da(a.clientWidth,a.clientHeight);a=[a.width,a.height].join("x");b.set(nc,a);return b}; -var fd=function(a,b){return new Bc(a.k,function(a){if(!ed){new L;var d=new tc(new bd("https://www.google-analytics.com/collect",8192)),e=new Fc;ed=new rc(a,new Gc(a,new zc(e,d)))}return new sc(b,ed)},U.Sb())};dd.prototype.cc=function(){return Tb(this.k.ya)};var gd=function(a,b,c,d,e,f){O.call(this,e,f);this.Ca=a;this.Da=[];this.Xa=!!b;this.vb=!!c;this.ub=!!d;for(b=this.Ya=0;b=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=-1a?"-":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;db.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);0c.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;cthis.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)}); })() From d3d933a704efef0a78395f8a2de70b4fee6e1293 Mon Sep 17 00:00:00 2001 From: cTn Date: Thu, 14 Aug 2014 16:23:08 +0200 Subject: [PATCH 28/54] experimenting with some undefined comparators in strict mode --- eventPage.js | 4 +++- js/serial_backend.js | 2 +- main.js | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/eventPage.js b/eventPage.js index 2d4d7b62..5f97f1c3 100644 --- a/eventPage.js +++ b/eventPage.js @@ -10,6 +10,8 @@ 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() { chrome.app.window.create('main.html', { id: 'main-window', @@ -79,7 +81,7 @@ chrome.runtime.onInstalled.addListener(function (details) { // only fire up notification sequence when one of the major version numbers changed if (currentVersionArr[0] != previousVersionArr[0] || currentVersionArr[1] != previousVersionArr[1]) { chrome.storage.local.get('update_notify', function (result) { - if (typeof result.update_notify === 'undefined' || result.update_notify) { + if (!result.update_notify || result.update_notify) { var manifest = chrome.runtime.getManifest(); var options = { priority: 0, diff --git a/js/serial_backend.js b/js/serial_backend.js index bb3bd090..fcabefbe 100644 --- a/js/serial_backend.js +++ b/js/serial_backend.js @@ -193,7 +193,7 @@ function read_serial(info) { function sensor_status(sensors_detected) { // initialize variable (if it wasn't) - if (sensor_status.previous_sensors_detected === 'undefined') { + if (!sensor_status.previous_sensors_detected) { sensor_status.previous_sensors_detected = 0; } diff --git a/main.js b/main.js index a6fde8b8..4fa29d3b 100644 --- a/main.js +++ b/main.js @@ -129,7 +129,7 @@ $(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 (!result.update_notify || result.update_notify) { $('div.notifications input').prop('checked', true); } }); From 468d7f57c809305ea7a86883a1ea6ffd63b60d84 Mon Sep 17 00:00:00 2001 From: cTn Date: Thu, 14 Aug 2014 16:40:55 +0200 Subject: [PATCH 29/54] fix graph initialization on cold start --- tabs/sensors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tabs/sensors.js b/tabs/sensors.js index 3dda5942..5bdcf2b4 100644 --- a/tabs/sensors.js +++ b/tabs/sensors.js @@ -219,7 +219,7 @@ TABS.sensors.initialize = function (callback) { checkboxes.eq(i).not(':disabled').prop('checked', result.graphs_enabled[i]).change(); } } else { - $('.tab-sensors .info input:lt(4)').prop('checked', true).change(); + $('.tab-sensors .info input:lt(4):not(:disabled)').prop('checked', true).change(); } }); From dbf528345e883c03a47e5d699d7f1b12d1ccfac6 Mon Sep 17 00:00:00 2001 From: cTn Date: Thu, 14 Aug 2014 16:41:49 +0200 Subject: [PATCH 30/54] another run on undefined comparators --- js/gui.js | 4 ++-- js/msp.js | 4 ++-- js/serial.js | 2 +- js/serial_backend.js | 20 ++++++++++---------- tabs/receiver.js | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/js/gui.js b/js/gui.js index 788534fd..94829539 100644 --- a/js/gui.js +++ b/js/gui.js @@ -30,7 +30,7 @@ var GUI_control = function () { // interval = time interval in miliseconds // first = true/false if code should be ran initially before next timer interval hits GUI_control.prototype.interval_add = function (name, code, interval, first) { - var data = {'name': name, 'timer': undefined, 'code': code, 'interval': interval, 'fired': 0, 'paused': false}; + var data = {'name': name, 'timer': null, 'code': code, 'interval': interval, 'fired': 0, 'paused': false}; if (first == true) { code(); // execute code @@ -132,7 +132,7 @@ GUI_control.prototype.interval_kill_all = function (keep_array) { // timeout = timeout in miliseconds GUI_control.prototype.timeout_add = function (name, code, timeout) { var self = this; - var data = {'name': name, 'timer': undefined, 'timeout': timeout}; + var data = {'name': name, 'timer': null, 'timeout': timeout}; // start timer with "cleaning" callback data.timer = setTimeout(function() { diff --git a/js/msp.js b/js/msp.js index 8323d621..be8c8124 100644 --- a/js/msp.js +++ b/js/msp.js @@ -59,8 +59,8 @@ var MSP = { code: 0, message_length_expected: 0, message_length_received: 0, - message_buffer: undefined, - message_buffer_uint8_view: undefined, + message_buffer: null, + message_buffer_uint8_view: null, message_checksum: 0, callbacks: [], diff --git a/js/serial.js b/js/serial.js index cabac688..ade6c7ab 100644 --- a/js/serial.js +++ b/js/serial.js @@ -13,7 +13,7 @@ var serial = { var self = this; chrome.serial.connect(path, options, function(connectionInfo) { - if (connectionInfo !== undefined) { + if (connectionInfo) { self.connectionId = connectionInfo.connectionId; self.bitrate = connectionInfo.bitrate; self.bytes_received = 0; diff --git a/js/serial_backend.js b/js/serial_backend.js index fcabefbe..c2955fbf 100644 --- a/js/serial_backend.js +++ b/js/serial_backend.js @@ -1,7 +1,7 @@ 'use strict'; -$(document).ready(function() { - $('div#port-picker a.connect').click(function() { +$(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'); @@ -60,8 +60,8 @@ $(document).ready(function() { }); // auto-connect - chrome.storage.local.get('auto_connect', function(result) { - if (typeof result.auto_connect === 'undefined' || result.auto_connect) { + chrome.storage.local.get('auto_connect', function (result) { + if (!result.auto_connect || result.auto_connect) { // default or enabled by user GUI.auto_connect = true; @@ -78,7 +78,7 @@ $(document).ready(function() { } // bind UI hook to auto-connect checkbos - $('input.auto_connect').change(function() { + $('input.auto_connect').change(function () { GUI.auto_connect = $(this).is(':checked'); // update title/tooltip @@ -111,8 +111,8 @@ function onOpen(openInfo) { GUI.log(chrome.i18n.getMessage('serialPortOpened', [openInfo.connectionId])); // save selected port with chrome.storage if the port differs - chrome.storage.local.get('last_used_port', function(result) { - if (typeof result.last_used_port != 'undefined') { + chrome.storage.local.get('last_used_port', function (result) { + if (result.last_used_port) { if (result.last_used_port != GUI.connected_to) { // last used port doesn't match the one found in local db, we will store the new one chrome.storage.local.set({'last_used_port': GUI.connected_to}); @@ -127,7 +127,7 @@ function onOpen(openInfo) { if (!CONFIGURATOR.mspPassThrough) { // disconnect after 10 seconds with error if we don't get IDENT data - GUI.timeout_add('connecting', function() { + GUI.timeout_add('connecting', function () { if (!CONFIGURATOR.connectionValid) { GUI.log(chrome.i18n.getMessage('noConfigurationReceived')); @@ -136,9 +136,9 @@ function onOpen(openInfo) { }, 10000); // request configuration data - MSP.send_message(MSP_codes.MSP_UID, false, false, function() { + 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() { + 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])); diff --git a/tabs/receiver.js b/tabs/receiver.js index 2247693e..d34148e2 100644 --- a/tabs/receiver.js +++ b/tabs/receiver.js @@ -28,7 +28,7 @@ TABS.receiver.initialize = function (callback) { $('.tunings .rate input[name="expo"]').val(RC_tuning.RC_EXPO.toFixed(2)); chrome.storage.local.get('rx_refresh_rate', function (result) { - if (typeof result.rx_refresh_rate != 'undefined') { + if (result.rx_refresh_rate) { $('select[name="rx_refresh_rate"]').val(result.rx_refresh_rate).change(); } else { $('select[name="rx_refresh_rate"]').change(); // start with default value From d7810e1bb622588a50a8fc0f48280f153b6851ea Mon Sep 17 00:00:00 2001 From: cTn Date: Thu, 14 Aug 2014 16:48:16 +0200 Subject: [PATCH 31/54] make initial tab data request burst better comply with strict mode to prevent random race conditions --- tabs/auxiliary_configuration.js | 4 ++-- tabs/gps.js | 4 ++-- tabs/initial_setup.js | 4 ++-- tabs/motor_outputs.js | 4 ++-- tabs/pid_tuning.js | 6 +++--- tabs/receiver.js | 4 ++-- tabs/servos.js | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tabs/auxiliary_configuration.js b/tabs/auxiliary_configuration.js index 246d3743..1e928ac3 100644 --- a/tabs/auxiliary_configuration.js +++ b/tabs/auxiliary_configuration.js @@ -7,8 +7,6 @@ TABS.auxiliary_configuration.initialize = function (callback) { GUI.active_tab = 'auxiliary_configuration'; googleAnalytics.sendAppView('Auxiliary Configuration'); - MSP.send_message(MSP_codes.MSP_BOXNAMES, false, false, get_box_data); - function get_box_data() { MSP.send_message(MSP_codes.MSP_BOX, false, false, get_box_ids); } @@ -25,6 +23,8 @@ TABS.auxiliary_configuration.initialize = function (callback) { $('#content').load("./tabs/auxiliary_configuration.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'); diff --git a/tabs/gps.js b/tabs/gps.js index b84cb40c..7eb47de6 100644 --- a/tabs/gps.js +++ b/tabs/gps.js @@ -6,12 +6,12 @@ TABS.gps.initialize = function (callback) { GUI.active_tab = 'gps'; googleAnalytics.sendAppView('GPS Page'); - MSP.send_message(MSP_codes.MSP_RAW_GPS, false, false, load_html); - function load_html() { $('#content').load("./tabs/gps.html", process_html); } + MSP.send_message(MSP_codes.MSP_RAW_GPS, false, false, load_html); + function process_html() { // translate to user-selected language localize(); diff --git a/tabs/initial_setup.js b/tabs/initial_setup.js index b38ac895..01be7701 100644 --- a/tabs/initial_setup.js +++ b/tabs/initial_setup.js @@ -10,8 +10,6 @@ TABS.initial_setup.initialize = function (callback) { GUI.active_tab = 'initial_setup'; googleAnalytics.sendAppView('Initial Setup'); - MSP.send_message(MSP_codes.MSP_ACC_TRIM, false, false, load_ident); - function load_ident() { MSP.send_message(MSP_codes.MSP_IDENT, false, false, load_misc_data); } @@ -24,6 +22,8 @@ TABS.initial_setup.initialize = function (callback) { $('#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(); diff --git a/tabs/motor_outputs.js b/tabs/motor_outputs.js index f5d17228..2e26bc62 100644 --- a/tabs/motor_outputs.js +++ b/tabs/motor_outputs.js @@ -124,8 +124,6 @@ TABS.motor_outputs.initialize = function (callback) { lines.attr('d', graphHelpers.line); } - MSP.send_message(MSP_codes.MSP_MISC, false, false, get_motor_data); - function get_motor_data() { MSP.send_message(MSP_codes.MSP_MOTOR, false, false, load_html); } @@ -134,6 +132,8 @@ TABS.motor_outputs.initialize = function (callback) { $('#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(); diff --git a/tabs/pid_tuning.js b/tabs/pid_tuning.js index faf88bc3..ffd053c4 100644 --- a/tabs/pid_tuning.js +++ b/tabs/pid_tuning.js @@ -6,9 +6,6 @@ TABS.pid_tuning.initialize = function (callback) { GUI.active_tab = 'pid_tuning'; googleAnalytics.sendAppView('PID Tuning'); - // requesting MSP_STATUS manually because it contains CONFIG.profile - MSP.send_message(MSP_codes.MSP_STATUS, false, false, get_pid_names); - function get_pid_names() { MSP.send_message(MSP_codes.MSP_PIDNAMES, false, false, get_pid_data); } @@ -25,6 +22,9 @@ TABS.pid_tuning.initialize = function (callback) { $('#content').load("./tabs/pid_tuning.html", process_html); } + // requesting MSP_STATUS manually because it contains CONFIG.profile + MSP.send_message(MSP_codes.MSP_STATUS, false, false, get_pid_names); + function process_html() { // translate to user-selected language localize(); diff --git a/tabs/receiver.js b/tabs/receiver.js index d34148e2..9fab5def 100644 --- a/tabs/receiver.js +++ b/tabs/receiver.js @@ -6,8 +6,6 @@ TABS.receiver.initialize = function (callback) { GUI.active_tab = 'receiver'; googleAnalytics.sendAppView('Receiver Page'); - MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, get_rc_data); - function get_rc_data() { MSP.send_message(MSP_codes.MSP_RC, false, false, load_html); } @@ -16,6 +14,8 @@ TABS.receiver.initialize = function (callback) { $('#content').load("./tabs/receiver.html", process_html); } + MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, get_rc_data); + function process_html() { // translate to user-selected language localize(); diff --git a/tabs/servos.js b/tabs/servos.js index d1bc55ed..edd02d6d 100644 --- a/tabs/servos.js +++ b/tabs/servos.js @@ -12,8 +12,6 @@ TABS.servos.initialize = function (callback) { GUI.active_tab = 'servos'; googleAnalytics.sendAppView('Servos'); - MSP.send_message(MSP_codes.MSP_IDENT, false, false, get_servo_conf_data); - function get_servo_conf_data() { MSP.send_message(MSP_codes.MSP_SERVO_CONF, false, false, get_boxnames_data); } @@ -26,6 +24,8 @@ TABS.servos.initialize = function (callback) { $('#content').load("./tabs/servos.html", process_html); } + MSP.send_message(MSP_codes.MSP_IDENT, false, false, get_servo_conf_data); + function process_html() { // translate to user-selected language localize(); From cc8e53205dea211cf9ea6f406b2ac0562e478f2f Mon Sep 17 00:00:00 2001 From: cTn Date: Thu, 14 Aug 2014 17:00:32 +0200 Subject: [PATCH 32/54] fix style --- js/backup_restore.js | 10 +++-- js/protocols/stm32.js | 76 ++++++++++++++++++------------------ js/protocols/stm32usbdfu.js | 78 ++++++++++++++++++------------------- js/serial_backend.js | 2 +- 4 files changed, 84 insertions(+), 82 deletions(-) diff --git a/js/backup_restore.js b/js/backup_restore.js index 72cfaa8a..061aabe7 100644 --- a/js/backup_restore.js +++ b/js/backup_restore.js @@ -193,8 +193,9 @@ function configuration_upload() { // should be reworked in the future, so the same code won't be cloned over !!! // PID section - var PID_buffer_out = new Array(); - var PID_buffer_needle = 0; + var PID_buffer_out = new Array(), + PID_buffer_needle = 0; + for (var i = 0; i < PIDs.length; i++) { switch (i) { case 0: @@ -220,6 +221,7 @@ function configuration_upload() { PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2] * 1000); break; } + PID_buffer_needle += 3; } @@ -243,9 +245,9 @@ function configuration_upload() { function aux() { // AUX section - var AUX_val_buffer_out = new Array(); + var AUX_val_buffer_out = new Array(), + needle = 0; - var needle = 0; 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]); diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index abfa1422..1980cd15 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -7,7 +7,7 @@ */ 'use strict'; -var STM32_protocol = function() { +var STM32_protocol = function () { this.options = {}; this.hex; // ref this.verify_hex; @@ -47,7 +47,7 @@ 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) { var self = this; self.hex = hex; @@ -69,7 +69,7 @@ STM32_protocol.prototype.connect = function(port, baud, hex, options) { } if (self.options.no_reboot) { - serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function(openInfo) { + serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) { if (openInfo) { // we are connected, disabling connect button in the UI GUI.connect_lock = true; @@ -80,7 +80,7 @@ STM32_protocol.prototype.connect = function(port, baud, hex, options) { } }); } else { - serial.connect(port, {bitrate: self.options.reboot_baud}, function(openInfo) { + serial.connect(port, {bitrate: self.options.reboot_baud}, function (openInfo) { if (openInfo) { console.log('Sending ascii "R" to reboot'); @@ -92,10 +92,10 @@ STM32_protocol.prototype.connect = function(port, baud, hex, options) { bufferView[0] = 0x52; - serial.send(bufferOut, function() { - serial.disconnect(function(result) { + 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: baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) { if (openInfo) { self.initialize(); } else { @@ -115,7 +115,7 @@ STM32_protocol.prototype.connect = function(port, baud, hex, options) { }; // initialize certain variables and start timers that oversee the communication -STM32_protocol.prototype.initialize = function() { +STM32_protocol.prototype.initialize = function () { var self = this; // reset and set some variables before we start @@ -130,11 +130,11 @@ STM32_protocol.prototype.initialize = function() { self.progress_bar_e.val(0); self.progress_bar_e.removeClass('valid invalid'); - serial.onReceive.addListener(function(info) { + serial.onReceive.addListener(function (info) { self.read(info); }); - GUI.interval_add('STM32_timeout', function() { + GUI.interval_add('STM32_timeout', function () { if (self.upload_process_alive) { // process is running self.upload_process_alive = false; } else { @@ -155,7 +155,7 @@ STM32_protocol.prototype.initialize = function() { // no input parameters // this method should be executed every 1 ms via interval timer -STM32_protocol.prototype.read = function(readInfo) { +STM32_protocol.prototype.read = function (readInfo) { // routine that fills the buffer var data = new Uint8Array(readInfo.data); @@ -175,7 +175,7 @@ STM32_protocol.prototype.read = function(readInfo) { }; // we should always try to consume all "proper" available data while using retrieve -STM32_protocol.prototype.retrieve = function(n_bytes, callback) { +STM32_protocol.prototype.retrieve = function (n_bytes, callback) { if (this.receive_buffer.length >= n_bytes) { // data that we need are there, process immediately var data = this.receive_buffer.slice(0, n_bytes); @@ -192,7 +192,7 @@ STM32_protocol.prototype.retrieve = function(n_bytes, callback) { // Array = array of bytes that will be send over serial // bytes_to_read = received bytes necessary to trigger read_callback // callback = function that will be executed after received bytes = bytes_to_read -STM32_protocol.prototype.send = function(Array, bytes_to_read, callback) { +STM32_protocol.prototype.send = function (Array, bytes_to_read, callback) { // flip flag this.upload_process_alive = true; @@ -210,13 +210,13 @@ STM32_protocol.prototype.send = function(Array, bytes_to_read, callback) { this.receive_buffer = []; // send over the actual data - serial.send(bufferOut, function(writeInfo) {}); + serial.send(bufferOut, function (writeInfo) {}); }; // val = single byte to be verified // data = response of n bytes from mcu (array) // result = true/false -STM32_protocol.prototype.verify_response = function(val, data) { +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 failed, wrong response, expected: ' + val + ' received: ' + data[0]); @@ -232,7 +232,7 @@ STM32_protocol.prototype.verify_response = function(val, data) { // input = 16 bit value // result = true/false -STM32_protocol.prototype.verify_chip_signature = function(signature) { +STM32_protocol.prototype.verify_chip_signature = function (signature) { switch (signature) { case 0x412: // not tested console.log('Chip recognized as F1 Low-density'); @@ -307,7 +307,7 @@ STM32_protocol.prototype.verify_chip_signature = function(signature) { // first_array = usually hex_to_flash array // second_array = usually verify_hex array // result = true/false -STM32_protocol.prototype.verify_flash = function(first_array, second_array) { +STM32_protocol.prototype.verify_flash = function (first_array, second_array) { for (var i = 0; i < first_array.length; i++) { if (first_array[i] != second_array[i]) { console.log('Verification failed on byte: ' + i + ' expected: 0x' + first_array[i].toString(16) + ' received: 0x' + second_array[i].toString(16)); @@ -321,7 +321,7 @@ STM32_protocol.prototype.verify_flash = function(first_array, second_array) { }; // step = value depending on current state of upload_procedure -STM32_protocol.prototype.upload_procedure = function(step) { +STM32_protocol.prototype.upload_procedure = function (step) { var self = this; switch (step) { @@ -330,8 +330,8 @@ STM32_protocol.prototype.upload_procedure = function(step) { GUI.log('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 - self.send([0x7F], 1, function(reply) { + 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 + self.send([0x7F], 1, function (reply) { if (reply[0] == 0x7F || reply[0] == self.status.ACK || reply[0] == self.status.NACK) { GUI.interval_remove('stm32_initialize_mcu'); console.log('STM32 - Serial interface initialized on the MCU side'); @@ -361,9 +361,9 @@ STM32_protocol.prototype.upload_procedure = function(step) { break; case 2: // get version of the bootloader and supported commands - self.send([self.command.get, 0xFF], 2, function(data) { // 0x00 ^ 0xFF + self.send([self.command.get, 0xFF], 2, function (data) { // 0x00 ^ 0xFF if (self.verify_response(self.status.ACK, data)) { - self.retrieve(data[1] + 1 + 1, function(data) { // data[1] = number of bytes that will follow [– 1 except current and ACKs] + self.retrieve(data[1] + 1 + 1, function (data) { // data[1] = number of bytes that will follow [– 1 except current and ACKs] console.log('STM32 - Bootloader version: ' + (parseInt(data[0].toString(16)) / 10).toFixed(1)); // convert dec to hex, hex to dec and add floating point // proceed to next step @@ -374,9 +374,9 @@ STM32_protocol.prototype.upload_procedure = function(step) { break; case 3: // get ID (device signature) - self.send([self.command.get_ID, 0xFD], 2, function(data) { // 0x01 ^ 0xFF + self.send([self.command.get_ID, 0xFD], 2, function (data) { // 0x01 ^ 0xFF if (self.verify_response(self.status.ACK, data)) { - self.retrieve(data[1] + 1 + 1, function(data) { // data[1] = number of bytes that will follow [– 1 (N = 1 for STM32), except for current byte and ACKs] + self.retrieve(data[1] + 1 + 1, function (data) { // data[1] = number of bytes that will follow [– 1 (N = 1 for STM32), except for current byte and ACKs] var signature = (data[0] << 8) | data[1]; console.log('STM32 - Signature: 0x' + signature.toString(16)); // signature in hex representation @@ -398,9 +398,9 @@ STM32_protocol.prototype.upload_procedure = function(step) { if (self.options.erase_chip) { console.log('Executing global chip erase'); - self.send([self.command.erase, 0xBC], 1, function(reply) { // 0x43 ^ 0xFF + self.send([self.command.erase, 0xBC], 1, function (reply) { // 0x43 ^ 0xFF if (self.verify_response(self.status.ACK, reply)) { - self.send([0xFF, 0x00], 1, function(reply) { + self.send([0xFF, 0x00], 1, function (reply) { if (self.verify_response(self.status.ACK, reply)) { console.log('Erasing: done'); // proceed to next step @@ -412,7 +412,7 @@ STM32_protocol.prototype.upload_procedure = function(step) { } else { console.log('Executing local erase (only needed pages)'); - self.send([self.command.erase, 0xBC], 1, function(reply) { // 0x43 ^ 0xFF + 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; @@ -427,7 +427,7 @@ STM32_protocol.prototype.upload_procedure = function(step) { } buff.push(checksum); - self.send(buff, 1, function(reply) { + self.send(buff, 1, function (reply) { if (self.verify_response(self.status.ACK, reply)) { console.log('Erasing: done'); // proceed to next step @@ -456,13 +456,13 @@ STM32_protocol.prototype.upload_procedure = function(step) { // console.log('STM32 - Writing to: 0x' + address.toString(16) + ', ' + bytes_to_write + ' bytes'); - self.send([self.command.write_memory, 0xCE], 1, function(reply) { // 0x31 ^ 0xFF + self.send([self.command.write_memory, 0xCE], 1, function (reply) { // 0x31 ^ 0xFF if (self.verify_response(self.status.ACK, reply)) { // address needs to be transmitted as 32 bit integer, we need to bit shift each byte out and then calculate address checksum var address_arr = [(address >> 24), (address >> 16), (address >> 8), address]; var address_checksum = address_arr[0] ^ address_arr[1] ^ address_arr[2] ^ address_arr[3]; - self.send([address_arr[0], address_arr[1], address_arr[2], address_arr[3], address_checksum], 1, function(reply) { // write start address + checksum + self.send([address_arr[0], address_arr[1], address_arr[2], address_arr[3], address_checksum], 1, function (reply) { // write start address + checksum if (self.verify_response(self.status.ACK, reply)) { var array_out = new Array(bytes_to_write + 2); // 2 byte overhead [N, ...., checksum] array_out[0] = bytes_to_write - 1; // number of bytes to be written (to write 128 bytes, N must be 127, to write 256 bytes, N must be 255) @@ -479,7 +479,7 @@ STM32_protocol.prototype.upload_procedure = function(step) { address += bytes_to_write; bytes_flashed_total += bytes_to_write; - self.send(array_out, 1, function(reply) { + 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); @@ -537,18 +537,18 @@ STM32_protocol.prototype.upload_procedure = function(step) { // console.log('STM32 - Reading from: 0x' + address.toString(16) + ', ' + bytes_to_read + ' bytes'); - self.send([self.command.read_memory, 0xEE], 1, function(reply) { // 0x11 ^ 0xFF + self.send([self.command.read_memory, 0xEE], 1, function (reply) { // 0x11 ^ 0xFF if (self.verify_response(self.status.ACK, reply)) { var address_arr = [(address >> 24), (address >> 16), (address >> 8), address]; var address_checksum = address_arr[0] ^ address_arr[1] ^ address_arr[2] ^ address_arr[3]; - self.send([address_arr[0], address_arr[1], address_arr[2], address_arr[3], address_checksum], 1, function(reply) { // read start address + checksum + self.send([address_arr[0], address_arr[1], address_arr[2], address_arr[3], address_checksum], 1, function (reply) { // read start address + checksum if (self.verify_response(self.status.ACK, reply)) { var bytes_to_read_n = bytes_to_read - 1; - self.send([bytes_to_read_n, (~bytes_to_read_n) & 0xFF], 1, function(reply) { // bytes to be read + checksum XOR(complement of bytes_to_read_n) + self.send([bytes_to_read_n, (~bytes_to_read_n) & 0xFF], 1, function (reply) { // bytes to be read + checksum XOR(complement of bytes_to_read_n) if (self.verify_response(self.status.ACK, reply)) { - self.retrieve(bytes_to_read, function(data) { + self.retrieve(bytes_to_read, function (data) { for (var i = 0; i < data.length; i++) { self.verify_hex[reading_block].push(data[i]); } @@ -621,13 +621,13 @@ STM32_protocol.prototype.upload_procedure = function(step) { // memory address = 4 bytes, 1st high byte, 4th low byte, 5th byte = checksum XOR(byte 1, byte 2, byte 3, byte 4) console.log('Sending GO command: 0x8000000'); - self.send([self.command.go, 0xDE], 1, function(reply) { // 0x21 ^ 0xFF + 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]; - self.send([address[0], address[1], address[2], address[3], address_checksum], 1, function(reply) { + self.send([address[0], address[1], address[2], address[3], address_checksum], 1, function (reply) { if (self.verify_response(self.status.ACK, reply)) { // disconnect self.upload_procedure(99); @@ -643,7 +643,7 @@ STM32_protocol.prototype.upload_procedure = function(step) { console.log('Script finished after: ' + (microtime() - self.upload_time_start).toFixed(4) + ' seconds'); // close connection - serial.disconnect(function(result) { + serial.disconnect(function (result) { if (result) { // All went as expected } else { // Something went wrong } diff --git a/js/protocols/stm32usbdfu.js b/js/protocols/stm32usbdfu.js index 45bbd736..50da3e9d 100644 --- a/js/protocols/stm32usbdfu.js +++ b/js/protocols/stm32usbdfu.js @@ -12,7 +12,7 @@ */ 'use strict'; -var STM32DFU_protocol = function() { +var STM32DFU_protocol = function () { this.hex; // ref this.verify_hex; @@ -62,7 +62,7 @@ var STM32DFU_protocol = function() { }; }; -STM32DFU_protocol.prototype.connect = function(device, hex) { +STM32DFU_protocol.prototype.connect = function (device, hex) { var self = this; self.hex = hex; @@ -75,7 +75,7 @@ STM32DFU_protocol.prototype.connect = function(device, hex) { self.progress_bar_e.val(0); self.progress_bar_e.removeClass('valid invalid'); - chrome.usb.getDevices(device, function(result) { + chrome.usb.getDevices(device, function (result) { if (result.length) { console.log('USB DFU detected with ID: ' + result[0].device); @@ -87,10 +87,10 @@ STM32DFU_protocol.prototype.connect = function(device, hex) { }); }; -STM32DFU_protocol.prototype.openDevice = function(device) { +STM32DFU_protocol.prototype.openDevice = function (device) { var self = this; - chrome.usb.openDevice(device, function(handle) { + chrome.usb.openDevice(device, function (handle) { self.handle = handle; console.log('Device opened with Handle ID: ' + handle.handle); @@ -98,7 +98,7 @@ STM32DFU_protocol.prototype.openDevice = function(device) { }); }; -STM32DFU_protocol.prototype.closeDevice = function() { +STM32DFU_protocol.prototype.closeDevice = function () { var self = this; chrome.usb.closeDevice(this.handle, function closed() { @@ -108,7 +108,7 @@ STM32DFU_protocol.prototype.closeDevice = function() { }); }; -STM32DFU_protocol.prototype.claimInterface = function(interfaceNumber) { +STM32DFU_protocol.prototype.claimInterface = function (interfaceNumber) { var self = this; chrome.usb.claimInterface(this.handle, interfaceNumber, function claimed() { @@ -118,7 +118,7 @@ STM32DFU_protocol.prototype.claimInterface = function(interfaceNumber) { }); }; -STM32DFU_protocol.prototype.releaseInterface = function(interfaceNumber) { +STM32DFU_protocol.prototype.releaseInterface = function (interfaceNumber) { var self = this; chrome.usb.releaseInterface(this.handle, interfaceNumber, function released() { @@ -128,15 +128,15 @@ STM32DFU_protocol.prototype.releaseInterface = function(interfaceNumber) { }); }; -STM32DFU_protocol.prototype.resetDevice = function(callback) { - chrome.usb.resetDevice(this.handle, function(result) { +STM32DFU_protocol.prototype.resetDevice = function (callback) { + chrome.usb.resetDevice(this.handle, function (result) { console.log('Reset Device: ' + result); if (callback) callback(); }); }; -STM32DFU_protocol.prototype.controlTransfer = function(direction, request, value, _interface, length, data, callback) { +STM32DFU_protocol.prototype.controlTransfer = function (direction, request, value, _interface, length, data, callback) { if (direction == 'in') { // data is ignored chrome.usb.controlTransfer(this.handle, { @@ -147,7 +147,7 @@ STM32DFU_protocol.prototype.controlTransfer = function(direction, request, value 'value': value, 'index': _interface, 'length': length - }, function(result) { + }, function (result) { if (result.resultCode) console.log(result.resultCode); var buf = new Uint8Array(result.data); @@ -171,7 +171,7 @@ STM32DFU_protocol.prototype.controlTransfer = function(direction, request, value 'value': value, 'index': _interface, 'data': arrayBuf - }, function(result) { + }, function (result) { if (result.resultCode) console.log(result.resultCode); callback(result); @@ -180,11 +180,11 @@ STM32DFU_protocol.prototype.controlTransfer = function(direction, request, value }; // routine calling DFU_CLRSTATUS until device is in dfuIDLE state -STM32DFU_protocol.prototype.clearStatus = function(callback) { +STM32DFU_protocol.prototype.clearStatus = function (callback) { var self = this; function check_status() { - self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { + self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { if (data[4] == self.state.dfuIDLE) { callback(data); } else { @@ -202,16 +202,16 @@ STM32DFU_protocol.prototype.clearStatus = function(callback) { check_status(); }; -STM32DFU_protocol.prototype.loadAddress = function(address, callback) { +STM32DFU_protocol.prototype.loadAddress = function (address, callback) { var self = this; - self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x21, address, (address >> 8), (address >> 16), (address >> 24)], function() { - self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { + self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x21, address, (address >> 8), (address >> 16), (address >> 24)], function () { + self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { if (data[4] == self.state.dfuDNBUSY) { var delay = data[1] | (data[2] << 8) | (data[3] << 16); - setTimeout(function() { - self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { + setTimeout(function () { + self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { if (data[4] == self.state.dfuDNLOAD_IDLE) { callback(data); } else { @@ -231,7 +231,7 @@ STM32DFU_protocol.prototype.loadAddress = function(address, callback) { // first_array = usually hex_to_flash array // second_array = usually verify_hex array // result = true/false -STM32DFU_protocol.prototype.verify_flash = function(first_array, second_array) { +STM32DFU_protocol.prototype.verify_flash = function (first_array, second_array) { for (var i = 0; i < first_array.length; i++) { if (first_array[i] != second_array[i]) { console.log('Verification failed on byte: ' + i + ' expected: 0x' + first_array[i].toString(16) + ' received: 0x' + second_array[i].toString(16)); @@ -244,12 +244,12 @@ STM32DFU_protocol.prototype.verify_flash = function(first_array, second_array) { return true; }; -STM32DFU_protocol.prototype.upload_procedure = function(step) { +STM32DFU_protocol.prototype.upload_procedure = function (step) { var self = this; switch (step) { case 1: - self.clearStatus(function() { + self.clearStatus(function () { self.upload_procedure(2); }); break; @@ -258,13 +258,13 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { console.log('Executing global chip erase'); GUI.log('Erasing ...'); - self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x41], function() { - self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { + self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x41], function () { + self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { if (data[4] == self.state.dfuDNBUSY) { // completely normal var delay = data[1] | (data[2] << 8) | (data[3] << 16); - setTimeout(function() { - self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { + setTimeout(function () { + self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { if (data[4] == self.state.dfuDNLOAD_IDLE) { self.upload_procedure(4); } else { @@ -307,13 +307,13 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { bytes_flashed += bytes_to_write; bytes_flashed_total += bytes_to_write; - self.controlTransfer('out', self.request.DNLOAD, wBlockNum++, 0, 0, data_to_flash, function() { - self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { + self.controlTransfer('out', self.request.DNLOAD, wBlockNum++, 0, 0, data_to_flash, function () { + self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { if (data[4] == self.state.dfuDNBUSY) { var delay = data[1] | (data[2] << 8) | (data[3] << 16); - setTimeout(function() { - self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { + setTimeout(function () { + self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { if (data[4] == self.state.dfuDNLOAD_IDLE) { // update progress bar self.progress_bar_e.val(bytes_flashed_total / (self.hex.bytes_total * 2) * 100); @@ -371,8 +371,8 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { } // start - self.clearStatus(function() { - self.loadAddress(address, function() { + self.clearStatus(function () { + self.loadAddress(address, function () { self.clearStatus(read); }); }); @@ -381,7 +381,7 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { if (bytes_verified < self.hex.data[reading_block].bytes) { var bytes_to_read = ((bytes_verified + 2048) <= self.hex.data[reading_block].bytes) ? 2048 : (self.hex.data[reading_block].bytes - bytes_verified); - self.controlTransfer('in', self.request.UPLOAD, wBlockNum++, 0, bytes_to_read, 0, function(data, code) { + self.controlTransfer('in', self.request.UPLOAD, wBlockNum++, 0, bytes_to_read, 0, function (data, code) { for (var i = 0; i < data.length; i++) { self.verify_hex[reading_block].push(data[i]); } @@ -405,8 +405,8 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { bytes_verified = 0; wBlockNum = 2; - self.clearStatus(function() { - self.loadAddress(address, function() { + self.clearStatus(function () { + self.loadAddress(address, function () { self.clearStatus(read); }); }); @@ -449,13 +449,13 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) { // jump to application code var address = self.hex.data[0].address; - self.clearStatus(function() { + self.clearStatus(function () { self.loadAddress(address, leave); }); var leave = function () { - self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, 0, function() { - self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) { + self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, 0, function () { + self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { self.upload_procedure(99); }); }); diff --git a/js/serial_backend.js b/js/serial_backend.js index c2955fbf..f3f778cc 100644 --- a/js/serial_backend.js +++ b/js/serial_backend.js @@ -61,7 +61,7 @@ $(document).ready(function () { // auto-connect chrome.storage.local.get('auto_connect', function (result) { - if (!result.auto_connect || result.auto_connect) { + if (result.auto_connect === 'undefined' || result.auto_connect) { // default or enabled by user GUI.auto_connect = true; From 906cf0d82b682990bfbf91a690c352b4729cc0d7 Mon Sep 17 00:00:00 2001 From: cTn Date: Thu, 14 Aug 2014 17:03:47 +0200 Subject: [PATCH 33/54] fixing all broken statements that got broken in recent undefined runs --- eventPage.js | 2 +- main.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eventPage.js b/eventPage.js index 5f97f1c3..be72ef57 100644 --- a/eventPage.js +++ b/eventPage.js @@ -81,7 +81,7 @@ chrome.runtime.onInstalled.addListener(function (details) { // only fire up notification sequence when one of the major version numbers changed if (currentVersionArr[0] != previousVersionArr[0] || currentVersionArr[1] != previousVersionArr[1]) { chrome.storage.local.get('update_notify', function (result) { - if (!result.update_notify || result.update_notify) { + if (result.update_notify === 'undefined' || result.update_notify) { var manifest = chrome.runtime.getManifest(); var options = { priority: 0, diff --git a/main.js b/main.js index 4fa29d3b..a6fde8b8 100644 --- a/main.js +++ b/main.js @@ -129,7 +129,7 @@ $(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 || result.update_notify) { + if (result.update_notify === 'undefined' || result.update_notify) { $('div.notifications input').prop('checked', true); } }); From 41615891a07ece601a70a3f7149b316cdfdf9ee0 Mon Sep 17 00:00:00 2001 From: creyc Date: Thu, 14 Aug 2014 14:03:17 -0400 Subject: [PATCH 34/54] Added airplane and vtail graphics Added airplane and vtail graphics. Also further reduced filesize of existing graphics + better readability. --- images/motor_order/airplane.svg | 101 ++++++++++++ images/motor_order/custom.svg | 42 +++-- images/motor_order/hex6p.svg | 220 +++++++++++-------------- images/motor_order/hex6x.svg | 222 +++++++++++-------------- images/motor_order/octox.svg | 281 ++++++++++++++------------------ images/motor_order/quadp.svg | 154 ++++++++--------- images/motor_order/quadx.svg | 153 ++++++++--------- images/motor_order/tri.svg | 163 +++++++++--------- images/motor_order/vtail.svg | 73 +++++++++ images/motor_order/y4.svg | 154 ++++++++--------- images/motor_order/y6.svg | 226 ++++++++++++------------- tabs/initial_setup.css | 5 + tabs/initial_setup.js | 4 + 13 files changed, 904 insertions(+), 894 deletions(-) create mode 100644 images/motor_order/airplane.svg create mode 100644 images/motor_order/vtail.svg diff --git a/images/motor_order/airplane.svg b/images/motor_order/airplane.svg new file mode 100644 index 00000000..a04b0f05 --- /dev/null +++ b/images/motor_order/airplane.svg @@ -0,0 +1,101 @@ + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/custom.svg b/images/motor_order/custom.svg index 2086558f..70a637ba 100644 --- a/images/motor_order/custom.svg +++ b/images/motor_order/custom.svg @@ -1,26 +1,22 @@ - - - - - - + +]> + + diff --git a/images/motor_order/hex6p.svg b/images/motor_order/hex6p.svg index 59700daf..63738458 100644 --- a/images/motor_order/hex6p.svg +++ b/images/motor_order/hex6p.svg @@ -1,126 +1,102 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/hex6x.svg b/images/motor_order/hex6x.svg index e4a3a72a..78e00860 100644 --- a/images/motor_order/hex6x.svg +++ b/images/motor_order/hex6x.svg @@ -1,129 +1,101 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/octox.svg b/images/motor_order/octox.svg index 1cf08940..0e088c7c 100644 --- a/images/motor_order/octox.svg +++ b/images/motor_order/octox.svg @@ -1,162 +1,129 @@ - + + + + +]> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + height="156.84px" viewBox="0 0 153.18 156.84" xml:space="preserve"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/quadp.svg b/images/motor_order/quadp.svg index aad058d3..8d19de64 100644 --- a/images/motor_order/quadp.svg +++ b/images/motor_order/quadp.svg @@ -1,89 +1,73 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/quadx.svg b/images/motor_order/quadx.svg index fea375d8..04be3d14 100644 --- a/images/motor_order/quadx.svg +++ b/images/motor_order/quadx.svg @@ -1,88 +1,73 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/tri.svg b/images/motor_order/tri.svg index bbbe1f23..cb8abc24 100644 --- a/images/motor_order/tri.svg +++ b/images/motor_order/tri.svg @@ -1,94 +1,77 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/vtail.svg b/images/motor_order/vtail.svg new file mode 100644 index 00000000..86e3984e --- /dev/null +++ b/images/motor_order/vtail.svg @@ -0,0 +1,73 @@ + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/y4.svg b/images/motor_order/y4.svg index b8a3542d..5260ae95 100644 --- a/images/motor_order/y4.svg +++ b/images/motor_order/y4.svg @@ -1,86 +1,76 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/motor_order/y6.svg b/images/motor_order/y6.svg index 80c5affd..1d68fbd4 100644 --- a/images/motor_order/y6.svg +++ b/images/motor_order/y6.svg @@ -1,130 +1,104 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tabs/initial_setup.css b/tabs/initial_setup.css index 20c07910..767e98d9 100644 --- a/tabs/initial_setup.css +++ b/tabs/initial_setup.css @@ -70,6 +70,11 @@ height: 30%; /* interactive_block height set to inherit */ } + #interactive_block .modelMixAirplane { /* Position airplane correctly */ + height: 35%; + padding-left: 0px; + } + #interactive_block .modelMixCustom { /* Position question mark correctly */ height: 20%; /* resize question mark */ padding-left: 25px; diff --git a/tabs/initial_setup.js b/tabs/initial_setup.js index b9eb129b..916b7c7f 100644 --- a/tabs/initial_setup.js +++ b/tabs/initial_setup.js @@ -140,9 +140,13 @@ tabs.initial_setup.initialize = function(callback) { case 5: // GIMBAL case 8: // FLYING_WING case 14: // AIRPLANE + $(".modelMixDiagram").attr("src","./images/motor_order/airplane.svg").addClass('modelMixAirplane'); + break; case 15: // Heli 120 case 16: // Heli 90 case 17: // Vtail + $(".modelMixDiagram").attr("src","./images/motor_order/vtail.svg").addClass('modelMixVtail'); + break; case 18: // HEX6 H case 19: // PPM to SERVO case 20: // Dualcopter From 14bb0b5dcac43561c91bd27a658803ff5dbe46a6 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 16 Aug 2014 00:11:25 +0200 Subject: [PATCH 35/54] merge multiType name and multiType diagram switch into one --- tabs/initial_setup.js | 67 ++++++++++--------------------------------- 1 file changed, 15 insertions(+), 52 deletions(-) diff --git a/tabs/initial_setup.js b/tabs/initial_setup.js index 900d2826..8ebfb0e8 100644 --- a/tabs/initial_setup.js +++ b/tabs/initial_setup.js @@ -44,17 +44,20 @@ TABS.initial_setup.initialize = function (callback) { $('input[name="pitch"]').val(CONFIG.accelerometerTrims[0]); $('input[name="roll"]').val(CONFIG.accelerometerTrims[1]); - // Display multiType + // Display multiType and motor diagram (if such exist) var str = ''; switch (CONFIG.multiType) { case 1: // TRI str = 'TRI'; + $('.modelMixDiagram').attr('src', './images/motor_order/tri.svg').addClass('modelMixTri'); break; case 2: // QUAD + str = 'Quad +'; + $('.modelMixDiagram').attr('src', './images/motor_order/quadp.svg').addClass('modelMixQuadP'); break; case 3: // QUAD X str = 'Quad X'; + $('.modelMixDiagram').attr('src', './images/motor_order/quadx.svg').addClass('modelMixQuadX'); break; case 4: // BI str = 'BI'; @@ -64,26 +67,32 @@ TABS.initial_setup.initialize = function (callback) { break; case 6: // Y6 str = 'Y6'; + $('.modelMixDiagram').attr('src', './images/motor_order/y6.svg').addClass('modelMixY6'); break; case 7: // HEX 6 str = 'HEX 6'; + $('.modelMixDiagram').attr('src', './images/motor_order/hex6p.svg').addClass('modelMixHex6P'); break; case 8: // FLYING_WING str = 'Flying Wing'; break; case 9: // Y4 str = 'Y4'; + $('.modelMixDiagram').attr('src', './images/motor_order/y4.svg').addClass('modelMixY4'); break; case 10: // HEX6 X str = 'HEX6 X'; + $('.modelMixDiagram').attr('src', './images/motor_order/hex6x.svg').addClass('modelMixHex6X'); break; case 11: // OCTO X8 case 12: case 13: str = 'OCTO X8'; + $('.modelMixDiagram').attr('src', './images/motor_order/octox.svg').addClass('modelMixOctoX'); break; case 14: // AIRPLANE str = 'Airplane'; + $('.modelMixDiagram').attr('src', './images/motor_order/airplane.svg').addClass('modelMixAirplane'); break; case 15: // Heli 120 str = 'Heli 120'; @@ -93,74 +102,28 @@ TABS.initial_setup.initialize = function (callback) { break; case 17: // Vtail str = 'Vtail'; + $('.modelMixDiagram').attr('src', './images/motor_order/vtail.svg').addClass('modelMixVtail'); break; case 18: // HEX6 H str = 'HEX6 H'; + $('.modelMixDiagram').attr("src", './images/motor_order/custom.svg').addClass('modelMixCustom'); break; case 19: // PPM to SERVO str = 'PPM to SERVO'; + $('.modelMixDiagram').attr("src", './images/motor_order/custom.svg').addClass('modelMixCustom'); break; case 20: // Dualcopter str = 'Dualcopter'; + $('.modelMixDiagram').attr("src", './images/motor_order/custom.svg').addClass('modelMixCustom'); break; case 21: // Singlecopter str = 'Singlecopter'; + $('.modelMixDiagram').attr("src", './images/motor_order/custom.svg').addClass('modelMixCustom'); break; } $('span.model').text(chrome.i18n.getMessage('initialSetupModel', [str])); - // Model Mix Diagram selection - switch (CONFIG.multiType) { - case 1: // TRI - $(".modelMixDiagram").attr("src","./images/motor_order/tri.svg").addClass('modelMixTri'); - break; - case 2: // QUAD + - $(".modelMixDiagram").attr("src","./images/motor_order/quadp.svg").addClass('modelMixQuadP'); - break; - case 3: // QUAD X - $(".modelMixDiagram").attr("src","./images/motor_order/quadx.svg").addClass('modelMixQuadX'); - break; - case 6: // Y6 - $(".modelMixDiagram").attr("src","./images/motor_order/y6.svg").addClass('modelMixY6'); - break; - case 7: // HEX 6 - $(".modelMixDiagram").attr("src","./images/motor_order/hex6p.svg").addClass('modelMixHex6P'); - break; - case 9: // Y4 - $(".modelMixDiagram").attr("src","./images/motor_order/y4.svg").addClass('modelMixY4'); - break; - case 10: // HEX6 X - $(".modelMixDiagram").attr("src","./images/motor_order/hex6x.svg").addClass('modelMixHex6X'); - break; - case 11: // OCTO X8 - case 12: - case 13: - $(".modelMixDiagram").attr("src","./images/motor_order/octox.svg").addClass('modelMixOctoX'); - break; - case 4: // BI - case 5: // GIMBAL - case 8: // FLYING_WING - case 14: // AIRPLANE - $(".modelMixDiagram").attr("src","./images/motor_order/airplane.svg").addClass('modelMixAirplane'); - break; - case 15: // Heli 120 - case 16: // Heli 90 - case 17: // Vtail - $(".modelMixDiagram").attr("src","./images/motor_order/vtail.svg").addClass('modelMixVtail'); - break; - case 18: // HEX6 H - case 19: // PPM to SERVO - case 20: // Dualcopter - case 21: // Singlecopter - $(".modelMixDiagram").attr("src","./images/motor_order/custom.svg").addClass('modelMixCustom'); - break; - - default: - $(".modelMixDiagram").attr("src","./images/motor_order/custom.svg").addClass('modelMixCustom'); - break; - } - // Heading $('span.heading').text(chrome.i18n.getMessage('initialSetupheading', [0])); From 80e60d5638c9f5f3fa02e134f02a800310597661 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 16 Aug 2014 00:16:28 +0200 Subject: [PATCH 36/54] motor and servo indicators will now have tooltip containing signal length in us --- tabs/motor_outputs.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tabs/motor_outputs.js b/tabs/motor_outputs.js index 2e26bc62..7cbe962c 100644 --- a/tabs/motor_outputs.js +++ b/tabs/motor_outputs.js @@ -347,6 +347,7 @@ TABS.motor_outputs.initialize = function (callback) { var height = (data * (block_height / full_block_scale)); var 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)'}); } @@ -357,6 +358,7 @@ TABS.motor_outputs.initialize = function (callback) { var height = (data * (block_height / 1000)); var 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)'}); } } From 194798ca2dd606740f5bf7ec78f25f06c418b0cf Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 16 Aug 2014 00:23:49 +0200 Subject: [PATCH 37/54] small ui polish / tweak for the plot control blocks --- tabs/motor_outputs.css | 14 +++++++------- tabs/sensors.css | 13 +++++++------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/tabs/motor_outputs.css b/tabs/motor_outputs.css index af6e383e..00387590 100644 --- a/tabs/motor_outputs.css +++ b/tabs/motor_outputs.css @@ -17,7 +17,7 @@ text-decoration: underline; } .tab-motor_outputs .plot_control dl { - padding: 5px 0 0 5px; + padding: 5px 5px 0 5px; line-height: 22px; } .tab-motor_outputs .plot_control dt { @@ -29,9 +29,14 @@ font-weight: bold; } .tab-motor_outputs .plot_control dd { - margin-left: 20px; height: 22px; } + .tab-motor_outputs .plot_control select { + float: right; + + width: 80px; + border: 1px solid silver; + } .tab-motor_outputs .plot_control .x { color: #00A8F0; } @@ -43,12 +48,7 @@ } .tab-motor_outputs .plot_control .x, .tab-motor_outputs .plot_control .y, .tab-motor_outputs .plot_control .z { text-align: right; - margin-right: 25px; } -.tab-motor_outputs select { - width: 70px; - border: 1px solid silver; -} .tab-motor_outputs svg { float: left; diff --git a/tabs/sensors.css b/tabs/sensors.css index 292fb713..e189ef78 100644 --- a/tabs/sensors.css +++ b/tabs/sensors.css @@ -36,7 +36,7 @@ background-color: #ececec; } .tab-sensors .plot_control dl { - padding: 5px 0 0 5px; + padding: 5px 5px 0 5px; line-height: 22px; } .tab-sensors .plot_control dt { @@ -51,6 +51,12 @@ margin-left: 20px; height: 22px; } + .tab-sensors .plot_control select { + float: right; + + width: 80px; + border: 1px solid silver; + } .tab-sensors .plot_control .x { color: #00A8F0; } @@ -62,12 +68,7 @@ } .tab-sensors .plot_control .x, .tab-sensors .plot_control .y, .tab-sensors .plot_control .z { text-align: right; - margin-right: 25px; } - .tab-sensors select { - width: 70px; - border: 1px solid silver; - } /* SVG classes*/ .tab-sensors svg { float: left; From 8fdda97b01622be9e6aa0da8267eae8aa7fc20f8 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 16 Aug 2014 15:04:17 +0200 Subject: [PATCH 38/54] reformat some stuff --- tabs/default.html | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tabs/default.html b/tabs/default.html index 40ccf9bf..fce56ceb 100644 --- a/tabs/default.html +++ b/tabs/default.html @@ -2,24 +2,21 @@
-

-

+

-
-
+
Sponsors

- • AbuseMark - International (Japan)
- • Multirotor Superstore - International (United States)
+ • AbuseMark
+ • Multirotor Superstore

@@ -27,6 +24,7 @@
+
From 2a3d26146534e7670bf8233314e666802a867dbe Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 17 Aug 2014 13:29:07 +0200 Subject: [PATCH 39/54] added time based update reminder (informing people on dev branch and ones with broken chrome auto-update mechanism) --- js/data_storage.js | 1 + main.js | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/js/data_storage.js b/js/data_storage.js index aec6aafd..a2fd0089 100644 --- a/js/data_storage.js +++ b/js/data_storage.js @@ -1,6 +1,7 @@ 'use strict'; var CONFIGURATOR = { + 'releaseDate': 1408273765004, // 08.17.2014 'firmwareVersionAccepted': 2.3, 'connectionValid': false, 'mspPassThrough': false, diff --git a/main.js b/main.js index a6fde8b8..3634a870 100644 --- a/main.js +++ b/main.js @@ -42,6 +42,12 @@ $(document).ready(function () { break; } + // 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 + GUI.log('You\'re using an old version of Baseflight - Configurator. Please update so you can benefit from recently added features and bugfixes.'); + } + + // Tabs var ui_tabs = $('#tabs > ul'); $('a', ui_tabs).click(function () { From 6ca1ca25165804d705cc1d6e9eff0f004cc2bec8 Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 17 Aug 2014 14:20:28 +0200 Subject: [PATCH 40/54] use name from .manifest instead of hard written one --- main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.js b/main.js index 3634a870..e947fecb 100644 --- a/main.js +++ b/main.js @@ -44,7 +44,7 @@ $(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 - GUI.log('You\'re using an old version of Baseflight - Configurator. Please update so you can benefit from recently added features and bugfixes.'); + 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.'); } From 5bfc81e3175a5d64423cb8335ea868c1c26b502c Mon Sep 17 00:00:00 2001 From: cTn Date: Mon, 18 Aug 2014 19:28:06 +0200 Subject: [PATCH 41/54] text polish --- _locales/en/messages.json | 2 +- tabs/motor_outputs.css | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index fd8b1642..b5569f76 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -452,7 +452,7 @@ "message": "Master" }, "motorsNotice": { - "message": "Motor Test Mode Notice:
Moving the sliders will cause the motors to spin up.
In order to prevent injury remove ALL propellers before using this feature.
If you understand these instructions check the box below to enable motor test.

" + "message": "Motor Test Mode Notice:
Moving the sliders will cause the motors to spin up.
In order to prevent injury remove ALL propellers before using this feature.
If you understand these instructions check the box below to enable motor test.

" }, "sensorsInfo": { diff --git a/tabs/motor_outputs.css b/tabs/motor_outputs.css index 00387590..88815da7 100644 --- a/tabs/motor_outputs.css +++ b/tabs/motor_outputs.css @@ -184,7 +184,5 @@ border: 1px dotted silver; } .tab-motor_outputs .motor_testing .notice input[type="checkbox"] { - margin-left: 5px; - vertical-align: middle; } \ No newline at end of file From ab02817095607c318bb1925b8c6c94383c29a39f Mon Sep 17 00:00:00 2001 From: cTn Date: Mon, 18 Aug 2014 19:28:26 +0200 Subject: [PATCH 42/54] slider bugfix, optimizations --- tabs/motor_outputs.js | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/tabs/motor_outputs.js b/tabs/motor_outputs.js index 7cbe962c..a4b4df1b 100644 --- a/tabs/motor_outputs.js +++ b/tabs/motor_outputs.js @@ -243,32 +243,44 @@ TABS.motor_outputs.initialize = function (callback) { $('div.sliders input').prop('min', MISC.mincommand); $('div.sliders input').prop('max', MISC.maxthrottle); $('div.sliders input').val(MISC.mincommand); - $('div.values li:not(:last)').html(MISC.mincommand); + $('div.values li:not(:last)').text(MISC.mincommand); // UI hooks + var buffering_set_motor = [], + buffer_delay = false; $('div.sliders input:not(.master)').on('input', function () { - var index = $(this).index(); + var index = $(this).index(), + buffer = [], + i; - $('div.values li').eq(index).html($(this).val()); + $('div.values li').eq(index).text($(this).val()); - // send data to mcu - var buffer_out = []; - - for (var i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { var val = parseInt($('div.sliders input').eq(i).val()); - buffer_out.push(lowByte(val)); - buffer_out.push(highByte(val)); + buffer.push(lowByte(val)); + buffer.push(highByte(val)); } - MSP.send_message(MSP_codes.MSP_SET_MOTOR, buffer_out); + buffering_set_motor.push(buffer); + + if (!buffer_delay) { + buffer_delay = setTimeout(function () { + buffer = buffering_set_motor.pop(); + + MSP.send_message(MSP_codes.MSP_SET_MOTOR, buffer); + + buffering_set_motor = []; + buffer_delay = false; + }, 10); + } }); $('div.sliders input.master').on('input', function () { var val = $(this).val(); $('div.sliders input:not(:disabled, :last)').val(val); - $('div.values li:not(:last)').slice(0, number_of_valid_outputs).html(val); + $('div.values li:not(:last)').slice(0, number_of_valid_outputs).text(val); $('div.sliders input:not(:last):first').trigger('input'); }); From 440d3250f1c7f2c438d3514efacf1f1a397c96c3 Mon Sep 17 00:00:00 2001 From: cTn Date: Mon, 18 Aug 2014 19:29:36 +0200 Subject: [PATCH 43/54] release --- changelog.html | 6 ++++++ js/data_storage.js | 2 +- manifest.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/changelog.html b/changelog.html index 6ea8dfa7..c8fd70ee 100644 --- a/changelog.html +++ b/changelog.html @@ -1,3 +1,9 @@ +08.18.2014 - 0.49 +

+ - Motor indicators now display signal length in tooltips
+ - Additional motor order diagrams (creyc)
+ - Bugfixes
+

07.27.2014 - 0.48

- Configurator reached 6000+ users on 07.26.2014
diff --git a/js/data_storage.js b/js/data_storage.js index a2fd0089..36151a7c 100644 --- a/js/data_storage.js +++ b/js/data_storage.js @@ -1,7 +1,7 @@ 'use strict'; var CONFIGURATOR = { - 'releaseDate': 1408273765004, // 08.17.2014 + 'releaseDate': 1408379746980, // 08.18.2014 - new Date().getTime() 'firmwareVersionAccepted': 2.3, 'connectionValid': false, 'mspPassThrough': false, diff --git a/manifest.json b/manifest.json index d25bf25f..4543421e 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "minimum_chrome_version": "36", - "version": "0.48", + "version": "0.49", "author": "cTn", "name": "Baseflight - Configurator", From 1e681bbdd28c878ba93d8723aa61a37d0b3fbf48 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 30 Aug 2014 08:26:12 +0200 Subject: [PATCH 44/54] polish variable definitions (only indentation changes) --- js/protocols/stm32.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index 1980cd15..49990a3d 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -415,16 +415,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) { @@ -443,12 +445,11 @@ STM32_protocol.prototype.upload_procedure = function (step) { console.log('Writing data ...'); GUI.log('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) { @@ -519,12 +520,11 @@ STM32_protocol.prototype.upload_procedure = function (step) { console.log('Verifying data ...'); GUI.log('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++) { @@ -623,9 +623,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)) { From 37746bf3ed423f8a1279542a66058b390fd1b3e1 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 30 Aug 2014 08:27:24 +0200 Subject: [PATCH 45/54] fix rare condition in which flasher could hang and wont let the user leave --- js/protocols/stm32.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index 49990a3d..83138eae 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -99,6 +99,7 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options) { if (openInfo) { self.initialize(); } else { + GUI.connect_lock = false; GUI.log('Failed to open serial port'); } }); From 6dec7dfbc17d8dec3e4e9c636b9ef18ba86e6e07 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 30 Aug 2014 08:35:09 +0200 Subject: [PATCH 46/54] if unexpected data is received, throw an error instead of log, this will also attach a stack trace for easier debugging --- js/protocols/stm32.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index 83138eae..8558bf12 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -219,7 +219,7 @@ 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]); + console.error('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]); GUI.log('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]); // disconnect From 322af92d45d1d4cc74d0761b3837ca47fb8bf02b Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 30 Aug 2014 08:59:21 +0200 Subject: [PATCH 47/54] add / implement flash slowly option in firmware flasher this will allow flashing via serial adapters that doesn't support 921600 flashing via various bluetooth adapters will be also possible now (untested) --- _locales/en/messages.json | 6 ++++++ js/protocols/stm32.js | 13 +++++++++---- tabs/firmware_flasher.html | 7 ++++++- tabs/firmware_flasher.js | 25 ++++++++++++++++++++----- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index b5569f76..eec2601b 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -530,6 +530,12 @@ "firmwareFlasherFullChipErase": { "message": "Full Chip Erase" }, + "firmwareFlasherFlashSlowly": { + "message": "Flash slowly" + }, + "firmwareFlasherFlashSlowlyTitle": { + "message": "Use 115200 baudrate for flashing" + }, "firmwareFlasherButtonLoadLocal": { "message": "Load Firmware [Local]" }, diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index 8558bf12..1cb4bdd9 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -51,11 +51,12 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options) { var self = this; self.hex = hex; - // 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 +69,12 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options) { self.options.erase_chip = true; } + if (options.flash_slowly) { + self.options.flash_slowly = true; + } + if (self.options.no_reboot) { - serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) { + serial.connect(port, {bitrate: (!self.options.flash_slowly) ? baud : 115200, parityBit: 'even', stopBits: 'one'}, function (openInfo) { if (openInfo) { // we are connected, disabling connect button in the UI GUI.connect_lock = true; @@ -95,7 +100,7 @@ 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.options.flash_slowly) ? baud : 115200, parityBit: 'even', stopBits: 'one'}, function (openInfo) { if (openInfo) { self.initialize(); } else { diff --git a/tabs/firmware_flasher.html b/tabs/firmware_flasher.html index 4f94451f..59adba33 100644 --- a/tabs/firmware_flasher.html +++ b/tabs/firmware_flasher.html @@ -1,6 +1,6 @@

- empty
+ Please load firmware file
0 bytes
@@ -22,6 +22,11 @@
+ +
diff --git a/tabs/firmware_flasher.js b/tabs/firmware_flasher.js index d8daf285..d5b5ceb5 100644 --- a/tabs/firmware_flasher.js +++ b/tabs/firmware_flasher.js @@ -111,9 +111,9 @@ TABS.firmware_flasher.initialize = function (callback) { if (parsed_hex != false) { if (String($('div#port-picker #port').val()) != 'DFU') { if (String($('div#port-picker #port').val()) != '0') { - var options = {}; - var port = String($('div#port-picker #port').val()); - var baud; + var options = {}, + port = String($('div#port-picker #port').val()), + baud; switch (GUI.operating_system) { case 'Windows': @@ -138,6 +138,10 @@ TABS.firmware_flasher.initialize = function (callback) { options.erase_chip = true; } + if ($('input.flash_slowly').is(':checked')) { + options.flash_slowly = true; + } + STM32.connect(port, baud, parsed_hex, options); } else { console.log('Please select valid serial port'); @@ -241,9 +245,20 @@ TABS.firmware_flasher.initialize = function (callback) { // bind UI hook so the status is saved on change $('input.erase_chip').change(function () { - var status = $(this).is(':checked'); + chrome.storage.local.set({'erase_chip': $(this).is(':checked')}); + }); + }); - chrome.storage.local.set({'erase_chip': status}); + chrome.storage.local.get('flash_slowly', function (result) { + if (result.flash_slowly) { + $('input.flash_slowly').prop('checked', true); + } else { + $('input.flash_slowly').prop('checked', false); + } + + // bind UI hook so the status is saved on change + $('input.flash_slowly').change(function () { + chrome.storage.local.set({'flash_slowly': $(this).is(':checked')}); }); }); From bed74a5f62c92a16d9ea2a23b3d89dda4d8c65d2 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 30 Aug 2014 09:08:08 +0200 Subject: [PATCH 48/54] add note about flash slowly to explain its purpose --- _locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index eec2601b..a0e30bdb 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -519,7 +519,7 @@ "message": "Progress:" }, "firmwareFlasherNote": { - "message": "If you are flashing board with bootloader pins shorted/connected, check No reboot sequence.
If you want configuration data to be wiped, check Full Chip Erase
" + "message": "If you are flashing board with bootloader pins shorted/connected, check No reboot sequence.
If you want configuration data to be wiped, check Full Chip Erase
If you are flashing via bluetooth adapter or using external usb to serial adapter, check Flash slowly
" }, "firmwareFlasherNoReboot": { "message": "No reboot sequence" From 37de8dfefabdc2be49d537d52066d19cb61b134a Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 30 Aug 2014 10:30:28 +0200 Subject: [PATCH 49/54] new simplified flasher status UI --- _locales/en/messages.json | 9 +++----- js/protocols/stm32.js | 29 ++++++++++++++++--------- js/protocols/stm32usbdfu.js | 10 ++++----- tabs/firmware_flasher.css | 42 ++++++++++++++++++++++++++++++------- tabs/firmware_flasher.html | 5 ++--- tabs/firmware_flasher.js | 16 ++++++-------- 6 files changed, 70 insertions(+), 41 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index a0e30bdb..655abf57 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -567,19 +567,16 @@ "message": "Leave Firmware Flasher" }, "firmwareFlasherFirmwareNotLoaded": { - "message": "Firmware not loaded" - }, - "firmwareFlasherLocalFirmwareLoaded": { - "message": "Local Firmware loaded, ready for flashing" + "message": "Firmware not loaded" }, "firmwareFlasherHexCorrupted": { - "message": "HEX file appears to be corrupted" + "message": "HEX file appears to be corrupted" }, "firmwareFlasherRemoteFirmwareLoaded": { "message": "Remote Firmware loaded, ready for flashing" }, "firmwareFlasherFailedToLoadOnlineFirmware": { - "message": "Failed to load remote firmware" + "message": "Failed to load remote firmware" }, "firmwareFlasherWaitForFinish": { "message": "You can't do this right now, please wait for current operation to finish ..." diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index 1cb4bdd9..cae1e8a7 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -145,7 +145,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: FAILED'); + + $('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 @@ -225,7 +228,8 @@ STM32_protocol.prototype.send = function (Array, bytes_to_read, callback) { STM32_protocol.prototype.verify_response = function (val, data) { if (val != data[0]) { console.error('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]); - GUI.log('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); @@ -333,7 +337,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 @@ -345,8 +349,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 failed'); // disconnect self.upload_procedure(99); @@ -356,7 +362,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: FAILED'); + + $('span.progressLabel').text('No reponse from the bootloader, programming: FAILED'); + self.progress_bar_e.addClass('invalid'); + GUI.interval_remove('stm32_initialize_mcu'); GUI.interval_remove('STM32_timeout'); @@ -399,7 +408,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'); @@ -449,7 +458,7 @@ 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, flashing_block = 0, @@ -524,7 +533,7 @@ 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, reading_block = 0, @@ -596,7 +605,7 @@ STM32_protocol.prototype.upload_procedure = function (step) { if (verify) { console.log('Programming: SUCCESSFUL'); - GUI.log('Programming: SUCCESSFUL'); + $('span.progressLabel').text('Programming: SUCCESSFUL'); googleAnalytics.sendEvent('Flashing', 'Programming', 'success'); // update progress bar @@ -606,7 +615,7 @@ STM32_protocol.prototype.upload_procedure = function (step) { self.upload_procedure(7); } else { console.log('Programming: FAILED'); - GUI.log('Programming: FAILED'); + $('span.progressLabel').text('Programming: FAILED'); googleAnalytics.sendEvent('Flashing', 'Programming', 'fail'); // update progress bar diff --git a/js/protocols/stm32usbdfu.js b/js/protocols/stm32usbdfu.js index 50da3e9d..e145f977 100644 --- a/js/protocols/stm32usbdfu.js +++ b/js/protocols/stm32usbdfu.js @@ -256,7 +256,7 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) { case 2: // full chip erase console.log('Executing global chip erase'); - GUI.log('Erasing ...'); + $('span.progressLabel').text('Erasing ...'); self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x41], function () { self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) { @@ -284,7 +284,7 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) { // upload // we dont need to clear the state as we are already using DFU_DNLOAD console.log('Writing data ...'); - GUI.log('Flashing ...'); + $('span.progressLabel').text('Flashing ...'); var blocks = self.hex.data.length - 1; var flashing_block = 0; @@ -355,7 +355,7 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) { case 5: // verify console.log('Verifying data ...'); - GUI.log('Verifying ...'); + $('span.progressLabel').text('Verifying ...'); var blocks = self.hex.data.length - 1; var reading_block = 0; @@ -422,7 +422,7 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) { if (verify) { console.log('Programming: SUCCESSFUL'); - GUI.log('Programming: SUCCESSFUL'); + $('span.progressLabel').text('Programming: SUCCESSFUL'); googleAnalytics.sendEvent('Flashing', 'Programming', 'success'); // update progress bar @@ -432,7 +432,7 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) { self.upload_procedure(6); } else { console.log('Programming: FAILED'); - GUI.log('Programming: FAILED'); + $('span.progressLabel').text('Programming: FAILED'); googleAnalytics.sendEvent('Flashing', 'Programming', 'fail'); // update progress bar diff --git a/tabs/firmware_flasher.css b/tabs/firmware_flasher.css index 1b79862d..be3f0df8 100644 --- a/tabs/firmware_flasher.css +++ b/tabs/firmware_flasher.css @@ -1,22 +1,50 @@ .tab-firmware_flasher .info { margin: 0 0 10px 0; + position: relative; } - .tab-firmware_flasher .info strong { - margin-right: 5px; + .tab-firmware_flasher .info .progressLabel { + position: absolute; + + width: 100%; + height: 26px; + + top: 0; + left: 0; + + text-align: center; + line-height: 24px; + + color: white; + font-weight: bold; + + /* text-shadow: 1px 0px 2px rgba(0, 0, 0, 0.9);*/ } .tab-firmware_flasher .info .progress { - width: 25%; + width: 100%; + height: 26px; border: 1px solid silver; } - .tab-firmware_flasher .info .progress::-webkit-progress-value { - background-color: #f4af4d; + .tab-firmware_flasher .info .progress { + -webkit-appearance: none; } + .tab-firmware_flasher .info .progress::-webkit-progress-bar { + background-color: #343434; + } + .tab-firmware_flasher .info .progress::-webkit-progress-value { + background-color: #F86008; + } + .tab-firmware_flasher .info .progress.valid::-webkit-progress-bar { + background-color: #73BE45; + } .tab-firmware_flasher .info .progress.valid::-webkit-progress-value { - background-color: #43c232; + background-color: #73BE45; + } + .tab-firmware_flasher .info .progress.invalid::-webkit-progress-bar { + background-color: #A62E32; } .tab-firmware_flasher .info .progress.invalid::-webkit-progress-value { - background-color: #cf2222; + background-color: #A62E32; } .tab-firmware_flasher .note { margin-bottom: 10px; diff --git a/tabs/firmware_flasher.html b/tabs/firmware_flasher.html index 59adba33..32b1bcb5 100644 --- a/tabs/firmware_flasher.html +++ b/tabs/firmware_flasher.html @@ -1,8 +1,7 @@
- Please load firmware file
- 0 bytes
- + + Please load firmware file

diff --git a/tabs/firmware_flasher.js b/tabs/firmware_flasher.js index d5b5ceb5..dd6e34c0 100644 --- a/tabs/firmware_flasher.js +++ b/tabs/firmware_flasher.js @@ -27,7 +27,6 @@ TABS.firmware_flasher.initialize = function (callback) { chrome.fileSystem.getDisplayPath(fileEntry, function (path) { console.log('Loading file from: ' + path); - $('span.path').html(path); fileEntry.file(function (file) { var reader = new FileReader(); @@ -50,13 +49,12 @@ TABS.firmware_flasher.initialize = function (callback) { parsed_hex = data; if (parsed_hex) { - GUI.log(chrome.i18n.getMessage('firmwareFlasherLocalFirmwareLoaded')); googleAnalytics.sendEvent('Flashing', 'Firmware', 'local'); $('a.flash_firmware').removeClass('locked'); - $('span.size').html(parsed_hex.bytes_total + ' bytes'); + $('span.progressLabel').text('Loaded Local firmware: (' + parsed_hex.bytes_total + ' bytes)'); } else { - GUI.log(chrome.i18n.getMessage('firmwareFlasherHexCorrupted')); + $('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherHexCorrupted')); } }); } @@ -76,18 +74,16 @@ TABS.firmware_flasher.initialize = function (callback) { parsed_hex = data; if (parsed_hex) { - GUI.log(chrome.i18n.getMessage('firmwareFlasherRemoteFirmwareLoaded')); googleAnalytics.sendEvent('Flashing', 'Firmware', 'online'); $('a.flash_firmware').removeClass('locked'); - $('span.path').text('Using remote Firmware'); - $('span.size').text(parsed_hex.bytes_total + ' bytes'); + $('span.progressLabel').text('Loaded Online firmware: (' + parsed_hex.bytes_total + ' bytes)'); } else { - GUI.log(chrome.i18n.getMessage('firmwareFlasherHexCorrupted')); + $('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherHexCorrupted')); } }); }).fail(function () { - GUI.log(chrome.i18n.getMessage('firmwareFlasherFailedToLoadOnlineFirmware')); + $('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherFailedToLoadOnlineFirmware')); $('a.flash_firmware').addClass('locked'); }); @@ -151,7 +147,7 @@ TABS.firmware_flasher.initialize = function (callback) { STM32DFU.connect(usbDevices.STM32DFU, parsed_hex); } } else { - GUI.log(chrome.i18n.getMessage('firmwareFlasherFirmwareNotLoaded')); + $('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherFirmwareNotLoaded')); } } } From b1390b0b017906ad855251acc0efe0a2a2239da5 Mon Sep 17 00:00:00 2001 From: cTn Date: Sat, 30 Aug 2014 10:36:55 +0200 Subject: [PATCH 50/54] updating changelog --- changelog.html | 6 ++++++ tabs/firmware_flasher.js | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/changelog.html b/changelog.html index c8fd70ee..f0f80a4c 100644 --- a/changelog.html +++ b/changelog.html @@ -1,3 +1,9 @@ +xx.xx.2014 - 0.50 +

+ - Small UI revamp for Firmware Flasher
+ - Added "Flash slowly" mode (bluetooth friendly)
+ - Bugfixes
+

08.18.2014 - 0.49

- Motor indicators now display signal length in tooltips
diff --git a/tabs/firmware_flasher.js b/tabs/firmware_flasher.js index dd6e34c0..56cab2f1 100644 --- a/tabs/firmware_flasher.js +++ b/tabs/firmware_flasher.js @@ -52,7 +52,7 @@ TABS.firmware_flasher.initialize = function (callback) { googleAnalytics.sendEvent('Flashing', 'Firmware', 'local'); $('a.flash_firmware').removeClass('locked'); - $('span.progressLabel').text('Loaded Local firmware: (' + parsed_hex.bytes_total + ' bytes)'); + $('span.progressLabel').text('Loaded Local Firmware: (' + parsed_hex.bytes_total + ' bytes)'); } else { $('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherHexCorrupted')); } @@ -77,7 +77,7 @@ TABS.firmware_flasher.initialize = function (callback) { googleAnalytics.sendEvent('Flashing', 'Firmware', 'online'); $('a.flash_firmware').removeClass('locked'); - $('span.progressLabel').text('Loaded Online firmware: (' + parsed_hex.bytes_total + ' bytes)'); + $('span.progressLabel').text('Loaded Online Firmware: (' + parsed_hex.bytes_total + ' bytes)'); } else { $('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherHexCorrupted')); } From 911ddba2789141b68ab124e11199d7a597493a8b Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 31 Aug 2014 10:10:53 +0200 Subject: [PATCH 51/54] only request firmware info from github api when firmware is valid --- tabs/firmware_flasher.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tabs/firmware_flasher.js b/tabs/firmware_flasher.js index 56cab2f1..c38eed33 100644 --- a/tabs/firmware_flasher.js +++ b/tabs/firmware_flasher.js @@ -6,8 +6,8 @@ TABS.firmware_flasher.initialize = function (callback) { GUI.active_tab = 'firmware_flasher'; googleAnalytics.sendAppView('Firmware Flasher'); - var intel_hex = false; // standard intel hex in string format - var parsed_hex = false; // parsed raw hex in array format + var intel_hex = false, // standard intel hex in string format + parsed_hex = false; // parsed raw hex in array format $('#content').load("./tabs/firmware_flasher.html", function () { // translate to user-selected language @@ -75,9 +75,22 @@ TABS.firmware_flasher.initialize = function (callback) { if (parsed_hex) { googleAnalytics.sendEvent('Flashing', 'Firmware', 'online'); + $('span.progressLabel').text('Loaded Online Firmware: (' + parsed_hex.bytes_total + ' bytes)'); $('a.flash_firmware').removeClass('locked'); - $('span.progressLabel').text('Loaded Online Firmware: (' + parsed_hex.bytes_total + ' bytes)'); + $.get('https://api.github.com/repos/multiwii/baseflight/commits?page=1&per_page=1&path=obj/baseflight.hex', function (data) { + var data = data[0], + d = new Date(data.commit.author.date), + date = ('0' + (d.getMonth() + 1)).slice(-2) + '.' + ('0' + (d.getDate() + 1)).slice(-2) + '.' + d.getFullYear(); + + date += ' @ ' + ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2); + + $('div.git_info .committer').text(data.commit.author.name); + $('div.git_info .date').text(date); + $('div.git_info .message').text(data.commit.message); + + $('div.git_info').slideDown(); + }); } else { $('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherHexCorrupted')); } @@ -86,19 +99,6 @@ TABS.firmware_flasher.initialize = function (callback) { $('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherFailedToLoadOnlineFirmware')); $('a.flash_firmware').addClass('locked'); }); - - $.get('https://api.github.com/repos/multiwii/baseflight/commits?page=1&per_page=1&path=obj/baseflight.hex', function (data) { - var data = data[0]; - var d = new Date(data.commit.author.date); - var date = ('0' + (d.getMonth() + 1)).slice(-2) + '.' + ('0' + (d.getDate() + 1)).slice(-2) + '.' + d.getFullYear(); - date += ' @ ' + ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2); - - $('div.git_info .committer').text(data.commit.author.name); - $('div.git_info .date').text(date); - $('div.git_info .message').text(data.commit.message); - - $('div.git_info').slideDown(); - }); }); $('a.flash_firmware').click(function () { From b5aeb8df2a095835e85d16e858090cc068805816 Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 31 Aug 2014 15:55:12 +0200 Subject: [PATCH 52/54] fix typo --- js/protocols/stm32.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/protocols/stm32.js b/js/protocols/stm32.js index cae1e8a7..e589fda0 100644 --- a/js/protocols/stm32.js +++ b/js/protocols/stm32.js @@ -363,7 +363,7 @@ STM32_protocol.prototype.upload_procedure = function (step) { // stop retrying, its too late to get any response from MCU console.log('STM32 - no response from bootloader, disconnecting'); - $('span.progressLabel').text('No reponse from the bootloader, programming: FAILED'); + $('span.progressLabel').text('No response from the bootloader, programming: FAILED'); self.progress_bar_e.addClass('invalid'); GUI.interval_remove('stm32_initialize_mcu'); From 9034a941353d9a19fa5b78440cf0b1a70dea2b45 Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 31 Aug 2014 16:52:55 +0200 Subject: [PATCH 53/54] release --- changelog.html | 2 +- js/data_storage.js | 2 +- tabs/default.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/changelog.html b/changelog.html index f0f80a4c..31ac7668 100644 --- a/changelog.html +++ b/changelog.html @@ -1,4 +1,4 @@ -xx.xx.2014 - 0.50 +08.31.2014 - 0.50

- Small UI revamp for Firmware Flasher
- Added "Flash slowly" mode (bluetooth friendly)
diff --git a/js/data_storage.js b/js/data_storage.js index 36151a7c..ef80cc99 100644 --- a/js/data_storage.js +++ b/js/data_storage.js @@ -1,7 +1,7 @@ 'use strict'; var CONFIGURATOR = { - 'releaseDate': 1408379746980, // 08.18.2014 - new Date().getTime() + 'releaseDate': 1409496670288, // 08.31.2014 - new Date().getTime() 'firmwareVersionAccepted': 2.3, 'connectionValid': false, 'mspPassThrough': false, diff --git a/tabs/default.html b/tabs/default.html index fce56ceb..40043279 100644 --- a/tabs/default.html +++ b/tabs/default.html @@ -10,7 +10,7 @@

Sponsors
From f5ed23c2b793a43c8a91cbdf1e5e8ca9af3caae7 Mon Sep 17 00:00:00 2001 From: cTn Date: Sun, 31 Aug 2014 16:55:51 +0200 Subject: [PATCH 54/54] bump the version --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 4543421e..68cf4b51 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "minimum_chrome_version": "36", - "version": "0.49", + "version": "0.50", "author": "cTn", "name": "Baseflight - Configurator",