diff --git a/.gitignore b/.gitignore index 064e8ff..fdedbdb 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ dataplot/ *.bmp *.gif +# OS +.DS_Store + # IDE file .idea/ diff --git a/Nov_27/Full/Arduino/timer/._timer.ino b/Nov_27/Full/Arduino/timer/._timer.ino new file mode 100644 index 0000000..94deaab Binary files /dev/null and b/Nov_27/Full/Arduino/timer/._timer.ino differ diff --git a/Nov_27/Full/Arduino/timer/timer.ino b/Nov_27/Full/Arduino/timer/timer.ino new file mode 100644 index 0000000..5f8e178 --- /dev/null +++ b/Nov_27/Full/Arduino/timer/timer.ino @@ -0,0 +1,111 @@ +// Global Variables +int timer = 0; +int on = 0; +int minInterval = 5; +float val; +float time2; +float time3; + +void setup() { + // Setup pins for pin activated interrupts: p8, p7 + pinMode(3,INPUT);//digitalWrite(8,HIGH); + pinMode(2,INPUT);//digitalWrite(7,HIGH); + //pinMode(2, INPUT_PULLUP); + + // Setup pin for timer activated interrupts: p13 + pinMode(13,OUTPUT);//`******digitalWrite(13,LOW); + pinMode(12,OUTPUT); // Open the relay to shut of RPi + + + // Setup the timer interrupt configuration for 1 Hz + /* + cli(); + TCCR1A = 0;// set entire TCCR1A register to 0 + TCCR1B = 0;// same for TCCR1B + TCNT1 = 0;//initialize counter value to 0 + // set compare match register for 1hz increments + OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536) + // Set CS12 and CS10 bits for 1024 prescaler + TCCR1B |= (1 << CS12) | (1 << CS10); + // enable timer compare interrupt + TIMSK1 |= (1 << OCIE1A); + // Normally would turn on, but this is left for the p8 interrupt to do: + // turn on CTC mode + // TCCR1B |= (1 << WGM12); + // + sei(); + */ + + // Setup p3 and p2 interrupt code + attachInterrupt(digitalPinToInterrupt(2),ISR_p2,FALLING); + //attachInterrupt(digitalPinToInterrupt(2),ISR_p2,RISING); + attachInterrupt(digitalPinToInterrupt(3),ISR_p3,RISING); + + // Turn on the RPi pin to start the flow of energy to the RPi so it + // can be configured to run the system and eventually activate p8 and + // p9 interrupt ISR's which will begin the total system operation. + digitalWrite(13,HIGH); // this flips a relay energizing the RPi + digitalWrite(12,LOW); + + Serial.begin(9600); + Serial.println("Running..."); +} + +// timer1 interrupt service routine +ISR(TIMER1_COMPA_vect){ + // turn on the RPi, as the time interval has elapsed + if(timer == 60*minInterval){ + //if(timer == 10){ + digitalWrite(12,LOW); + digitalWrite(13,HIGH); + timer = 1; + Serial.println(timer); + } else { + timer += 1; + Serial.println(timer); + } +} + +// pin2 interrupt service routine +void ISR_p2(){ + // turn off RPi, as the signal pin has lifted saying it is shutdown + //if (timer > 1){ + //if (timer > 5){ + // digitalWrite(13,LOW); + // digitalWrite(12,HIGH); + // Serial.println("pin 2 lifted"); + delay(10000); + digitalWrite(13,LOW); + digitalWrite(12,HIGH); + Serial.println("pin 2 lifted"); + //} +} + +// pin3 interrup service routine +void ISR_p3(){ + // start the timer1, as the signal pin has been lifted saying the clocks are synchronized + cli(); + TCCR1A = 0;// set entire TCCR1A register to 0 + TCCR1B = 0;// same for TCCR1B + TCNT1 = 0;//initialize counter value to 0 + // set compare match register for 1hz increments + OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536) + // Set CS12 and CS10 bits for 1024 prescaler + TCCR1B |= (1 << CS12) | (1 << CS10); + // enable timer compare interrupt + TIMSK1 |= (1 << OCIE1A); + TCCR1B |= (1 << WGM12); + sei(); + Serial.println("pin 3 lifted"); + detachInterrupt(3); +} + + + +void loop() { + // put your main code here, to run repeatedly: + //int pinstate = digitalRead(2); + //Serial.println(pinstate); + //delay(1); + +} diff --git a/Nov_27/Full/Arduino/timer_polls/timer_polls.ino b/Nov_27/Full/Arduino/timer_polls/timer_polls.ino new file mode 100644 index 0000000..44d358e --- /dev/null +++ b/Nov_27/Full/Arduino/timer_polls/timer_polls.ino @@ -0,0 +1,112 @@ +// Global Variables +int timer = 0; +int minInterval = 5; +int syncInterval = 1; +int flag_sync = 0; +//int timer_sync = 0; + +int CurrentStatePin2 = LOW; +int PrevStatePin2 = LOW; +int CurrentStatePin3 = LOW; +int PrevStatePin3 = LOW; + +void setup() { + // Setup pins for pin activated interrupts: p8, p7 + pinMode(3,INPUT);//digitalWrite(8,HIGH); + pinMode(2,INPUT);//digitalWrite(7,HIGH); + + // Setup pin for timer activated interrupts: p13 + pinMode(13,OUTPUT);//`******digitalWrite(13,LOW); + pinMode(12,OUTPUT); // Open the relay to shut of RPi + + // Turn on the RPi pin to start the flow of energy to the RPi so it + // can be configured to run the system and eventually activate p8 and + // p9 interrupt ISR's which will begin the total system operation. + digitalWrite(13,HIGH); // this flips a relay energizing the RPi + digitalWrite(12,LOW); + + Serial.begin(9600); + Serial.println("Running..."); +} + +// timer1 interrupt service routine +ISR(TIMER1_COMPA_vect){ + // turn on the RPi, as the time interval has elapsed + if(timer == 60*minInterval && flag_sync == 0){ + digitalWrite(12,LOW); + digitalWrite(13,HIGH); + timer = 1; + Serial.println(timer); + } else if (timer == 60*syncInterval && flag_sync == 1){ + digitalWrite(12,LOW); + digitalWrite(13,HIGH); + timer = 1; + Serial.println(timer); + flag_sync = 0; + Serial.println("flag_sync off"); + //} else if (timer_sync == 1) { + // timer = 1; + // timer_sync = 0; + // Serial.println("timer_sync off"); + } else { + timer += 1; + Serial.println(timer); + } +} + +// pin2 interrupt service routine +void ISR_p2(){ + // turn off RPi, as the signal pin has lifted saying it is shutdown + delay(1000); + digitalWrite(13,LOW); + digitalWrite(12,HIGH); + Serial.println("pin 2 lifted"); +} + +// pin3 interrup service routine +void ISR_p3(){ + // start the timer1, as the signal pin has been lifted saying the clocks are synchronized + cli(); + Serial.println("l1"); + TCCR1A = 0;// set entire TCCR1A register to 0 + TCCR1B = 0;// same for TCCR1B + TCNT1 = 0;//initialize counter value to 0 + Serial.println("l2"); + // set compare match register for 1hz increments + OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536) + //OCR1A = 15614;// for Laser Module + Serial.println("l3"); + // Set CS12 and CS10 bits for 1024 prescaler + TCCR1B |= (1 << CS12) | (1 << CS10); + // enable timer compare interrupt + TIMSK1 |= (1 << OCIE1A); + TCCR1B |= (1 << WGM12); + Serial.println("l4"); + sei(); + Serial.println("l5"); + timer = 0; // initialize or reset timer (first execution, or re-sync) + Serial.println("pin 3 lifted"); +} + + +void loop() { + + PrevStatePin2 = CurrentStatePin2; + PrevStatePin3 = CurrentStatePin3; + + delay (10); + + CurrentStatePin2 = digitalRead(2); + CurrentStatePin3 = digitalRead(3); + + if ((PrevStatePin2 == HIGH) && (CurrentStatePin2 == LOW)){ + ISR_p2(); + } + if ((PrevStatePin3 == LOW) && (CurrentStatePin3 == HIGH)){ + ISR_p3(); + flag_sync = 1; + //timer_sync = 1; + Serial.println("flag_sync on"); + //Serial.println("timer_sync on"); + } +} diff --git a/Nov_27/Full/Camera/RPiCam/._RPiCM.py b/Nov_27/Full/Camera/RPiCam/._RPiCM.py new file mode 100644 index 0000000..540a5a9 Binary files /dev/null and b/Nov_27/Full/Camera/RPiCam/._RPiCM.py differ diff --git a/Nov_27/Full/Camera/RPiCam/._img_capture.py b/Nov_27/Full/Camera/RPiCam/._img_capture.py new file mode 100644 index 0000000..cdc2139 Binary files /dev/null and b/Nov_27/Full/Camera/RPiCam/._img_capture.py differ diff --git a/Nov_27/Full/Camera/RPiCam/RPiCM.py b/Nov_27/Full/Camera/RPiCam/RPiCM.py new file mode 100644 index 0000000..ca837ac --- /dev/null +++ b/Nov_27/Full/Camera/RPiCam/RPiCM.py @@ -0,0 +1,174 @@ +# Author: Alex R. Mead +# Date: May 2016 +# Description: +# This code will run on the Raspberry Pi 2 with Camera Module (RPiCM) to interact with the MacBookPro (MBP). It will +# wait for the MBP to request a measurement, take a measurement, then wait for the MBP to request the latest +# measurement, at which time it will send the measurement to the MBP. + +# Same as the MBP this system is designed to run like finite state machine. + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) + +import sys +import socket +import io +import subprocess +import picamera +import numpy as np +import gc +from time import sleep + +# Constants +#IP = '127.0.0.1' # Testing on a single machine +IP = '0.0.0.0' # Actual run time. +port1 = 1234 +port2 = 2345 +marker = "?" + +MAX_PIXEL_VALUE = 1023 # 2^10 = 1024 +PIXEL_HEIGHT = 1944 +PIXEL_WIDTH = 2592 + +# Takes in the Camera object instantiated at the beginning of the run and takes the desired SS expsoures with it. +def HDRI(SS,camera): + + size = len(SS) + print("Taking %i measurements.\n",size) + names = [] + + # Loop through for each shutter speed requested + for index, shutterSpeed in enumerate(SS): + fileName = str(shutterSpeed) + ".data" + camera.shutter_speed = shutterSpeed + sleep(1) + print(str(camera.shutter_speed)) + camera.capture(fileName,format='jpeg',bayer=True) + names.append(fileName) + + # Return the list of filenames to the calling function. + return names + +def main(): + + STATE = "idle" + RUNNING = [True,0] + + # First declare the camera object and configure it as needed + camera = picamera.PiCamera() + camera.framerate=1 + sleep(1.0) + + camera.led = False + camera.iso = 100 + sleep(10.0) + # This longer sleep is needed so analog_gain and digital_gains settle so when I turn them off in the next step + # they will have settled and not be in their initial 'low' values. + + camera.exposure_mode = 'off' # Fixes analog_gain and digital_gain values + g = camera.awb_gains + camera.aws_mode = 'off' + camera.awb_gains = [1.0,1.0] # typical values 0.9-1.9 according to documentation, I picked these for consistency. + camera.rotation = 180 + sleep(2.0) + + while(RUNNING[0]): + + if("idle" == STATE): + print("We're in idle state waiting to hear from the MacBookPro...") + + # Start up a connection listening for the MBP. + sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) + sock.bind((IP,port1)) + sock.listen(1) + connection, client_address = sock.accept() + + rcv_msg = [] + while True: + data = connection.recv(1) + if marker in data: + rcv_msg.append(data[:data.find(marker)]) + break + rcv_msg.append(data) + + # Check the message received from the MBP, if correct, continue, else exit. + rpl = ''.join(rcv_msg) + if rpl == "True": + print("Now going to acknowledge measurement.") + + # elif used to teminate remotely. + elif rpl == "c": + print("Big John called it for me...") + sys.exit(0) + + # Acknowledge the MBP so it knows a measurement will be taking place. + connection.send("True?") + connection.close() + + # Change state: Continue on and take measurement + STATE ="Measuring" + + elif ("Measuring" == STATE): + print("Engaging the Camera Module to measure the output of the CFS under test...") + # Here is the function call to take the measurement of the CFS inside CUBE2.0 + + # List of the shutter speeds in microseconds to be used + #SS = [1000000, 100000, 10000, 1000, 100, 10]; + SS = [1000000, 100000, 10000]; + + # Take the measurements with the above stated shutter speeds + files = HDRI(SS,camera) + + print("...Measurement taken of CFS.\n") + + # Continue to the next state and wait for MBP to query for the 145 measurements. + STATE = "waitToSend" + + elif("waitToSend" == STATE): + print("Waiting to send to MBP...") + # Setup connection to wait for the request from the MBP + # This maybe a short wait as the MBP may be trying to connect already if the Measurememt was a long time. + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind((IP, port2)) + sock.listen(1) + connection, client_address = sock.accept() + + rcv_msg = [] + while True: + data = connection.recv(1) + if marker in data: + rcv_msg.append(data[:data.find(marker)]) + break + rcv_msg.append(data) + + # Check the message received from the MBP, if correct, continue, else exit. + rpl = ''.join(rcv_msg) + if rpl == "True": + print("Send measurement.") + + # Now use the same connection to let the MBP know it can grab the .jpg+RAW + # files and run RPiCM_C.c locally over there, which is MUCH faster. + connection.sendall("True?") + connection.close() + + print("...measurment has been sent.\n") + + # Change state: measurement has been sent, change state back to idle + STATE = "idle" + + # Cycle counter for the finite state machine + RUNNING[1] = RUNNING[1] + 1 + print("Cycle number: " + str(RUNNING[1])) + + print("Little John called it...") + sys.exit(0) + +if __name__ == "__main__": + main() + diff --git a/Nov_27/Full/Camera/RPiCam/cam.py b/Nov_27/Full/Camera/RPiCam/cam.py new file mode 100644 index 0000000..c91e666 --- /dev/null +++ b/Nov_27/Full/Camera/RPiCam/cam.py @@ -0,0 +1,32 @@ +import picamera +from fractions import Fraction + +cam = picamera.PiCamera(resolution=(640, 480)) +cam.exposure_mode = 'off' +DEBUG_DIR = 'debug/' +filename = DEBUG_DIR + 'shutter_{0}_iso_{1}_expo_{2}.png' +cam.capture("base.png") +cam.framerate = Fraction(1, 6) +while True: + try: + exp = input("Run experiment?[y/n] ") + if exp == 'y': + ss = input("shutter speed: ") + iso = input("iso: ") + options = {'a': 'off', 'b': 'auto', 'c': 'night', 'd': 'night_preview', 'e': 'sports'} + expo = input("exposure mode: " + str(options) + " ") + #bright = input("brightness: ") + ss, iso, opt = int(ss), int(iso), options[expo] + cam.shutter_speed = ss + cam.iso = iso + cam.exposure_mode = options[expo] + #cam.brightness = bright + cam.capture(filename.format(ss, iso, opt)) + else: + cam.close() + break + except ValueError: + pass + + + diff --git a/Nov_27/Full/Camera/RPiCam/img_capture.py b/Nov_27/Full/Camera/RPiCam/img_capture.py new file mode 100644 index 0000000..86fd14a --- /dev/null +++ b/Nov_27/Full/Camera/RPiCam/img_capture.py @@ -0,0 +1,186 @@ +import picamera +import os +from fractions import Fraction +import sys, traceback +import time + + +class ImgCollector: + + def __init__(self, dir='', ns='img', form='png', raw=False, num=1, serialize=True): + if dir: + if not os.path.exists(dir): + os.mkdir(dir) + if dir[len(dir)-1] != '/': + dir += '/' + + self.name_scheme = dir + ns + '_{0}.' + form + self._dir = dir + self._ns = ns + self._form = form + self._raw = raw + self._num = num + self.init_cam() + if serialize: + if os.path.exists("img_log.txt"): + rfile = open("img_log.txt", "r") + try: + self.counter = int(rfile.read()) + except ValueError: + self.counter = 1 + else: + rfile = open("img_log.txt", "w") + self.counter = 1 + rfile.close() + else: + self.counter = 1 + + + def change_ns(self, ns): + self._ns = ns + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_format(self, form): + self._form = form + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_dir(self, dir): + self._dir = dir + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_num(self, num): + self._num = num + if self._num == 1: + self.capture = self.uni_capture + else: + self.capture = self.multi_capture + + def init_cam(self): + self.cam = picamera.PiCamera(resolution=(640, 480)) + time.sleep(2) + self.cam.led = False + self.cam.framerate = Fraction(1, 6) + self.cam.rotation = 180 + self.cam.shutter_speed = 800000 + self.cam.iso = 100 + self.cam.exposure_mode = 'off' + time.sleep(3) + if self._num == 1: + self.capture = self.uni_capture + else: + self.capture = self.multi_capture + + def get_last_meas(self): + if self._num == 1: + return self.name_scheme.format(self.counter - 1) + else: + return self._dir + self._ns + '_%d_{0}.' % (self.counter - 1) + self._form + + def shutdown(self): + self.cam.close() + wfile = open("img_log.txt", "w") + wfile.write(str(self.counter)) + wfile.close() + + def uni_capture(self): + self.cam.capture(self.name_scheme.format(self.counter), bayer=self._raw) + self.counter += 1 + + def multi_capture(self): + file_list = [self.name_scheme.format("%d_%d" % (self.counter, i)) for i in range(1, self._num+1)] + self.cam.capture_sequence(file_list, bayer=self._raw) + self.counter += 1 + + +def main(): + prompt = input("Welcome to the RPiCam Module. Type q for quick test, d for debug, or f / [other inputs] for full test.\n") + global recur + if prompt == 'q': + directory = 'quick_test' + name_pattern = 'img' + pic_format = 'png' + raw_image = False + num_meas = 1 + recur = True + elif prompt == 'd': + camera_debug() + sys.exit() + else: + directory = input("Input a directory:\n") + name_pattern = input("Input a name pattern:\n") + pic_format = input("Input a picture format:\n") + raw_image = input("Raw image?[y/n]\n") in ['y', 'yes'] + num_meas = int(input("Number of image samples for one measurement?\n")) + recur = False + + while True: + try: + ic = ImgCollector(dir=directory, ns=name_pattern, form=pic_format, raw=raw_image, num=num_meas) + break + except: + directory = input("Ill-formated directory, type in another one: ") + traceback.print_exc(file=sys.stdout) + + while True: + if recur: + ic.shutdown() + break + + option = input("Type in an action or h for help:\n") + if option == 'h': + print("m: take measurement\n" + + "r: show raw image status\n" + + "cr: change raw image status\n" + + "cf: change image format\n" + + "cd: change directory\n" + + "cn: change name\n" + + "cm: change number of measurement\n" + + "e: end the program") + elif option == 'm': + ic.capture() + elif option == 'r': + print(ic._raw) + elif option == 'cr': + ic._raw = input("Raw image?[y/n]\n") in ['y', 'yes'] + elif option == 'cf': + ic.change_format(input("Input a picture format:\n")) + elif option == 'cd': + ic.change_dir(input("Input a directory:\n")) + elif option == 'cn': + ic.change_ns(input("Input a name pattern:\n")) + elif option == 'cm': + ic.change_num(int(input("Number of image samples for one measurement?\n"))) + elif option == 'e': + ic.shutdown() + break + + +def camera_debug(): + DEBUG_DIR = 'debug/' + filename = DEBUG_DIR + 'shutter_{0}_iso_{1}_bright_{2}.jpeg' + analog = 'analog_gain: ' + awb_gain = 'awb_gain: ' + expo_modes = ['night', 'night_preview', 'very_long'] + #flash_modes = ['off', 'redeye'] + flash_modes = ['off'] + shutter = [600000, 800000, 1000000] + with picamera.PiCamera(resolution=(640, 480)) as cam: + time.sleep(1) + print(analog + str(cam.analog_gain)) + print(awb_gain + str(cam.awb_gains)) + cam.framerate = Fraction(1, 6) + for ss in shutter: + #for br in brightness: + time.sleep(0.1) + cam.shutter_speed = ss + cam.brightness = 50 + cam.capture(filename.format(ss), bayer=False) + + +if __name__ == "__main__": + recur = True + while recur: + main() + + + diff --git a/Nov_27/Full/Camera/accel_correct_config/LICENSE b/Nov_27/Full/Camera/accel_correct_config/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/Nov_27/Full/Camera/accel_correct_config/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Nov_27/Full/Camera/accel_correct_config/accel.py b/Nov_27/Full/Camera/accel_correct_config/accel.py new file mode 100644 index 0000000..1c04871 --- /dev/null +++ b/Nov_27/Full/Camera/accel_correct_config/accel.py @@ -0,0 +1,739 @@ +#!/usr/bin/env python +# -*- coding:utf-8, indent=tab, tabstop=4 -*- +# +# See 'LICENSE' for copying +# +# Revision history +# Date Author Version Details +# ---------------------------------------------------------------------------------- +# 2016-12-31 Massimo Di Primio V.0.04 Fixed some basic functionality +# +# 2017-01-03 Massimo Di Primio 0.05 Added Interrut handler +# +# 2018-01-10 Massimo Di Primio 0.06 Added config file parser + +"""Simple code example for Adafruit MMA8452 3-axis Accelerometer + +This experimental code is intended for measuring gravity acceleration trough Adafruit(c) MMA8451, connected +to a Raspberry Pi Model 2A, 2B, 2B+ or 3 (not yet tested with RPi Zero). +Through this code we will demonstrate the ability of the 3-axis sensor MMA8451 to efficiently measure +gravity acceleration, so that we can identify the spatial orientation of the device. +Further and even more useful application can start from this minimal basic code. +""" + +import smbus +import time +import datetime +import os +import sys +import logging +import threading +import RPi.GPIO as GPIO +import rss_cli_config as clicfg +from collections import deque + +__author__ = "Massimo Di Primio" +__copyright__ = "Copyright 2016, dpmiictc" +__credits__ = ["Massimo Di Primio", "Dario Dalla Libera"] +__license__ = "GNU GENERAL PUBLIC LICENSE Version 3" +__version__ = "0.0.1" +__deprecated__ = "None so far" +__date__ = "2017-01-03" +__maintainer__ = "Massimo Di Primio" +__email__ = "massimo@diprimio.com" +__status__ = "Testing" +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# User Configuration Options (UCO) +# This section will be repaced soon by an external configuration file +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CFG_INTERRUPT = 1 +# MMA8451_RANGE = {} + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Application Definition Constants (ADC) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Useful definitions +EARTH_GRAVITY_MS2 = 9.80665 + +# Range values +RANGE_8_G = 0b10 # +/- 8g +RANGE_4_G = 0b01 # +/- 4g +RANGE_2_G = 0b00 # +/- 2g (default value) + +RANGE_DIVIDER = { + RANGE_2_G: 4096 / EARTH_GRAVITY_MS2, + RANGE_4_G: 2048 / EARTH_GRAVITY_MS2, + RANGE_8_G: 1024 / EARTH_GRAVITY_MS2, +} + +# Some static values +deviceName = 0x1a + +# Various addresses +i2caddr = 0x1D +# +# Useful Register Address +REG_STATUS = 0x00 # Read-Only +REG_WHOAMI = 0x0d # Read-Only +REG_DEVID = 0x1A # Read-Only +REG_OUT_X_MSB = 0x01 # Read-Only +REG_OUT_X_LSB = 0x02 # Read-Only +REG_OUT_Y_MSB = 0x03 # Read-Only +REG_OUT_Y_LSB = 0x04 # Read-Only +REG_OUT_Z_MSB = 0x05 # Read-Only +REG_OUT_Z_LSB = 0x06 # Read-Only +REG_F_SETUP = 0x09 # Read/Write +REG_XYZ_DATA_CFG = 0x0e # Read/Write +REG_PL_STATUS = 0x10 # Read-Only +REG_PL_CFG = 0x11 # Read/Write +REG_CTRL_REG1 = 0x2A # Read/Write +REG_CTRL_REG2 = 0x2B # Read/Write +REG_CTRL_REG3 = 0x2C # Read/Write +REG_CTRL_REG4 = 0x2D # Read/Write +REG_CTRL_REG5 = 0x2E # Read/Write + +REDUCED_NOISE_MODE = 0 +OVERSAMPLING_MODE = 1 +HIGH_RES_MODE = { + REDUCED_NOISE_MODE: [REG_CTRL_REG1, 0x4], + OVERSAMPLING_MODE: [REG_CTRL_REG2, 0x2], +} + +# Auto-Wake Sample Frequencies for Register CTRL_REG1 (0x2A) (Read/Write) +# sample frequency when the device is in SLEEP Mode. Default value: 00. +ASLP_RATE_FREQ_50_HZ = 0x00 +ASLP_RATE_FREQ_12_5_HZ = 0x40 +ASLP_RATE_FREQ_6_25HZ = 0x80 +ASLP_RATE_FREQ_1_56_HZ = 0xc0 + +# Data rate values +DATARATE_800_HZ = 0x00 # 800Hz +DATARATE_400_HZ = 0x08 # 400Hz +DATARATE_200_HZ = 0x10 # 200Hz +DATARATE_100_HZ = 0x18 # 100Hz +DATARATE_50_HZ = 0x20 # 50Hz +DATARATE_12_5_HZ = 0x28 # 12.5Hz +DATARATE_6_25HZ = 0x30 # 6.25Hz +DATARATE_1_56_HZ = 0x38 # 1.56Hz + +# Orientation labeling +PL_PUF = 0 +PL_PUB = 1 +PL_PDF = 2 +PL_PDB = 3 +PL_LRF = 4 +PL_LRB = 5 +PL_LLF = 6 +PL_LLB = 7 + +# Precision +PRECISION_14_BIT = 14 +PRECISION_08_BIT = 8 + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define Register Flags +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Register CTRL_REG1 (0x2a) R/W - System Control 1 Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | ASLPRATE1 | ASLPRATE0 | DR2 | DR1 | DR0 | LNOISE | F_READ | ACTIVE | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Auto-Wake Sample frequency Selection +FLAG_ASLPRATE_50_HZ = 0x00 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 50 Hz +FLAG_ASLPRATE_12_5_HZ = 0x40 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 12.5 Hz +FLAG_ASLPRATE_6_25_HZ = 0x80 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 6.25 Hz +FLAG_ASLPRATE_1_56_HZ = 0xc0 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 1.56 Hz +# System Output Data Rates Selection +FLAG_ODR_800_HZ = 0x00 # System Output Data Rate 800 Hz +FLAG_ODR_400_HZ = 0x08 # System Output Data Rate 400 Hz +FLAG_ODR_200_HZ = 0x10 # System Output Data Rate 200 Hz +FLAG_ODR_100_HZ = 0x18 # System Output Data Rate 100 Hz +FLAG_ODR_50_HZ = 0x20 # System Output Data Rate 50 Hz +FLAG_ODR_12_5_HZ = 0x28 # System Output Data Rate 12.5 Hz +FLAG_ODR_6_25_HZ = 0x30 # System Output Data Rate 6.25 Hz +FLAG_ODR_1_56_HZ = 0x38 # System Output Data Rate 1.56 Hz +# Other Flags +FLAG_LNOISE = 0x04 # Low Noise (1: Reduced Noise, 0: Normal Mode) +FLAG_F_READ = 0x02 # Fast Read (1: 8 bit sample, 0: 14 bit Sample) +FLAG_ACTIVE = 0x01 # Active (1: ACTIVE Mode, 0: STANDBY Mode) + +# Register CTRL_REG2 (0x2b) R/W - System Control 2 Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | ST | RST | 0 | SMODS1 | SMODS0 | SLPE | MODS1 | MODS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Other Flags +FLAG_STEST = 0x80 # Self Test (1: Self-Test enabled, 0: Self-Test disabled) +FLAG_RESET = 0x40 # Reset (1: Reset enabled, 0: Reset disabled) +# Sleep Mode Power Scheme Selection +FLAG_SMODS_NORM = 0x00 # Sleep Mode Power Scheme Selection: Normal +FLAG_SMODS_LNLP = 0x0a # Sleep Mode Power Scheme Selection: Low-Noise Low Power +FLAG_SMODS_HR = 0x12 # Sleep Mode Power Scheme Selection: High Resolution +FLAG_SMODS_LP = 0x1b # Sleep Mode Power Scheme Selection: Low Power +# Other Flags +FLAG_SLPE = 0x04 # Auto-Sleep (1: Auto-Sleep enabled, 0: Auto-Sleep Disabled) +# Active Mode Power Scheme Selection (for both: Sleep and Active mode) +FLAG_MODS_NORM = 0x00 # Active Mode Power Scheme Selection: Normal +FLAG_MODS_LNLP = 0x09 # Active Mode Power Scheme Selection: Low-Noise Low Power +FLAG_MODS_HR = 0x12 # Active Mode Power Scheme Selection: High Resolution +FLAG_MODS_LP = 0x1b # Active Mode Power Scheme Selection: Low Power + +# Register CTRL_REG4 (0x2d) R/W - Interrupt Enable Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | INT_EN_ASLP | INT_EN_FIFO |INT_EN_TRANS |INT_EN_LNDPR |INT_EN_PULSE |INT_EN_FF_MT | - | INT_EN_DRDY | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_INT_EN_ASLP = 0x80 # Interrupt Auto SLEEP/WAKE (0: Disabled, 1: Enabled) +FLAG_INT_EN_FIFO = 0x40 # Interrupt FIFO (0: Disabled, 1: Enabled) +FLAG_INT_EN_TRANS = 0x20 # Interrupt Transient (0: Disabled, 1: Enabled) +FLAG_INT_EN_LNDPRT = 0x10 # Interrupt Orientation (0: Disabled, 1: Enabled) +FLAG_INT_EN_PULSE = 0x08 # Interrupt Pulse Detection (0: Disabled, 1: Enabled) +FLAG_INT_EN_FF_MT = 0x04 # Interrupt Freefall/Motion (0: Disabled, 1: Enabled) +FLAG_INT_EN_BIT1 = 0x00 # Not Used +FLAG_INT_EN_DRDY = 0x01 # Interrupt Data Ready (0: Disabled, 1: Enabled) + +# Register CTRL_REG5 (0x2e) R/W - Interrupt Configuration Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | INT_CFG_ASLP | INT_CFG_FIFO |INT_CFG_TRANS |INT_CFG_LNDPRT|INT_CFG_PULSE |INT_CFG_FF_MT | - | INT_CFG_DRDY | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_INT_CFG_ASLP = 0x80 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_FIFO = 0x40 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_TRANS = 0x20 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_LNDPRT = 0x10 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_PULSE = 0x08 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_FF_MT = 0x04 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_BIT1 = 0x00 # Not Used +FLAG_INT_CFG_DRDY = 0x01 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) + +# Register XYZ_DATA_CFG (0x0e) R/W +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | 0 | 0 | 0 | HPF_OUT | 0 | 0 | FS1 | FS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Other Flags +FLAG_XYZ_DATA_BIT_7 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_6 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_5 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_HPF_OUT = 0x00 # High-Pass Filter (1: output data High-pass filtered, 0: output data High-pass NOT filtered) +FLAG_XYZ_DATA_BIT_3 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_2 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_FS_2G = 0x00 # Full Scale Range 2g +FLAG_XYZ_DATA_BIT_FS_4G = 0x01 # Full Scale Range 4g +FLAG_XYZ_DATA_BIT_FS_8G = 0x02 # Full Scale Range 8g +FLAG_XYZ_DATA_BIT_FS_RSVD = 0x03 # Reserved + +# Register F_SETUP (0x09) R/W - FIFO Setup Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | F_MODE1 | F_MODE0 | F_WMRK5 | F_WMRK4 | F_WMRK3 | F_WMRK2 | F_WMRK1 | F_WMRK0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_F_MODE_FIFO_NO = 0x00 # FIFO is disabled. +FLAG_F_MODE_FIFO_RECNT = 0x40 # FIFO contains the most recent samples when overflowed (circular buffer) +FLAG_F_MODE_FIFO_STOP = 0x80 # FIFO stops accepting new samples when overflowed. +FLAG_F_MODE_FIFO_TRIGGER = 0xc0 # FIFO Trigger mode + +# Register PL_STATUS (0x010) R/O - Portrait/Landscape Status Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | NEWLP | LO | - | - | - | LAPO[1] | LAPO[0] | BAFRO | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_PL_NEWLP = 0x80 # Landscape/Portrait status change flag. +FLAG_PL_LO = 0x40 # Z-Tilt Angle Lockout. +FLAG_PL_LAPO_PU = 0x00 # 00: Portrait Up: Equipment standing vertically in the normal orientation +FLAG_PL_LAPO_PD = 0x02 # 01: Portrait Down: Equipment standing vertically in the inverted orientation +FLAG_PL_LAPO_LR = 0x04 # 10: Landscape Right: Equipment is in landscape mode to the right +FLAG_PL_LAPO_LL = 0x06 # 11: Landscape Left: Equipment is in landscape mode to the left. +FLAG_PL_BAFRO = 0x01 # Back or Front orientation. (0: Front: Equipment is in the front facing orientation, 1: Back) + +# Register PL_CFG (0x011) R/W - Portrait/Landscape Configuration Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | DBCNTM | PL_EN | - | - | - | - | - | - | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_PL_CFG_DBCNTM = 0x80 # Debounce counter mode selection (0: Decrements debounce, 1: Clears counter) +FLAG_PL_CFG_PL_EN = 0x40 # Portrait/Landscape Detection Enable (0: P/L Detection Disabled, 1: P/L Detection Enabled) + +# Register TRANSIENT_CFG (0x1d) R/W - Transient_CFG Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | - | - | - | ELE | ZTEFE | YTEFE | XTEFE | HPF_BYP | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_TRANSIENT_CFG_ELE = 0x10 # Transient event flags (0: Event flag latch disabled; 1: Event flag latch enabled) +FLAG_TRANSIENT_CFG_ZTEFE = 0x08 # Event flag enable on Z (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_YTEFE = 0x04 # Event flag enable on Y (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_XTEFE = 0x02 # Event flag enable on X (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_HPF_BYP = 0x01 # Bypass High-Pass filter/Motion Detection + +# Register TRANSIENT_SCR (0x01e) R/O - TRANSIENT_SRC Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | - | EA | ZTRANSE | Z_Trans_Pol | YTRANSE | Y_Trans_Pol | XTRANSE | X_Trans_Pol | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_TRANSIENT_SCR_EA = 0x40 # Event Active Flag (0: no event flag has been asserted; 1: one or more event flag has been asserted) +FLAG_TRANSIENT_SCR_ZTRANSE = 0x20 # Z transient event (0: no interrupt, 1: Z Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_ZTR_POL = 0x10 # Polarity of Z Transient Event that triggered interrupt (0: Z event Positive g, 1: Z event Negative g) +FLAG_TRANSIENT_SCR_YTRANSE = 0x08 # Y transient event (0: no interrupt, 1: Y Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_YTR_POL = 0x04 # Polarity of Y Transient Event that triggered interrupt (0: Y event Positive g, 1: Y event Negative g) +FLAG_TRANSIENT_SCR_XTRANSE = 0x02 # X transient event (0: no interrupt, 1: X Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_XTR_POL = 0x01 # Polarity of X Transient Event that triggered interrupt (0: X event Positive g, 1: X event Negative g) + +# Register FF_MT_THS (0x017) R/W - Freefall and Motion Threshold Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | DBCNTM | THS6 | THS5 | THS4 | THS3 | THS2 | THS1 | THS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define SOME GLOBAL VARIABLES +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define the acceleration FIFO buffer +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# The acceleration FIFO buffer is a list of records containing all meaningful acceleration data plus some +# other useful information, whose format il as described below +# +# 1. curTime as returned by: datetime.datetime.now(). Format is: 'YYYY-MM-DD hh:mi:ss.uuuuuuu' +# 2. xAccel Current X acceleration value in row format +# 3. yAccel Current Y acceleration value in row format +# 4. xAccel Current Z acceleration value in row format +# 5. plo Current Portrait/Landscape orientation +#accelBuffer = [0, 0, 0, 0, 0] +accelBuffer = [] +#accelBuffer.append([0, 0, 0, 0, 0]) + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define the threaded interrupt vector +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +def my_callback(channel): + """ + my_callback is the threaded callback functions for interrupt events. + These will run in another thread when our events are detected + + :param channel: The GPIO channel where the interrupt event was risen + :return: None + """ + # Please nte that, for performance reasons, axis data are not convertd in m/s2, + # Although, all 6 registers containing acceleration data are read and formatted appropriately + bus = smbus.SMBus(1) + axisData = bus.read_i2c_block_data(i2caddr, REG_OUT_X_MSB, 6) + # + #print ("!"), #print("Falling edge detected on GPIO channel: " + str(channel)) + # + runTimeConfigObject.NumInterrupts = runTimeConfigObject.NumInterrupts + 1 + # + xAccel = ((axisData[0] << 8) | axisData[1]) >> 2 + yAccel = ((axisData[2] << 8) | axisData[3]) >> 2 + zAccel = ((axisData[4] << 8) | axisData[5]) >> 2 + plo = bus.read_byte_data(i2caddr, REG_PL_STATUS) & 0x7 + # Append data to the accelBuffer + accelBuffer.append([str(datetime.datetime.now()), xAccel, yAccel, zAccel, plo]) + pass + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define a class called Accel +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +import ConfigParser +class Accel(): + raspiBus = -1 # The Raspberry Pi Bus (dpends on hardware model) + raspiIntEnabled = 0 # 0 = Interrupt routine was not enabled after initialization, 1 = Interrupt routine enabled successfully + raspiInfo = "" # Raspberry Pi Info + + def __init__(self): + + # + # Setup RPI specific bus + # + myBus = "" + if GPIO.RPI_INFO['P1_REVISION'] == 1: + myBus = 0 + else: + myBus = 1 + #print('myBus=' + str(myBus)) + self.raspiBus = myBus + + self.b = smbus.SMBus(myBus) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1) + self.a = i2caddr + self.high_res_mode = OVERSAMPLING_MODE + self.sensor_range = RANGE_4_G + self.raspiInfo = GPIO.RPI_INFO + + + def whoAmI(self): + return self.b.read_byte_data(i2caddr, REG_WHOAMI) + + def init(self): + # Preliminary actions + # sudo chmod 666 /sys/module/i2c_bcm2708/parameters/combined + # sudo echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined + # + # the above 2 sh commands can be replaced with the following statements, in the case this program is ran as root (sudo) + # (For more information, please see: http://raspberrypi.znix.com/hipidocs/topic_i2c_rs_and_cs.htm) + # + # BCM2708_COMBINED_PARAM_PATH = '/sys/module/i2c_bcm2708/parameters/combined' + # os.chmod(BCM2708_COMBINED_PARAM_PATH, 666) + # os.system('echo -n 1 > {!s}'.format(BCM2708_COMBINED_PARAM_PATH)) + # sudo i2cdetect -y 1 # this sh cmmand will search /dev/i2c-1 for all address + # sudo i2cget -y 1 0x1d 0x0d # This sh command should return 0x1a for MMA8451 + # + # Setup all registers appropriately + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_RESET) # Reset + # self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_STEST) # SelfTest + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) & ~FLAG_ACTIVE) # Put the device in Standby + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) & ~FLAG_F_READ) # No Fast-Read (14-bits), Fast-Read (8-Bits) + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_ODR_50_HZ) # Data Rate + self.writeRegister(REG_XYZ_DATA_CFG, self.readRegister(REG_XYZ_DATA_CFG) | FLAG_XYZ_DATA_BIT_FS_4G) # Full Scale Range 2g, 4g or 8g + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_LNOISE) # Low Noise + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) & ~FLAG_SLPE) # No Auto-Sleep + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_SMODS_HR) # High Resolution + self.writeRegister(REG_PL_CFG, self.readRegister(REG_PL_CFG) | FLAG_PL_CFG_PL_EN) # P/L Detection Enabled + + # Setup interrupts + if CFG_INTERRUPT == 1: + GPIO.setmode(GPIO.BCM) + # GPIO 23 & 17 set up as inputs, pulled up to avoid false detection. + # Both ports are wired to connect to GND on button press. + # So we'll be setting up falling edge detection for both + GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP) + # when a falling edge is detected on port 17, regardless of whatever + # else is happening in the program, the function my_callback will be run + # GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback, bouncetime=300) + GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback) + #print("Interrupt OK") + self.raspiIntEnabled = 1 # Interrupt enabled successfully + # Force 1st sensor read + my_callback(0) + + + # Configure register for interrupt + self.writeRegister(REG_CTRL_REG4, 0x00) # Reset all interrupt enabled flags + self.writeRegister(REG_CTRL_REG4, self.readRegister(REG_CTRL_REG4) | FLAG_INT_EN_DRDY) # Data Ready Interrupt Enabled + self.writeRegister(REG_CTRL_REG5, 0x00) # Reset all interrupt config flags + self.writeRegister(REG_CTRL_REG5, self.readRegister(REG_CTRL_REG5) | FLAG_INT_CFG_DRDY) # Data Ready Interrupt is routed to INT1 pin + + # Initialize the accelBuffer + accelBuffer = deque() + + + # Finally, Activate the sensor + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_ACTIVE) # Activate the device + + def writeRegister(self, regNumber, regData): + """ + Writes one byte (8-bts) of data passed in 'regData', into the register 'regNumber' + """ + try: + self.b.write_byte_data(self.a, regNumber, regData) + time.sleep(0.01) + except IOError: + print("Error detected in function writeRegister() [IOError = " + str(IOError) + "]") + sys.exit() + + def readRegister(self, regNumber): + """ + Retrieves one byte (8-bits) of data from register 'regNumber' returning to the caller + """ + try: + return self.b.read_byte_data(self.a, regNumber) + except IOError: + print("Error detected in function readRegister() [IOError = " + str(IOError) + "]") + sys.exit() + + def block_read(self, offset, length): + """ + Performs a burst-read on the device registers retrieving the requested amount of data + Read a block of bytes from offset + """ + try: + return self.b.read_i2c_block_data(i2caddr, offset, length) + except IOError: + print("Error detected in function block_read() [IOError = " + str(IOError) + "]") + sys.exit() + + def get_orientation(self): + """ + Get current orientation of the sensor. + :return: orientation. Orientation number for the sensor. + """ + orientation = self.b.read_byte_data(self.a, REG_PL_STATUS) & 0x7 + return orientation + + def getAxisValue(self): + """ + Retrieves axis values and converts into a readable format (i.e. m/s2) + :return: None + """ + # Make sure F_READ and F_MODE are disabled. + f_read = self.b.read_byte_data(self.a, REG_CTRL_REG1) & FLAG_F_READ + assert f_read == 0, 'F_READ mode is not disabled. : %s' % (f_read) + f_mode = self.b.read_byte_data(self.a, REG_F_SETUP) & FLAG_F_MODE_FIFO_TRIGGER + assert f_mode == 0, 'F_MODE mode is not disabled. : %s' % (f_mode) + + # + self.xyzdata = self.block_read(REG_OUT_X_MSB, 6) + if self.high_res_mode is not None: + x = ((self.xyzdata[0] << 8) | self.xyzdata[1]) >> 2 + y = ((self.xyzdata[2] << 8) | self.xyzdata[3]) >> 2 + z = ((self.xyzdata[4] << 8) | self.xyzdata[5]) >> 2 + precision = PRECISION_14_BIT # Precision 14 bit data + else: + x = (self.xyzdata[0] << 8) + y = (self.xyzdata[1] << 8) + z = (self.xyzdata[2] << 8) + precision = PRECISION_08_BIT # Precision 08 bit data + max_val = 2 ** (precision - 1) - 1 + signed_max = 2 ** precision + # + x -= signed_max if x > max_val else 0 + y -= signed_max if y > max_val else 0 + z -= signed_max if z > max_val else 0 + # + x = round((float(x)) / RANGE_DIVIDER[self.sensor_range], 3) + y = round((float(y)) / RANGE_DIVIDER[self.sensor_range], 3) + z = round((float(z)) / RANGE_DIVIDER[self.sensor_range], 3) + + return {"x": x, "y": y, "z": z} + + def debugShowRpiInfo(self): + #print("Raspberry Info = " + str(GPIO.RPI_INFO)) + print("Raspberry Info = " + str(self.raspiInfo)) + + def debugShowRegisters(self): + print("REG_STATUS (0x00):" + str(format(self.readRegister(REG_STATUS), '#04x')) + " | Binary: " + format(self.readRegister(REG_STATUS), 'b').zfill(8)) + print("REG_WHOAMI (0x0d):" + str(format(self.readRegister(REG_WHOAMI), '#04x')) + " | Binary: " + format(self.readRegister(REG_WHOAMI), 'b').zfill(8)) + print("REG_F_SETUP (0x09):" + str(format(self.readRegister(REG_F_SETUP), '#04x')) + " | Binary: " + format(self.readRegister(REG_F_SETUP), 'b').zfill(8)) + print("REG_XYZ_DATA_CFG (0x0e):" + str(format(self.readRegister(REG_XYZ_DATA_CFG), '#04x')) + " | Binary: " + format(self.readRegister(REG_XYZ_DATA_CFG), 'b').zfill(8)) + print("REG_CTRL_REG1 (0x2a):" + str(format(self.readRegister(REG_CTRL_REG1), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG1), 'b').zfill(8)) + print("REG_CTRL_REG2 (0x2b):" + str(format(self.readRegister(REG_CTRL_REG2), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG2), 'b').zfill(8)) + print("REG_CTRL_REG3 (0x2c):" + str(format(self.readRegister(REG_CTRL_REG3), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG3), 'b').zfill(8)) + print("REG_CTRL_REG4 (0x2d):" + str(format(self.readRegister(REG_CTRL_REG4), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG4), 'b').zfill(8)) + print("REG_CTRL_REG5 (0x2e):" + str(format(self.readRegister(REG_CTRL_REG5), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG5), 'b').zfill(8)) + print("REG_PL_STATUS (0x10):" + str(format(self.readRegister(REG_PL_STATUS), '#04x')) + " | Binary: " + format(self.readRegister(REG_PL_STATUS), 'b').zfill(8)) + print ("debugRealTime " + str(runTimeConfigObject.debugRealTime)) + print ("NumInterrupts " + str(runTimeConfigObject.NumInterrupts)) + + def debugShowOrientation(self): + print("Position = %d" % (self.get_orientation())) + + def debugShowAxisAcceleration(self, xaccel, yaccel, zaccel): + print(" x (m/s2)= %+.3f" % (xaccel)) + print(" y (m/s2)= %+.3f" % (yaccel)) + print(" z (m/s2)= %+.3f" % (zaccel)) + + def debugRealTimeBuffer(self): + n = 0 + for elements in accelBuffer: + myData = accelBuffer.pop() + n += 1 + print ("N=" + str(n) + " myData=" + str(myData)) # + "Element=" + str(elements)) + try: + print("End of printout\n") + #time.sleep(1.0) + # os.system("clear") + except KeyboardInterrupt: + print("Program Termination Requested") + sys.exit() + +############################################################################### +# Threading functions +############################################################################### +#def rssClient(): +# """Manage data shipping over th network, in a separate thread.""" +# #logger.debug('Thread Starting') +# while True: +# time.sleep(1.0) +# print ("This is thread rssClient()") +# +############################################################################### +# Useful functions +############################################################################### +def printHelp(): + print ("\n") + print ("usage: accel.py [options]") + print ("Available options:") + print (" -h \t\t Print this help and exit") + print (" -d \t\t Show debug realtime interrupt data") + print (" -s \t\t Execute silently (no screen output)") + print (" -L \t Set Log level. where is the log level (0 = NONE - 8 = DEBUG)") + print ("") + + +def main(argv): + import sys, getopt, logging + # + try: + opts, args = getopt.getopt(argv,"hdsL:") + except getopt.GetoptError: + print ("\nInvalid option requested on command line") + printHelp() + sys.exit(2) + + for opt, arg in opts: + if opt == '-h': + printHelp() + sys.exit() + elif opt == '-d': + runTimeConfigObject.debugRealTime = 1 + elif opt == '-s': + runTimeConfigObject.executeSilently = 1 + elif opt == '-L': + if (int(arg) == 0) or (int(arg) > 5): + pass + #logger.setLevel(logger.NOTSET) # Same as value 0 + elif int(arg) == 1: + logger.setLevel(logging.CRITICAL) # Same as value 50 + elif int(arg) == 2: + logger.setLevel(logging.ERROR) # Same as value 40 + elif int(arg) == 3: + logger.setLevel(logging.WARNING) # Same as value 30 + elif int(arg) == 4: + logger.setLevel(logging.INFO) # Same as value 20 + elif int(arg) == 5: + logger.setLevel(logging.DEBUG) # Same as value 10 + + +##################################################################################### +# M A I N +##################################################################################### +class runTimeConfigObject(object): + pass +#if __name__ == "__main__": +def extract_meas(): + + #class runTimeConfigObject(object): + #pass + # + # Setup Logger + # + #logger = logging.basicConfig(level=logging.DEBUG, format='[%(asctime)15s].%(levelname)s] (%(threadName)-10s) %(message)s', ) + #logger.basicConfig(level=logging.DEBUG,format='[%(asctime)15s].%(levelname)s] (%(threadName)-10s) %(message)s',) + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + # create console handler and set level to debug + ch = logging.StreamHandler() + ch.setLevel(logging.DEBUG) + # create formatter + formatter = logging.Formatter('[%(asctime)s.%(levelname)s] (%(name)s.%(threadName)-10s) : %(message)s') + # add formatter to ch + ch.setFormatter(formatter) + # add ch to logger + logger.addHandler(ch) + + # + # Set some default command line options + # + runTimeConfig = runTimeConfigObject() + runTimeConfigObject.debugRealTime = 0 # 1 = Show debug realtime interrupt data + runTimeConfigObject.executeSilently = 0 # 1 = Execute silently (no sceen output) + runTimeConfigObject.NumInterrupts = 0 # keep Nbr of sensor interrupts withi the main loop + + main(sys.argv[1:]) + + # + # Read configuration file + # + configFile = "./rss_config.dat" + #logger.debug('Reading Config file: ' + configFile) #Commented out by Henry + sections = {'GeoData', 'DeviceInfo', 'Networking'} + #configParameters = {} + #Config = ConfigParser.ConfigParser() + #Config.read(configFile) + #for section in sections: + # try: + # options = Config.options(section) + # except: + # print ("ERROR: Section '" + section + "' Not found in config file: '" + configFile + "'.") + # sys.exit() + # for option in options: + # try: + # configParameters[option] = Config.get(section, option) + # except: + # configParameters[option] = None + # logger.debug("Config Section: " + section + " / Option: " + option + " => " + configParameters[option]) + + MMA8451 = Accel() + #os.system("clear") + MMA8451.init() + + if MMA8451.whoAmI() != deviceName: + print("Error! Device not recognized! (" + str(deviceName) + ")") + sys.exit() + + # + # Thread client start + # Commented out by Henry + ''' + import rss_client + pill2kill = threading.Event() + #threadClient = threading.Thread(name='netClientWorker', target=rss_client.cli_worker, args=(pill2kill, configParameters, accelBuffer)) + threadClient = threading.Thread(name='netClientWorker', target=rss_client.cli_worker, args=(pill2kill, accelBuffer)) + threadClient.setDaemon(False) #threadClient.daemon = False + threadClient.start() + myThread = [] + myThread.append('netClientWorker') + ''' + + #Added by Henry: + count_samples = 5 #num of samples we want + count_taken = 0 + xvals = [] + yvals = [] + zvals = [] + while count_taken < count_samples: + if runTimeConfigObject.executeSilently == 0: + axes = MMA8451.getAxisValue() + print("X: " + str(axes['x']) + ", Y: " + str(axes['y']) + ", Z: " + str(axes['z'])) + xvals.append(axes['x']) + yvals.append(axes['y']) + zvals.append(axes['z']) + count_taken = count_taken + 1 + return xvals,yvals,zvals + + #Commented Out by Henry: + ''' + while True: # forever loop + if runTimeConfigObject.executeSilently == 0: + print ("\nCurrent Date-Time: " + str(datetime.datetime.now())) + print ("Raspberry Bus = " + str(MMA8451.raspiBus)) + print ("Raspberry Interrupt = " + str(MMA8451.raspiIntEnabled)) + print ("Number of elemets = " + str(len(accelBuffer))) + MMA8451.debugShowRpiInfo() + MMA8451.debugShowRegisters() + MMA8451.debugShowOrientation() + axes = MMA8451.getAxisValue() + MMA8451.debugShowAxisAcceleration(axes['x'], axes['y'], axes['z']) + # + if runTimeConfigObject.debugRealTime != 0: + MMA8451.debugRealTimeBuffer() + + runTimeConfigObject.NumInterrupts = 0 + try: + time.sleep(1.0) + except KeyboardInterrupt: + logger.debug ("Killing threads...") + pill2kill.set() + threadClient.join() + time.sleep(1.0) + + logger.debug("\nUser termination requested!\n") + sys.exit() + + sys.exit() + ''' + diff --git a/Nov_27/Full/Camera/accel_correct_config/raspidata.py b/Nov_27/Full/Camera/accel_correct_config/raspidata.py new file mode 100644 index 0000000..fb99cbb --- /dev/null +++ b/Nov_27/Full/Camera/accel_correct_config/raspidata.py @@ -0,0 +1,48 @@ +""" A Raspberry Pi class. +To access some of the most useful hardware information +""" + + +#class RaspiData(): + + + # Get Raspberry Serial Number + # You can do it in bash: + # cat /proc/cpuinfo | perl -n -e '/^Serial[ ]*: ([0-9a-f]{16})$/ && print "$1\n"' + # Or with perl: + # cat cpuinfo | perl -n -e '/^Serial[ ]*: ([0-9a-f]{16})$/ && print "$1\n"' + # + # + + +# def __init__(self): +# pass +from uuid import getnode as get_mac + +# @staticmethod +# def get_serial(self): +def get_serial(): + """Extract serial from cpuinfo file""" + cpu_serial= "0000000000000000" + try: + f = open('/proc/cpuinfo','r') + for line in f: + if line[0:6]=='Serial': + cpu_serial = line[10:26] + f.close() + except: + cpu_serial = "ERROR000000000" + return cpu_serial + + +def mac_address(): + """Extract rth0 MAC address""" + # mac = '00:00:00:00:00:00' + # mac = '00:00:00:00:00:00' + try: + t = get_mac() + except: + t = "000000000000" + mac = ':'.join(("%012X" % t)[i:i+2] for i in range(0, 12, 2)) + return mac + diff --git a/Nov_27/Full/Camera/accel_correct_config/rss_cli_config.py b/Nov_27/Full/Camera/accel_correct_config/rss_cli_config.py new file mode 100644 index 0000000..e10aa53 --- /dev/null +++ b/Nov_27/Full/Camera/accel_correct_config/rss_cli_config.py @@ -0,0 +1,21 @@ +# [GeoData] +City = 'Rome' +cityname = 'Rome' +latitude = 41.947550 +longitude = 12.469794 +deviceorientation = 'L' + +# [DeviceInfo] +devicetype = 'raspberry' +devicename = 'rssd0001' +sensorname = 'mma8451' +sensortheshold = 20 +logfile = './rssd.log' + +# [Networking] +#serveraddress = 'www.diprimio.com' +serveraddress = 'localhost' +serverprotocol = 'tcp' +servertcpport = 15000 +serverhearthbit = 100 +receivebuffersize = 1024 diff --git a/Nov_27/Full/Camera/accel_correct_config/rss_client.py b/Nov_27/Full/Camera/accel_correct_config/rss_client.py new file mode 100644 index 0000000..a2a4d1b --- /dev/null +++ b/Nov_27/Full/Camera/accel_correct_config/rss_client.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# -*- coding:utf-8, indent=tab, tabstop=4 -*- +# +# See 'LICENSE' for copying +# +# This file contains the code for the client module of 'accel.py' +# +# Revision history +# Date Author Version Details +# ---------------------------------------------------------------------------------- +# 2018-01-18 Massimo Di Primio 0.06 1st file implementation + +"""Client thread worker - This is a simple client code example for 'accel'.py' program""" + +import logging +import time +import datetime +import socket +import json +import rss_client_messages as climsg +import rss_cli_config as ccfg +import raspidata + + +#def cli_connect(params): +def cli_connect(): + """Open connection to the server""" + server_address = (str(ccfg.serveraddress), int(ccfg.servertcpport)) + logging.debug('Trying to connect to server ' + str(server_address)) + # Create a TCP/IP socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + # Connect the socket to the port where the server is listening + s.connect(server_address) + logging.debug('Connection Established to server ' + str(server_address)) + except: + logging.debug( + "Failed to open connection: " + str(ccfg.serverprotocol) + + ", to IP: " + str(ccfg.serveraddress) + + ", on port: " + str(ccfg.servertcpport) + ) + return(-1) + return(s) + + +def cli_close(s): + """Close the server connection""" + if s > -1: + s.close() + + +# def cli_worker(stopEvent, config, accelBuffer): +def cli_worker(stopEvent, accelBuffer): + """A client worker as thread""" + logging.debug('Thread Starting') + s = cli_connect() # s = cli_connect(config) + send_client_hello(s) + time.sleep(0.5) + send_config_affirm_message(s) + + ts = int(time.time()) + te = ts + while not stopEvent.wait(0.3): + if len(accelBuffer) > 0: + send_accel_data(s, accelBuffer) + te = int(time.time()) + if (te - ts) > 10: + send_client_heartbit(s) + ts = int(time.time()) + + time.sleep(0.5) + send_zap_message(s) + cli_close(s) + logging.debug("Thread cliWorker is terminating as per your request.") + + +def send_accel_data(s, accelBuffer): + """Send acceleration data to the server""" + #msg = dict(cmd='ADM', timestamp=str(datetime.datetime.now()), clid=raspidata.get_serial()) + #a = 123 #str(datetime.datetime.now()) + pbuf = parse_accel_data(accelBuffer) + msg = dict(cmd = 'ADM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial(), data = pbuf) + # if len(pbuf) > 0: # this sometimes returns error (when buf is empty, it has None type) + if (pbuf is not None) and (len(pbuf) > 0): + #str = climsg.accel_data_message(pbuf) + try: + logging.debug("Sending Acceleration data to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(str) + "\n") + except: + logging.debug("Failed to send Acceleration-Data to the server") + + +def send_client_hello(s): + """Send Hello message to the server""" + msg = dict(cmd = 'CHM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial()) + try: + logging.debug("Sending Hello to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.hello_message()) + "\n") + except: + logging.debug("Failed to send Hello to the server") + + +def send_zap_message(s): + """Send Zap message to the server""" + msg = dict(cmd = 'CZM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial()) + try: + logging.debug("Sending Zap to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.zap_message()) + "\n") + except: + logging.debug("Failed to send Zap to the server") + + +def send_config_affirm_message(s): #def send_config_affirm_message(s, config): + msg_data = dict(city = ccfg.cityname, latitude = ccfg.latitude,longitude = ccfg.longitude) + msg = dict(cmd = 'CCA', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial(), config = msg_data) + try: + logging.debug("Sending client configuration to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(climsg.config_affirm_message(cfg_data)) + except: + logging.debug("Failed to send client configuration to the server") + + +def send_client_heartbit(s): + """Send Heartbit to the server""" + msg = dict(cmd = 'CHB', timestamp = str(datetime.datetime.now()), clid=raspidata.get_serial()) + try: + logging.debug("Sending Heartbit to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.heart_bit()) + "\n") + except: + logging.debug("Failed to send Heartbit to the server") + + +def parse_accel_data(b): + """Parse acceleration data to make sure we only send meaningfull data to the server""" + tsh = 10 + tbuf = [] + # tbuf.append([0, 0, 0, 0, 0]) + # bLength = len(b) + # logging.debug("parseAccelData(b) # of elements = " + str(len(b))) + if len(b) > 1: + logging.debug("parseAccelData: In AccelData/BufLen: " + str(len(b)) + "/" +str(len(tbuf))) + firstTime = 1 + prow = None + for row in b: + crow = b.pop(0) # Get the oldest record + if firstTime == 1: + prow = crow + firstTime = 0 + if ( (abs(abs(int(crow[1])) - abs(int(prow[1]))) > tsh) or + (abs(abs(int(crow[2])) - abs(int(prow[2]))) > tsh) or + (abs(abs(int(crow[3])) - abs(int(prow[3]))) > tsh) + ): + tbuf.append(crow) + prow = crow + print ("Again PROW/CROW/TBUFLEN:" + str(prow) + " / " + str(crow) + " / " + str(len(tbuf))) + + logging.debug("parseAccelData: Out AccelData/BufLen: " + str(len(b)) + "/" +str(len(tbuf))) + return(tbuf) + diff --git a/Nov_27/Full/Camera/accel_correct_config/rss_client_messages.py b/Nov_27/Full/Camera/accel_correct_config/rss_client_messages.py new file mode 100644 index 0000000..4a507d7 --- /dev/null +++ b/Nov_27/Full/Camera/accel_correct_config/rss_client_messages.py @@ -0,0 +1,113 @@ + +import datetime +import raspidata +import json +import rss_cli_config as ccfg + + +# +# All client messages are handled in here. +# +# Message Formats +# --------------- +# 1 - Timestamp +# 2 - Device ID +# 3 - Message Type +# +# Client message types +# -------------------- +# 0001 CHB - Client Heart Bit (Client is alive) +# 0002 CHM - Client Hello Message (Client is online) +# 0003 CZM - Client Zap Message (Client is shut down) +# 0004 ADM - Acceleration Data Message (Acceleration data) +# 0005 CCA - Client Config Affirm +# ... (other to come) +# +# Data message Format for all Client Message Types +# ------------------------------------------------ +# +# # 0001 - CHB - Client Heart Bit +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0001 | Var | Literally 'CHB' | +# # +-------------------------------------------------------------------------------+ +# +# 0002 CHM - Client Hello Message +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0002 | Var | Literally 'CHM' | +# +--------------+-------+--------------------------------------------------------+ +# +# 0003 CZM - Client Zap Message (Client is shut down) +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0003 | Var | Literally 'CZM' | +# +--------------+-------+--------------------------------------------------------+ +# +# 0004 ADM - Acceleration Data Message (Acceleration data) +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0004 | Var | Literally 'ADM' | +# | Accel Data | Var | Array containing acceleration data (X,Y,Z.O) | +# +--------------+-------+--------------------------------------------------------+ +# +# 0005 CCA - Client Configuration Affirm +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0004 | Var | Literally 'CCA' | +# | Config Data | Var | Array containing client configuration | +# +--------------+-------+--------------------------------------------------------+ + +########################################################################### +# WARNIG ! THIS FILE IS NOT CURRENTLY USED ! +# Its presence it is for debugging/testing only +# Althought, it will be used in some future version +########################################################################### + +#def heart_bit(): +# """Client Heart Bit""" +# msg = {'cmd': 'CHB', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def hello_message(): +# """Client Hello Message""" +# msg = {'cmd': 'CHM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def zap_message(): +# """Client Zap Message""" +# msg = {'cmd': 'CZM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def accel_data_message(data): +# """Acceleration Data Message""" +# msg = {'cmd': 'ADM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial(), 'acceldata': str(data)} +# return msg +# +# +#def config_affirm_message(data): #def config_affirm_message(data): +# """Client Configuration Affirm""" +# ### +# pkt_hdr = {'cmd': 'CCA', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial(), 'data' : data} +# +# msg = dict(city = ccfg.cityname, latitude = ccfg.latitude, longitude = ccfg.longitude, config = data) +# return msg + diff --git a/Nov_27/Full/Camera/communication_module/._communication.py b/Nov_27/Full/Camera/communication_module/._communication.py new file mode 100644 index 0000000..f2e25e8 Binary files /dev/null and b/Nov_27/Full/Camera/communication_module/._communication.py differ diff --git a/Nov_27/Full/Camera/communication_module/com_test.py b/Nov_27/Full/Camera/communication_module/com_test.py new file mode 100644 index 0000000..a99d3ec --- /dev/null +++ b/Nov_27/Full/Camera/communication_module/com_test.py @@ -0,0 +1,35 @@ +import requests +from requests import Session +import json +from datetime import datetime +from dateutil import parser +from random import randint + +BRIDGE_NAME = 'dummy' +dest = "http://127.0.0.1:8000/sensors/"+BRIDGE_NAME+"/update/" +PASSWORD = "djioewfj34jod2jdoi3jr0jl983jsa" + + +def send_data_to_server(x=0.0, y=0.0, z=0.0, theta=0.0, phi=0.0, psi=0.0): + payload = {'x': x, 'y': y, 'z': z, 'theta': theta, 'phi': phi, 'psi': psi} + dt = datetime.now() + cookies = {'csrftoken': encode(dt), 'time': str(dt)} + r = requests.post(dest, data=payload, cookies=cookies) + print(r.status_code) + if r.status_code == 403: + raise RuntimeWarning("CSRF ALERT ON, INSPECT YOUR SYSTEM") + else: + return r.text + + +def encode(time_sign): + len_pw = len(PASSWORD) + index = (time_sign.year + time_sign.month * 100 + time_sign.day + time_sign.hour * time_sign.minute + * time_sign.second) % len_pw + repl = chr(randint(97, 122)) + return PASSWORD[:index] + repl + PASSWORD[index+1:] + + +print(send_data_to_server(0.5, 1.5, 1.5)) +#send_data_form(1.0, 2.0, 3.0) +#cookies = {'csrftoken': "djioewfj34jod2jdoi3jr0jl983jsa", 'TIME': datetime.now()} diff --git a/Nov_27/Full/Camera/communication_module/communication.py b/Nov_27/Full/Camera/communication_module/communication.py new file mode 100644 index 0000000..8c8b9a4 --- /dev/null +++ b/Nov_27/Full/Camera/communication_module/communication.py @@ -0,0 +1,28 @@ +import requests, sys +from requests import Session +import json +from datetime import datetime +from dateutil import parser +from random import randint +sys.path.insert(0,"/home/pi/Desktop/Full_Demo/transfer_test_correct_config") +from SETTINGS import PASSWORD, SERVER + +dest = SERVER + +def send_data_to_server(x=0.0, y=0.0, z=0.0, theta=0.0, phi=0.0, psi=0.0): + payload = {'x': x, 'y': y, 'z': z, 'theta': theta, 'phi': phi, 'psi': psi} + dt = datetime.now() + cookies = {'csrftoken': encode(dt), 'time': str(dt)} + r = requests.post(dest, data=payload, cookies=cookies) + if r.status_code == 403: + raise RuntimeWarning("CSRF ALERT ON, INSPECT YOUR SYSTEM") + else: + return r.text + + +def encode(time_sign): + len_pw = len(PASSWORD) + index = (time_sign.year + time_sign.month * 100 + time_sign.day + time_sign.hour * time_sign.minute + * time_sign.second) % len_pw + repl = chr(randint(97, 122)) + return PASSWORD[:index] + repl + PASSWORD[index+1:] \ No newline at end of file diff --git a/Nov_27/Full/Camera/img_rec_module/._img_1_1new_meas.txt b/Nov_27/Full/Camera/img_rec_module/._img_1_1new_meas.txt new file mode 100644 index 0000000..6ccf872 Binary files /dev/null and b/Nov_27/Full/Camera/img_rec_module/._img_1_1new_meas.txt differ diff --git a/Nov_27/Full/Camera/img_rec_module/FastDataMatrixTest.py b/Nov_27/Full/Camera/img_rec_module/FastDataMatrixTest.py new file mode 100644 index 0000000..21cdf8d --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/FastDataMatrixTest.py @@ -0,0 +1,45 @@ +from img_rec_module.sig_proc_test import FM +import numpy as np +from random import randint +import traceback +import sys + +matrix = np.random.rand(20, 30) + + +def segmentation_test(sample): + ax = randint(0, 1) + target = randint(0, 19) if ax == 1 else randint(0, 29) + fmat = FM(matrix, ax, target) + assert fmat.irange() == 20 if ax == 1 else fmat.irange() == 30 + cap = len(fmat) + for i in range(sample): + start = randint(0, cap - 1) + end = randint(start + 1, cap) + fmat.segmentize(start, end) + assert len(fmat.extract_array()) == end - start, "start: {0}, end: {1}".format(start, end) + elem = randint(0, len(fmat) - 1) + assert fmat[elem] == matrix.item(target, elem + start) if ax == 1 \ + else fmat[elem] == matrix.item(elem + start, target) + print("Test 1 passed!") + return fmat.copy() + + +def shape_change_test(sample): + fmat = mat + print(len(fmat), "start: {0}, end: {1}, ax: {2}, index: {3}".format(fmat.start, fmat.end, fmat._ax, fmat._index)) + for i in range(sample): + ax = randint(0, 1) + target = randint(0, 19) if ax == 1 else randint(0, 29) + try: + fmat = fmat.copy(ax, target) + elem = randint(0, len(fmat) - 1) + assert fmat[elem] == matrix.item(target, elem) if ax == 1 else fmat[elem] == matrix.item(elem, target), "start: {0}, end: {1}, ax: {2}, index: {3}, changed:{4}, elem: {5}".format(fmat.start, fmat.end, ax, fmat._index, target, elem) + except IndexError: + print("Index Error, start: {0}, end: {1}, ax: {2}, index: {3}".format(fmat.start, fmat.end, fmat._ax, fmat._index)) + traceback.print_exc(file=sys.stderr) + sys.exit(0) + print("Test 2 passed!") + +mat = segmentation_test(1000000) +shape_change_test(1000000) \ No newline at end of file diff --git a/Nov_27/Full/Camera/img_rec_module/HoughLineTest.py b/Nov_27/Full/Camera/img_rec_module/HoughLineTest.py new file mode 100644 index 0000000..a338b2c --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/HoughLineTest.py @@ -0,0 +1,70 @@ +from img_rec_module.sig_proc_test import HoughLine, angle_interp, normalize_angle +import numpy as np +from random import uniform +from math import sin, cos, asin, acos, degrees + + +def angle_interp_test(sample): + for t in range(4): + angle = np.pi * t / 2 + angle_test(angle) + for i in range(sample): + angle = uniform(0, 2 * np.pi) + angle_test(angle) + print("All tests passed!") + + +def angle_test(angle): + s, c = sin(angle), cos(angle) + aint = angle_interp(s, c) + e = abs(aint - angle) + assert e < 10 ** (-8), "angle: {0} aint: {3} sin: {1}, cos: {2}".format(degrees(angle), s, c, degrees(aint)) + + +data1 = [(50, 93.58985799408744), (100, 94.83752561512769), (150, 93.46476622047003), (200, 92.12757475618413), (250, 91.21899822237681), (300, 94.66610143151713), (350, 93.39700158152765), (400, 93.55400856320203), (450, 94.81488837189904)] +data2 = [(50, 220.68898677024384), (150, 207.0369850844262), (200, 219.1873113806197), (250, 218.4221525438996), (300, 215.83141259108666), (350, 216.1097540779057), (400, 214.30630223604018), (450, 211.84789180370862), (500, 211.03929058602466), (550, 208.37556376057634), (600, 208.1358916890448)] + + +def diagnose(): + x1 = np.array([d[1] for d in data1]) + y1 = np.array([d[0] for d in data1]) + line1 = HoughLine(x=x1, data=y1) + x2 = np.array([d[0] for d in data2]) + y2 = np.array([d[1] for d in data2]) + line2 = HoughLine(x=x2, data=y2) + xmean = sum(x1) / len(x1) + ymean = sum(y2) / len(y2) + print(line1._r, line1._t) + print(line2._r, line2._t) + print((xmean, ymean), HoughLine.intersect(line1, line2)) + + +def normalize_angle_test(sample): + for t in range(4): + angle = np.pi * t / 2 + test_normalize(angle) + for i in range(sample): + angle = uniform(0, 1000000) + test_normalize(angle) + print('All tests passed!') + + +def test_normalize(angle): + s, c = sin(angle), cos(angle) + norm_ang = normalize_angle(angle) + ns, nc = sin(norm_ang), cos(norm_ang) + case1 = equal_within_error(s, ns) and equal_within_error(c, nc) + case2 = equal_within_error(s, -ns) and equal_within_error(c, -nc) + assert case1 or case2, 's:{0} c:{1}, ns:{2}, nc:{3}, angle:{4}, norm:{5}'.format(s, c, ns, nc, angle, norm_ang) + + + +def equal_within_error(v1, v2): + e = abs(v1 - v2) + return e < 10 ** (-8) + + +if __name__ == '__main__': + #angle_interp_test(100000000) + #diagnose() + normalize_angle_test(1000000) \ No newline at end of file diff --git a/Nov_27/Full/Camera/img_rec_module/__init__.py b/Nov_27/Full/Camera/img_rec_module/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/centers.txt b/Nov_27/Full/Camera/img_rec_module/centers.txt new file mode 100644 index 0000000..ea1e64b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/centers.txt @@ -0,0 +1,640 @@ +135.5 +134.5 +134.0 +127.5 +131.0 +131.0 +133.5 +131.0 +131.5 +131.5 +129.5 +135.5 +135.5 +126.5 +134.0 +131.5 +132.5 +128.5 +131.5 +134.5 +130.5 +1.0 +132.5 +129.5 +70.5 +131.5 +132.5 +132.0 +132.5 +129.5 +135.5 +129.5 +132.5 +130.5 +131.5 +134.0 +72.0 +67.5 +130.5 +135.0 +132.0 +133.5 +130.5 +129.5 +129.5 +132.0 +130.5 +134.0 +129.5 +136.0 +129.5 +127.5 +133.5 +131.0 +134.0 +131.5 +128.5 +132.0 +132.5 +136.0 +132.0 +133.5 +132.0 +132.5 +132.0 +129.0 +138.5 +133.5 +134.0 +132.5 +132.5 +134.0 +134.5 +131.5 +133.0 +135.5 +132.0 +130.5 +130.5 +128.0 +130.0 +133.0 +132.0 +136.0 +135.5 +132.5 +135.5 +130.5 +136.5 +136.5 +129.5 +129.0 +130.0 +138.5 +135.0 +127.5 +126.5 +135.5 +135.5 +130.5 +127.5 +131.5 +136.5 +134.5 +136.5 +133.5 +133.0 +131.5 +130.0 +136.5 +135.5 +135.0 +134.0 +133.0 +131.5 +130.5 +132.5 +135.5 +133.5 +129.5 +133.0 +136.5 +129.0 +135.5 +133.5 +133.5 +134.0 +129.5 +133.5 +132.0 +134.5 +137.0 +130.5 +129.5 +130.5 +131.5 +133.5 +137.5 +134.5 +130.5 +131.0 +134.0 +137.5 +132.5 +128.0 +129.0 +132.0 +136.5 +129.5 +128.0 +127.5 +128.0 +135.0 +128.5 +129.0 +135.0 +137.5 +136.0 +131.5 +131.0 +130.0 +134.0 +135.5 +133.0 +134.5 +134.0 +133.0 +132.0 +135.0 +132.0 +135.5 +132.5 +130.5 +127.5 +131.5 +131.0 +134.0 +131.0 +129.0 +130.0 +129.0 +129.5 +133.0 +132.0 +127.5 +131.5 +135.0 +134.0 +133.0 +133.0 +130.0 +130.5 +127.5 +133.0 +135.0 +134.0 +135.5 +131.5 +129.5 +128.5 +138.5 +134.0 +132.0 +135.5 +132.0 +128.0 +127.5 +134.5 +130.0 +130.5 +131.0 +129.5 +125.5 +130.0 +130.5 +134.5 +137.5 +129.5 +132.5 +134.0 +131.5 +134.0 +128.5 +131.5 +134.0 +133.5 +134.0 +133.0 +132.5 +130.5 +126.5 +128.5 +130.0 +128.0 +131.5 +131.0 +129.5 +132.5 +131.0 +129.5 +127.5 +135.0 +126.5 +141.5 +132.5 +133.0 +136.0 +131.0 +129.0 +134.5 +130.5 +127.5 +133.0 +133.5 +131.5 +135.5 +134.0 +131.0 +133.5 +133.5 +133.5 +127.5 +132.0 +132.5 +134.5 +132.0 +132.0 +128.0 +132.0 +136.0 +136.0 +132.5 +134.5 +137.0 +131.0 +131.5 +137.0 +130.5 +128.0 +133.0 +129.5 +135.0 +140.0 +130.5 +134.5 +129.0 +136.0 +128.0 +133.5 +136.5 +135.0 +127.5 +131.5 +139.5 +131.5 +128.5 +136.0 +135.0 +131.5 +131.5 +133.5 +127.5 +135.5 +135.5 +128.0 +130.0 +127.5 +128.0 +130.0 +126.5 +142.5 +134.5 +134.5 +124.5 +126.5 +129.5 +131.0 +129.5 +131.5 +127.0 +127.5 +135.0 +134.5 +131.5 +126.0 +130.5 +132.0 +138.0 +131.5 +135.5 +125.0 +133.0 +127.5 +136.5 +131.5 +131.5 +131.0 +124.0 +128.5 +137.5 +133.5 +130.0 +131.0 +129.0 +133.0 +131.0 +125.5 +129.5 +132.0 +129.5 +137.5 +128.5 +130.0 +131.0 +134.5 +130.0 +131.5 +131.5 +136.5 +134.0 +132.0 +136.0 +126.5 +128.0 +133.5 +135.5 +129.0 +133.0 +131.5 +132.0 +129.5 +126.0 +126.0 +130.5 +135.0 +129.0 +131.0 +130.5 +131.5 +135.5 +133.5 +134.0 +131.5 +126.0 +130.0 +131.0 +131.5 +130.5 +133.5 +130.0 +125.0 +126.5 +133.5 +132.0 +129.5 +133.5 +130.5 +132.5 +136.0 +135.0 +130.0 +129.5 +134.0 +135.5 +131.5 +135.5 +135.5 +131.5 +130.0 +130.0 +131.5 +132.0 +129.5 +131.5 +127.5 +136.0 +131.0 +134.5 +135.0 +126.5 +128.0 +131.5 +131.5 +127.0 +130.0 +130.5 +136.5 +130.5 +129.0 +130.0 +130.5 +135.5 +125.5 +130.5 +130.0 +127.5 +132.5 +133.5 +130.0 +127.5 +126.0 +132.0 +127.0 +126.0 +130.5 +127.5 +127.5 +129.5 +131.5 +133.0 +129.5 +127.0 +129.0 +126.5 +130.5 +130.0 +126.5 +128.5 +126.5 +126.5 +127.5 +134.0 +136.5 +129.5 +130.0 +128.5 +130.0 +127.5 +130.5 +135.0 +137.5 +130.0 +129.5 +134.5 +130.5 +127.5 +132.5 +129.0 +132.5 +130.0 +133.5 +127.5 +129.5 +129.0 +124.5 +126.5 +126.0 +128.0 +130.0 +133.0 +129.5 +131.0 +128.5 +132.5 +129.5 +199.5 +133.5 +133.5 +130.0 +127.5 +114.0 +227.5 +113.5 +134.5 +129.5 +130.0 +128.5 +130.0 +132.5 +126.5 +127.5 +129.0 +135.5 +129.5 +126.5 +127.5 +132.5 +127.0 +131.0 +124.5 +132.5 +128.0 +129.5 +135.5 +131.5 +129.0 +131.5 +132.0 +131.5 +130.5 +130.5 +136.5 +135.5 +131.5 +129.0 +130.5 +130.0 +129.0 +130.5 +128.0 +126.5 +133.5 +131.0 +129.0 +128.0 +131.5 +132.5 +128.5 +134.5 +130.0 +127.5 +130.0 +129.5 +131.5 +127.5 +131.0 +129.0 +127.5 +135.5 +128.0 +127.0 +131.0 +131.0 +129.5 +126.0 +128.5 +128.5 +131.0 +126.0 +132.5 +128.0 +130.0 +133.0 +127.5 +128.5 +131.5 +135.5 +133.0 +133.0 +131.0 +132.0 +128.0 +132.0 +130.0 +132.5 +128.5 +127.5 +130.5 +130.0 +131.5 +128.5 +126.5 +132.0 +126.5 +129.5 +128.0 +127.0 +126.5 +133.5 +128.5 +135.5 +133.5 +132.5 +132.0 +132.5 +131.5 +131.0 +131.0 +129.5 +130.5 +127.0 +127.5 +125.0 +129.5 +130.5 +130.5 +132.5 +128.0 +129.5 +126.5 +125.5 +125.0 +131.5 +130.0 +131.5 +128.5 +127.0 +134.0 +129.0 +132.5 +130.0 +129.5 +129.0 +129.0 +126.5 +127.5 +128.0 +125.5 +131.0 +129.5 diff --git a/Nov_27/Full/Camera/img_rec_module/flags.txt b/Nov_27/Full/Camera/img_rec_module/flags.txt new file mode 100644 index 0000000..b15d479 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/flags.txt @@ -0,0 +1,274 @@ +COLOR_BAYER_BG2BGR +COLOR_BAYER_BG2BGRA +COLOR_BAYER_BG2BGR_EA +COLOR_BAYER_BG2BGR_VNG +COLOR_BAYER_BG2GRAY +COLOR_BAYER_BG2RGB +COLOR_BAYER_BG2RGBA +COLOR_BAYER_BG2RGB_EA +COLOR_BAYER_BG2RGB_VNG +COLOR_BAYER_GB2BGR +COLOR_BAYER_GB2BGRA +COLOR_BAYER_GB2BGR_EA +COLOR_BAYER_GB2BGR_VNG +COLOR_BAYER_GB2GRAY +COLOR_BAYER_GB2RGB +COLOR_BAYER_GB2RGBA +COLOR_BAYER_GB2RGB_EA +COLOR_BAYER_GB2RGB_VNG +COLOR_BAYER_GR2BGR +COLOR_BAYER_GR2BGRA +COLOR_BAYER_GR2BGR_EA +COLOR_BAYER_GR2BGR_VNG +COLOR_BAYER_GR2GRAY +COLOR_BAYER_GR2RGB +COLOR_BAYER_GR2RGBA +COLOR_BAYER_GR2RGB_EA +COLOR_BAYER_GR2RGB_VNG +COLOR_BAYER_RG2BGR +COLOR_BAYER_RG2BGRA +COLOR_BAYER_RG2BGR_EA +COLOR_BAYER_RG2BGR_VNG +COLOR_BAYER_RG2GRAY +COLOR_BAYER_RG2RGB +COLOR_BAYER_RG2RGBA +COLOR_BAYER_RG2RGB_EA +COLOR_BAYER_RG2RGB_VNG +COLOR_BGR2BGR555 +COLOR_BGR2BGR565 +COLOR_BGR2BGRA +COLOR_BGR2GRAY +COLOR_BGR2HLS +COLOR_BGR2HLS_FULL +COLOR_BGR2HSV +COLOR_BGR2HSV_FULL +COLOR_BGR2LAB +COLOR_BGR2LUV +COLOR_BGR2Lab +COLOR_BGR2Luv +COLOR_BGR2RGB +COLOR_BGR2RGBA +COLOR_BGR2XYZ +COLOR_BGR2YCR_CB +COLOR_BGR2YCrCb +COLOR_BGR2YUV +COLOR_BGR2YUV_I420 +COLOR_BGR2YUV_IYUV +COLOR_BGR2YUV_YV12 +COLOR_BGR5552BGR +COLOR_BGR5552BGRA +COLOR_BGR5552GRAY +COLOR_BGR5552RGB +COLOR_BGR5552RGBA +COLOR_BGR5652BGR +COLOR_BGR5652BGRA +COLOR_BGR5652GRAY +COLOR_BGR5652RGB +COLOR_BGR5652RGBA +COLOR_BGRA2BGR +COLOR_BGRA2BGR555 +COLOR_BGRA2BGR565 +COLOR_BGRA2GRAY +COLOR_BGRA2RGB +COLOR_BGRA2RGBA +COLOR_BGRA2YUV_I420 +COLOR_BGRA2YUV_IYUV +COLOR_BGRA2YUV_YV12 +COLOR_BayerBG2BGR +COLOR_BayerBG2BGRA +COLOR_BayerBG2BGR_EA +COLOR_BayerBG2BGR_VNG +COLOR_BayerBG2GRAY +COLOR_BayerBG2RGB +COLOR_BayerBG2RGBA +COLOR_BayerBG2RGB_EA +COLOR_BayerBG2RGB_VNG +COLOR_BayerGB2BGR +COLOR_BayerGB2BGRA +COLOR_BayerGB2BGR_EA +COLOR_BayerGB2BGR_VNG +COLOR_BayerGB2GRAY +COLOR_BayerGB2RGB +COLOR_BayerGB2RGBA +COLOR_BayerGB2RGB_EA +COLOR_BayerGB2RGB_VNG +COLOR_BayerGR2BGR +COLOR_BayerGR2BGRA +COLOR_BayerGR2BGR_EA +COLOR_BayerGR2BGR_VNG +COLOR_BayerGR2GRAY +COLOR_BayerGR2RGB +COLOR_BayerGR2RGBA +COLOR_BayerGR2RGB_EA +COLOR_BayerGR2RGB_VNG +COLOR_BayerRG2BGR +COLOR_BayerRG2BGRA +COLOR_BayerRG2BGR_EA +COLOR_BayerRG2BGR_VNG +COLOR_BayerRG2GRAY +COLOR_BayerRG2RGB +COLOR_BayerRG2RGBA +COLOR_BayerRG2RGB_EA +COLOR_BayerRG2RGB_VNG +COLOR_COLORCVT_MAX +COLOR_GRAY2BGR +COLOR_GRAY2BGR555 +COLOR_GRAY2BGR565 +COLOR_GRAY2BGRA +COLOR_GRAY2RGB +COLOR_GRAY2RGBA +COLOR_HLS2BGR +COLOR_HLS2BGR_FULL +COLOR_HLS2RGB +COLOR_HLS2RGB_FULL +COLOR_HSV2BGR +COLOR_HSV2BGR_FULL +COLOR_HSV2RGB +COLOR_HSV2RGB_FULL +COLOR_LAB2BGR +COLOR_LAB2LBGR +COLOR_LAB2LRGB +COLOR_LAB2RGB +COLOR_LBGR2LAB +COLOR_LBGR2LUV +COLOR_LBGR2Lab +COLOR_LBGR2Luv +COLOR_LRGB2LAB +COLOR_LRGB2LUV +COLOR_LRGB2Lab +COLOR_LRGB2Luv +COLOR_LUV2BGR +COLOR_LUV2LBGR +COLOR_LUV2LRGB +COLOR_LUV2RGB +COLOR_Lab2BGR +COLOR_Lab2LBGR +COLOR_Lab2LRGB +COLOR_Lab2RGB +COLOR_Luv2BGR +COLOR_Luv2LBGR +COLOR_Luv2LRGB +COLOR_Luv2RGB +COLOR_M_RGBA2RGBA +COLOR_RGB2BGR +COLOR_RGB2BGR555 +COLOR_RGB2BGR565 +COLOR_RGB2BGRA +COLOR_RGB2GRAY +COLOR_RGB2HLS +COLOR_RGB2HLS_FULL +COLOR_RGB2HSV +COLOR_RGB2HSV_FULL +COLOR_RGB2LAB +COLOR_RGB2LUV +COLOR_RGB2Lab +COLOR_RGB2Luv +COLOR_RGB2RGBA +COLOR_RGB2XYZ +COLOR_RGB2YCR_CB +COLOR_RGB2YCrCb +COLOR_RGB2YUV +COLOR_RGB2YUV_I420 +COLOR_RGB2YUV_IYUV +COLOR_RGB2YUV_YV12 +COLOR_RGBA2BGR +COLOR_RGBA2BGR555 +COLOR_RGBA2BGR565 +COLOR_RGBA2BGRA +COLOR_RGBA2GRAY +COLOR_RGBA2M_RGBA +COLOR_RGBA2RGB +COLOR_RGBA2YUV_I420 +COLOR_RGBA2YUV_IYUV +COLOR_RGBA2YUV_YV12 +COLOR_RGBA2mRGBA +COLOR_XYZ2BGR +COLOR_XYZ2RGB +COLOR_YCR_CB2BGR +COLOR_YCR_CB2RGB +COLOR_YCrCb2BGR +COLOR_YCrCb2RGB +COLOR_YUV2BGR +COLOR_YUV2BGRA_I420 +COLOR_YUV2BGRA_IYUV +COLOR_YUV2BGRA_NV12 +COLOR_YUV2BGRA_NV21 +COLOR_YUV2BGRA_UYNV +COLOR_YUV2BGRA_UYVY +COLOR_YUV2BGRA_Y422 +COLOR_YUV2BGRA_YUNV +COLOR_YUV2BGRA_YUY2 +COLOR_YUV2BGRA_YUYV +COLOR_YUV2BGRA_YV12 +COLOR_YUV2BGRA_YVYU +COLOR_YUV2BGR_I420 +COLOR_YUV2BGR_IYUV +COLOR_YUV2BGR_NV12 +COLOR_YUV2BGR_NV21 +COLOR_YUV2BGR_UYNV +COLOR_YUV2BGR_UYVY +COLOR_YUV2BGR_Y422 +COLOR_YUV2BGR_YUNV +COLOR_YUV2BGR_YUY2 +COLOR_YUV2BGR_YUYV +COLOR_YUV2BGR_YV12 +COLOR_YUV2BGR_YVYU +COLOR_YUV2GRAY_420 +COLOR_YUV2GRAY_I420 +COLOR_YUV2GRAY_IYUV +COLOR_YUV2GRAY_NV12 +COLOR_YUV2GRAY_NV21 +COLOR_YUV2GRAY_UYNV +COLOR_YUV2GRAY_UYVY +COLOR_YUV2GRAY_Y422 +COLOR_YUV2GRAY_YUNV +COLOR_YUV2GRAY_YUY2 +COLOR_YUV2GRAY_YUYV +COLOR_YUV2GRAY_YV12 +COLOR_YUV2GRAY_YVYU +COLOR_YUV2RGB +COLOR_YUV2RGBA_I420 +COLOR_YUV2RGBA_IYUV +COLOR_YUV2RGBA_NV12 +COLOR_YUV2RGBA_NV21 +COLOR_YUV2RGBA_UYNV +COLOR_YUV2RGBA_UYVY +COLOR_YUV2RGBA_Y422 +COLOR_YUV2RGBA_YUNV +COLOR_YUV2RGBA_YUY2 +COLOR_YUV2RGBA_YUYV +COLOR_YUV2RGBA_YV12 +COLOR_YUV2RGBA_YVYU +COLOR_YUV2RGB_I420 +COLOR_YUV2RGB_IYUV +COLOR_YUV2RGB_NV12 +COLOR_YUV2RGB_NV21 +COLOR_YUV2RGB_UYNV +COLOR_YUV2RGB_UYVY +COLOR_YUV2RGB_Y422 +COLOR_YUV2RGB_YUNV +COLOR_YUV2RGB_YUY2 +COLOR_YUV2RGB_YUYV +COLOR_YUV2RGB_YV12 +COLOR_YUV2RGB_YVYU +COLOR_YUV420P2BGR +COLOR_YUV420P2BGRA +COLOR_YUV420P2GRAY +COLOR_YUV420P2RGB +COLOR_YUV420P2RGBA +COLOR_YUV420SP2BGR +COLOR_YUV420SP2BGRA +COLOR_YUV420SP2GRAY +COLOR_YUV420SP2RGB +COLOR_YUV420SP2RGBA +COLOR_YUV420p2BGR +COLOR_YUV420p2BGRA +COLOR_YUV420p2GRAY +COLOR_YUV420p2RGB +COLOR_YUV420p2RGBA +COLOR_YUV420sp2BGR +COLOR_YUV420sp2BGRA +COLOR_YUV420sp2GRAY +COLOR_YUV420sp2RGB +COLOR_YUV420sp2RGBA +COLOR_mRGBA2RGBA diff --git a/Nov_27/Full/Camera/img_rec_module/img_1_1_meas.txt b/Nov_27/Full/Camera/img_rec_module/img_1_1_meas.txt new file mode 100644 index 0000000..97ed4c5 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_1_1_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 384.9492753623189; +y: zero_crossing: 128.7986577181208, edge_converge: 124.79086538461539 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 385.07291666666663; +y: zero_crossing: 129.5, edge_converge: 125.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 383.90625, edge_converge: 379.9741379310345; +y: zero_crossing: 129.52727272727273, edge_converge: 130.70366132723112 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 379.9741379310345; +y: zero_crossing: 129.6, edge_converge: 130.70366132723112 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 379.9741379310345; +y: zero_crossing: 129.68627450980392, edge_converge: 130.70366132723112 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 383.6551724137931, edge_converge: 379.9741379310345; +y: zero_crossing: 129.55172413793105, edge_converge: 130.70366132723112 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 383.55172413793105, edge_converge: 379.9741379310345; +y: zero_crossing: 129.5, edge_converge: 130.70366132723112 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 383.90625, edge_converge: 379.9741379310345; +y: zero_crossing: 129.5, edge_converge: 130.70366132723112 diff --git a/Nov_27/Full/Camera/img_rec_module/img_1_1new_meas.txt b/Nov_27/Full/Camera/img_rec_module/img_1_1new_meas.txt new file mode 100644 index 0000000..70d4297 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_1_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 323.66566716641677; +y: zero_crossing: -1, edge_converge: 828.3849673202615 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 597.0; +y: zero_crossing: -1, edge_converge: 792.34375 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 880.0; +y: zero_crossing: -1, edge_converge: 796.6236413043478 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 716.546875; +y: zero_crossing: -1, edge_converge: 832.172697368421 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 321.5, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/img_20_1_meas.txt b/Nov_27/Full/Camera/img_rec_module/img_20_1_meas.txt new file mode 100644 index 0000000..8f3d333 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_20_1_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 225.33333333333334, edge_converge: 222.40969899665552; +y: zero_crossing: 222.44086021505376, edge_converge: 232.5 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 224.90625, edge_converge: 212.425; +y: zero_crossing: 222.7012987012987, edge_converge: 244.8653846153846 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 224.55172413793105, edge_converge: 225.7096153846154; +y: zero_crossing: 222.8507462686567, edge_converge: 233.3653846153846 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 224.86363636363637, edge_converge: 207.6159420289855; +y: zero_crossing: 223.22413793103448, edge_converge: 215.5216346153846 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.37254901960785, edge_converge: 238.5 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.33333333333334, edge_converge: 238.5 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.46341463414635, edge_converge: 238.5 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 224.56521739130434, edge_converge: 198.0; +y: zero_crossing: 223.57894736842104, edge_converge: 238.5 diff --git a/Nov_27/Full/Camera/img_rec_module/img_20_2_meas.txt b/Nov_27/Full/Camera/img_rec_module/img_20_2_meas.txt new file mode 100644 index 0000000..4e85aab --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_20_2_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 225.58333333333331; +y: zero_crossing: -1, edge_converge: 182.35897435897436 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 227.5; +y: zero_crossing: -1, edge_converge: 224.0 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 218.89655172413794, edge_converge: 212.9415292353823; +y: zero_crossing: -1, edge_converge: 232.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 218.86363636363637, edge_converge: 266.84375; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 218.5, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: 191.76923076923077, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/img_20_3_meas.txt b/Nov_27/Full/Camera/img_rec_module/img_20_3_meas.txt new file mode 100644 index 0000000..b228fdb --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_20_3_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 43.1578947368421, edge_converge: 27.907894736842106; +y: zero_crossing: 222.41739130434783, edge_converge: 224.8991379310345 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 222.0; +y: zero_crossing: 222.53191489361703, edge_converge: 228.6346153846154 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 225.0; +y: zero_crossing: 222.6338028169014, edge_converge: 213.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.75, edge_converge: 291.0 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.79166666666666, edge_converge: 200.0 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.7450980392157, edge_converge: 200.0 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.92105263157896, edge_converge: 200.0 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.9268292682927, edge_converge: 200.0 diff --git a/Nov_27/Full/Camera/img_rec_module/img_2_1new_meas.txt b/Nov_27/Full/Camera/img_rec_module/img_2_1new_meas.txt new file mode 100644 index 0000000..a8b0bc8 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_2_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1178.6311475409836; +y: zero_crossing: -1, edge_converge: 376.4716202270382 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 635.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1582.0; +y: zero_crossing: -1, edge_converge: 723.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1682.4423076923076; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 72.5, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 diff --git a/Nov_27/Full/Camera/img_rec_module/img_3_1new_meas.txt b/Nov_27/Full/Camera/img_rec_module/img_3_1new_meas.txt new file mode 100644 index 0000000..8cf1d3c --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_3_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 485.2365079365079; +y: zero_crossing: -1, edge_converge: 463.47727272727275 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 484.8125; +y: zero_crossing: -1, edge_converge: 464.0 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 482.4; +y: zero_crossing: 462.8421052631579, edge_converge: 464.13461538461536 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 480.5, edge_converge: 475.3696120689655; +y: zero_crossing: 462.5, edge_converge: 478.50674662668666 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 485.2307692307692, edge_converge: 493.35480943738656; +y: zero_crossing: 462.1875, edge_converge: 448.98519736842104 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 493.35480943738656; +y: zero_crossing: 462.5, edge_converge: 448.98519736842104 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 487.5, edge_converge: 493.35480943738656; +y: zero_crossing: 462.1875, edge_converge: 448.98519736842104 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 493.35480943738656; +y: zero_crossing: 462.4347826086956, edge_converge: 448.98519736842104 diff --git a/Nov_27/Full/Camera/img_rec_module/img_filter.py b/Nov_27/Full/Camera/img_rec_module/img_filter.py new file mode 100644 index 0000000..3b8b0dc --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_filter.py @@ -0,0 +1,23 @@ +import cv2 +import numpy as np +from matplotlib import pyplot as plt + +img = cv2.imread('../testpic/img_20_1.png',0) +blur = cv2.GaussianBlur(img,(5,5),0) +cv2.imshow("ok", blur) +img = blur + +laplacian = cv2.Laplacian(img,cv2.CV_64F) +sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5) +sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5) + +plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray') +plt.title('Original'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray') +plt.title('Laplacian'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') +plt.title('Sobel X'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') +plt.title('Sobel Y'), plt.xticks([]), plt.yticks([]) + +plt.show() \ No newline at end of file diff --git a/Nov_27/Full/Camera/img_rec_module/img_rec.py b/Nov_27/Full/Camera/img_rec_module/img_rec.py new file mode 100644 index 0000000..eac36ff --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/img_rec.py @@ -0,0 +1,176 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +import os +from img_rec_module.sig_proc_test import FM, compare_data_plots, compare_images + + +def identity(img): + return img + + +def grayscale(img): + return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + +def grad_detect(img, n, ori, func): + #img = np.array(img) + if ori == 'h': + grad = [func(img, n, i+1) - func(img, n, i) for i in range(img.shape[1]-1)] + else: + grad = [func(img, i+1, n) - func(img, i, n) for i in range(img.shape[0]-1)] + return grad + + +def abs_detect(img, n, ori, func): + if ori == 'h': + return [func(img, n, i) for i in range(img.shape[1])] + else: + return [func(img, i, n) for i in range(img.shape[0])] + + +def visualize_data(folder, oname, sample, orient, func, data_p=grad_detect, img_p=identity): + dirs = os.listdir(folder) + for f in dirs: + try: + img = img_p(cv2.imread(folder + f)) + interval = int(img.shape[1 if orient == 'v' else 0] / sample) + for j in range(sample): + n = j * interval + data = data_p(img, n, orient, func) + plt_save_data(data, oname + 'data_{0}{1}_'.format(orient, n) + f) + except: + print(f) + + +def max_entry(img): + max_e = 0 + for row in img: + temp = max(row) + if temp > max_e: + max_e = temp + + +def record_file(vals, fname): + f = open(fname, 'w') + for v in vals: + f.write(str(v) + '\n') + f.close() + + +def rel_lumin(img, r, c): + b = img.item(r, c, 0) + g = img.item(r, c, 1) + r = img.item(r, c, 2) + return 0.2126 * r + 0.7152 * g + 0.0722 * b + + +def max_method(img): + index = [] + s = 0 + for i in range(img.shape[1]): + val = np.argmax(img[:, i]) + index.append(val) + s += val + return s / len(index) + + +def plot_show_data(data): + plt.figure(figsize=(16, 8)) + #plt.xticks(range(0, img.shape[0], 20), range(0, img.shape[0], 20)) + plt.plot(data, 'b-') + plt.show() + plt.close() + + +def plt_save_data(data, fname): + plt.figure(figsize=(16, 8)) + plt.plot(data, 'b-') + plt.savefig(fname) + plt.close() + + +def centroid(img, func): + r = img.shape[0] + c = img.shape[1] + aggr_i = 0 + aggr_j = 0 + aggr = 0 + for i in range(r): + for j in range(c): + lum = func(img, i, j) + aggr_i += lum * i + aggr_j += lum * j + aggr += lum + dim = r * c + return aggr_i / aggr, aggr_j / aggr + # return aggr_i / dim, aggr_j / dim + + +def centroid_test(fname, n, trials, func, img_p=identity): + for i in range(1, n+1): + for j in range(1, trials+1): + cf = fname.format(i, j) + print(cf) + im = img_p(cv2.imread(cf)) + print(centroid(im, func)) + + +def brightness_test(): + BASE_DIR = '../calib/' + image_name = 'shutter_{0}_iso_{1}_bright_{2}.jpeg' + img_path = BASE_DIR + image_name + shutter = [100, 1000, 5000, 10000] + isos = [100, 400, 800] + brightness = [0, 50, 100] + expo_modes = ['auto', 'very_long'] + for ss in shutter[0:]: + comp = [] + plts = [] + print(ss) + for iso in isos: + name = img_path.format(ss, iso, 'very_long') + imgr = cv2.imread(name) + tp = (imgr, name) + comp.append(tp) + img = cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY) + plts.append((FM(img, FM.HOR, img.shape[0] // 2).extract_array(), name)) + compare_images(ilist=comp) + compare_data_plots(ilist=plts) + + +gray_p = lambda img, r, c: img.item(r, c) + +if __name__ == '__main__': + #centroid_test("../testpic/img_{0}_{1}.png", 25, 3, gray_p, img_p=grayscale) + # centroid_test("../testpic/img_{0}_{1}.png", 25, 3, rel_lumin) + + """img = cv2.imread("../testpic/png_1_1.png") + plot_show_data(abs_detect(img, 0, 'v', rel_lumin))""" + + """img = cv2.imread("../testpic/png_1_1.png") + print(img.shape) + cv2.imshow('all', img) + gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + cv2.imshow('gray', gs) + print(sum(centers) / len(centers)) + print(max_method(gs)) + record_file(centers, 'centers.txt') + + while True: + prompt = input("type in an index to draw or q to quit") + if prompt == 'q': + break + else: + plot_i(int(prompt)) + + centers = [] + for i in range(gs.shape[1]): + grad = grad_detect(gs, i, 'v', rel_lumin) + max_v = max(range(len(grad)), key=lambda i: grad[i]) + min_v = min(range(len(grad)), key=lambda i: grad[i]) + centers.append((max_v + min_v) / 2)""" + + #visualize_data("../testpic/", "../absdataplot/", 10, 'h', rel_lumin, data_p=abs_detect) + brightness_test() + diff --git a/Nov_27/Full/Camera/img_rec_module/log.docx b/Nov_27/Full/Camera/img_rec_module/log.docx new file mode 100644 index 0000000..b574f98 Binary files /dev/null and b/Nov_27/Full/Camera/img_rec_module/log.docx differ diff --git a/Nov_27/Full/Camera/img_rec_module/meas/convergence.csv b/Nov_27/Full/Camera/img_rec_module/meas/convergence.csv new file mode 100644 index 0000000..418d98a --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/convergence.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392 +60,95.68692886974831,217.86446645631813 +61,95.27930768267886,218.4321212539979 +62,179.68821344888678,221.21713400884485 +63,180.64677254143638,221.7765304937586 +64,179.86073442223173,223.68541859670074 +65,267.0750705461852,204.74717443096984 +66,267.19879488924516,209.60901887734772 +67,266.1798697712201,208.51040145394091 +73,274.3400431870006,204.75610310411912 +74,273.44321864391185,205.81069417739437 +75,273.15099171429256,205.61817173382607 +77,353.2630018061804,204.6061088758629 +78,353.8852531441488,203.30592180203516 +79,352.21840596322596,204.15679894425952 +80,312.34313113441607,204.52530436142615 +81,313.1160349693985,201.4084182788836 +82,312.11840038067925,201.00669797880116 +83,312.29317276741347,200.45780062295867 +84,132.42237239805132,254.29214663519284 +85,131.29521858798734,255.4865958538821 +86,135.9988356956537,254.77748611685175 +87,130.98094102950247,254.42187606024922 +88,174.56636927613675,254.4831815599854 +89,173.67935580024877,254.09783447631526 +90,173.36920502447623,252.290452181076 +91,175.2895186608897,257.2751667704358 +92,215.07500705655937,253.80949363235624 +93,216.94462220467622,255.47756358425315 +94,217.3834915918711,256.4745644877478 +95,219.6648004345676,255.57239348461326 +96,257.50957542067664,254.1259284055811 +97,257.570545197815,253.88751117668164 +98,257.6089813372307,253.78662089019835 +99,257.6936671647974,254.2498517060511 +100,298.2952436151055,254.76909617478606 +101,298.1169393001307,255.21794911950758 +102,298.3189654536773,255.25096983760508 +103,298.4415890038736,254.35763625124292 +104,337.66969489877954,251.71635156144524 +105,338.1116560201459,251.7179090471175 +107,337.93979130669914,251.84264636476274 +108,338.18833275957206,250.67508565210196 +113,274.2817559120019,308.9374117445766 +114,275.7421347767481,310.2555996702759 +115,276.0461325201841,310.02072804280994 +116,276.2417374542582,310.24048782871637 +117,319.6559290654899,310.99105624588617 +118,319.6313092726346,312.1826263203713 +119,319.46776160473627,311.841371820779 +120,319.76654338764155,311.98447027104925 +121,360.82585188540037,313.3258908241004 +122,360.64739266264627,312.8307783296112 +123,360.689270210389,312.2626467099784 +124,360.8335382258014,312.5428875466125 +125,442.1542117060401,317.1277309025985 +126,441.42140737582423,315.78584607818385 +127,441.5300773440553,315.90717126090226 +128,441.95769286933466,316.8407357397122 +129,481.35090878368925,317.4272946632326 +130,481.4725819590857,316.6159681822135 +131,481.1535576706723,316.8819465108059 +132,482.21933609621834,316.90676933858305 +133,59.55768321914789,300.29871844382603 +134,61.376816545951996,298.3523691730104 +135,60.60960139542109,300.5877018018443 +136,59.19985355062283,300.1851062687214 +137,102.6280068014727,297.40383468175656 +138,102.40955557323258,298.7865911290351 +139,100.57013333623348,296.8202762296189 +140,102.67850653460079,298.5730025774653 +141,120.23221696171454,300.1898879495705 +142,118.10535832779757,301.85912326532906 +143,118.16700474619614,302.0417496311767 +144,118.19187121087131,302.5378510894045 +145,143.380762851227,297.65106023170455 +146,142.46748228973178,297.3647432540817 +147,143.2239805848247,297.5672414624104 +148,140.51718892104998,297.9845023911149 +149,182.6593569656309,298.1418468359333 +150,182.64828488417706,297.92582445480707 +151,182.92797391602642,297.87455852433123 +152,183.0029286817877,297.8637465373881 +153,186.1728851830908,329.8083307385874 +154,186.5492243440529,329.1491955430002 +155,186.0292302003802,329.23752125561214 +156,186.05706501583137,329.3191466220413 +157,233.36795685970054,328.463961880729 +158,232.82586842848798,327.60883484043825 +159,229.71350413783279,328.3780985513343 +160,232.72525153041173,327.7700361791668 +161,273.76316751955034,329.73823826493043 +162,275.7575781134558,329.9125721193857 +163,273.60940070127293,330.0025820738042 +164,273.7244999819209,330.09757535831045 +165,313.3973669095876,330.59163642669836 +166,313.23094160288184,330.71155384663837 +167,313.2083786255443,330.77428522126553 +168,313.36106959216625,330.6523370232485 +169,396.3640143494862,332.05477157898144 +170,395.617460222669,331.85554030819173 +171,396.3911361968549,332.1303447002533 +172,395.89256887798285,332.16822339411516 +173,176.02029170516317,153.71245910000232 +174,176.10545306203875,155.20318481126037 +175,176.03197440143745,154.95241321278883 +176,175.6846804297304,154.63359606135103 +177,219.46327960613064,157.23609785750858 +178,221.0564853241154,157.3435472260885 +179,219.62129396536662,157.2666553285107 +180,219.69587995502016,157.1490063640601 +181,263.23636033723557,157.46707082247306 +182,261.3833848255912,157.14497162705263 +183,263.2875985178052,157.05504332147794 +184,263.16270089611913,157.68858593709763 +185,304.0771964580808,156.36708101762838 +186,303.2325028543831,156.57995759281437 +187,303.42630311491723,156.4924674158584 +188,304.6158660912609,156.4818813819881 +189,385.45560134261797,158.37035395252553 +190,385.8286612719259,156.9884186905783 +191,386.1864174896063,157.19189241238993 +192,385.6347971660166,158.1411858434322 +1 +59,93.1287423931208,218.29700908810787 +60,94.70512938803542,212.6540109552706 +61,90.1361278577332,213.33121631876608 +62,163.05397573990066,223.03302231371174 +63,178.56039861950646,222.19098474984543 +64,178.37920648184422,223.51557294327878 +65,255.80438353417117,203.04815455047097 +66,262.478672605179,208.85138164100843 +67,263.60616955216886,207.2183121488101 +73,272.29022155441146,203.26015396542505 +74,271.46793735704193,204.00075736023095 +75,271.0412882240347,203.67673019265595 +77,350.53069989533947,205.1215453780687 +78,351.5335450988067,203.6132402057685 +79,350.54080463471854,202.80860415043412 +80,310.84312359894454,203.07084060099984 +81,309.4303871248667,198.8260778916456 +82,312.8487475083582,197.88498609405823 +83,312.4494378330193,198.02482356912975 +84,129.73316120742015,252.31402870350382 +85,130.09936826716955,255.07600217340146 +86,136.48684968097632,256.98593054341063 +87,129.96018632025633,253.63904238622214 +88,180.12754728190527,256.91804818977533 +89,173.42291095269067,255.58833819764322 +90,173.0543226504001,252.5748838461415 +91,174.29585433427428,254.46270745029543 +92,216.78511969207446,254.5914187233686 +93,215.97344562124545,254.7054640425066 +94,219.24024367384476,255.41662872012847 +95,213.81498670140752,252.60321047848737 +96,257.3830982530756,252.6691612485834 +97,256.07878148245777,252.5850508469038 +98,256.6563709830754,252.14302077100646 +99,257.10274737541874,252.44669038983187 +100,297.3527413648711,254.3197859755712 +101,297.36935919598676,254.31625883281748 +102,297.45043676182286,253.29006124829388 +103,297.15639353267426,254.26565823155238 +104,337.0838455883894,250.64743017278894 +105,338.2943046084806,250.9606925384406 +107,338.46927119138405,251.82861699933284 +108,337.6321115297869,249.87042147419172 +113,273.20050531167254,309.1760573916311 +114,275.593658985165,308.5727448984995 +115,276.45985797306344,307.75120186662025 +116,276.6589541465393,307.7328403118153 +117,323.8680795155452,311.25555593462394 +118,323.990822160368,310.23497244583933 +119,324.4759468599942,310.5137190042532 +120,325.7385894442358,310.39579583995135 +121,361.82046220765505,312.6906221126212 +122,360.25109899783934,312.73975566628565 +123,361.13964194906663,312.4482596768938 +124,360.8021695665512,312.55731463103996 +125,443.60378722604213,316.81523544669056 +126,462.74164751366203,314.6397925160877 +127,284.4684422338389,315.96181914108945 +128,451.0537747662026,315.05034330850094 +129,486.2262311408019,318.917422588962 +130,484.203371665194,317.155262043757 +131,493.1775485408943,316.3518621311899 +132,483.79815450187516,313.87456269013853 +133,58.415796919717515,296.3367806354237 +134,59.66992690532717,295.46552315023496 +135,58.30852857429605,301.14443002474417 +136,57.19875149216512,296.2038703275876 +137,101.88869112962361,295.36699152796956 +138,97.74223572831934,296.64159635228486 +139,95.13971714462463,297.63279866894925 +140,100.97448449522825,296.37143206657936 +141,119.6488680328135,295.99857882673734 +142,116.04630564586442,300.9428981940468 +143,115.93833802312685,301.4015147621542 +144,117.66427038686425,301.67621994166734 +145,143.61862339021508,296.87569921241607 +146,143.84226240395634,296.5995702000957 +147,143.41726284468888,296.4604242772443 +148,139.90710854861246,297.05847391439454 +149,177.97012292111646,297.29360417935067 +150,179.09943783225685,297.22176671479934 +151,178.4595029850307,297.07969710485736 +152,178.9990807254096,297.58186299960556 +153,187.06432524491635,327.5110792134713 +154,187.40611165319353,327.24266469486685 +155,187.48202253723917,328.1910452260973 +156,187.4554203440108,326.77537509295496 +157,230.1275716483488,327.66375493177526 +158,230.19455285047118,329.6573791501422 +159,236.39481488323716,328.4457905246168 +160,230.1984260911562,328.23405030487964 +161,272.1545894887068,329.32912181766994 +162,272.8983988300567,328.70387641284987 +163,271.6162444327857,329.4696874435773 +164,271.6290916788945,328.8920615225914 +165,313.03716740034986,330.7975522275865 +166,312.7612082311074,331.01658878813123 +167,312.555857804164,330.94886104868783 +168,312.99233681057194,330.7594147506374 +169,395.6599712440442,331.38000769767353 +170,395.7269407162828,332.3551932767835 +171,395.64772093777225,331.19728501985406 +172,394.5822232990254,331.28589367585266 +173,172.19300877613125,153.8677984100333 +174,174.43739755929997,152.4534316026212 +175,174.29318678572136,152.18270882980445 +176,174.37774565459176,153.9168218422937 +177,218.8977614990739,156.58401687998017 +178,218.82234457362887,155.93775870476483 +179,218.14869261453913,156.17880976796908 +180,219.6136087965169,156.013833915525 +181,260.39420520785944,156.89107932316213 +182,260.75752017274766,156.5286129544145 +183,260.0769741828374,156.73605149236164 +184,260.3205919730126,156.89282130924727 +185,302.8007745851293,155.22452212795463 +186,301.70658980492703,155.39202732491273 +187,301.9655960101498,155.27173302476598 +188,307.3464400351471,155.7530563647103 +189,385.16837677047874,156.43907420157797 +190,383.77693943350675,155.96991177533516 +191,384.2249550976313,157.41263864645526 +192,385.2223566829572,156.31521854739066 +2 +59,94.17681256320567,218.7493975260511 +60,95.60291842116452,220.23420259378253 +61,95.02957510532019,220.4523644522619 +62,177.79543145664374,219.57549575966527 +63,179.18294098400213,220.75147009194285 +64,178.6879893390563,223.61664229341952 +65,263.02108805781836,206.8238570753259 +66,265.3281568315068,210.99878283626376 +67,264.9755279946045,209.25693017899349 +73,274.91234547074936,204.52721235111983 +74,273.0873606007509,206.72185414526035 +75,272.91870930424335,206.4183338799366 +77,352.6038013638071,203.61911600747297 +78,353.00800784867783,202.31796836001985 +79,351.746134852955,203.05786731461058 +80,311.08741311854095,205.08798593428077 +81,310.4676353064527,202.3951467032501 +82,311.07935156741206,200.8328753632899 +83,311.4698975682484,201.29198895046432 +84,131.85526420446874,252.0193765605421 +85,130.09901692321196,252.49815518747823 +86,128.98108803670195,254.22164770572394 +87,129.58841891167637,253.33496272524005 +88,174.3431769252481,257.67973667788516 +89,173.08617175672723,252.22705318297471 +90,173.16612346262423,251.83252079351362 +91,175.31435856398238,256.47051595889315 +92,214.0019796882893,255.64524660837301 +93,213.6417614987187,254.76260041862824 +94,212.59841286272757,256.77538398368796 +95,214.6340156872122,257.02599392382655 +96,257.12202196483105,254.71576094200717 +97,257.3916794657995,254.02867969902485 +98,257.2278305685032,254.5619736557002 +99,257.16282933783424,254.477050995793 +100,297.5612747805052,254.68621271243086 +101,298.3394946306158,254.9149917819558 +102,297.7037470787607,254.32926027245796 +103,297.9018444784966,254.79769770872946 +104,337.7041120241776,252.2287315192184 +105,338.43934115988196,252.2496982308047 +107,337.8271824583213,250.73973826046893 +108,337.86197274862946,250.42655028770324 +113,275.3004995531795,306.83564646386503 +114,276.88576480308285,311.35434787217997 +115,277.14029465508577,309.65039091667654 +116,277.4324777875824,310.4960617480911 +117,319.3288258962187,311.6702225501444 +118,319.8591509274496,310.989524065149 +119,318.99005649592243,312.4173775749036 +120,319.6131328938472,310.5522979637107 +121,365.29517640566365,314.6454813265486 +122,361.82211363523294,313.68568720200915 +123,361.4480761928614,313.0382171673784 +124,362.77676743108657,312.1993102338357 +125,444.8280999329621,315.2874742212303 +126,440.039105136866,316.4990582369399 +127,440.1448707987162,316.91453325930746 +128,444.4735843873624,318.5837135172218 +129,480.4945871932981,317.7789400812657 +130,480.34502455519726,313.1237155709503 +131,479.79765238044547,317.8026694666446 +132,480.81626241860704,316.98435781490645 +133,482.1126824365287,292.7236746644675 +134,60.57986058588791,298.3572263782008 +135,60.26789543218528,299.7821310194954 +136,59.50091999103519,298.34107118829087 +137,101.38271621918946,296.483247325443 +138,100.43332664554771,300.16356781590855 +139,88.95536885340141,299.07746679015054 +140,100.29389089950519,299.8972675509202 +141,119.96308784890563,299.8312652747876 +142,119.21634890704448,298.4258068241335 +143,112.26314328941838,302.0132035682278 +144,118.63154926153814,299.5090092566827 +145,140.22829557703238,295.83589398019353 +146,143.96502880541922,295.45158153676647 +147,140.66008917985863,295.75005128745903 +148,141.21893535376495,296.1533805219746 +149,183.47872058961224,299.0180109809012 +150,183.1202811035564,298.79425325159076 +151,183.2016789609457,298.4838438451825 +152,183.56716590770395,298.3764936397965 +153,190.41048704769,330.4978785855013 +154,188.96675676778156,329.9036439013521 +155,188.33490314035438,329.81417912235116 +156,188.31414516895805,330.23186734474723 +157,231.30258441852257,329.2869590111576 +158,635.9719402081547,323.45669801247647 +159,231.58692741290457,329.78511421313885 +160,251.94245026669623,329.3621392921355 +161,275.38274900691636,330.6582764942376 +162,288.16094061378243,329.96864420502334 +163,273.9343912983064,330.28517683915425 +164,277.40318080027276,331.32724722075693 +165,294.8273106877241,330.7078842677868 +166,317.03626643514605,330.57896380392424 +167,314.93276908458336,330.67614347282944 +168,299.640483801822,330.68496013319924 +169,397.31504374955824,332.3446123671715 +170,396.5580357804531,331.5612694467712 +171,397.49205012933754,332.4442253933989 +172,396.4373476151805,332.4498304809778 +173,172.71708638362486,155.60703919548823 +174,174.69066860790247,155.66811371703272 +175,174.36012639095586,155.21688748228445 +176,174.27542002212184,155.33243945954135 +177,211.35953547851577,157.84363965463723 +178,215.49817946473246,157.8061035073585 +179,211.58080964064885,157.9196266744007 +180,212.21010780634873,157.82655078622685 +181,261.951692200774,158.03145626439886 +182,258.53106462200054,156.41654274449266 +183,261.9931127261629,156.844374467896 +184,261.97037263466234,158.27263012263947 +185,303.2394620820782,156.27343358354165 +186,281.81947814044815,157.07330827651708 +187,296.79672730554864,156.66963976209618 +188,300.202613978401,156.83041886564462 +189,383.13489230058434,158.29028886500078 +190,385.65899984883004,157.07389261777607 +191,385.5178115620514,157.22774057918932 +192,383.2113575049479,157.78585537067738 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std1.5.csv b/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std1.5.csv new file mode 100644 index 0000000..cd215cf --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std1.5.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.32510644540474,217.16136239737153,0.6182377010412883,3.437860778311802 +60,94.65266061580076,212.6177146123835,0.765212453826913,3.6739543947311417 +61,94.61401364788813,214.22486674207525,0.8412783951060775,3.3611479966616367 +62,178.35158089537316,221.847988586586,0.9403897569392258,2.7273751079265014 +63,178.77936146556561,222.1382787309958,0.9463391509324931,2.657550420078367 +64,178.51870559728806,224.63353150383256,1.0071690155319815,4.55962144903764 +65,265.4101380731767,202.08888192291917,2.9369222816228366,13.78987315189462 +66,265.6989344950027,207.74953132239617,3.0204535635810923,3.1036977294508623 +67,263.08964545761665,205.42187070515965,4.431842546811981,2.358949151269513 +73,273.4831703233573,203.64459660353015,7.04945617162013,7.94901069703423 +74,273.07076432835294,204.06679372614934,6.89788799009703,8.626898083569905 +75,272.1738130844689,203.78689920903042,7.135173768291136,8.947454341776009 +77,351.279939281129,204.46673588623955,6.045106258240715,3.909769225255067 +78,351.9201632813107,203.06242013391767,6.757744778249452,2.7563070866266073 +79,351.5222044161429,203.62412359740455,6.8762860015843,2.4772722541589194 +80,311.4321457450739,203.50054128359008,6.239505058348041,5.6340319630028475 +81,309.7350900557848,200.1189157557026,6.786112432854393,3.7532785541909637 +82,311.0972982876571,199.22509501936744,6.892343194786746,3.2293740231207715 +83,311.16518083066256,199.25055482945473,7.010045021779638,2.7712015561427807 +84,131.23754348858074,252.26390581496943,4.531133252555627,5.315476076691151 +85,130.00327880890623,253.73048027246645,5.394441049750279,5.395681634052309 +86,129.11103579380026,255.02208812060525,5.279052334030264,5.613375422087035 +87,129.85581048785428,254.17406429530502,5.674102333754549,5.78050786879303 +88,173.6706310017366,256.75225947929334,5.866553313440161,5.378715368726579 +89,173.10982411900085,251.5446731759652,6.879373651171615,2.5523562516540665 +90,172.75015150634195,248.10188260321166,7.047271185711796,2.007986084013029 +91,174.99352952512763,256.09184964129855,5.235714833141598,3.313609851436995 +92,213.8661562238959,255.830056426469,6.707076930736432,2.458271305003053 +93,213.4468844061598,254.50412813549863,6.518799611232329,3.278464480563131 +94,212.79962250914713,255.43887452853883,6.766022500672822,2.705140416783796 +95,212.4983956286567,255.64768535613388,8.38922518196436,1.1489063054666482 +96,256.74603239035036,253.07252663449168,6.865986829223564,2.6663521829239336 +97,256.72510650144056,252.79028393976105,6.828380413657813,2.603426429287444 +98,256.8221014295006,252.7889068984261,6.821267955887984,2.7406932410109657 +99,256.95819898248175,253.16068182860602,6.8533044126794715,2.6857466734869786 +100,298.0833417924816,255.11218204520893,6.68748523503982,2.5312282089724154 +101,298.2658386968296,255.0162251091937,6.972265462941957,2.391655492853278 +102,298.07594362921077,254.9831987261273,6.694673144383624,2.446242469655284 +103,298.2353998576801,255.3627222097245,6.715087554789903,2.4808962893039186 +104,337.3091830161018,251.4473414930906,6.239563573099407,3.9949672494208963 +105,338.50157961505033,251.25839644260412,5.899400220598736,4.074419748640388 +107,338.2423485650474,252.9079453166733,5.969934007979263,2.2333183687357447 +108,338.5801482804283,250.28634549329695,5.539855669597802,4.858284281787599 +113,275.59876651558005,307.46189968535816,3.9436251120891708,5.10683987641902 +114,276.1686694961398,308.57204326970526,5.356119731482595,4.772688054972327 +115,276.8157548930389,309.70713161790934,5.002026768143788,2.583003901658473 +116,277.0444072504442,310.2242983789689,5.093238900500282,3.2415570106605673 +117,308.9662148000703,311.7697205368066,2.2792009412856546,5.410806300828905 +118,308.46078668862316,311.92138655579373,2.3941030136668364,5.421098042888929 +119,308.7154324709243,310.66348827344274,2.3309057135226756,3.5206003610285515 +120,308.24434710841035,311.76621158888577,2.470183201647586,5.328252659543528 +121,363.68682214557504,313.51876571316154,3.8856640715067936,4.058166847376938 +122,349.14935421068765,314.03103766657546,2.329671674152375,2.776838944594597 +123,367.58471869225144,311.42252084107196,3.923615531492719,4.789041635546242 +124,366.2205639783599,312.0147408219617,3.7204140057381685,3.975220041758474 +125,443.4421791253585,317.0454064337059,3.8532517828906077,3.2746926716250857 +126,442.3085572430623,315.4881011805151,2.1017637979425676,5.638134747002355 +127,444.0456031701909,315.5453281878035,2.457515375747752,5.721606221790266 +128,441.29274663891704,315.9751158703776,2.8445523791239578,3.391499475116884 +129,480.1126176912876,317.72874213425126,1.9715561431765554,2.8371867515089835 +130,480.7028108376642,316.04711281162145,2.1090053401415116,3.7239493086812376 +131,480.3028282756367,316.9828674719394,1.931835914107085,2.6912419384547803 +132,480.759709821911,316.6390215996198,1.8855815838100882,3.2368313913566618 +133,9.357026815909922,301.1394481670515,7.424860692299219,3.8886973359748533 +134,60.799946985869205,290.82662639382374,2.410669490697829,3.3307667086551547 +135,60.28851015248002,299.3626408593879,2.610803253456402,3.4448392908334102 +136,59.58730981243586,299.348986354774,2.4093805788992184,3.557779220380588 +137,103.27374468276936,295.56230309563284,2.5132133127505014,4.351160826227996 +138,99.75383058106173,296.569880707365,2.5218334720238236,3.501899754104677 +139,95.32232328874625,296.73397752555695,2.877040509030959,3.4555743629781466 +140,100.87147176733903,296.3324977713732,2.4143008563576176,3.405547995808848 +141,119.67590393924556,299.5719162206477,2.715209640937237,2.3146688915381275 +142,117.02401243356974,298.35207687180383,3.08539437068056,3.0048819093528643 +143,116.04574600753108,299.0124296372606,2.8382177918151514,3.279021572744144 +144,117.37742445192025,299.4258416995056,3.1697222157479636,3.228779441784994 +145,142.9769721583903,296.5366900343606,3.0832619899763425,2.644094161149235 +146,144.05541849455753,296.38389634445554,2.9996657202962216,2.5996279341099453 +147,142.7610177499935,296.49057527125143,3.132429288120055,2.6497556402515237 +148,140.654399096409,296.487509133948,3.0056568959849406,2.058048941223319 +149,183.71806867676824,297.5062440925511,2.457573643605339,3.0504821593031735 +150,183.33793283890802,297.31881173151646,2.392042666256841,3.050918286277636 +151,183.61600393859536,296.51652050691774,2.4097480630875605,2.764147393280351 +152,183.8339373966336,297.2945340604019,2.460682969826688,3.050060229583357 +153,181.09589492836406,329.6242218226362,1.0425141465757852,3.0368750466096333 +154,186.11052367996277,329.36778207951437,1.3324891141111836,3.0102790481884694 +155,186.71507659948506,329.31046601919013,1.491127987331188,2.737120605219304 +156,186.77967822458413,329.3378404603494,1.4948700160207713,2.734563650578621 +157,230.65228943659753,327.7840930500721,2.295828556135942,2.4982820936800283 +158,208.88398865586805,327.9985148865243,2.02425621449308,2.350854989534598 +159,230.76774042649313,328.3139314865929,1.058343333489383,2.1110955225257957 +160,252.12645006163774,327.8829847714941,1.9966581003411814,2.5372848351369273 +161,273.4567736740019,329.5617685669899,1.9537976371799024,2.0154389968753095 +162,282.2315955976967,329.51993412315335,1.6558383645274921,2.0452106688498017 +163,273.720574310258,329.68024219956664,1.5653369253681564,1.8342890718749 +164,273.889758529857,330.16719840873463,1.5821177076586581,1.694040868940706 +165,313.5406083274413,330.6880662983543,1.5169373766112113,1.9512244512786259 +166,312.99217961793585,330.84544281473285,1.9687039019856765,2.6822749686071305 +167,313.7630009835721,330.8583984920328,1.4848333229111295,1.9827954471887683 +168,312.9401442321904,330.7254552672906,1.7568824225422763,1.9323110607855833 +169,395.7207767219437,332.183165147594,2.4577717664195537,1.7621285751654179 +170,395.3337266028771,331.43381176706987,2.181281870585342,3.1337432803521126 +171,395.85186369230047,332.27068551595306,2.518966823398722,1.7204609744266823 +172,395.8084329126563,332.26796527945555,2.6126143387145087,1.724913210963549 +173,172.9730835697278,153.07041804847032,2.9494726617733757,3.382217579007034 +174,167.91626071048515,153.50090831100303,2.2490783825049045,3.4124393018031505 +175,174.36354763148583,153.16813701756828,3.0454139103327917,3.4583182798940344 +176,163.9948808388554,153.12115036518048,2.245850905919589,3.0039836826659077 +177,217.69107890505612,155.58013869177068,2.7767507060557537,3.794972875980232 +178,214.66253412696085,155.42760092218833,2.282992010999303,3.7924195042280746 +179,217.2668815139982,155.37466732788673,2.82114799379885,3.7715102977100545 +180,213.54537138523426,155.3242530398654,2.39080632265553,3.8737974440740692 +181,261.6939418857524,157.09312093358466,2.9274288743236836,4.2654996092602575 +182,259.5388851666542,156.21847108548155,2.740600451522983,4.256469485200473 +183,261.7749420583441,156.80848263234637,2.8761845595169624,3.611268367181998 +184,261.7034113220799,157.33345113871377,2.9950641148825974,3.4845516638308904 +185,303.89901305026916,155.6612518414893,2.621571563900723,3.473866833204008 +186,301.62587627334796,157.29265691699584,2.567822100277209,3.8190983468951436 +187,302.2849628418849,157.1968491242557,3.008452770801469,3.8181849057828567 +188,303.7565642594758,155.85469430778133,2.429239927505623,3.326076201679362 +189,384.98371808681327,157.38821592622213,3.1474479877455135,2.841847047972341 +190,385.6953493035584,155.9304125075569,3.6373602156895406,3.649388391215581 +191,386.1522285343919,157.13110788307986,3.4178090658584948,1.681812080594319 +192,385.09319956411656,157.18765906545738,3.129473983251964,2.975867208927914 +1 +59,93.00875717999857,213.0864805157829,0.5227911458975513,6.19713029420415 +60,94.33424540812612,209.6207769002175,0.712959043184757,5.35016277729406 +61,95.1076356890004,210.44116297321946,0.8764776639925613,5.547156704495216 +62,207.5747279334015,229.35385437625325,0.5721218590130254,7.308688366893414 +63,178.26435087496964,230.13928425075747,0.9163078266059032,7.241140371768349 +64,177.90044660433097,228.64882156245648,0.8264625430894746,6.592321670041416 +65,261.4355459288758,202.518302086519,4.641943406474736,13.108375146006386 +66,263.67870524819034,208.7072384357703,3.5858326934539724,2.433228596876354 +67,262.17751550130487,206.93217537761328,3.452444759098905,3.8722633351342384 +73,271.56705521542676,202.40830594251935,6.020267230118504,8.477756512699672 +74,271.73829194020016,202.86157549101065,6.298067280843489,8.419553297292511 +75,271.44195864454383,203.13378150076727,6.235685371158418,8.78878791063504 +77,350.3978097520949,205.99099129354195,5.486198418330991,4.23015499642844 +78,350.8542007403272,204.8726031135868,5.884173027734943,2.402879521643992 +79,350.33767761544766,202.27664047975287,8.070802178703657,1.9426946744270117 +80,311.14553424067776,202.4869088895573,6.8627096705514905,3.849897420660647 +81,308.5842159554098,198.77298238575344,6.52057770401923,6.006445353466768 +82,310.7458930121221,195.62555942687163,5.367642235757289,7.169712735992463 +83,310.4462741092919,196.04905416426502,5.898927104709222,7.285208599925228 +84,130.13558933089806,251.82817494602546,7.150925955550858,5.341680351200341 +85,130.18397703583258,253.52743282837022,6.541689138699417,6.299622234665423 +86,127.98319134864182,250.82109733724317,4.738368491228839,2.57221862750688 +87,130.22115190707984,252.63693413729288,7.110134503566371,5.544397590264715 +88,170.3259733642306,255.66266877807428,5.690121369029169,5.9867577312345635 +89,172.0725262476556,250.99873611079994,6.021708452291268,4.7312867200629105 +90,171.99327618907063,249.17936838672563,6.229499399540459,5.078719873917035 +91,172.29510140368106,254.5565739501181,6.451006926460406,3.9136334301532982 +92,213.1828066056623,254.92363133767387,4.131010753144876,3.5262173672553687 +93,212.87022485654242,254.1472663576613,6.024553307028744,4.36937145736752 +94,212.13601387505264,254.10698963113109,5.484917596658879,4.460238419613106 +95,214.87325400509656,254.39310436749193,5.506727817013678,3.986223925190019 +96,255.87095795884755,251.70990738025452,6.095777014998389,3.032297848733597 +97,255.63216745384443,251.63937961156105,6.119873150459129,3.4431842597866478 +98,256.06917412538536,251.38312888217393,6.172049945445992,3.0818160436840696 +99,256.44518378286506,252.4176024183597,6.2866487953086825,2.5551750914715052 +100,297.8311949255675,253.9653171752207,5.924725404966239,3.1672044636908576 +101,297.57833588228533,253.99818141838037,5.944381655046086,2.746686532181724 +102,297.50136975432514,253.68544368933334,5.860286142652836,2.8473861302268335 +103,297.7295288163928,253.7737365687886,6.239643764909305,3.2568997394492816 +104,336.7180543456296,252.55145794454867,5.584269888775618,3.3139652271056144 +105,338.49750522296745,252.07705913627754,5.543320366201012,5.442573748366097 +107,338.0150937851073,252.18608250396494,6.036908819248115,5.0311597932446395 +108,337.2951518337468,250.18224258519146,5.881938681047152,6.491905854296189 +113,273.4815993508197,307.6936923289109,3.1012639427533784,5.154672012501804 +114,275.70060000212146,308.5897280752863,3.9037828113839366,4.201910703737281 +115,275.8323442926472,308.5631016742169,4.908621601004965,3.639510737864438 +116,275.6606088252997,309.15745128264456,5.248785953237486,4.1594464461611045 +117,306.56743395611335,311.7534996826885,2.112121697069489,5.820314553091814 +118,319.6052247158424,309.2092876138521,3.0994427567914853,8.01149636027687 +119,308.98961216723023,310.3876530882548,1.9815028323151676,4.505358981721892 +120,307.0431037398603,309.3570250757065,2.1228582042961364,8.133763836800041 +121,364.6612653249806,312.867105648696,3.6082645560201403,4.907320783558812 +122,359.5565312405258,310.50474411241805,2.3300472525322222,3.6383073582313625 +123,359.67023843236564,311.274718807607,2.359429636308929,4.812109039516953 +124,359.55652211431163,309.9599256178089,2.821256013884825,3.8133629555932114 +125,444.4021410207277,317.8526352360211,4.078133482194948,3.9911353122263296 +126,439.64702159418067,315.15017744463006,2.254461458911636,5.747036062574868 +127,440.69585939100426,315.0579828759502,2.7149707354695605,5.752920657180591 +128,441.8625387527503,317.7326376075549,3.3446365437819154,4.190002229264773 +129,478.5750112776985,317.8659165254805,1.7655709538040265,3.094544391955392 +130,480.50423944788866,317.3650260367778,1.6290524950029868,3.015416485400363 +131,478.66450057520063,316.38942944947695,1.7953728376964107,2.42227888620822 +132,483.0153971429184,314.7305690623162,2.7300211118973263,3.080445570051542 +133,90.20291039246604,298.07507002916145,7.598743409857649,4.552890998174248 +134,57.81287299171998,292.38407844216607,2.514015918277811,5.136006470534924 +135,56.72481683615359,300.0118009139173,2.857620857781098,4.750166949488199 +136,45.96616366715866,299.693904996051,2.6917302124926694,4.645496991603487 +137,88.02035707489331,293.3669429657606,2.0117005484316364,3.9293747558559278 +138,160.04855077999034,293.33750956777976,2.7841652419514227,3.7908670426694497 +139,353.4092012789472,292.0076334322056,3.014363497918401,2.928043350479415 +140,89.97636900626323,292.9113392808752,2.65494720185284,2.8719276763310857 +141,115.9594791110215,297.7222868684274,1.9069874131620126,3.352456382715099 +142,132.15536640954062,297.2171229012815,2.706901698676143,2.9568780838711826 +143,127.1646193746793,298.2335745308878,2.769134247080161,4.01114038711725 +144,130.87079961636513,297.89834733182647,2.818953624476529,3.8997116282895603 +145,150.31209355255865,296.8214130757569,2.725175079922067,4.209022465413865 +146,148.97786084884208,296.6038327691481,2.7067927491075574,4.17492062013239 +147,150.24661339572495,296.7796929595484,2.810800536874064,4.312780918203187 +148,152.5470386382202,296.79763117851934,2.8754159917495565,3.731793392125523 +149,178.862609212918,295.9186248626812,2.5841961653378953,3.1991556673695176 +150,180.89610810712188,295.92807355671397,1.6842427525491304,3.8890257041235543 +151,180.40049251926752,295.77981228572037,2.6591704134491323,3.917421171009508 +152,179.72946886796663,296.05583778880305,2.564660161772704,3.9159370208085704 +153,185.76625246646185,327.4055525477087,1.9261688345955168,2.5002553115545973 +154,185.68007483081436,328.060632980561,2.609970861940605,1.946219519924639 +155,185.37113250572602,328.73195534315664,2.4795691921165655,3.2840453584363116 +156,185.5418021015136,327.6689562730928,2.375786778236521,2.651340769524802 +157,229.27152294423166,327.3561714417115,2.4437228704779783,3.2195371224858063 +158,232.28441597607784,328.09402673325656,1.357599811770978,3.094542048630364 +159,231.00284475154749,327.9998620514896,1.2108444033536565,2.66674404960965 +160,230.25470725406453,328.0859285158972,1.7316362106698195,2.88263756637543 +161,275.7222561716378,329.45078955534507,1.5401263844373954,1.7585024676985501 +162,747.2675063983792,324.7536431546597,2.1073598387590406,1.9846975991560125 +163,272.00721091330865,328.94613162616673,1.9128906508563452,2.480037037665106 +164,272.2943718583655,329.13463420388416,1.8135422013484646,2.333221321023227 +165,312.27917579462644,330.90999638474113,1.8158878550164057,1.9866753158839707 +166,312.63990435472545,330.70825140967025,1.9310585450982856,3.1257959767437193 +167,312.13911877602334,330.8661550202716,1.8464663431187927,1.573517775693253 +168,312.52858835763556,330.76426646797455,2.161251844547869,1.933118359992701 +169,395.14083600756334,331.87815070527694,1.448023063266429,2.3167851906782087 +170,396.5732738072064,331.21301140029664,2.7671279378720532,3.432678442805089 +171,395.3116027704574,331.9375695732541,1.4531763607459942,2.2989452818042047 +172,396.71305866511483,332.1630656147329,1.4224167184507017,2.910921037939185 +173,172.38094968570545,152.05413649604458,3.009792250294108,3.523757740020178 +174,173.8453388820814,151.9722418163993,2.4225092170582014,3.3547430273206764 +175,173.7469031569836,152.01702715147732,2.992197181370308,3.5878204759260535 +176,173.94321589450442,151.8994649734145,2.441865274900331,3.3191803731856986 +177,220.05954791045562,153.93486125597713,2.916964654294944,5.161796303421409 +178,219.06032109265325,153.8679197592309,3.02283014757281,5.214692401346838 +179,220.20248145797134,153.83037812747935,2.811916018641933,5.135768243874929 +180,219.8402257665675,153.69441590096454,2.365027188775977,5.195182563087241 +181,260.4380890463525,156.1736753615838,3.5506189837569733,4.210885005617385 +182,261.1508899611818,155.0680682988112,2.839394772014497,3.5985227200258616 +183,260.30310151802394,155.61059359790818,3.5432570320956893,3.1707993199082107 +184,260.4910132005214,155.66192708074522,3.478073697651597,3.1191145304607857 +185,300.5406946589481,154.9084556815696,2.3966410747454683,4.257306637411747 +186,301.78308068276635,155.27677811490247,3.0779278021862946,5.064316807047082 +187,302.2761713726962,155.27023677113314,2.993547760611472,5.214144626020445 +188,302.8236206973499,154.69674142960957,2.4778587529647105,4.640007316386941 +189,385.48180701984114,155.92489835616408,3.473675270188691,3.1517197697620283 +190,385.08967578482293,157.6459314691889,3.5586590950004457,2.667151842484689 +191,385.58591970819674,157.30125119156654,3.631613447401373,1.9082302724245561 +192,385.21072355609897,155.7094594652936,3.6798775544177063,3.5067454833259255 +2 +59,92.65376110690876,217.01497137821914,0.8683837090191788,4.157428729871967 +60,94.82990413785946,219.90540926030366,0.7890608958947835,6.846135813191627 +61,94.29121037749401,220.03685469388876,1.0749214557030176,6.838018547816678 +62,177.10956003057285,218.90103728250688,1.3905251660790856,2.7497320728371646 +63,177.74456263111466,220.06649622720403,1.2185587916549738,4.188825256215504 +64,177.4433366943884,223.83295887197295,1.371218908578905,5.2592726336887425 +65,265.6878095601755,206.65513281700575,5.33587015800756,16.669713322142147 +66,269.2923498741563,209.05824066438973,4.66895680216908,5.263799522185158 +67,264.42528410909586,207.364718342118,7.577757476106213,4.472335501339223 +73,280.9764776348652,202.68253855726255,1.6546267117994216,6.318822469408919 +74,274.03045869010333,206.973282686757,7.997571675272475,7.243843769359161 +75,276.0822341347654,205.61933530967025,6.510520268907271,10.3236022000293 +77,352.4139935670206,203.48156974798098,8.32458599948799,4.470725516378897 +78,352.6633237122737,201.43070660774114,8.497380645406677,5.377940688297667 +79,351.62852667070297,202.74208620682512,8.658775240139533,6.487198309406779 +80,310.6751701124307,204.64495746423012,8.062037456416205,7.444446872078048 +81,309.7010694340917,201.889057384221,9.465643221743878,4.651552993103335 +82,310.6335818256993,200.22299800671655,8.67387089777447,4.664159850458751 +83,310.8614265739441,199.458651883236,8.510118775528804,2.8724484284650633 +84,132.03262725456108,249.4924232903857,3.0768121962170567,5.169014220579259 +85,129.09144907108433,251.7203734728845,5.198191014751725,5.290792123590904 +86,128.11492684472694,253.65236303540686,5.978168978981718,4.352921913597757 +87,128.5504980446596,252.95544188750205,5.339963887657365,5.754904964464613 +88,173.85018852313817,255.81968964851026,6.482400441297941,3.4989983294150475 +89,172.52528902354035,249.2499609079768,7.275410666068803,2.2756893414086514 +90,172.38753943021908,247.6577135955906,7.222779487902638,1.831029568977615 +91,174.91415300342587,249.18228108995524,5.447412274608176,0.9909035227650256 +92,212.05665773319856,256.1820062089689,6.711658598234498,2.9976841684576496 +93,212.8172314127949,253.39712914171187,6.857530904039771,3.977160865721656 +94,211.8792430432469,255.82761299122967,7.222038595318558,3.1694534357454573 +95,215.0833848468073,256.1212830567826,8.467407782374746,1.9473456404121796 +96,256.9743035103019,254.71512762526666,7.44290569053337,2.68632372187447 +97,257.1457284865542,253.4535805850962,7.332108489145229,2.4944378698026863 +98,257.03430784028274,254.5812608515072,7.2764048131626184,2.4480433538371873 +99,257.11318563543705,254.84544472082902,7.423089718980076,2.5660592893878267 +100,297.53329552210926,253.81655725507431,6.852565823032563,2.567811443943226 +101,298.60461192426146,254.17438371162478,7.905691877078718,1.825741321015611 +102,297.69407107379396,254.4850393852944,6.836012542442264,1.946205259389151 +103,297.9023244730469,254.38868473138925,6.751896664205788,3.3116178759031087 +104,339.48285905633736,251.81900285371069,5.942208628240243,4.945594824336877 +105,339.1205482251966,251.30122032806455,6.500886426061445,4.808751958411583 +107,338.4272019992697,252.19848894388656,6.48687937625559,2.8213077726348095 +108,339.54299063145817,250.0031283857795,5.812146409240677,5.287653170857336 +113,275.910952296904,305.86738853882827,5.34030651381748,5.289299280058491 +114,276.35015397667075,312.1081102609041,5.162726712460268,6.6369445658697455 +115,279.0736812899919,311.07994680544203,4.951788309478035,5.01744381383027 +116,279.87420391551683,310.72506489150953,4.822827709017515,4.736286987210306 +117,304.24552486172325,309.69865127849215,3.00277312239498,4.555283930061753 +118,302.7212817727547,309.2230592598733,3.16363749983184,6.857616858633486 +119,327.09308351776593,310.69024753529516,5.288987908246067,4.6842841758469556 +120,301.0220842644409,308.7703307062073,3.8966104642189516,6.518991290453131 +121,367.6098676953658,314.58028508890305,9.39615711787979,5.649531231448145 +122,397.3328204276317,315.34567189868795,5.7108612456732715,3.258105059687543 +123,390.7453940415891,311.6470607282421,5.5964184306698455,6.030687385605649 +124,432.23467177419724,311.2122511991688,5.881307854257575,4.563765149392382 +125,446.24432082170046,315.27649965719536,6.395392871846412,2.4772515296514643 +126,438.8511287502254,316.37095567311974,1.799887035029369,6.635379091123845 +127,440.35515062380387,316.80874455617004,2.7747867554906676,6.796381592950393 +128,448.99707714791936,316.64328100115915,4.9199468672846844,3.6299256024726247 +129,480.21281513978687,318.2237602367352,1.939096401014579,3.836710322440239 +130,478.7339197387106,314.27301630895124,2.087142296065961,5.08374236725423 +131,479.4617027213679,318.2468896366567,1.5978214301813713,3.688680674174361 +132,484.13323268726947,316.73499335627196,2.002291195085977,3.781086788196597 +133,85.29652368782442,299.9267050080891,7.827458514431236,3.9374236627298966 +134,59.630826345700406,299.5528993065781,2.293779231438959,5.560856320277098 +135,55.11028578417307,298.40091605755845,2.4753999616786904,3.1001830452921184 +136,52.88374765283322,297.62420743734526,2.052251163735395,3.0356052182771274 +137,102.2627134309745,296.1781450112869,1.2262813798013208,5.212420406396804 +138,78.25837410035345,298.6824898421718,2.6075704778239923,3.377654496084566 +139,109.1163322762621,297.6290300025382,2.3024123744989207,3.1885843136710754 +140,48.41182620962574,297.1931703451722,2.625583107839479,2.7907983124386684 +141,119.51602776789325,300.10453175611184,3.4424531063915236,2.642126479181898 +142,118.1973619086592,298.0334936483938,4.076098186731008,2.6346682961879635 +143,115.46104139376924,297.8312691405318,4.279452761468254,3.2247085556456048 +144,119.86152598306575,298.3571523952646,3.493981329511576,2.953550317426917 +145,145.90006454487417,294.33120612383067,3.8031724141145062,2.4031438376062857 +146,145.39522138169184,293.9045479404022,4.534922195360379,2.5317897016901143 +147,145.56468242678977,294.28930454392895,4.470204993442609,3.0933985628535288 +148,139.98418133069634,294.72850928798835,4.278137116722635,3.048819187424443 +149,184.61384435804203,298.9796024091839,2.529497564999449,4.490567912543599 +150,184.64043155451438,298.7318610841073,2.6174338934133505,4.277160291745099 +151,184.44418125715643,298.25564342712596,2.4439277524700747,4.343490136232689 +152,184.66560803927564,298.18036927693134,2.564579983473208,4.385135450871558 +153,194.19362024463055,330.1400811375832,1.1767713277123986,2.6700939408054847 +154,174.86887852527403,329.979989704711,1.8484097857820594,2.591571956692586 +155,180.79865067404023,329.8562242828808,1.738097755840568,2.338466226674033 +156,179.56170004415435,330.31834841798707,1.7754061019312333,2.638869441184331 +157,231.71308757803595,328.672133593381,2.575835953649238,2.9234623232364685 +158,255.4632386220983,327.6416302142385,4.012448382356306,3.42068392727793 +159,205.50139246153256,329.9023818846584,1.9582108272811507,3.923308113475421 +160,235.88906246092358,329.0473855498786,3.444258781962619,2.6163214632167398 +161,276.3094789576173,330.4608109053376,3.4419490584726287,2.564981348675966 +162,285.59180034302733,329.7481991930167,1.8378511022559236,2.962363935958349 +163,276.28783266348086,330.4003933681143,2.1081569415614108,2.0262424617108703 +164,197.25002629984402,331.7884197277611,1.7077843114772655,1.9623226431578948 +165,288.0915533470578,330.8983776107492,2.6656921890922276,2.4733683795597825 +166,318.99404577369717,330.52622945989987,2.512905677477683,3.0041332311662914 +167,347.80228956810066,330.51035383722933,2.7357481343278547,2.6900125091285605 +168,295.96785278892344,330.8541466179879,2.7327133833859794,2.5553494567631065 +169,399.4046364026606,331.7493713707221,3.23644714671924,1.744053910168871 +170,397.57150520306647,333.3787113091005,2.0553328419425942,2.9972979280312493 +171,399.5202454111206,331.87094628141256,3.319483494438871,1.7408731153504877 +172,399.37556911546983,332.0970117083097,3.2770522011812937,2.0503115948740924 +173,167.59893809491587,154.3249244129017,3.578104764139934,3.3198423220094764 +174,172.84296794779806,154.0436851912386,4.065505613610561,3.1479614150013635 +175,172.53685506876784,153.5142164683417,4.048705697811711,2.906116813730039 +176,172.4903195543538,153.75399965885978,4.181462595099683,3.2085629045903814 +177,219.17346400289313,157.06361150991273,3.7208701762725958,3.977297645616966 +178,218.5571656670773,157.04802019919677,3.903522619785598,4.337287440506104 +179,219.08587325813014,157.06764805172753,3.794218226236283,4.170614188910467 +180,220.20815419984615,156.9157243686214,2.7714160963084615,4.408356106260135 +181,260.19885472358294,157.7365391738532,3.7452159562165885,4.8366413757834135 +182,241.9395975737316,156.28097820179985,3.450826603860176,5.030259376007136 +183,260.2353298294739,156.54302588067847,3.729468016831249,3.948234547478585 +184,260.7848372561543,157.9506538637672,3.5754121929574882,3.800985332770269 +185,302.7343292496292,155.53108168722034,3.3675563663327583,3.3417704291330135 +186,332.63645946919394,156.3859992454305,2.765786036774427,6.391527497892834 +187,284.71333669266966,157.72636771256072,3.3503763444766745,6.365038877320703 +188,304.3997409110315,156.17999029402282,3.740908409488698,2.700855536462382 +189,386.0604531581429,157.4606593487467,3.503153843484056,3.8679991937676528 +190,385.18009669613696,156.2333983389331,3.2976202226268665,3.788089778011118 +191,385.0925046602618,156.67041836007596,2.6210706316937795,3.2806588007554622 +192,386.2128341829654,156.16694016460218,3.3738623057156985,4.160360297012765 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std2.csv b/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std2.csv new file mode 100644 index 0000000..9c454aa --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std2.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.33971469075367,218.50270598733297,0.6182377010412883,4.519603519601824 +60,94.65266061580076,212.6177146123835,0.765212453826913,3.6739543947311417 +61,95.41265351990087,214.21478810961165,1.1080389271434514,3.3611479966616367 +62,177.68104319925217,221.8562022028197,1.210105165576976,2.7273751079265014 +63,178.12474883940652,222.14572970009505,1.2756265672756038,2.657550420078367 +64,177.98709471591388,224.6454307841806,1.232576692361491,4.55962144903764 +65,262.5800156706123,202.10797896730915,3.9515122758252583,13.78987315189462 +66,263.12260735580236,208.6888275933953,3.996672369259087,3.8323992242499187 +67,263.2208458621908,207.81872361983278,4.431842546811981,4.012811725696324 +73,273.4831703233573,203.64459660353015,7.04945617162013,7.94901069703423 +74,273.07076432835294,204.06679372614934,6.89788799009703,8.626898083569905 +75,272.1738130844689,203.78689920903042,7.135173768291136,8.947454341776009 +77,351.28674760518,204.59842941618587,6.045106258240715,4.408743803212035 +78,351.93164737416873,203.26383152358028,6.757744778249452,3.4138998666946025 +79,351.51705628039196,203.5492416308136,6.8762860015843,3.019482596125626 +80,311.4321457450739,203.50054128359008,6.239505058348041,5.6340319630028475 +81,309.71370799855777,199.8072317333757,6.786112432854393,5.546655412414925 +82,311.0912672829532,199.1202501566774,6.892343194786746,5.054703376541651 +83,311.1638007195464,199.2269266475195,7.010045021779638,4.7578939104794555 +84,131.25454150771196,252.74638995613617,4.531133252555627,6.22007738425752 +85,130.00327880890623,253.73048027246645,5.394441049750279,5.395681634052309 +86,129.22821068759833,257.7545799264177,5.279052334030264,7.778585552031296 +87,129.85581048785428,254.17406429530502,5.674102333754549,5.78050786879303 +88,173.6706310017366,256.75225947929334,5.866553313440161,5.378715368726579 +89,173.19230063382054,252.91916601625073,6.879373651171615,3.4635068657166914 +90,172.94503754837874,251.33290936706462,7.047271185711796,3.2903077685151048 +91,175.02952167330142,257.0499364883758,5.235714833141598,4.602554026194267 +92,213.7890816038331,254.6249053619213,6.707076930736432,3.4712358181628 +93,213.4468844061598,254.50412813549863,6.518799611232329,3.278464480563131 +94,212.79962250914713,255.43887452853883,6.766022500672822,2.705140416783796 +95,215.7691494277275,256.0321075659609,11.50061919709342,2.706589746451831 +96,256.7694241536286,253.44332189577563,6.865986829223564,3.232990348543302 +97,256.72510650144056,252.79028393976105,6.828380413657813,2.603426429287444 +98,256.8442650233618,253.14460283696363,6.821267955887984,3.254494004204524 +99,256.9799728864509,253.50866793284385,6.8533044126794715,3.166075950840959 +100,298.0833417924816,255.11218204520893,6.68748523503982,2.5312282089724154 +101,298.2658386968296,255.0162251091937,6.972265462941957,2.391655492853278 +102,298.07594362921077,254.9831987261273,6.694673144383624,2.446242469655284 +103,298.1576505106038,253.88763222872188,6.715087554789903,3.885076107906952 +104,337.3091830161018,251.4473414930906,6.239563573099407,3.9949672494208963 +105,338.52343083029405,251.73143621714976,5.899400220598736,4.827509891673079 +107,338.1840923615987,251.65216202919063,5.969934007979263,3.751028655396448 +108,337.64939708910254,250.30336435438954,6.249968722123418,4.858284281787599 +113,273.95099656515106,308.7034217127645,4.47709247898054,5.982967845021163 +114,276.2427158717565,309.6243826995124,5.356119731482595,5.519574978016204 +115,276.84469790647285,310.1401260519893,5.002026768143788,3.605341196767828 +116,277.0444072504442,310.2242983789689,5.093238900500282,3.2415570106605673 +117,320.1389402262641,311.63009189142485,4.939108050053555,5.410806300828905 +118,320.02073795683015,309.86619068708495,5.027296431375431,8.060815849838507 +119,320.1219104879224,311.65149736236003,5.012337784903855,4.875094660414595 +120,320.07204598420145,309.7142498435185,5.096615721025626,7.995525189669432 +121,361.50564549283087,313.53985202649335,4.795734938117528,4.058166847376938 +122,361.26704674904295,312.86969370023394,4.911340820107842,5.091228854756303 +123,361.2967353862394,312.27740018121676,5.035196497174981,5.584514630261738 +124,361.10126473389414,312.0592776230653,4.783581913783201,5.306719192876605 +125,443.007863468424,317.0482807576108,5.010510348067979,3.2746926716250857 +126,440.19719004623624,315.5077064666447,2.501683625204251,5.638134747002355 +127,440.39835940889833,315.5795170075373,2.85606034332895,5.721606221790266 +128,441.67660517656856,316.6947608213303,3.639566862837229,4.302035563866815 +129,480.016363698198,317.9126206681539,2.233190012581438,3.490216783801077 +130,480.61644673663056,318.57621643309193,2.3716485330417605,4.382988558323238 +131,480.2151199142978,317.2082517588217,2.247293593796934,3.5149416209558377 +132,480.759709821911,316.6390215996198,1.8855815838100882,3.2368313913566618 +133,9.357026815909922,301.1394481670515,7.424860692299219,3.8886973359748533 +134,60.67253427636335,295.1565427193327,2.410669490697829,4.491297160618824 +135,60.246223227743805,300.40587765988005,2.610803253456402,3.8238226248434817 +136,59.58730981243586,299.348986354774,2.4093805788992184,3.557779220380588 +137,101.23721185167861,297.1740950583595,3.1474540219144633,4.890082550289469 +138,99.63203134966024,298.11971146106544,2.5218334720238236,4.231121185206979 +139,95.14237458574763,297.9444005267218,2.877040509030959,4.1131387022222885 +140,100.78477416100239,297.8704635718194,2.4143008563576176,4.154160490535302 +141,119.7250471805502,298.01476664170673,2.715209640937237,3.093112605602225 +142,117.02401243356974,298.35207687180383,3.08539437068056,3.0048819093528643 +143,115.80692312962971,302.2766266204045,2.8382177918151514,5.138019098209974 +144,117.37742445192025,299.4258416995056,3.1697222157479636,3.228779441784994 +145,142.90918088465534,297.6178016264094,3.0832619899763425,3.60199958241714 +146,143.99054736678715,297.3373199008806,2.9996657202962216,3.476044966382911 +147,142.68589497073927,297.6157999040096,3.132429288120055,3.6266815665628562 +148,140.49454000047197,298.03917216089854,3.0056568959849406,3.734214838274721 +149,181.1180739987013,297.45610301892515,2.9102280695661635,3.430326706550376 +150,179.8095562359686,297.27756454662233,3.021840744008918,3.4405430793578002 +151,180.86813470943852,297.15918644525635,2.8691980137577318,3.454347921701997 +152,181.2406356303146,297.2424283977706,2.9384917862774746,3.4319912000139534 +153,186.63497292825323,329.71520796854617,1.8343875090418584,3.3743188292573 +154,187.13559762838133,329.51685230643136,2.083912846195953,3.300784079309373 +155,187.40105015626258,329.53867670663755,2.14805160685666,3.2933937706575724 +156,187.47298980472146,329.56496093677737,2.1638184471687887,3.301333072095006 +157,231.53011125776158,328.40789450036294,2.6073775062440263,2.988502538747351 +158,232.95501178876998,327.80492336093096,2.424236811554027,2.350854989534598 +159,229.72646596258252,329.3298075897175,1.7204738903289671,3.0704923118251815 +160,231.2073236731834,328.6714932883225,2.4438861147678295,2.994769224677437 +161,272.85319893527105,329.5668274175589,2.341440048111982,2.0154389968753095 +162,282.2212417820937,329.4367762421606,1.6558383645274921,2.653180738201903 +163,272.98005102373446,329.914142628833,2.0535729706681347,2.386063407880205 +164,272.95435454694245,330.43431753911966,2.0639940112617947,2.36112135650202 +165,312.8967133138425,330.7228636434229,2.4191353299335647,2.683491777579408 +166,312.8953561925438,330.8465788842154,2.4840737872275156,2.6822749686071305 +167,313.02590086745846,330.8849995926087,2.3762208918687464,2.697650571027151 +168,312.9409779932792,330.75973451781795,1.7568824225422763,2.681011243704313 +169,395.70755072087877,331.7781381458078,2.4577717664195537,2.5638227463557386 +170,395.3337266028771,331.43381176706987,2.181281870585342,3.1337432803521126 +171,395.80626830723384,331.83504925004354,3.343168830623854,2.549566986608766 +172,395.9132452906355,331.8528749734858,3.487324246008807,2.5438283475869454 +173,172.9730835697278,153.07041804847032,2.9494726617733757,3.382217579007034 +174,174.54971679519662,153.38021154909217,2.9795452304182835,3.4124393018031505 +175,174.36354763148583,153.16813701756828,3.0454139103327917,3.4583182798940344 +176,174.35826919924722,153.1700612928826,3.0211141262576273,3.4091382049295103 +177,217.2505549073576,156.64130212161544,3.566395537735253,5.205239829046527 +178,217.6980323106648,156.20521332851527,3.441914436456696,5.052429489736655 +179,217.06819564151806,156.2917309214015,3.586543606555209,5.007013880138526 +180,217.747171393919,156.15624360378254,2.801603355598029,5.1577319803732085 +181,260.65829263531697,157.11165943543224,4.071932875596254,4.2654996092602575 +182,260.2873418729937,156.01133511605644,3.8080469436278466,4.739826748647123 +183,260.65241208670443,156.65264585083804,4.066095494476047,4.309005262298059 +184,260.7008275437579,157.3470048006293,4.0954566230931215,3.4845516638308904 +185,303.74815224402664,155.66355774568396,3.170947192231751,3.473866833204008 +186,302.12965337523497,155.7857969814269,2.9930059801075064,6.048866083796893 +187,300.60769039476713,155.76327680748759,3.9951348071403796,5.998453375045407 +188,303.74316048048706,155.85489621294607,2.9236413377489514,3.326076201679362 +189,384.93902681068244,157.58958174688522,3.689645238386051,3.2199234634363325 +190,385.6953493035584,155.9304125075569,3.6373602156895406,3.649388391215581 +191,384.52200141722733,157.28840768944934,4.29808384390818,2.2580181721891828 +192,385.00974793928197,156.45140110834245,3.6598188496146618,4.150545508756308 +1 +59,93.01404247432006,213.5226271525372,0.5227911458975513,6.748081819440171 +60,94.33424540812612,209.6207769002175,0.712959043184757,5.35016277729406 +61,96.49374458366215,210.39800263419923,1.1303680657085802,5.547156704495216 +62,176.2808701725152,230.63601199191507,1.0055010380867206,7.308688366893414 +63,177.7659470241458,230.15931042185892,1.1083723356140194,7.241140371768349 +64,177.32083639697316,228.6702361548934,0.9940812742434725,6.592321670041416 +65,261.4355459288758,202.518302086519,4.641943406474736,13.108375146006386 +66,261.77358521125467,208.71156784518865,4.228802506962239,2.433228596876354 +67,262.2239840728469,206.93200819390404,3.913133965048002,3.8722633351342384 +73,271.56840159049864,202.43979307690176,6.020267230118504,9.252928727047907 +74,271.7499513480728,203.11926113487155,6.298067280843489,9.460113190107432 +75,271.44195864454383,203.13378150076727,6.235685371158418,8.78878791063504 +77,350.3678386604973,205.31362830989096,5.486198418330991,5.167398353061708 +78,350.84767505700546,204.7348154139331,5.884173027734943,3.1267473645330095 +79,350.3672092162146,202.65537701706708,8.070802178703657,2.602867171044783 +80,311.14553424067776,202.4869088895573,6.8627096705514905,3.849897420660647 +81,308.52906773639614,197.89051485190024,6.52057770401923,6.5753546391985545 +82,310.7458930121221,195.62555942687163,5.367642235757289,7.169712735992463 +83,310.4462741092919,196.04905416426502,5.898927104709222,7.285208599925228 +84,132.59882836689548,252.18106881985727,9.792699149145234,6.074176114983168 +85,130.27271083469327,255.0125898993776,6.541689138699417,7.5432442383212415 +86,128.24730309169942,258.24673630933165,4.738368491228839,8.535578411913749 +87,130.45275524711,255.95852341410014,7.110134503566371,8.006575003774147 +88,170.36255985278285,256.37507510380607,5.690121369029169,6.698852732879058 +89,172.0725262476556,250.99873611079994,6.021708452291268,4.7312867200629105 +90,172.12065301401947,251.62393859671212,6.229499399540459,5.814534676493482 +91,176.161018968339,256.37597941761925,9.979846996542312,5.435649021007985 +92,212.93760785065032,253.73852022713282,4.877015070829818,4.420381137303506 +93,212.87022485654242,254.1472663576613,6.024553307028744,4.36937145736752 +94,212.6901735716537,254.11072679512063,6.253967049885242,4.460238419613106 +95,214.72029157599158,253.32794140075904,10.942416527294561,4.6292928147759165 +96,255.87095795884755,251.70990738025452,6.095777014998389,3.032297848733597 +97,255.65851168088042,252.1188764922263,6.119873150459129,4.2912655878809405 +98,256.06917412538536,251.38312888217393,6.172049945445992,3.0818160436840696 +99,256.4256676707784,252.06892690237498,6.2866487953086825,3.3887198764991386 +100,297.8256649973607,253.8462555802079,5.924725404966239,4.397206605295746 +101,297.5756213294392,253.9391774660706,5.944381655046086,4.005013371810662 +102,297.502368857641,253.7073727620472,5.860286142652836,4.041363460966722 +103,297.7274471303382,253.7310964744231,6.239643764909305,4.305568077335959 +104,336.6561093798173,251.17938258703765,5.584269888775618,4.812738974889911 +105,338.49750522296745,252.07705913627754,5.543320366201012,5.442573748366097 +107,338.0150937851073,252.18608250396494,6.036908819248115,5.0311597932446395 +108,337.2951518337468,250.18224258519146,5.881938681047152,6.491905854296189 +113,272.4491338841411,308.8369345911772,3.9306201818330053,5.901638358317446 +114,274.3616111627661,308.84705520975774,4.644046045611964,5.516775342288276 +115,276.16521348060496,307.7328192973856,5.477181608323385,4.274725827291863 +116,275.7219694287137,310.13716548933456,5.248785953237486,4.9634566528627255 +117,318.9497922417631,311.557654756341,4.404954111761173,5.820314553091814 +118,319.1412036522322,309.2162698967087,4.478984811722864,8.01149636027687 +119,319.0529158028501,311.2794691857636,4.084462770697858,5.557665052342318 +120,319.10116577059574,309.1842470522271,4.386098755065277,8.133763836800041 +121,361.7830962316519,312.9030603457879,4.571180054194281,4.907320783558812 +122,363.0043086937134,311.7292896961028,2.8960472677148883,5.951933529573732 +123,363.19625593743865,311.0733660860651,2.9383205358529714,6.1061913146876945 +124,359.63316117679994,311.552139939443,2.821256013884825,5.5763574754572796 +125,442.75956343881825,316.115466064729,4.778336574085548,5.530606828021713 +126,439.5856299442215,315.1505995864219,2.585590965608122,5.747036062574868 +127,440.69585939100426,315.0579828759502,2.7149707354695605,5.752920657180591 +128,442.14857834779656,315.935012126325,3.816863855176525,5.744951427518666 +129,480.0220424915058,318.0508150479775,2.545818620191014,3.655165569690837 +130,480.2961674860558,317.54390725750557,2.605035779868517,3.5415144855244005 +131,480.2157699796402,316.6071568907418,2.6092555233226427,3.3584986805507486 +132,483.0300110911751,315.06269628406767,2.7300211118973263,3.898312260468843 +133,87.11667489567593,294.14241735058243,7.598743409857649,5.19998245236602 +134,57.81287299171998,292.38407844216607,2.514015918277811,5.136006470534924 +135,56.72481683615359,300.0118009139173,2.857620857781098,4.750166949488199 +136,47.21055945404092,294.95922659039326,2.6917302124926694,5.369878030902169 +137,82.9740487845219,293.3928921084636,2.4848999003333803,3.9293747558559278 +138,161.9550663905005,295.0453226209086,2.7841652419514227,4.6158307977098305 +139,360.9021185534379,293.4515559554225,3.014363497918401,4.4291415710214785 +140,89.27996833990208,295.47084639542686,2.65494720185284,4.648541410028614 +141,116.08881622892042,295.90714432478194,1.9069874131620126,4.150080850969694 +142,132.15536640954062,297.2171229012815,2.706901698676143,2.9568780838711826 +143,127.63875390271042,301.4424845378769,2.769134247080161,5.578151587102764 +144,130.87079961636513,297.89834733182647,2.818953624476529,3.8997116282895603 +145,150.31209355255865,296.8214130757569,2.725175079922067,4.209022465413865 +146,148.97786084884208,296.6038327691481,2.7067927491075574,4.17492062013239 +147,150.24661339572495,296.7796929595484,2.810800536874064,4.312780918203187 +148,152.60600094096128,297.232015083595,2.8754159917495565,4.377707355346677 +149,210.67045705478267,296.141990804855,3.265568007984475,4.047456332372859 +150,197.09292075504828,296.3228305878953,3.180756798374725,4.46039907916231 +151,119.65069386862973,297.0907409886854,3.355490697464104,4.394699915307226 +152,227.24737645933865,295.9919464826721,3.29596076395495,4.365046047151038 +153,185.29407593743096,328.9756512787473,2.4739170556894745,3.6908535828009685 +154,187.84229703035945,328.67458417656786,3.441179047809909,3.032614629941614 +155,186.58809302809905,328.98652600447394,2.9369976692797604,3.5987191187020073 +156,186.9163443606333,328.6316285416275,2.8964425091038914,3.4524747234516604 +157,229.29082047745888,328.15179687646463,2.4437228704779783,3.75376327066602 +158,229.7362726809719,328.8007493567453,1.7377499391208846,3.510569661296656 +159,208.26809226199518,328.86828867681027,1.5607659119719737,3.1037014684154176 +160,229.09214710427673,328.6178358476461,2.260028006988348,3.6920398661292713 +161,272.30550005795965,329.31313118492073,2.228336338998844,3.1347450587831363 +162,744.7928105338103,324.23769166614653,2.1073598387590406,2.539759184702161 +163,271.92463381929605,329.4914525203367,2.354794935998881,3.3821523721928775 +164,272.0763070212753,329.43329625041076,2.2564082813073223,2.976824453200896 +165,312.5002968548282,330.6396470335998,2.4980562783012132,3.342049851550277 +166,312.6633003087961,330.708018763403,2.485750243447884,3.1257959767437193 +167,312.43290491220614,330.60640551938684,2.5861522827731918,3.1384938126252546 +168,312.53461746652715,330.59614144293295,2.6327977881534315,3.2738519720709336 +169,395.4235565349371,332.05857012716825,3.042284807396061,2.6618134827186033 +170,395.89575300552235,331.2204950674755,3.5075609281016074,3.432678442805089 +171,395.42995858598874,332.11325844782596,3.0389919063576745,2.634943595710816 +172,395.74810123344724,332.1696223944591,3.3020110174888058,2.910921037939185 +173,172.38094968570545,152.05413649604458,3.009792250294108,3.523757740020178 +174,173.8277034486298,151.97246989575592,2.927263574496173,3.3547430273206764 +175,173.7469031569836,152.01702715147732,2.992197181370308,3.5878204759260535 +176,173.87444349441117,151.90034527705913,3.001730291594699,3.3191803731856986 +177,220.05954791045562,153.93486125597713,2.916964654294944,5.161796303421409 +178,219.06032109265325,153.8679197592309,3.02283014757281,5.214692401346838 +179,220.20248145797134,153.83037812747935,2.811916018641933,5.135768243874929 +180,219.8662882177588,153.69386761094438,2.8932331677602288,5.195182563087241 +181,258.7941680380869,156.20170959987001,4.509844805839375,4.210885005617385 +182,260.70623290807583,155.5691133699838,3.9964474629559583,4.494356603934025 +183,258.66062861832245,156.13098164693182,4.524480095522743,4.217380456749666 +184,258.7614643354862,156.22967958243044,4.5086857868814425,4.199456605512427 +185,303.22935297897106,154.43469284754158,2.9235122344572497,5.0253634772759375 +186,301.737374625956,154.2611896143699,3.0779278021862946,6.153602357601281 +187,302.23615729321835,154.26453424384667,2.993547760611472,6.256352853265299 +188,303.7378760514983,154.33358903047713,3.094665979648467,5.269632450902677 +189,385.4931704373973,156.2752179977739,3.473675270188691,3.9607689131121706 +190,385.00254984000435,155.26821198570494,3.5586590950004457,5.391583365108707 +191,384.0813093792461,157.57737240690167,4.44594499401667,2.8998689471390326 +192,385.1801338588461,154.8206336674526,3.6798775544177063,5.162336041483175 +2 +59,91.30284200670633,218.07642242545626,1.1539219073226616,4.534512576080954 +60,94.47064527098745,219.916516135159,1.2005691862986814,6.846135813191627 +61,94.15679646295986,220.04095088976442,1.4155925768586246,6.838018547816678 +62,177.10956003057285,218.90103728250688,1.3905251660790856,2.7497320728371646 +63,177.74456263111466,220.06649622720403,1.2185587916549738,4.188825256215504 +64,177.49917127590462,225.5014059314746,1.662625480516144,6.3447162872422735 +65,260.83235784169676,206.768453469812,6.640373185442694,16.669713322142147 +66,264.61912522766306,211.23389035030604,6.418829493449439,6.7515824557814765 +67,264.56313646993567,208.898424261183,7.577757476106213,5.397905740603194 +73,275.0807583567399,203.46314981555653,7.529121753107468,7.79068598394073 +74,273.3391581028213,206.03543897900892,10.405037115613153,8.539004741937488 +75,273.12815716759474,205.75279846700272,10.383171899212439,10.3236022000293 +77,352.39736693776445,203.25064337648874,8.32458599948799,5.647682458487953 +78,352.6804091269042,201.66565569114204,8.497380645406677,6.217216240364239 +79,351.5731625392584,202.19179726341497,8.658775240139533,7.111128909229292 +80,310.6751701124307,204.64495746423012,8.062037456416205,7.444446872078048 +81,309.6670401069309,201.55447995655948,9.465643221743878,6.881819412692541 +82,310.6335818256993,200.22299800671655,8.67387089777447,4.664159850458751 +83,310.9019318418565,200.02015346830518,8.510118775528804,3.8829013885017067 +84,131.06337257497074,251.28475092908215,5.159471427859664,7.099566355433584 +85,129.09144907108433,251.7203734728845,5.198191014751725,5.290792123590904 +86,128.14221980812886,254.23635236985004,5.978168978981718,6.3363646857946305 +87,128.5504980446596,252.95544188750205,5.339963887657365,5.754904964464613 +88,173.96747545182777,257.59357552003803,6.482400441297941,5.234590780368996 +89,172.64797467848848,251.12847549296245,7.275410666068803,3.2555916560823848 +90,172.60455067578906,251.16298927626656,7.222779487902638,3.496102713076582 +91,178.63195743713817,256.00196219903546,8.724215688749194,4.5367531498363824 +92,213.30204486943944,254.65697701565333,7.662137596538662,4.165845349061372 +93,212.8172314127949,253.39712914171187,6.857530904039771,3.977160865721656 +94,211.8792430432469,255.82761299122967,7.222038595318558,3.1694534357454573 +95,213.7978436356281,256.0278412645292,15.452080822376551,2.4945072295635016 +96,256.93972703527453,254.22973688137205,7.44290569053337,3.428653114933794 +97,257.1457284865542,253.4535805850962,7.332108489145229,2.4944378698026863 +98,257.00282187401416,254.12419273967237,7.2764048131626184,3.3193016977855763 +99,257.04994365436653,253.94432494945963,7.423089718980076,2.973336749681888 +100,297.56026404755863,254.32212106774926,6.852565823032563,2.8493609623085123 +101,298.63371928814155,254.61437178101048,7.905691877078718,2.165690092942747 +102,297.69407107379396,254.4850393852944,6.836012542442264,1.946205259389151 +103,297.9023244730469,254.38868473138925,6.751896664205788,3.3116178759031087 +104,338.0053276434522,251.83336967087538,7.799885374056114,4.945594824336877 +105,339.1582769256123,251.94932873663424,6.500886426061445,6.047632898215193 +107,338.3102566581982,250.25272692617727,6.48687937625559,4.657479797529445 +108,337.9547753028731,250.03478792262877,7.680658310818983,5.287653170857336 +113,275.910952296904,305.86738853882827,5.34030651381748,5.289299280058491 +114,277.42120270272227,311.21743667247097,6.194812315610025,7.468012633884288 +115,278.93960224322814,309.638371888345,4.951788309478035,5.6357014265428536 +116,279.87420391551683,310.72506489150953,4.822827709017515,4.736286987210306 +117,319.79423896861897,311.2133693181722,5.668930716768623,6.682907491520234 +118,320.5540626961792,310.68709367641236,6.419719926410251,8.237770206306163 +119,319.33379454853355,310.70701535995903,6.465185367234193,7.897980684891891 +120,320.2722313120129,310.1782745929597,6.268219945694488,8.023329923606077 +121,367.6098676953658,314.58028508890305,9.39615711787979,5.649531231448145 +122,363.74508504031036,313.48439864622117,6.684116998496468,6.329996512810745 +123,363.29642172711425,312.67626164324315,6.400837328497925,6.909673033958756 +124,365.0277447799763,311.6147364893551,6.720810503358312,6.645516125018006 +125,446.2253017919773,314.99416404393594,6.395392871846412,3.382574041643381 +126,441.1237388588513,316.35150200412727,2.5546429518376508,6.635379091123845 +127,442.10117921669377,316.7934137028694,3.617061357493329,6.796381592950393 +128,446.6969923351063,318.5296550554647,5.9848567355794176,4.343944361749059 +129,479.94558754651956,318.22536134864447,2.220264608006834,3.836710322440239 +130,481.2539099375137,312.640306388908,2.593318771161441,6.6486224400214775 +131,479.45347062880376,318.2469542979415,2.0004364038172557,3.688680674174361 +132,484.13323268726947,316.73499335627196,2.002291195085977,3.781086788196597 +133,85.29652368782442,299.9267050080891,7.827458514431236,3.9374236627298966 +134,59.67355911737736,298.3611375665026,2.293779231438959,7.12389408216543 +135,54.93006667794998,299.54260321894077,2.4753999616786904,3.512718857180827 +136,52.88374765283322,297.62420743734526,2.052251163735395,3.0356052182771274 +137,100.22096248097169,296.1954497008577,4.3012641162676175,5.212420406396804 +138,77.57773257938949,300.1917036834339,2.6075704778239923,4.343174316530481 +139,114.23749297790368,298.69307716260715,2.9175645781194874,4.154406732926865 +140,45.03330152423734,300.5503452125839,2.625583107839479,4.294099847159548 +141,119.51809674004014,300.04111347523275,3.4424531063915236,3.6098269870345647 +142,118.45488030550041,293.42435614635554,4.076098186731008,5.934920124944857 +143,110.877037200568,302.13823496880946,4.847942451776839,5.374114325813509 +144,116.6620641371857,298.368278265185,4.685262545376076,2.953550317426917 +145,142.45731006430879,295.1000575604827,5.189856548842566,3.111987985605453 +146,143.20014617587012,294.78019680871137,6.0198625121087534,3.3010521003465834 +147,142.56298735658783,295.1170233357802,5.20261559459805,3.442242559647229 +148,139.89055528539328,295.48129747000496,4.278137116722635,3.3562006136085 +149,182.28248910013076,298.8925711419297,3.882958147572496,4.932530677517502 +150,181.93047252438868,298.64825753275414,4.0369897133739485,4.744932625303357 +151,181.98693496359542,298.1631625286757,3.8155850034361163,4.774725772494465 +152,182.3110519597161,298.0855672750618,3.9895325459128514,4.794576201460771 +153,259.4920457606562,329.2756913744665,2.454071420423271,3.5104389207411675 +154,191.55276246651394,330.10335406699386,2.7535159658488753,3.735374001963311 +155,194.48534159817734,329.9443292127414,2.1365830195361943,3.127947562092398 +156,193.39092086391267,330.38614167206975,2.1963679483715697,3.459040917080195 +157,236.17750038130092,329.0436536647159,3.1786720809581777,3.1430140286789383 +158,30.916842755515052,331.29060642770753,4.841452724981102,3.7495713033876124 +159,247.27788073241743,329.51692678380493,3.088707102960316,3.923308113475421 +160,250.22189392231115,329.26270263655886,4.2316219686433225,2.8273483917495277 +161,276.3128460929227,330.511230724005,3.4419490584726287,3.1926367377041047 +162,285.59180034302733,329.7481991930167,1.8378511022559236,2.962363935958349 +163,276.2745382801029,330.0900901745128,2.1081569415614108,2.3238295865477 +164,287.0159796232469,331.2727625321787,2.716127438341672,2.4485626997745595 +165,317.7395849994937,330.4138825095169,3.3757057306286984,2.8095989664256256 +166,314.6572377648183,330.5793633642782,3.194427388751986,3.0041332311662914 +167,317.00117777059165,330.6383247898892,3.201153763642872,3.0057526788151607 +168,319.284335249175,330.4196934261666,3.436552449874256,2.8793534460468897 +169,398.9491001935992,332.1016164460315,4.590701775382649,2.4853527290993047 +170,397.4873909051454,331.4430567330248,2.0553328419425942,5.097090036367185 +171,399.09113630168383,332.21159139918905,4.665806570428414,2.438404994920128 +172,397.7907669635104,332.21375146950754,4.160036511822063,2.302533773606481 +173,167.6549194927225,154.8195960714067,3.578104764139934,4.293948219715187 +174,172.8857977008767,154.73930238156944,4.065505613610561,4.397450234808648 +175,172.58520462200156,154.29013402780822,4.048705697811711,4.112000867673462 +176,172.5358949970105,154.45532035873933,4.181462595099683,4.211635985550709 +177,191.54370072344057,157.73353022270507,4.841190533624689,4.763972692389171 +178,204.05445279340313,157.37702899559486,4.494318996136587,4.337287440506104 +179,191.65543785128887,157.74655585598282,4.883158661002671,4.919623053094591 +180,189.28378158246906,157.63000871303564,3.5274346584972274,4.408356106260135 +181,260.37023207173655,157.73328509764173,4.261494343445461,4.8366413757834135 +182,256.12032377018954,156.0742352828994,4.281428257218825,5.030259376007136 +183,260.3960744140202,156.38669157075003,4.242232860054043,4.583829032686845 +184,260.6791000228129,157.9519422581545,4.2747999006513835,3.800985332770269 +185,302.4998205898764,155.53480279841136,4.116529613451282,3.3417704291330135 +186,294.8930629353272,157.4031130939023,3.9041732736595818,6.391527497892834 +187,297.53924094539656,157.38305310411857,4.3287195790389985,6.365038877320703 +188,294.8108560332771,156.29685130271133,4.759679064189887,2.700855536462382 +189,379.62100651919303,157.52580336807762,4.648970244832296,4.614333688454686 +190,385.0749564946942,156.23453384699377,4.097215876576247,3.788089778011118 +191,384.1197434977094,156.68532544972354,4.287357345412347,3.2806588007554622 +192,379.3432570533363,156.93410438422325,4.592318070059131,4.5896206349551 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std2_p20.csv b/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std2_p20.csv new file mode 100644 index 0000000..2961aa4 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std2_p20.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392,0.9677151865944192,4.009449743264753 +60,95.68692886974831,217.86446645631813,0.7424975144337135,5.151973582834018 +61,95.27930768267886,218.4321212539979,0.7270480243366128,5.212134543408362 +62,179.68821344888678,221.21713400884485,1.1147842657503555,2.1332525060692515 +63,180.64677254143638,221.7765304937586,0.83092419657981,2.5740660863437568 +64,179.86073442223173,223.68541859670074,1.1381174020649096,3.626058878513354 +65,267.0750705461852,204.74717443096984,2.241840204786577,13.182457200661304 +66,267.19879488924516,209.60901887734772,2.3697667509990565,5.035545962902496 +67,266.1798697712201,208.51040145394091,3.540061676733699,4.595558869507625 +73,274.3400431870006,204.75610310411912,6.491531432619202,7.31888797087335 +74,273.44321864391185,205.81069417739437,8.261574847627143,7.257546441830887 +75,273.15099171429256,205.61817173382607,8.395328002698498,7.565385107130859 +77,353.2630018061804,204.6061088758629,5.493098240735283,4.29566322817894 +78,353.8852531441488,203.30592180203516,6.087365194189325,3.3836943891959814 +79,352.21840596322596,204.15679894425952,6.557195072515586,3.1954900594475086 +80,312.34313113441607,204.52530436142615,5.588158051911466,5.745243989851365 +81,313.1160349693985,201.4084182788836,6.025875449926955,3.654284157032464 +82,312.11840038067925,201.00669797880116,7.0864910249072635,4.406813194332426 +83,312.29317276741347,200.45780062295867,7.089188755441932,3.1660046223221405 +84,132.42237239805132,254.29214663519284,4.3067464843901515,6.417058493680035 +85,131.29521858798734,255.4865958538821,4.908850345384105,6.3671100735668835 +86,135.9988356956537,254.77748611685175,8.584433337345413,4.9941716761414146 +87,130.98094102950247,254.42187606024922,5.117211446405824,5.370134929913309 +88,174.56636927613675,254.4831815599854,4.7275771979909464,3.1678947409316813 +89,173.67935580024877,254.09783447631526,6.437695363099053,3.474606588647915 +90,173.36920502447623,252.290452181076,6.593885801251147,2.7873975371893436 +91,175.2895186608897,257.2751667704358,4.729209363054509,4.452820054846227 +92,215.07500705655937,253.80949363235624,6.334123387607411,1.9488808007329534 +93,216.94462220467622,255.47756358425315,8.080773269328214,2.7211585139427834 +94,217.3834915918711,256.4745644877478,8.267318853585852,2.211181525286066 +95,219.6648004345676,255.57239348461326,9.86068974730619,1.4652046608845635 +96,257.50957542067664,254.1259284055811,6.675780060232609,2.704136241957288 +97,257.570545197815,253.88751117668164,6.647657278502652,2.9140751377307628 +98,257.6089813372307,253.78662089019835,6.605179609252467,2.6809454420956143 +99,257.6936671647974,254.2498517060511,6.576722939133856,2.7069332019005827 +100,298.2952436151055,254.76909617478606,6.705809824561147,2.981349985017069 +101,298.1169393001307,255.21794911950758,6.624534032640799,2.181605220236403 +102,298.3189654536773,255.25096983760508,6.750900350115645,2.3083727544087247 +103,298.4415890038736,254.35763625124292,6.663590033871669,3.2667839890941295 +104,337.66969489877954,251.71635156144524,6.210728685673001,3.377413692122266 +105,338.1116560201459,251.7179090471175,6.338074391942699,3.587185716331372 +107,337.93979130669914,251.84264636476274,6.288961573364599,3.0282904644933937 +108,338.18833275957206,250.67508565210196,6.186589358792703,4.10107941402743 +113,274.2817559120019,308.9374117445766,3.892956777078502,4.794749659977309 +114,275.7421347767481,310.2555996702759,4.535765938235691,4.66622650744931 +115,276.0461325201841,310.02072804280994,4.545655403672037,2.2262514157125017 +116,276.2417374542582,310.24048782871637,4.6497847767530995,2.8951312130050146 +117,319.6559290654899,310.99105624588617,4.410519998245082,3.0198480458627897 +118,319.6313092726346,312.1826263203713,4.334709687203355,3.9909339754311914 +119,319.46776160473627,311.841371820779,4.471689460416843,3.8980513701355664 +120,319.76654338764155,311.98447027104925,4.4491853585047645,3.9716440216868176 +121,360.82585188540037,313.3258908241004,4.744138263484551,3.1950268933478396 +122,360.64739266264627,312.8307783296112,4.673876604017344,4.0505350195787555 +123,360.689270210389,312.2626467099784,4.717842951294665,4.331175918113057 +124,360.8335382258014,312.5428875466125,4.7257637014968825,4.238743771700391 +125,442.1542117060401,317.1277309025985,5.1708505304868275,2.8339991015485375 +126,441.42140737582423,315.78584607818385,2.592454459875001,4.6687701093869 +127,441.5300773440553,315.90717126090226,2.8050705738429227,4.687041451309435 +128,441.95769286933466,316.8407357397122,4.805859396667629,3.6325916039286454 +129,481.35090878368925,317.4272946632326,3.3586867882998677,3.2305216999009705 +130,481.4725819590857,316.6159681822135,3.546147101969164,3.2838056303462357 +131,481.1535576706723,316.8819465108059,3.263691605498864,3.2346725461032757 +132,482.21933609621834,316.90676933858305,3.3334111968000197,2.8211028940841043 +133,59.55768321914789,300.29871844382603,3.8761928423107794,3.6951665481304303 +134,61.376816545951996,298.3523691730104,2.113993300917673,3.899220174332725 +135,60.60960139542109,300.5877018018443,3.3916290934001863,3.597118842410694 +136,59.19985355062283,300.1851062687214,3.520034988226608,3.5453648546285197 +137,102.6280068014727,297.40383468175656,2.749638491064498,3.880988203100239 +138,102.40955557323258,298.7865911290351,2.7573372442370903,4.089700063188653 +139,100.57013333623348,296.8202762296189,2.9651756626973564,3.163333481381463 +140,102.67850653460079,298.5730025774653,2.656076828883503,4.008870765124035 +141,120.23221696171454,300.1898879495705,2.3495738375350714,3.7101386992401784 +142,118.10535832779757,301.85912326532906,2.662771758344228,4.434372354516663 +143,118.16700474619614,302.0417496311767,2.810926040633238,4.442752618047973 +144,118.19187121087131,302.5378510894045,2.8502302470584953,4.428574269320613 +145,143.380762851227,297.65106023170455,2.9029598644975594,2.9494319243206975 +146,142.46748228973178,297.3647432540817,3.516542953167025,2.7867411900804395 +147,143.2239805848247,297.5672414624104,2.925450223126345,2.8821527557517435 +148,140.51718892104998,297.9845023911149,3.134479693224828,3.0837592352072623 +149,182.6593569656309,298.1418468359333,2.648390300198232,3.275571713707499 +150,182.64828488417706,297.92582445480707,2.7260433370787203,3.287985243918374 +151,182.92797391602642,297.87455852433123,2.5754349127258473,3.303821768124996 +152,183.0029286817877,297.8637465373881,2.6850779296217095,3.268506780902108 +153,186.1728851830908,329.8083307385874,1.6988565395865438,3.2857803265960546 +154,186.5492243440529,329.1491955430002,1.9159248202789043,3.190026296337793 +155,186.0292302003802,329.23752125561214,1.630100824234192,3.143397778827556 +156,186.05706501583137,329.3191466220413,1.6185913035274193,3.18627620460259 +157,233.36795685970054,328.463961880729,2.643309826783174,1.9867341998292147 +158,232.82586842848798,327.60883484043825,2.477588134745834,2.5854098103097747 +159,229.71350413783279,328.3780985513343,1.4377331090494412,3.4686128953627313 +160,232.72525153041173,327.7700361791668,2.4530240891852237,2.5077492129850194 +161,273.76316751955034,329.73823826493043,2.394688280474286,1.806427127995776 +162,275.7575781134558,329.9125721193857,1.3584269354839966,2.5506427041479443 +163,273.60940070127293,330.0025820738042,2.4087695062685763,2.2557767070416954 +164,273.7244999819209,330.09757535831045,2.4201727937672897,1.7894497412511505 +165,313.3973669095876,330.59163642669836,2.5664663718925884,2.5175272820859127 +166,313.23094160288184,330.71155384663837,2.556749103943359,2.517895305394224 +167,313.2083786255443,330.77428522126553,2.440925958919023,2.523508078782979 +168,313.36106959216625,330.6523370232485,2.5105680868176643,2.5022918306323914 +169,396.3640143494862,332.05477157898144,2.544597691516881,2.2242293500191375 +170,395.617460222669,331.85554030819173,3.094183882820774,2.2794261534246627 +171,396.3911361968549,332.1303447002533,2.5527965384171347,2.1830363581679078 +172,395.89256887798285,332.16822339411516,3.601013097767017,2.1716024486759946 +173,176.02029170516317,153.71245910000232,2.3779159513262353,3.409134278667166 +174,176.10545306203875,155.20318481126037,2.4825478178566596,4.418906030455666 +175,176.03197440143745,154.95241321278883,2.42399408636437,4.430327097224612 +176,175.6846804297304,154.63359606135103,2.5997462043064927,4.219400830122209 +177,219.46327960613064,157.23609785750858,2.529672116014354,5.058864568041901 +178,221.0564853241154,157.3435472260885,2.2463229070198545,5.480115541197549 +179,219.62129396536662,157.2666553285107,2.5021134486595593,5.352065132338259 +180,219.69587995502016,157.1490063640601,2.516169881431476,5.470652636210902 +181,263.23636033723557,157.46707082247306,2.6921936322678013,4.204926201545835 +182,261.3833848255912,157.14497162705263,3.132796451668047,4.135023908563071 +183,263.2875985178052,157.05504332147794,2.6601053814719973,4.186611997777448 +184,263.16270089611913,157.68858593709763,2.7082086799182084,3.4205893941412424 +185,304.0771964580808,156.36708101762838,2.6882263261194885,3.319861960122729 +186,303.2325028543831,156.57995759281437,2.7961523629805916,5.391517197327435 +187,303.42630311491723,156.4924674158584,2.783092188384192,5.365203962414015 +188,304.6158660912609,156.4818813819881,2.506720194343099,3.179833381166062 +189,385.45560134261797,158.37035395252553,3.5085984360932585,2.735043850552565 +190,385.8286612719259,156.9884186905783,3.520976122354819,3.199129896839037 +191,386.1864174896063,157.19189241238993,3.2937940620339354,3.0663737335825165 +192,385.6347971660166,158.1411858434322,3.4609224939824603,2.846649085773437 +1 +59,93.1287423931208,218.29700908810787,0.586116217920642,4.982728971287442 +60,94.70512938803542,212.6540109552706,0.7530580888942188,5.342989457535182 +61,90.1361278577332,213.33121631876608,0.7741246171980174,5.183322455003788 +62,163.05397573990066,223.03302231371174,8.768671109743122,3.608965585949599 +63,178.56039861950646,222.19098474984543,0.900267664385944,2.917664454486164 +64,178.37920648184422,223.51557294327878,1.0988445958401813,3.973656567077689 +65,255.80438353417117,203.04815455047097,6.766813492476352,13.29699627358335 +66,262.478672605179,208.85138164100843,3.5774987545822987,3.7830932795933596 +67,263.60616955216886,207.2183121488101,3.5771988890480593,4.252166210585195 +73,272.29022155441146,203.26015396542505,7.667403148427107,8.484726496612334 +74,271.46793735704193,204.00075736023095,7.006836949843662,8.57906517149974 +75,271.0412882240347,203.67673019265595,6.9166949430129225,8.702335904677817 +77,350.53069989533947,205.1215453780687,6.3913113962364445,4.675912501749536 +78,351.5335450988067,203.6132402057685,6.914935781146339,3.647320534476688 +79,350.54080463471854,202.80860415043412,7.576153280744988,2.405442522969295 +80,310.84312359894454,203.07084060099984,7.338460358520777,5.637962269519666 +81,309.4303871248667,198.8260778916456,7.8402558918165015,5.732595151892859 +82,312.8487475083582,197.88498609405823,5.545843437300968,5.5454679231566235 +83,312.4494378330193,198.02482356912975,6.100953297862154,5.205602033075617 +84,129.73316120742015,252.31402870350382,5.182904459352007,5.7859701617993196 +85,130.09936826716955,255.07600217340146,5.535923397107699,7.036159941672144 +86,136.48684968097632,256.98593054341063,10.027649034484337,7.342825955920834 +87,129.96018632025633,253.63904238622214,5.660756401038712,5.8266843261131385 +88,180.12754728190527,256.91804818977533,10.57223062780983,6.228147264882277 +89,173.42291095269067,255.58833819764322,6.700532645820975,6.247923198559783 +90,173.0543226504001,252.5748838461415,6.760737603124655,5.231000998435721 +91,174.29585433427428,254.46270745029543,5.389533179624763,2.8578511182829476 +92,216.78511969207446,254.5914187233686,8.95047307481889,4.249360054724529 +93,215.97344562124545,254.7054640425066,8.196439917611718,4.011111129846635 +94,219.24024367384476,255.41662872012847,10.121690584983755,3.367632134220822 +95,213.81498670140752,252.60321047848737,6.581085797491111,2.395105254724356 +96,257.3830982530756,252.6691612485834,6.880768996147865,2.9353265504494703 +97,256.07878148245777,252.5850508469038,7.193370431289156,3.536434124406424 +98,256.6563709830754,252.14302077100646,7.020255474285572,2.742516414019443 +99,257.10274737541874,252.44669038983187,6.759367673913806,2.5065554147623534 +100,297.3527413648711,254.3197859755712,6.974691942771777,4.204342914024384 +101,297.36935919598676,254.31625883281748,7.003782434070834,3.8132099844257588 +102,297.45043676182286,253.29006124829388,7.147301062318091,3.0312100621116413 +103,297.15639353267426,254.26565823155238,7.3776805534006185,3.914660604118064 +104,337.0838455883894,250.64743017278894,5.921815081770851,4.024140676300613 +105,338.2943046084806,250.9606925384406,5.481575455905726,4.1053232838414155 +107,338.46927119138405,251.82861699933284,6.654167871317137,4.251478363049102 +108,337.6321115297869,249.87042147419172,6.005664399486008,5.04451473974955 +113,273.20050531167254,309.1760573916311,3.4219821116654865,4.957144824013617 +114,275.593658985165,308.5727448984995,4.702522493967433,4.008413607725532 +115,276.45985797306344,307.75120186662025,5.767076285351399,2.479883936569082 +116,276.6589541465393,307.7328403118153,6.184525915073467,3.409658651068851 +117,323.8680795155452,311.25555593462394,5.6467354698699,4.163445875643856 +118,323.990822160368,310.23497244583933,6.354306297639026,3.605863723170547 +119,324.4759468599942,310.5137190042532,5.951639025695133,3.8742178925550625 +120,325.7385894442358,310.39579583995135,7.723927817628718,3.904269142941334 +121,361.82046220765505,312.6906221126212,4.3915079798209895,3.595391320936084 +122,360.25109899783934,312.73975566628565,3.3364555278083112,2.7719078470887877 +123,361.13964194906663,312.4482596768938,4.009973777907947,3.338550731387954 +124,360.8021695665512,312.55731463103996,5.178975914859417,3.147724551644225 +125,443.60378722604213,316.81523544669056,5.441494217460369,5.859512902880808 +126,462.74164751366203,314.6397925160877,3.1723106571758315,4.673495905701873 +127,284.4684422338389,315.96181914108945,3.781047749264403,4.799446710082581 +128,451.0537747662026,315.05034330850094,4.165022446102917,5.582872998184059 +129,486.2262311408019,318.917422588962,4.360015955842124,4.24279052637777 +130,484.203371665194,317.155262043757,4.666439360195373,3.538660983437178 +131,493.1775485408943,316.3518621311899,4.495507964960477,4.044073143583547 +132,483.79815450187516,313.87456269013853,5.0513219188547716,3.976286497193232 +133,58.415796919717515,296.3367806354237,2.745318197812863,5.347714894650585 +134,59.66992690532717,295.46552315023496,3.0521020998678443,5.04724168228645 +135,58.30852857429605,301.14443002474417,3.0314355414314353,4.891148165556274 +136,57.19875149216512,296.2038703275876,3.0187024946676813,5.430283114579736 +137,101.88869112962361,295.36699152796956,3.0605704820563435,3.976231975252619 +138,97.74223572831934,296.64159635228486,2.388879471730324,4.818867004598817 +139,95.13971714462463,297.63279866894925,2.5874115321204054,5.108323412261206 +140,100.97448449522825,296.37143206657936,2.23273639508488,4.835560641819327 +141,119.6488680328135,295.99857882673734,2.945034185014498,4.051944183392203 +142,116.04630564586442,300.9428981940468,3.646493643610884,4.201903655805421 +143,115.93833802312685,301.4015147621542,2.7752574824028806,4.899750014060764 +144,117.66427038686425,301.67621994166734,3.2562262537824718,4.934112992862415 +145,143.61862339021508,296.87569921241607,2.9793460068872264,4.493879539069787 +146,143.84226240395634,296.5995702000957,2.6657882037152505,4.487866588043545 +147,143.41726284468888,296.4604242772443,2.892883624851368,4.50539522391336 +148,139.90710854861246,297.05847391439454,3.4669655178811123,4.588153704670423 +149,177.97012292111646,297.29360417935067,2.9817918310917375,3.750304964672955 +150,179.09943783225685,297.22176671479934,3.0286986838896457,3.881572977421466 +151,178.4595029850307,297.07969710485736,2.9749987384442655,3.775627144339658 +152,178.9990807254096,297.58186299960556,3.0418692927202193,3.8833402396923353 +153,187.06432524491635,327.5110792134713,1.9103539442817077,3.1747672773580633 +154,187.40611165319353,327.24266469486685,2.028936750132528,3.039992572908433 +155,187.48202253723917,328.1910452260973,2.046736087360523,4.07325152306089 +156,187.4554203440108,326.77537509295496,2.0468424040406785,3.0346527434557236 +157,230.1275716483488,327.66375493177526,1.3064642552426002,4.735119343666496 +158,230.19455285047118,329.6573791501422,1.6872246668899367,3.583570894848579 +159,236.39481488323716,328.4457905246168,2.716174379714519,3.4183380314351863 +160,230.1984260911562,328.23405030487964,1.818805777200218,4.578868396563749 +161,272.1545894887068,329.32912181766994,2.0716370234969204,3.1939556616595848 +162,272.8983988300567,328.70387641284987,2.430197123109527,3.1487498704390036 +163,271.6162444327857,329.4696874435773,2.203277751618005,4.017476086378616 +164,271.6290916788945,328.8920615225914,2.008299706725287,3.3041284732956586 +165,313.03716740034986,330.7975522275865,3.0420523810535003,3.7108953229128367 +166,312.7612082311074,331.01658878813123,2.756286496478564,3.635011569085448 +167,312.555857804164,330.94886104868783,2.895089352246948,3.630322203243039 +168,312.99233681057194,330.7594147506374,2.9514521257261572,3.7325921124368473 +169,395.6599712440442,331.38000769767353,3.6713668117121325,3.4549858187839337 +170,395.7269407162828,332.3551932767835,3.1249445864849728,3.2139419865878307 +171,395.64772093777225,331.19728501985406,3.652929258669073,3.3877347902405988 +172,394.5822232990254,331.28589367585266,3.5115519861174,3.4415616827579543 +173,172.19300877613125,153.8677984100333,2.9936489675181246,4.5406288069622285 +174,174.43739755929997,152.4534316026212,3.1172372976035665,3.3179648689547276 +175,174.29318678572136,152.18270882980445,3.1219958686591287,3.3048067882101986 +176,174.37774565459176,153.9168218422937,3.148891388697558,4.4895441435882795 +177,218.8977614990739,156.58401687998017,2.7063981074883805,5.2876376907111124 +178,218.82234457362887,155.93775870476483,2.6795499708167725,5.033370956683506 +179,218.14869261453913,156.17880976796908,2.747386160206801,5.050217973950996 +180,219.6136087965169,156.013833915525,2.654919821631967,5.093161539439035 +181,260.39420520785944,156.89107932316213,3.256704661733587,4.125191869561575 +182,260.75752017274766,156.5286129544145,3.674975253680245,4.728421517934744 +183,260.0769741828374,156.73605149236164,3.2485067302773727,4.2314614221050855 +184,260.3205919730126,156.89282130924727,3.016527309499428,4.22117756304117 +185,302.8007745851293,155.22452212795463,2.1986861092464727,4.536996509806027 +186,301.70658980492703,155.39202732491273,3.616906361622583,5.809560313914322 +187,301.9655960101498,155.27173302476598,3.5367891506442364,5.787704448891815 +188,307.3464400351471,155.7530563647103,1.0636861640988715,3.4615533986219376 +189,385.16837677047874,156.43907420157797,3.813439832275512,4.1547295279172625 +190,383.77693943350675,155.96991177533516,4.219569642219233,3.833536791723274 +191,384.2249550976313,157.41263864645526,4.594412135572423,2.424078159567562 +192,385.2223566829572,156.31521854739066,3.877568024165435,4.253414111013303 +2 +59,94.17681256320567,218.7493975260511,0.6672950811803234,4.0696236612012 +60,95.60291842116452,220.23420259378253,1.2432894303505535,6.268557799628915 +61,95.02957510532019,220.4523644522619,1.03897231445469,6.283961945108087 +62,177.79543145664374,219.57549575966527,1.1635891534947462,2.4336404189113736 +63,179.18294098400213,220.75147009194285,0.9073027108364632,4.022599904522527 +64,178.6879893390563,223.61664229341952,1.4338252285037825,4.345355288391667 +65,263.02108805781836,206.8238570753259,5.5378567029179875,16.167997116958563 +66,265.3281568315068,210.99878283626376,5.500522890838178,6.34492497544118 +67,264.9755279946045,209.25693017899349,6.61860699217799,5.010726338500632 +73,274.91234547074936,204.52721235111983,7.271387658815161,7.492660955010252 +74,273.0873606007509,206.72185414526035,10.116961928861889,7.92146394391769 +75,272.91870930424335,206.4183338799366,10.032578813526321,9.289382922896465 +77,352.6038013638071,203.61911600747297,7.436756719086957,5.005556173534007 +78,353.00800784867783,202.31796836001985,7.664430224814655,5.213297761872742 +79,351.746134852955,203.05786731461058,8.028743708479537,6.197058831659775 +80,311.08741311854095,205.08798593428077,7.289167841693958,7.075120130726391 +81,310.4676353064527,202.3951467032501,8.630027200417027,6.3233804917837135 +82,311.07935156741206,200.8328753632899,8.282608636183143,5.648212100237218 +83,311.4698975682484,201.29198895046432,8.073700564520845,3.988913299124529 +84,131.85526420446874,252.0193765605421,4.710522724823439,6.327903412535792 +85,130.09901692321196,252.49815518747823,4.810325247545613,4.925112427111756 +86,128.98108803670195,254.22164770572394,5.286838664341266,5.5052487948351745 +87,129.58841891167637,253.33496272524005,5.004724826446331,5.207955764055635 +88,174.3431769252481,257.67973667788516,5.936812237283513,5.016793813986966 +89,173.08617175672723,252.22705318297471,6.9528446346151735,2.9206960921180114 +90,173.16612346262423,251.83252079351362,6.7445812273675925,3.0963895698154125 +91,175.31435856398238,256.47051595889315,5.036171505418926,4.369569543933027 +92,214.0019796882893,255.64524660837301,6.840266287108221,3.3162161792801035 +93,213.6417614987187,254.76260041862824,6.181548205388113,3.4669409389809114 +94,212.59841286272757,256.77538398368796,6.642291270826204,2.865009376798548 +95,214.6340156872122,257.02599392382655,14.761579728638067,2.9573164604380775 +96,257.12202196483105,254.71576094200717,6.982679389033818,2.9625204035270136 +97,257.3916794657995,254.02867969902485,6.8307722895588965,2.3226285735907486 +98,257.2278305685032,254.5619736557002,6.809772888664755,2.8383983340571364 +99,257.16282933783424,254.477050995793,6.931960195707054,2.6611905102158038 +100,297.5612747805052,254.68621271243086,6.616832054817872,2.682409735201763 +101,298.3394946306158,254.9149917819558,7.4103859236839025,2.0032533635948298 +102,297.7037470787607,254.32926027245796,6.697390437340011,2.6035794639192695 +103,297.9018444784966,254.79769770872946,6.481459768864603,2.9116637606731044 +104,337.7041120241776,252.2287315192184,6.785308450450591,4.100479545727181 +105,338.43934115988196,252.2496982308047,6.235731773413765,4.82066583664529 +107,337.8271824583213,250.73973826046893,6.0034125806830785,3.931922093279878 +108,337.86197274862946,250.42655028770324,6.756971947757317,4.556599933768003 +113,275.3004995531795,306.83564646386503,4.779925536315024,4.424861919299598 +114,276.88576480308285,311.35434787217997,5.549501601726021,6.526755225085992 +115,277.14029465508577,309.65039091667654,4.580940412764937,5.080639071791438 +116,277.4324777875824,310.4960617480911,4.471359740657681,4.32292480362113 +117,319.3288258962187,311.6702225501444,5.058071424215753,5.61952659445947 +118,319.8591509274496,310.989524065149,5.676606774774989,7.467429803565788 +119,318.99005649592243,312.4173775749036,5.750237766169274,5.397366324681752 +120,319.6131328938472,310.5522979637107,5.5022885295904205,7.263578897387779 +121,365.29517640566365,314.6454813265486,8.460762409909734,4.6709015542721914 +122,361.82211363523294,313.68568720200915,5.985773405781822,5.263777316141343 +123,361.4480761928614,313.0382171673784,5.736550096606568,5.653009750209729 +124,362.77676743108657,312.1993102338357,5.979547887317892,5.588195075901747 +125,444.8280999329621,315.2874742212303,6.27290398703566,3.2254871043818376 +126,440.039105136866,316.4990582369399,2.717419411362314,5.5021381149114275 +127,440.1448707987162,316.91453325930746,3.591630687306421,5.692686701585921 +128,444.4735843873624,318.5837135172218,5.650865106238081,3.8098846947664695 +129,480.4945871932981,317.7789400812657,2.8473874205661946,3.2846798443123237 +130,480.34502455519726,313.1237155709503,2.8405711463483505,5.887133881466956 +131,479.79765238044547,317.8026694666446,2.5364142708665374,3.2181996809796747 +132,480.81626241860704,316.98435781490645,2.135649445640601,3.5315188723853113 +133,482.1126824365287,292.7236746644675,6.795795621748642,3.589777249851841 +134,60.57986058588791,298.3572263782008,2.0715574011265097,6.518875203291838 +135,60.26789543218528,299.7821310194954,2.4359457319030224,3.302053162843642 +136,59.50091999103519,298.34107118829087,2.338468862304903,3.0546922696738714 +137,101.38271621918946,296.483247325443,3.5173219751207268,4.497162712521202 +138,100.43332664554771,300.16356781590855,2.6915212734293545,4.145281353905138 +139,88.95536885340141,299.07746679015054,2.783698934533499,3.917152490131537 +140,100.29389089950519,299.8972675509202,2.566259282658186,4.137718806425782 +141,119.96308784890563,299.8312652747876,2.8076039128455625,3.487604969893026 +142,119.21634890704448,298.4258068241335,3.1000278549881677,4.175736792274726 +143,112.26314328941838,302.0132035682278,4.497193147167675,4.627836503294436 +144,118.63154926153814,299.5090092566827,3.3112468547584886,2.82625813066952 +145,140.22829557703238,295.83589398019353,4.880610377957939,2.876734137897074 +146,143.96502880541922,295.45158153676647,4.250115873207735,3.0733240603225105 +147,140.66008917985863,295.75005128745903,4.893542903008491,3.138028915535486 +148,141.21893535376495,296.1533805219746,3.774408848238054,3.0467012666428333 +149,183.47872058961224,299.0180109809012,3.257615072049357,4.1723220562822725 +150,183.1202811035564,298.79425325159076,3.469002943022174,3.997120410978376 +151,183.2016789609457,298.4838438451825,3.1679502308294953,4.084970750698522 +152,183.56716590770395,298.3764936397965,3.3471833496481467,4.077681465171855 +153,190.41048704769,330.4978785855013,2.083041500838133,3.4668015126104454 +154,188.96675676778156,329.9036439013521,1.9931882571475936,3.508215161643373 +155,188.33490314035438,329.81417912235116,1.8728073653310773,3.0484929469157747 +156,188.31414516895805,330.23186734474723,1.8830058285338804,3.3131134887294613 +157,231.30258441852257,329.2869590111576,2.1015883812262706,2.7686520980654414 +158,635.9719402081547,323.45669801247647,3.890586665705017,3.4262788642164947 +159,231.58692741290457,329.78511421313885,2.073756648357063,3.6457128678010338 +160,251.94245026669623,329.3621392921355,3.4400207042718804,2.525297437969197 +161,275.38274900691636,330.6582764942376,2.7758194307457162,2.781269710685483 +162,288.16094061378243,329.96864420502334,1.7425792225683983,2.7891999383989616 +163,273.9343912983064,330.28517683915425,1.88697235808454,2.153903027764216 +164,277.40318080027276,331.32724722075693,2.51910988134524,2.2364789702215044 +165,294.8273106877241,330.7078842677868,2.0202421142551663,2.645341711239525 +166,317.03626643514605,330.57896380392424,1.9865816645763301,2.776754699862097 +167,314.93276908458336,330.67614347282944,2.6509184944650532,2.7861880759516926 +168,299.640483801822,330.68496013319924,2.1034251306897223,2.6995826605586095 +169,397.31504374955824,332.3446123671715,4.011960577043935,2.119261063102862 +170,396.5580357804531,331.5612694467712,2.1013176840578547,4.345997085530413 +171,397.49205012933754,332.4442253933989,4.083617010295474,2.083000027123604 +172,396.4373476151805,332.4498304809778,3.6443064475289324,1.9520773323350806 +173,172.71708638362486,155.60703919548823,3.073597315308788,4.401620808681049 +174,174.69066860790247,155.66811371703272,3.3201919365119563,4.524189384907778 +175,174.36012639095586,155.21688748228445,3.313966666920818,4.280738433967948 +176,174.27542002212184,155.33243945954135,3.4684361769046457,4.3256192119148285 +177,211.35953547851577,157.84363965463723,3.719577632132569,4.52395842333967 +178,215.49817946473246,157.8061035073585,3.420835243071113,5.204301731036066 +179,211.58080964064885,157.9196266744007,3.750774395208928,4.781345943827068 +180,212.21010780634873,157.82655078622685,3.0477176203472505,5.171003834767582 +181,261.951692200774,158.03145626439886,3.3820588588480125,4.517024497962329 +182,258.53106462200054,156.41654274449266,3.610545283020404,4.607365869710835 +183,261.9931127261629,156.844374467896,3.3582923289081412,4.203836335498702 +184,261.97037263466234,158.27263012263947,3.4440759214867183,3.5700855150119994 +185,303.2394620820782,156.27343358354165,3.4728086741188746,3.133134636490943 +186,281.81947814044815,157.07330827651708,2.3587900891205402,7.458771102609963 +187,296.79672730554864,156.66963976209618,2.4956604990337636,7.422350136504288 +188,300.202613978401,156.83041886564462,3.6244136435867715,2.652614592092425 +189,383.13489230058434,158.29028886500078,3.9437889097096543,4.109817373692409 +190,385.65899984883004,157.07389261777607,3.7243534642349445,3.3291912053378807 +191,385.5178115620514,157.22774057918932,3.5586432492433517,3.220168950341415 +192,383.2113575049479,157.78585537067738,3.864821842971764,4.094143758353614 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std_1.2.csv b/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std_1.2.csv new file mode 100644 index 0000000..5f851e0 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/convergence_naive_std_1.2.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical, +0,,,,, +59,93.31359188,216.1040838,0.618237701,2.897325933, +60,94.25152003,211.5127273,0.358870938,3.374833177, +61,94.64301786,213.3034423,0.841278395,3.062799586, +62,178.7915698,221.842599,0.620940525,2.727375108, +63,178.7793615,222.1382787,0.946339151,2.65755042, +64,178.9998276,224.6227623,0.61583784,4.559621449, +65,267.3253475,202.0759585,1.85039789,13.78987315, +66,267.6140114,206.8004802,1.867849351,1.710489483, +67,264.4386823,205.8818785,3.840233588,1.91476041, +73,274.5584796,203.6589219,4.505342013,7.217491136, +74,277.6065739,204.8403967,2.53813086,7.562467947, +75,273.475128,204.5665369,6.401795049,8.18811108, +77,350.1228767,205.4123371,5.43844845,2.525576348, +78,350.6271681,203.2043449,6.076846255,2.128968071, +79,353.5340449,203.7901342,5.894050026,2.029409224, +80,314.0476596,202.7447844,4.208062302,4.422405408, +81,303.4655309,200.20082,5.864841166,3.753278554, +82,309.7350728,199.2472142,6.146777379,3.229374023, +83,309.8136405,199.2700541,6.473807505,2.771201556, +84,131.8274832,250.45136,3.454262443,4.292952578, +85,130.5911362,251.9466741,5.088611576,3.864515618, +86,128.8594455,249.1550605,5.279052334,1.307516431, +87,129.6418099,249.7265599,5.674102334,2.163786429, +88,173.670631,256.7522595,5.866553313,5.378715369, +89,172.1209707,251.555845,6.337603661,2.552356252, +90,171.7976064,248.0992246,6.534417234,2.007986084, +91,175.4092531,250.5219813,4.288839034,0.449640845, +92,212.7821633,254.033097,4.812117576,1.782691476, +93,207.3837324,254.5046734,0.604104252,3.278464481, +94,205.878535,255.4463699,1.55981283,2.705140417, +95,215.1501942,255.6424315,6.824346381,1.148906305, +96,255.9885149,253.6259804,6.494243171,2.421806172, +97,255.9826219,253.3646297,6.468647931,2.314616274, +98,256.1173538,253.322848,6.512173805,2.525898973, +99,256.2712916,253.7108958,6.57082344,2.465309527, +100,298.0833418,255.112182,6.687485235,2.531228209, +101,298.2465484,254.6691023,6.972265463,2.244339125, +102,298.0574205,254.6292176,6.694673144,2.290234567, +103,298.2353999,255.3627222,6.715087555,2.480896289, +104,338.9662203,251.6682432,4.494612613,2.181306735, +105,338.561305,252.5513452,5.899400221,2.549982168, +107,338.2423486,252.9079453,5.969934008,2.233318369, +108,338.5868489,250.286223,5.33707157,4.858284282, +113,277.5107012,307.0031736,3.046533561,4.079715047, +114,255.1425714,309.5914535,2.510342558,4.047091188, +115,163.3300795,311.0088971,1.739802853,2.119176746, +116,280.0267197,310.1878877,3.540974806,3.241557011, +117,309.0100015,310.4995789,2.279200941,3.89632061, +118,308.5100407,310.6270883,2.394103014,3.880968022, +119,308.7154325,310.6634883,2.330905714,3.520600361, +120,308.2952932,310.4657549,2.470183202,3.733393577, +121,343.0092421,313.7186642,2.116047292,4.058166847, +122,349.1493542,314.0310377,2.329671674,2.776838945, +123,349.1687586,313.2820578,2.324583878,3.911303408, +124,349.4798254,312.2673706,2.167920266,2.618473133, +125,447.2714051,317.0089575,2.288747629,2.283465886, +126,502.0743419,314.9331407,1.859257159,5.638134747, +127,442.2191901,315.5624488,2.275416429,5.721606222, +128,440.9195945,316.1320465,1.959733233,2.12793613, +129,482.4868589,317.7187731,1.760711011,2.837186752, +130,485.077771,315.7744691,1.876571793,2.865671883, +131,482.3554415,316.9661161,1.737629421,2.691241938, +132,480.7531236,316.3363629,1.885581584,2.381456819, +133,9.357026816,301.1394482,7.424860692,3.888697336, +134,60.72228834,293.4657307,2.410669491,2.816753402, +135,60.53625758,293.2506041,2.610803253,2.504754891, +136,59.62145759,298.4361014,2.409380579,3.230447055, +137,103.2748467,295.0002111,2.285610091,3.448504993, +138,108.7313646,294.0818247,1.941384263,2.600507881, +139,98.77723689,295.1770333,2.394266051,2.756924387, +140,109.8090092,293.9924853,1.789054477,2.547258237, +141,121.6681385,299.5494119,1.285859505,2.314668892, +142,117.0240124,298.3520769,3.085394371,3.004881909, +143,118.231263,298.9916067,2.3397467,3.279021573, +144,119.3795533,299.4061851,2.582789129,3.228779442, +145,145.2816959,296.1970142,2.38417805,2.058778107, +146,20.45948253,296.5421431,2.681947682,2.011036224, +147,145.2227435,296.1268899,2.395705671,2.043939485, +148,140.6543991,296.4875091,3.005656896,2.058048941, +149,176.9462544,296.4796109,2.24719876,2.122544254, +150,148.5858476,296.4403641,2.206492677,2.144769353, +151,65.25284426,296.7475332,2.121864812,2.069698061, +152,178.3156184,296.2248128,2.213752826,2.117494282, +153,181.1171007,328.9279925,1.042514147,2.315998788, +154,159.2464172,329.6605288,0.722943069,2.202447441, +155,181.1092004,329.3955388,0.942331973,2.157325361, +156,181.3698422,329.4487599,0.935400997,2.159791188, +157,231.0298311,328.6050525,1.743400369,2.014717548, +158,240.4715846,328.1027257,1.297159757,1.643873703, +159,230.7677404,328.3139315,1.058343333,2.111095523, +160,229.5831095,328.8765845,1.186522348,2.087957983, +161,274.5137789,329.787221,1.746109884,1.564619793, +162,282.1821412,329.1227352,1.655838365,1.70307133, +163,274.4928638,329.3941296,1.454030821,1.270915558, +164,273.8955019,330.3408954,1.582117708,1.359498013, +165,313.5529536,331.0516411,1.516937377,1.509223594, +166,313.3897344,330.8407781,1.689424981,2.682274969, +167,313.7752015,331.2133122,1.484833323,1.572483211, +168,313.5745346,331.0747921,1.494009096,1.508575908, +169,396.3749593,331.9599787,2.151936274,1.343475157, +170,395.4237167,331.4329569,1.38376668,3.13374328, +171,396.5362021,332.0594479,2.233402524,1.33687979, +172,396.1637403,332.0628234,2.324809169,1.357494946, +173,159.2585618,152.0587907,2.454979661,2.419010121, +174,167.764136,151.9791958,2.249078383,2.39506924, +175,174.3513505,152.8927439,3.04541391,3.046012787, +176,163.8593125,152.1163908,2.245850906,2.431233894, +177,205.7580054,155.8305562,1.827178353,3.281469065, +178,214.6691565,155.4932254,2.282992011,3.193875104, +179,181.5625169,155.9851325,1.905636989,3.261743342, +180,222.7501825,155.2467436,0.53759681,3.263462486, +181,262.2540038,157.0830956,2.25298472,4.265499609, +182,259.441742,154.8143458,2.740600452,3.54091322, +183,262.3021049,155.3844415,2.205532074,1.69929688, +184,262.2291226,157.3954305,2.293182978,2.60561097, +185,304.5189197,156.0942392,1.719384081,2.919789238, +186,303.0823173,157.2681966,1.029613582,3.819098347, +187,301.7653099,157.2055926,2.575352453,3.818184906, +188,304.453398,156.148651,1.750578234,2.570731724, +189,384.9615182,156.8279163,3.147447988,2.436219831, +190,385.142509,155.9370708,3.034486866,3.649388391, +191,386.1865606,157.1308598,3.021833082,1.681812081, +192,385.0689288,156.5647839,3.129473983,2.464805802, +1,,,,, +59,92.98020296,210.7301638,0.522791146,3.672149354, +60,94.33424541,209.6207769,0.712959043,5.350162777, +61,92.64802764,210.5177497,0.595418733,5.547156704, +62,207.5747279,229.3538544,0.572121859,7.308688367, +63,178.2643509,230.1392843,0.916307827,7.241140372, +64,178.1218968,228.6406397,0.596703167,6.59232167, +65,263.1356007,202.5171299,2.993282392,13.10837515, +66,263.5498432,207.7381358,3.121060979,1.878113055, +67,263.39403,208.059889,3.084362941,2.375246951, +73,271.8260844,202.3394456,4.989389367,8.076149884, +74,271.8410755,202.8123375,5.31885568,8.053726527, +75,271.4096589,203.2728694,5.377230076,7.871267788, +77,349.9253798,206.1879045,4.582862379,3.702027552, +78,350.3296416,205.0583594,4.842890663,1.299663431, +79,350.0649697,202.2775243,5.79411775,1.942694674, +80,309.6366463,202.5052936,5.826833998,3.849897421, +81,304.2156432,197.8316841,5.835220622,4.295831468, +82,309.9442683,195.4976857,4.627150851,6.342731115, +83,309.7147295,197.0265133,5.058831189,5.889513251, +84,130.7344064,251.8116871,6.430453555,5.341680351, +85,129.1112752,251.1902156,6.008621382,4.323092999, +86,127.9831913,250.8210973,4.738368491,2.572218628, +87,130.1965719,252.2844149,7.110134504,5.09323269, +88,170.3002318,255.161434,5.690121369,4.700436401, +89,171.2585947,250.0133249,5.680641798,3.776527602, +90,172.1235758,251.6800326,6.2294994,4.20315816, +91,173.3400802,254.5386511,5.543590958,3.91363343, +92,213.2603045,252.3008681,2.335677624,2.872250524, +93,215.0902707,254.1583026,4.339354721,4.369371457, +94,211.9678785,254.1058558,4.275784379,4.46023842, +95,214.8368785,253.4169863,5.506727817,1.911466032, +96,256.517454,252.3881478,5.815407196,2.550431856, +97,255.6478728,251.9252364,6.11987315,2.152700053, +98,256.1374083,252.0516904,5.782654633,2.667395102, +99,257.7228752,252.1299079,5.335083237,2.128049929, +100,297.8311949,253.9653172,5.924725405,3.167204464, +101,297.5128414,253.9978911,5.638642622,2.746686532, +102,297.4725186,253.0521962,5.860286143,2.352795437, +103,297.3362522,254.4734242,5.715730646,2.516042898, +104,337.4351662,252.5457049,4.125562667,3.313965227, +105,337.8624427,251.5183513,4.989598867,3.12923061, +107,338.2193223,252.1032549,5.515561111,2.99820905, +108,336.3124802,250.2062703,4.716755758,6.491905854, +113,273.4054239,309.0245598,2.007529628,4.545176202, +114,275.7006,308.5897281,3.903782811,4.201910704, +115,275.6098701,308.5642409,4.631427944,3.639510738, +116,277.3921761,308.2813594,3.80169276,3.534953726, +117,293.8297693,310.7195738,1.521629374,4.613201387, +118,291.7659335,310.0988882,1.468614673,3.891663176, +119,309.4115342,310.3821357,1.182104119,4.505358982, +120,292.5515413,310.0542368,1.424775019,4.061589902, +121,347.8690582,312.263906,2.086860469,4.058200539, +122,359.5565312,310.5047441,2.330047253,3.638307358, +123,359.6470891,310.5270923,2.359429636,4.285573798, +124,361.5717357,311.4896921,2.501565545,3.082805746, +125,445.1246388,317.8559644,2.770881273,3.991135312, +126,416.7634163,315.3075299,1.770909628,5.747036063, +127,446.3346171,315.0196018,2.263014967,5.752920657, +128,442.282108,318.1603279,3.090257217,3.581681297, +129,478.5480048,315.9810021,1.765570954,2.41855109, +130,479.1318974,315.5731843,1.398148504,2.403118465, +131,478.6645006,316.3894294,1.795372838,2.422278886, +132,485.0663804,314.7146343,2.330786814,3.08044557, +133,87.59543272,294.7524772,7.59874341,3.091737517, +134,57.18983221,299.3908146,2.514015918,4.165559587, +135,57.04702337,296.9718239,2.857620858,3.649136041, +136,46.33616939,298.2861068,2.691730212,4.096440805, +137,100.69449,290.5774527,1.724170339,3.065422071, +138,159.3624208,292.72289,2.784165242,2.962548105, +139,353.4092013,292.0076334,3.014363498,2.92804335, +140,89.97636901,292.9113393,2.654947202,2.871927676, +141,122.0853563,297.6938028,0.685452566,3.352456383, +142,132.1553664,297.2171229,2.706901699,2.956878084, +143,127.1646194,298.2335745,2.769134247,4.011140387, +144,130.8707996,297.8983473,2.818953624,3.899711628, +145,150.2748279,296.4426353,2.72517508,3.718234377, +146,148.9487989,296.2260643,2.706792749,3.704570535, +147,150.1580396,295.8625463,2.810800537,2.960921611, +148,152.5470386,296.7976312,2.875415992,3.731793392, +149,178.2623154,295.1070469,1.566658642,2.765605075, +150,180.9716772,294.9012941,1.684242753,3.139648254, +151,182.3315967,293.1571828,1.88832792,2.268070032, +152,181.137088,293.5579351,1.671971687,2.330347328, +153,185.9711466,327.425234,1.691859372,2.387374111, +154,185.6800748,328.060633,2.609970862,1.94621952, +155,185.8166898,327.7405073,1.727258135,1.871705694, +156,186.4702702,327.2910587,1.608306647,1.866211656, +157,232.0471896,327.1305533,1.526798514,2.151252107, +158,229.4438949,328.3898306,1.156559873,2.225493584, +159,231.0122446,328.2692359,1.210844403,2.221420963, +160,244.7640449,328.8696047,1.374765582,1.935943501, +161,272.0799492,329.052411,1.166202217,1.28745393, +162,752.5860223,325.8625051,2.107359839,1.609035927, +163,272.5343254,328.9438388,1.464422622,2.480037038, +164,283.0401036,328.6492917,1.198989734,1.977731191, +165,314.9483725,330.5771118,0.672009898,1.622968038, +166,313.958339,330.6951411,1.098557555,3.125795977, +167,312.3748044,330.5081672,1.235648115,0.963304922, +168,312.8132723,330.7618727,1.348540765,1.93311836, +169,395.1307954,331.5074481,1.448023063,1.892084895, +170,378.9013814,331.4082092,1.792713799,3.432678443, +171,395.3009462,331.5620671,1.453176361,1.84090791, +172,396.6957515,331.684604,1.422416718,2.181389097, +173,172.4328077,153.1365897,3.00979225,3.273591347, +174,174.8689464,151.9590035,1.271482898,3.354743027, +175,173.7469032,152.0170272,2.992197181,3.587820476, +176,175.0489368,152.9142709,1.273711372,3.067651219, +177,220.2914705,153.9301722,2.661722075,5.161796303, +178,218.8061959,153.873329,2.751169022,5.214692401, +179,220.2111266,153.8301993,2.528867915,5.135768244, +180,221.0904806,153.6681136,1.36428459,5.195182563, +181,260.2185867,156.1774186,3.167143162,4.210885006, +182,276.9192779,155.752447,2.098877657,3.126639131, +183,260.0002443,154.9000065,3.142718258,2.746624899, +184,260.1158035,154.8963762,3.210429251,2.62793041, +185,298.167749,156.5262689,2.118650858,2.472370547, +186,303.7104855,155.0312339,2.739066062,3.598984306, +187,302.2662231,155.0201999,2.993547761,3.828128242, +188,168.6937164,157.3888805,0.989603153,4.043452094, +189,380.4478403,157.1834126,2.567599568,2.068498326, +190,385.0896758,157.6459315,3.558659095,2.667151842, +191,385.9717948,157.3015558,2.616974703,1.908230272, +192,379.9755719,157.0348278,2.624845194,2.4242362, +2,,,,, +59,92.80774775,223.3561377,0.63373947,3.204356685, +60,94.82990414,219.9054093,0.789060896,6.846135813, +61,90.4092595,220.1551552,0.922257111,6.838018548, +62,177.10956,218.9010373,1.390525166,2.749732073, +63,177.7445626,220.0664962,1.218558792,4.188825256, +64,177.3811761,221.4094598,1.295990619,3.612508185, +65,265.6878096,206.6551328,5.335870158,16.66971332, +66,273.1624412,205.5267621,2.216267652,3.574602068, +67,266.4284457,207.3593812,7.16312328,4.472335501, +73,280.9659797,202.1605676,1.654626712,5.681306637, +74,280.0193239,205.0374117,2.330531985,6.377333876, +75,280.9384725,204.351971,1.646830184,7.965623143, +77,354.887108,203.2393539,7.442012113,3.928986671, +78,355.1071844,201.8006435,7.656540481,5.190365035, +79,354.3451992,201.3442388,7.686501926,5.138973819, +80,289.243447,204.0055532,4.58144207,5.795627738, +81,302.5452164,202.0428129,8.253331974,4.651552993, +82,308.7167046,199.8020174,7.194696682,4.047995764, +83,308.8793972,199.482231,6.945358429,2.872448428, +84,131.9672656,247.4466899,3.076812196,3.459870992, +85,129.8883587,249.5830759,4.540042819,3.450294622, +86,128.1149268,253.652363,5.978168979,4.352921914, +87,128.537252,252.6585171,5.339963888,4.941548474, +88,174.7763496,255.8013916,5.728268852,3.498998329, +89,172.4531156,250.0851165,6.313071019,1.962531993, +90,171.3409715,247.6560238,6.581855503,1.831029569, +91,174.6659473,249.1824453,4.505611672,0.990903523, +92,212.1155467,257.1963349,6.711658598,2.240845082, +93,214.992281,253.3937445,4.95745259,3.977160866, +94,204.873601,255.8708178,2.120263764,3.169453436, +95,215.0833848,256.1212831,8.467407782,1.94734564, +96,255.92502,254.9921917,6.763112158,2.141438665, +97,256.1940783,254.3374307,6.713514562,2.121641996, +98,256.0021708,254.8322904,6.607905276,2.023401889, +99,256.0562427,254.8473944,6.760889792,2.566059289, +100,297.8613113,254.3084187,6.299358006,1.871267236, +101,297.5090684,254.1732975,7.403403204,1.825741321, +102,297.570531,254.484813,6.393439895,1.946205259, +103,298.2356864,254.3132468,6.191791543,2.014387656, +104,339.4930838,252.0286054,5.942208628,3.19529963, +105,339.8235924,252.7216561,5.056927498,3.013043648, +107,337.8947682,251.0496843,5.760272081,2.151022333, +108,339.5429906,250.0031284,5.812146409,5.287653171, +113,278.5304079,306.5030719,4.761955088,2.589866432, +114,276.3287806,311.8059975,5.162726712,5.347412476, +115,279.5195273,309.7197114,3.678439981,3.528386683, +116,277.8341863,310.7569919,3.685601883,4.736286987, +117,304.2455249,309.6986513,3.002773122,4.55528393, +118,302.5910518,310.8630341,3.1636375,4.959892925, +119,296.4299281,310.9683457,3.025514328,4.684284176, +120,303.1474392,308.7545195,3.172637676,6.51899129, +121,365.2154226,314.6041009,4.98222295,5.649531231, +122,341.3097453,313.954716,4.082311959,2.23304854, +123,341.7161701,313.5306694,3.968339357,2.174027249, +124,345.5257173,313.0220584,3.990163672,3.578776944, +125,469.1330131,315.0513307,4.437377537,2.47725153, +126,438.8511288,316.3709557,1.799887035,6.635379091, +127,437.9643787,316.8297365,2.404378501,6.796381593, +128,456.5949916,316.0343792,3.316370103,3.022194886, +129,478.3667044,317.5900476,1.477074747,2.534323472, +130,478.6797334,315.61719,1.885919089,3.697683958, +131,484.2348696,317.9951215,0.962093158,3.007330919, +132,484.1170489,316.4021371,2.002291195,2.919700186, +133,85.29652369,299.926705,7.827458514,3.937423663, +134,59.67047635,298.4471118,2.293779231,4.907606339, +135,55.46090118,296.1797692,2.475399962,2.485135918, +136,52.88374765,297.6242074,2.052251164,3.035605218, +137,102.2355224,295.6763876,1.22628138,4.920419862, +138,107.0183407,296.2388908,2.187701543,2.202721291, +139,108.9649908,296.1444929,2.302412374,2.209906061, +140,106.7279343,296.3701875,2.251034343,2.356004223, +141,120.9447868,299.1646936,2.931034996,1.870227654, +142,118.1973619,298.0334936,4.076098187,2.634668296, +143,117.626087,297.8252302,2.900494158,3.224708556, +144,119.861526,298.3571524,3.49398133,2.953550317, +145,145.9000645,294.3312061,3.803172414,2.403143838, +146,145.4214846,294.4868154,3.267697342,1.825315104, +147,145.7428138,294.1450033,3.987455312,2.437598704, +148,143.0284346,294.5618795,3.649189497,2.401468767, +149,185.8282608,298.0425231,1.272428277,3.643826725, +150,185.9498776,297.7664853,1.248367103,3.441098707, +151,185.6174834,297.1887106,1.024053665,3.507686463, +152,185.7795824,297.0711508,1.20747523,3.5087149, +153,194.1877708,330.071149,1.176771328,2.255752122, +154,189.2603762,329.3370618,1.370351835,2.119976972, +155,183.5303914,329.4293977,1.576418861,2.023661479, +156,183.3754904,329.9333334,1.585241848,2.049146037, +157,232.8780299,328.5197502,1.546698079,2.435561977, +158,255.3837334,327.39891,4.012448382,2.890275591, +159,205.5013925,329.9023819,1.958210827,3.923308113, +160,216.4453637,329.1893338,2.373852392,2.222571188, +161,277.1390123,330.8696438,2.264039169,2.174324696, +162,273.7246411,328.1831137,1.667751192,0.989783278, +163,322.3699595,329.7367532,1.852350787,1.37665533, +164,197.2500263,331.7884197,1.707784311,1.962322643, +165,301.3391123,330.7070529,2.05808286,1.699031874, +166,318.9940458,330.5262295,2.512905677,3.004133231, +167,285.6755255,330.6208442,2.005104058,1.510838797, +168,303.3766759,330.6890426,2.123836632,1.561502074, +169,399.4469649,332.5112476,3.236447147,1.345904021, +170,399.4479821,332.1869344,1.78598569,2.110197381, +171,399.5666501,332.7032035,3.319483494,1.271894754, +172,403.9857431,332.7091106,2.841535249,1.352866247, +173,272.0791472,152.2310031,3.137638063,3.319842322, +174,171.1803293,154.0741983,3.043033059,3.147961415, +175,172.5368551,153.5142165,4.048705698,2.906116814, +176,173.5537003,153.7359113,3.18246475,3.208562905, +177,220.452141,156.7383818,2.725644558,3.229124685, +178,219.9369118,157.0167193,2.929832633,4.337287441, +179,220.2700191,156.7580906,2.801366932,3.436425987, +180,220.212808,156.9960205,2.771416096,3.551997, +181,260.8297065,157.7245607,2.864867836,4.836641376, +182,299.4671643,156.5779657,3.042758034,4.175090355, +183,260.8703321,155.9495176,2.856985202,3.724198165, +184,261.1959859,157.7695767,2.671200412,2.608809478, +185,303.7898051,155.2967427,1.996466596,2.949035097, +186,312.0293319,157.0403841,2.517021055,4.306578124, +187,335.3153106,156.695305,2.879498971,4.237238691, +188,304.3482421,155.9405605,3.14362489,2.311963161, +189,386.0460662,157.1564715,3.503153843,3.344989582, +190,383.2598233,156.2541372,2.931096625,3.788089778, +191,385.0925047,156.6704184,2.621070632,3.280658801, +192,386.2252536,156.4378146,3.373862306,3.19857897, \ No newline at end of file diff --git a/Nov_27/Full/Camera/img_rec_module/meas/convergence_prime.csv b/Nov_27/Full/Camera/img_rec_module/meas/convergence_prime.csv new file mode 100644 index 0000000..54b1f8f --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/convergence_prime.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392,0.9677151865944192,4.009449743264753 +60,95.68692886974831,217.86446645631813,0.7424975144337135,5.151973582834018 +61,95.27930768267886,218.4321212539979,0.7270480243366128,5.212134543408362 +62,179.76038347611592,223.31234892921998,1.1147842657503555,4.609101395283265 +63,180.6656249576765,223.71898099246778,0.83092419657981,4.560940210510493 +64,179.89926897794987,225.49954804120625,1.1381174020649096,5.315085189344285 +65,267.2846565814505,205.23349976223787,2.3312417949986513,12.645312337636021 +66,267.49589526309217,209.85177109164337,2.394374307275872,4.5107503315754 +67,266.1835519250078,208.6210325552379,3.540061676733699,4.360052044157361 +73,274.3400431870006,204.75610310411912,6.491531432619202,7.31888797087335 +74,273.48666750879767,206.22331690671257,8.261574847627143,6.971589386730805 +75,273.15099171429256,205.61817173382607,8.395328002698498,7.565385107130859 +77,353.2863004930388,205.14959199780805,5.493098240735283,4.2828384868245655 +78,353.9238420531685,204.12742442066988,6.087365194189325,3.791338436749506 +79,352.21840596322596,204.15679894425952,6.557195072515586,3.1954900594475086 +80,312.16235018388227,202.94043465851004,5.386818198872637,9.493830520912068 +81,313.14659922988295,201.99717866560937,6.025875449926955,4.661460417025812 +82,312.11840038067925,201.00669797880116,7.0864910249072635,4.406813194332426 +83,312.29317276741347,200.45780062295867,7.089188755441932,3.1660046223221405 +84,132.42237239805132,254.29214663519284,4.3067464843901515,6.417058493680035 +85,131.29521858798734,255.4865958538821,4.908850345384105,6.3671100735668835 +86,136.03545039679358,255.0814813071878,8.584433337345413,4.807018608010044 +87,130.98094102950247,254.42187606024922,5.117211446405824,5.370134929913309 +88,174.55795757665564,254.28580927665664,4.7275771979909464,2.9159640887010574 +89,173.67935580024877,254.09783447631526,6.437695363099053,3.474606588647915 +90,173.43573264703227,253.47071779954354,6.593885801251147,3.4291368786010663 +91,182.2241727196623,255.67658212128163,9.720017436299852,2.9496717195778195 +92,215.12055072666627,254.67325551865426,6.334123387607411,3.0867909122735444 +93,216.94462220467622,255.47756358425315,8.080773269328214,2.7211585139427834 +94,217.3834915918711,256.4745644877478,8.267318853585852,2.211181525286066 +95,221.02053888484144,254.6506021697632,9.359150594815015,2.1628014762683434 +96,257.50957542067664,254.1259284055811,6.675780060232609,2.704136241957288 +97,257.570545197815,253.88751117668164,6.647657278502652,2.9140751377307628 +98,257.6089813372307,253.78662089019835,6.605179609252467,2.6809454420956143 +99,257.6936671647974,254.2498517060511,6.576722939133856,2.7069332019005827 +100,298.2952436151055,254.76909617478606,6.705809824561147,2.981349985017069 +101,298.1169393001307,255.21794911950758,6.624534032640799,2.181605220236403 +102,298.3189654536773,255.25096983760508,6.750900350115645,2.3083727544087247 +103,298.4415890038736,254.35763625124292,6.663590033871669,3.2667839890941295 +104,337.61901332805763,250.6788168722553,6.210728685673001,4.844297880273439 +105,338.06248003559915,250.78747044533233,6.338074391942699,5.000637757727747 +107,337.90938740495653,251.25867480332388,6.288961573364599,3.8152539451454097 +108,338.18833275957206,250.67508565210196,6.186589358792703,4.10107941402743 +113,274.2817559120019,308.9374117445766,3.892956777078502,4.794749659977309 +114,275.7421347767481,310.2555996702759,4.535765938235691,4.66622650744931 +115,276.0461325201841,310.02072804280994,4.545655403672037,2.2262514157125017 +116,276.2417374542582,310.24048782871637,4.6497847767530995,2.8951312130050146 +117,319.70071456271313,311.8764440530121,4.410519998245082,4.1053878934009775 +118,319.6313092726346,312.1826263203713,4.334709687203355,3.9909339754311914 +119,319.3774988742649,309.9857812246406,4.471689460416843,7.048323199965066 +120,319.76654338764155,311.98447027104925,4.4491853585047645,3.9716440216868176 +121,360.8050494733246,312.9126753058037,4.744138263484551,3.2959591069664484 +122,360.64739266264627,312.8307783296112,4.673876604017344,4.0505350195787555 +123,360.689270210389,312.2626467099784,4.717842951294665,4.331175918113057 +124,360.8335382258014,312.5428875466125,4.7257637014968825,4.238743771700391 +125,442.06586848771724,315.54047492369574,5.1708505304868275,4.096628870255675 +126,441.42140737582423,315.78584607818385,2.592454459875001,4.6687701093869 +127,441.5300773440553,315.90717126090226,2.8050705738429227,4.687041451309435 +128,441.95769286933466,316.8407357397122,4.805859396667629,3.6325916039286454 +129,481.35090878368925,317.4272946632326,3.3586867882998677,3.2305216999009705 +130,481.4725819590857,316.6159681822135,3.546147101969164,3.2838056303462357 +131,481.2522465836884,319.49752085243165,3.263691605498864,4.032091628707869 +132,482.31846086642565,319.45748209732994,3.3334111968000197,3.4001948797889874 +133,59.55768321914789,300.29871844382603,3.8761928423107794,3.6951665481304303 +134,61.376816545951996,298.3523691730104,2.113993300917673,3.899220174332725 +135,60.796935680150746,298.09076040109204,3.3916290934001863,3.4328323193984733 +136,59.19985355062283,300.1851062687214,3.520034988226608,3.5453648546285197 +137,102.6280068014727,297.40383468175656,2.749638491064498,3.880988203100239 +138,102.40955557323258,298.7865911290351,2.7573372442370903,4.089700063188653 +139,100.57013333623348,296.8202762296189,2.9651756626973564,3.163333481381463 +140,102.67850653460079,298.5730025774653,2.656076828883503,4.008870765124035 +141,120.23221696171454,300.1898879495705,2.3495738375350714,3.7101386992401784 +142,118.10535832779757,301.85912326532906,2.662771758344228,4.434372354516663 +143,118.16700474619614,302.0417496311767,2.810926040633238,4.442752618047973 +144,118.19187121087131,302.5378510894045,2.8502302470584953,4.428574269320613 +145,143.380762851227,297.65106023170455,2.9029598644975594,2.9494319243206975 +146,142.46748228973178,297.3647432540817,3.516542953167025,2.7867411900804395 +147,143.2239805848247,297.5672414624104,2.925450223126345,2.8821527557517435 +148,140.51718892104998,297.9845023911149,3.134479693224828,3.0837592352072623 +149,182.6593569656309,298.1418468359333,2.648390300198232,3.275571713707499 +150,182.64828488417706,297.92582445480707,2.7260433370787203,3.287985243918374 +151,182.92797391602642,297.87455852433123,2.5754349127258473,3.303821768124996 +152,183.0029286817877,297.8637465373881,2.6850779296217095,3.268506780902108 +153,186.1728851830908,329.8083307385874,1.6988565395865438,3.2857803265960546 +154,186.5492243440529,329.1491955430002,1.9159248202789043,3.190026296337793 +155,186.0292302003802,329.23752125561214,1.630100824234192,3.143397778827556 +156,186.05706501583137,329.3191466220413,1.6185913035274193,3.18627620460259 +157,233.36795685970054,328.463961880729,2.643309826783174,1.9867341998292147 +158,232.82586842848798,327.60883484043825,2.477588134745834,2.5854098103097747 +159,229.71350413783279,328.3780985513343,1.4377331090494412,3.4686128953627313 +160,232.72525153041173,327.7700361791668,2.4530240891852237,2.5077492129850194 +161,273.76316751955034,329.73823826493043,2.394688280474286,1.806427127995776 +162,275.7575781134558,329.9125721193857,1.3584269354839966,2.5506427041479443 +163,273.60940070127293,330.0025820738042,2.4087695062685763,2.2557767070416954 +164,273.7244999819209,330.09757535831045,2.4201727937672897,1.7894497412511505 +165,313.3973669095876,330.59163642669836,2.5664663718925884,2.5175272820859127 +166,313.23094160288184,330.71155384663837,2.556749103943359,2.517895305394224 +167,313.2083786255443,330.77428522126553,2.440925958919023,2.523508078782979 +168,313.36106959216625,330.6523370232485,2.5105680868176643,2.5022918306323914 +169,396.3640143494862,332.05477157898144,2.544597691516881,2.2242293500191375 +170,395.617460222669,331.85554030819173,3.094183882820774,2.2794261534246627 +171,396.3911361968549,332.1303447002533,2.5527965384171347,2.1830363581679078 +172,395.89256887798285,332.16822339411516,3.601013097767017,2.1716024486759946 +173,176.02029170516317,153.71245910000232,2.3779159513262353,3.409134278667166 +174,176.10545306203875,155.20318481126037,2.4825478178566596,4.418906030455666 +175,176.03197440143745,154.95241321278883,2.42399408636437,4.430327097224612 +176,175.6846804297304,154.63359606135103,2.5997462043064927,4.219400830122209 +177,219.46327960613064,157.23609785750858,2.529672116014354,5.058864568041901 +178,221.0564853241154,157.3435472260885,2.2463229070198545,5.480115541197549 +179,219.62129396536662,157.2666553285107,2.5021134486595593,5.352065132338259 +180,219.69587995502016,157.1490063640601,2.516169881431476,5.470652636210902 +181,263.23636033723557,157.46707082247306,2.6921936322678013,4.204926201545835 +182,261.4098116420003,157.70610911447298,3.132796451668047,4.302605485582752 +183,263.2875985178052,157.05504332147794,2.6601053814719973,4.186611997777448 +184,263.16270089611913,157.68858593709763,2.7082086799182084,3.4205893941412424 +185,304.06394490620954,155.96888190631856,2.6882263261194885,4.294769105680108 +186,303.2325028543831,156.57995759281437,2.7961523629805916,5.391517197327435 +187,303.42630311491723,156.4924674158584,2.783092188384192,5.365203962414015 +188,304.6158660912609,156.4818813819881,2.506720194343099,3.179833381166062 +189,385.42176721515784,157.40021026648142,3.5085984360932585,3.721190877059472 +190,385.8286612719259,156.9884186905783,3.520976122354819,3.199129896839037 +191,386.21040345226567,157.9321486459702,3.2937940620339354,3.184759624897468 +192,385.60316481175545,157.2028302886849,3.4609224939824603,3.763410712575745 +1 +59,93.1287423931208,218.29700908810787,0.586116217920642,4.982728971287442 +60,94.70512938803542,212.6540109552706,0.7530580888942188,5.342989457535182 +61,90.1361278577332,213.33121631876608,0.7741246171980174,5.183322455003788 +62,165.64289497225215,225.874391036669,8.768671109743122,6.55018459819764 +63,178.59192480601794,225.09457355443593,0.900267664385944,6.339222495180265 +64,178.41449448989624,226.08373120485984,1.0988445958401813,6.645297501896177 +65,260.3568485015321,203.21378596696644,6.531586140510156,12.691771056267052 +66,263.21633393064695,208.05235410434855,3.3776181785676784,3.91127933981223 +67,263.60509933731674,207.1941441096728,3.5771988890480593,4.045622146226897 +73,272.29022155441146,203.26015396542505,7.667403148427107,8.484726496612334 +74,271.44632269355435,203.63647815827935,7.006836949843662,8.247800147818172 +75,271.0412882240347,203.67673019265595,6.9166949430129225,8.702335904677817 +77,350.55117323928704,205.53824540412742,6.3913113962364445,4.535767728612248 +78,351.5831370996324,204.56554912486993,6.914935781146339,4.208591544669765 +79,350.54080463471854,202.80860415043412,7.576153280744988,2.405442522969295 +80,310.6203346770107,198.9727284928463,7.295908168915119,8.99449222675377 +81,309.4303871248667,198.8260778916456,7.8402558918165015,5.732595151892859 +82,312.8487475083582,197.88498609405823,5.545843437300968,5.5454679231566235 +83,312.4494378330193,198.02482356912975,6.100953297862154,5.205602033075617 +84,129.73316120742015,252.31402870350382,5.182904459352007,5.7859701617993196 +85,130.09936826716955,255.07600217340146,5.535923397107699,7.036159941672144 +86,135.81702697516587,252.10204054872278,10.027649034484337,4.399918094601206 +87,129.96018632025633,253.63904238622214,5.660756401038712,5.8266843261131385 +88,179.7261278913035,255.3456126662452,10.57223062780983,5.845563121104949 +89,173.42291095269067,255.58833819764322,6.700532645820975,6.247923198559783 +90,173.10761109611573,253.5025139362306,6.760737603124655,5.536745737424702 +91,174.12745797775463,253.2601960722921,4.897753124735466,2.522716607958386 +92,216.78511969207446,254.5914187233686,8.95047307481889,4.249360054724529 +93,215.97344562124545,254.7054640425066,8.196439917611718,4.011111129846635 +94,219.24024367384476,255.41662872012847,10.121690584983755,3.367632134220822 +95,213.91037600886813,255.01236900202147,6.258734602959029,3.284512606242694 +96,257.3830982530756,252.6691612485834,6.880768996147865,2.9353265504494703 +97,256.07878148245777,252.5850508469038,7.193370431289156,3.536434124406424 +98,256.6563709830754,252.14302077100646,7.020255474285572,2.742516414019443 +99,257.10274737541874,252.44669038983187,6.759367673913806,2.5065554147623534 +100,297.3527413648711,254.3197859755712,6.974691942771777,4.204342914024384 +101,297.36935919598676,254.31625883281748,7.003782434070834,3.8132099844257588 +102,297.45043676182286,253.29006124829388,7.147301062318091,3.0312100621116413 +103,297.15639353267426,254.26565823155238,7.3776805534006185,3.914660604118064 +104,337.0467224043386,249.84436792649663,5.921815081770851,5.271202014540857 +105,338.2530319319246,250.01216730218792,5.481575455905726,5.469000206273413 +107,338.4288143610566,251.12173304980342,6.654167871317137,5.370828824572206 +108,337.6321115297869,249.87042147419172,6.005664399486008,5.04451473974955 +113,273.20050531167254,309.1760573916311,3.4219821116654865,4.957144824013617 +114,275.593658985165,308.5727448984995,4.702522493967433,4.008413607725532 +115,276.45985797306344,307.75120186662025,5.767076285351399,2.479883936569082 +116,276.6589541465393,307.7328403118153,6.184525915073467,3.409658651068851 +117,323.8680795155452,311.25555593462394,5.6467354698699,4.163445875643856 +118,323.990822160368,310.23497244583933,6.354306297639026,3.605863723170547 +119,324.32484229774974,308.2748476589923,5.951639025695133,8.081943297913417 +120,325.7385894442358,310.39579583995135,7.723927817628718,3.904269142941334 +121,361.79131456676873,312.1771387146637,4.3915079798209895,3.778217894990519 +122,360.25109899783934,312.73975566628565,3.3364555278083112,2.7719078470887877 +123,361.13964194906663,312.4482596768938,4.009973777907947,3.338550731387954 +124,360.8021695665512,312.55731463103996,5.178975914859417,3.147724551644225 +125,443.6146844651626,316.9499823437052,5.441494217460369,5.589514223334737 +126,462.74164751366203,314.6397925160877,3.1723106571758315,4.673495905701873 +127,284.4684422338389,315.96181914108945,3.781047749264403,4.799446710082581 +128,451.0537747662026,315.05034330850094,4.165022446102917,5.582872998184059 +129,486.2262311408019,318.917422588962,4.360015955842124,4.24279052637777 +130,484.203371665194,317.155262043757,4.666439360195373,3.538660983437178 +131,493.89209637934295,319.54817622659806,4.495507964960477,5.054370244042043 +132,483.79815450187516,313.87456269013853,5.0513219188547716,3.976286497193232 +133,58.415796919717515,296.3367806354237,2.745318197812863,5.347714894650585 +134,59.66992690532717,295.46552315023496,3.0521020998678443,5.04724168228645 +135,58.43814573925214,299.01257928228273,3.0314355414314353,4.680341029748839 +136,57.19875149216512,296.2038703275876,3.0187024946676813,5.430283114579736 +137,101.88869112962361,295.36699152796956,3.0605704820563435,3.976231975252619 +138,97.74223572831934,296.64159635228486,2.388879471730324,4.818867004598817 +139,95.13971714462463,297.63279866894925,2.5874115321204054,5.108323412261206 +140,100.97448449522825,296.37143206657936,2.23273639508488,4.835560641819327 +141,119.46912848294882,301.03987366288305,2.945034185014498,5.579249063467622 +142,116.04630564586442,300.9428981940468,3.646493643610884,4.201903655805421 +143,115.93833802312685,301.4015147621542,2.7752574824028806,4.899750014060764 +144,117.66427038686425,301.67621994166734,3.2562262537824718,4.934112992862415 +145,143.61862339021508,296.87569921241607,2.9793460068872264,4.493879539069787 +146,143.84226240395634,296.5995702000957,2.6657882037152505,4.487866588043545 +147,143.41726284468888,296.4604242772443,2.892883624851368,4.50539522391336 +148,139.90710854861246,297.05847391439454,3.4669655178811123,4.588153704670423 +149,177.97012292111646,297.29360417935067,2.9817918310917375,3.750304964672955 +150,179.09943783225685,297.22176671479934,3.0286986838896457,3.881572977421466 +151,178.4595029850307,297.07969710485736,2.9749987384442655,3.775627144339658 +152,178.9990807254096,297.58186299960556,3.0418692927202193,3.8833402396923353 +153,187.06432524491635,327.5110792134713,1.9103539442817077,3.1747672773580633 +154,187.40611165319353,327.24266469486685,2.028936750132528,3.039992572908433 +155,187.48202253723917,328.1910452260973,2.046736087360523,4.07325152306089 +156,187.4554203440108,326.77537509295496,2.0468424040406785,3.0346527434557236 +157,230.1275716483488,327.66375493177526,1.3064642552426002,4.735119343666496 +158,230.19455285047118,329.6573791501422,1.6872246668899367,3.583570894848579 +159,236.39481488323716,328.4457905246168,2.716174379714519,3.4183380314351863 +160,230.1984260911562,328.23405030487964,1.818805777200218,4.578868396563749 +161,272.1545894887068,329.32912181766994,2.0716370234969204,3.1939556616595848 +162,272.8983988300567,328.70387641284987,2.430197123109527,3.1487498704390036 +163,271.6162444327857,329.4696874435773,2.203277751618005,4.017476086378616 +164,271.6290916788945,328.8920615225914,2.008299706725287,3.3041284732956586 +165,313.03716740034986,330.7975522275865,3.0420523810535003,3.7108953229128367 +166,312.7612082311074,331.01658878813123,2.756286496478564,3.635011569085448 +167,312.555857804164,330.94886104868783,2.895089352246948,3.630322203243039 +168,312.99233681057194,330.7594147506374,2.9514521257261572,3.7325921124368473 +169,395.6599712440442,331.38000769767353,3.6713668117121325,3.4549858187839337 +170,395.7269407162828,332.3551932767835,3.1249445864849728,3.2139419865878307 +171,395.64772093777225,331.19728501985406,3.652929258669073,3.3877347902405988 +172,395.7526488830209,331.2745983423243,3.9055257304944306,3.4415616827579543 +173,172.19300877613125,153.8677984100333,2.9936489675181246,4.5406288069622285 +174,174.43739755929997,152.4534316026212,3.1172372976035665,3.3179648689547276 +175,174.29318678572136,152.18270882980445,3.1219958686591287,3.3048067882101986 +176,174.37774565459176,153.9168218422937,3.148891388697558,4.4895441435882795 +177,218.92125782027884,157.06267339391565,2.7063981074883805,5.4304455216655905 +178,218.85237431972325,156.51579863987993,2.6795499708167725,5.289366508551004 +179,218.17652673671887,156.67648159701702,2.747386160206801,5.224977213644244 +180,219.63668315938992,156.54252374150602,2.654919821631967,5.2993336248236345 +181,260.39420520785944,156.89107932316213,3.256704661733587,4.125191869561575 +182,260.7451262620054,156.26061389330727,3.674975253680245,4.673081143856457 +183,260.0769741828374,156.73605149236164,3.2485067302773727,4.2314614221050855 +184,260.3205919730126,156.89282130924727,3.016527309499428,4.22117756304117 +185,302.8007745851293,155.22452212795463,2.1986861092464727,4.536996509806027 +186,301.70658980492703,155.39202732491273,3.616906361622583,5.809560313914322 +187,301.9655960101498,155.27173302476598,3.5367891506442364,5.787704448891815 +188,307.3464400351471,155.7530563647103,1.0636861640988715,3.4615533986219376 +189,385.2275499165649,158.1706520863393,3.813439832275512,3.640361036690412 +190,383.77693943350675,155.96991177533516,4.219569642219233,3.833536791723274 +191,384.1919840339305,156.6889394336518,4.594412135572423,2.0156822112075097 +192,385.249022040249,157.09793266480662,3.877568024165435,4.522637183712553 +2 +59,94.17681256320567,218.7493975260511,0.6672950811803234,4.0696236612012 +60,95.60291842116452,220.23420259378253,1.2432894303505535,6.268557799628915 +61,95.02957510532019,220.4523644522619,1.03897231445469,6.283961945108087 +62,177.88668491962127,221.41680696479915,1.1635891534947462,4.266168737180917 +63,179.2047201008017,222.0714847243557,0.9073027108364632,4.622657461501109 +64,178.76685855250403,226.32660678265475,1.4338252285037825,6.163194163231048 +65,254.59096062439968,207.56765796649344,6.468811941167413,15.484181828020908 +66,262.3514299707784,211.47058512229123,6.200035074796359,5.723850290560224 +67,265.06237168987434,210.4005448238059,6.61860699217799,5.422654412058275 +73,274.91234547074936,204.52721235111983,7.271387658815161,7.492660955010252 +74,273.2143306337384,207.55888389096398,10.116961928861889,7.899368121489383 +75,272.91870930424335,206.4183338799366,10.032578813526321,9.289382922896465 +77,352.6324668691135,204.06675998471425,7.436756719086957,4.8581936941677935 +78,353.05135609325134,202.98520282433685,7.664430224814655,5.142377982862242 +79,351.746134852955,203.05786731461058,8.028743708479537,6.197058831659775 +80,310.21870253063406,204.63993652062547,6.829422420637117,11.038982037055565 +81,310.5482455608953,203.3161899769199,8.630027200417027,6.825063086136599 +82,311.07935156741206,200.8328753632899,8.282608636183143,5.648212100237218 +83,311.4698975682484,201.29198895046432,8.073700564520845,3.988913299124529 +84,131.85526420446874,252.0193765605421,4.710522724823439,6.327903412535792 +85,130.09901692321196,252.49815518747823,4.810325247545613,4.925112427111756 +86,129.09877923534668,257.0902057833205,5.286838664341266,6.0960063153090545 +87,129.58841891167637,253.33496272524005,5.004724826446331,5.207955764055635 +88,174.34014870627018,257.6293741682174,5.936812237283513,4.578268483473221 +89,173.08617175672723,252.22705318297471,6.9528446346151735,2.9206960921180114 +90,173.29362621289272,254.03640143495207,6.7445812273675925,4.594746547363893 +91,183.93566207705527,256.40769459187646,11.366675081342697,4.086344657301128 +92,214.000238044348,255.61808278157844,6.840266287108221,3.162185843886936 +93,213.6417614987187,254.76260041862824,6.181548205388113,3.4669409389809114 +94,212.59841286272757,256.77538398368796,6.642291270826204,2.865009376798548 +95,219.36862273251444,256.7917930393642,15.042021453799604,2.839050343283112 +96,257.12202196483105,254.71576094200717,6.982679389033818,2.9625204035270136 +97,257.3916794657995,254.02867969902485,6.8307722895588965,2.3226285735907486 +98,257.2278305685032,254.5619736557002,6.809772888664755,2.8383983340571364 +99,257.16282933783424,254.477050995793,6.931960195707054,2.6611905102158038 +100,297.5612747805052,254.68621271243086,6.616832054817872,2.682409735201763 +101,298.3394946306158,254.9149917819558,7.4103859236839025,2.0032533635948298 +102,297.7037470787607,254.32926027245796,6.697390437340011,2.6035794639192695 +103,297.9018444784966,254.79769770872946,6.481459768864603,2.9116637606731044 +104,337.7041120241776,252.2287315192184,6.785308450450591,4.100479545727181 +105,338.5071288183876,253.47618492583723,6.235731773413765,5.665420262300457 +107,337.8271824583213,250.73973826046893,6.0034125806830785,3.931922093279878 +108,337.86197274862946,250.42655028770324,6.756971947757317,4.556599933768003 +113,275.3004995531795,306.83564646386503,4.779925536315024,4.424861919299598 +114,276.88576480308285,311.35434787217997,5.549501601726021,6.526755225085992 +115,277.14029465508577,309.65039091667654,4.580940412764937,5.080639071791438 +116,277.4324777875824,310.4960617480911,4.471359740657681,4.32292480362113 +117,319.2852262928977,311.077818303166,5.058071424215753,5.709272247895537 +118,319.8591509274496,310.989524065149,5.676606774774989,7.467429803565788 +119,319.02916641933683,312.90617379038326,5.750237766169274,5.40025366381934 +120,319.6131328938472,310.5522979637107,5.5022885295904205,7.263578897387779 +121,365.2832995228827,314.5597006669066,8.460762409909734,4.458496704270642 +122,361.82211363523294,313.68568720200915,5.985773405781822,5.263777316141343 +123,361.4480761928614,313.0382171673784,5.736550096606568,5.653009750209729 +124,362.77676743108657,312.1993102338357,5.979547887317892,5.588195075901747 +125,444.73301900096925,313.7677536345598,6.27290398703566,4.75455241049808 +126,440.039105136866,316.4990582369399,2.717419411362314,5.5021381149114275 +127,440.1448707987162,316.91453325930746,3.591630687306421,5.692686701585921 +128,444.4735843873624,318.5837135172218,5.650865106238081,3.8098846947664695 +129,480.4945871932981,317.7789400812657,2.8473874205661946,3.2846798443123237 +130,480.34502455519726,313.1237155709503,2.8405711463483505,5.887133881466956 +131,479.84017942259044,319.58019508589905,2.5364142708665374,3.470339268830257 +132,480.860280231984,318.72555273736816,2.135649445640601,3.5691704658960353 +133,482.1126824365287,292.7236746644675,6.795795621748642,3.589777249851841 +134,60.57986058588791,298.3572263782008,2.0715574011265097,6.518875203291838 +135,60.46461499266122,295.5965103880334,2.4359457319030224,3.521159186195473 +136,59.50091999103519,298.34107118829087,2.338468862304903,3.0546922696738714 +137,101.38271621918946,296.483247325443,3.5173219751207268,4.497162712521202 +138,100.43332664554771,300.16356781590855,2.6915212734293545,4.145281353905138 +139,88.95536885340141,299.07746679015054,2.783698934533499,3.917152490131537 +140,100.29389089950519,299.8972675509202,2.566259282658186,4.137718806425782 +141,119.97612156854062,299.369658232651,2.8076039128455625,3.339917039106144 +142,119.21634890704448,298.4258068241335,3.1000278549881677,4.175736792274726 +143,112.26314328941838,302.0132035682278,4.497193147167675,4.627836503294436 +144,118.63154926153814,299.5090092566827,3.3112468547584886,2.82625813066952 +145,140.22829557703238,295.83589398019353,4.880610377957939,2.876734137897074 +146,143.96502880541922,295.45158153676647,4.250115873207735,3.0733240603225105 +147,140.66008917985863,295.75005128745903,4.893542903008491,3.138028915535486 +148,141.21893535376495,296.1533805219746,3.774408848238054,3.0467012666428333 +149,183.47872058961224,299.0180109809012,3.257615072049357,4.1723220562822725 +150,183.1202811035564,298.79425325159076,3.469002943022174,3.997120410978376 +151,183.2016789609457,298.4838438451825,3.1679502308294953,4.084970750698522 +152,183.56716590770395,298.3764936397965,3.3471833496481467,4.077681465171855 +153,190.41048704769,330.4978785855013,2.083041500838133,3.4668015126104454 +154,188.96675676778156,329.9036439013521,1.9931882571475936,3.508215161643373 +155,188.33490314035438,329.81417912235116,1.8728073653310773,3.0484929469157747 +156,188.31414516895805,330.23186734474723,1.8830058285338804,3.3131134887294613 +157,231.30258441852257,329.2869590111576,2.1015883812262706,2.7686520980654414 +158,635.9719402081547,323.45669801247647,3.890586665705017,3.4262788642164947 +159,231.58692741290457,329.78511421313885,2.073756648357063,3.6457128678010338 +160,251.94245026669623,329.3621392921355,3.4400207042718804,2.525297437969197 +161,275.38274900691636,330.6582764942376,2.7758194307457162,2.781269710685483 +162,288.16094061378243,329.96864420502334,1.7425792225683983,2.7891999383989616 +163,273.9343912983064,330.28517683915425,1.88697235808454,2.153903027764216 +164,277.40318080027276,331.32724722075693,2.51910988134524,2.2364789702215044 +165,294.8273106877241,330.7078842677868,2.0202421142551663,2.645341711239525 +166,317.03626643514605,330.57896380392424,1.9865816645763301,2.776754699862097 +167,314.93276908458336,330.67614347282944,2.6509184944650532,2.7861880759516926 +168,299.640483801822,330.68496013319924,2.1034251306897223,2.6995826605586095 +169,397.31504374955824,332.3446123671715,4.011960577043935,2.119261063102862 +170,396.5580357804531,331.5612694467712,2.1013176840578547,4.345997085530413 +171,397.49205012933754,332.4442253933989,4.083617010295474,2.083000027123604 +172,396.4373476151805,332.4498304809778,3.6443064475289324,1.9520773323350806 +173,172.71708638362486,155.60703919548823,3.073597315308788,4.401620808681049 +174,174.69066860790247,155.66811371703272,3.3201919365119563,4.524189384907778 +175,174.36012639095586,155.21688748228445,3.313966666920818,4.280738433967948 +176,174.27542002212184,155.33243945954135,3.4684361769046457,4.3256192119148285 +177,211.35953547851577,157.84363965463723,3.719577632132569,4.52395842333967 +178,215.49817946473246,157.8061035073585,3.420835243071113,5.204301731036066 +179,211.58080964064885,157.9196266744007,3.750774395208928,4.781345943827068 +180,212.21010780634873,157.82655078622685,3.0477176203472505,5.171003834767582 +181,261.951692200774,158.03145626439886,3.3820588588480125,4.517024497962329 +182,258.6077504340104,157.3952123759144,3.610545283020404,5.537995823967975 +183,261.9931127261629,156.844374467896,3.3582923289081412,4.203836335498702 +184,261.97037263466234,158.27263012263947,3.4440759214867183,3.5700855150119994 +185,303.22094845720875,155.75474871290248,3.4728086741188746,4.537460217001407 +186,281.81947814044815,157.07330827651708,2.3587900891205402,7.458771102609963 +187,296.79672730554864,156.66963976209618,2.4956604990337636,7.422350136504288 +188,300.202613978401,156.83041886564462,3.6244136435867715,2.652614592092425 +189,383.13489230058434,158.29028886500078,3.9437889097096543,4.109817373692409 +190,385.65899984883004,157.07389261777607,3.7243534642349445,3.3291912053378807 +191,385.5898403232217,158.93279796052937,3.5586432492433517,4.719422333593461 +192,383.2113575049479,157.78585537067738,3.864821842971764,4.094143758353614 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 200).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 200).txt new file mode 100644 index 0000000..06ac13b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 291.03499068467625, poly: 289.2972972972973, gaussian: 289.8178178178178; +y: edge_centroid: 250.59977810650898, poly: 256.96096096096096, gaussian: 216.0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 300).txt new file mode 100644 index 0000000..c66127c --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 291.03499068467625, poly: 289.2972972972973, gaussian: 289.8408408408408; +y: edge_centroid: -1, poly: 0, gaussian: 0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(120, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(120, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(490, 50).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(490, 50).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_10_{0}/img_10_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_10_{0}/img_10_{0}_(240, 320).txt new file mode 100644 index 0000000..0aa7bd9 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_10_{0}/img_10_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 275.7147319104633, poly: 277.54654654654655, gaussian: 276.4354354354354; +y: edge_centroid: 218.90439189189192, poly: 219.87387387387386, gaussian: 219.96996996996998 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(100, 150).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(100, 150).txt new file mode 100644 index 0000000..5cc8360 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(100, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.0200477822787, poly: 474.4554554554555, gaussian: 475.0960960960961; +y: edge_centroid: 319.75075987841956, poly: 352.0, gaussian: 317.5045045045045 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(150, 200).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(150, 200).txt new file mode 100644 index 0000000..c181231 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(150, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 483.1316033979296, poly: 479.963963963964, gaussian: 472.96596596596595; +y: edge_centroid: 326.8176090597337, poly: 325.0900900900901, gaussian: 325.9259259259259 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(20, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(20, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 250).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 250).txt new file mode 100644 index 0000000..8e70bbf --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 324.4145637296835, poly: 318.4034034034034, gaussian: 328.4984984984985 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 300).txt new file mode 100644 index 0000000..0858c20 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 315.5961538461538, poly: 301.93293293293294, gaussian: 314.3693693693694 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 500).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 500).txt new file mode 100644 index 0000000..f65380f --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 307.213521344408, poly: 323.22522522522524, gaussian: 322.5015015015015 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(250, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(250, 300).txt new file mode 100644 index 0000000..41d732a --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(250, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.7974399164053, poly: 480.7717717717718, gaussian: 478.4754754754755; +y: edge_centroid: 315.5961538461538, poly: 301.93293293293294, gaussian: 314.3693693693694 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(30, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(30, 100).txt new file mode 100644 index 0000000..9a0a702 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(30, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7408469342743, poly: 474.3133133133133, gaussian: 475.96296296296293; +y: edge_centroid: 312.8755548978987, poly: 312.6666666666667, gaussian: 313.2162162162162 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 350).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 350).txt new file mode 100644 index 0000000..9fcb0bd --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 478.06332670022255, poly: 479.2022022022022, gaussian: 478.8808808808809; +y: edge_centroid: 315.1341000267452, poly: 314.23823823823824, gaussian: 347.0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 400).txt new file mode 100644 index 0000000..002895d --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 478.06332670022255, poly: 479.2022022022022, gaussian: 478.8808808808809; +y: edge_centroid: 310.42203052422025, poly: 313.1111111111111, gaussian: 312.4864864864865 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(350, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(350, 400).txt new file mode 100644 index 0000000..99ae642 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(350, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.5766195632225, poly: 479.4594594594595, gaussian: 477.3223223223223; +y: edge_centroid: 310.42203052422025, poly: 313.1111111111111, gaussian: 312.4864864864865 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(400, 450).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(400, 450).txt new file mode 100644 index 0000000..0101161 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(400, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 481.25031779661015, poly: 481.04804804804803, gaussian: 480.36036036036035; +y: edge_centroid: 320.51106920874355, poly: 322.13113113113116, gaussian: 321.7687687687688 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(450, 550).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(450, 550).txt new file mode 100644 index 0000000..f859e85 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(450, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 480.90588235294115, poly: 479.13613613613614, gaussian: 479.12312312312315; +y: edge_centroid: 316.68044077134977, poly: 313.73273273273276, gaussian: 315.5095095095095 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(50, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(50, 100).txt new file mode 100644 index 0000000..c0a15fe --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(50, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 474.3070001323277, poly: 472.996996996997, gaussian: 472.81081081081084; +y: edge_centroid: 312.8755548978987, poly: 312.6666666666667, gaussian: 313.2162162162162 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 100).txt new file mode 100644 index 0000000..f2af609 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 277.76777028087247, poly: 281.1461461461461, gaussian: 278.5765765765766; +y: edge_centroid: 302.41199200532964, poly: 296.71771771771773, gaussian: 299.7837837837838 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 50).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 50).txt new file mode 100644 index 0000000..b79b4f9 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 277.76777028087247, poly: 281.1461461461461, gaussian: 278.5765765765766; +y: edge_centroid: 266.9218650877565, poly: 284.07207207207205, gaussian: 279.6546546546547 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(300, 550).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(300, 550).txt new file mode 100644 index 0000000..84b1934 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(300, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 81.92717111682785, poly: 81.3933933933934, gaussian: 81.24724724724724; +y: edge_centroid: 289.13216374268995, poly: 286.6216216216216, gaussian: 288.1381381381381 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_134_{0}/img_134_{0}.png_(200, 150).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_134_{0}/img_134_{0}.png_(200, 150).txt new file mode 100644 index 0000000..0d980c5 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_134_{0}/img_134_{0}.png_(200, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 58.87142186766776, poly: 57.72372372372372, gaussian: 58.56256256256256; +y: edge_centroid: 298.5141452126122, poly: 298.53453453453454, gaussian: 299.05505505505505 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_13_{0}/img_13_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_13_{0}/img_13_{0}_(240, 320).txt new file mode 100644 index 0000000..f932d1e --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_13_{0}/img_13_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 52.44813278008298, poly: 53.77977977977978, gaussian: 53.35935935935936; +y: edge_centroid: 215.0489725113424, poly: 217.44444444444446, gaussian: 216.44444444444446 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_157_{0}/img_157_{0}.png_(250, 450).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_157_{0}/img_157_{0}.png_(250, 450).txt new file mode 100644 index 0000000..bc8985f --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_157_{0}/img_157_{0}.png_(250, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 231.9349172144786, poly: 229.16516516516518, gaussian: 230.4204204204204; +y: edge_centroid: 324.7964368509638, poly: 320.92092092092093, gaussian: 322.7027027027027 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(100, 500).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(100, 500).txt new file mode 100644 index 0000000..7b9d1b7 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(100, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 225.6382858488344, poly: 219.85385385385385, gaussian: 223.6846846846847; +y: edge_centroid: 326.9082845283447, poly: 329.64864864864865, gaussian: 329.45245245245246 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(300, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(300, 400).txt new file mode 100644 index 0000000..a009916 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 218.77561608300925, poly: 224.71471471471472, gaussian: 223.88388388388387; +y: edge_centroid: 325.48699770378875, poly: 323.76576576576576, gaussian: 321.72972972972974 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(350, 450).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(350, 450).txt new file mode 100644 index 0000000..7dca8cd --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(350, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 221.86800998243837, poly: 223.86086086086087, gaussian: 222.33833833833833; +y: edge_centroid: 324.95901767558263, poly: 319.3243243243243, gaussian: 320.1621621621622 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 350).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 350).txt new file mode 100644 index 0000000..deecda3 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 392.6319532908705, poly: 390.93993993993996, gaussian: 391.22222222222223; +y: edge_centroid: 332.7505637119807, poly: 333.94494494494495, gaussian: 333.13613613613614 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 450).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 450).txt new file mode 100644 index 0000000..b69498b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 392.6319532908705, poly: 390.93993993993996, gaussian: 391.22222222222223; +y: edge_centroid: 340.36645473811694, poly: 333.6066066066066, gaussian: 333.86686686686687 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(100, 150).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(100, 150).txt new file mode 100644 index 0000000..0564307 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(100, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 220.7910065139735, poly: 217.15515515515517, gaussian: 220.11711711711712; +y: edge_centroid: 160.24814595075648, poly: 158.1981981981982, gaussian: 155.2112112112112 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(150, 200).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(150, 200).txt new file mode 100644 index 0000000..1f815cd --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(150, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 226.56943727413525, poly: 233.0, gaussian: 231.61461461461462; +y: edge_centroid: -1, poly: 157.03003003003002, gaussian: 159.97997997998 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 250).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 250).txt new file mode 100644 index 0000000..7084079 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 224.38829323735553, poly: 221.4204204204204, gaussian: 222.997997997998; +y: edge_centroid: -1, poly: 136.21621621621622, gaussian: 153.43543543543544 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 50).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 50).txt new file mode 100644 index 0000000..751271c --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 224.38829323735553, poly: 221.4204204204204, gaussian: 222.997997997998; +y: edge_centroid: 159.31560235197594, poly: 147.12512512512512, gaussian: 138.0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(250, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(250, 300).txt new file mode 100644 index 0000000..e2f1dfc --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(250, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.60011869116025, poly: 215.4144144144144, gaussian: 201.0; +y: edge_centroid: 155.03382867757378, poly: 157.1791791791792, gaussian: 158.998998998999 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(300, 350).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(300, 350).txt new file mode 100644 index 0000000..238ae5c --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(300, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.2786542650262, poly: 231.36236236236238, gaussian: 224.34534534534535; +y: edge_centroid: -1, poly: 139.21621621621622, gaussian: 139.81581581581582 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(350, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(350, 400).txt new file mode 100644 index 0000000..c508eef --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(350, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 218.11615628299896, poly: 221.07207207207207, gaussian: 219.3013013013013; +y: edge_centroid: 155.50516848445383, poly: 152.59459459459458, gaussian: 152.37137137137137 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(400, 450).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(400, 450).txt new file mode 100644 index 0000000..4c33dde --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(400, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.5702052689802, poly: 220.84284284284286, gaussian: 200.0; +y: edge_centroid: 148.5988915951851, poly: 134.5095095095095, gaussian: 135.5895895895896 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(50, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(50, 100).txt new file mode 100644 index 0000000..45a7482 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(50, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 225.69889181411875, poly: 219.86186186186185, gaussian: 228.002002002002; +y: edge_centroid: 156.60606647930996, poly: 154.3803803803804, gaussian: 151.83083083083082 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_19_3/img_19_3_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_19_3/img_19_3_(240, 320).txt new file mode 100644 index 0000000..5d569df --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_19_3/img_19_3_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 354.17105263157896; +y: zero_crossing: 264.9651162790698, edge_converge: 252.34375 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 355.72727272727275, edge_converge: 353.32894736842104; +y: zero_crossing: 265.5, edge_converge: 269.3763586956522 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 355.76190476190476, edge_converge: 349.5; +y: zero_crossing: 265.5, edge_converge: 239.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 356.1034482758621, edge_converge: 371.0; +y: zero_crossing: 265.37254901960785, edge_converge: 300.0 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 346.65625; +y: zero_crossing: 265.4313725490196, edge_converge: 238.5 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 356.40625, edge_converge: 422.36538461538464; +y: zero_crossing: 265.40845070422534, edge_converge: 294.36538461538464 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 356.3095238095238, edge_converge: 256.4673913043478; +y: zero_crossing: 265.37254901960785, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 356.09375, edge_converge: 317.0; +y: zero_crossing: 265.3333333333333, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_19_{0}/img_19_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_19_{0}/img_19_{0}_(240, 320).txt new file mode 100644 index 0000000..84c72a9 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_19_{0}/img_19_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 356.46369710467707, poly: 356.40440440440443, gaussian: 356.67667667667666; +y: edge_centroid: 264.30495510475555, poly: 263.84384384384384, gaussian: 264.1141141141141 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_1_1/img_1_1_(600, 960).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_1_1/img_1_1_(600, 960).txt new file mode 100644 index 0000000..1495c39 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_1_1/img_1_1_(600, 960).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1033.5062801932368; +y: zero_crossing: -1, edge_converge: 671.6582417582417 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 285.5, edge_converge: 286.10200668896323; +y: zero_crossing: -1, edge_converge: -1 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 285.5, edge_converge: 276.20913461538464; +y: zero_crossing: -1, edge_converge: 771.828947368421 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 278.8111413043478; +y: zero_crossing: -1, edge_converge: 607.5 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 285.5, edge_converge: 284.02163461538464; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 284.5, edge_converge: 279.5; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 283.8615560640732; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 306.5; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(240, 320).txt new file mode 100644 index 0000000..d00a799 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 383.30516277540283, poly: 383.17317317317315, gaussian: 383.2852852852853; +y: edge_centroid: 129.78768233387356, poly: 129.64064064064064, gaussian: 129.4164164164164 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(600, 960).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(600, 960).txt new file mode 100644 index 0000000..1df54e1 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(600, 960).txt @@ -0,0 +1,6 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 282.80022496724126; +y: zero_crossing: -1, edge_converge: -1 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 277.11846281807; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_20_1/img_20_1_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_20_1/img_20_1_(240, 320).txt new file mode 100644 index 0000000..7f8ccc7 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_20_1/img_20_1_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 225.33333333333334, edge_converge: 222.40969899665552; +y: zero_crossing: 222.44086021505376, edge_converge: 232.5 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 224.90625, edge_converge: 212.425; +y: zero_crossing: 222.7012987012987, edge_converge: 244.8653846153846 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 224.55172413793105, edge_converge: 225.7096153846154; +y: zero_crossing: 222.8507462686567, edge_converge: 233.3653846153846 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 224.86363636363637, edge_converge: 207.6159420289855; +y: zero_crossing: 223.22413793103448, edge_converge: 215.5216346153846 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.37254901960785, edge_converge: 238.5 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: -1; +y: zero_crossing: 223.33333333333334, edge_converge: 309.4673913043478 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 220.5; +y: zero_crossing: 223.46341463414635, edge_converge: 210.0 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 224.56521739130434, edge_converge: -1; +y: zero_crossing: 223.57894736842104, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_20_1/img_20_1_(900, 1400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_20_1/img_20_1_(900, 1400).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(200, 500).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(200, 500).txt new file mode 100644 index 0000000..b5bbd3d --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(200, 500).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1178.6311475409836; +y: zero_crossing: -1, edge_converge: 376.4716202270382 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 635.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1582.0; +y: zero_crossing: -1, edge_converge: 723.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1682.4423076923076; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 72.5, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 600.4166666666666 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(400, 700).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(400, 700).txt new file mode 100644 index 0000000..5799b85 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(400, 700).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1114.8653846153848; +y: zero_crossing: -1, edge_converge: 920.8071348940914 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 1120.671052631579; +y: zero_crossing: -1, edge_converge: 604.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 886.5258620689655; +y: zero_crossing: -1, edge_converge: 614.671052631579 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 847.671052631579; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 1025.9558823529412 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 94.1875, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(600, 960).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(600, 960).txt new file mode 100644 index 0000000..9b33d97 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(600, 960).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 316.76911544227886; +y: zero_crossing: -1, edge_converge: 646.7335664335665 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 360.91666666666663; +y: zero_crossing: -1, edge_converge: 910.05625 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 919.5; +y: zero_crossing: -1, edge_converge: 568.328947368421 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 422.0326086956522; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 782.0326086956521; +y: zero_crossing: -1, edge_converge: 1111.5 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 231.65625; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(800, 900).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(800, 900).txt new file mode 100644 index 0000000..85e0c4d --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(800, 900).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 94.49201474201475; +y: zero_crossing: -1, edge_converge: 612.9423076923077 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 97.05847076461768; +y: zero_crossing: -1, edge_converge: 615.672697368421 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 95.59030100334448; +y: zero_crossing: -1, edge_converge: 626.328947368421 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 96.23076923076923, edge_converge: 104.08333333333333; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 72.65625; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 105.76923076923077, edge_converge: 135.17105263157896; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 106.5, edge_converge: 264.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 1700).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 1700).txt new file mode 100644 index 0000000..51550d1 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 1700).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 992.733709273183; +y: zero_crossing: -1, edge_converge: 779.3782051282051 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 968.26875; +y: zero_crossing: -1, edge_converge: -1 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 953.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 198.43478260869566, edge_converge: 189.65625; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 197.5, edge_converge: 207.5; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 200.55172413793105, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 207.40969899665552; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 900).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 900).txt new file mode 100644 index 0000000..4e5269e --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 900).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 992.733709273183; +y: zero_crossing: -1, edge_converge: 612.9423076923077 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 968.26875; +y: zero_crossing: -1, edge_converge: 615.672697368421 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 953.0; +y: zero_crossing: -1, edge_converge: 626.328947368421 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 198.43478260869566, edge_converge: 189.65625; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 197.5, edge_converge: 207.5; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 200.55172413793105, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 207.40969899665552; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_4/img_2_4_(1400, 900).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_4/img_2_4_(1400, 900).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_4/img_2_4_(600, 960).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_4/img_2_4_(600, 960).txt new file mode 100644 index 0000000..725c811 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_4/img_2_4_(600, 960).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1100.8305555555555; +y: zero_crossing: 468.88853503184714, edge_converge: 468.9624718174986 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 1284.6410256410256; +y: zero_crossing: -1, edge_converge: 472.02868852459017 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1086.828947368421; +y: zero_crossing: 468.9056603773585, edge_converge: 469.513210927004 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1086.6; +y: zero_crossing: -1, edge_converge: 526.828947368421 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 1092.3333333333333, edge_converge: 1189.2003676470588; +y: zero_crossing: -1, edge_converge: 445.3327759197324 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 1092.157894736842, edge_converge: 1190.0; +y: zero_crossing: -1, edge_converge: 439.0 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1046.8653846153848; +y: zero_crossing: -1, edge_converge: 503.0326086956522 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 1072.84375; +y: zero_crossing: -1, edge_converge: 517.84375 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_4/img_2_4_(900, 1400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_4/img_2_4_(900, 1400).txt new file mode 100644 index 0000000..b979bb5 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_4/img_2_4_(900, 1400).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1296.632183836245; +y: zero_crossing: -1, edge_converge: 683.452135931303 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 1295.6363633216238; +y: zero_crossing: 690.1150168914178, edge_converge: 693.2398839220738 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1295.3653844696842; +y: zero_crossing: -1, edge_converge: 693.9883644021885 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1278.906249850798; +y: zero_crossing: 688.6590191104578, edge_converge: 700.2655993429721 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 1174.4999998716144; +y: zero_crossing: -1, edge_converge: 964.4428415672992 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 1161.4999997817608; +y: zero_crossing: -1, edge_converge: 940.947694754178 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1160.9999998929734; +y: zero_crossing: -1, edge_converge: 941.7896120081671 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 1186.0000001232456, edge_converge: 1174.4999996450306; +y: zero_crossing: -1, edge_converge: 962.456256071665 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_5/img_2_5_(600, 960).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_5/img_2_5_(600, 960).txt new file mode 100644 index 0000000..d1de3a8 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_5/img_2_5_(600, 960).txt @@ -0,0 +1,21 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: 1158.301886792453, edge_converge: 1158.0; +y: zero_crossing: 423.6167664670659, edge_converge: 425.51180555555555 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 1158.3440860215053, edge_converge: 1166.740170940171; +y: zero_crossing: -1, edge_converge: 385.2810276679842 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 1158.134328358209, edge_converge: 1188.467391304348; +y: zero_crossing: -1, edge_converge: 326.3781954887218 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 1158.2131147540983, edge_converge: 1194.753947368421; +y: zero_crossing: 423.44827586206895, edge_converge: 374.91666666666663 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 1170.5; +y: zero_crossing: 423.1578947368421, edge_converge: 351.5 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1255.0; +y: zero_crossing: -1, edge_converge: 700.0326086956521 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 1218.532608695652; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(240, 320).txt new file mode 100644 index 0000000..d77b164 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 383.569200132758, poly: 382.83083083083085, gaussian: 383.4114114114114; +y: edge_centroid: 128.77362969356932, poly: 129.4084084084084, gaussian: 129.21021021021022 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(600, 960).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(600, 960).txt new file mode 100644 index 0000000..d22680c --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(600, 960).txt @@ -0,0 +1 @@ +ksize:(7, 7), sigmax:0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_3_3/img_3_3_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_3_3/img_3_3_(240, 320).txt new file mode 100644 index 0000000..15cad33 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_3_3/img_3_3_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 388.0; +y: zero_crossing: 129.02597402597402, edge_converge: 125.57692307692308 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 384.1578947368421, edge_converge: 389.5364372469636; +y: zero_crossing: 129.47297297297297, edge_converge: 129.40969899665552 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 384.23809523809524, edge_converge: 371.13461538461536; +y: zero_crossing: 129.62337662337663, edge_converge: 129.21517027863777 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 401.32894736842104; +y: zero_crossing: 129.66666666666666, edge_converge: 199.6346153846154 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 405.3327759197324; +y: zero_crossing: 129.72916666666666, edge_converge: 123.56414473684211 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 129.60416666666666, edge_converge: 125.0 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 383.8421052631579, edge_converge: -1; +y: zero_crossing: 129.5, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 383.59375, edge_converge: -1; +y: zero_crossing: 129.46341463414635, edge_converge: 105.46739130434783 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_3_3/img_3_3_new_(600, 960).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_3_3/img_3_3_new_(600, 960).txt new file mode 100644 index 0000000..85506ff --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_3_3/img_3_3_new_(600, 960).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 627.2624342255776; +y: zero_crossing: 282.9597701149425, edge_converge: 280.3083778966132 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 626.3650177462289; +y: zero_crossing: -1, edge_converge: 283.4423076923077 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 608.9765275707898; +y: zero_crossing: 287.3333333333333, edge_converge: 284.86538461538464 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 650.8565573770492; +y: zero_crossing: -1, edge_converge: 296.0326086956522 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 652.203125; +y: zero_crossing: -1, edge_converge: 689.3056680161943 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 659.8423913043478; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 631.6904761904761, edge_converge: 597.0326086956522; +y: zero_crossing: -1, edge_converge: 683.5 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 645.0; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(240, 320).txt new file mode 100644 index 0000000..056b176 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 383.6794588625068, poly: 383.2082082082082, gaussian: 383.5855855855856; +y: edge_centroid: 128.72770467836258, poly: 129.44144144144144, gaussian: 129.17717717717719 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(300, 573).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(300, 573).txt new file mode 100644 index 0000000..6a9be15 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(300, 573).txt @@ -0,0 +1,21 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 551.1085016945578; +y: zero_crossing: -1, edge_converge: 401.2614005098476 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 551.0790923034685; +y: zero_crossing: -1, edge_converge: 401.1959898455841 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 551.3164486248141; +y: zero_crossing: -1, edge_converge: 396.65866001765227 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 553.6140783045154; +y: zero_crossing: 385.44129158264957, edge_converge: 391.39592471066015 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 554.2854352720954, edge_converge: 553.3228366624788; +y: zero_crossing: 385.28612080628454, edge_converge: 391.30816089061875 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 554.0283816103325, edge_converge: 552.9026715626205; +y: zero_crossing: 385.12690508006284, edge_converge: 391.2389474584604 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 553.7215989908605, edge_converge: 552.4769129699359; +y: zero_crossing: 384.9703803392806, edge_converge: 391.0686695466003 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(600, 960).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(600, 960).txt new file mode 100644 index 0000000..eebe206 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(600, 960).txt @@ -0,0 +1,6 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 629.1857205127992; +y: zero_crossing: -1, edge_converge: 303.2178917674522 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 626.2193034291377; +y: zero_crossing: -1, edge_converge: 279.055693080456 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_4_1/img_4_1_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_4_1/img_4_1_(240, 320).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_4_1/img_4_1_(500, 1200).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_4_1/img_4_1_(500, 1200).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_4_{0}/img_4_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_4_{0}/img_4_{0}_(240, 320).txt new file mode 100644 index 0000000..7808d12 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_4_{0}/img_4_{0}_(240, 320).txt @@ -0,0 +1,6 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: 236.92774193101968, edge_converge: 237.5228648141686; +y: zero_crossing: 325.7458333221428, edge_converge: 321.11252693875815 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 237.21044902427207, edge_converge: 234.45920213005442; +y: zero_crossing: 325.6826399612562, edge_converge: 321.13169019760346 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(200, 50).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(200, 50).txt new file mode 100644 index 0000000..cb9440f --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(200, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 93.01701701701703, gaussian: 92.54954954954955; +y: edge_centroid: 220.67972613160907, poly: 205.44544544544544, gaussian: 220.13513513513513 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 100).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 150).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 150).txt new file mode 100644 index 0000000..4e7e731 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 207.25707213578505, poly: 211.72972972972974, gaussian: 210.05605605605606 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 250).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 250).txt new file mode 100644 index 0000000..0b0c80e --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 218.612658674189, poly: 210.37037037037038, gaussian: 216.64864864864865 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 550).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 550).txt new file mode 100644 index 0000000..5d716b8 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 208.3091801113311, poly: 194.96096096096096, gaussian: 207.03603603603602 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(300, 500).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(300, 500).txt new file mode 100644 index 0000000..7669241 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(300, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.85585585585585, gaussian: 94.37537537537537; +y: edge_centroid: 211.19331646152077, poly: 195.86786786786786, gaussian: 209.42642642642642 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 10).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 10).txt new file mode 100644 index 0000000..c7c4711 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 10).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.53349610865254, poly: 90.78078078078079, gaussian: 90.11711711711712; +y: edge_centroid: 221.0741458686698, poly: 244.62762762762765, gaussian: 258.0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 400).txt new file mode 100644 index 0000000..e9008a5 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.53349610865254, poly: 92.03003003003003, gaussian: 92.93793793793793; +y: edge_centroid: 214.17900156837212, poly: 209.03203203203202, gaussian: 214.83483483483485 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 100).txt new file mode 100644 index 0000000..34f75b7 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64864864864865; +y: edge_centroid: -1, poly: 196.7027027027027, gaussian: 220.20220220220222 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 300).txt new file mode 100644 index 0000000..b1e658b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 215.8282069593912, poly: 200.8108108108108, gaussian: 203.97297297297297 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 350).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 350).txt new file mode 100644 index 0000000..ae51c4c --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 215.93902685241267, poly: 199.14814814814815, gaussian: 201.96296296296296 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 40).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 40).txt new file mode 100644 index 0000000..35d04b6 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 40).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 213.46588200238375, poly: 187.52852852852854, gaussian: 250.0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 400).txt new file mode 100644 index 0000000..dd9188e --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 93.01701701701703, gaussian: 92.54954954954955; +y: edge_centroid: 214.17900156837212, poly: 209.03203203203202, gaussian: 214.83483483483485 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(240, 320).txt new file mode 100644 index 0000000..beaeadc --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.95545171339562, poly: 92.43843843843844, gaussian: 92.54054054054055; +y: edge_centroid: 216.32595947660937, poly: 197.66066066066065, gaussian: 203.43843843843842 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(250, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(250, 100).txt new file mode 100644 index 0000000..d73fc36 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(250, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: -1, poly: 198.59459459459458, gaussian: 236.03003003003005 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(30, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(30, 300).txt new file mode 100644 index 0000000..8c9068f --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(30, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 106.90241734802697, poly: 130.08608608608608, gaussian: 137.0; +y: edge_centroid: 215.8282069593912, poly: 200.8108108108108, gaussian: 203.94794794794794 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 150).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 150).txt new file mode 100644 index 0000000..00f639b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.85585585585585, gaussian: 94.37537537537537; +y: edge_centroid: 207.25707213578505, poly: 211.72972972972974, gaussian: 210.05605605605606 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 400).txt new file mode 100644 index 0000000..07a7d5e --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.72372372372372, gaussian: 94.26126126126127; +y: edge_centroid: 214.17900156837212, poly: 194.24424424424424, gaussian: 197.8028028028028 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(350, 200).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(350, 200).txt new file mode 100644 index 0000000..031f3ef --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(350, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30997090716743, poly: 92.7907907907908, gaussian: 93.55555555555556; +y: edge_centroid: 219.13322627053438, poly: 210.43043043043042, gaussian: 218.1951951951952 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(400, 250).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(400, 250).txt new file mode 100644 index 0000000..525a96e --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(400, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.80265120132562, poly: 93.7977977977978, gaussian: 93.90190190190191; +y: edge_centroid: 218.612658674189, poly: 210.37037037037038, gaussian: 216.64864864864865 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(450, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(450, 300).txt new file mode 100644 index 0000000..013cc84 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(450, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.75074524191695, poly: 94.30530530530531, gaussian: 94.26426426426427; +y: edge_centroid: 215.8282069593912, poly: 211.35135135135135, gaussian: 215.15915915915917 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(50, 550).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(50, 550).txt new file mode 100644 index 0000000..7db67f4 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(50, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.89583756345176, poly: 92.57657657657657, gaussian: 92.48648648648648; +y: edge_centroid: 208.3091801113311, poly: 189.6096096096096, gaussian: 209.03303303303304 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_5_1/img_5_1_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_5_1/img_5_1_(240, 320).txt new file mode 100644 index 0000000..aed0952 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_5_1/img_5_1_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 556.6842105263158, edge_converge: -1; +y: zero_crossing: 301.9344262295082, edge_converge: 308.5 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 555.8125, edge_converge: -1; +y: zero_crossing: 301.94444444444446, edge_converge: 301.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 555.4347826086956, edge_converge: -1; +y: zero_crossing: 301.84375, edge_converge: 293.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 555.5, edge_converge: -1; +y: zero_crossing: 301.75, edge_converge: 318.4673913043478 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 555.5, edge_converge: -1; +y: zero_crossing: 301.6862745098039, edge_converge: 280.9673913043478 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 446.17105263157896; +y: zero_crossing: 301.7291666666667, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 301.7291666666667, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 301.6666666666667, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_5_1/img_5_1_(900, 1400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_5_1/img_5_1_(900, 1400).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_5_{0}/img_5_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_5_{0}/img_5_{0}_(240, 320).txt new file mode 100644 index 0000000..65e1696 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_5_{0}/img_5_{0}_(240, 320).txt @@ -0,0 +1,21 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: 555.6464323051268, edge_converge: 568.4630895970322; +y: zero_crossing: 302.34291829038295, edge_converge: 304.5181313275549 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 555.4526325366787, edge_converge: 566.8934642695242; +y: zero_crossing: 302.34965401891816, edge_converge: 304.4386691292941 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 555.2960595115023, edge_converge: 563.5356471927093; +y: zero_crossing: 302.33803803307313, edge_converge: 304.27810760651005 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 555.1849293811231, edge_converge: 563.5416332228492; +y: zero_crossing: 302.3176065339906, edge_converge: 300.31359690803674 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 555.1016003888399, edge_converge: 563.6004921726214; +y: zero_crossing: 302.29189598827344, edge_converge: 300.16238390552815 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 555.0360469257112, edge_converge: 563.6160702558284; +y: zero_crossing: 302.26525876715635, edge_converge: 296.30288208863885 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 554.9834021944725, edge_converge: 554.5573053432411; +y: zero_crossing: 302.24049538378574, edge_converge: 308.2023326126082 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}.png_(200, 600).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}.png_(200, 600).txt new file mode 100644 index 0000000..ed07d5f --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}.png_(200, 600).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.32846573208725, poly: 92.23423423423424, gaussian: 92.21921921921921; +y: edge_centroid: 196.4742684157417, poly: 195.8928928928929, gaussian: 196.3783783783784 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(200, 500).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(200, 500).txt new file mode 100644 index 0000000..a483322 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.32846573208725, poly: 92.03003003003003, gaussian: 92.08708708708708; +y: edge_centroid: 210.0317535296279, poly: 189.0990990990991, gaussian: 212.75375375375376 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(240, 320).txt new file mode 100644 index 0000000..302af08 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.0877174261018, poly: 92.41741741741741, gaussian: 92.28528528528528; +y: edge_centroid: 221.40502732240432, poly: 205.07807807807808, gaussian: 206.8998998998999 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 100).txt new file mode 100644 index 0000000..b340acb --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30595634480204, poly: 94.14414414414415, gaussian: 93.81681681681681; +y: edge_centroid: 307.8291557805356, poly: 354.0, gaussian: 308.5155155155155 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 400).txt new file mode 100644 index 0000000..461ddb4 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30595634480204, poly: 94.14414414414415, gaussian: 93.81681681681681; +y: edge_centroid: 212.21240264432728, poly: 190.33833833833833, gaussian: 193.35135135135135 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(240, 320).txt new file mode 100644 index 0000000..750c5f3 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.9518581931715, poly: 92.18618618618618, gaussian: 91.98798798798799; +y: edge_centroid: 218.40512573697507, poly: 201.44444444444446, gaussian: 206.24924924924926 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(400, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(400, 400).txt new file mode 100644 index 0000000..7978897 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.19376913380157, poly: 94.17417417417417, gaussian: 94.03603603603604; +y: edge_centroid: 212.52264302981456, poly: 190.97897897897897, gaussian: 194.45845845845847 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_62_{0}/img_62_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_62_{0}/img_62_{0}_(240, 320).txt new file mode 100644 index 0000000..d58a228 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_62_{0}/img_62_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 178.91803535934721, poly: 178.44144144144144, gaussian: 178.33333333333334; +y: edge_centroid: -1, poly: 184.47747747747746, gaussian: 265.93293293293294 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_63_{0}/img_63_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_63_{0}/img_63_{0}_(240, 320).txt new file mode 100644 index 0000000..52cbf69 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_63_{0}/img_63_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 178.97878718007834, poly: 178.87387387387386, gaussian: 178.72972972972974; +y: edge_centroid: -1, poly: 182.97297297297297, gaussian: 227.4954954954955 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_6_{0}/img_6_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_6_{0}/img_6_{0}_(240, 320).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_73_{0}/img_73_{0}_(400, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_73_{0}/img_73_{0}_(400, 400).txt new file mode 100644 index 0000000..3c97a4b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_73_{0}/img_73_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 283.485064401206, poly: 323.0, gaussian: 286.4864864864865; +y: edge_centroid: 195.9362609551483, poly: 189.6016016016016, gaussian: 190.22222222222223 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(100, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(100, 300).txt new file mode 100644 index 0000000..462740a --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(100, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 278.09682467236087, poly: 268.2682682682683, gaussian: 274.5575575575576; +y: edge_centroid: 174.44361763022326, poly: 175.0990990990991, gaussian: 174.0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(150, 350).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(150, 350).txt new file mode 100644 index 0000000..3abe0ab --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(150, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 264.6934011476264, poly: 267.4674674674675, gaussian: 265.3213213213213; +y: edge_centroid: 212.65002063557583, poly: 193.16216216216216, gaussian: 205.15315315315314 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 100).txt new file mode 100644 index 0000000..ec7eba6 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 299.2048811389324, poly: 298.0, gaussian: 299.0900900900901; +y: edge_centroid: 212.06545603775513, poly: 211.82282282282281, gaussian: 212.06006006006007 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 400).txt new file mode 100644 index 0000000..0fc7e6b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 299.2048811389324, poly: 298.0, gaussian: 299.0900900900901; +y: edge_centroid: 216.82302078726215, poly: 193.26126126126127, gaussian: 186.53453453453454 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(250, 150).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(250, 150).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(250, 450).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(250, 450).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_78_{0}/img_78_{0}_(400, 260).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_78_{0}/img_78_{0}_(400, 260).txt new file mode 100644 index 0000000..6892c16 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_78_{0}/img_78_{0}_(400, 260).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 366.0705646776132, poly: 403.0, gaussian: 402.0; +y: edge_centroid: 206.59396835595538, poly: 198.7157157157157, gaussian: 201.34434434434434 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(100, 200).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(100, 200).txt new file mode 100644 index 0000000..de27310 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(100, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 361.17140024783157, poly: 351.23423423423424, gaussian: 355.06006006006004; +y: edge_centroid: 206.05061553818015, poly: 197.32232232232232, gaussian: 204.25025025025025 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(200, 200).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(200, 200).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_7_{0}/img_7_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_7_{0}/img_7_{0}_(240, 320).txt new file mode 100644 index 0000000..43ad63f --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_7_{0}/img_7_{0}_(240, 320).txt @@ -0,0 +1,21 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: 157.8389116826965, edge_converge: 158.45130962399327; +y: zero_crossing: -1, edge_converge: 411.79259030140565 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 157.75410480327545, edge_converge: 158.32429639754088; +y: zero_crossing: -1, edge_converge: 411.6718763916268 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 157.7245284134464, edge_converge: 155.54913028965618; +y: zero_crossing: -1, edge_converge: 411.593647090896 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 157.76000829765138, edge_converge: 158.15343806061153; +y: zero_crossing: -1, edge_converge: 411.5797965685118 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 157.83060827808885, edge_converge: 157.98016047257528; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 157.90853193451255, edge_converge: 157.6948902708295; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 157.98721999268648, edge_converge: 157.47066779723983; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(200, 300).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(200, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(300, 280).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(300, 280).txt new file mode 100644 index 0000000..5df82f5 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(300, 280).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 311.3298049296839, poly: 319.7637637637638, gaussian: 319.5735735735736; +y: edge_centroid: -1, poly: 0, gaussian: 0 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(150, 100).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(150, 100).txt new file mode 100644 index 0000000..639b64b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(150, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 122.42161046111492, poly: 124.84684684684684, gaussian: 124.58358358358359; +y: edge_centroid: 268.99951226309923, poly: 263.5865865865866, gaussian: 263.9189189189189 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(200, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(200, 400).txt new file mode 100644 index 0000000..34cfc9d --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 326.7772293517605, poly: 326.3703703703704, gaussian: 326.84684684684686; +y: edge_centroid: 247.36609869795853, poly: 246.3783783783784, gaussian: 244.63563563563565 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_97_{0}/img_97_{0}_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_97_{0}/img_97_{0}_(240, 320).txt new file mode 100644 index 0000000..5d771cc --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_97_{0}/img_97_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 249.44900531810134, poly: 248.6956956956957, gaussian: 249.67667667667666; +y: edge_centroid: 259.66796296933614, poly: 261.015015015015, gaussian: 261.4074074074074 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(200, 500).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(200, 500).txt new file mode 100644 index 0000000..653e98a --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 248.7235796541028, poly: 252.58858858858858, gaussian: 249.82882882882882; +y: edge_centroid: 262.84957891453524, poly: 258.80680680680683, gaussian: 260.3963963963964 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(373, 234).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(373, 234).txt new file mode 100644 index 0000000..550694b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(373, 234).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 246.9395417318486, poly: 256.96296296296293, gaussian: 253.03203203203202; +y: edge_centroid: 280.6590576754352, poly: 258.1631631631632, gaussian: 257.65765765765764 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(400, 400).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(400, 400).txt new file mode 100644 index 0000000..ceb5b0e --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 263.7749063060128, poly: 262.6166166166166, gaussian: 263.40440440440443; +y: edge_centroid: 255.54966073622904, poly: 253.15915915915917, gaussian: 254.85185185185185 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/img_9_1/img_9_1_(240, 320).txt b/Nov_27/Full/Camera/img_rec_module/meas/img_9_1/img_9_1_(240, 320).txt new file mode 100644 index 0000000..501f1b1 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/img_9_1/img_9_1_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 243.84375; +y: zero_crossing: 211.51459854014598, edge_converge: 204.6346153846154 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 241.55172413793105, edge_converge: 250.5; +y: zero_crossing: 211.45945945945945, edge_converge: 205.6346153846154 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 241.59375, edge_converge: 243.8653846153846; +y: zero_crossing: 211.30208333333334, edge_converge: 233.08333333333334 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 241.76190476190476, edge_converge: 252.2848297213622; +y: zero_crossing: -1, edge_converge: 145.15625 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 241.86363636363637, edge_converge: 252.4673913043478; +y: zero_crossing: 210.77586206896552, edge_converge: 218.0 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 252.5; +y: zero_crossing: 210.64814814814815, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 241.63888888888889, edge_converge: 217.0; +y: zero_crossing: 210.5, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 249.52586206896552; +y: zero_crossing: 210.52727272727273, edge_converge: -1 diff --git a/Nov_27/Full/Camera/img_rec_module/meas/truth.txt b/Nov_27/Full/Camera/img_rec_module/meas/truth.txt new file mode 100644 index 0000000..dcf364f --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/meas/truth.txt @@ -0,0 +1,32 @@ +new_test +img_4 237, 325 + +calib +img_29 140, 203 + +testpic +img_1 385, 130 E: (2, 1) +img_2 385, 130 E: (2, 1) +img_3 385, 130 E: (2, 1) +img_4 -2, -2 175, 113 E: (4, 7) (DATA) +img_5 176, 52 E: (1, 3) +img_6 174, -1 E: (1, 0) +img_7 158, -1 E: (0, 0) +img_8 -2, -2 159, -1 E: (F, 0) (DATA) +img_9 242, 212 E: (0, 2) +img_10 278, 215 E: (1, 3) +img_11 -2, -2 325, 218 E: (1, 4) (DATA) +img_12 143, 215 E: (0, 1) +img_13 53, 219 E: (0, 4) +img_14 -1, 17 E: (0, 0) +img_15 138, 19 E: (0, 0) +img_16 355, 14 E: (1, 0) +img_17 288, -1 E: (1, 0) +img_18 369, 180 E: (1, 0) +img_19 357, 265 E: (0, 1) +img_20 225, 224 E: (3, 1) +img_21 41, 224 E: (0, 1) +img_22 -1, 59 E: (0, 3) +img_23 -2, -2 -1, -1 E: (0, T) (DATA) +img_24 -1, 160 E: (0, 1) +img_25 445, 166 E: (2, 4) diff --git a/Nov_27/Full/Camera/img_rec_module/sig_proc.py b/Nov_27/Full/Camera/img_rec_module/sig_proc.py new file mode 100644 index 0000000..9640c3b --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/sig_proc.py @@ -0,0 +1,958 @@ +import cv2 +import numpy as np +import csv +from scipy.optimize import curve_fit +from math import atan, sqrt, tan, radians, acos, asin, degrees, sin, cos + +""" =================================== +========== ANALYTIC GEOMETRY ========== +======================================= """ + + +class Line: + inf = float('inf') + + def __init__(self, a=inf, b=inf, p1=None, p2=None, data=None): + if p1 and p2: + self.point(p1, p2) + elif data: + self.reg(data) + else: + self.a = a + self.b = b + + def reg(self, data): + D = np.array([[d[0], 1] for d in data]) + y = np.array([d[1] for d in data]) + self.a, self.b = leastSquares(D, y) + + def point(self, p1, p2): + self.a = 1 + + @staticmethod + def intersect(l1, l2): + x = (l2.b - l1.b) / (l1.a - l2.a) + y = l1.a * x + l1.b + return x, y + + +class HoughLine: + def __init__(self, rho_rad=0, theta=0, x=None, data=None): + if data is not None and x is not None: + self.reg(x, data) + else: + self._r = degrees(rho_rad) + self._t = theta + self._s = sin(rho_rad) + self._c = cos(rho_rad) + + def reg(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + x1, x2 = x[0], x[-1] + y1, y2 = data[0], data[-1] + theta0 = theta_pred(x1, y1, x2, y2) + # print(degrees(theta0)) + p0 = [theta0, x1 * cos(theta0) + y1 * sin(theta0)] + pm, vm = curve_fit(hough_line, x, data, p0=p0) + # data_pred = hough_line(x, *pm) + # print('PRED', data_pred) + # res = data_pred - data + # print("RES", res) + # stderr = np.linalg.norm(res, 2) + # print("ERR", stderr) + # rankerr = res / stderr + # print("Z", rankerr) + if pm[1] < 0: + pm[1] = -pm[1] + pm[0] -= HC + # pm[0] = 2 * np.pi + angle = normalize_angle(pm[0]) + self._t = angle + self._r = pm[1] + self._s = sin(angle) + self._c = cos(angle) + + def extract_points(self, x_input): + x1 = int(x_input[0]) + x2 = int(x_input[-1]) + y1 = int(self.fit_x(x1)) + y2 = int(self.fit_x(x2)) + return (x1, y1), (x2, y2) + + def fit_x(self, x): + # print(self._r, self._t) + return (self._r - x * self._c) / self._s + + def __str__(self): + return 'hough line with cos:{0}, sin:{1}, rho:{2}, theta:{3}'.format(self._c, self._s, + self._r, degrees(self._t)) + + @staticmethod + def intersect(l1, l2): + x = (l2._r / l2._s - l1._r / l1._s) / (l2._c / l2._s - l1._c / l1._s) + y = l1.fit_x(x) + return x, y + + +# QC: QUARTER_CYCLE, HC: HALF_CYCLE, TQC: THIRD_QUARTER_CYCLE, FC: FULL_CYCLE +QC = np.pi / 2 +HC = np.pi +TQC = 3 * np.pi / 2 +FC = 2 * np.pi + + +def angle_interp(s, c): + if c == 1.0: + return 0 + elif s == 1.0: + return np.pi / 2 + elif c == -1.0: + return np.pi + elif s == -1.0: + return np.pi * 3 / 2 + elif c < 0 < s: + return acos(c) + elif s < 0 and c < 0: + return 2 * np.pi - acos(c) + elif s < 0 < c: + return asin(s) + 2 * np.pi + else: + return asin(s) + + +def normalize_angle(angle): + res = angle - (angle // FC) * FC + return res + """ + if QC < res < HC: + return res + HC + elif HC <= res <= TQC: + return res - HC + else: + return res""" + + +def theta_pred(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + angle = sin_angle_from_points(dx, dy) + if dx * dy <= 0: + return np.pi / 2 - angle + else: + root = root_finding(x1, x2, y1, y2) + if root < 0: + return np.pi / 2 + angle + else: + return angle + 3 * np.pi / 2 + + +def sin_angle_from_points(dx, dy): + return asin(abs(dy) / sqrt(dx ** 2 + dy ** 2)) + + +def poly_curve(params, x_input): + # params contains the coefficients that multiply the polynomial terms, in degree of lowest degree to highest degree + degree = len(params) - 1 + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = x * 0 + + for k in range(0, degree + 1): + coeff = params[k] + y = y + list(map(lambda z: coeff * z ** k, x)) + return x, y + + +def gauss_2d(x, y, a, b1, c_s1, b2, c_s2): + return a * np.exp(- ((x - b1) ** 2 / (2 * c_s1) + (y - b2) ** 2) / (2 * c_s2)) + + +def gauss_hat(x, a, b, c_s): + return a * np.exp(- (x - b) ** 2 / (2 * c_s)) + + +def gaussian_curve(x_input, a, b, c_s): + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = a * np.exp(- (x - b) ** 2 / (2 * c_s)) + return x, y + + +def hough_line(x, theta, rho): + return (rho - x * cos(theta)) / sin(theta) + + +""" =================================== +========== MATRIX-ARRAY UTIL ========== +======================================= """ + + +class FastDataMatrix2D: + # TODO: HANDLE THE CASE WHEN IT WRAPS 1D + + HOR = 1 + VER = 0 + + def __init__(self, data, ax, index): + self._data = data + self._ax = ax + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + self.itr = 0 + self.initialize() + + def segmentize(self, start, end): + assert 0 <= start < end <= self._data.shape[self._ax], "start: {0}, end: {1}, ax: {2}, index: {3}".format(start, + end, + self._ax, + self._index) + self.start = start + self.end = end + + def initialize(self): + self.segmentize(0, self._data.shape[self._ax]) + + def irange(self): + # index range of the fast matrix array + return self._data.shape[1 - self._ax] + + def set_axis(self, ax): + """USE copy when trying to switch axis and index""" + self._ax = ax + if self._index >= self.irange(): + raise IndexError("Old index {0} is too large for the new axis".format(self._index)) + self.initialize() + + def set_index(self, index): + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + + def extract_array(self): + """Optimize later for better performance""" + arr = self._data[self._index, self.start:self.end] if self._ax == FastDataMatrix2D.HOR \ + else self._data[self.start:self.end, self._index] + return np.array(arr) + + def copy(self, ax=None, index=None): + if ax is not None and index is not None: + return FastDataMatrix2D(self._data, ax, index) + else: + return FastDataMatrix2D(self._data, self._ax, self._index) + + def __iter__(self): + raise RuntimeError("You need the ITER method!") + + def __next__(self): + raise RuntimeError("You need the NEXT method!") + + def __getitem__(self, item): + return self._data[self._index, item + self.start] if self._ax == FastDataMatrix2D.HOR else self._data[item + self.start, self._index] + + def __setitem__(self, key, value): + if self._ax == FastDataMatrix2D.HOR: + self._data[self._index, key + self.start] = value + else: + self._data[key + self.start, self._index] = value + + def __len__(self): + return self.end - self.start + + +""" =================================== +=========== REGRESSION UTILS ========== +======================================= """ + + +# Generic Regression Tools 128-133 +def leastSquares(D, y): + return np.linalg.lstsq(D, y, rcond=None)[0] + + +def MSE(y, y_hat, N): + return np.linalg.norm(y - y_hat) ** 2 / N + + +def std_dev(data): + std_dev = 0 + len_data = len(data) + mean = sum(data) / len_data + for i in range(len_data): + std_dev += (data[i] - mean) ** 2 + return sqrt(std_dev / len_data) + + +def reg_pre_debias(ind, data): + sd = np.std(data) + miu = np.mean(data) + debiased_data = [] + debiased_ind = [] + for i in range(len(data)): + dev = abs((data[i] - miu) / sd) + if dev < 2: + debiased_data.append(data[i]) + debiased_ind.append(ind[i]) + return debiased_ind, debiased_data + + +# Polynomial Regression Tools 137-171 +def poly_data_matrix(input_data, degree): + # degree is the degree of the polynomial you plan to fit the data with + Data = np.zeros((len(input_data), degree + 1)) + + for k in range(0, degree + 1): + Data[:, k] = (list(map(lambda x: x ** k, input_data))) + + return Data + + +def poly_error(params, D_a, y_a): + '''degree=len(params)-1 + y=x_a*0 + + for k in range(0,degree+1): + coeff=params[k] + y=y+list(map(lambda z:coeff*z**k,x_a))''' + y = np.dot(D_a, params) + return np.linalg.norm(y - y_a) ** 2 + + +def improvedCost(x, y, x_test, y_test, start, end): + """Given a set of x and y points training points, + this function calculates polynomial approximations of varying + degrees from start to end. Then it returns the cost, with + the polynomial tested on test points of each degree in an array""" + c = [] + degrees = range(start, end) + ps = [] + for degree in degrees: + # YOUR CODE HERE + D = poly_data_matrix(x, degree) + p = leastSquares(D, y) + ps.append(p) + D_t = poly_data_matrix(x_test, degree) + y_hat = np.dot(D_t, p) + c.append(MSE(y_test, y_hat, len(x_test))) + return np.array(degrees), ps, np.array(c) + + +# Gaussian Regression Tools 184-210 +def gauss_data_matrix(data): + return np.array([[1, x ** 2, x, 1] for x in data]) + + +def gauss_reg(x, y, p0): + """Given a set of x and y training points, this function + calculates the gaussian approximation function""" + """skip_x = np.array([x[i] for i in range(len(y)) if y[i] != 0]) + y_prime = np.array([y[i] for i in range(len(y)) if y[i] != 0]) + logy = np.log(y_prime) + + sol = leastSquares(gauss_data_matrix(skip_x), logy) + alp, bet, gam, lam = sol + a = np.e ** alp + c_s = - 1 / (2 * bet) + b = gam * c_s + maxi, mini = max_min(y) + pred = gauss_hat(maxi, a, b, c_s) + real = y[maxi] + a = real / pred // 1000000000 * 10""" + # timeb = datetime.now() + param, vm = curve_fit(gauss_hat, x, y, p0=p0) + # timea = datetime.now() + # print(timea - timeb) + return param + + +def gauss_mat(shape, a, b1, c_s1, b2, c_s2): + mat = np.zeros(shape) + for r in range(mat.shape[0]): + for c in range(mat.shape[1]): + mat[r, c] = gauss_2d(c, r, a, b1, c_s1, b2, c_s2) + + return mat + + +# Hough Transform Regression Tools +def hough_data_matrix(x, y): + dim = len(x) + mat = np.full((dim, 3), -1.0) + for i in range(dim): + mat[i][0] = x[i] + mat[i][1] = y[i] + return mat + + +""" ======================================= +========= EDGE DETECTION UTILS ============ +=========================================== """ + + +# Generic Helper +def max_min(data): + # Returns the maximum and minimum for the data + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + return max_ind, min_ind + + +def edge_max_min(data): + # Returns a *safe* edge maxi, mini for the data + # TODO: OPTIMIZE THE WIDTH AND VALUE THRESHOLD + width_thres = 90 + value_thres = 20 + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + maxi, mini = max_ind, min_ind + assert data[maxi] >= value_thres and mini - maxi <= width_thres and maxi < mini + return maxi, mini + + +def min_max(data, max, min): + """ Converts the data to min max space. """ + g_diff = max - min + return [(d - min) / g_diff for d in data] + + +def root_finding(x1, x2, y1, y2): + """Given two points on a line, finds its zero crossing root.""" + return - y1 * (x2 - x1) / (y2 - y1) + x1 + + +def check_cross(a, b): + # Checks whether two points are of opposite signs + return a * b < 0 + + +def round_up(num): + down = int(num) + if num - down > 0: + return num + 1 + else: + return num + + +def smart_interval(start, end, data): + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + return start, end + + +def edge_preprocess(data, padding): + maxi, mini = edge_max_min(data) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end + + +# ZERO CROSSING (PEAK FINDING) +def zero_crossing(data): + # Yields the center with zero-crossing method + maxi, mini = max_min(data) + cross = -1 + cross_count = 0 + for j in range(maxi, mini): + y1 = data[j] + x2 = j + 1 + y2 = data[x2] + if check_cross(y1, y2): + cross = root_finding(j, x2, y1, y2) # change to function later + cross_count += 1 + return -1 if cross_count > 1 else cross + + +# AVERAGE METHOD FOR EDGE CENTER FINDING +def edge_converge_base(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + else: + return (maxi + mini) / 2 + + +# PSEUDO EDGE (closest noise gradient change) CENTER FINDING +def edge_converge_extreme(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + emax = -1 + emin = -1 + maxflag = True + minflag = True + cmax = maxi + cmin = mini + while cmax > 0 and cmin < len(data) - 1 and (maxflag or minflag): + max2 = cmax - 1 + maxy1, maxy2 = data[cmax], data[max2] + min2 = cmin + 1 + miny1, miny2 = data[cmin], data[min2] + if check_cross(maxy1, maxy2) and maxflag: + emax = root_finding(cmax, max2, maxy1, maxy2) + maxflag = False + if check_cross(miny1, miny2) and minflag: + emin = root_finding(cmin, min2, miny1, miny2) + minflag = False + if maxflag: + cmax -= 1 + if minflag: + cmin += 1 + return -1 if (emax == -1 or emin == -1) else (emax + emin) / 2 + + +def extract_extrema(data): + len_data = len(data) + mean = sum(data) / len_data + std_dev = 0 + for x in data: + std_dev += (x - mean) ** 2 + std_dev = sqrt(std_dev / len_data) + signifmax = [] + signifmin = [] + coeff = 3 + for i, x in enumerate(data): + diff = (x - mean) / std_dev + if diff >= coeff: + signifmax.append(i) + elif diff <= -coeff: + signifmin.append(i) + return signifmax, signifmin + + +# CENTROID METHOD FOR EDGE CENTER FINDING +def edge_centroid(data, img_data, padding=20): + # With Gaussian Blur might achieve the best performance + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + isums = 0 + total = 0 + for i in range(start, end): + isums += img_data[i] * i + total += img_data[i] + return isums / total if total else -1 + + +def centroid_seg(data, start, end): + """ Given a segment (start, end) of the data, + find the centroid. """ + isums = 0 + total = 0 + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + for i in range(start, end): + isums += data[i] * i + total += data[i] + return isums / total if total else -1 + + +# POLYNOMIAL FITTING +def poly_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + #y = np.array(img_data[start:end]) + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + curve_x, curve_y = poly_curve(param, x) + center_id = np.argmax(curve_y) + return curve_x[center_id] + + +def poly_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + 1 + start, end = smart_interval(start, end, data) + if start > end: + try: + print(maxi, mini, img_data._ax, start, end) + except: + print("else", maxi, mini, start, end) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + return param, x + + +DEGREES = {} + + +def degree_register(elem): + if elem in DEGREES: + DEGREES[elem] += 1 + else: + DEGREES[elem] = 1 + + +# GAUSSIAN FITTING +def gaussian_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + try: + maxi, mini = edge_max_min(data) + except AssertionError: + return -1 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end-start) + for i in range(start, end): + idata[i-start] = img_data[i] + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +def gaussian_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 # TODO: CONSOLIDATE THIS VALUE + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + start, end = smart_interval(start, end, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i-start] = img_data[i] + return gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]), x + + +"""====================================== +======== IMAGE PROCESSING UTIL ========== +========================================= """ + + +def gauss_bg_deduce(x, img_data): + # TODO: OPTIMIZE PERFORMANCE + idata = img_data.extract_array() + p0 = [1, len(img_data) / 2, std_dev(idata)] + a, b, c_s = gauss_reg(x, idata, p0=p0) + rem_gauss = gauss_hat(x, a, b, c_s) + new_y = idata - rem_gauss + return x, rem_gauss, new_y + + +def significance_test(data, val): + """Outputs whether the maximum or minimum value is a significant value.""" + return val in extract_extrema(data)[0] or val in extract_extrema(data)[1] + + +def edge_detect_expr(edges, original): + """ + TODO: 1. SIMPLE Approach: pairwise mask over original image, then compute total + 2. Traverse the image to mark the image. + """ + se = 0 + row_sum = 0 + col_sum = 0 + tot_sum = 0 + for i in range(edges.shape[0]): + for j in range(edges.shape[1]): + if edges[i][j] > 0: + row_sum += i * original[i][j] + col_sum += j * original[i][j] + tot_sum += original[i][j] + se += 1 + print(se) + if tot_sum != 0: + print(row_sum / tot_sum) + print(col_sum / tot_sum) + + +def hori(img, i, j, d): + dest = j + d + if dest < 0 or dest >= img.shape[1]: + return img.item(i, j) + return img.item(i, dest) + + +def verti(img, i, j, d): + dest = i + d + if dest < 0 or dest >= img.shape[0]: + return img.item(i, j) + return img.item(dest, j) + + +def test_blur_then_nr(iname): + imgs = iname + numIMG = 5 + imgr = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + target = cv2.GaussianBlur(target, (9, 9), 0) + if i == 1: + imgr = np.uint16(target) + else: + imgr = imgr + target + return imgr / numIMG + + +def get_center_val(img): + return img.item(img.shape[0] // 2, img.shape[1] // 2) + + +def test_noise_reduce(iname, numIMG=5): + imgs = iname + imgr = None + original = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + if target is None: + raise AttributeError("File {0} not found".format(iname)) + if i == 1: + imgr = np.uint16(target) + original = target + else: + imgr = imgr + target + return imgr / numIMG, original + + +def img_add(dest, src): + """Destructive!""" + row, col = dest.shape + for i in range(row): + for j in range(col): + dest[i][j] += src[i][j] + + +FM = FastDataMatrix2D + + +def folder_to_imgs(img_name_scheme, num_sample): + """This function takes img files and return cv imgs""" + return [cv2.imread(img_name_scheme.format(i)) for i in range(1, num_sample + 1)] + + +# The image taken is flipped horizontally, result x should be img.shape[1] - x +# The image sometimes has two peaks, try experimenting with different gaussian kernels +def center_detect(img_name_scheme, num_sample, sample_int=50, gk=9, ks=-1, m=0, p=20, + b=1, c=0): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # ------------------------------------------------------------ + # Parameter Setting + METHODS = {0: gaussian_fitting, 1: poly_fitting, 2: edge_centroid, + 3: zero_crossing, 4: edge_converge_base, 5: edge_converge_extreme} + edge_method = METHODS[m] + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + # ------------------------------------------------------------ + # Gathering Data + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + if m < 3: + ec_x = edge_method(data_x, FM(img, FM.HOR, nr), p) + else: + ec_x = edge_method(data_x) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, ec_x)) + + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + if m < 3: + ec_y = edge_method(data_y, FM(img, FM.VER, nc), p) + else: + ec_y = edge_method(data_y) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, ec_y)) + len_hs = len(hs) + len_vs = len(vs) + # ------------------------------------------------------------ + # --------------- PRE-CHECK DATA VALUES ---------------------- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + x_valid = False + y_valid = False + # OUTLIER DETECTION TODO: OPTIMIZE, THIS IS NAIVE + if len_hs >= r_thresh: + x_valid = True + hys, hxs = reg_pre_debias(hys, hxs) + line_a = HoughLine(x=hxs, data=hys) + if len_vs >= c_thresh: + y_valid = True + vxs, vys = reg_pre_debias(vxs, vys) + line_b = HoughLine(x=vxs, data=vys) + # ------------------------------------------------------------ + # ----- Following Modules Handles Hough Line Drawing --------- + # ------------------------------------------------------------ + # DATA RECORDING AND PROCESSING + if c == 1: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + else: + if x_valid and y_valid: + center_x, center_y = HoughLine.intersect(line_a, line_b) + else: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + # --------------------------------------------------------- + return center_x, center_y + + + +def convergence_test_final(folder, ns): + offset = '../' + convergence = {} + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + # print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + msepv = sqrt(pv / pvs) + cvg = {'PicConsistency': msepv} + convergence[m] = cvg + variations.append(msepv) + print(convergence) + fwrite.close() + +if __name__ == '__main__': + convergence_test_final('calib4/', 'img_{0}') + +#print(center_detect('../calib4/img_59_{0}.png', 5)) + diff --git a/Nov_27/Full/Camera/img_rec_module/sig_proc_test.py b/Nov_27/Full/Camera/img_rec_module/sig_proc_test.py new file mode 100644 index 0000000..459fec9 --- /dev/null +++ b/Nov_27/Full/Camera/img_rec_module/sig_proc_test.py @@ -0,0 +1,2371 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from scipy.optimize import curve_fit +#from img_rec_module import img_rec +from random import randint +import os +import csv +from datetime import datetime +from math import atan, sqrt, tan, radians, acos, asin, degrees, sin, cos + + +""" =================================== +========== ANALYTIC GEOMETRY ========== +======================================= """ + + +class Line: + + inf = float('inf') + + def __init__(self, a=inf, b=inf, p1=None, p2=None, data=None): + if p1 and p2: + self.point(p1, p2) + elif data: + self.reg(data) + else: + self.a = a + self.b = b + + def reg(self, data): + D = np.array([[d[0], 1] for d in data]) + y = np.array([d[1] for d in data]) + self.a, self.b = leastSquares(D, y) + + def point(self, p1, p2): + self.a = 1 + + @staticmethod + def intersect(l1, l2): + x = (l2.b - l1.b) / (l1.a - l2.a) + y = l1.a * x + l1.b + return x, y + + +class HoughLine: + + def __init__(self, rho_rad=0, theta=0, x=None, data=None): + if data is not None and x is not None: + self.reg(x, data) + else: + self._r = degrees(rho_rad) + self._t = theta + self._s = sin(rho_rad) + self._c = cos(rho_rad) + + def reg(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + x1, x2 = x[0], x[-1] + y1, y2 = data[0], data[-1] + theta0 = theta_pred(x1, y1, x2, y2) + #print(degrees(theta0)) + p0 = [theta0, x1 * cos(theta0) + y1 * sin(theta0)] + pm, vm = curve_fit(hough_line, x, data, p0=p0) + #data_pred = hough_line(x, *pm) + #print('PRED', data_pred) + #res = data_pred - data + #print("RES", res) + #stderr = np.linalg.norm(res, 2) + #print("ERR", stderr) + #rankerr = res / stderr + #print("Z", rankerr) + if pm[1] < 0: + pm[1] = -pm[1] + pm[0] -= HC + #pm[0] = 2 * np.pi + angle = normalize_angle(pm[0]) + self._t = angle + self._r = pm[1] + self._s = sin(angle) + self._c = cos(angle) + + def extract_points(self, x_input): + x1 = int(x_input[0]) + x2 = int(x_input[-1]) + y1 = int(self.fit_x(x1)) + y2 = int(self.fit_x(x2)) + return (x1, y1), (x2, y2) + + def fit_x(self, x): + #print(self._r, self._t) + return (self._r - x * self._c) / self._s + + def __str__(self): + return 'hough line with cos:{0}, sin:{1}, rho:{2}, theta:{3}'.format(self._c, self._s, + self._r, degrees(self._t)) + + @staticmethod + def intersect(l1, l2): + x = (l2._r / l2._s - l1._r / l1._s) / (l2._c / l2._s - l1._c / l1._s) + y = l1.fit_x(x) + return x, y + + +# QC: QUARTER_CYCLE, HC: HALF_CYCLE, TQC: THIRD_QUARTER_CYCLE, FC: FULL_CYCLE +QC = np.pi / 2 +HC = np.pi +TQC = 3 * np.pi / 2 +FC = 2 * np.pi + + +def angle_interp(s, c): + if c == 1.0: + return 0 + elif s == 1.0: + return np.pi / 2 + elif c == -1.0: + return np.pi + elif s == -1.0: + return np.pi * 3 / 2 + elif c < 0 < s: + return acos(c) + elif s < 0 and c < 0: + return 2 * np.pi - acos(c) + elif s < 0 < c: + return asin(s) + 2 * np.pi + else: + return asin(s) + + +def normalize_angle(angle): + res = angle - (angle // FC) * FC + return res + """ + if QC < res < HC: + return res + HC + elif HC <= res <= TQC: + return res - HC + else: + return res""" + + +def theta_pred(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + angle = sin_angle_from_points(dx, dy) + if dx * dy <= 0: + return np.pi / 2 - angle + else: + root = root_finding(x1, x2, y1, y2) + if root < 0: + return np.pi / 2 + angle + else: + return angle + 3 * np.pi / 2 + + +def sin_angle_from_points(dx, dy): + return asin(abs(dy) / sqrt(dx ** 2 + dy ** 2)) + + +def poly_curve(params, x_input): + # params contains the coefficients that multiply the polynomial terms, in degree of lowest degree to highest degree + degree = len(params) - 1 + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = x * 0 + + for k in range(0, degree + 1): + coeff = params[k] + y = y + list(map(lambda z: coeff * z ** k, x)) + return x, y + + +def gauss_2d(x, y, a, b1, c_s1, b2, c_s2): + return a * np.exp(- ((x - b1) ** 2 / (2 * c_s1) + (y - b2) ** 2) / (2 * c_s2)) + + +def gauss_hat(x, a, b, c_s): + return a * np.exp(- (x - b) ** 2 / (2 * c_s)) + + +def gaussian_curve(x_input, a, b, c_s): + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = a * np.exp(- (x - b) ** 2 / (2 * c_s)) + return x, y + + +def hough_line(x, theta, rho): + return (rho - x * cos(theta)) / sin(theta) + + +""" =================================== +========== MATRIX-ARRAY UTIL ========== +======================================= """ + + +class FastDataMatrix2D: + # TODO: HANDLE THE CASE WHEN IT WRAPS 1D + + HOR = 1 + VER = 0 + + def __init__(self, data, ax, index): + self._data = data + self._ax = ax + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + self.itr = 0 + self.initialize() + + def segmentize(self, start, end): + assert 0 <= start < end <= self._data.shape[self._ax], "start: {0}, end: {1}, ax: {2}, index: {3}".format(start, end, self._ax, self._index) + self.start = start + self.end = end + + def initialize(self): + self.segmentize(0, self._data.shape[self._ax]) + + def irange(self): + # index range of the fast matrix array + return self._data.shape[1 - self._ax] + + def set_axis(self, ax): + """USE copy when trying to switch axis and index""" + self._ax = ax + if self._index >= self.irange(): + raise IndexError("Old index {0} is too large for the new axis".format(self._index)) + self.initialize() + + def set_index(self, index): + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, self._ax, index) + self._index = index + + def extract_array(self): + """Optimize later for better performance""" + arr = self._data[self._index, self.start:self.end] if self._ax == FastDataMatrix2D.HOR \ + else self._data[self.start:self.end, self._index] + return np.array(arr) + + def copy(self, ax=None, index=None): + if ax is not None and index is not None: + return FastDataMatrix2D(self._data, ax, index) + else: + return FastDataMatrix2D(self._data, self._ax, self._index) + + def __iter__(self): + raise RuntimeError("You need the ITER method!") + + def __next__(self): + raise RuntimeError("You need the NEXT method!") + + def __getitem__(self, item): + return self._data[self._index, item + self.start] if self._ax == FastDataMatrix2D.HOR \ + else self._data[item + self.start, self._index] + + def __setitem__(self, key, value): + if self._ax == FastDataMatrix2D.HOR: + self._data[self._index, key + self.start] = value + else: + self._data[key + self.start, self._index] = value + + def __len__(self): + return self.end - self.start + + +""" =================================== +=========== REGRESSION UTILS ========== +======================================= """ + + +# Generic Regression Tools 128-133 +def leastSquares(D, y): + return np.linalg.lstsq(D, y, rcond=None)[0] + + +def MSE(y, y_hat, N): + return np.linalg.norm(y - y_hat) ** 2 / N + + +def std_dev(data): + std_dev = 0 + len_data = len(data) + mean = sum(data) / len_data + for i in range(len_data): + std_dev += (data[i] - mean) ** 2 + return sqrt(std_dev / len_data) + + +def reg_pre_debias(ind, data): + sd = np.std(data) + miu = np.mean(data) + debiased_data = [] + debiased_ind = [] + for i in range(len(data)): + dev = abs((data[i] - miu) / sd) + if dev < 2: + debiased_data.append(data[i]) + debiased_ind.append(ind[i]) + return debiased_ind, debiased_data + + +# Polynomial Regression Tools 137-171 +def poly_data_matrix(input_data, degree): + # degree is the degree of the polynomial you plan to fit the data with + Data = np.zeros((len(input_data), degree + 1)) + + for k in range(0, degree + 1): + Data[:, k] = (list(map(lambda x: x ** k, input_data))) + + return Data + + +def poly_error(params, D_a, y_a): + '''degree=len(params)-1 + y=x_a*0 + + for k in range(0,degree+1): + coeff=params[k] + y=y+list(map(lambda z:coeff*z**k,x_a))''' + y = np.dot(D_a, params) + return np.linalg.norm(y - y_a) ** 2 + + +def improvedCost(x, y, x_test, y_test, start, end): + """Given a set of x and y points training points, + this function calculates polynomial approximations of varying + degrees from start to end. Then it returns the cost, with + the polynomial tested on test points of each degree in an array""" + c = [] + degrees = range(start, end) + ps = [] + for degree in degrees: + # YOUR CODE HERE + D = poly_data_matrix(x, degree) + p = leastSquares(D, y) + ps.append(p) + D_t = poly_data_matrix(x_test, degree) + y_hat = np.dot(D_t, p) + c.append(MSE(y_test, y_hat, len(x_test))) + return np.array(degrees), ps, np.array(c) + + +# Gaussian Regression Tools 184-210 +def gauss_data_matrix(data): + return np.array([[1, x ** 2, x, 1] for x in data]) + + +def gauss_reg(x, y, p0): + """Given a set of x and y training points, this function + calculates the gaussian approximation function""" + """skip_x = np.array([x[i] for i in range(len(y)) if y[i] != 0]) + y_prime = np.array([y[i] for i in range(len(y)) if y[i] != 0]) + logy = np.log(y_prime) + + sol = leastSquares(gauss_data_matrix(skip_x), logy) + alp, bet, gam, lam = sol + a = np.e ** alp + c_s = - 1 / (2 * bet) + b = gam * c_s + maxi, mini = max_min(y) + pred = gauss_hat(maxi, a, b, c_s) + real = y[maxi] + a = real / pred // 1000000000 * 10""" + #timeb = datetime.now() + param, vm = curve_fit(gauss_hat, x, y, p0=p0) + #timea = datetime.now() + #print(timea - timeb) + return param + + +def gauss_mat(shape, a, b1, c_s1, b2, c_s2): + mat = np.zeros(shape) + for r in range(mat.shape[0]): + for c in range(mat.shape[1]): + mat[r, c] = gauss_2d(c, r, a, b1, c_s1, b2, c_s2) + + return mat + + +# Hough Transform Regression Tools +def hough_data_matrix(x, y): + dim = len(x) + mat = np.full((dim, 3), -1.0) + for i in range(dim): + mat[i][0] = x[i] + mat[i][1] = y[i] + return mat + + +""" ======================================= +========= EDGE DETECTION UTILS ============ +=========================================== """ + + +# Generic Helper +def max_min(data): + # Returns the maximum and minimum for the data + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + return max_ind, min_ind + + +def edge_max_min(data): + # Returns a *safe* edge maxi, mini for the data + # TODO: OPTIMIZE THE WIDTH AND VALUE THRESHOLD + width_thres = 90 + value_thres = 20 + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + maxi, mini = max_ind, min_ind + assert data[maxi] >= value_thres and mini - maxi <= width_thres and maxi < mini + return maxi, mini + + +def min_max(data, max, min): + """ Converts the data to min max space. """ + g_diff = max - min + return [(d - min) / g_diff for d in data] + + +def root_finding(x1, x2, y1, y2): + """Given two points on a line, finds its zero crossing root.""" + return - y1 * (x2 - x1) / (y2 - y1) + x1 + + +def check_cross(a, b): + # Checks whether two points are of opposite signs + return a * b < 0 + + +def round_up(num): + down = int(num) + if num - down > 0: + return num + 1 + else: + return num + + +def smart_interval(start, end, data): + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + return start, end + + +def edge_preprocess(data, padding): + maxi, mini = edge_max_min(data) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end + + +# ZERO CROSSING (PEAK FINDING) +def zero_crossing(data): + # Yields the center with zero-crossing method + maxi, mini = max_min(data) + cross = -1 + cross_count = 0 + for j in range(maxi, mini): + y1 = data[j] + x2 = j + 1 + y2 = data[x2] + if check_cross(y1, y2): + cross = root_finding(j, x2, y1, y2) # change to function later + cross_count += 1 + return -1 if cross_count > 1 else cross + + +# AVERAGE METHOD FOR EDGE CENTER FINDING +def edge_converge_base(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + else: + return (maxi + mini) / 2 + + +# PSEUDO EDGE (closest noise gradient change) CENTER FINDING +def edge_converge_extreme(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + emax = -1 + emin = -1 + maxflag = True + minflag = True + cmax = maxi + cmin = mini + while cmax > 0 and cmin < len(data) - 1 and (maxflag or minflag): + max2 = cmax - 1 + maxy1, maxy2 = data[cmax], data[max2] + min2 = cmin + 1 + miny1, miny2 = data[cmin], data[min2] + if check_cross(maxy1, maxy2) and maxflag: + emax = root_finding(cmax, max2, maxy1, maxy2) + maxflag = False + if check_cross(miny1, miny2) and minflag: + emin = root_finding(cmin, min2, miny1, miny2) + minflag = False + if maxflag: + cmax -= 1 + if minflag: + cmin += 1 + return -1 if (emax == -1 or emin == -1) else (emax + emin) / 2 + + +def extract_extrema(data): + len_data = len(data) + mean = sum(data) / len_data + std_dev = 0 + for x in data: + std_dev += (x - mean) ** 2 + std_dev = sqrt(std_dev / len_data) + signifmax = [] + signifmin = [] + coeff = 3 + for i, x in enumerate(data): + diff = (x - mean) / std_dev + if diff >= coeff: + signifmax.append(i) + elif diff <= -coeff: + signifmin.append(i) + return signifmax, signifmin + + +# CENTROID METHOD FOR EDGE CENTER FINDING +def edge_centroid(data, img_data, padding=10): + # With Gaussian Blur might achieve the best performance + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + isums = 0 + total = 0 + for i in range(start, end): + isums += img_data[i] * i + total += img_data[i] + return isums / total if total else -1 + + +def centroid_seg(data, start, end): + """ Given a segment (start, end) of the data, + find the centroid. """ + isums = 0 + total = 0 + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + for i in range(start, end): + isums += data[i] * i + total += data[i] + return isums / total if total else -1 + + +# POLYNOMIAL FITTING +def poly_fitting(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + y = np.array(img_data[start:end]) + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + curve_x, curve_y = poly_curve(param, x) + center_id = np.argmax(curve_y) + return curve_x[center_id] + + +def poly_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + 1 + start, end = smart_interval(start, end, data) + if start > end: + try: + print(maxi, mini, img_data._ax, start, end) + except: + print("else", maxi, mini, start, end) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + y = np.array(img_data[start:end]) + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + return param, x + + +DEGREES = {} + + +def degree_register(elem): + if elem in DEGREES: + DEGREES[elem] += 1 + else: + DEGREES[elem] = 1 + + +# GAUSSIAN FITTING +def gaussian_fitting(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + try: + maxi, mini = edge_max_min(data) + except AssertionError: + return -1 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.array(img_data[start:end]) + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +def gaussian_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 # TODO: CONSOLIDATE THIS VALUE + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + start, end = smart_interval(start, end, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.array(img_data[start:end]) + return gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]), x + + +"""====================================== +======== IMAGE PROCESSING UTIL ========== +========================================= """ + + +def gauss_bg_deduce(x, img_data): + # TODO: OPTIMIZE PERFORMANCE + idata = img_data.extract_array() + p0 = [1, len(img_data) / 2, std_dev(idata)] + a, b, c_s = gauss_reg(x, idata, p0=p0) + rem_gauss = gauss_hat(x, a, b, c_s) + new_y = idata - rem_gauss + return x, rem_gauss, new_y + + +def sobel_process(imgr, gks, sig): + gksize = (gks, gks) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(imgr.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + return img, sobelx, sobely + + +def test_canny_detect(): + imgn = "img_89_{0}.png" + IMGDIR = "../calib4/" + NAME = IMGDIR + imgn + + while True: + lowp = input("Type the Lower Bound or c to cancel: ") + if lowp == 'c': + break + while True: + try: + low = int(lowp) + break + except ValueError: + lowp = input("Bad input Try again! ") + highp = input("Type the Upper Bound or c to cancel: ") + if highp == 'c': + break + while True: + try: + high = int(highp) + break + except ValueError: + highp = input("Bad input Try again! ") + + denoised, original = test_noise_reduce(NAME) + print(get_center_val(denoised)) + NL_denoised = cv2.fastNlMeansDenoising(original) + bdenoise = test_blur_then_nr(NAME) + + dblur, sobelx, sobely = sobel_process(denoised, 9, 0) + nldblur = sobel_process(NL_denoised, 9, 0)[0] + pblur, sobelx, sobely = sobel_process(original, 9, 0) + + de_edges = canny_detect(denoised, low, high) + db_edges = canny_detect(dblur, low, high) + nld_edges = canny_detect(nldblur, low, high) + blur_denoise = canny_detect(bdenoise, low, high) + blur_edges = canny_detect(pblur, low, high) + #edge_detect_expr(db_edges, original) + """compare_images((imgr, 'Original'), (edges, 'Canny Edge'), + (sobelx, 'Sobel X'), (sobely, 'Sobel Y'))""" + compare_images((original, 'Original'), (NL_denoised, "NLMEANS"), (de_edges, 'DENOISE Edges'), + (blur_edges, 'Plain Blur Edges'), (denoised, 'Denoised'), (nld_edges, 'NIDE-BLUR Edges'), + (db_edges, 'DE-BLUR Edges'), (blur_denoise, "BDENOISE Edges"), color_map='gray') + + +def canny_detect(src, low=4, high=10): + return cv2.Canny(np.uint8(src), 4, 10, L2gradient=True) + + +def extract_verge(edges, i, j, max_blank, dir, axis): + """ + :param edges: img MAT resulting from canny edge procedure + :param i: starting row i + :param j: starting col j + :param max_blank: maximum number of blanks to rule out the existence of a verge outside of the current verge (in which case would be a fake verge) + :param dir: Directions of movement, 1 for right or down, -1 for left or up + :param axis: + :return: (r, c) index of the verge on the given 'axis' in the given 'dir' from the starting point (i, j) + """ + + +def significance_test(data, val): + """Outputs whether the maximum or minimum value is a significant value.""" + return val in extract_extrema(data)[0] or val in extract_extrema(data)[1] + + +def edge_detect_expr(edges, original): + """ + TODO: 1. SIMPLE Approach: pairwise mask over original image, then compute total + 2. Traverse the image to mark the image. + """ + se = 0 + row_sum = 0 + col_sum = 0 + tot_sum = 0 + for i in range(edges.shape[0]): + for j in range(edges.shape[1]): + if edges[i][j] > 0: + row_sum += i * original[i][j] + col_sum += j * original[i][j] + tot_sum += original[i][j] + se += 1 + print(se) + if tot_sum != 0: + print(row_sum / tot_sum) + print(col_sum / tot_sum) + + +def hori(img, i, j, d): + dest = j + d + if dest < 0 or dest >= img.shape[1]: + return img.item(i, j) + return img.item(i, dest) + + +def verti(img, i, j, d): + dest = i + d + if dest < 0 or dest >= img.shape[0]: + return img.item(i, j) + return img.item(dest, j) + + +def test_blur_then_nr(iname): + imgs = iname + numIMG = 5 + imgr = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + target = cv2.GaussianBlur(target, (9, 9), 0) + if i == 1: + imgr = np.uint16(target) + else: + imgr = imgr + target + return imgr / numIMG + + +def get_center_val(img): + return img.item(img.shape[0] // 2, img.shape[1] // 2) + + +def test_noise_reduce(iname, numIMG=5): + imgs = iname + imgr = None + original = None + for i in range(1, numIMG+1): + target = cv2.imread(imgs.format(i), 0) + if target is None: + raise AttributeError("File {0} not found".format(iname)) + if i == 1: + imgr = np.uint16(target) + original = target + else: + imgr = imgr + target + return imgr / numIMG, original + + +def img_add(dest, src): + """Destructive!""" + row, col = dest.shape + for i in range(row): + for j in range(col): + dest[i][j] += src[i][j] + + +""" =================================== + ============ PLOTTING ============= + ============= HELPER ============== + =================================== """ + + +def quick_plot(data, xs=None): + plt.figure() + if xs: + plt.plot(xs, data, 'bo-') + else: + plt.plot(data, 'bo-') + plt.show() + plt.close() + + +def compare_images(*args, ilist=None, color_map=None): + # Takes in a sequence of IMG(Gray) and TITLE pairs and plot them side by side + if ilist: + args = ilist + graph_amount = len(args) + row = int(sqrt(graph_amount)) + col = round_up(float(graph_amount) / row) + plt.figure(figsize=(16, 8)) + for i, pair in enumerate(args): + plt.subplot(row, col, i+1) + if color_map: + plt.imshow(pair[0], cmap=color_map) + plt.xticks([]), plt.yticks([]) + plt.title(pair[1]) + plt.show() + + +def compare_data_plots(*args, ilist=None, suptitle=None): + # Takes in a sequence of tuples with data, xs, and title pairs + if ilist: + args = ilist + graph_amount = len(args) + row = int(sqrt(graph_amount)) + col = round_up(float(graph_amount) / row) + plt.figure(figsize=(16, 8)) + if suptitle: + plt.suptitle(suptitle, fontsize=14) + for i, pair in enumerate(args): + plt.subplot(row, col, i + 1) + if len(pair) == 2: + plt.plot(pair[0], 'bo-') + plt.title(pair[1]) + else: + plt.plot(pair[1], pair[0], 'bo-') + plt.title(pair[2]) + plt.show() + + +def line_graph_contrast(img, xs, ys): + line = HoughLine(x=xs, data=ys) + #print(xs) + x0 = line._c * line._r + y0 = line._s * line._r + + print('x0:{0}, y0:{1}, cos:{2}, sin:{3}, rho:{4}, theta:{5}'.format(x0, y0, line._c, line._s, line._r, degrees(line._t))) + x1 = int(x0 + 1000 * (-line._s)) + y1 = int(y0 + 1000 * (line._c)) + x2 = int(x0 - 1000 * (-line._s)) + y2 = int(y0 - 1000 * (line._c)) + p1, p2 = (x1, y1), (x2, y2) + cv2.line(img, p1, p2, (255, 0, 0), 1) + return p1, p2, line + + +""" =================================== + ====== DATA RECORDING HELPER ====== + =================================== """ + +# 1. Try Noise Reduction: +# ---- 1.1 Reduction By Averaging, without FastNIMEANS ~~ GOOD +# ---- 1.2 Reduction By FastNIMEANS ~~ INFERIOR +# ---- 1.3 Reduction By Combination ~~ INFERIOR +# ---- 1 NOTE: USE PLOTTING OF ORIGINAL GRAPH TO SEE RESULT +# 2. Try Di-Axial Scharr Kernel +# ---- 2.1 Add To Name Scheme, record graphs and compare them +# ---- 2 NOTE: GRAPH TO SAVE: 4-CONTRAST, TRANSITION PLOTS +# 3. Optimizing Data Processing: +# ---- 3.1 Marking point as edge maxima and minima according to STD Dev values +# ---- 3.2 Taking Sequential Samples +# ---- 3.3 Explore Thresholding Techniques + + +def register(img): + lval = [] + for i in range(img.shape[0]): + for j in range(img.shape[1]): + if img.item(i, j) > 250: + lval.append((i, j, img.item(i, j))) + print(lval) + + +""" TEST GAUSSIAN BLUR'S influence on noise distribution: + Method: + 1. Preliminary + 1. Generate a random noise matrix with n * n, change shape to a vector + 2. Gaussian blur applied, change shape to a vector + 3. Compare noise level + 2. Secondary + 1. Generate a Gaussian / Cosine Matrix and add random noise matrix + 2. Gaussian blur applied + 3. Compare a randomly selected row of each one +""" + + +def test_old(): + # SETTINGS + imgn = "img_4_{0}" + IMGDIR = "../new_test/" + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS+imgn + "/" + #imgr = cv2.imread(IMGDIR + imgn + ".png") + imgr, ori = test_noise_reduce(IMGDIR + imgn + ".png") + dimc = imgr.shape[1] + dimr = imgr.shape[0] + r_int = dimr // 2 + c_int = dimc // 2 + start = 7 + end = 10 + sig = 0 + ins = range(start, end, 2) + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + + # INITIALIZATION + cenvalsx = [] + cenvalsy = [] + edgvalsx = [] + edgvalsy = [] + ebvalsx = [] + ebvalsy = [] + ecvalsx = [] + ecvalsy = [] + ecbvalsx = [] + ecbvalsy = [] + #cv2.imshow("denoised", np.uint8(imgr)) # REMOVES TO SHOW IMAGE + x = np.array(range(dimc)) + x2 = np.array(range(dimr)) + + for i in ins: + # INITIALIZATION + gksize = (i, i) + sigmaX = sig + blur = cv2.GaussianBlur(imgr,gksize,sigmaX) + #cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + """kernel = np.array([[-1, -1, -1], + [-1, 8, -1], + [-1, -1, -1]]) + kerneled = cv2.filter2D(img, -1, kernel) + cv2.imshow("kerneled", kerneled)""" # KERNEL EXPERIMENT + #laplacian = cv2.Laplacian(img,cv2.CV_64F) # LAPLACIAN FILTERING + """plt.subplot(2,2,1),plt.imshow(cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY),cmap = 'gray') + plt.title('Original'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,2),plt.imshow(img,cmap = 'gray') + plt.title('Gaussian Filter'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') + plt.title('Scharr X'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') + plt.title('Scharr Y'), plt.xticks([]), plt.yticks([])""" + #plt.savefig(NAME_HEADER + "filters.png") + #plt.savefig(NAME_HEADER + "2D_filters.png") + #plt.close() # REMOVES TO SHOW CONTRAST OF FILTERS + + + # DETECTION INIT + gk_setting = "ksize:{0}, sigmax:{1}".format(gksize, sigmaX) + y_s_x = np.array([sobelx.item(r_int, c) for c in x]) + y_s_y = np.array([sobely.item(r, c_int) for r in x2]) + imgx = [imgr.item(r_int, c) for c in x] + imgy = [imgr.item(r, c_int) for r in x2] + blurimgx = [img.item(r_int, c) for c in x] + blurimgy = [img.item(r, c_int) for r in x2] + print(gk_setting) + print(extract_extrema(y_s_x)) + print(extract_extrema(y_s_y)) + fwrite.write(gk_setting) + fwrite.write('\n') + + # EDGE DETECTION + zx = zero_crossing(y_s_x) + cenvalsx.append(zx) + ex = edge_converge_extreme(y_s_x) + edgvalsx.append(ex) + ebx = edge_converge_base(y_s_x) + ebvalsx.append(ebx) + ecx = edge_centroid(y_s_x, imgx) + ecvalsx.append(ecx) + ecbx = edge_centroid(y_s_x, blurimgx) + ecbvalsx.append(ecbx) + + zy = zero_crossing(y_s_y) + cenvalsy.append(zy) + ey = edge_converge_extreme(y_s_y) + edgvalsy.append(ey) + eby = edge_converge_base(y_s_y) + ebvalsy.append(eby) + ecy = edge_centroid(y_s_y, imgy) + ecvalsy.append(ecy) + ecby = edge_centroid(y_s_y, blurimgy) + ecbvalsy.append(ecby) + + # DATA RECORDING + fwrite.write("x: zero_crossing: {0}, edge_converge: {1}; ".format(zx, ex)) + fwrite.write('\n') + fwrite.write("y: zero_crossing: {0}, edge_converge: {1}\n".format(zy, ey)) + + # GK_PLOT + """if i == 9: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + #plt.savefig(NAME_HEADER + "_" + gk_setting + ".png")""" + + #if i >= 13: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + plt.show() + # plt.savefig(NAME_HEADER + "_" + gk_setting + ".png") # UNCOMMENT WHEN SAVING PLOTS + + # USING MIN-MAX + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(221) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(222) + plt.plot(min_max(y_s_x, max(y_s_x), min(y_s_x)), 'b-') + plt.subplot(223) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + plt.xlabel("Plain") + plt.subplot(224) + plt.plot(min_max(y_s_y, max(y_s_y), min(y_s_y)), 'b-') + plt.xlabel("MINMAX") + plt.show() + + + fig = plt.figure(figsize=(16, 8)) + plt.subplot(2, 1, 1) + #plt.plot(ins, cenvalsx, 'b-', ins, edgvalsx, 'r-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + #plt.legend(['zero crossing', 'edge_converging_extreme', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + #plt.plot(ins, cenvalsx, 'b-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + #plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'],loc="lower left") + plt.plot(ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'],loc="lower left") + plt.ylabel("x_meas") + plt.subplot(2, 1, 2) + #plt.plot(ins, cenvalsy, 'b-', ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + #plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.plot(ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.ylabel("y_meas") + plt.xlabel("kernel size") + plt.show() + #fig.savefig(plot_save) + #plt.savefig(plot_save) + + +def test_interactive(): + # TODO: TEST OUT FACET MODEL AND CONDITIONAL CONVOLUTIONAL KERNEL + # SETTINGS + while True: + number = input("type the picture number u wanna test or c to cancel: ") + if number == 'c': + break + imgn = "img_%d_{0}" % int(number) + print(imgn) + IMGDIR = "../testpic/" + IMGDIR = "../calib4/" + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS + imgn + "/" + # imgr = cv2.imread(IMGDIR + imgn + ".png") + + imgr, ori = test_noise_reduce(IMGDIR + imgn + ".png", numIMG=5) + dimc = imgr.shape[1] + dimr = imgr.shape[0] + r_prompt = input("Type in the index for horizontal slice: (range: [0, {0}]) ".format(dimr - 1)) #dimr // 2 + c_prompt = input("Type in the index for vertical slice: (range: [0, {0}]) ".format(dimc - 1)) #dimc // 2 + while True: + try: + r_int = int(r_prompt) + assert 0 <= r_int < dimr + break + except ValueError: + r_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + except AssertionError: + r_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimr - 1)) + while True: + try: + c_int = int(c_prompt) + assert 0 <= c_int < dimc + break + except ValueError: + c_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + except AssertionError: + c_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + #start = 7 + #end = 10 + sig = 0 + gk = 9 + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + # INITIALIZATION + # cv2.imshow("denoised", np.uint8(imgr)) # REMOVES TO SHOW IMAGE + #x = np.array(range(dimc)) + #x2 = np.array(range(dimr)) + + # INITIALIZATION + gksize = (gk, gk) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + """kernel = np.array([[-1, -1, -1], + [-1, 8, -1], + [-1, -1, -1]]) + kerneled = cv2.filter2D(img, -1, kernel) + cv2.imshow("kerneled", kerneled)""" # KERNEL EXPERIMENT + # laplacian = cv2.Laplacian(img,cv2.CV_64F) # LAPLACIAN FILTERING + """plt.subplot(2,2,1),plt.imshow(cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY),cmap = 'gray') + plt.title('Original'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,2),plt.imshow(img,cmap = 'gray') + plt.title('Gaussian Filter'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') + plt.title('Scharr X'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') + plt.title('Scharr Y'), plt.xticks([]), plt.yticks([])""" + # plt.savefig(NAME_HEADER + "filters.png") + # plt.savefig(NAME_HEADER + "2D_filters.png") + # plt.close() # REMOVES TO SHOW CONTRAST OF FILTERS + + + # DETECTION INIT + xh = np.array(range(dimc)) + xv = np.array(range(dimr)) + zeroh = np.zeros(dimc) + zerov = np.zeros(dimr) + y_s_x = FM(sobelx, FM.HOR, r_int) + y_s_y = FM(sobely, FM.VER, c_int) + imgx = FM(imgr, FM.HOR, r_int) + imgy = FM(imgr, FM.VER, c_int) + blurimgx = FM(img, FM.HOR, r_int) + blurimgy = FM(img, FM.VER, c_int) + gx, bgx, deducedx = gauss_bg_deduce(xh, imgx) + gy, bgy, deducedy = gauss_bg_deduce(xv, imgy) + + #print(extract_extrema(y_s_x)) + #print(extract_extrema(y_s_y)) + + # EDGE DETECTION + zx = zero_crossing(y_s_x) + ex = edge_converge_extreme(y_s_x) + ebx = edge_converge_base(y_s_x) + ecbx = edge_centroid(y_s_x, blurimgx) + ecx = edge_centroid(y_s_x, imgx) + try: + #paramhp, xp1 = poly_fitting_params(y_s_x, deducedx) + #paramhg, xg1 = gaussian_fitting_params(y_s_x, deducedx) + paramhp, xp1 = poly_fitting_params(y_s_x, imgx) + paramhg, xg1 = gaussian_fitting_params(y_s_x, imgx) + xp_h_plot, yp_h_plot = poly_curve(paramhp, xp1) + xg_h_plot, yg_h_plot = gaussian_curve(xg1, paramhg[0], paramhg[1], paramhg[2]) + except AssertionError: + print("No image data for horizontal slice!") + xp_h_plot, yp_h_plot = xh, zeroh + xg_h_plot, yg_h_plot = xh, zeroh + + px, gx = xp_h_plot[np.argmax(yp_h_plot)], xg_h_plot[np.argmax(yg_h_plot)] + print("edge: {0}, poly:{1}, gaussian:{2}".format(ecx, px, gx)) + + zy = zero_crossing(y_s_y) + ey = edge_converge_extreme(y_s_y) + eby = edge_converge_base(y_s_y) + ecby = edge_centroid(y_s_y, blurimgy) + ecy = edge_centroid(y_s_y, imgy) + try: + paramvp, xp2 = poly_fitting_params(y_s_y, imgy) + paramvg, xg2 = gaussian_fitting_params(y_s_y, imgy) + xp_v_plot, yp_v_plot = poly_curve(paramvp, xp2) + xg_v_plot, yg_v_plot = gaussian_curve(xg2, paramvg[0], paramvg[1], paramvg[2]) + except AssertionError: + print("No image data for vertical slice!") + xp_v_plot, yp_v_plot = xv, zerov + xg_v_plot, yg_v_plot = xv, zerov + py, gy = xp_v_plot[np.argmax(yp_v_plot)], xg_v_plot[np.argmax(yg_v_plot)] + print("edge: {0} poly:{1}, gaussian:{2}".format(ecy, py, gy)) + + + # DATA RECORDING + fwrite.write("x: edge_centroid: {0}, poly: {1}, gaussian: {2}; ".format(ecx, px, gx)) + fwrite.write('\n') + fwrite.write("y: edge_centroid: {0}, poly: {1}, gaussian: {2}\n".format(ecy, py, gy)) + + # GK_PLOT + """if i == 9: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + #plt.savefig(NAME_HEADER + "_" + gk_setting + ".png")""" + + # if i >= 13: + fig = plt.figure(figsize=(16, 8)) + plt.subplot(211) + imgx.initialize() + plt.plot(xh, imgx.extract_array(), 'b-', xh, bgx, 'm-', xh, deducedx, 'c-', xp_h_plot, yp_h_plot, 'g-', xg_h_plot, yg_h_plot, 'r-') + plt.ylabel("Horizontal Slice, ECX: {0}".format(ecx)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.subplot(212) + imgy.initialize() + plt.plot(xv, imgy.extract_array(), 'b-', xv, bgy, 'm-', xv, deducedy, 'c-', xp_v_plot, yp_v_plot, 'g-', xg_v_plot, yg_v_plot, 'r-') + plt.ylabel("Vertical Slice, ECY: {0}".format(ecy)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.show() + # plt.savefig(NAME_HEADER + "_" + gk_setting + ".png") # UNCOMMENT WHEN SAVING PLOTS + + """fig = plt.figure(figsize=(16, 8)) + plt.subplot(2, 1, 1)""" + # plt.plot(ins, cenvalsx, 'b-', ins, edgvalsx, 'r-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + # plt.legend(['zero crossing', 'edge_converging_extreme', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + # plt.plot(ins, cenvalsx, 'b-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + # plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'],loc="lower left") + """plt.plot(ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.ylabel("x_meas") + plt.subplot(2, 1, 2) + # plt.plot(ins, cenvalsy, 'b-', ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + # plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.plot(ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.ylabel("y_meas") + plt.xlabel("kernel size") + plt.show() + # fig.savefig(plot_save) + # plt.savefig(plot_save)""" + + +def test(folder, imgn): + # TODO: TEST OUT FACET MODEL AND CONDITIONAL CONVOLUTIONAL KERNEL + # SETTINGS + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS + imgn[:-4] + "/" + # imgr = cv2.imread(IMGDIR + imgn + ".png") + + imgr, ori = test_noise_reduce(folder + imgn, numIMG=5) + dimc = imgr.shape[1] + dimr = imgr.shape[0] + while True: + r_prompt = input("Type in the index for horizontal slice or c to cancel: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + c_prompt = input("Type in the index for vertical slice: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + if r_prompt == 'c': + break + while True: + try: + r_int = int(r_prompt) + assert 0 <= r_int < dimr + break + except ValueError: + r_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + except AssertionError: + r_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimr - 1)) + while True: + try: + c_int = int(c_prompt) + assert 0 <= c_int < dimc + break + except ValueError: + c_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + except AssertionError: + c_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + # start = 7 + # end = 10 + sig = 0 + gk = 9 + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + # INITIALIZATION + # cv2.imshow("denoised", np.uint8(imgr)) # REMOVES TO SHOW IMAGE + # x = np.array(range(dimc)) + # x2 = np.array(range(dimr)) + + # INITIALIZATION + gksize = (gk, gk) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + + + # DETECTION INIT + xh = np.array(range(dimc)) + xv = np.array(range(dimr)) + zeroh = np.zeros(dimc) + zerov = np.zeros(dimr) + y_s_x = FM(sobelx, FM.HOR, r_int) + y_s_y = FM(sobely, FM.VER, c_int) + imgx = FM(imgr, FM.HOR, r_int) + imgy = FM(imgr, FM.VER, c_int) + blurimgx = FM(img, FM.HOR, r_int) + blurimgy = FM(img, FM.VER, c_int) + gx, bgx, deducedx = gauss_bg_deduce(xh, imgx) + gy, bgy, deducedy = gauss_bg_deduce(xv, imgy) + # print(extract_extrema(y_s_x)) + # print(extract_extrema(y_s_y)) + # EDGE DETECTION + ecx = edge_centroid(y_s_x, imgx) + try: + # paramhp, xp1 = poly_fitting_params(y_s_x, deducedx) + # paramhg, xg1 = gaussian_fitting_params(y_s_x, deducedx) + paramhp, xp1 = poly_fitting_params(y_s_x, imgx) + paramhg, xg1 = gaussian_fitting_params(y_s_x, imgx) + xp_h_plot, yp_h_plot = poly_curve(paramhp, xp1) + xg_h_plot, yg_h_plot = gaussian_curve(xg1, paramhg[0], paramhg[1], paramhg[2]) + except AssertionError: + print("No image data for horizontal slice!") + xp_h_plot, yp_h_plot = xh, zeroh + xg_h_plot, yg_h_plot = xh, zeroh + + px, gx = xp_h_plot[np.argmax(yp_h_plot)], xg_h_plot[np.argmax(yg_h_plot)] + print("edge: {0}, poly:{1}, gaussian:{2}".format(ecx, px, gx)) + + ecy = edge_centroid(y_s_y, imgy) + try: + paramvp, xp2 = poly_fitting_params(y_s_y, imgy) + paramvg, xg2 = gaussian_fitting_params(y_s_y, imgy) + xp_v_plot, yp_v_plot = poly_curve(paramvp, xp2) + xg_v_plot, yg_v_plot = gaussian_curve(xg2, paramvg[0], paramvg[1], paramvg[2]) + except AssertionError: + print("No image data for vertical slice!") + xp_v_plot, yp_v_plot = xv, zerov + xg_v_plot, yg_v_plot = xv, zerov + py, gy = xp_v_plot[np.argmax(yp_v_plot)], xg_v_plot[np.argmax(yg_v_plot)] + print("edge: {0} poly:{1}, gaussian:{2}".format(ecy, py, gy)) + + # DATA RECORDING + fwrite.write("x: edge_centroid: {0}, poly: {1}, gaussian: {2}; ".format(ecx, px, gx)) + fwrite.write('\n') + fwrite.write("y: edge_centroid: {0}, poly: {1}, gaussian: {2}\n".format(ecy, py, gy)) + + # if i >= 13: + fig = plt.figure(figsize=(16, 8)) + plt.subplot(411) + plt.plot(y_s_x.extract_array(), 'b-') + plt.ylabel("sobel_x") + plt.subplot(412) + imgx.initialize() + plt.plot(xh, imgx.extract_array(), 'b-', xh, bgx, 'm-', xh, deducedx, 'c-', xp_h_plot, yp_h_plot, 'g-', + xg_h_plot, yg_h_plot, 'r-') + plt.ylabel("Horizontal Slice, ECX: {0}".format(ecx)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.subplot(413) + plt.plot(y_s_y.extract_array(), 'b-') + plt.ylabel("sobel_y") + plt.subplot(414) + imgy.initialize() + plt.plot(xv, imgy.extract_array(), 'b-', xv, bgy, 'm-', xv, deducedy, 'c-', xp_v_plot, yp_v_plot, 'g-', + xg_v_plot, yg_v_plot, 'r-') + plt.ylabel("Vertical Slice, ECY: {0}".format(ecy)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.show() + # plt.savefig(NAME_HEADER + "_" + gk_setting + ".png") # UNCOMMENT WHEN SAVING PLOTS + + +FM = FastDataMatrix2D + + +def folder_to_imgs(img_name_scheme, num_sample): + """This function takes img files and return cv imgs""" + return [cv2.imread(img_name_scheme.format(i)) for i in range(1, num_sample+1)] + + +def center_detect_old(img_name_scheme, num_sample, sample_int=50): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair""" + imgs = folder_to_imgs(img_name_scheme, num_sample) + num_imgs = len(imgs) + dimr = imgs[0].shape[0] + dimc = imgs[0].shape[1] + xnum_imgs = num_imgs + ynum_imgs = num_imgs + xsum = 0 + ysum = 0 + zw = 0 + ew = 1 + gk = 9 + count = 1 + for imgr in imgs: + if count == num_sample: + imgshow = imgr + count += 1 + #print(imgr.shape) + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + # Gathering Data + nr = sample_int + r_thresh = dimr * 2.0 / (sample_int * 3) + xs = [] + xdummies = [] + ys = [] + ydummies = [] + while nr < dimr: + data_x = sobelx[nr, :] + zc_x = zero_crossing(data_x) + print("row:", nr) + ed_x = edge_centroid(data_x, FM(img, FM.HOR, nr)) + print("At {0}: {1}".format(nr, ed_x)) + nr += sample_int + xdummies.append(zc_x * zw + ed_x * ew) + if zc_x == -1: + continue + else: + xs.append(zc_x * zw + ed_x * ew) + nc = sample_int + c_thresh = dimc * 2.0 / (sample_int * 3) + while nc < dimc: + data_y = sobely[:, nc] + zc_y = zero_crossing(data_y) + ed_y = edge_centroid(data_y, FM(img, FM.VER, nc)) + nc += sample_int + ydummies.append(zc_y * zw + ed_y * ew) + if zc_y == -1: + continue + else: + ys.append(zc_y * zw + ed_y * ew) + #print("x") + #print(xdummies) + #print(xs) + #print("y") + #print(ydummies) + #print(ys) + len_xs = len(xs) + len_ys = len(ys) + print("img {0}: {1}".format(count - 1, xs)) + if len_xs < r_thresh: + xnum_imgs -= 1 + else: + xsum += sum(xs) / len(xs) + if len_ys < c_thresh: + ynum_imgs -= 1 + else: + ysum += sum(ys) / len(ys) + + plt.show() + + center_x = -1 if xnum_imgs == 0 else xsum / xnum_imgs + center_y = -1 if ynum_imgs == 0 else ysum / ynum_imgs + return center_x, center_y + +# The image taken is flipped horizontally, result x should be img.shape[1] - x +# The image sometimes has two peaks, try experimenting with different gaussian kernels + + +def center_detect_test(folder_path, img_name_scheme, num_sample, sample_int=50, debug=False, gk=9, ks=-1, m=0, p=20, b=1, c=0, hough=True): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(folder_path + img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # ------------------------------------------------------------ + # Parameter Setting + METHODS = {0: gaussian_fitting, 1: poly_fitting, 2: edge_centroid, + 3: zero_crossing, 4: edge_converge_base, 5: edge_converge_extreme} + edge_method = METHODS[m] + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + # ------------------------------------------------------------ + # Gathering Data + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + if m < 3: + ec_x = edge_method(data_x, FM(img, FM.HOR, nr), p) + else: + ec_x = edge_method(data_x) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, ec_x)) + + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + if m < 3: + ec_y = edge_method(data_y, FM(img, FM.VER, nc), p) + else: + ec_y = edge_method(data_y) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, ec_y)) + len_hs = len(hs) + len_vs = len(vs) + # --------------- PRE-CHECK DATA VALUES ---------------------- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + x_valid = False + y_valid = False + stdh = -1 + stdv = -1 + #valuesH = [d[1] for d in hs] + #valuesV = [d[1] for d in vs] + if len_hs >= r_thresh: + x_valid = True + stdh = std_dev(hxs) + if len_vs >= c_thresh: + y_valid = True + stdv = std_dev(vys) + #hough_img = img_name_scheme.format(1) + + # OUTLIER DETECTION TODO: OPTIMIZE, THIS IS NAIVE + if x_valid: # NAIVE + hys, hxs = reg_pre_debias(hys, hxs) + if y_valid: + vxs, vys = reg_pre_debias(vxs, vys) + # --------------------------------------------------------- + # ----- Following Modules Handles Hough Line Drawing --------- + if hough: + hough_img = folder_path + img_name_scheme.format(1) + print(hough_img) + img_h = cv2.imread(hough_img) + if len_hs: + hp1, hp2, line_a = line_graph_contrast(img_h, hxs, hys) + print('Drawn H') + if len_vs: + vp1, vp2, line_b = line_graph_contrast(img_h, vxs, vys) + print('Drawn V') + namespace = 'houghs/hough_{0}{1}_{2}'.format(folder_path[3:], m, img_name_scheme.format(1)) + if len_hs: + print(hp1, hp2) + if len_vs: + print(vp1, vp2) + print(namespace) + cv2.imwrite(namespace, img_h) + else: + #print("MEAS", hys) + line_a = HoughLine(x=hxs, data=hys) + #print("MEAS", vys) + line_b = HoughLine(x=vxs, data=vys) + # ------------------------------------------------------------ + # DEBUG MODULE + if debug: + print((dimr, dimc)) + print("imgX(BEFORE):", hs) + print("imgX:", list(zip(hys, hxs))) + print("imgY(BEFORE):", vs) + print("imgY:", list(zip(vxs, vys))) + compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), color_map='gray') + test(folder_path, img_name_scheme) + # -------------------------------------------------------- + # DATA RECORDING AND PROCESSING + if len_hs >= r_thresh: + x_valid = True + stdh = std_dev(hxs) + if len_vs >= c_thresh: + y_valid = True + stdv = std_dev(vys) + if c == 1: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + else: + if x_valid and y_valid: + center_x, center_y = HoughLine.intersect(line_a, line_b) + else: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + # --------------------------------------------------------- + return center_x, center_y, stdh, stdv + + +def center_detect(img_name_scheme, num_sample, sample_int=50, debug=False, gk=9, ks=-1, m=1, p=10, b=1): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + zw = 0 + ew = 1 + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # Gathering Data + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + zc_x = zero_crossing(data_x) + ec_x = edge_centroid(data_x, FM(img, FM.HOR, nr)) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, zc_x * zw + ec_x * ew)) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + zc_y = zero_crossing(data_y) + ec_y = edge_centroid(data_y, FM(img, FM.VER, nc)) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, zc_y * zw + ec_y * ew)) + len_hs = len(hs) + len_vs = len(vs) + if debug: + print((dimr, dimc)) + print("imgX:", hs) + print("imgY:", vs) + compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), color_map='gray') + while True: + ax = input("Input the axis you wanna debug, h for horizontal, v for vertical, or c to cancel: ") + if ax == 'c': + break + inds = input("Input the index you wanna debug: ") + while True: + try: + index = int(inds) + axis = FM.HOR if ax == 'h' else FM.VER + assert 0 <= index < imgr.shape[1 - axis] + break + except ValueError: + inds = input("Invalid input, do it again: ") + except AssertionError: + inds = input("Index Out of Bound, do it again: {0} ".format(imgr.shape)) + sobelop = sobelx if axis else sobely + quick_plot(FM(sobelop, axis, index).extract_array()) + + # ----- Following Modules Handles Hough Line Drawing ----- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + + hough_img = img_name_scheme.format(1) + img_h = cv2.imread(hough_img) + if len_hs: + hp1, hp2, lina = line_graph_contrast(img_h, hxs, hys) + print('Drawn H') + if len_vs: + vp1, vp2, linb = line_graph_contrast(img_h, vxs, vys) + print('Drawn V') + namespace = 'houghs/hough_{0}'.format(hough_img[3:]) + if len_hs: + print(hp1, hp2) + if len_vs: + print(vp1, vp2) + print(namespace) + cv2.imwrite(namespace, img_h) + # -------------------------------------------------------- + x_invalid = False + y_invalid = False + if len_hs < r_thresh: + x_invalid = True + if len_vs < c_thresh: + y_invalid = True + + center_x = -1 if x_invalid else sum([d[1] for d in hs]) / len_hs + center_y = -1 if y_invalid else sum([d[1] for d in vs]) / len_vs + return center_x, center_y + + +def random_test(): + data = [27, 21, 22, 21, 21, 18, 41, 69, 83, 62, 38, 16, 21, 20, 18, 17] + print(len(data)) + ids = 0 + gs = 0 + for i, d in enumerate(data): + if d == 83: + print(i) + ids += i * d + gs += d + print(ids / gs) + + +TEST_PIC_TRUTH = [(385, 130), + (385, 130), + (385, 130), + (-2, -2), + (176, 52), + (174, -1), + (158, -1), + (159, -1), + (242, 212), + (278, 215), + (325, 218), + (143, 215), + (53, 219), + (-1, 17), + (138, 19), + (355, 14), + (288, -1), + (369, 180), + (357, 265), + (225, 224), + (-1, 195), + (-1, 59), + (-1, -1), + (-1, 160), + (445, 166)] + + +def read_truth(filename): + with open(filename) as truth: + TRUTH = {} + active = None + for line in truth: + meas = line.replace(',', ' ').split() + if len(meas) == 0: + pass + elif len(meas) == 1: + active = {} + TRUTH[meas[0]] = active + + else: + tp = (int(meas[1]), int(meas[2])) + active[meas[0]] = tp + return TRUTH + + +def error_calc(meas, truth): + E = 0 + T = 0 + F = 0 + terms = 0 + #ls = ['img_5', 'img_6', 'img_7', 'img_12', 'img_13', 'img_14', 'img_15', 'img_16', 'img_17', 'img_18', 'img_20', 'img_21', 'img_22', 'img_25'] + #ms = [] + #es = [] + for m, vals in meas.items(): + """if m in ls: + continue""" + mx, my = vals + tx, ty = truth[m] + if tx == -2 or ty == -2: + pass + elif (mx == -1 and tx != -1) or (my == -1 and ty != -1): + F += 1 + #ms.append(m) + elif (mx != -1 and tx == -1) or (my != -1 and ty == -1): + T += 1 + else: + dx = mx - tx + dy = my - ty + E += (dx) ** 2 + (dy) ** 2 + #es.append((dx, dy)) + terms += 2 + # print(ms) + # print(es) + error = sqrt(E / terms) if terms else float('inf') + return {'E': error, 'T': T, 'F': F} + + +TRUTH_FILE = "meas/truth.txt" +TRUTH = read_truth(TRUTH_FILE) + + +""" ================================= +============= Parameter ============= +=========== Optimization ============ +===================================== """ + + +# TODO: OPTIMIZE ON THE THE GAUSSIAN KERNEL PARAMETER. WHAT HAPPENED THAT MAKES THE SMALL KERNEL BETTER??? +def gaussian_kernel_expr(folder, ns): + offset = '../' + truth_doc = TRUTH[folder] + error = {} + gs = range(1, 20, 2) + Es = [] + Ts = [] + Fs = [] + for g in gs: + meas = {} + #print(g) + for i in range(1, 26): + img_name = ns.format(i) + imgfile = offset + folder + "/%s_{0}.png" % img_name + # if i in [11, 13, 21, 23, 25]: + if i == 0: + val = center_detect(imgfile, 3, debug=True, gk=g) + else: + val = center_detect(imgfile, 3, gk=g) + #print(str(i), val) + meas[img_name] = val + # print(str(i), val) + + ed = error_calc(meas, truth_doc) + Es.append(ed['E']) + Ts.append(ed['T']) + Fs.append(ed['F']) + error[g] = ed + print(error) + compare_data_plots((Es, gs, 'Error'), (Ts, gs, 'False Positive'), (Fs, gs, 'False Negative'), suptitle="Gaussian Blur Test") + + +def sobel_kernel_expr(folder, ns): + offset = '../' + truth_doc = TRUTH[folder] + error = {} + #ks = [-1] + #ks.extend(list(range(3, 8, 2))) + ks = range(-1, 8, 2) + Es = [] + Ts = [] + Fs = [] + for k in ks: + # print(k) + meas = {} + for i in range(1, 26): + img_name = ns.format(i) + imgfile = offset + folder + "/%s_{0}.png" % img_name + # if i in [11, 13, 21, 23, 25]: + if i == 0: + val = center_detect(imgfile, 3, debug=True, ks=k) + else: + val = center_detect(imgfile, 3, ks=k) + #print(str(i), val) + meas[img_name] = val + # print(str(i), val) + + ed = error_calc(meas, truth_doc) + Es.append(ed['E']) + Ts.append(ed['T']) + Fs.append(ed['F']) + error[k] = ed + print(error) + compare_data_plots((Es, ks, 'Error'), (Ts, ks, 'False Positive'), (Fs, ks, 'False Negative'), suptitle="Sobel Kernel Test") + + +def convergence_test(folder, ns): + offset = '../' + convergence = {} + line_stdh = [] + line_stdv = [] + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Convergence + lrh = 0 + lrhs = 0 + lrv = 0 + lrvs = 0 + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + #print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y, stdh, stdv = center_detect_test(fpath, imgfile, 5, debug=False, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y), str(stdh), str(stdv)]) + # CONVERGENCE + if x != -1: + lrh += stdh ** 2 + lrhs += 1 + if y != -1: + lrv += stdv ** 2 + lrvs += 1 + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y, stdh, stdv = center_detect_test(fpath, imgfile, 5, debug=False, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y), str(stdh), str(stdv)]) + # CONVERGENCE + if x != -1: + lrh += stdh ** 2 + lrhs += 1 + if y != -1: + lrv += stdv ** 2 + lrvs += 1 + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + mselrh = sqrt(lrh / lrhs) + mselrv = sqrt(lrv / lrvs) + msepv = sqrt(pv / pvs) + cvg = {'LineConvergenceH': mselrh if lrhs else float('inf'), + 'LineConvergenceV': mselrv if lrvs else float('inf'), + 'PicConsistency': msepv} + convergence[m] = cvg + line_stdh.append(mselrh) + line_stdv.append(mselrv) + variations.append(msepv) + print(convergence) + compare_data_plots((line_stdh, ms, 'Line Convergence Hor'), (line_stdv, ms, 'Line Convergence Ver'), + (variations, ms, 'Reading Consistency'), suptitle="Convergence/Consistency Test") + fwrite.close() + + +def convergence_test_final(folder, ns): + offset = '../' + convergence = {} + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + # print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + msepv = sqrt(pv / pvs) + cvg = {'PicConsistency': msepv} + convergence[m] = cvg + variations.append(msepv) + print(convergence) + fwrite.close() +"""""" + + +def parameter_convert(method, padding, blur): + return method + 2 * padding + blur * 100 + + +def main(): + # TODO: HANDLE THE MAXI MINI LEFT AND RIGHT PROBLEM (2 PEAKS) + folder = "../calib4/" + img_name = "img_59_{0}.jpg" + ns = "img_%d_{0}.png" + # print("Center Detection yields: ") + # gaussian_kernel_expr('testpic', 'img_{0}') + #sobel_kernel_expr('testpic', 'img_{0}') + convergence_test('calib4/', 'img_{0}') + """for i in range(59, 193): + #if i in [29]: + try: + if i in [133, 134, 157, 158, 159, 160]: + print(i) + val = center_detect_test(folder, ns % i, 5, debug=True, hough=False) + print(str(i), val) + #val = center_detect_test(folder, ns % i, 5, hough=False) + #print(str(i), val) + except AttributeError: + print('No image {0}!'.format(i)) + print('------------------------------------------------------')""" + # convergence_test_final('calib4/', 'img_{0}') + + +def case_calc(): + hori_lower = 53.50 - 0.13 + hori_upper = 53.50 + 0.13 + verti_lower = 41.41 - 0.11 + verti_upper = 41.41 + 0.11 + height = 3 + width = 4 + print('hori_lower: {0}'.format(distance(width / 2, hori_lower / 2))) + print('hori_upper: {0}'.format(distance(width / 2, hori_upper / 2))) + print('verti_lower: {0}'.format(distance(height / 2, verti_lower / 2))) + print('verti_upper: {0}'.format(distance(height / 2, verti_upper / 2))) + + +def distance(h, angle): + return 2.54 * (h / tan(radians(angle))) + + + #print(center_detect(folder + img_name, 10, debug=True)) + + + + #print("Center Detection yields: ") + #print(center_detect("../new_test/img_3_{0}.png", 5)) + #2.5 + 13 = 15.5 / 2 = 7.75 + + """plt.figure() + plt.plot([1,2 ,3]) + plt.show()""" + + #print(atan(56 / 200) * 180 / 3.1415926535) + #print(atan(134 / 537) * 180 / 3.1415926535) + + #test() + #test_canny_detect() + #random_test() + + +if __name__ == '__main__': + main() + #print(DEGREES) + #test_interactive() + #test_canny_detect() + + + +# INSIGHT: +"""Might be able to solve the problem by auto-thresholding and converting to binary. +Alternative: + 1. Mark the maximum and minimum that are certain multitudes of standard deviation above + +=========================================== +========= THE FOLLOWING FUNCTIONS ========= +============== ARE DEPRECATED ============= +==========================================- + +def OMP(imDims, sparsity, measurements, A): + display = None + numPixels = 0 + r = measurements.copy() + indices = [] + + # Threshold to check error. If error is below this value, stop. + THRESHOLD = 0.1 + + # For iterating to recover all signal + i = 0 + + while i < sparsity and np.linalg.norm(r) > THRESHOLD: + # Calculate the correlations + print('%d - ' % i, end="", flush=True) + corrs = A.T.dot(r) + + # Choose highest-correlated pixel location and add to collection + # COMPLETE THE LINE BELOW + best_index = np.argmax(np.abs(corrs)) + indices.append(best_index) + + # Build the matrix made up of selected indices so far + # COMPLETE THE LINE BELOW + Atrunc = A[:, indices] + + # Find orthogonal projection of measurements to subspace + # spanned by recovered codewords + b = measurements + # COMPLETE THE LINE BELOW + xhat = np.linalg.lstsq(Atrunc, b)[0] + + # Find component orthogonal to subspace to use for next measurement + # COMPLETE THE LINE BELOW + r = b - Atrunc.dot(xhat) + + # This is for viewing the recovery process + if i % 10 == 0 or i == sparsity - 1 or np.linalg.norm(r) <= THRESHOLD: + recovered_signal = np.zeros(numPixels) + for j, x in zip(indices, xhat): + recovered_signal[j] = x + Ihat = recovered_signal.reshape(imDims) + plt.title('estimated image') + plt.imshow(Ihat, cmap=plt.cm.gray, interpolation='nearest') + display.clear_output(wait=True) + display.display(plt.gcf()) + + i = i + 1 + + display.clear_output(wait=True) + + # Fill in the recovered signal + recovered_signal = np.zeros(numPixels) + for i, x in zip(indices, xhat): + recovered_signal[i] = x + + return recovered_signal + +if ori == 'h': + x = np.array(range(img.shape[1])) + y = np.array([img_rec.rel_lumin(img, p, c) for c in x]) +else: + x = np.array(range(img.shape[0])) + y = np.array([img_rec.rel_lumin(img, r, p) for r in x]) +""" + +CALK = 166.1861 diff --git a/Nov_27/Full/Camera/img_rec_module/~$log.docx b/Nov_27/Full/Camera/img_rec_module/~$log.docx new file mode 100644 index 0000000..0430bb4 Binary files /dev/null and b/Nov_27/Full/Camera/img_rec_module/~$log.docx differ diff --git a/Nov_27/Full/Camera/transfer_test_correct_config/._RPI_C.py b/Nov_27/Full/Camera/transfer_test_correct_config/._RPI_C.py new file mode 100644 index 0000000..304e0fd Binary files /dev/null and b/Nov_27/Full/Camera/transfer_test_correct_config/._RPI_C.py differ diff --git a/Nov_27/Full/Camera/transfer_test_correct_config/._Read_Accel.py b/Nov_27/Full/Camera/transfer_test_correct_config/._Read_Accel.py new file mode 100644 index 0000000..af4016e Binary files /dev/null and b/Nov_27/Full/Camera/transfer_test_correct_config/._Read_Accel.py differ diff --git a/Nov_27/Full/Camera/transfer_test_correct_config/RPI_C.py b/Nov_27/Full/Camera/transfer_test_correct_config/RPI_C.py new file mode 100644 index 0000000..78342b9 --- /dev/null +++ b/Nov_27/Full/Camera/transfer_test_correct_config/RPI_C.py @@ -0,0 +1,212 @@ +#Code for communications, sensor actions, and calculations for RPi on camera module +#Assume that RPI_C and RPI_L codes are implemented at same time (synced) +#Below code will execute at startup of RPI_C + +from SETTINGS import * +import subprocess +import RPi.GPIO as GPIO +import sys +import socket +import time +from Read_Accel import read_accel +sys.path.insert(0,IMG_REC) +from sig_proc import center_detect +sys.path.insert(0,IMG_CAM) +from img_capture import ImgCollector +sys.path.insert(0,COMM) +from communication import send_data_to_server +from server_socket_connect_new import server_socket +from pinMasterSleep import pinMasterSleep +import traceback + +#Givens + +#See SETTINGS.py + +time.sleep(10) #to avoid pins being set during flickering + +def main(): + + running = True + + print("run_log_path: " + RUN_LOG_PATH) + if os.path.exists(RUN_LOG_PATH): + rfile = open(RUN_LOG_PATH, "r") + try: + run_counter = int(rfile.read()) + except ValueError: + run_counter = -1 + else: + rfile = open(RUN_LOG_PATH, "w") + run_counter = 0 + rfile.write(str(run_counter)) + rfile.close() + + print("run _counter: " + str(run_counter)) + if run_counter > 0 and run_counter % re_sync != 0: + #Power Pins (The same actions would be performed in pinMasterSleep if run_counter = 0) + GPIO.setmode(GPIO.BCM) + GPIO.setup(pMap[12], GPIO.OUT) + GPIO.output(pMap[12], GPIO.HIGH) + print("RPICam: 12 High") + + #Other initializations + pos = [] + pitch_1 = [] + pitch_2 = [] + ds = [] + state = "BASELINE" + elif run_counter == -1: + print("RPICam: Issue with Run_File Read, Proceeding to Shutdown") + state = "SHUTDOWN" + else: + state = "SYNC" + + while running == True: + + try: + if state == "BASELINE": + #Listen for Connection from RPI_L + print("RPICam: Waiting for RPI_L to Wake") + try: + rsv_msg_L = server_socket("RPI_C_AWAKE?") + if rsv_msg_L == '': + print("RPICam: Connection with RPI_L Not Successful") + print("RPICam: Proceeding to Safe Shutdown") + state = "SHUTDOWN" + joined_msg = ''.join(rsv_msg_L) + print("RPICam: Received: " + joined_msg) + if joined_msg == "LaserOn": + print("RPICam: Laser is On, Continuing to Accel Acquisition") + state = "ACCEL" + else: + print("RPICam: ERROR: Laser Apparently Not On") + print("RPICam: Will Proceed to Safe Shutdown") + state = "SHUTDOWN" + except: + print("RPICam: BASELINE ERROR") + state = "SHUTDOWN" + + elif state == "SYNC": + #Run Master or Slave code + print("RPICam: Performing Time Sync with RPI_L") + try: + t_sleep_sec = pinMasterSleep(pMap) + except: + print("RPICam: SYNC ERROR") + t_sleep_sec = -1 + + state = "SYNC_SHUTDOWN" + + elif state == "ACCEL": + try: + print("RPICam: Taking Acceleration 1 Readings at Camera Module") + pitch_1 = read_accel() + print("pitch_1: " + str(pitch_1*180/pi)) + print("RPICam: Continue to Image Acquisition") + state = "IMAGE" + except: + print("RPICam: ACCEL ERROR") + state = "SHUTDOWN" + + elif state == "IMAGE": + try: + img_collector = ImgCollector(IMG_DIR, NAME_SCHEME, FILE_FORMAT, RAW_IMAGE, NUM_SAMPLES) + print("RPICam: Taking Camera Picture of Laser Beam") + img_collector.capture() + time.sleep(2) + img_collector.shutdown() + + rsv_msg_L = server_socket("TURN_OFF_LASER?") + joined_msg = ''.join(rsv_msg_L) + if joined_msg == "RPI_L_WAITING": + print("RPICam: Performing Image Processing of Image") + pos = center_detect(img_collector.get_last_meas(), NUM_SAMPLES) + print("pos = [" + str(pos[0]) + "," + str(pos[1]) + "]") + print("RPICam: Proceeding to Settlement Estimation") + state = "ESTIMATE" + else: + print("RPICam: RPI_L Communication Error") + state = "SHUTDOWN" + except: + traceback.print_exc(file = sys.stdout) + print("RPICam: IMAGE ERROR") + state = "SHUTDOWN" + + elif state == "ESTIMATE": + print("RPICam: Retrieving Acceleration Value from Laser Module") + try: + accel_2_rsv = server_socket("GOT_ACCEL_2?") + joined_msg = ''.join(accel_2_rsv) + print("RPICam: Received: " + joined_msg) + if joined_msg == "ERROR_ACCEL": + print("RPICam: ERROR: Accel_2 Not Valid") + state = "SHUTDOWN" + else: + pitch_2 = float(''.join(accel_2_rsv)) + print("pitch_2: " + str(pitch_2 * 180 / pi)) + + print("RPI_Cam: Performing Settlement Estimation") + ds = pos[1] + print("Settlement = " + str(ds) + " " + units) + print("RPI_Cam: Proceeding to Server Connection") + state = "SERVER" + except: + traceback.print_exc(file = sys.stdout) + print("RPICam: ESTIMATE ERROR") + state = "SHUTDOWN" + + + elif state == "SERVER": + print("Sending Data to Server") + try: + print(send_data_to_server(x = pos[0], y = ds, phi = pitch_1)) + print("RPI_Cam: Value pushed, proceeding to safe shutdown") + except RuntimeWarning as e: + print(e) + print("RPI_Cam: RunTime Warning: Value Not Pushed to Server") + except: + print("RPI_Cam: Value Not Pushed to Server") + time.sleep(1) + state = "SHUTDOWN" + + elif state == "SHUTDOWN": + run_counter = run_counter + 1 + wfile = open(RUN_LOG_PATH, "w") + wfile.write(str(run_counter)) + wfile.close() + + img_collector.shutdown() + print("RPI_Cam: Defer to Arduino for Power Control") + time.sleep(10) + subprocess.call(["shutdown", "-h", "now"]) + + elif state == "SYNC_SHUTDOWN": + if t_sleep_sec == -1: + print("RPICam: Will Reattempt Sync") + else: + run_counter = run_counter + 1 + wfile = open(RUN_LOG_PATH, "w") + wfile.write(str(run_counter)) + wfile.close() + time.sleep(t_sleep_sec) + GPIO.output(pMap[16], GPIO.HIGH) + print("RPI_Cam: 16 high") + time.sleep(1) + subprocess.call(['shutdown', '-h', 'now']) + + except KeyboardInterrupt: + img_collector.shutdown() + print('User KeyBoard Interrupt, Proceeding to Shutdown') + time.sleep(10) + subprocess.call(["shutdown", "-h", "now"]) + +if __name__ == "__main__": + main() + + + + + + + diff --git a/Nov_27/Full/Camera/transfer_test_correct_config/Read_Accel.py b/Nov_27/Full/Camera/transfer_test_correct_config/Read_Accel.py new file mode 100644 index 0000000..ae2388e --- /dev/null +++ b/Nov_27/Full/Camera/transfer_test_correct_config/Read_Accel.py @@ -0,0 +1,19 @@ +from SETTINGS import * +import sys +from math import atan,sin,cos,sqrt +sys.path.insert(0,ACCELEROMETER) +from accel import extract_meas + +grav = 9.81 + +def read_accel(): + x_vec,y_vec,z_vec = extract_meas() + x = float(sum(x_vec))/float(len(x_vec)) + y = float(sum(y_vec))/float(len(y_vec)) + z = float(sum(z_vec))/float(len(z_vec)) + pitch = atan(x/(sqrt(z**2 + y**2))) #angle forward from vert [x,y flat, z up] + #roll = atan(y/(sqrt(x**2 + z**2))) #angle side from vert [x,y flat, z up] + return pitch + + + diff --git a/Nov_27/Full/Camera/transfer_test_correct_config/SETTINGS.py b/Nov_27/Full/Camera/transfer_test_correct_config/SETTINGS.py new file mode 100644 index 0000000..6cb09e7 --- /dev/null +++ b/Nov_27/Full/Camera/transfer_test_correct_config/SETTINGS.py @@ -0,0 +1,34 @@ +import os + +BASE_DIR = "/home/pi/Desktop/Full/" + +IMG_DIR = os.path.join(BASE_DIR, "images") +ACCELEROMETER = os.path.join(BASE_DIR, "accel_correct_config") +IMG_REC = os.path.join(BASE_DIR, "img_rec_module") +IMG_CAM = os.path.join(BASE_DIR, "RPiCam") +COMM = os.path.join(BASE_DIR,"communication_module") +RUN_LOG_PATH = os.path.join(BASE_DIR, "transfer_test_correct_config/run_log.txt") +NAME_SCHEME = "img" +FILE_FORMAT = "png" +RAW_IMAGE = False +NUM_SAMPLES = 5 +NAME_FORMAT = IMG_DIR + NAME_SCHEME + "_{0}" + FILE_FORMAT + +#------- IMPORT THESE THREE ---- +BRIDGE_NAME = 'dummy' +SERVER = "http://192.168.15.101:8000/sensors/"+BRIDGE_NAME+"/update/" +PASSWORD = "djioewfj34jod2jdoi3jr0jl983jsa" +#-------- ABOVE ------ +#For RPI_C.py + +RPI_L_IP = "192.168.15.103" #when hooked to Netgear Switch (Phil) +RPI_C_IP = "0.0.0.0" +RPI_C_Port = 1234 +marker = "?" +units = "mm" +span = 10*1000 +pi = 3.1415926535897932 +query_time = 5 +re_sync = 3 + +pMap = {3:2,5:3,7:4,8:14,10:15,11:17,12:18,13:27,15:22,16:23,18:24,19:10,21:9,22:25,23:11,24:8,26:7} diff --git a/Nov_27/Full/Camera/transfer_test_correct_config/pinMasterSleep.py b/Nov_27/Full/Camera/transfer_test_correct_config/pinMasterSleep.py new file mode 100644 index 0000000..a48ff3f --- /dev/null +++ b/Nov_27/Full/Camera/transfer_test_correct_config/pinMasterSleep.py @@ -0,0 +1,60 @@ +import socket, time +import RPi.GPIO as GPIO +from SETTINGS import * + +def pinMasterSleep(pMap): + max_count = 30 + # Configure board pin numbering system + GPIO.setmode(GPIO.BCM) + # Setup pin 12 to high so upon shutdown the pin drops and notifies the Arduino to cut power + GPIO.setup(pMap[12],GPIO.OUT) + GPIO.output(pMap[12],GPIO.HIGH) + # Set up pin 16 as clock output + GPIO.setup(pMap[16],GPIO.OUT) + GPIO.setup(pMap[16],GPIO.LOW) + print("RPI_Cam: 16 Low, 12 High") + + # Set up the server socket + server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + server.settimeout(query_time*max_count) + server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) + server.bind((RPI_C_IP, RPI_C_Port)) + + # Listen to the socket for client connection + #server.bind(('localhost',1234)) + #server.bind(('0.0.0.0',1234)) + server.listen(1) + toClient, client_address = server.accept() + + + # Send time t1 to slave + toClient.send(str.encode(str(int(time.time()*10**6)))) + + # Get msg from Slave, delivered at t4 + BURN = toClient.recv(16) + t4 = time.time() + t4 = str.encode(str(int(t4*10**6))) + + # Send t4 to slave + toClient.send(t4) + + print('Done with the code') + + # Now determine the clock coordination code. + + t_now = int(time.time()*10**6) + + #t_awake = t_now + 0.25*60*10**6 + t_awake = t_now + 15*10**6 + + toClient.send(str.encode(str(t_awake))) + + t_sleep = t_awake - int(time.time()*10**6) + + t_sleep_sec = t_sleep / 10.0**6 + + print('sleep time: ' + str(t_sleep_sec)) + + server.close() + + return t_sleep_sec diff --git a/Nov_27/Full/Camera/transfer_test_correct_config/server_socket_connect_new.py b/Nov_27/Full/Camera/transfer_test_correct_config/server_socket_connect_new.py new file mode 100644 index 0000000..13c264a --- /dev/null +++ b/Nov_27/Full/Camera/transfer_test_correct_config/server_socket_connect_new.py @@ -0,0 +1,76 @@ +from SETTINGS import * +import socket, time, sys, select, traceback + +#connects (one client only), and reads any data (one message anticipated), then sends out a response (one) +max_count = 30 + +def server_socket(send = "" ): + + recv = [] + print("RPICam: Establishing Server Socket...") + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind((RPI_C_IP, RPI_C_Port)) + sock.listen(1) + sock.setblocking(0) + print("RPICam: Waiting for RPI_L to Connect") + inputs = [sock] + connect = False + try: + while inputs: + readable, writable, errored = select.select(inputs, [], [], query_time*max_count) + #print readable + #print writable + #print errored + if not readable: + break #case of no connection + for s in readable: + if s is sock and connect == False: #the socket itself is ready to accept a connection + print("RPICam: Connected") + connection, server_address = s.accept() + connection.setblocking(0) + inputs.append(connection) + connect = True + else: #the socket has something that needs to be read + print("RPICam: Reading Data") + msg = s.recv(1) + rsv_msg_L = [] + if msg: #rea d in the message if the queue not empty + while True: + if marker in msg: + rsv_msg_L.append(msg[:msg.find(marker)]) + break + rsv_msg_L.append(msg) + msg = s.recv(1) + print("RPICam: Data Read Successfully") + print("received: " + str(rsv_msg_L)) + recv = rsv_msg_L + s.send(send) #immediately send back message response + print("RPICam: Data Sent") + else: #no data, client disconnected, close socket + inputs.remove(s) #remove socket from inputs + s.close() #close socket + print("RPICam: Accept Socket Closed") + print(inputs) + if connect == True: + inputs.remove(sock) + sock.close() + print("RPICam: Listen Socket Closed") + + except KeyboardInterrupt: + if sock: + sock.close + except: + traceback.print_exc(file=sys.stdout) + + return recv + + + + + + + + + + diff --git a/Nov_27/Full/Camera/transfer_test_correct_config/server_socket_connect_new_backup.py b/Nov_27/Full/Camera/transfer_test_correct_config/server_socket_connect_new_backup.py new file mode 100644 index 0000000..828551b --- /dev/null +++ b/Nov_27/Full/Camera/transfer_test_correct_config/server_socket_connect_new_backup.py @@ -0,0 +1,92 @@ +from SETTINGS import * +import socket, time, sys, select, traceback, Queue + +#connects (one client only), and reads any data (one message anticipated), then sends out a response (one) +max_count = 30 + +def server_socket(send = "" ): + + recv = [] + print("RPICam: Establishing Server Socket...") + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind((RPI_C_IP, RPI_C_Port)) + sock.listen(1) + sock.setblocking(0) + print("RPICam: Waiting for RPI_L to Connect") + message_queues = {} + inputs = [sock] + outputs = [] + + try: + while inputs: + readable, writable, errored = select.select(inputs, [], [], query_time*max_count) + print readable + print writable + print errored + for s in readable: + if s is sock: #the socket itself is ready to accept a connection + print("RPICam: Connected") + connection, server_address = s.accept() + connection.setblocking(0) + inputs.append(connection) + message_queues[connection] = Queue.Queue() + else: #the socket has something that needs to be read + print("RPICam: Reading Data") + msg = s.recv(1) + rsv_msg_L = [] + if msg: #read in the message if the queue not empty + while True: + if marker in msg: + rsv_msg_L.append(msg[:msg.find(marker)]) + break + rsv_msg_L.append(msg) + msg = s.recv(1) + message_queues[s].put(send) + print("RPICam: Data Read Successfully") + print("received: " + str(rsv_msg_L)) + recv = rsv_msg_L + if s not in outputs: + outputs.append(s) + print("RPICam: Data to be Sent") + s.send(send) + #print(inputs) + #print(outputs) + else: #no data, client disconnected, close socket + if s in outputs: + outputs.remove(s) + inputs.remove(s) + s.close() + print("RPICam: Socket Closed") + del message_queues[s] + #for s in writable: + # try: #retrieve output queue message and send it + # next_msg = message_queues[s].get_nowait() + # s.send(next_msg) + # print("RPICam: Data Sent Successfully") + # except Queue.Empty: + # outputs.remove(s) + # print("RPICam: All Data Sent") + #for s in errored: + # inputs.remove(s) + # if s in outputs: + # outputs.remove(s) + # s.close() + # del message_queues[s] + except KeyboardInterrupt: + if sock: + sock.close + except: + traceback.print_exc(file=sys.stdout) + + return recv + + + + + + + + + + diff --git a/Nov_27/Full/Laser/accel_correct_config/._accel.py b/Nov_27/Full/Laser/accel_correct_config/._accel.py new file mode 100644 index 0000000..e00addf Binary files /dev/null and b/Nov_27/Full/Laser/accel_correct_config/._accel.py differ diff --git a/Nov_27/Full/Laser/accel_correct_config/LICENSE b/Nov_27/Full/Laser/accel_correct_config/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/Nov_27/Full/Laser/accel_correct_config/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Nov_27/Full/Laser/accel_correct_config/accel.py b/Nov_27/Full/Laser/accel_correct_config/accel.py new file mode 100644 index 0000000..1c04871 --- /dev/null +++ b/Nov_27/Full/Laser/accel_correct_config/accel.py @@ -0,0 +1,739 @@ +#!/usr/bin/env python +# -*- coding:utf-8, indent=tab, tabstop=4 -*- +# +# See 'LICENSE' for copying +# +# Revision history +# Date Author Version Details +# ---------------------------------------------------------------------------------- +# 2016-12-31 Massimo Di Primio V.0.04 Fixed some basic functionality +# +# 2017-01-03 Massimo Di Primio 0.05 Added Interrut handler +# +# 2018-01-10 Massimo Di Primio 0.06 Added config file parser + +"""Simple code example for Adafruit MMA8452 3-axis Accelerometer + +This experimental code is intended for measuring gravity acceleration trough Adafruit(c) MMA8451, connected +to a Raspberry Pi Model 2A, 2B, 2B+ or 3 (not yet tested with RPi Zero). +Through this code we will demonstrate the ability of the 3-axis sensor MMA8451 to efficiently measure +gravity acceleration, so that we can identify the spatial orientation of the device. +Further and even more useful application can start from this minimal basic code. +""" + +import smbus +import time +import datetime +import os +import sys +import logging +import threading +import RPi.GPIO as GPIO +import rss_cli_config as clicfg +from collections import deque + +__author__ = "Massimo Di Primio" +__copyright__ = "Copyright 2016, dpmiictc" +__credits__ = ["Massimo Di Primio", "Dario Dalla Libera"] +__license__ = "GNU GENERAL PUBLIC LICENSE Version 3" +__version__ = "0.0.1" +__deprecated__ = "None so far" +__date__ = "2017-01-03" +__maintainer__ = "Massimo Di Primio" +__email__ = "massimo@diprimio.com" +__status__ = "Testing" +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# User Configuration Options (UCO) +# This section will be repaced soon by an external configuration file +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CFG_INTERRUPT = 1 +# MMA8451_RANGE = {} + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Application Definition Constants (ADC) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Useful definitions +EARTH_GRAVITY_MS2 = 9.80665 + +# Range values +RANGE_8_G = 0b10 # +/- 8g +RANGE_4_G = 0b01 # +/- 4g +RANGE_2_G = 0b00 # +/- 2g (default value) + +RANGE_DIVIDER = { + RANGE_2_G: 4096 / EARTH_GRAVITY_MS2, + RANGE_4_G: 2048 / EARTH_GRAVITY_MS2, + RANGE_8_G: 1024 / EARTH_GRAVITY_MS2, +} + +# Some static values +deviceName = 0x1a + +# Various addresses +i2caddr = 0x1D +# +# Useful Register Address +REG_STATUS = 0x00 # Read-Only +REG_WHOAMI = 0x0d # Read-Only +REG_DEVID = 0x1A # Read-Only +REG_OUT_X_MSB = 0x01 # Read-Only +REG_OUT_X_LSB = 0x02 # Read-Only +REG_OUT_Y_MSB = 0x03 # Read-Only +REG_OUT_Y_LSB = 0x04 # Read-Only +REG_OUT_Z_MSB = 0x05 # Read-Only +REG_OUT_Z_LSB = 0x06 # Read-Only +REG_F_SETUP = 0x09 # Read/Write +REG_XYZ_DATA_CFG = 0x0e # Read/Write +REG_PL_STATUS = 0x10 # Read-Only +REG_PL_CFG = 0x11 # Read/Write +REG_CTRL_REG1 = 0x2A # Read/Write +REG_CTRL_REG2 = 0x2B # Read/Write +REG_CTRL_REG3 = 0x2C # Read/Write +REG_CTRL_REG4 = 0x2D # Read/Write +REG_CTRL_REG5 = 0x2E # Read/Write + +REDUCED_NOISE_MODE = 0 +OVERSAMPLING_MODE = 1 +HIGH_RES_MODE = { + REDUCED_NOISE_MODE: [REG_CTRL_REG1, 0x4], + OVERSAMPLING_MODE: [REG_CTRL_REG2, 0x2], +} + +# Auto-Wake Sample Frequencies for Register CTRL_REG1 (0x2A) (Read/Write) +# sample frequency when the device is in SLEEP Mode. Default value: 00. +ASLP_RATE_FREQ_50_HZ = 0x00 +ASLP_RATE_FREQ_12_5_HZ = 0x40 +ASLP_RATE_FREQ_6_25HZ = 0x80 +ASLP_RATE_FREQ_1_56_HZ = 0xc0 + +# Data rate values +DATARATE_800_HZ = 0x00 # 800Hz +DATARATE_400_HZ = 0x08 # 400Hz +DATARATE_200_HZ = 0x10 # 200Hz +DATARATE_100_HZ = 0x18 # 100Hz +DATARATE_50_HZ = 0x20 # 50Hz +DATARATE_12_5_HZ = 0x28 # 12.5Hz +DATARATE_6_25HZ = 0x30 # 6.25Hz +DATARATE_1_56_HZ = 0x38 # 1.56Hz + +# Orientation labeling +PL_PUF = 0 +PL_PUB = 1 +PL_PDF = 2 +PL_PDB = 3 +PL_LRF = 4 +PL_LRB = 5 +PL_LLF = 6 +PL_LLB = 7 + +# Precision +PRECISION_14_BIT = 14 +PRECISION_08_BIT = 8 + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define Register Flags +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Register CTRL_REG1 (0x2a) R/W - System Control 1 Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | ASLPRATE1 | ASLPRATE0 | DR2 | DR1 | DR0 | LNOISE | F_READ | ACTIVE | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Auto-Wake Sample frequency Selection +FLAG_ASLPRATE_50_HZ = 0x00 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 50 Hz +FLAG_ASLPRATE_12_5_HZ = 0x40 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 12.5 Hz +FLAG_ASLPRATE_6_25_HZ = 0x80 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 6.25 Hz +FLAG_ASLPRATE_1_56_HZ = 0xc0 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 1.56 Hz +# System Output Data Rates Selection +FLAG_ODR_800_HZ = 0x00 # System Output Data Rate 800 Hz +FLAG_ODR_400_HZ = 0x08 # System Output Data Rate 400 Hz +FLAG_ODR_200_HZ = 0x10 # System Output Data Rate 200 Hz +FLAG_ODR_100_HZ = 0x18 # System Output Data Rate 100 Hz +FLAG_ODR_50_HZ = 0x20 # System Output Data Rate 50 Hz +FLAG_ODR_12_5_HZ = 0x28 # System Output Data Rate 12.5 Hz +FLAG_ODR_6_25_HZ = 0x30 # System Output Data Rate 6.25 Hz +FLAG_ODR_1_56_HZ = 0x38 # System Output Data Rate 1.56 Hz +# Other Flags +FLAG_LNOISE = 0x04 # Low Noise (1: Reduced Noise, 0: Normal Mode) +FLAG_F_READ = 0x02 # Fast Read (1: 8 bit sample, 0: 14 bit Sample) +FLAG_ACTIVE = 0x01 # Active (1: ACTIVE Mode, 0: STANDBY Mode) + +# Register CTRL_REG2 (0x2b) R/W - System Control 2 Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | ST | RST | 0 | SMODS1 | SMODS0 | SLPE | MODS1 | MODS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Other Flags +FLAG_STEST = 0x80 # Self Test (1: Self-Test enabled, 0: Self-Test disabled) +FLAG_RESET = 0x40 # Reset (1: Reset enabled, 0: Reset disabled) +# Sleep Mode Power Scheme Selection +FLAG_SMODS_NORM = 0x00 # Sleep Mode Power Scheme Selection: Normal +FLAG_SMODS_LNLP = 0x0a # Sleep Mode Power Scheme Selection: Low-Noise Low Power +FLAG_SMODS_HR = 0x12 # Sleep Mode Power Scheme Selection: High Resolution +FLAG_SMODS_LP = 0x1b # Sleep Mode Power Scheme Selection: Low Power +# Other Flags +FLAG_SLPE = 0x04 # Auto-Sleep (1: Auto-Sleep enabled, 0: Auto-Sleep Disabled) +# Active Mode Power Scheme Selection (for both: Sleep and Active mode) +FLAG_MODS_NORM = 0x00 # Active Mode Power Scheme Selection: Normal +FLAG_MODS_LNLP = 0x09 # Active Mode Power Scheme Selection: Low-Noise Low Power +FLAG_MODS_HR = 0x12 # Active Mode Power Scheme Selection: High Resolution +FLAG_MODS_LP = 0x1b # Active Mode Power Scheme Selection: Low Power + +# Register CTRL_REG4 (0x2d) R/W - Interrupt Enable Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | INT_EN_ASLP | INT_EN_FIFO |INT_EN_TRANS |INT_EN_LNDPR |INT_EN_PULSE |INT_EN_FF_MT | - | INT_EN_DRDY | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_INT_EN_ASLP = 0x80 # Interrupt Auto SLEEP/WAKE (0: Disabled, 1: Enabled) +FLAG_INT_EN_FIFO = 0x40 # Interrupt FIFO (0: Disabled, 1: Enabled) +FLAG_INT_EN_TRANS = 0x20 # Interrupt Transient (0: Disabled, 1: Enabled) +FLAG_INT_EN_LNDPRT = 0x10 # Interrupt Orientation (0: Disabled, 1: Enabled) +FLAG_INT_EN_PULSE = 0x08 # Interrupt Pulse Detection (0: Disabled, 1: Enabled) +FLAG_INT_EN_FF_MT = 0x04 # Interrupt Freefall/Motion (0: Disabled, 1: Enabled) +FLAG_INT_EN_BIT1 = 0x00 # Not Used +FLAG_INT_EN_DRDY = 0x01 # Interrupt Data Ready (0: Disabled, 1: Enabled) + +# Register CTRL_REG5 (0x2e) R/W - Interrupt Configuration Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | INT_CFG_ASLP | INT_CFG_FIFO |INT_CFG_TRANS |INT_CFG_LNDPRT|INT_CFG_PULSE |INT_CFG_FF_MT | - | INT_CFG_DRDY | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_INT_CFG_ASLP = 0x80 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_FIFO = 0x40 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_TRANS = 0x20 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_LNDPRT = 0x10 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_PULSE = 0x08 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_FF_MT = 0x04 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_BIT1 = 0x00 # Not Used +FLAG_INT_CFG_DRDY = 0x01 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) + +# Register XYZ_DATA_CFG (0x0e) R/W +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | 0 | 0 | 0 | HPF_OUT | 0 | 0 | FS1 | FS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Other Flags +FLAG_XYZ_DATA_BIT_7 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_6 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_5 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_HPF_OUT = 0x00 # High-Pass Filter (1: output data High-pass filtered, 0: output data High-pass NOT filtered) +FLAG_XYZ_DATA_BIT_3 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_2 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_FS_2G = 0x00 # Full Scale Range 2g +FLAG_XYZ_DATA_BIT_FS_4G = 0x01 # Full Scale Range 4g +FLAG_XYZ_DATA_BIT_FS_8G = 0x02 # Full Scale Range 8g +FLAG_XYZ_DATA_BIT_FS_RSVD = 0x03 # Reserved + +# Register F_SETUP (0x09) R/W - FIFO Setup Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | F_MODE1 | F_MODE0 | F_WMRK5 | F_WMRK4 | F_WMRK3 | F_WMRK2 | F_WMRK1 | F_WMRK0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_F_MODE_FIFO_NO = 0x00 # FIFO is disabled. +FLAG_F_MODE_FIFO_RECNT = 0x40 # FIFO contains the most recent samples when overflowed (circular buffer) +FLAG_F_MODE_FIFO_STOP = 0x80 # FIFO stops accepting new samples when overflowed. +FLAG_F_MODE_FIFO_TRIGGER = 0xc0 # FIFO Trigger mode + +# Register PL_STATUS (0x010) R/O - Portrait/Landscape Status Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | NEWLP | LO | - | - | - | LAPO[1] | LAPO[0] | BAFRO | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_PL_NEWLP = 0x80 # Landscape/Portrait status change flag. +FLAG_PL_LO = 0x40 # Z-Tilt Angle Lockout. +FLAG_PL_LAPO_PU = 0x00 # 00: Portrait Up: Equipment standing vertically in the normal orientation +FLAG_PL_LAPO_PD = 0x02 # 01: Portrait Down: Equipment standing vertically in the inverted orientation +FLAG_PL_LAPO_LR = 0x04 # 10: Landscape Right: Equipment is in landscape mode to the right +FLAG_PL_LAPO_LL = 0x06 # 11: Landscape Left: Equipment is in landscape mode to the left. +FLAG_PL_BAFRO = 0x01 # Back or Front orientation. (0: Front: Equipment is in the front facing orientation, 1: Back) + +# Register PL_CFG (0x011) R/W - Portrait/Landscape Configuration Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | DBCNTM | PL_EN | - | - | - | - | - | - | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_PL_CFG_DBCNTM = 0x80 # Debounce counter mode selection (0: Decrements debounce, 1: Clears counter) +FLAG_PL_CFG_PL_EN = 0x40 # Portrait/Landscape Detection Enable (0: P/L Detection Disabled, 1: P/L Detection Enabled) + +# Register TRANSIENT_CFG (0x1d) R/W - Transient_CFG Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | - | - | - | ELE | ZTEFE | YTEFE | XTEFE | HPF_BYP | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_TRANSIENT_CFG_ELE = 0x10 # Transient event flags (0: Event flag latch disabled; 1: Event flag latch enabled) +FLAG_TRANSIENT_CFG_ZTEFE = 0x08 # Event flag enable on Z (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_YTEFE = 0x04 # Event flag enable on Y (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_XTEFE = 0x02 # Event flag enable on X (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_HPF_BYP = 0x01 # Bypass High-Pass filter/Motion Detection + +# Register TRANSIENT_SCR (0x01e) R/O - TRANSIENT_SRC Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | - | EA | ZTRANSE | Z_Trans_Pol | YTRANSE | Y_Trans_Pol | XTRANSE | X_Trans_Pol | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_TRANSIENT_SCR_EA = 0x40 # Event Active Flag (0: no event flag has been asserted; 1: one or more event flag has been asserted) +FLAG_TRANSIENT_SCR_ZTRANSE = 0x20 # Z transient event (0: no interrupt, 1: Z Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_ZTR_POL = 0x10 # Polarity of Z Transient Event that triggered interrupt (0: Z event Positive g, 1: Z event Negative g) +FLAG_TRANSIENT_SCR_YTRANSE = 0x08 # Y transient event (0: no interrupt, 1: Y Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_YTR_POL = 0x04 # Polarity of Y Transient Event that triggered interrupt (0: Y event Positive g, 1: Y event Negative g) +FLAG_TRANSIENT_SCR_XTRANSE = 0x02 # X transient event (0: no interrupt, 1: X Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_XTR_POL = 0x01 # Polarity of X Transient Event that triggered interrupt (0: X event Positive g, 1: X event Negative g) + +# Register FF_MT_THS (0x017) R/W - Freefall and Motion Threshold Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | DBCNTM | THS6 | THS5 | THS4 | THS3 | THS2 | THS1 | THS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define SOME GLOBAL VARIABLES +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define the acceleration FIFO buffer +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# The acceleration FIFO buffer is a list of records containing all meaningful acceleration data plus some +# other useful information, whose format il as described below +# +# 1. curTime as returned by: datetime.datetime.now(). Format is: 'YYYY-MM-DD hh:mi:ss.uuuuuuu' +# 2. xAccel Current X acceleration value in row format +# 3. yAccel Current Y acceleration value in row format +# 4. xAccel Current Z acceleration value in row format +# 5. plo Current Portrait/Landscape orientation +#accelBuffer = [0, 0, 0, 0, 0] +accelBuffer = [] +#accelBuffer.append([0, 0, 0, 0, 0]) + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define the threaded interrupt vector +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +def my_callback(channel): + """ + my_callback is the threaded callback functions for interrupt events. + These will run in another thread when our events are detected + + :param channel: The GPIO channel where the interrupt event was risen + :return: None + """ + # Please nte that, for performance reasons, axis data are not convertd in m/s2, + # Although, all 6 registers containing acceleration data are read and formatted appropriately + bus = smbus.SMBus(1) + axisData = bus.read_i2c_block_data(i2caddr, REG_OUT_X_MSB, 6) + # + #print ("!"), #print("Falling edge detected on GPIO channel: " + str(channel)) + # + runTimeConfigObject.NumInterrupts = runTimeConfigObject.NumInterrupts + 1 + # + xAccel = ((axisData[0] << 8) | axisData[1]) >> 2 + yAccel = ((axisData[2] << 8) | axisData[3]) >> 2 + zAccel = ((axisData[4] << 8) | axisData[5]) >> 2 + plo = bus.read_byte_data(i2caddr, REG_PL_STATUS) & 0x7 + # Append data to the accelBuffer + accelBuffer.append([str(datetime.datetime.now()), xAccel, yAccel, zAccel, plo]) + pass + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define a class called Accel +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +import ConfigParser +class Accel(): + raspiBus = -1 # The Raspberry Pi Bus (dpends on hardware model) + raspiIntEnabled = 0 # 0 = Interrupt routine was not enabled after initialization, 1 = Interrupt routine enabled successfully + raspiInfo = "" # Raspberry Pi Info + + def __init__(self): + + # + # Setup RPI specific bus + # + myBus = "" + if GPIO.RPI_INFO['P1_REVISION'] == 1: + myBus = 0 + else: + myBus = 1 + #print('myBus=' + str(myBus)) + self.raspiBus = myBus + + self.b = smbus.SMBus(myBus) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1) + self.a = i2caddr + self.high_res_mode = OVERSAMPLING_MODE + self.sensor_range = RANGE_4_G + self.raspiInfo = GPIO.RPI_INFO + + + def whoAmI(self): + return self.b.read_byte_data(i2caddr, REG_WHOAMI) + + def init(self): + # Preliminary actions + # sudo chmod 666 /sys/module/i2c_bcm2708/parameters/combined + # sudo echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined + # + # the above 2 sh commands can be replaced with the following statements, in the case this program is ran as root (sudo) + # (For more information, please see: http://raspberrypi.znix.com/hipidocs/topic_i2c_rs_and_cs.htm) + # + # BCM2708_COMBINED_PARAM_PATH = '/sys/module/i2c_bcm2708/parameters/combined' + # os.chmod(BCM2708_COMBINED_PARAM_PATH, 666) + # os.system('echo -n 1 > {!s}'.format(BCM2708_COMBINED_PARAM_PATH)) + # sudo i2cdetect -y 1 # this sh cmmand will search /dev/i2c-1 for all address + # sudo i2cget -y 1 0x1d 0x0d # This sh command should return 0x1a for MMA8451 + # + # Setup all registers appropriately + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_RESET) # Reset + # self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_STEST) # SelfTest + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) & ~FLAG_ACTIVE) # Put the device in Standby + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) & ~FLAG_F_READ) # No Fast-Read (14-bits), Fast-Read (8-Bits) + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_ODR_50_HZ) # Data Rate + self.writeRegister(REG_XYZ_DATA_CFG, self.readRegister(REG_XYZ_DATA_CFG) | FLAG_XYZ_DATA_BIT_FS_4G) # Full Scale Range 2g, 4g or 8g + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_LNOISE) # Low Noise + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) & ~FLAG_SLPE) # No Auto-Sleep + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_SMODS_HR) # High Resolution + self.writeRegister(REG_PL_CFG, self.readRegister(REG_PL_CFG) | FLAG_PL_CFG_PL_EN) # P/L Detection Enabled + + # Setup interrupts + if CFG_INTERRUPT == 1: + GPIO.setmode(GPIO.BCM) + # GPIO 23 & 17 set up as inputs, pulled up to avoid false detection. + # Both ports are wired to connect to GND on button press. + # So we'll be setting up falling edge detection for both + GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP) + # when a falling edge is detected on port 17, regardless of whatever + # else is happening in the program, the function my_callback will be run + # GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback, bouncetime=300) + GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback) + #print("Interrupt OK") + self.raspiIntEnabled = 1 # Interrupt enabled successfully + # Force 1st sensor read + my_callback(0) + + + # Configure register for interrupt + self.writeRegister(REG_CTRL_REG4, 0x00) # Reset all interrupt enabled flags + self.writeRegister(REG_CTRL_REG4, self.readRegister(REG_CTRL_REG4) | FLAG_INT_EN_DRDY) # Data Ready Interrupt Enabled + self.writeRegister(REG_CTRL_REG5, 0x00) # Reset all interrupt config flags + self.writeRegister(REG_CTRL_REG5, self.readRegister(REG_CTRL_REG5) | FLAG_INT_CFG_DRDY) # Data Ready Interrupt is routed to INT1 pin + + # Initialize the accelBuffer + accelBuffer = deque() + + + # Finally, Activate the sensor + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_ACTIVE) # Activate the device + + def writeRegister(self, regNumber, regData): + """ + Writes one byte (8-bts) of data passed in 'regData', into the register 'regNumber' + """ + try: + self.b.write_byte_data(self.a, regNumber, regData) + time.sleep(0.01) + except IOError: + print("Error detected in function writeRegister() [IOError = " + str(IOError) + "]") + sys.exit() + + def readRegister(self, regNumber): + """ + Retrieves one byte (8-bits) of data from register 'regNumber' returning to the caller + """ + try: + return self.b.read_byte_data(self.a, regNumber) + except IOError: + print("Error detected in function readRegister() [IOError = " + str(IOError) + "]") + sys.exit() + + def block_read(self, offset, length): + """ + Performs a burst-read on the device registers retrieving the requested amount of data + Read a block of bytes from offset + """ + try: + return self.b.read_i2c_block_data(i2caddr, offset, length) + except IOError: + print("Error detected in function block_read() [IOError = " + str(IOError) + "]") + sys.exit() + + def get_orientation(self): + """ + Get current orientation of the sensor. + :return: orientation. Orientation number for the sensor. + """ + orientation = self.b.read_byte_data(self.a, REG_PL_STATUS) & 0x7 + return orientation + + def getAxisValue(self): + """ + Retrieves axis values and converts into a readable format (i.e. m/s2) + :return: None + """ + # Make sure F_READ and F_MODE are disabled. + f_read = self.b.read_byte_data(self.a, REG_CTRL_REG1) & FLAG_F_READ + assert f_read == 0, 'F_READ mode is not disabled. : %s' % (f_read) + f_mode = self.b.read_byte_data(self.a, REG_F_SETUP) & FLAG_F_MODE_FIFO_TRIGGER + assert f_mode == 0, 'F_MODE mode is not disabled. : %s' % (f_mode) + + # + self.xyzdata = self.block_read(REG_OUT_X_MSB, 6) + if self.high_res_mode is not None: + x = ((self.xyzdata[0] << 8) | self.xyzdata[1]) >> 2 + y = ((self.xyzdata[2] << 8) | self.xyzdata[3]) >> 2 + z = ((self.xyzdata[4] << 8) | self.xyzdata[5]) >> 2 + precision = PRECISION_14_BIT # Precision 14 bit data + else: + x = (self.xyzdata[0] << 8) + y = (self.xyzdata[1] << 8) + z = (self.xyzdata[2] << 8) + precision = PRECISION_08_BIT # Precision 08 bit data + max_val = 2 ** (precision - 1) - 1 + signed_max = 2 ** precision + # + x -= signed_max if x > max_val else 0 + y -= signed_max if y > max_val else 0 + z -= signed_max if z > max_val else 0 + # + x = round((float(x)) / RANGE_DIVIDER[self.sensor_range], 3) + y = round((float(y)) / RANGE_DIVIDER[self.sensor_range], 3) + z = round((float(z)) / RANGE_DIVIDER[self.sensor_range], 3) + + return {"x": x, "y": y, "z": z} + + def debugShowRpiInfo(self): + #print("Raspberry Info = " + str(GPIO.RPI_INFO)) + print("Raspberry Info = " + str(self.raspiInfo)) + + def debugShowRegisters(self): + print("REG_STATUS (0x00):" + str(format(self.readRegister(REG_STATUS), '#04x')) + " | Binary: " + format(self.readRegister(REG_STATUS), 'b').zfill(8)) + print("REG_WHOAMI (0x0d):" + str(format(self.readRegister(REG_WHOAMI), '#04x')) + " | Binary: " + format(self.readRegister(REG_WHOAMI), 'b').zfill(8)) + print("REG_F_SETUP (0x09):" + str(format(self.readRegister(REG_F_SETUP), '#04x')) + " | Binary: " + format(self.readRegister(REG_F_SETUP), 'b').zfill(8)) + print("REG_XYZ_DATA_CFG (0x0e):" + str(format(self.readRegister(REG_XYZ_DATA_CFG), '#04x')) + " | Binary: " + format(self.readRegister(REG_XYZ_DATA_CFG), 'b').zfill(8)) + print("REG_CTRL_REG1 (0x2a):" + str(format(self.readRegister(REG_CTRL_REG1), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG1), 'b').zfill(8)) + print("REG_CTRL_REG2 (0x2b):" + str(format(self.readRegister(REG_CTRL_REG2), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG2), 'b').zfill(8)) + print("REG_CTRL_REG3 (0x2c):" + str(format(self.readRegister(REG_CTRL_REG3), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG3), 'b').zfill(8)) + print("REG_CTRL_REG4 (0x2d):" + str(format(self.readRegister(REG_CTRL_REG4), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG4), 'b').zfill(8)) + print("REG_CTRL_REG5 (0x2e):" + str(format(self.readRegister(REG_CTRL_REG5), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG5), 'b').zfill(8)) + print("REG_PL_STATUS (0x10):" + str(format(self.readRegister(REG_PL_STATUS), '#04x')) + " | Binary: " + format(self.readRegister(REG_PL_STATUS), 'b').zfill(8)) + print ("debugRealTime " + str(runTimeConfigObject.debugRealTime)) + print ("NumInterrupts " + str(runTimeConfigObject.NumInterrupts)) + + def debugShowOrientation(self): + print("Position = %d" % (self.get_orientation())) + + def debugShowAxisAcceleration(self, xaccel, yaccel, zaccel): + print(" x (m/s2)= %+.3f" % (xaccel)) + print(" y (m/s2)= %+.3f" % (yaccel)) + print(" z (m/s2)= %+.3f" % (zaccel)) + + def debugRealTimeBuffer(self): + n = 0 + for elements in accelBuffer: + myData = accelBuffer.pop() + n += 1 + print ("N=" + str(n) + " myData=" + str(myData)) # + "Element=" + str(elements)) + try: + print("End of printout\n") + #time.sleep(1.0) + # os.system("clear") + except KeyboardInterrupt: + print("Program Termination Requested") + sys.exit() + +############################################################################### +# Threading functions +############################################################################### +#def rssClient(): +# """Manage data shipping over th network, in a separate thread.""" +# #logger.debug('Thread Starting') +# while True: +# time.sleep(1.0) +# print ("This is thread rssClient()") +# +############################################################################### +# Useful functions +############################################################################### +def printHelp(): + print ("\n") + print ("usage: accel.py [options]") + print ("Available options:") + print (" -h \t\t Print this help and exit") + print (" -d \t\t Show debug realtime interrupt data") + print (" -s \t\t Execute silently (no screen output)") + print (" -L \t Set Log level. where is the log level (0 = NONE - 8 = DEBUG)") + print ("") + + +def main(argv): + import sys, getopt, logging + # + try: + opts, args = getopt.getopt(argv,"hdsL:") + except getopt.GetoptError: + print ("\nInvalid option requested on command line") + printHelp() + sys.exit(2) + + for opt, arg in opts: + if opt == '-h': + printHelp() + sys.exit() + elif opt == '-d': + runTimeConfigObject.debugRealTime = 1 + elif opt == '-s': + runTimeConfigObject.executeSilently = 1 + elif opt == '-L': + if (int(arg) == 0) or (int(arg) > 5): + pass + #logger.setLevel(logger.NOTSET) # Same as value 0 + elif int(arg) == 1: + logger.setLevel(logging.CRITICAL) # Same as value 50 + elif int(arg) == 2: + logger.setLevel(logging.ERROR) # Same as value 40 + elif int(arg) == 3: + logger.setLevel(logging.WARNING) # Same as value 30 + elif int(arg) == 4: + logger.setLevel(logging.INFO) # Same as value 20 + elif int(arg) == 5: + logger.setLevel(logging.DEBUG) # Same as value 10 + + +##################################################################################### +# M A I N +##################################################################################### +class runTimeConfigObject(object): + pass +#if __name__ == "__main__": +def extract_meas(): + + #class runTimeConfigObject(object): + #pass + # + # Setup Logger + # + #logger = logging.basicConfig(level=logging.DEBUG, format='[%(asctime)15s].%(levelname)s] (%(threadName)-10s) %(message)s', ) + #logger.basicConfig(level=logging.DEBUG,format='[%(asctime)15s].%(levelname)s] (%(threadName)-10s) %(message)s',) + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + # create console handler and set level to debug + ch = logging.StreamHandler() + ch.setLevel(logging.DEBUG) + # create formatter + formatter = logging.Formatter('[%(asctime)s.%(levelname)s] (%(name)s.%(threadName)-10s) : %(message)s') + # add formatter to ch + ch.setFormatter(formatter) + # add ch to logger + logger.addHandler(ch) + + # + # Set some default command line options + # + runTimeConfig = runTimeConfigObject() + runTimeConfigObject.debugRealTime = 0 # 1 = Show debug realtime interrupt data + runTimeConfigObject.executeSilently = 0 # 1 = Execute silently (no sceen output) + runTimeConfigObject.NumInterrupts = 0 # keep Nbr of sensor interrupts withi the main loop + + main(sys.argv[1:]) + + # + # Read configuration file + # + configFile = "./rss_config.dat" + #logger.debug('Reading Config file: ' + configFile) #Commented out by Henry + sections = {'GeoData', 'DeviceInfo', 'Networking'} + #configParameters = {} + #Config = ConfigParser.ConfigParser() + #Config.read(configFile) + #for section in sections: + # try: + # options = Config.options(section) + # except: + # print ("ERROR: Section '" + section + "' Not found in config file: '" + configFile + "'.") + # sys.exit() + # for option in options: + # try: + # configParameters[option] = Config.get(section, option) + # except: + # configParameters[option] = None + # logger.debug("Config Section: " + section + " / Option: " + option + " => " + configParameters[option]) + + MMA8451 = Accel() + #os.system("clear") + MMA8451.init() + + if MMA8451.whoAmI() != deviceName: + print("Error! Device not recognized! (" + str(deviceName) + ")") + sys.exit() + + # + # Thread client start + # Commented out by Henry + ''' + import rss_client + pill2kill = threading.Event() + #threadClient = threading.Thread(name='netClientWorker', target=rss_client.cli_worker, args=(pill2kill, configParameters, accelBuffer)) + threadClient = threading.Thread(name='netClientWorker', target=rss_client.cli_worker, args=(pill2kill, accelBuffer)) + threadClient.setDaemon(False) #threadClient.daemon = False + threadClient.start() + myThread = [] + myThread.append('netClientWorker') + ''' + + #Added by Henry: + count_samples = 5 #num of samples we want + count_taken = 0 + xvals = [] + yvals = [] + zvals = [] + while count_taken < count_samples: + if runTimeConfigObject.executeSilently == 0: + axes = MMA8451.getAxisValue() + print("X: " + str(axes['x']) + ", Y: " + str(axes['y']) + ", Z: " + str(axes['z'])) + xvals.append(axes['x']) + yvals.append(axes['y']) + zvals.append(axes['z']) + count_taken = count_taken + 1 + return xvals,yvals,zvals + + #Commented Out by Henry: + ''' + while True: # forever loop + if runTimeConfigObject.executeSilently == 0: + print ("\nCurrent Date-Time: " + str(datetime.datetime.now())) + print ("Raspberry Bus = " + str(MMA8451.raspiBus)) + print ("Raspberry Interrupt = " + str(MMA8451.raspiIntEnabled)) + print ("Number of elemets = " + str(len(accelBuffer))) + MMA8451.debugShowRpiInfo() + MMA8451.debugShowRegisters() + MMA8451.debugShowOrientation() + axes = MMA8451.getAxisValue() + MMA8451.debugShowAxisAcceleration(axes['x'], axes['y'], axes['z']) + # + if runTimeConfigObject.debugRealTime != 0: + MMA8451.debugRealTimeBuffer() + + runTimeConfigObject.NumInterrupts = 0 + try: + time.sleep(1.0) + except KeyboardInterrupt: + logger.debug ("Killing threads...") + pill2kill.set() + threadClient.join() + time.sleep(1.0) + + logger.debug("\nUser termination requested!\n") + sys.exit() + + sys.exit() + ''' + diff --git a/Nov_27/Full/Laser/accel_correct_config/raspidata.py b/Nov_27/Full/Laser/accel_correct_config/raspidata.py new file mode 100644 index 0000000..fb99cbb --- /dev/null +++ b/Nov_27/Full/Laser/accel_correct_config/raspidata.py @@ -0,0 +1,48 @@ +""" A Raspberry Pi class. +To access some of the most useful hardware information +""" + + +#class RaspiData(): + + + # Get Raspberry Serial Number + # You can do it in bash: + # cat /proc/cpuinfo | perl -n -e '/^Serial[ ]*: ([0-9a-f]{16})$/ && print "$1\n"' + # Or with perl: + # cat cpuinfo | perl -n -e '/^Serial[ ]*: ([0-9a-f]{16})$/ && print "$1\n"' + # + # + + +# def __init__(self): +# pass +from uuid import getnode as get_mac + +# @staticmethod +# def get_serial(self): +def get_serial(): + """Extract serial from cpuinfo file""" + cpu_serial= "0000000000000000" + try: + f = open('/proc/cpuinfo','r') + for line in f: + if line[0:6]=='Serial': + cpu_serial = line[10:26] + f.close() + except: + cpu_serial = "ERROR000000000" + return cpu_serial + + +def mac_address(): + """Extract rth0 MAC address""" + # mac = '00:00:00:00:00:00' + # mac = '00:00:00:00:00:00' + try: + t = get_mac() + except: + t = "000000000000" + mac = ':'.join(("%012X" % t)[i:i+2] for i in range(0, 12, 2)) + return mac + diff --git a/Nov_27/Full/Laser/accel_correct_config/rss_cli_config.py b/Nov_27/Full/Laser/accel_correct_config/rss_cli_config.py new file mode 100644 index 0000000..e10aa53 --- /dev/null +++ b/Nov_27/Full/Laser/accel_correct_config/rss_cli_config.py @@ -0,0 +1,21 @@ +# [GeoData] +City = 'Rome' +cityname = 'Rome' +latitude = 41.947550 +longitude = 12.469794 +deviceorientation = 'L' + +# [DeviceInfo] +devicetype = 'raspberry' +devicename = 'rssd0001' +sensorname = 'mma8451' +sensortheshold = 20 +logfile = './rssd.log' + +# [Networking] +#serveraddress = 'www.diprimio.com' +serveraddress = 'localhost' +serverprotocol = 'tcp' +servertcpport = 15000 +serverhearthbit = 100 +receivebuffersize = 1024 diff --git a/Nov_27/Full/Laser/accel_correct_config/rss_client.py b/Nov_27/Full/Laser/accel_correct_config/rss_client.py new file mode 100644 index 0000000..a2a4d1b --- /dev/null +++ b/Nov_27/Full/Laser/accel_correct_config/rss_client.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# -*- coding:utf-8, indent=tab, tabstop=4 -*- +# +# See 'LICENSE' for copying +# +# This file contains the code for the client module of 'accel.py' +# +# Revision history +# Date Author Version Details +# ---------------------------------------------------------------------------------- +# 2018-01-18 Massimo Di Primio 0.06 1st file implementation + +"""Client thread worker - This is a simple client code example for 'accel'.py' program""" + +import logging +import time +import datetime +import socket +import json +import rss_client_messages as climsg +import rss_cli_config as ccfg +import raspidata + + +#def cli_connect(params): +def cli_connect(): + """Open connection to the server""" + server_address = (str(ccfg.serveraddress), int(ccfg.servertcpport)) + logging.debug('Trying to connect to server ' + str(server_address)) + # Create a TCP/IP socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + # Connect the socket to the port where the server is listening + s.connect(server_address) + logging.debug('Connection Established to server ' + str(server_address)) + except: + logging.debug( + "Failed to open connection: " + str(ccfg.serverprotocol) + + ", to IP: " + str(ccfg.serveraddress) + + ", on port: " + str(ccfg.servertcpport) + ) + return(-1) + return(s) + + +def cli_close(s): + """Close the server connection""" + if s > -1: + s.close() + + +# def cli_worker(stopEvent, config, accelBuffer): +def cli_worker(stopEvent, accelBuffer): + """A client worker as thread""" + logging.debug('Thread Starting') + s = cli_connect() # s = cli_connect(config) + send_client_hello(s) + time.sleep(0.5) + send_config_affirm_message(s) + + ts = int(time.time()) + te = ts + while not stopEvent.wait(0.3): + if len(accelBuffer) > 0: + send_accel_data(s, accelBuffer) + te = int(time.time()) + if (te - ts) > 10: + send_client_heartbit(s) + ts = int(time.time()) + + time.sleep(0.5) + send_zap_message(s) + cli_close(s) + logging.debug("Thread cliWorker is terminating as per your request.") + + +def send_accel_data(s, accelBuffer): + """Send acceleration data to the server""" + #msg = dict(cmd='ADM', timestamp=str(datetime.datetime.now()), clid=raspidata.get_serial()) + #a = 123 #str(datetime.datetime.now()) + pbuf = parse_accel_data(accelBuffer) + msg = dict(cmd = 'ADM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial(), data = pbuf) + # if len(pbuf) > 0: # this sometimes returns error (when buf is empty, it has None type) + if (pbuf is not None) and (len(pbuf) > 0): + #str = climsg.accel_data_message(pbuf) + try: + logging.debug("Sending Acceleration data to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(str) + "\n") + except: + logging.debug("Failed to send Acceleration-Data to the server") + + +def send_client_hello(s): + """Send Hello message to the server""" + msg = dict(cmd = 'CHM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial()) + try: + logging.debug("Sending Hello to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.hello_message()) + "\n") + except: + logging.debug("Failed to send Hello to the server") + + +def send_zap_message(s): + """Send Zap message to the server""" + msg = dict(cmd = 'CZM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial()) + try: + logging.debug("Sending Zap to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.zap_message()) + "\n") + except: + logging.debug("Failed to send Zap to the server") + + +def send_config_affirm_message(s): #def send_config_affirm_message(s, config): + msg_data = dict(city = ccfg.cityname, latitude = ccfg.latitude,longitude = ccfg.longitude) + msg = dict(cmd = 'CCA', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial(), config = msg_data) + try: + logging.debug("Sending client configuration to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(climsg.config_affirm_message(cfg_data)) + except: + logging.debug("Failed to send client configuration to the server") + + +def send_client_heartbit(s): + """Send Heartbit to the server""" + msg = dict(cmd = 'CHB', timestamp = str(datetime.datetime.now()), clid=raspidata.get_serial()) + try: + logging.debug("Sending Heartbit to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.heart_bit()) + "\n") + except: + logging.debug("Failed to send Heartbit to the server") + + +def parse_accel_data(b): + """Parse acceleration data to make sure we only send meaningfull data to the server""" + tsh = 10 + tbuf = [] + # tbuf.append([0, 0, 0, 0, 0]) + # bLength = len(b) + # logging.debug("parseAccelData(b) # of elements = " + str(len(b))) + if len(b) > 1: + logging.debug("parseAccelData: In AccelData/BufLen: " + str(len(b)) + "/" +str(len(tbuf))) + firstTime = 1 + prow = None + for row in b: + crow = b.pop(0) # Get the oldest record + if firstTime == 1: + prow = crow + firstTime = 0 + if ( (abs(abs(int(crow[1])) - abs(int(prow[1]))) > tsh) or + (abs(abs(int(crow[2])) - abs(int(prow[2]))) > tsh) or + (abs(abs(int(crow[3])) - abs(int(prow[3]))) > tsh) + ): + tbuf.append(crow) + prow = crow + print ("Again PROW/CROW/TBUFLEN:" + str(prow) + " / " + str(crow) + " / " + str(len(tbuf))) + + logging.debug("parseAccelData: Out AccelData/BufLen: " + str(len(b)) + "/" +str(len(tbuf))) + return(tbuf) + diff --git a/Nov_27/Full/Laser/accel_correct_config/rss_client_messages.py b/Nov_27/Full/Laser/accel_correct_config/rss_client_messages.py new file mode 100644 index 0000000..4a507d7 --- /dev/null +++ b/Nov_27/Full/Laser/accel_correct_config/rss_client_messages.py @@ -0,0 +1,113 @@ + +import datetime +import raspidata +import json +import rss_cli_config as ccfg + + +# +# All client messages are handled in here. +# +# Message Formats +# --------------- +# 1 - Timestamp +# 2 - Device ID +# 3 - Message Type +# +# Client message types +# -------------------- +# 0001 CHB - Client Heart Bit (Client is alive) +# 0002 CHM - Client Hello Message (Client is online) +# 0003 CZM - Client Zap Message (Client is shut down) +# 0004 ADM - Acceleration Data Message (Acceleration data) +# 0005 CCA - Client Config Affirm +# ... (other to come) +# +# Data message Format for all Client Message Types +# ------------------------------------------------ +# +# # 0001 - CHB - Client Heart Bit +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0001 | Var | Literally 'CHB' | +# # +-------------------------------------------------------------------------------+ +# +# 0002 CHM - Client Hello Message +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0002 | Var | Literally 'CHM' | +# +--------------+-------+--------------------------------------------------------+ +# +# 0003 CZM - Client Zap Message (Client is shut down) +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0003 | Var | Literally 'CZM' | +# +--------------+-------+--------------------------------------------------------+ +# +# 0004 ADM - Acceleration Data Message (Acceleration data) +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0004 | Var | Literally 'ADM' | +# | Accel Data | Var | Array containing acceleration data (X,Y,Z.O) | +# +--------------+-------+--------------------------------------------------------+ +# +# 0005 CCA - Client Configuration Affirm +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0004 | Var | Literally 'CCA' | +# | Config Data | Var | Array containing client configuration | +# +--------------+-------+--------------------------------------------------------+ + +########################################################################### +# WARNIG ! THIS FILE IS NOT CURRENTLY USED ! +# Its presence it is for debugging/testing only +# Althought, it will be used in some future version +########################################################################### + +#def heart_bit(): +# """Client Heart Bit""" +# msg = {'cmd': 'CHB', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def hello_message(): +# """Client Hello Message""" +# msg = {'cmd': 'CHM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def zap_message(): +# """Client Zap Message""" +# msg = {'cmd': 'CZM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def accel_data_message(data): +# """Acceleration Data Message""" +# msg = {'cmd': 'ADM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial(), 'acceldata': str(data)} +# return msg +# +# +#def config_affirm_message(data): #def config_affirm_message(data): +# """Client Configuration Affirm""" +# ### +# pkt_hdr = {'cmd': 'CCA', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial(), 'data' : data} +# +# msg = dict(city = ccfg.cityname, latitude = ccfg.latitude, longitude = ccfg.longitude, config = data) +# return msg + diff --git a/Nov_27/Full/Laser/transfer_test_correct_config/._Read_Accel.py b/Nov_27/Full/Laser/transfer_test_correct_config/._Read_Accel.py new file mode 100644 index 0000000..bb564a5 Binary files /dev/null and b/Nov_27/Full/Laser/transfer_test_correct_config/._Read_Accel.py differ diff --git a/Nov_27/Full/Laser/transfer_test_correct_config/RPI_L.py b/Nov_27/Full/Laser/transfer_test_correct_config/RPI_L.py new file mode 100644 index 0000000..8e9ce36 --- /dev/null +++ b/Nov_27/Full/Laser/transfer_test_correct_config/RPI_L.py @@ -0,0 +1,185 @@ +#Code for communications, sensor actions, and calculations for RPi on laser module +#Assume that RPI_C and RPI_L codes are implemented at same time (synced) +#Below code will execute at startup of RPI_L + +from SETTINGS import * +import sys +import subprocess +import socket +import RPi.GPIO as GPIO +import time +from Read_Accel import read_accel +from client_socket_connect_new import client_socket +from slaveSleep import slaveSleep + +#Givens + +# See: SETTINGS.py + +time.sleep(10) #to avoid setting pins when pins are flickering + +def main(): + running = True + + print("run_log_path: " + RUN_LOG_PATH) + if os.path.exists(RUN_LOG_PATH): + rfile = open(RUN_LOG_PATH, "r") + try: + run_counter = int(rfile.read()) + except ValueError: + run_counter = -1 + else: + rfile = open(RUN_LOG_PATH, "w") + run_counter = 0 + rfile.write(str(run_counter)) + rfile.close() + print("run_counter: " + str(run_counter)) + if run_counter > 0 and run_counter % re_sync != 0: + #Power Pins (The same actions would be performed in slaveSleep if run_counter = 0) + GPIO.setmode(GPIO.BCM) + GPIO.setup(pMap[12], GPIO.OUT) + GPIO.output(pMap[12], GPIO.HIGH) + print("RPI_L: 12 High") + + #Other initializations + pitch_2 = [] + state = "BASELINE" + elif run_counter == -1: + print("RPI_L: Issue with Run_File Read, Proceeding to Shutdown") + state = "SHUTDOWN" + else: + state = "SYNC" + + while running == True: + + try: + if state == "BASELINE": + + print("RPI_L: Turning on Laser") + GPIO.setmode(GPIO.BCM) + GPIO.setup(pMap[Laser_Port], GPIO.OUT) + GPIO.output(pMap[Laser_Port], True) + print("RPI_L: Waiting for RPI_Cam to Connect") + + try: + rsv_msg_C = client_socket("LaserOn?") + joined_msg = ''.join(rsv_msg_C) + print("RPI_L: Received: " + joined_msg) + if joined_msg == '': + print("RPI_L: Connection with RPI_C Not Successful") + print("RPI_L: Will Proceed to Safe Shutdown") + GPIO.output(pMap(Laser_Port),False) + state = "SHUTDOWN" + if joined_msg == "RPI_C_AWAKE": + print("RPI_L: RPICam Awake, Will Turn off Laser Upon Notice") + state = "WAIT" + else: + print("RPI_L: ERROR: RPICam Apparently Not On") + print("RPI_L: Will Proceed to Safe Shutdown") + GPIO.output(pMap(Laser_Port),False) + state = "SHUTDOWN" + except: + print("RPI_L: BASELINE ERROR") + state = "SHUTDOWN" + + elif state == "WAIT": + try: + time.sleep(query_time * 5) # give RPI_C a chance to close its socket + rsv_msg_C = client_socket("RPI_L_WAITING?") + joined_msg = ''.join(rsv_msg_C) + print("RPI_L: Received: " + joined_msg) + + if joined_msg == "TURN_OFF_LASER": + print("RPI_L: RPICam Took Photo, Will Turn Off Laser") + try: + GPIO.output(pMap[Laser_Port], False) + state = "ACCEL" + time.sleep(2) + except: + print("RPI_L: ERROR: Cannot Turn off Laser, Proceed to Shutdown") + state = "SHUTDOWN" + else: + print("RPI_L: ERROR: RPICam Apparently Did Not Take Photo. Exiting Program") + state = "SHUTDOWN" + except: + print("RPI_L: WAIT ERROR") + state = "SHUTDOWN" + + elif state == "SYNC": + #Run Master or Slave code + print("RPI_L: Performing Time Sync with RPICam") + try: + t_sleep_sec = slaveSleep(pMap) + except: + print("RPI_L: SYNC ERROR") + t_sleep_sec = -1 + + state = "SYNC_SHUTDOWN" + + elif state == "ACCEL": + print("RPI_L: Taking Acceleration Reading at Laser Module") + try: + pitch_2 = read_accel() #[rads] + print("pitch_2: " + str(pitch_2*180/pi)) + state = "SEND_ACCEL" + except: + print("RPI_L: ACCEL ERROR") + state = "SHUTDOWN" + + elif state == "SEND_ACCEL": + try: + rsv_msg_C = client_socket(str(pitch_2) + "?") + joined_msg = ''.join(rsv_msg_C) + + if joined_msg == "GOT_ACCEL_2": + print("RPI_L: RPICam Received Accel_2, Proceed to Safe Shutdown") + state = "SHUTDOWN" + else: + print("RPI_L: ERROR: Accel_2 Not Acquired, Proceed to Safe Shutdown") + state = "SHUTDOWN" + except: + print("RPI_L: ACCEL ERROR") + state = "SHUTDOWN" + + elif state == "SHUTDOWN": + run_counter = run_counter + 1 + wfile = open(RUN_LOG_PATH, "w") + wfile.write(str(run_counter)) + wfile.close() + + print("RPI_L: Defer to Arduino for Power Control") + time.sleep(10) + subprocess.call(["shutdown", "-h", "now"]) + + elif state == "SYNC_SHUTDOWN": + if t_sleep_sec == -1: + print("RPI_L: Will Reattempt Sync") + else: + run_counter = run_counter + 1 + wfile = open(RUN_LOG_PATH, "w") + wfile.write(str(run_counter)) + wfile.close() + time.sleep(t_sleep_sec) + GPIO.output(pMap[16], GPIO.HIGH) + print("RPI_L: pin 16 HIGH") + time.sleep(1) + subprocess.call(['shutdown', '-h', 'now']) + + except KeyboardInterrupt: + print('User KeyBoard Interrupt, Proceeding to Shutdown') + time.sleep(10) + subprocess.call(["shutdown", "-h", "now"]) + + +if __name__ == "__main__": + main() + + + + + + + + + + diff --git a/Nov_27/Full/Laser/transfer_test_correct_config/Read_Accel.py b/Nov_27/Full/Laser/transfer_test_correct_config/Read_Accel.py new file mode 100644 index 0000000..0e9ccf4 --- /dev/null +++ b/Nov_27/Full/Laser/transfer_test_correct_config/Read_Accel.py @@ -0,0 +1,19 @@ +from SETTINGS import * +import sys +from math import atan,sqrt,sin,cos +sys.path.insert(0,ACCELEROMETER) +from accel import extract_meas + +grav = 9.81 + +def read_accel(): + x_vec,y_vec,z_vec = extract_meas() + x = float(sum(x_vec))/float(len(x_vec)) + y = float(sum(y_vec))/float(len(y_vec)) + z = float(sum(z_vec))/float(len(z_vec)) + pitch = atan(x/(sqrt(z**2 + y**2))) #angle forward from vert [x,y flat, z vert] + #roll = atan(y/(sqrt(x**2 + z**2))) #angle side from vert [x,y flat, z vert] + return pitch + + + diff --git a/Nov_27/Full/Laser/transfer_test_correct_config/SETTINGS.py b/Nov_27/Full/Laser/transfer_test_correct_config/SETTINGS.py new file mode 100644 index 0000000..210b3ba --- /dev/null +++ b/Nov_27/Full/Laser/transfer_test_correct_config/SETTINGS.py @@ -0,0 +1,21 @@ +import os + +BASE_DIR = '/home/pi/Desktop/Full/' + +ACCELEROMETER = os.path.join(BASE_DIR, "accel_correct_config") +RUN_LOG_PATH = os.path.join(BASE_DIR, "transfer_test_correct_config/run_log.txt") + +#For RPI_L.py + +#RPI_L_IP = "192.168.3.3" #address of cam module (client) +RPI_C_IP = "192.168.15.104" #when hooked to Netgear Switch (Phil) +RPI_L_IP = "192.168.15.103" #when hooked to Netgear Switch (Phil) +RPI_L_Port = 1234 +RPI_C_Port = 1234 +Laser_Port = 11 +marker = "?" +query_time = 5 +re_sync = 3 +pi = 3.1415926535897932 + +pMap = {3:2,5:3,7:4,8:14,10:15,11:17,12:18,13:27,15:22,16:23,18:24,19:10,21:9,22:25,23:11,24:8,26:7} diff --git a/Nov_27/Full/Laser/transfer_test_correct_config/client_socket_connect_new.py b/Nov_27/Full/Laser/transfer_test_correct_config/client_socket_connect_new.py new file mode 100644 index 0000000..6ce00d4 --- /dev/null +++ b/Nov_27/Full/Laser/transfer_test_correct_config/client_socket_connect_new.py @@ -0,0 +1,73 @@ +from SETTINGS import * +import socket, time, sys, select, traceback, Queue + +max_count = 40 + +def client_socket(send_msg = ''): + + rcv = [] + print("RPI_L: Establishing Client Socket...") + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setblocking(0) + sock.settimeout(max_count * query_time) + + try: + for i in range(0,max_count-1): + try: + print("RPI_L: Waiting for RPICam to Come On..." + str(i) + "/" + str(max_count-1)) + sock.connect((RPI_C_IP, RPI_C_Port)) + print("RPI_L: Link Established") + break + except: + time.sleep(query_time) + except KeyboardInterrupt: + if sock: + sock.close() + except: + traceback.print_exc(file=sys.stdout) + + try: + try: + print("RPI_L: Sending Data") + sock.send(send_msg) + print("RPI_L: Data Sent") + count = 0 + while True: + print("RPI_L: Reading Data...") + if count < max_count: + try: + #print("trying...") + msg = sock.recv(1) + #print("msg: " + str(msg)) + if marker in msg: + rcv.append(msg[:msg.find(marker)]) + break + rcv.append(msg) + count = count + 1 + except KeyboardInterrupt: + if sock: + sock.close() + break + except: + print("RPI_L: ERROR: Reading Interrupted") + break + sock.close() + except KeyboardInterrupt: + if sock: + sock.close() + except: + traceback.print_exc(file=sys.stdout) + print("RPI_L: Connect Attempt Failed") + if sock: + sock.close() + sock = -1 + except KeyboardInterrupt: + sock.close() + except: + if i == max_count - 1: + print("RPI_L: RPI_C Never Connected") + traceback.print_exc(file=sys.stdout) + + return rcv + + diff --git a/Nov_27/Full/Laser/transfer_test_correct_config/slaveSleep.py b/Nov_27/Full/Laser/transfer_test_correct_config/slaveSleep.py new file mode 100644 index 0000000..9d0b0c8 --- /dev/null +++ b/Nov_27/Full/Laser/transfer_test_correct_config/slaveSleep.py @@ -0,0 +1,77 @@ +import socket, time, sys, subprocess +import RPi.GPIO as GPIO +from SETTINGS import * + +def slaveSleep(pMap): + max_count = 30 + + # Configure board pin numbering system + GPIO.setmode(GPIO.BCM) + # Setup pin 12 to high so upon shutdown the pin drops and notifies the Arduino to cut power + GPIO.setup(pMap[12],GPIO.OUT) + GPIO.output(pMap[12],GPIO.HIGH) + # Set up pin 16 as clock output + GPIO.setup(pMap[16],GPIO.OUT) + GPIO.output(pMap[16],GPIO.LOW) + print("RPI_L: 16 Low, 12 High") + + # Set up socket and connect to the server + client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + client.setblocking(0) + client.settimeout(query_time*max_count) + #client.connect(('192.168.15.104',1234)) + + for i in range(0, max_count - 1): + try: + client.connect((RPI_C_IP, RPI_C_Port)) + break + except: + time.sleep(query_time) + + # Receive t1 from Master, at t1p + t1b = client.recv(16) # Receive t1 value + t2p = time.time() # Get time of delivery of t1, which is t2p + + t3p = time.time() # Get time t3p, send notification to Master + client.send(str.encode(str(int(time.time()*10**6)))) + + t4b = client.recv(16) + + # Now we have all times, t1, t2p, t3p, t4 + + t1 = int(t1b.decode()) + t2p = int(t2p*10**6) + t3p = int(t3p*10**6) + t4 = int(t4b) + + + print('t1: ' + str(t1)) + print('t2p: ' + str(t2p)) + print('t3p: ' + str(t3p)) + print('t4: ' + str(t4)) + + r = 30 # transmission time, microseconds + + e = t2p - t1 - (r / 2) + + print('Error Estimate: ' + str(e)) + + + #print(str(t1 - t2p)) + + # This is the synchronization code for the CalTrans bridge start up + t_awake = int(client.recv(16)) + + t_sleep = t_awake - int(time.time()*10**6) + e + + print('t_sleep: ' + str(t_sleep)) + + t_sleep_sec = t_sleep / 10.0**6 + + print('sleep time: ' + str(t_sleep_sec)) + + client.close() + + return t_sleep_sec + + diff --git a/Nov_27/Manual/Camera/RPiCam/._RPiCM.py b/Nov_27/Manual/Camera/RPiCam/._RPiCM.py new file mode 100644 index 0000000..540a5a9 Binary files /dev/null and b/Nov_27/Manual/Camera/RPiCam/._RPiCM.py differ diff --git a/Nov_27/Manual/Camera/RPiCam/._img_capture.py b/Nov_27/Manual/Camera/RPiCam/._img_capture.py new file mode 100644 index 0000000..cdc2139 Binary files /dev/null and b/Nov_27/Manual/Camera/RPiCam/._img_capture.py differ diff --git a/Nov_27/Manual/Camera/RPiCam/RPiCM.py b/Nov_27/Manual/Camera/RPiCam/RPiCM.py new file mode 100644 index 0000000..ca837ac --- /dev/null +++ b/Nov_27/Manual/Camera/RPiCam/RPiCM.py @@ -0,0 +1,174 @@ +# Author: Alex R. Mead +# Date: May 2016 +# Description: +# This code will run on the Raspberry Pi 2 with Camera Module (RPiCM) to interact with the MacBookPro (MBP). It will +# wait for the MBP to request a measurement, take a measurement, then wait for the MBP to request the latest +# measurement, at which time it will send the measurement to the MBP. + +# Same as the MBP this system is designed to run like finite state machine. + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) + +import sys +import socket +import io +import subprocess +import picamera +import numpy as np +import gc +from time import sleep + +# Constants +#IP = '127.0.0.1' # Testing on a single machine +IP = '0.0.0.0' # Actual run time. +port1 = 1234 +port2 = 2345 +marker = "?" + +MAX_PIXEL_VALUE = 1023 # 2^10 = 1024 +PIXEL_HEIGHT = 1944 +PIXEL_WIDTH = 2592 + +# Takes in the Camera object instantiated at the beginning of the run and takes the desired SS expsoures with it. +def HDRI(SS,camera): + + size = len(SS) + print("Taking %i measurements.\n",size) + names = [] + + # Loop through for each shutter speed requested + for index, shutterSpeed in enumerate(SS): + fileName = str(shutterSpeed) + ".data" + camera.shutter_speed = shutterSpeed + sleep(1) + print(str(camera.shutter_speed)) + camera.capture(fileName,format='jpeg',bayer=True) + names.append(fileName) + + # Return the list of filenames to the calling function. + return names + +def main(): + + STATE = "idle" + RUNNING = [True,0] + + # First declare the camera object and configure it as needed + camera = picamera.PiCamera() + camera.framerate=1 + sleep(1.0) + + camera.led = False + camera.iso = 100 + sleep(10.0) + # This longer sleep is needed so analog_gain and digital_gains settle so when I turn them off in the next step + # they will have settled and not be in their initial 'low' values. + + camera.exposure_mode = 'off' # Fixes analog_gain and digital_gain values + g = camera.awb_gains + camera.aws_mode = 'off' + camera.awb_gains = [1.0,1.0] # typical values 0.9-1.9 according to documentation, I picked these for consistency. + camera.rotation = 180 + sleep(2.0) + + while(RUNNING[0]): + + if("idle" == STATE): + print("We're in idle state waiting to hear from the MacBookPro...") + + # Start up a connection listening for the MBP. + sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) + sock.bind((IP,port1)) + sock.listen(1) + connection, client_address = sock.accept() + + rcv_msg = [] + while True: + data = connection.recv(1) + if marker in data: + rcv_msg.append(data[:data.find(marker)]) + break + rcv_msg.append(data) + + # Check the message received from the MBP, if correct, continue, else exit. + rpl = ''.join(rcv_msg) + if rpl == "True": + print("Now going to acknowledge measurement.") + + # elif used to teminate remotely. + elif rpl == "c": + print("Big John called it for me...") + sys.exit(0) + + # Acknowledge the MBP so it knows a measurement will be taking place. + connection.send("True?") + connection.close() + + # Change state: Continue on and take measurement + STATE ="Measuring" + + elif ("Measuring" == STATE): + print("Engaging the Camera Module to measure the output of the CFS under test...") + # Here is the function call to take the measurement of the CFS inside CUBE2.0 + + # List of the shutter speeds in microseconds to be used + #SS = [1000000, 100000, 10000, 1000, 100, 10]; + SS = [1000000, 100000, 10000]; + + # Take the measurements with the above stated shutter speeds + files = HDRI(SS,camera) + + print("...Measurement taken of CFS.\n") + + # Continue to the next state and wait for MBP to query for the 145 measurements. + STATE = "waitToSend" + + elif("waitToSend" == STATE): + print("Waiting to send to MBP...") + # Setup connection to wait for the request from the MBP + # This maybe a short wait as the MBP may be trying to connect already if the Measurememt was a long time. + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind((IP, port2)) + sock.listen(1) + connection, client_address = sock.accept() + + rcv_msg = [] + while True: + data = connection.recv(1) + if marker in data: + rcv_msg.append(data[:data.find(marker)]) + break + rcv_msg.append(data) + + # Check the message received from the MBP, if correct, continue, else exit. + rpl = ''.join(rcv_msg) + if rpl == "True": + print("Send measurement.") + + # Now use the same connection to let the MBP know it can grab the .jpg+RAW + # files and run RPiCM_C.c locally over there, which is MUCH faster. + connection.sendall("True?") + connection.close() + + print("...measurment has been sent.\n") + + # Change state: measurement has been sent, change state back to idle + STATE = "idle" + + # Cycle counter for the finite state machine + RUNNING[1] = RUNNING[1] + 1 + print("Cycle number: " + str(RUNNING[1])) + + print("Little John called it...") + sys.exit(0) + +if __name__ == "__main__": + main() + diff --git a/Nov_27/Manual/Camera/RPiCam/cam.py b/Nov_27/Manual/Camera/RPiCam/cam.py new file mode 100644 index 0000000..c91e666 --- /dev/null +++ b/Nov_27/Manual/Camera/RPiCam/cam.py @@ -0,0 +1,32 @@ +import picamera +from fractions import Fraction + +cam = picamera.PiCamera(resolution=(640, 480)) +cam.exposure_mode = 'off' +DEBUG_DIR = 'debug/' +filename = DEBUG_DIR + 'shutter_{0}_iso_{1}_expo_{2}.png' +cam.capture("base.png") +cam.framerate = Fraction(1, 6) +while True: + try: + exp = input("Run experiment?[y/n] ") + if exp == 'y': + ss = input("shutter speed: ") + iso = input("iso: ") + options = {'a': 'off', 'b': 'auto', 'c': 'night', 'd': 'night_preview', 'e': 'sports'} + expo = input("exposure mode: " + str(options) + " ") + #bright = input("brightness: ") + ss, iso, opt = int(ss), int(iso), options[expo] + cam.shutter_speed = ss + cam.iso = iso + cam.exposure_mode = options[expo] + #cam.brightness = bright + cam.capture(filename.format(ss, iso, opt)) + else: + cam.close() + break + except ValueError: + pass + + + diff --git a/Nov_27/Manual/Camera/RPiCam/img_capture.py b/Nov_27/Manual/Camera/RPiCam/img_capture.py new file mode 100644 index 0000000..86fd14a --- /dev/null +++ b/Nov_27/Manual/Camera/RPiCam/img_capture.py @@ -0,0 +1,186 @@ +import picamera +import os +from fractions import Fraction +import sys, traceback +import time + + +class ImgCollector: + + def __init__(self, dir='', ns='img', form='png', raw=False, num=1, serialize=True): + if dir: + if not os.path.exists(dir): + os.mkdir(dir) + if dir[len(dir)-1] != '/': + dir += '/' + + self.name_scheme = dir + ns + '_{0}.' + form + self._dir = dir + self._ns = ns + self._form = form + self._raw = raw + self._num = num + self.init_cam() + if serialize: + if os.path.exists("img_log.txt"): + rfile = open("img_log.txt", "r") + try: + self.counter = int(rfile.read()) + except ValueError: + self.counter = 1 + else: + rfile = open("img_log.txt", "w") + self.counter = 1 + rfile.close() + else: + self.counter = 1 + + + def change_ns(self, ns): + self._ns = ns + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_format(self, form): + self._form = form + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_dir(self, dir): + self._dir = dir + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_num(self, num): + self._num = num + if self._num == 1: + self.capture = self.uni_capture + else: + self.capture = self.multi_capture + + def init_cam(self): + self.cam = picamera.PiCamera(resolution=(640, 480)) + time.sleep(2) + self.cam.led = False + self.cam.framerate = Fraction(1, 6) + self.cam.rotation = 180 + self.cam.shutter_speed = 800000 + self.cam.iso = 100 + self.cam.exposure_mode = 'off' + time.sleep(3) + if self._num == 1: + self.capture = self.uni_capture + else: + self.capture = self.multi_capture + + def get_last_meas(self): + if self._num == 1: + return self.name_scheme.format(self.counter - 1) + else: + return self._dir + self._ns + '_%d_{0}.' % (self.counter - 1) + self._form + + def shutdown(self): + self.cam.close() + wfile = open("img_log.txt", "w") + wfile.write(str(self.counter)) + wfile.close() + + def uni_capture(self): + self.cam.capture(self.name_scheme.format(self.counter), bayer=self._raw) + self.counter += 1 + + def multi_capture(self): + file_list = [self.name_scheme.format("%d_%d" % (self.counter, i)) for i in range(1, self._num+1)] + self.cam.capture_sequence(file_list, bayer=self._raw) + self.counter += 1 + + +def main(): + prompt = input("Welcome to the RPiCam Module. Type q for quick test, d for debug, or f / [other inputs] for full test.\n") + global recur + if prompt == 'q': + directory = 'quick_test' + name_pattern = 'img' + pic_format = 'png' + raw_image = False + num_meas = 1 + recur = True + elif prompt == 'd': + camera_debug() + sys.exit() + else: + directory = input("Input a directory:\n") + name_pattern = input("Input a name pattern:\n") + pic_format = input("Input a picture format:\n") + raw_image = input("Raw image?[y/n]\n") in ['y', 'yes'] + num_meas = int(input("Number of image samples for one measurement?\n")) + recur = False + + while True: + try: + ic = ImgCollector(dir=directory, ns=name_pattern, form=pic_format, raw=raw_image, num=num_meas) + break + except: + directory = input("Ill-formated directory, type in another one: ") + traceback.print_exc(file=sys.stdout) + + while True: + if recur: + ic.shutdown() + break + + option = input("Type in an action or h for help:\n") + if option == 'h': + print("m: take measurement\n" + + "r: show raw image status\n" + + "cr: change raw image status\n" + + "cf: change image format\n" + + "cd: change directory\n" + + "cn: change name\n" + + "cm: change number of measurement\n" + + "e: end the program") + elif option == 'm': + ic.capture() + elif option == 'r': + print(ic._raw) + elif option == 'cr': + ic._raw = input("Raw image?[y/n]\n") in ['y', 'yes'] + elif option == 'cf': + ic.change_format(input("Input a picture format:\n")) + elif option == 'cd': + ic.change_dir(input("Input a directory:\n")) + elif option == 'cn': + ic.change_ns(input("Input a name pattern:\n")) + elif option == 'cm': + ic.change_num(int(input("Number of image samples for one measurement?\n"))) + elif option == 'e': + ic.shutdown() + break + + +def camera_debug(): + DEBUG_DIR = 'debug/' + filename = DEBUG_DIR + 'shutter_{0}_iso_{1}_bright_{2}.jpeg' + analog = 'analog_gain: ' + awb_gain = 'awb_gain: ' + expo_modes = ['night', 'night_preview', 'very_long'] + #flash_modes = ['off', 'redeye'] + flash_modes = ['off'] + shutter = [600000, 800000, 1000000] + with picamera.PiCamera(resolution=(640, 480)) as cam: + time.sleep(1) + print(analog + str(cam.analog_gain)) + print(awb_gain + str(cam.awb_gains)) + cam.framerate = Fraction(1, 6) + for ss in shutter: + #for br in brightness: + time.sleep(0.1) + cam.shutter_speed = ss + cam.brightness = 50 + cam.capture(filename.format(ss), bayer=False) + + +if __name__ == "__main__": + recur = True + while recur: + main() + + + diff --git a/Nov_27/Manual/Camera/accel_correct_config/LICENSE b/Nov_27/Manual/Camera/accel_correct_config/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/Nov_27/Manual/Camera/accel_correct_config/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Nov_27/Manual/Camera/accel_correct_config/accel.py b/Nov_27/Manual/Camera/accel_correct_config/accel.py new file mode 100644 index 0000000..331c0c6 --- /dev/null +++ b/Nov_27/Manual/Camera/accel_correct_config/accel.py @@ -0,0 +1,739 @@ +#!/usr/bin/env python +# -*- coding:utf-8, indent=tab, tabstop=4 -*- +# +# See 'LICENSE' for copying +# +# Revision history +# Date Author Version Details +# ---------------------------------------------------------------------------------- +# 2016-12-31 Massimo Di Primio V.0.04 Fixed some basic functionality +# +# 2017-01-03 Massimo Di Primio 0.05 Added Interrut handler +# +# 2018-01-10 Massimo Di Primio 0.06 Added config file parser + +"""Simple code example for Adafruit MMA8452 3-axis Accelerometer + +This experimental code is intended for measuring gravity acceleration trough Adafruit(c) MMA8451, connected +to a Raspberry Pi Model 2A, 2B, 2B+ or 3 (not yet tested with RPi Zero). +Through this code we will demonstrate the ability of the 3-axis sensor MMA8451 to efficiently measure +gravity acceleration, so that we can identify the spatial orientation of the device. +Further and even more useful application can start from this minimal basic code. +""" + +import smbus +import time +import datetime +import os +import sys +import logging +import threading +import RPi.GPIO as GPIO +import rss_cli_config as clicfg +from collections import deque + +__author__ = "Massimo Di Primio" +__copyright__ = "Copyright 2016, dpmiictc" +__credits__ = ["Massimo Di Primio", "Dario Dalla Libera"] +__license__ = "GNU GENERAL PUBLIC LICENSE Version 3" +__version__ = "0.0.1" +__deprecated__ = "None so far" +__date__ = "2017-01-03" +__maintainer__ = "Massimo Di Primio" +__email__ = "massimo@diprimio.com" +__status__ = "Testing" +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# User Configuration Options (UCO) +# This section will be repaced soon by an external configuration file +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CFG_INTERRUPT = 1 +# MMA8451_RANGE = {} + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Application Definition Constants (ADC) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Useful definitions +EARTH_GRAVITY_MS2 = 9.80665 + +# Range values +RANGE_8_G = 0b10 # +/- 8g +RANGE_4_G = 0b01 # +/- 4g +RANGE_2_G = 0b00 # +/- 2g (default value) + +RANGE_DIVIDER = { + RANGE_2_G: 4096 / EARTH_GRAVITY_MS2, + RANGE_4_G: 2048 / EARTH_GRAVITY_MS2, + RANGE_8_G: 1024 / EARTH_GRAVITY_MS2, +} + +# Some static values +deviceName = 0x1a + +# Various addresses +i2caddr = 0x1D +# +# Useful Register Address +REG_STATUS = 0x00 # Read-Only +REG_WHOAMI = 0x0d # Read-Only +REG_DEVID = 0x1A # Read-Only +REG_OUT_X_MSB = 0x01 # Read-Only +REG_OUT_X_LSB = 0x02 # Read-Only +REG_OUT_Y_MSB = 0x03 # Read-Only +REG_OUT_Y_LSB = 0x04 # Read-Only +REG_OUT_Z_MSB = 0x05 # Read-Only +REG_OUT_Z_LSB = 0x06 # Read-Only +REG_F_SETUP = 0x09 # Read/Write +REG_XYZ_DATA_CFG = 0x0e # Read/Write +REG_PL_STATUS = 0x10 # Read-Only +REG_PL_CFG = 0x11 # Read/Write +REG_CTRL_REG1 = 0x2A # Read/Write +REG_CTRL_REG2 = 0x2B # Read/Write +REG_CTRL_REG3 = 0x2C # Read/Write +REG_CTRL_REG4 = 0x2D # Read/Write +REG_CTRL_REG5 = 0x2E # Read/Write + +REDUCED_NOISE_MODE = 0 +OVERSAMPLING_MODE = 1 +HIGH_RES_MODE = { + REDUCED_NOISE_MODE: [REG_CTRL_REG1, 0x4], + OVERSAMPLING_MODE: [REG_CTRL_REG2, 0x2], +} + +# Auto-Wake Sample Frequencies for Register CTRL_REG1 (0x2A) (Read/Write) +# sample frequency when the device is in SLEEP Mode. Default value: 00. +ASLP_RATE_FREQ_50_HZ = 0x00 +ASLP_RATE_FREQ_12_5_HZ = 0x40 +ASLP_RATE_FREQ_6_25HZ = 0x80 +ASLP_RATE_FREQ_1_56_HZ = 0xc0 + +# Data rate values +DATARATE_800_HZ = 0x00 # 800Hz +DATARATE_400_HZ = 0x08 # 400Hz +DATARATE_200_HZ = 0x10 # 200Hz +DATARATE_100_HZ = 0x18 # 100Hz +DATARATE_50_HZ = 0x20 # 50Hz +DATARATE_12_5_HZ = 0x28 # 12.5Hz +DATARATE_6_25HZ = 0x30 # 6.25Hz +DATARATE_1_56_HZ = 0x38 # 1.56Hz + +# Orientation labeling +PL_PUF = 0 +PL_PUB = 1 +PL_PDF = 2 +PL_PDB = 3 +PL_LRF = 4 +PL_LRB = 5 +PL_LLF = 6 +PL_LLB = 7 + +# Precision +PRECISION_14_BIT = 14 +PRECISION_08_BIT = 8 + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define Register Flags +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Register CTRL_REG1 (0x2a) R/W - System Control 1 Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | ASLPRATE1 | ASLPRATE0 | DR2 | DR1 | DR0 | LNOISE | F_READ | ACTIVE | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Auto-Wake Sample frequency Selection +FLAG_ASLPRATE_50_HZ = 0x00 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 50 Hz +FLAG_ASLPRATE_12_5_HZ = 0x40 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 12.5 Hz +FLAG_ASLPRATE_6_25_HZ = 0x80 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 6.25 Hz +FLAG_ASLPRATE_1_56_HZ = 0xc0 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 1.56 Hz +# System Output Data Rates Selection +FLAG_ODR_800_HZ = 0x00 # System Output Data Rate 800 Hz +FLAG_ODR_400_HZ = 0x08 # System Output Data Rate 400 Hz +FLAG_ODR_200_HZ = 0x10 # System Output Data Rate 200 Hz +FLAG_ODR_100_HZ = 0x18 # System Output Data Rate 100 Hz +FLAG_ODR_50_HZ = 0x20 # System Output Data Rate 50 Hz +FLAG_ODR_12_5_HZ = 0x28 # System Output Data Rate 12.5 Hz +FLAG_ODR_6_25_HZ = 0x30 # System Output Data Rate 6.25 Hz +FLAG_ODR_1_56_HZ = 0x38 # System Output Data Rate 1.56 Hz +# Other Flags +FLAG_LNOISE = 0x04 # Low Noise (1: Reduced Noise, 0: Normal Mode) +FLAG_F_READ = 0x02 # Fast Read (1: 8 bit sample, 0: 14 bit Sample) +FLAG_ACTIVE = 0x01 # Active (1: ACTIVE Mode, 0: STANDBY Mode) + +# Register CTRL_REG2 (0x2b) R/W - System Control 2 Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | ST | RST | 0 | SMODS1 | SMODS0 | SLPE | MODS1 | MODS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Other Flags +FLAG_STEST = 0x80 # Self Test (1: Self-Test enabled, 0: Self-Test disabled) +FLAG_RESET = 0x40 # Reset (1: Reset enabled, 0: Reset disabled) +# Sleep Mode Power Scheme Selection +FLAG_SMODS_NORM = 0x00 # Sleep Mode Power Scheme Selection: Normal +FLAG_SMODS_LNLP = 0x0a # Sleep Mode Power Scheme Selection: Low-Noise Low Power +FLAG_SMODS_HR = 0x12 # Sleep Mode Power Scheme Selection: High Resolution +FLAG_SMODS_LP = 0x1b # Sleep Mode Power Scheme Selection: Low Power +# Other Flags +FLAG_SLPE = 0x04 # Auto-Sleep (1: Auto-Sleep enabled, 0: Auto-Sleep Disabled) +# Active Mode Power Scheme Selection (for both: Sleep and Active mode) +FLAG_MODS_NORM = 0x00 # Active Mode Power Scheme Selection: Normal +FLAG_MODS_LNLP = 0x09 # Active Mode Power Scheme Selection: Low-Noise Low Power +FLAG_MODS_HR = 0x12 # Active Mode Power Scheme Selection: High Resolution +FLAG_MODS_LP = 0x1b # Active Mode Power Scheme Selection: Low Power + +# Register CTRL_REG4 (0x2d) R/W - Interrupt Enable Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | INT_EN_ASLP | INT_EN_FIFO |INT_EN_TRANS |INT_EN_LNDPR |INT_EN_PULSE |INT_EN_FF_MT | - | INT_EN_DRDY | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_INT_EN_ASLP = 0x80 # Interrupt Auto SLEEP/WAKE (0: Disabled, 1: Enabled) +FLAG_INT_EN_FIFO = 0x40 # Interrupt FIFO (0: Disabled, 1: Enabled) +FLAG_INT_EN_TRANS = 0x20 # Interrupt Transient (0: Disabled, 1: Enabled) +FLAG_INT_EN_LNDPRT = 0x10 # Interrupt Orientation (0: Disabled, 1: Enabled) +FLAG_INT_EN_PULSE = 0x08 # Interrupt Pulse Detection (0: Disabled, 1: Enabled) +FLAG_INT_EN_FF_MT = 0x04 # Interrupt Freefall/Motion (0: Disabled, 1: Enabled) +FLAG_INT_EN_BIT1 = 0x00 # Not Used +FLAG_INT_EN_DRDY = 0x01 # Interrupt Data Ready (0: Disabled, 1: Enabled) + +# Register CTRL_REG5 (0x2e) R/W - Interrupt Configuration Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | INT_CFG_ASLP | INT_CFG_FIFO |INT_CFG_TRANS |INT_CFG_LNDPRT|INT_CFG_PULSE |INT_CFG_FF_MT | - | INT_CFG_DRDY | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_INT_CFG_ASLP = 0x80 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_FIFO = 0x40 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_TRANS = 0x20 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_LNDPRT = 0x10 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_PULSE = 0x08 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_FF_MT = 0x04 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_BIT1 = 0x00 # Not Used +FLAG_INT_CFG_DRDY = 0x01 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) + +# Register XYZ_DATA_CFG (0x0e) R/W +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | 0 | 0 | 0 | HPF_OUT | 0 | 0 | FS1 | FS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Other Flags +FLAG_XYZ_DATA_BIT_7 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_6 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_5 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_HPF_OUT = 0x00 # High-Pass Filter (1: output data High-pass filtered, 0: output data High-pass NOT filtered) +FLAG_XYZ_DATA_BIT_3 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_2 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_FS_2G = 0x00 # Full Scale Range 2g +FLAG_XYZ_DATA_BIT_FS_4G = 0x01 # Full Scale Range 4g +FLAG_XYZ_DATA_BIT_FS_8G = 0x02 # Full Scale Range 8g +FLAG_XYZ_DATA_BIT_FS_RSVD = 0x03 # Reserved + +# Register F_SETUP (0x09) R/W - FIFO Setup Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | F_MODE1 | F_MODE0 | F_WMRK5 | F_WMRK4 | F_WMRK3 | F_WMRK2 | F_WMRK1 | F_WMRK0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_F_MODE_FIFO_NO = 0x00 # FIFO is disabled. +FLAG_F_MODE_FIFO_RECNT = 0x40 # FIFO contains the most recent samples when overflowed (circular buffer) +FLAG_F_MODE_FIFO_STOP = 0x80 # FIFO stops accepting new samples when overflowed. +FLAG_F_MODE_FIFO_TRIGGER = 0xc0 # FIFO Trigger mode + +# Register PL_STATUS (0x010) R/O - Portrait/Landscape Status Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | NEWLP | LO | - | - | - | LAPO[1] | LAPO[0] | BAFRO | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_PL_NEWLP = 0x80 # Landscape/Portrait status change flag. +FLAG_PL_LO = 0x40 # Z-Tilt Angle Lockout. +FLAG_PL_LAPO_PU = 0x00 # 00: Portrait Up: Equipment standing vertically in the normal orientation +FLAG_PL_LAPO_PD = 0x02 # 01: Portrait Down: Equipment standing vertically in the inverted orientation +FLAG_PL_LAPO_LR = 0x04 # 10: Landscape Right: Equipment is in landscape mode to the right +FLAG_PL_LAPO_LL = 0x06 # 11: Landscape Left: Equipment is in landscape mode to the left. +FLAG_PL_BAFRO = 0x01 # Back or Front orientation. (0: Front: Equipment is in the front facing orientation, 1: Back) + +# Register PL_CFG (0x011) R/W - Portrait/Landscape Configuration Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | DBCNTM | PL_EN | - | - | - | - | - | - | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_PL_CFG_DBCNTM = 0x80 # Debounce counter mode selection (0: Decrements debounce, 1: Clears counter) +FLAG_PL_CFG_PL_EN = 0x40 # Portrait/Landscape Detection Enable (0: P/L Detection Disabled, 1: P/L Detection Enabled) + +# Register TRANSIENT_CFG (0x1d) R/W - Transient_CFG Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | - | - | - | ELE | ZTEFE | YTEFE | XTEFE | HPF_BYP | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_TRANSIENT_CFG_ELE = 0x10 # Transient event flags (0: Event flag latch disabled; 1: Event flag latch enabled) +FLAG_TRANSIENT_CFG_ZTEFE = 0x08 # Event flag enable on Z (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_YTEFE = 0x04 # Event flag enable on Y (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_XTEFE = 0x02 # Event flag enable on X (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_HPF_BYP = 0x01 # Bypass High-Pass filter/Motion Detection + +# Register TRANSIENT_SCR (0x01e) R/O - TRANSIENT_SRC Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | - | EA | ZTRANSE | Z_Trans_Pol | YTRANSE | Y_Trans_Pol | XTRANSE | X_Trans_Pol | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_TRANSIENT_SCR_EA = 0x40 # Event Active Flag (0: no event flag has been asserted; 1: one or more event flag has been asserted) +FLAG_TRANSIENT_SCR_ZTRANSE = 0x20 # Z transient event (0: no interrupt, 1: Z Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_ZTR_POL = 0x10 # Polarity of Z Transient Event that triggered interrupt (0: Z event Positive g, 1: Z event Negative g) +FLAG_TRANSIENT_SCR_YTRANSE = 0x08 # Y transient event (0: no interrupt, 1: Y Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_YTR_POL = 0x04 # Polarity of Y Transient Event that triggered interrupt (0: Y event Positive g, 1: Y event Negative g) +FLAG_TRANSIENT_SCR_XTRANSE = 0x02 # X transient event (0: no interrupt, 1: X Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_XTR_POL = 0x01 # Polarity of X Transient Event that triggered interrupt (0: X event Positive g, 1: X event Negative g) + +# Register FF_MT_THS (0x017) R/W - Freefall and Motion Threshold Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | DBCNTM | THS6 | THS5 | THS4 | THS3 | THS2 | THS1 | THS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define SOME GLOBAL VARIABLES +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define the acceleration FIFO buffer +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# The acceleration FIFO buffer is a list of records containing all meaningful acceleration data plus some +# other useful information, whose format il as described below +# +# 1. curTime as returned by: datetime.datetime.now(). Format is: 'YYYY-MM-DD hh:mi:ss.uuuuuuu' +# 2. xAccel Current X acceleration value in row format +# 3. yAccel Current Y acceleration value in row format +# 4. xAccel Current Z acceleration value in row format +# 5. plo Current Portrait/Landscape orientation +#accelBuffer = [0, 0, 0, 0, 0] +accelBuffer = [] +#accelBuffer.append([0, 0, 0, 0, 0]) + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define the threaded interrupt vector +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +def my_callback(channel): + """ + my_callback is the threaded callback functions for interrupt events. + These will run in another thread when our events are detected + + :param channel: The GPIO channel where the interrupt event was risen + :return: None + """ + # Please nte that, for performance reasons, axis data are not convertd in m/s2, + # Although, all 6 registers containing acceleration data are read and formatted appropriately + bus = smbus.SMBus(1) + axisData = bus.read_i2c_block_data(i2caddr, REG_OUT_X_MSB, 6) + # + #print ("!"), #print("Falling edge detected on GPIO channel: " + str(channel)) + # + runTimeConfigObject.NumInterrupts = runTimeConfigObject.NumInterrupts + 1 + # + xAccel = ((axisData[0] << 8) | axisData[1]) >> 2 + yAccel = ((axisData[2] << 8) | axisData[3]) >> 2 + zAccel = ((axisData[4] << 8) | axisData[5]) >> 2 + plo = bus.read_byte_data(i2caddr, REG_PL_STATUS) & 0x7 + # Append data to the accelBuffer + accelBuffer.append([str(datetime.datetime.now()), xAccel, yAccel, zAccel, plo]) + pass + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define a class called Accel +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +import ConfigParser +class Accel(): + raspiBus = -1 # The Raspberry Pi Bus (dpends on hardware model) + raspiIntEnabled = 0 # 0 = Interrupt routine was not enabled after initialization, 1 = Interrupt routine enabled successfully + raspiInfo = "" # Raspberry Pi Info + + def __init__(self): + + # + # Setup RPI specific bus + # + myBus = "" + if GPIO.RPI_INFO['P1_REVISION'] == 1: + myBus = 0 + else: + myBus = 1 + #print('myBus=' + str(myBus)) + self.raspiBus = myBus + + self.b = smbus.SMBus(myBus) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1) + self.a = i2caddr + self.high_res_mode = OVERSAMPLING_MODE + self.sensor_range = RANGE_4_G + self.raspiInfo = GPIO.RPI_INFO + + + def whoAmI(self): + return self.b.read_byte_data(i2caddr, REG_WHOAMI) + + def init(self): + # Preliminary actions + # sudo chmod 666 /sys/module/i2c_bcm2708/parameters/combined + # sudo echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined + # + # the above 2 sh commands can be replaced with the following statements, in the case this program is ran as root (sudo) + # (For more information, please see: http://raspberrypi.znix.com/hipidocs/topic_i2c_rs_and_cs.htm) + # + # BCM2708_COMBINED_PARAM_PATH = '/sys/module/i2c_bcm2708/parameters/combined' + # os.chmod(BCM2708_COMBINED_PARAM_PATH, 666) + # os.system('echo -n 1 > {!s}'.format(BCM2708_COMBINED_PARAM_PATH)) + # sudo i2cdetect -y 1 # this sh cmmand will search /dev/i2c-1 for all address + # sudo i2cget -y 1 0x1d 0x0d # This sh command should return 0x1a for MMA8451 + # + # Setup all registers appropriately + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_RESET) # Reset + # self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_STEST) # SelfTest + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) & ~FLAG_ACTIVE) # Put the device in Standby + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) & ~FLAG_F_READ) # No Fast-Read (14-bits), Fast-Read (8-Bits) + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_ODR_50_HZ) # Data Rate + self.writeRegister(REG_XYZ_DATA_CFG, self.readRegister(REG_XYZ_DATA_CFG) | FLAG_XYZ_DATA_BIT_FS_4G) # Full Scale Range 2g, 4g or 8g + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_LNOISE) # Low Noise + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) & ~FLAG_SLPE) # No Auto-Sleep + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_SMODS_HR) # High Resolution + self.writeRegister(REG_PL_CFG, self.readRegister(REG_PL_CFG) | FLAG_PL_CFG_PL_EN) # P/L Detection Enabled + + # Setup interrupts + if CFG_INTERRUPT == 1: + GPIO.setmode(GPIO.BCM) + # GPIO 23 & 17 set up as inputs, pulled up to avoid false detection. + # Both ports are wired to connect to GND on button press. + # So we'll be setting up falling edge detection for both + GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP) + # when a falling edge is detected on port 17, regardless of whatever + # else is happening in the program, the function my_callback will be run + # GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback, bouncetime=300) + GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback) + #print("Interrupt OK") + self.raspiIntEnabled = 1 # Interrupt enabled successfully + # Force 1st sensor read + my_callback(0) + + + # Configure register for interrupt + self.writeRegister(REG_CTRL_REG4, 0x00) # Reset all interrupt enabled flags + self.writeRegister(REG_CTRL_REG4, self.readRegister(REG_CTRL_REG4) | FLAG_INT_EN_DRDY) # Data Ready Interrupt Enabled + self.writeRegister(REG_CTRL_REG5, 0x00) # Reset all interrupt config flags + self.writeRegister(REG_CTRL_REG5, self.readRegister(REG_CTRL_REG5) | FLAG_INT_CFG_DRDY) # Data Ready Interrupt is routed to INT1 pin + + # Initialize the accelBuffer + accelBuffer = deque() + + + # Finally, Activate the sensor + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_ACTIVE) # Activate the device + + def writeRegister(self, regNumber, regData): + """ + Writes one byte (8-bts) of data passed in 'regData', into the register 'regNumber' + """ + try: + self.b.write_byte_data(self.a, regNumber, regData) + time.sleep(0.01) + except IOError: + print("Error detected in function writeRegister() [IOError = " + str(IOError) + "]") + sys.exit() + + def readRegister(self, regNumber): + """ + Retrieves one byte (8-bits) of data from register 'regNumber' returning to the caller + """ + try: + return self.b.read_byte_data(self.a, regNumber) + except IOError: + print("Error detected in function readRegister() [IOError = " + str(IOError) + "]") + sys.exit() + + def block_read(self, offset, length): + """ + Performs a burst-read on the device registers retrieving the requested amount of data + Read a block of bytes from offset + """ + try: + return self.b.read_i2c_block_data(i2caddr, offset, length) + except IOError: + print("Error detected in function block_read() [IOError = " + str(IOError) + "]") + sys.exit() + + def get_orientation(self): + """ + Get current orientation of the sensor. + :return: orientation. Orientation number for the sensor. + """ + orientation = self.b.read_byte_data(self.a, REG_PL_STATUS) & 0x7 + return orientation + + def getAxisValue(self): + """ + Retrieves axis values and converts into a readable format (i.e. m/s2) + :return: None + """ + # Make sure F_READ and F_MODE are disabled. + f_read = self.b.read_byte_data(self.a, REG_CTRL_REG1) & FLAG_F_READ + assert f_read == 0, 'F_READ mode is not disabled. : %s' % (f_read) + f_mode = self.b.read_byte_data(self.a, REG_F_SETUP) & FLAG_F_MODE_FIFO_TRIGGER + assert f_mode == 0, 'F_MODE mode is not disabled. : %s' % (f_mode) + + # + self.xyzdata = self.block_read(REG_OUT_X_MSB, 6) + if self.high_res_mode is not None: + x = ((self.xyzdata[0] << 8) | self.xyzdata[1]) >> 2 + y = ((self.xyzdata[2] << 8) | self.xyzdata[3]) >> 2 + z = ((self.xyzdata[4] << 8) | self.xyzdata[5]) >> 2 + precision = PRECISION_14_BIT # Precision 14 bit data + else: + x = (self.xyzdata[0] << 8) + y = (self.xyzdata[1] << 8) + z = (self.xyzdata[2] << 8) + precision = PRECISION_08_BIT # Precision 08 bit data + max_val = 2 ** (precision - 1) - 1 + signed_max = 2 ** precision + # + x -= signed_max if x > max_val else 0 + y -= signed_max if y > max_val else 0 + z -= signed_max if z > max_val else 0 + # + x = round((float(x)) / RANGE_DIVIDER[self.sensor_range], 3) + y = round((float(y)) / RANGE_DIVIDER[self.sensor_range], 3) + z = round((float(z)) / RANGE_DIVIDER[self.sensor_range], 3) + + return {"x": x, "y": y, "z": z} + + def debugShowRpiInfo(self): + #print("Raspberry Info = " + str(GPIO.RPI_INFO)) + print("Raspberry Info = " + str(self.raspiInfo)) + + def debugShowRegisters(self): + print("REG_STATUS (0x00):" + str(format(self.readRegister(REG_STATUS), '#04x')) + " | Binary: " + format(self.readRegister(REG_STATUS), 'b').zfill(8)) + print("REG_WHOAMI (0x0d):" + str(format(self.readRegister(REG_WHOAMI), '#04x')) + " | Binary: " + format(self.readRegister(REG_WHOAMI), 'b').zfill(8)) + print("REG_F_SETUP (0x09):" + str(format(self.readRegister(REG_F_SETUP), '#04x')) + " | Binary: " + format(self.readRegister(REG_F_SETUP), 'b').zfill(8)) + print("REG_XYZ_DATA_CFG (0x0e):" + str(format(self.readRegister(REG_XYZ_DATA_CFG), '#04x')) + " | Binary: " + format(self.readRegister(REG_XYZ_DATA_CFG), 'b').zfill(8)) + print("REG_CTRL_REG1 (0x2a):" + str(format(self.readRegister(REG_CTRL_REG1), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG1), 'b').zfill(8)) + print("REG_CTRL_REG2 (0x2b):" + str(format(self.readRegister(REG_CTRL_REG2), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG2), 'b').zfill(8)) + print("REG_CTRL_REG3 (0x2c):" + str(format(self.readRegister(REG_CTRL_REG3), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG3), 'b').zfill(8)) + print("REG_CTRL_REG4 (0x2d):" + str(format(self.readRegister(REG_CTRL_REG4), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG4), 'b').zfill(8)) + print("REG_CTRL_REG5 (0x2e):" + str(format(self.readRegister(REG_CTRL_REG5), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG5), 'b').zfill(8)) + print("REG_PL_STATUS (0x10):" + str(format(self.readRegister(REG_PL_STATUS), '#04x')) + " | Binary: " + format(self.readRegister(REG_PL_STATUS), 'b').zfill(8)) + print ("debugRealTime " + str(runTimeConfigObject.debugRealTime)) + print ("NumInterrupts " + str(runTimeConfigObject.NumInterrupts)) + + def debugShowOrientation(self): + print("Position = %d" % (self.get_orientation())) + + def debugShowAxisAcceleration(self, xaccel, yaccel, zaccel): + print(" x (m/s2)= %+.3f" % (xaccel)) + print(" y (m/s2)= %+.3f" % (yaccel)) + print(" z (m/s2)= %+.3f" % (zaccel)) + + def debugRealTimeBuffer(self): + n = 0 + for elements in accelBuffer: + myData = accelBuffer.pop() + n += 1 + print ("N=" + str(n) + " myData=" + str(myData)) # + "Element=" + str(elements)) + try: + print("End of printout\n") + #time.sleep(1.0) + # os.system("clear") + except KeyboardInterrupt: + print("Program Termination Requested") + sys.exit() + +############################################################################### +# Threading functions +############################################################################### +#def rssClient(): +# """Manage data shipping over th network, in a separate thread.""" +# #logger.debug('Thread Starting') +# while True: +# time.sleep(1.0) +# print ("This is thread rssClient()") +# +############################################################################### +# Useful functions +############################################################################### +def printHelp(): + print ("\n") + print ("usage: accel.py [options]") + print ("Available options:") + print (" -h \t\t Print this help and exit") + print (" -d \t\t Show debug realtime interrupt data") + print (" -s \t\t Execute silently (no screen output)") + print (" -L \t Set Log level. where is the log level (0 = NONE - 8 = DEBUG)") + print ("") + + +def main(argv): + import sys, getopt, logging + # + try: + opts, args = getopt.getopt(argv,"hdsL:") + except getopt.GetoptError: + print ("\nInvalid option requested on command line") + printHelp() + sys.exit(2) + + for opt, arg in opts: + if opt == '-h': + printHelp() + sys.exit() + elif opt == '-d': + runTimeConfigObject.debugRealTime = 1 + elif opt == '-s': + runTimeConfigObject.executeSilently = 1 + elif opt == '-L': + if (int(arg) == 0) or (int(arg) > 5): + pass + #logger.setLevel(logger.NOTSET) # Same as value 0 + elif int(arg) == 1: + logger.setLevel(logging.CRITICAL) # Same as value 50 + elif int(arg) == 2: + logger.setLevel(logging.ERROR) # Same as value 40 + elif int(arg) == 3: + logger.setLevel(logging.WARNING) # Same as value 30 + elif int(arg) == 4: + logger.setLevel(logging.INFO) # Same as value 20 + elif int(arg) == 5: + logger.setLevel(logging.DEBUG) # Same as value 10 + + +##################################################################################### +# M A I N +##################################################################################### +class runTimeConfigObject(object): + pass +#if __name__ == "__main__": +def extract_meas(): + + #class runTimeConfigObject(object): + #pass + # + # Setup Logger + # + #logger = logging.basicConfig(level=logging.DEBUG, format='[%(asctime)15s].%(levelname)s] (%(threadName)-10s) %(message)s', ) + #logger.basicConfig(level=logging.DEBUG,format='[%(asctime)15s].%(levelname)s] (%(threadName)-10s) %(message)s',) + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + # create console handler and set level to debug + ch = logging.StreamHandler() + ch.setLevel(logging.DEBUG) + # create formatter + formatter = logging.Formatter('[%(asctime)s.%(levelname)s] (%(name)s.%(threadName)-10s) : %(message)s') + # add formatter to ch + ch.setFormatter(formatter) + # add ch to logger + logger.addHandler(ch) + + # + # Set some default command line options + # + runTimeConfig = runTimeConfigObject() + runTimeConfigObject.debugRealTime = 0 # 1 = Show debug realtime interrupt data + runTimeConfigObject.executeSilently = 0 # 1 = Execute silently (no sceen output) + runTimeConfigObject.NumInterrupts = 0 # keep Nbr of sensor interrupts withi the main loop + + main(sys.argv[1:]) + + # + # Read configuration file + # + configFile = "./rss_config.dat" + #logger.debug('Reading Config file: ' + configFile) #Commented out by Henry + sections = {'GeoData', 'DeviceInfo', 'Networking'} + #configParameters = {} + #Config = ConfigParser.ConfigParser() + #Config.read(configFile) + #for section in sections: + # try: + # options = Config.options(section) + # except: + # print ("ERROR: Section '" + section + "' Not found in config file: '" + configFile + "'.") + # sys.exit() + # for option in options: + # try: + # configParameters[option] = Config.get(section, option) + # except: + # configParameters[option] = None + # logger.debug("Config Section: " + section + " / Option: " + option + " => " + configParameters[option]) + + MMA8451 = Accel() + #os.system("clear") + MMA8451.init() + + if MMA8451.whoAmI() != deviceName: + print("Error! Device not recognized! (" + str(deviceName) + ")") + sys.exit() + + # + # Thread client start + # Commented out by Henry + ''' + import rss_client + pill2kill = threading.Event() + #threadClient = threading.Thread(name='netClientWorker', target=rss_client.cli_worker, args=(pill2kill, configParameters, accelBuffer)) + threadClient = threading.Thread(name='netClientWorker', target=rss_client.cli_worker, args=(pill2kill, accelBuffer)) + threadClient.setDaemon(False) #threadClient.daemon = False + threadClient.start() + myThread = [] + myThread.append('netClientWorker') + ''' + + #Added by Henry: + count_samples = 8 #num of samples we want + count_taken = 0 + xvals = [] + yvals = [] + zvals = [] + while count_taken < count_samples: + if runTimeConfigObject.executeSilently == 0: + axes = MMA8451.getAxisValue() + print("X: " + str(axes['x']) + ", Y: " + str(axes['y']) + ", Z: " + str(axes['z'])) + xvals.append(axes['x']) + yvals.append(axes['y']) + zvals.append(axes['z']) + count_taken = count_taken + 1 + return xvals,yvals,zvals + + #Commented Out by Henry: + ''' + while True: # forever loop + if runTimeConfigObject.executeSilently == 0: + print ("\nCurrent Date-Time: " + str(datetime.datetime.now())) + print ("Raspberry Bus = " + str(MMA8451.raspiBus)) + print ("Raspberry Interrupt = " + str(MMA8451.raspiIntEnabled)) + print ("Number of elemets = " + str(len(accelBuffer))) + MMA8451.debugShowRpiInfo() + MMA8451.debugShowRegisters() + MMA8451.debugShowOrientation() + axes = MMA8451.getAxisValue() + MMA8451.debugShowAxisAcceleration(axes['x'], axes['y'], axes['z']) + # + if runTimeConfigObject.debugRealTime != 0: + MMA8451.debugRealTimeBuffer() + + runTimeConfigObject.NumInterrupts = 0 + try: + time.sleep(1.0) + except KeyboardInterrupt: + logger.debug ("Killing threads...") + pill2kill.set() + threadClient.join() + time.sleep(1.0) + + logger.debug("\nUser termination requested!\n") + sys.exit() + + sys.exit() + ''' + diff --git a/Nov_27/Manual/Camera/accel_correct_config/raspidata.py b/Nov_27/Manual/Camera/accel_correct_config/raspidata.py new file mode 100644 index 0000000..fb99cbb --- /dev/null +++ b/Nov_27/Manual/Camera/accel_correct_config/raspidata.py @@ -0,0 +1,48 @@ +""" A Raspberry Pi class. +To access some of the most useful hardware information +""" + + +#class RaspiData(): + + + # Get Raspberry Serial Number + # You can do it in bash: + # cat /proc/cpuinfo | perl -n -e '/^Serial[ ]*: ([0-9a-f]{16})$/ && print "$1\n"' + # Or with perl: + # cat cpuinfo | perl -n -e '/^Serial[ ]*: ([0-9a-f]{16})$/ && print "$1\n"' + # + # + + +# def __init__(self): +# pass +from uuid import getnode as get_mac + +# @staticmethod +# def get_serial(self): +def get_serial(): + """Extract serial from cpuinfo file""" + cpu_serial= "0000000000000000" + try: + f = open('/proc/cpuinfo','r') + for line in f: + if line[0:6]=='Serial': + cpu_serial = line[10:26] + f.close() + except: + cpu_serial = "ERROR000000000" + return cpu_serial + + +def mac_address(): + """Extract rth0 MAC address""" + # mac = '00:00:00:00:00:00' + # mac = '00:00:00:00:00:00' + try: + t = get_mac() + except: + t = "000000000000" + mac = ':'.join(("%012X" % t)[i:i+2] for i in range(0, 12, 2)) + return mac + diff --git a/Nov_27/Manual/Camera/accel_correct_config/rss_cli_config.py b/Nov_27/Manual/Camera/accel_correct_config/rss_cli_config.py new file mode 100644 index 0000000..e10aa53 --- /dev/null +++ b/Nov_27/Manual/Camera/accel_correct_config/rss_cli_config.py @@ -0,0 +1,21 @@ +# [GeoData] +City = 'Rome' +cityname = 'Rome' +latitude = 41.947550 +longitude = 12.469794 +deviceorientation = 'L' + +# [DeviceInfo] +devicetype = 'raspberry' +devicename = 'rssd0001' +sensorname = 'mma8451' +sensortheshold = 20 +logfile = './rssd.log' + +# [Networking] +#serveraddress = 'www.diprimio.com' +serveraddress = 'localhost' +serverprotocol = 'tcp' +servertcpport = 15000 +serverhearthbit = 100 +receivebuffersize = 1024 diff --git a/Nov_27/Manual/Camera/accel_correct_config/rss_client.py b/Nov_27/Manual/Camera/accel_correct_config/rss_client.py new file mode 100644 index 0000000..a2a4d1b --- /dev/null +++ b/Nov_27/Manual/Camera/accel_correct_config/rss_client.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# -*- coding:utf-8, indent=tab, tabstop=4 -*- +# +# See 'LICENSE' for copying +# +# This file contains the code for the client module of 'accel.py' +# +# Revision history +# Date Author Version Details +# ---------------------------------------------------------------------------------- +# 2018-01-18 Massimo Di Primio 0.06 1st file implementation + +"""Client thread worker - This is a simple client code example for 'accel'.py' program""" + +import logging +import time +import datetime +import socket +import json +import rss_client_messages as climsg +import rss_cli_config as ccfg +import raspidata + + +#def cli_connect(params): +def cli_connect(): + """Open connection to the server""" + server_address = (str(ccfg.serveraddress), int(ccfg.servertcpport)) + logging.debug('Trying to connect to server ' + str(server_address)) + # Create a TCP/IP socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + # Connect the socket to the port where the server is listening + s.connect(server_address) + logging.debug('Connection Established to server ' + str(server_address)) + except: + logging.debug( + "Failed to open connection: " + str(ccfg.serverprotocol) + + ", to IP: " + str(ccfg.serveraddress) + + ", on port: " + str(ccfg.servertcpport) + ) + return(-1) + return(s) + + +def cli_close(s): + """Close the server connection""" + if s > -1: + s.close() + + +# def cli_worker(stopEvent, config, accelBuffer): +def cli_worker(stopEvent, accelBuffer): + """A client worker as thread""" + logging.debug('Thread Starting') + s = cli_connect() # s = cli_connect(config) + send_client_hello(s) + time.sleep(0.5) + send_config_affirm_message(s) + + ts = int(time.time()) + te = ts + while not stopEvent.wait(0.3): + if len(accelBuffer) > 0: + send_accel_data(s, accelBuffer) + te = int(time.time()) + if (te - ts) > 10: + send_client_heartbit(s) + ts = int(time.time()) + + time.sleep(0.5) + send_zap_message(s) + cli_close(s) + logging.debug("Thread cliWorker is terminating as per your request.") + + +def send_accel_data(s, accelBuffer): + """Send acceleration data to the server""" + #msg = dict(cmd='ADM', timestamp=str(datetime.datetime.now()), clid=raspidata.get_serial()) + #a = 123 #str(datetime.datetime.now()) + pbuf = parse_accel_data(accelBuffer) + msg = dict(cmd = 'ADM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial(), data = pbuf) + # if len(pbuf) > 0: # this sometimes returns error (when buf is empty, it has None type) + if (pbuf is not None) and (len(pbuf) > 0): + #str = climsg.accel_data_message(pbuf) + try: + logging.debug("Sending Acceleration data to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(str) + "\n") + except: + logging.debug("Failed to send Acceleration-Data to the server") + + +def send_client_hello(s): + """Send Hello message to the server""" + msg = dict(cmd = 'CHM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial()) + try: + logging.debug("Sending Hello to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.hello_message()) + "\n") + except: + logging.debug("Failed to send Hello to the server") + + +def send_zap_message(s): + """Send Zap message to the server""" + msg = dict(cmd = 'CZM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial()) + try: + logging.debug("Sending Zap to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.zap_message()) + "\n") + except: + logging.debug("Failed to send Zap to the server") + + +def send_config_affirm_message(s): #def send_config_affirm_message(s, config): + msg_data = dict(city = ccfg.cityname, latitude = ccfg.latitude,longitude = ccfg.longitude) + msg = dict(cmd = 'CCA', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial(), config = msg_data) + try: + logging.debug("Sending client configuration to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(climsg.config_affirm_message(cfg_data)) + except: + logging.debug("Failed to send client configuration to the server") + + +def send_client_heartbit(s): + """Send Heartbit to the server""" + msg = dict(cmd = 'CHB', timestamp = str(datetime.datetime.now()), clid=raspidata.get_serial()) + try: + logging.debug("Sending Heartbit to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.heart_bit()) + "\n") + except: + logging.debug("Failed to send Heartbit to the server") + + +def parse_accel_data(b): + """Parse acceleration data to make sure we only send meaningfull data to the server""" + tsh = 10 + tbuf = [] + # tbuf.append([0, 0, 0, 0, 0]) + # bLength = len(b) + # logging.debug("parseAccelData(b) # of elements = " + str(len(b))) + if len(b) > 1: + logging.debug("parseAccelData: In AccelData/BufLen: " + str(len(b)) + "/" +str(len(tbuf))) + firstTime = 1 + prow = None + for row in b: + crow = b.pop(0) # Get the oldest record + if firstTime == 1: + prow = crow + firstTime = 0 + if ( (abs(abs(int(crow[1])) - abs(int(prow[1]))) > tsh) or + (abs(abs(int(crow[2])) - abs(int(prow[2]))) > tsh) or + (abs(abs(int(crow[3])) - abs(int(prow[3]))) > tsh) + ): + tbuf.append(crow) + prow = crow + print ("Again PROW/CROW/TBUFLEN:" + str(prow) + " / " + str(crow) + " / " + str(len(tbuf))) + + logging.debug("parseAccelData: Out AccelData/BufLen: " + str(len(b)) + "/" +str(len(tbuf))) + return(tbuf) + diff --git a/Nov_27/Manual/Camera/accel_correct_config/rss_client_messages.py b/Nov_27/Manual/Camera/accel_correct_config/rss_client_messages.py new file mode 100644 index 0000000..4a507d7 --- /dev/null +++ b/Nov_27/Manual/Camera/accel_correct_config/rss_client_messages.py @@ -0,0 +1,113 @@ + +import datetime +import raspidata +import json +import rss_cli_config as ccfg + + +# +# All client messages are handled in here. +# +# Message Formats +# --------------- +# 1 - Timestamp +# 2 - Device ID +# 3 - Message Type +# +# Client message types +# -------------------- +# 0001 CHB - Client Heart Bit (Client is alive) +# 0002 CHM - Client Hello Message (Client is online) +# 0003 CZM - Client Zap Message (Client is shut down) +# 0004 ADM - Acceleration Data Message (Acceleration data) +# 0005 CCA - Client Config Affirm +# ... (other to come) +# +# Data message Format for all Client Message Types +# ------------------------------------------------ +# +# # 0001 - CHB - Client Heart Bit +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0001 | Var | Literally 'CHB' | +# # +-------------------------------------------------------------------------------+ +# +# 0002 CHM - Client Hello Message +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0002 | Var | Literally 'CHM' | +# +--------------+-------+--------------------------------------------------------+ +# +# 0003 CZM - Client Zap Message (Client is shut down) +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0003 | Var | Literally 'CZM' | +# +--------------+-------+--------------------------------------------------------+ +# +# 0004 ADM - Acceleration Data Message (Acceleration data) +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0004 | Var | Literally 'ADM' | +# | Accel Data | Var | Array containing acceleration data (X,Y,Z.O) | +# +--------------+-------+--------------------------------------------------------+ +# +# 0005 CCA - Client Configuration Affirm +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0004 | Var | Literally 'CCA' | +# | Config Data | Var | Array containing client configuration | +# +--------------+-------+--------------------------------------------------------+ + +########################################################################### +# WARNIG ! THIS FILE IS NOT CURRENTLY USED ! +# Its presence it is for debugging/testing only +# Althought, it will be used in some future version +########################################################################### + +#def heart_bit(): +# """Client Heart Bit""" +# msg = {'cmd': 'CHB', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def hello_message(): +# """Client Hello Message""" +# msg = {'cmd': 'CHM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def zap_message(): +# """Client Zap Message""" +# msg = {'cmd': 'CZM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def accel_data_message(data): +# """Acceleration Data Message""" +# msg = {'cmd': 'ADM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial(), 'acceldata': str(data)} +# return msg +# +# +#def config_affirm_message(data): #def config_affirm_message(data): +# """Client Configuration Affirm""" +# ### +# pkt_hdr = {'cmd': 'CCA', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial(), 'data' : data} +# +# msg = dict(city = ccfg.cityname, latitude = ccfg.latitude, longitude = ccfg.longitude, config = data) +# return msg + diff --git a/Nov_27/Manual/Camera/communication_module/._communication.py b/Nov_27/Manual/Camera/communication_module/._communication.py new file mode 100644 index 0000000..f2e25e8 Binary files /dev/null and b/Nov_27/Manual/Camera/communication_module/._communication.py differ diff --git a/Nov_27/Manual/Camera/communication_module/com_test.py b/Nov_27/Manual/Camera/communication_module/com_test.py new file mode 100644 index 0000000..a99d3ec --- /dev/null +++ b/Nov_27/Manual/Camera/communication_module/com_test.py @@ -0,0 +1,35 @@ +import requests +from requests import Session +import json +from datetime import datetime +from dateutil import parser +from random import randint + +BRIDGE_NAME = 'dummy' +dest = "http://127.0.0.1:8000/sensors/"+BRIDGE_NAME+"/update/" +PASSWORD = "djioewfj34jod2jdoi3jr0jl983jsa" + + +def send_data_to_server(x=0.0, y=0.0, z=0.0, theta=0.0, phi=0.0, psi=0.0): + payload = {'x': x, 'y': y, 'z': z, 'theta': theta, 'phi': phi, 'psi': psi} + dt = datetime.now() + cookies = {'csrftoken': encode(dt), 'time': str(dt)} + r = requests.post(dest, data=payload, cookies=cookies) + print(r.status_code) + if r.status_code == 403: + raise RuntimeWarning("CSRF ALERT ON, INSPECT YOUR SYSTEM") + else: + return r.text + + +def encode(time_sign): + len_pw = len(PASSWORD) + index = (time_sign.year + time_sign.month * 100 + time_sign.day + time_sign.hour * time_sign.minute + * time_sign.second) % len_pw + repl = chr(randint(97, 122)) + return PASSWORD[:index] + repl + PASSWORD[index+1:] + + +print(send_data_to_server(0.5, 1.5, 1.5)) +#send_data_form(1.0, 2.0, 3.0) +#cookies = {'csrftoken': "djioewfj34jod2jdoi3jr0jl983jsa", 'TIME': datetime.now()} diff --git a/Nov_27/Manual/Camera/communication_module/communication.py b/Nov_27/Manual/Camera/communication_module/communication.py new file mode 100644 index 0000000..8c8b9a4 --- /dev/null +++ b/Nov_27/Manual/Camera/communication_module/communication.py @@ -0,0 +1,28 @@ +import requests, sys +from requests import Session +import json +from datetime import datetime +from dateutil import parser +from random import randint +sys.path.insert(0,"/home/pi/Desktop/Full_Demo/transfer_test_correct_config") +from SETTINGS import PASSWORD, SERVER + +dest = SERVER + +def send_data_to_server(x=0.0, y=0.0, z=0.0, theta=0.0, phi=0.0, psi=0.0): + payload = {'x': x, 'y': y, 'z': z, 'theta': theta, 'phi': phi, 'psi': psi} + dt = datetime.now() + cookies = {'csrftoken': encode(dt), 'time': str(dt)} + r = requests.post(dest, data=payload, cookies=cookies) + if r.status_code == 403: + raise RuntimeWarning("CSRF ALERT ON, INSPECT YOUR SYSTEM") + else: + return r.text + + +def encode(time_sign): + len_pw = len(PASSWORD) + index = (time_sign.year + time_sign.month * 100 + time_sign.day + time_sign.hour * time_sign.minute + * time_sign.second) % len_pw + repl = chr(randint(97, 122)) + return PASSWORD[:index] + repl + PASSWORD[index+1:] \ No newline at end of file diff --git a/Nov_27/Manual/Camera/img_rec_module/FastDataMatrixTest.py b/Nov_27/Manual/Camera/img_rec_module/FastDataMatrixTest.py new file mode 100644 index 0000000..21cdf8d --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/FastDataMatrixTest.py @@ -0,0 +1,45 @@ +from img_rec_module.sig_proc_test import FM +import numpy as np +from random import randint +import traceback +import sys + +matrix = np.random.rand(20, 30) + + +def segmentation_test(sample): + ax = randint(0, 1) + target = randint(0, 19) if ax == 1 else randint(0, 29) + fmat = FM(matrix, ax, target) + assert fmat.irange() == 20 if ax == 1 else fmat.irange() == 30 + cap = len(fmat) + for i in range(sample): + start = randint(0, cap - 1) + end = randint(start + 1, cap) + fmat.segmentize(start, end) + assert len(fmat.extract_array()) == end - start, "start: {0}, end: {1}".format(start, end) + elem = randint(0, len(fmat) - 1) + assert fmat[elem] == matrix.item(target, elem + start) if ax == 1 \ + else fmat[elem] == matrix.item(elem + start, target) + print("Test 1 passed!") + return fmat.copy() + + +def shape_change_test(sample): + fmat = mat + print(len(fmat), "start: {0}, end: {1}, ax: {2}, index: {3}".format(fmat.start, fmat.end, fmat._ax, fmat._index)) + for i in range(sample): + ax = randint(0, 1) + target = randint(0, 19) if ax == 1 else randint(0, 29) + try: + fmat = fmat.copy(ax, target) + elem = randint(0, len(fmat) - 1) + assert fmat[elem] == matrix.item(target, elem) if ax == 1 else fmat[elem] == matrix.item(elem, target), "start: {0}, end: {1}, ax: {2}, index: {3}, changed:{4}, elem: {5}".format(fmat.start, fmat.end, ax, fmat._index, target, elem) + except IndexError: + print("Index Error, start: {0}, end: {1}, ax: {2}, index: {3}".format(fmat.start, fmat.end, fmat._ax, fmat._index)) + traceback.print_exc(file=sys.stderr) + sys.exit(0) + print("Test 2 passed!") + +mat = segmentation_test(1000000) +shape_change_test(1000000) \ No newline at end of file diff --git a/Nov_27/Manual/Camera/img_rec_module/HoughLineTest.py b/Nov_27/Manual/Camera/img_rec_module/HoughLineTest.py new file mode 100644 index 0000000..a338b2c --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/HoughLineTest.py @@ -0,0 +1,70 @@ +from img_rec_module.sig_proc_test import HoughLine, angle_interp, normalize_angle +import numpy as np +from random import uniform +from math import sin, cos, asin, acos, degrees + + +def angle_interp_test(sample): + for t in range(4): + angle = np.pi * t / 2 + angle_test(angle) + for i in range(sample): + angle = uniform(0, 2 * np.pi) + angle_test(angle) + print("All tests passed!") + + +def angle_test(angle): + s, c = sin(angle), cos(angle) + aint = angle_interp(s, c) + e = abs(aint - angle) + assert e < 10 ** (-8), "angle: {0} aint: {3} sin: {1}, cos: {2}".format(degrees(angle), s, c, degrees(aint)) + + +data1 = [(50, 93.58985799408744), (100, 94.83752561512769), (150, 93.46476622047003), (200, 92.12757475618413), (250, 91.21899822237681), (300, 94.66610143151713), (350, 93.39700158152765), (400, 93.55400856320203), (450, 94.81488837189904)] +data2 = [(50, 220.68898677024384), (150, 207.0369850844262), (200, 219.1873113806197), (250, 218.4221525438996), (300, 215.83141259108666), (350, 216.1097540779057), (400, 214.30630223604018), (450, 211.84789180370862), (500, 211.03929058602466), (550, 208.37556376057634), (600, 208.1358916890448)] + + +def diagnose(): + x1 = np.array([d[1] for d in data1]) + y1 = np.array([d[0] for d in data1]) + line1 = HoughLine(x=x1, data=y1) + x2 = np.array([d[0] for d in data2]) + y2 = np.array([d[1] for d in data2]) + line2 = HoughLine(x=x2, data=y2) + xmean = sum(x1) / len(x1) + ymean = sum(y2) / len(y2) + print(line1._r, line1._t) + print(line2._r, line2._t) + print((xmean, ymean), HoughLine.intersect(line1, line2)) + + +def normalize_angle_test(sample): + for t in range(4): + angle = np.pi * t / 2 + test_normalize(angle) + for i in range(sample): + angle = uniform(0, 1000000) + test_normalize(angle) + print('All tests passed!') + + +def test_normalize(angle): + s, c = sin(angle), cos(angle) + norm_ang = normalize_angle(angle) + ns, nc = sin(norm_ang), cos(norm_ang) + case1 = equal_within_error(s, ns) and equal_within_error(c, nc) + case2 = equal_within_error(s, -ns) and equal_within_error(c, -nc) + assert case1 or case2, 's:{0} c:{1}, ns:{2}, nc:{3}, angle:{4}, norm:{5}'.format(s, c, ns, nc, angle, norm_ang) + + + +def equal_within_error(v1, v2): + e = abs(v1 - v2) + return e < 10 ** (-8) + + +if __name__ == '__main__': + #angle_interp_test(100000000) + #diagnose() + normalize_angle_test(1000000) \ No newline at end of file diff --git a/Nov_27/Manual/Camera/img_rec_module/__init__.py b/Nov_27/Manual/Camera/img_rec_module/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/centers.txt b/Nov_27/Manual/Camera/img_rec_module/centers.txt new file mode 100644 index 0000000..ea1e64b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/centers.txt @@ -0,0 +1,640 @@ +135.5 +134.5 +134.0 +127.5 +131.0 +131.0 +133.5 +131.0 +131.5 +131.5 +129.5 +135.5 +135.5 +126.5 +134.0 +131.5 +132.5 +128.5 +131.5 +134.5 +130.5 +1.0 +132.5 +129.5 +70.5 +131.5 +132.5 +132.0 +132.5 +129.5 +135.5 +129.5 +132.5 +130.5 +131.5 +134.0 +72.0 +67.5 +130.5 +135.0 +132.0 +133.5 +130.5 +129.5 +129.5 +132.0 +130.5 +134.0 +129.5 +136.0 +129.5 +127.5 +133.5 +131.0 +134.0 +131.5 +128.5 +132.0 +132.5 +136.0 +132.0 +133.5 +132.0 +132.5 +132.0 +129.0 +138.5 +133.5 +134.0 +132.5 +132.5 +134.0 +134.5 +131.5 +133.0 +135.5 +132.0 +130.5 +130.5 +128.0 +130.0 +133.0 +132.0 +136.0 +135.5 +132.5 +135.5 +130.5 +136.5 +136.5 +129.5 +129.0 +130.0 +138.5 +135.0 +127.5 +126.5 +135.5 +135.5 +130.5 +127.5 +131.5 +136.5 +134.5 +136.5 +133.5 +133.0 +131.5 +130.0 +136.5 +135.5 +135.0 +134.0 +133.0 +131.5 +130.5 +132.5 +135.5 +133.5 +129.5 +133.0 +136.5 +129.0 +135.5 +133.5 +133.5 +134.0 +129.5 +133.5 +132.0 +134.5 +137.0 +130.5 +129.5 +130.5 +131.5 +133.5 +137.5 +134.5 +130.5 +131.0 +134.0 +137.5 +132.5 +128.0 +129.0 +132.0 +136.5 +129.5 +128.0 +127.5 +128.0 +135.0 +128.5 +129.0 +135.0 +137.5 +136.0 +131.5 +131.0 +130.0 +134.0 +135.5 +133.0 +134.5 +134.0 +133.0 +132.0 +135.0 +132.0 +135.5 +132.5 +130.5 +127.5 +131.5 +131.0 +134.0 +131.0 +129.0 +130.0 +129.0 +129.5 +133.0 +132.0 +127.5 +131.5 +135.0 +134.0 +133.0 +133.0 +130.0 +130.5 +127.5 +133.0 +135.0 +134.0 +135.5 +131.5 +129.5 +128.5 +138.5 +134.0 +132.0 +135.5 +132.0 +128.0 +127.5 +134.5 +130.0 +130.5 +131.0 +129.5 +125.5 +130.0 +130.5 +134.5 +137.5 +129.5 +132.5 +134.0 +131.5 +134.0 +128.5 +131.5 +134.0 +133.5 +134.0 +133.0 +132.5 +130.5 +126.5 +128.5 +130.0 +128.0 +131.5 +131.0 +129.5 +132.5 +131.0 +129.5 +127.5 +135.0 +126.5 +141.5 +132.5 +133.0 +136.0 +131.0 +129.0 +134.5 +130.5 +127.5 +133.0 +133.5 +131.5 +135.5 +134.0 +131.0 +133.5 +133.5 +133.5 +127.5 +132.0 +132.5 +134.5 +132.0 +132.0 +128.0 +132.0 +136.0 +136.0 +132.5 +134.5 +137.0 +131.0 +131.5 +137.0 +130.5 +128.0 +133.0 +129.5 +135.0 +140.0 +130.5 +134.5 +129.0 +136.0 +128.0 +133.5 +136.5 +135.0 +127.5 +131.5 +139.5 +131.5 +128.5 +136.0 +135.0 +131.5 +131.5 +133.5 +127.5 +135.5 +135.5 +128.0 +130.0 +127.5 +128.0 +130.0 +126.5 +142.5 +134.5 +134.5 +124.5 +126.5 +129.5 +131.0 +129.5 +131.5 +127.0 +127.5 +135.0 +134.5 +131.5 +126.0 +130.5 +132.0 +138.0 +131.5 +135.5 +125.0 +133.0 +127.5 +136.5 +131.5 +131.5 +131.0 +124.0 +128.5 +137.5 +133.5 +130.0 +131.0 +129.0 +133.0 +131.0 +125.5 +129.5 +132.0 +129.5 +137.5 +128.5 +130.0 +131.0 +134.5 +130.0 +131.5 +131.5 +136.5 +134.0 +132.0 +136.0 +126.5 +128.0 +133.5 +135.5 +129.0 +133.0 +131.5 +132.0 +129.5 +126.0 +126.0 +130.5 +135.0 +129.0 +131.0 +130.5 +131.5 +135.5 +133.5 +134.0 +131.5 +126.0 +130.0 +131.0 +131.5 +130.5 +133.5 +130.0 +125.0 +126.5 +133.5 +132.0 +129.5 +133.5 +130.5 +132.5 +136.0 +135.0 +130.0 +129.5 +134.0 +135.5 +131.5 +135.5 +135.5 +131.5 +130.0 +130.0 +131.5 +132.0 +129.5 +131.5 +127.5 +136.0 +131.0 +134.5 +135.0 +126.5 +128.0 +131.5 +131.5 +127.0 +130.0 +130.5 +136.5 +130.5 +129.0 +130.0 +130.5 +135.5 +125.5 +130.5 +130.0 +127.5 +132.5 +133.5 +130.0 +127.5 +126.0 +132.0 +127.0 +126.0 +130.5 +127.5 +127.5 +129.5 +131.5 +133.0 +129.5 +127.0 +129.0 +126.5 +130.5 +130.0 +126.5 +128.5 +126.5 +126.5 +127.5 +134.0 +136.5 +129.5 +130.0 +128.5 +130.0 +127.5 +130.5 +135.0 +137.5 +130.0 +129.5 +134.5 +130.5 +127.5 +132.5 +129.0 +132.5 +130.0 +133.5 +127.5 +129.5 +129.0 +124.5 +126.5 +126.0 +128.0 +130.0 +133.0 +129.5 +131.0 +128.5 +132.5 +129.5 +199.5 +133.5 +133.5 +130.0 +127.5 +114.0 +227.5 +113.5 +134.5 +129.5 +130.0 +128.5 +130.0 +132.5 +126.5 +127.5 +129.0 +135.5 +129.5 +126.5 +127.5 +132.5 +127.0 +131.0 +124.5 +132.5 +128.0 +129.5 +135.5 +131.5 +129.0 +131.5 +132.0 +131.5 +130.5 +130.5 +136.5 +135.5 +131.5 +129.0 +130.5 +130.0 +129.0 +130.5 +128.0 +126.5 +133.5 +131.0 +129.0 +128.0 +131.5 +132.5 +128.5 +134.5 +130.0 +127.5 +130.0 +129.5 +131.5 +127.5 +131.0 +129.0 +127.5 +135.5 +128.0 +127.0 +131.0 +131.0 +129.5 +126.0 +128.5 +128.5 +131.0 +126.0 +132.5 +128.0 +130.0 +133.0 +127.5 +128.5 +131.5 +135.5 +133.0 +133.0 +131.0 +132.0 +128.0 +132.0 +130.0 +132.5 +128.5 +127.5 +130.5 +130.0 +131.5 +128.5 +126.5 +132.0 +126.5 +129.5 +128.0 +127.0 +126.5 +133.5 +128.5 +135.5 +133.5 +132.5 +132.0 +132.5 +131.5 +131.0 +131.0 +129.5 +130.5 +127.0 +127.5 +125.0 +129.5 +130.5 +130.5 +132.5 +128.0 +129.5 +126.5 +125.5 +125.0 +131.5 +130.0 +131.5 +128.5 +127.0 +134.0 +129.0 +132.5 +130.0 +129.5 +129.0 +129.0 +126.5 +127.5 +128.0 +125.5 +131.0 +129.5 diff --git a/Nov_27/Manual/Camera/img_rec_module/flags.txt b/Nov_27/Manual/Camera/img_rec_module/flags.txt new file mode 100644 index 0000000..b15d479 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/flags.txt @@ -0,0 +1,274 @@ +COLOR_BAYER_BG2BGR +COLOR_BAYER_BG2BGRA +COLOR_BAYER_BG2BGR_EA +COLOR_BAYER_BG2BGR_VNG +COLOR_BAYER_BG2GRAY +COLOR_BAYER_BG2RGB +COLOR_BAYER_BG2RGBA +COLOR_BAYER_BG2RGB_EA +COLOR_BAYER_BG2RGB_VNG +COLOR_BAYER_GB2BGR +COLOR_BAYER_GB2BGRA +COLOR_BAYER_GB2BGR_EA +COLOR_BAYER_GB2BGR_VNG +COLOR_BAYER_GB2GRAY +COLOR_BAYER_GB2RGB +COLOR_BAYER_GB2RGBA +COLOR_BAYER_GB2RGB_EA +COLOR_BAYER_GB2RGB_VNG +COLOR_BAYER_GR2BGR +COLOR_BAYER_GR2BGRA +COLOR_BAYER_GR2BGR_EA +COLOR_BAYER_GR2BGR_VNG +COLOR_BAYER_GR2GRAY +COLOR_BAYER_GR2RGB +COLOR_BAYER_GR2RGBA +COLOR_BAYER_GR2RGB_EA +COLOR_BAYER_GR2RGB_VNG +COLOR_BAYER_RG2BGR +COLOR_BAYER_RG2BGRA +COLOR_BAYER_RG2BGR_EA +COLOR_BAYER_RG2BGR_VNG +COLOR_BAYER_RG2GRAY +COLOR_BAYER_RG2RGB +COLOR_BAYER_RG2RGBA +COLOR_BAYER_RG2RGB_EA +COLOR_BAYER_RG2RGB_VNG +COLOR_BGR2BGR555 +COLOR_BGR2BGR565 +COLOR_BGR2BGRA +COLOR_BGR2GRAY +COLOR_BGR2HLS +COLOR_BGR2HLS_FULL +COLOR_BGR2HSV +COLOR_BGR2HSV_FULL +COLOR_BGR2LAB +COLOR_BGR2LUV +COLOR_BGR2Lab +COLOR_BGR2Luv +COLOR_BGR2RGB +COLOR_BGR2RGBA +COLOR_BGR2XYZ +COLOR_BGR2YCR_CB +COLOR_BGR2YCrCb +COLOR_BGR2YUV +COLOR_BGR2YUV_I420 +COLOR_BGR2YUV_IYUV +COLOR_BGR2YUV_YV12 +COLOR_BGR5552BGR +COLOR_BGR5552BGRA +COLOR_BGR5552GRAY +COLOR_BGR5552RGB +COLOR_BGR5552RGBA +COLOR_BGR5652BGR +COLOR_BGR5652BGRA +COLOR_BGR5652GRAY +COLOR_BGR5652RGB +COLOR_BGR5652RGBA +COLOR_BGRA2BGR +COLOR_BGRA2BGR555 +COLOR_BGRA2BGR565 +COLOR_BGRA2GRAY +COLOR_BGRA2RGB +COLOR_BGRA2RGBA +COLOR_BGRA2YUV_I420 +COLOR_BGRA2YUV_IYUV +COLOR_BGRA2YUV_YV12 +COLOR_BayerBG2BGR +COLOR_BayerBG2BGRA +COLOR_BayerBG2BGR_EA +COLOR_BayerBG2BGR_VNG +COLOR_BayerBG2GRAY +COLOR_BayerBG2RGB +COLOR_BayerBG2RGBA +COLOR_BayerBG2RGB_EA +COLOR_BayerBG2RGB_VNG +COLOR_BayerGB2BGR +COLOR_BayerGB2BGRA +COLOR_BayerGB2BGR_EA +COLOR_BayerGB2BGR_VNG +COLOR_BayerGB2GRAY +COLOR_BayerGB2RGB +COLOR_BayerGB2RGBA +COLOR_BayerGB2RGB_EA +COLOR_BayerGB2RGB_VNG +COLOR_BayerGR2BGR +COLOR_BayerGR2BGRA +COLOR_BayerGR2BGR_EA +COLOR_BayerGR2BGR_VNG +COLOR_BayerGR2GRAY +COLOR_BayerGR2RGB +COLOR_BayerGR2RGBA +COLOR_BayerGR2RGB_EA +COLOR_BayerGR2RGB_VNG +COLOR_BayerRG2BGR +COLOR_BayerRG2BGRA +COLOR_BayerRG2BGR_EA +COLOR_BayerRG2BGR_VNG +COLOR_BayerRG2GRAY +COLOR_BayerRG2RGB +COLOR_BayerRG2RGBA +COLOR_BayerRG2RGB_EA +COLOR_BayerRG2RGB_VNG +COLOR_COLORCVT_MAX +COLOR_GRAY2BGR +COLOR_GRAY2BGR555 +COLOR_GRAY2BGR565 +COLOR_GRAY2BGRA +COLOR_GRAY2RGB +COLOR_GRAY2RGBA +COLOR_HLS2BGR +COLOR_HLS2BGR_FULL +COLOR_HLS2RGB +COLOR_HLS2RGB_FULL +COLOR_HSV2BGR +COLOR_HSV2BGR_FULL +COLOR_HSV2RGB +COLOR_HSV2RGB_FULL +COLOR_LAB2BGR +COLOR_LAB2LBGR +COLOR_LAB2LRGB +COLOR_LAB2RGB +COLOR_LBGR2LAB +COLOR_LBGR2LUV +COLOR_LBGR2Lab +COLOR_LBGR2Luv +COLOR_LRGB2LAB +COLOR_LRGB2LUV +COLOR_LRGB2Lab +COLOR_LRGB2Luv +COLOR_LUV2BGR +COLOR_LUV2LBGR +COLOR_LUV2LRGB +COLOR_LUV2RGB +COLOR_Lab2BGR +COLOR_Lab2LBGR +COLOR_Lab2LRGB +COLOR_Lab2RGB +COLOR_Luv2BGR +COLOR_Luv2LBGR +COLOR_Luv2LRGB +COLOR_Luv2RGB +COLOR_M_RGBA2RGBA +COLOR_RGB2BGR +COLOR_RGB2BGR555 +COLOR_RGB2BGR565 +COLOR_RGB2BGRA +COLOR_RGB2GRAY +COLOR_RGB2HLS +COLOR_RGB2HLS_FULL +COLOR_RGB2HSV +COLOR_RGB2HSV_FULL +COLOR_RGB2LAB +COLOR_RGB2LUV +COLOR_RGB2Lab +COLOR_RGB2Luv +COLOR_RGB2RGBA +COLOR_RGB2XYZ +COLOR_RGB2YCR_CB +COLOR_RGB2YCrCb +COLOR_RGB2YUV +COLOR_RGB2YUV_I420 +COLOR_RGB2YUV_IYUV +COLOR_RGB2YUV_YV12 +COLOR_RGBA2BGR +COLOR_RGBA2BGR555 +COLOR_RGBA2BGR565 +COLOR_RGBA2BGRA +COLOR_RGBA2GRAY +COLOR_RGBA2M_RGBA +COLOR_RGBA2RGB +COLOR_RGBA2YUV_I420 +COLOR_RGBA2YUV_IYUV +COLOR_RGBA2YUV_YV12 +COLOR_RGBA2mRGBA +COLOR_XYZ2BGR +COLOR_XYZ2RGB +COLOR_YCR_CB2BGR +COLOR_YCR_CB2RGB +COLOR_YCrCb2BGR +COLOR_YCrCb2RGB +COLOR_YUV2BGR +COLOR_YUV2BGRA_I420 +COLOR_YUV2BGRA_IYUV +COLOR_YUV2BGRA_NV12 +COLOR_YUV2BGRA_NV21 +COLOR_YUV2BGRA_UYNV +COLOR_YUV2BGRA_UYVY +COLOR_YUV2BGRA_Y422 +COLOR_YUV2BGRA_YUNV +COLOR_YUV2BGRA_YUY2 +COLOR_YUV2BGRA_YUYV +COLOR_YUV2BGRA_YV12 +COLOR_YUV2BGRA_YVYU +COLOR_YUV2BGR_I420 +COLOR_YUV2BGR_IYUV +COLOR_YUV2BGR_NV12 +COLOR_YUV2BGR_NV21 +COLOR_YUV2BGR_UYNV +COLOR_YUV2BGR_UYVY +COLOR_YUV2BGR_Y422 +COLOR_YUV2BGR_YUNV +COLOR_YUV2BGR_YUY2 +COLOR_YUV2BGR_YUYV +COLOR_YUV2BGR_YV12 +COLOR_YUV2BGR_YVYU +COLOR_YUV2GRAY_420 +COLOR_YUV2GRAY_I420 +COLOR_YUV2GRAY_IYUV +COLOR_YUV2GRAY_NV12 +COLOR_YUV2GRAY_NV21 +COLOR_YUV2GRAY_UYNV +COLOR_YUV2GRAY_UYVY +COLOR_YUV2GRAY_Y422 +COLOR_YUV2GRAY_YUNV +COLOR_YUV2GRAY_YUY2 +COLOR_YUV2GRAY_YUYV +COLOR_YUV2GRAY_YV12 +COLOR_YUV2GRAY_YVYU +COLOR_YUV2RGB +COLOR_YUV2RGBA_I420 +COLOR_YUV2RGBA_IYUV +COLOR_YUV2RGBA_NV12 +COLOR_YUV2RGBA_NV21 +COLOR_YUV2RGBA_UYNV +COLOR_YUV2RGBA_UYVY +COLOR_YUV2RGBA_Y422 +COLOR_YUV2RGBA_YUNV +COLOR_YUV2RGBA_YUY2 +COLOR_YUV2RGBA_YUYV +COLOR_YUV2RGBA_YV12 +COLOR_YUV2RGBA_YVYU +COLOR_YUV2RGB_I420 +COLOR_YUV2RGB_IYUV +COLOR_YUV2RGB_NV12 +COLOR_YUV2RGB_NV21 +COLOR_YUV2RGB_UYNV +COLOR_YUV2RGB_UYVY +COLOR_YUV2RGB_Y422 +COLOR_YUV2RGB_YUNV +COLOR_YUV2RGB_YUY2 +COLOR_YUV2RGB_YUYV +COLOR_YUV2RGB_YV12 +COLOR_YUV2RGB_YVYU +COLOR_YUV420P2BGR +COLOR_YUV420P2BGRA +COLOR_YUV420P2GRAY +COLOR_YUV420P2RGB +COLOR_YUV420P2RGBA +COLOR_YUV420SP2BGR +COLOR_YUV420SP2BGRA +COLOR_YUV420SP2GRAY +COLOR_YUV420SP2RGB +COLOR_YUV420SP2RGBA +COLOR_YUV420p2BGR +COLOR_YUV420p2BGRA +COLOR_YUV420p2GRAY +COLOR_YUV420p2RGB +COLOR_YUV420p2RGBA +COLOR_YUV420sp2BGR +COLOR_YUV420sp2BGRA +COLOR_YUV420sp2GRAY +COLOR_YUV420sp2RGB +COLOR_YUV420sp2RGBA +COLOR_mRGBA2RGBA diff --git a/Nov_27/Manual/Camera/img_rec_module/img_1_1_meas.txt b/Nov_27/Manual/Camera/img_rec_module/img_1_1_meas.txt new file mode 100644 index 0000000..97ed4c5 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_1_1_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 384.9492753623189; +y: zero_crossing: 128.7986577181208, edge_converge: 124.79086538461539 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 385.07291666666663; +y: zero_crossing: 129.5, edge_converge: 125.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 383.90625, edge_converge: 379.9741379310345; +y: zero_crossing: 129.52727272727273, edge_converge: 130.70366132723112 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 379.9741379310345; +y: zero_crossing: 129.6, edge_converge: 130.70366132723112 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 379.9741379310345; +y: zero_crossing: 129.68627450980392, edge_converge: 130.70366132723112 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 383.6551724137931, edge_converge: 379.9741379310345; +y: zero_crossing: 129.55172413793105, edge_converge: 130.70366132723112 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 383.55172413793105, edge_converge: 379.9741379310345; +y: zero_crossing: 129.5, edge_converge: 130.70366132723112 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 383.90625, edge_converge: 379.9741379310345; +y: zero_crossing: 129.5, edge_converge: 130.70366132723112 diff --git a/Nov_27/Manual/Camera/img_rec_module/img_1_1new_meas.txt b/Nov_27/Manual/Camera/img_rec_module/img_1_1new_meas.txt new file mode 100644 index 0000000..70d4297 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_1_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 323.66566716641677; +y: zero_crossing: -1, edge_converge: 828.3849673202615 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 597.0; +y: zero_crossing: -1, edge_converge: 792.34375 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 880.0; +y: zero_crossing: -1, edge_converge: 796.6236413043478 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 716.546875; +y: zero_crossing: -1, edge_converge: 832.172697368421 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 321.5, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/img_20_1_meas.txt b/Nov_27/Manual/Camera/img_rec_module/img_20_1_meas.txt new file mode 100644 index 0000000..8f3d333 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_20_1_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 225.33333333333334, edge_converge: 222.40969899665552; +y: zero_crossing: 222.44086021505376, edge_converge: 232.5 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 224.90625, edge_converge: 212.425; +y: zero_crossing: 222.7012987012987, edge_converge: 244.8653846153846 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 224.55172413793105, edge_converge: 225.7096153846154; +y: zero_crossing: 222.8507462686567, edge_converge: 233.3653846153846 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 224.86363636363637, edge_converge: 207.6159420289855; +y: zero_crossing: 223.22413793103448, edge_converge: 215.5216346153846 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.37254901960785, edge_converge: 238.5 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.33333333333334, edge_converge: 238.5 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.46341463414635, edge_converge: 238.5 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 224.56521739130434, edge_converge: 198.0; +y: zero_crossing: 223.57894736842104, edge_converge: 238.5 diff --git a/Nov_27/Manual/Camera/img_rec_module/img_20_2_meas.txt b/Nov_27/Manual/Camera/img_rec_module/img_20_2_meas.txt new file mode 100644 index 0000000..4e85aab --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_20_2_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 225.58333333333331; +y: zero_crossing: -1, edge_converge: 182.35897435897436 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 227.5; +y: zero_crossing: -1, edge_converge: 224.0 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 218.89655172413794, edge_converge: 212.9415292353823; +y: zero_crossing: -1, edge_converge: 232.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 218.86363636363637, edge_converge: 266.84375; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 218.5, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: 191.76923076923077, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/img_20_3_meas.txt b/Nov_27/Manual/Camera/img_rec_module/img_20_3_meas.txt new file mode 100644 index 0000000..b228fdb --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_20_3_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 43.1578947368421, edge_converge: 27.907894736842106; +y: zero_crossing: 222.41739130434783, edge_converge: 224.8991379310345 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 222.0; +y: zero_crossing: 222.53191489361703, edge_converge: 228.6346153846154 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 225.0; +y: zero_crossing: 222.6338028169014, edge_converge: 213.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.75, edge_converge: 291.0 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.79166666666666, edge_converge: 200.0 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.7450980392157, edge_converge: 200.0 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.92105263157896, edge_converge: 200.0 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.9268292682927, edge_converge: 200.0 diff --git a/Nov_27/Manual/Camera/img_rec_module/img_2_1new_meas.txt b/Nov_27/Manual/Camera/img_rec_module/img_2_1new_meas.txt new file mode 100644 index 0000000..a8b0bc8 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_2_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1178.6311475409836; +y: zero_crossing: -1, edge_converge: 376.4716202270382 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 635.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1582.0; +y: zero_crossing: -1, edge_converge: 723.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1682.4423076923076; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 72.5, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 diff --git a/Nov_27/Manual/Camera/img_rec_module/img_3_1new_meas.txt b/Nov_27/Manual/Camera/img_rec_module/img_3_1new_meas.txt new file mode 100644 index 0000000..8cf1d3c --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_3_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 485.2365079365079; +y: zero_crossing: -1, edge_converge: 463.47727272727275 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 484.8125; +y: zero_crossing: -1, edge_converge: 464.0 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 482.4; +y: zero_crossing: 462.8421052631579, edge_converge: 464.13461538461536 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 480.5, edge_converge: 475.3696120689655; +y: zero_crossing: 462.5, edge_converge: 478.50674662668666 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 485.2307692307692, edge_converge: 493.35480943738656; +y: zero_crossing: 462.1875, edge_converge: 448.98519736842104 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 493.35480943738656; +y: zero_crossing: 462.5, edge_converge: 448.98519736842104 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 487.5, edge_converge: 493.35480943738656; +y: zero_crossing: 462.1875, edge_converge: 448.98519736842104 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 493.35480943738656; +y: zero_crossing: 462.4347826086956, edge_converge: 448.98519736842104 diff --git a/Nov_27/Manual/Camera/img_rec_module/img_filter.py b/Nov_27/Manual/Camera/img_rec_module/img_filter.py new file mode 100644 index 0000000..3b8b0dc --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_filter.py @@ -0,0 +1,23 @@ +import cv2 +import numpy as np +from matplotlib import pyplot as plt + +img = cv2.imread('../testpic/img_20_1.png',0) +blur = cv2.GaussianBlur(img,(5,5),0) +cv2.imshow("ok", blur) +img = blur + +laplacian = cv2.Laplacian(img,cv2.CV_64F) +sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5) +sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5) + +plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray') +plt.title('Original'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray') +plt.title('Laplacian'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') +plt.title('Sobel X'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') +plt.title('Sobel Y'), plt.xticks([]), plt.yticks([]) + +plt.show() \ No newline at end of file diff --git a/Nov_27/Manual/Camera/img_rec_module/img_rec.py b/Nov_27/Manual/Camera/img_rec_module/img_rec.py new file mode 100644 index 0000000..eac36ff --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/img_rec.py @@ -0,0 +1,176 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +import os +from img_rec_module.sig_proc_test import FM, compare_data_plots, compare_images + + +def identity(img): + return img + + +def grayscale(img): + return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + +def grad_detect(img, n, ori, func): + #img = np.array(img) + if ori == 'h': + grad = [func(img, n, i+1) - func(img, n, i) for i in range(img.shape[1]-1)] + else: + grad = [func(img, i+1, n) - func(img, i, n) for i in range(img.shape[0]-1)] + return grad + + +def abs_detect(img, n, ori, func): + if ori == 'h': + return [func(img, n, i) for i in range(img.shape[1])] + else: + return [func(img, i, n) for i in range(img.shape[0])] + + +def visualize_data(folder, oname, sample, orient, func, data_p=grad_detect, img_p=identity): + dirs = os.listdir(folder) + for f in dirs: + try: + img = img_p(cv2.imread(folder + f)) + interval = int(img.shape[1 if orient == 'v' else 0] / sample) + for j in range(sample): + n = j * interval + data = data_p(img, n, orient, func) + plt_save_data(data, oname + 'data_{0}{1}_'.format(orient, n) + f) + except: + print(f) + + +def max_entry(img): + max_e = 0 + for row in img: + temp = max(row) + if temp > max_e: + max_e = temp + + +def record_file(vals, fname): + f = open(fname, 'w') + for v in vals: + f.write(str(v) + '\n') + f.close() + + +def rel_lumin(img, r, c): + b = img.item(r, c, 0) + g = img.item(r, c, 1) + r = img.item(r, c, 2) + return 0.2126 * r + 0.7152 * g + 0.0722 * b + + +def max_method(img): + index = [] + s = 0 + for i in range(img.shape[1]): + val = np.argmax(img[:, i]) + index.append(val) + s += val + return s / len(index) + + +def plot_show_data(data): + plt.figure(figsize=(16, 8)) + #plt.xticks(range(0, img.shape[0], 20), range(0, img.shape[0], 20)) + plt.plot(data, 'b-') + plt.show() + plt.close() + + +def plt_save_data(data, fname): + plt.figure(figsize=(16, 8)) + plt.plot(data, 'b-') + plt.savefig(fname) + plt.close() + + +def centroid(img, func): + r = img.shape[0] + c = img.shape[1] + aggr_i = 0 + aggr_j = 0 + aggr = 0 + for i in range(r): + for j in range(c): + lum = func(img, i, j) + aggr_i += lum * i + aggr_j += lum * j + aggr += lum + dim = r * c + return aggr_i / aggr, aggr_j / aggr + # return aggr_i / dim, aggr_j / dim + + +def centroid_test(fname, n, trials, func, img_p=identity): + for i in range(1, n+1): + for j in range(1, trials+1): + cf = fname.format(i, j) + print(cf) + im = img_p(cv2.imread(cf)) + print(centroid(im, func)) + + +def brightness_test(): + BASE_DIR = '../calib/' + image_name = 'shutter_{0}_iso_{1}_bright_{2}.jpeg' + img_path = BASE_DIR + image_name + shutter = [100, 1000, 5000, 10000] + isos = [100, 400, 800] + brightness = [0, 50, 100] + expo_modes = ['auto', 'very_long'] + for ss in shutter[0:]: + comp = [] + plts = [] + print(ss) + for iso in isos: + name = img_path.format(ss, iso, 'very_long') + imgr = cv2.imread(name) + tp = (imgr, name) + comp.append(tp) + img = cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY) + plts.append((FM(img, FM.HOR, img.shape[0] // 2).extract_array(), name)) + compare_images(ilist=comp) + compare_data_plots(ilist=plts) + + +gray_p = lambda img, r, c: img.item(r, c) + +if __name__ == '__main__': + #centroid_test("../testpic/img_{0}_{1}.png", 25, 3, gray_p, img_p=grayscale) + # centroid_test("../testpic/img_{0}_{1}.png", 25, 3, rel_lumin) + + """img = cv2.imread("../testpic/png_1_1.png") + plot_show_data(abs_detect(img, 0, 'v', rel_lumin))""" + + """img = cv2.imread("../testpic/png_1_1.png") + print(img.shape) + cv2.imshow('all', img) + gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + cv2.imshow('gray', gs) + print(sum(centers) / len(centers)) + print(max_method(gs)) + record_file(centers, 'centers.txt') + + while True: + prompt = input("type in an index to draw or q to quit") + if prompt == 'q': + break + else: + plot_i(int(prompt)) + + centers = [] + for i in range(gs.shape[1]): + grad = grad_detect(gs, i, 'v', rel_lumin) + max_v = max(range(len(grad)), key=lambda i: grad[i]) + min_v = min(range(len(grad)), key=lambda i: grad[i]) + centers.append((max_v + min_v) / 2)""" + + #visualize_data("../testpic/", "../absdataplot/", 10, 'h', rel_lumin, data_p=abs_detect) + brightness_test() + diff --git a/Nov_27/Manual/Camera/img_rec_module/log.docx b/Nov_27/Manual/Camera/img_rec_module/log.docx new file mode 100644 index 0000000..b574f98 Binary files /dev/null and b/Nov_27/Manual/Camera/img_rec_module/log.docx differ diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/convergence.csv b/Nov_27/Manual/Camera/img_rec_module/meas/convergence.csv new file mode 100644 index 0000000..418d98a --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/convergence.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392 +60,95.68692886974831,217.86446645631813 +61,95.27930768267886,218.4321212539979 +62,179.68821344888678,221.21713400884485 +63,180.64677254143638,221.7765304937586 +64,179.86073442223173,223.68541859670074 +65,267.0750705461852,204.74717443096984 +66,267.19879488924516,209.60901887734772 +67,266.1798697712201,208.51040145394091 +73,274.3400431870006,204.75610310411912 +74,273.44321864391185,205.81069417739437 +75,273.15099171429256,205.61817173382607 +77,353.2630018061804,204.6061088758629 +78,353.8852531441488,203.30592180203516 +79,352.21840596322596,204.15679894425952 +80,312.34313113441607,204.52530436142615 +81,313.1160349693985,201.4084182788836 +82,312.11840038067925,201.00669797880116 +83,312.29317276741347,200.45780062295867 +84,132.42237239805132,254.29214663519284 +85,131.29521858798734,255.4865958538821 +86,135.9988356956537,254.77748611685175 +87,130.98094102950247,254.42187606024922 +88,174.56636927613675,254.4831815599854 +89,173.67935580024877,254.09783447631526 +90,173.36920502447623,252.290452181076 +91,175.2895186608897,257.2751667704358 +92,215.07500705655937,253.80949363235624 +93,216.94462220467622,255.47756358425315 +94,217.3834915918711,256.4745644877478 +95,219.6648004345676,255.57239348461326 +96,257.50957542067664,254.1259284055811 +97,257.570545197815,253.88751117668164 +98,257.6089813372307,253.78662089019835 +99,257.6936671647974,254.2498517060511 +100,298.2952436151055,254.76909617478606 +101,298.1169393001307,255.21794911950758 +102,298.3189654536773,255.25096983760508 +103,298.4415890038736,254.35763625124292 +104,337.66969489877954,251.71635156144524 +105,338.1116560201459,251.7179090471175 +107,337.93979130669914,251.84264636476274 +108,338.18833275957206,250.67508565210196 +113,274.2817559120019,308.9374117445766 +114,275.7421347767481,310.2555996702759 +115,276.0461325201841,310.02072804280994 +116,276.2417374542582,310.24048782871637 +117,319.6559290654899,310.99105624588617 +118,319.6313092726346,312.1826263203713 +119,319.46776160473627,311.841371820779 +120,319.76654338764155,311.98447027104925 +121,360.82585188540037,313.3258908241004 +122,360.64739266264627,312.8307783296112 +123,360.689270210389,312.2626467099784 +124,360.8335382258014,312.5428875466125 +125,442.1542117060401,317.1277309025985 +126,441.42140737582423,315.78584607818385 +127,441.5300773440553,315.90717126090226 +128,441.95769286933466,316.8407357397122 +129,481.35090878368925,317.4272946632326 +130,481.4725819590857,316.6159681822135 +131,481.1535576706723,316.8819465108059 +132,482.21933609621834,316.90676933858305 +133,59.55768321914789,300.29871844382603 +134,61.376816545951996,298.3523691730104 +135,60.60960139542109,300.5877018018443 +136,59.19985355062283,300.1851062687214 +137,102.6280068014727,297.40383468175656 +138,102.40955557323258,298.7865911290351 +139,100.57013333623348,296.8202762296189 +140,102.67850653460079,298.5730025774653 +141,120.23221696171454,300.1898879495705 +142,118.10535832779757,301.85912326532906 +143,118.16700474619614,302.0417496311767 +144,118.19187121087131,302.5378510894045 +145,143.380762851227,297.65106023170455 +146,142.46748228973178,297.3647432540817 +147,143.2239805848247,297.5672414624104 +148,140.51718892104998,297.9845023911149 +149,182.6593569656309,298.1418468359333 +150,182.64828488417706,297.92582445480707 +151,182.92797391602642,297.87455852433123 +152,183.0029286817877,297.8637465373881 +153,186.1728851830908,329.8083307385874 +154,186.5492243440529,329.1491955430002 +155,186.0292302003802,329.23752125561214 +156,186.05706501583137,329.3191466220413 +157,233.36795685970054,328.463961880729 +158,232.82586842848798,327.60883484043825 +159,229.71350413783279,328.3780985513343 +160,232.72525153041173,327.7700361791668 +161,273.76316751955034,329.73823826493043 +162,275.7575781134558,329.9125721193857 +163,273.60940070127293,330.0025820738042 +164,273.7244999819209,330.09757535831045 +165,313.3973669095876,330.59163642669836 +166,313.23094160288184,330.71155384663837 +167,313.2083786255443,330.77428522126553 +168,313.36106959216625,330.6523370232485 +169,396.3640143494862,332.05477157898144 +170,395.617460222669,331.85554030819173 +171,396.3911361968549,332.1303447002533 +172,395.89256887798285,332.16822339411516 +173,176.02029170516317,153.71245910000232 +174,176.10545306203875,155.20318481126037 +175,176.03197440143745,154.95241321278883 +176,175.6846804297304,154.63359606135103 +177,219.46327960613064,157.23609785750858 +178,221.0564853241154,157.3435472260885 +179,219.62129396536662,157.2666553285107 +180,219.69587995502016,157.1490063640601 +181,263.23636033723557,157.46707082247306 +182,261.3833848255912,157.14497162705263 +183,263.2875985178052,157.05504332147794 +184,263.16270089611913,157.68858593709763 +185,304.0771964580808,156.36708101762838 +186,303.2325028543831,156.57995759281437 +187,303.42630311491723,156.4924674158584 +188,304.6158660912609,156.4818813819881 +189,385.45560134261797,158.37035395252553 +190,385.8286612719259,156.9884186905783 +191,386.1864174896063,157.19189241238993 +192,385.6347971660166,158.1411858434322 +1 +59,93.1287423931208,218.29700908810787 +60,94.70512938803542,212.6540109552706 +61,90.1361278577332,213.33121631876608 +62,163.05397573990066,223.03302231371174 +63,178.56039861950646,222.19098474984543 +64,178.37920648184422,223.51557294327878 +65,255.80438353417117,203.04815455047097 +66,262.478672605179,208.85138164100843 +67,263.60616955216886,207.2183121488101 +73,272.29022155441146,203.26015396542505 +74,271.46793735704193,204.00075736023095 +75,271.0412882240347,203.67673019265595 +77,350.53069989533947,205.1215453780687 +78,351.5335450988067,203.6132402057685 +79,350.54080463471854,202.80860415043412 +80,310.84312359894454,203.07084060099984 +81,309.4303871248667,198.8260778916456 +82,312.8487475083582,197.88498609405823 +83,312.4494378330193,198.02482356912975 +84,129.73316120742015,252.31402870350382 +85,130.09936826716955,255.07600217340146 +86,136.48684968097632,256.98593054341063 +87,129.96018632025633,253.63904238622214 +88,180.12754728190527,256.91804818977533 +89,173.42291095269067,255.58833819764322 +90,173.0543226504001,252.5748838461415 +91,174.29585433427428,254.46270745029543 +92,216.78511969207446,254.5914187233686 +93,215.97344562124545,254.7054640425066 +94,219.24024367384476,255.41662872012847 +95,213.81498670140752,252.60321047848737 +96,257.3830982530756,252.6691612485834 +97,256.07878148245777,252.5850508469038 +98,256.6563709830754,252.14302077100646 +99,257.10274737541874,252.44669038983187 +100,297.3527413648711,254.3197859755712 +101,297.36935919598676,254.31625883281748 +102,297.45043676182286,253.29006124829388 +103,297.15639353267426,254.26565823155238 +104,337.0838455883894,250.64743017278894 +105,338.2943046084806,250.9606925384406 +107,338.46927119138405,251.82861699933284 +108,337.6321115297869,249.87042147419172 +113,273.20050531167254,309.1760573916311 +114,275.593658985165,308.5727448984995 +115,276.45985797306344,307.75120186662025 +116,276.6589541465393,307.7328403118153 +117,323.8680795155452,311.25555593462394 +118,323.990822160368,310.23497244583933 +119,324.4759468599942,310.5137190042532 +120,325.7385894442358,310.39579583995135 +121,361.82046220765505,312.6906221126212 +122,360.25109899783934,312.73975566628565 +123,361.13964194906663,312.4482596768938 +124,360.8021695665512,312.55731463103996 +125,443.60378722604213,316.81523544669056 +126,462.74164751366203,314.6397925160877 +127,284.4684422338389,315.96181914108945 +128,451.0537747662026,315.05034330850094 +129,486.2262311408019,318.917422588962 +130,484.203371665194,317.155262043757 +131,493.1775485408943,316.3518621311899 +132,483.79815450187516,313.87456269013853 +133,58.415796919717515,296.3367806354237 +134,59.66992690532717,295.46552315023496 +135,58.30852857429605,301.14443002474417 +136,57.19875149216512,296.2038703275876 +137,101.88869112962361,295.36699152796956 +138,97.74223572831934,296.64159635228486 +139,95.13971714462463,297.63279866894925 +140,100.97448449522825,296.37143206657936 +141,119.6488680328135,295.99857882673734 +142,116.04630564586442,300.9428981940468 +143,115.93833802312685,301.4015147621542 +144,117.66427038686425,301.67621994166734 +145,143.61862339021508,296.87569921241607 +146,143.84226240395634,296.5995702000957 +147,143.41726284468888,296.4604242772443 +148,139.90710854861246,297.05847391439454 +149,177.97012292111646,297.29360417935067 +150,179.09943783225685,297.22176671479934 +151,178.4595029850307,297.07969710485736 +152,178.9990807254096,297.58186299960556 +153,187.06432524491635,327.5110792134713 +154,187.40611165319353,327.24266469486685 +155,187.48202253723917,328.1910452260973 +156,187.4554203440108,326.77537509295496 +157,230.1275716483488,327.66375493177526 +158,230.19455285047118,329.6573791501422 +159,236.39481488323716,328.4457905246168 +160,230.1984260911562,328.23405030487964 +161,272.1545894887068,329.32912181766994 +162,272.8983988300567,328.70387641284987 +163,271.6162444327857,329.4696874435773 +164,271.6290916788945,328.8920615225914 +165,313.03716740034986,330.7975522275865 +166,312.7612082311074,331.01658878813123 +167,312.555857804164,330.94886104868783 +168,312.99233681057194,330.7594147506374 +169,395.6599712440442,331.38000769767353 +170,395.7269407162828,332.3551932767835 +171,395.64772093777225,331.19728501985406 +172,394.5822232990254,331.28589367585266 +173,172.19300877613125,153.8677984100333 +174,174.43739755929997,152.4534316026212 +175,174.29318678572136,152.18270882980445 +176,174.37774565459176,153.9168218422937 +177,218.8977614990739,156.58401687998017 +178,218.82234457362887,155.93775870476483 +179,218.14869261453913,156.17880976796908 +180,219.6136087965169,156.013833915525 +181,260.39420520785944,156.89107932316213 +182,260.75752017274766,156.5286129544145 +183,260.0769741828374,156.73605149236164 +184,260.3205919730126,156.89282130924727 +185,302.8007745851293,155.22452212795463 +186,301.70658980492703,155.39202732491273 +187,301.9655960101498,155.27173302476598 +188,307.3464400351471,155.7530563647103 +189,385.16837677047874,156.43907420157797 +190,383.77693943350675,155.96991177533516 +191,384.2249550976313,157.41263864645526 +192,385.2223566829572,156.31521854739066 +2 +59,94.17681256320567,218.7493975260511 +60,95.60291842116452,220.23420259378253 +61,95.02957510532019,220.4523644522619 +62,177.79543145664374,219.57549575966527 +63,179.18294098400213,220.75147009194285 +64,178.6879893390563,223.61664229341952 +65,263.02108805781836,206.8238570753259 +66,265.3281568315068,210.99878283626376 +67,264.9755279946045,209.25693017899349 +73,274.91234547074936,204.52721235111983 +74,273.0873606007509,206.72185414526035 +75,272.91870930424335,206.4183338799366 +77,352.6038013638071,203.61911600747297 +78,353.00800784867783,202.31796836001985 +79,351.746134852955,203.05786731461058 +80,311.08741311854095,205.08798593428077 +81,310.4676353064527,202.3951467032501 +82,311.07935156741206,200.8328753632899 +83,311.4698975682484,201.29198895046432 +84,131.85526420446874,252.0193765605421 +85,130.09901692321196,252.49815518747823 +86,128.98108803670195,254.22164770572394 +87,129.58841891167637,253.33496272524005 +88,174.3431769252481,257.67973667788516 +89,173.08617175672723,252.22705318297471 +90,173.16612346262423,251.83252079351362 +91,175.31435856398238,256.47051595889315 +92,214.0019796882893,255.64524660837301 +93,213.6417614987187,254.76260041862824 +94,212.59841286272757,256.77538398368796 +95,214.6340156872122,257.02599392382655 +96,257.12202196483105,254.71576094200717 +97,257.3916794657995,254.02867969902485 +98,257.2278305685032,254.5619736557002 +99,257.16282933783424,254.477050995793 +100,297.5612747805052,254.68621271243086 +101,298.3394946306158,254.9149917819558 +102,297.7037470787607,254.32926027245796 +103,297.9018444784966,254.79769770872946 +104,337.7041120241776,252.2287315192184 +105,338.43934115988196,252.2496982308047 +107,337.8271824583213,250.73973826046893 +108,337.86197274862946,250.42655028770324 +113,275.3004995531795,306.83564646386503 +114,276.88576480308285,311.35434787217997 +115,277.14029465508577,309.65039091667654 +116,277.4324777875824,310.4960617480911 +117,319.3288258962187,311.6702225501444 +118,319.8591509274496,310.989524065149 +119,318.99005649592243,312.4173775749036 +120,319.6131328938472,310.5522979637107 +121,365.29517640566365,314.6454813265486 +122,361.82211363523294,313.68568720200915 +123,361.4480761928614,313.0382171673784 +124,362.77676743108657,312.1993102338357 +125,444.8280999329621,315.2874742212303 +126,440.039105136866,316.4990582369399 +127,440.1448707987162,316.91453325930746 +128,444.4735843873624,318.5837135172218 +129,480.4945871932981,317.7789400812657 +130,480.34502455519726,313.1237155709503 +131,479.79765238044547,317.8026694666446 +132,480.81626241860704,316.98435781490645 +133,482.1126824365287,292.7236746644675 +134,60.57986058588791,298.3572263782008 +135,60.26789543218528,299.7821310194954 +136,59.50091999103519,298.34107118829087 +137,101.38271621918946,296.483247325443 +138,100.43332664554771,300.16356781590855 +139,88.95536885340141,299.07746679015054 +140,100.29389089950519,299.8972675509202 +141,119.96308784890563,299.8312652747876 +142,119.21634890704448,298.4258068241335 +143,112.26314328941838,302.0132035682278 +144,118.63154926153814,299.5090092566827 +145,140.22829557703238,295.83589398019353 +146,143.96502880541922,295.45158153676647 +147,140.66008917985863,295.75005128745903 +148,141.21893535376495,296.1533805219746 +149,183.47872058961224,299.0180109809012 +150,183.1202811035564,298.79425325159076 +151,183.2016789609457,298.4838438451825 +152,183.56716590770395,298.3764936397965 +153,190.41048704769,330.4978785855013 +154,188.96675676778156,329.9036439013521 +155,188.33490314035438,329.81417912235116 +156,188.31414516895805,330.23186734474723 +157,231.30258441852257,329.2869590111576 +158,635.9719402081547,323.45669801247647 +159,231.58692741290457,329.78511421313885 +160,251.94245026669623,329.3621392921355 +161,275.38274900691636,330.6582764942376 +162,288.16094061378243,329.96864420502334 +163,273.9343912983064,330.28517683915425 +164,277.40318080027276,331.32724722075693 +165,294.8273106877241,330.7078842677868 +166,317.03626643514605,330.57896380392424 +167,314.93276908458336,330.67614347282944 +168,299.640483801822,330.68496013319924 +169,397.31504374955824,332.3446123671715 +170,396.5580357804531,331.5612694467712 +171,397.49205012933754,332.4442253933989 +172,396.4373476151805,332.4498304809778 +173,172.71708638362486,155.60703919548823 +174,174.69066860790247,155.66811371703272 +175,174.36012639095586,155.21688748228445 +176,174.27542002212184,155.33243945954135 +177,211.35953547851577,157.84363965463723 +178,215.49817946473246,157.8061035073585 +179,211.58080964064885,157.9196266744007 +180,212.21010780634873,157.82655078622685 +181,261.951692200774,158.03145626439886 +182,258.53106462200054,156.41654274449266 +183,261.9931127261629,156.844374467896 +184,261.97037263466234,158.27263012263947 +185,303.2394620820782,156.27343358354165 +186,281.81947814044815,157.07330827651708 +187,296.79672730554864,156.66963976209618 +188,300.202613978401,156.83041886564462 +189,383.13489230058434,158.29028886500078 +190,385.65899984883004,157.07389261777607 +191,385.5178115620514,157.22774057918932 +192,383.2113575049479,157.78585537067738 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std1.5.csv b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std1.5.csv new file mode 100644 index 0000000..cd215cf --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std1.5.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.32510644540474,217.16136239737153,0.6182377010412883,3.437860778311802 +60,94.65266061580076,212.6177146123835,0.765212453826913,3.6739543947311417 +61,94.61401364788813,214.22486674207525,0.8412783951060775,3.3611479966616367 +62,178.35158089537316,221.847988586586,0.9403897569392258,2.7273751079265014 +63,178.77936146556561,222.1382787309958,0.9463391509324931,2.657550420078367 +64,178.51870559728806,224.63353150383256,1.0071690155319815,4.55962144903764 +65,265.4101380731767,202.08888192291917,2.9369222816228366,13.78987315189462 +66,265.6989344950027,207.74953132239617,3.0204535635810923,3.1036977294508623 +67,263.08964545761665,205.42187070515965,4.431842546811981,2.358949151269513 +73,273.4831703233573,203.64459660353015,7.04945617162013,7.94901069703423 +74,273.07076432835294,204.06679372614934,6.89788799009703,8.626898083569905 +75,272.1738130844689,203.78689920903042,7.135173768291136,8.947454341776009 +77,351.279939281129,204.46673588623955,6.045106258240715,3.909769225255067 +78,351.9201632813107,203.06242013391767,6.757744778249452,2.7563070866266073 +79,351.5222044161429,203.62412359740455,6.8762860015843,2.4772722541589194 +80,311.4321457450739,203.50054128359008,6.239505058348041,5.6340319630028475 +81,309.7350900557848,200.1189157557026,6.786112432854393,3.7532785541909637 +82,311.0972982876571,199.22509501936744,6.892343194786746,3.2293740231207715 +83,311.16518083066256,199.25055482945473,7.010045021779638,2.7712015561427807 +84,131.23754348858074,252.26390581496943,4.531133252555627,5.315476076691151 +85,130.00327880890623,253.73048027246645,5.394441049750279,5.395681634052309 +86,129.11103579380026,255.02208812060525,5.279052334030264,5.613375422087035 +87,129.85581048785428,254.17406429530502,5.674102333754549,5.78050786879303 +88,173.6706310017366,256.75225947929334,5.866553313440161,5.378715368726579 +89,173.10982411900085,251.5446731759652,6.879373651171615,2.5523562516540665 +90,172.75015150634195,248.10188260321166,7.047271185711796,2.007986084013029 +91,174.99352952512763,256.09184964129855,5.235714833141598,3.313609851436995 +92,213.8661562238959,255.830056426469,6.707076930736432,2.458271305003053 +93,213.4468844061598,254.50412813549863,6.518799611232329,3.278464480563131 +94,212.79962250914713,255.43887452853883,6.766022500672822,2.705140416783796 +95,212.4983956286567,255.64768535613388,8.38922518196436,1.1489063054666482 +96,256.74603239035036,253.07252663449168,6.865986829223564,2.6663521829239336 +97,256.72510650144056,252.79028393976105,6.828380413657813,2.603426429287444 +98,256.8221014295006,252.7889068984261,6.821267955887984,2.7406932410109657 +99,256.95819898248175,253.16068182860602,6.8533044126794715,2.6857466734869786 +100,298.0833417924816,255.11218204520893,6.68748523503982,2.5312282089724154 +101,298.2658386968296,255.0162251091937,6.972265462941957,2.391655492853278 +102,298.07594362921077,254.9831987261273,6.694673144383624,2.446242469655284 +103,298.2353998576801,255.3627222097245,6.715087554789903,2.4808962893039186 +104,337.3091830161018,251.4473414930906,6.239563573099407,3.9949672494208963 +105,338.50157961505033,251.25839644260412,5.899400220598736,4.074419748640388 +107,338.2423485650474,252.9079453166733,5.969934007979263,2.2333183687357447 +108,338.5801482804283,250.28634549329695,5.539855669597802,4.858284281787599 +113,275.59876651558005,307.46189968535816,3.9436251120891708,5.10683987641902 +114,276.1686694961398,308.57204326970526,5.356119731482595,4.772688054972327 +115,276.8157548930389,309.70713161790934,5.002026768143788,2.583003901658473 +116,277.0444072504442,310.2242983789689,5.093238900500282,3.2415570106605673 +117,308.9662148000703,311.7697205368066,2.2792009412856546,5.410806300828905 +118,308.46078668862316,311.92138655579373,2.3941030136668364,5.421098042888929 +119,308.7154324709243,310.66348827344274,2.3309057135226756,3.5206003610285515 +120,308.24434710841035,311.76621158888577,2.470183201647586,5.328252659543528 +121,363.68682214557504,313.51876571316154,3.8856640715067936,4.058166847376938 +122,349.14935421068765,314.03103766657546,2.329671674152375,2.776838944594597 +123,367.58471869225144,311.42252084107196,3.923615531492719,4.789041635546242 +124,366.2205639783599,312.0147408219617,3.7204140057381685,3.975220041758474 +125,443.4421791253585,317.0454064337059,3.8532517828906077,3.2746926716250857 +126,442.3085572430623,315.4881011805151,2.1017637979425676,5.638134747002355 +127,444.0456031701909,315.5453281878035,2.457515375747752,5.721606221790266 +128,441.29274663891704,315.9751158703776,2.8445523791239578,3.391499475116884 +129,480.1126176912876,317.72874213425126,1.9715561431765554,2.8371867515089835 +130,480.7028108376642,316.04711281162145,2.1090053401415116,3.7239493086812376 +131,480.3028282756367,316.9828674719394,1.931835914107085,2.6912419384547803 +132,480.759709821911,316.6390215996198,1.8855815838100882,3.2368313913566618 +133,9.357026815909922,301.1394481670515,7.424860692299219,3.8886973359748533 +134,60.799946985869205,290.82662639382374,2.410669490697829,3.3307667086551547 +135,60.28851015248002,299.3626408593879,2.610803253456402,3.4448392908334102 +136,59.58730981243586,299.348986354774,2.4093805788992184,3.557779220380588 +137,103.27374468276936,295.56230309563284,2.5132133127505014,4.351160826227996 +138,99.75383058106173,296.569880707365,2.5218334720238236,3.501899754104677 +139,95.32232328874625,296.73397752555695,2.877040509030959,3.4555743629781466 +140,100.87147176733903,296.3324977713732,2.4143008563576176,3.405547995808848 +141,119.67590393924556,299.5719162206477,2.715209640937237,2.3146688915381275 +142,117.02401243356974,298.35207687180383,3.08539437068056,3.0048819093528643 +143,116.04574600753108,299.0124296372606,2.8382177918151514,3.279021572744144 +144,117.37742445192025,299.4258416995056,3.1697222157479636,3.228779441784994 +145,142.9769721583903,296.5366900343606,3.0832619899763425,2.644094161149235 +146,144.05541849455753,296.38389634445554,2.9996657202962216,2.5996279341099453 +147,142.7610177499935,296.49057527125143,3.132429288120055,2.6497556402515237 +148,140.654399096409,296.487509133948,3.0056568959849406,2.058048941223319 +149,183.71806867676824,297.5062440925511,2.457573643605339,3.0504821593031735 +150,183.33793283890802,297.31881173151646,2.392042666256841,3.050918286277636 +151,183.61600393859536,296.51652050691774,2.4097480630875605,2.764147393280351 +152,183.8339373966336,297.2945340604019,2.460682969826688,3.050060229583357 +153,181.09589492836406,329.6242218226362,1.0425141465757852,3.0368750466096333 +154,186.11052367996277,329.36778207951437,1.3324891141111836,3.0102790481884694 +155,186.71507659948506,329.31046601919013,1.491127987331188,2.737120605219304 +156,186.77967822458413,329.3378404603494,1.4948700160207713,2.734563650578621 +157,230.65228943659753,327.7840930500721,2.295828556135942,2.4982820936800283 +158,208.88398865586805,327.9985148865243,2.02425621449308,2.350854989534598 +159,230.76774042649313,328.3139314865929,1.058343333489383,2.1110955225257957 +160,252.12645006163774,327.8829847714941,1.9966581003411814,2.5372848351369273 +161,273.4567736740019,329.5617685669899,1.9537976371799024,2.0154389968753095 +162,282.2315955976967,329.51993412315335,1.6558383645274921,2.0452106688498017 +163,273.720574310258,329.68024219956664,1.5653369253681564,1.8342890718749 +164,273.889758529857,330.16719840873463,1.5821177076586581,1.694040868940706 +165,313.5406083274413,330.6880662983543,1.5169373766112113,1.9512244512786259 +166,312.99217961793585,330.84544281473285,1.9687039019856765,2.6822749686071305 +167,313.7630009835721,330.8583984920328,1.4848333229111295,1.9827954471887683 +168,312.9401442321904,330.7254552672906,1.7568824225422763,1.9323110607855833 +169,395.7207767219437,332.183165147594,2.4577717664195537,1.7621285751654179 +170,395.3337266028771,331.43381176706987,2.181281870585342,3.1337432803521126 +171,395.85186369230047,332.27068551595306,2.518966823398722,1.7204609744266823 +172,395.8084329126563,332.26796527945555,2.6126143387145087,1.724913210963549 +173,172.9730835697278,153.07041804847032,2.9494726617733757,3.382217579007034 +174,167.91626071048515,153.50090831100303,2.2490783825049045,3.4124393018031505 +175,174.36354763148583,153.16813701756828,3.0454139103327917,3.4583182798940344 +176,163.9948808388554,153.12115036518048,2.245850905919589,3.0039836826659077 +177,217.69107890505612,155.58013869177068,2.7767507060557537,3.794972875980232 +178,214.66253412696085,155.42760092218833,2.282992010999303,3.7924195042280746 +179,217.2668815139982,155.37466732788673,2.82114799379885,3.7715102977100545 +180,213.54537138523426,155.3242530398654,2.39080632265553,3.8737974440740692 +181,261.6939418857524,157.09312093358466,2.9274288743236836,4.2654996092602575 +182,259.5388851666542,156.21847108548155,2.740600451522983,4.256469485200473 +183,261.7749420583441,156.80848263234637,2.8761845595169624,3.611268367181998 +184,261.7034113220799,157.33345113871377,2.9950641148825974,3.4845516638308904 +185,303.89901305026916,155.6612518414893,2.621571563900723,3.473866833204008 +186,301.62587627334796,157.29265691699584,2.567822100277209,3.8190983468951436 +187,302.2849628418849,157.1968491242557,3.008452770801469,3.8181849057828567 +188,303.7565642594758,155.85469430778133,2.429239927505623,3.326076201679362 +189,384.98371808681327,157.38821592622213,3.1474479877455135,2.841847047972341 +190,385.6953493035584,155.9304125075569,3.6373602156895406,3.649388391215581 +191,386.1522285343919,157.13110788307986,3.4178090658584948,1.681812080594319 +192,385.09319956411656,157.18765906545738,3.129473983251964,2.975867208927914 +1 +59,93.00875717999857,213.0864805157829,0.5227911458975513,6.19713029420415 +60,94.33424540812612,209.6207769002175,0.712959043184757,5.35016277729406 +61,95.1076356890004,210.44116297321946,0.8764776639925613,5.547156704495216 +62,207.5747279334015,229.35385437625325,0.5721218590130254,7.308688366893414 +63,178.26435087496964,230.13928425075747,0.9163078266059032,7.241140371768349 +64,177.90044660433097,228.64882156245648,0.8264625430894746,6.592321670041416 +65,261.4355459288758,202.518302086519,4.641943406474736,13.108375146006386 +66,263.67870524819034,208.7072384357703,3.5858326934539724,2.433228596876354 +67,262.17751550130487,206.93217537761328,3.452444759098905,3.8722633351342384 +73,271.56705521542676,202.40830594251935,6.020267230118504,8.477756512699672 +74,271.73829194020016,202.86157549101065,6.298067280843489,8.419553297292511 +75,271.44195864454383,203.13378150076727,6.235685371158418,8.78878791063504 +77,350.3978097520949,205.99099129354195,5.486198418330991,4.23015499642844 +78,350.8542007403272,204.8726031135868,5.884173027734943,2.402879521643992 +79,350.33767761544766,202.27664047975287,8.070802178703657,1.9426946744270117 +80,311.14553424067776,202.4869088895573,6.8627096705514905,3.849897420660647 +81,308.5842159554098,198.77298238575344,6.52057770401923,6.006445353466768 +82,310.7458930121221,195.62555942687163,5.367642235757289,7.169712735992463 +83,310.4462741092919,196.04905416426502,5.898927104709222,7.285208599925228 +84,130.13558933089806,251.82817494602546,7.150925955550858,5.341680351200341 +85,130.18397703583258,253.52743282837022,6.541689138699417,6.299622234665423 +86,127.98319134864182,250.82109733724317,4.738368491228839,2.57221862750688 +87,130.22115190707984,252.63693413729288,7.110134503566371,5.544397590264715 +88,170.3259733642306,255.66266877807428,5.690121369029169,5.9867577312345635 +89,172.0725262476556,250.99873611079994,6.021708452291268,4.7312867200629105 +90,171.99327618907063,249.17936838672563,6.229499399540459,5.078719873917035 +91,172.29510140368106,254.5565739501181,6.451006926460406,3.9136334301532982 +92,213.1828066056623,254.92363133767387,4.131010753144876,3.5262173672553687 +93,212.87022485654242,254.1472663576613,6.024553307028744,4.36937145736752 +94,212.13601387505264,254.10698963113109,5.484917596658879,4.460238419613106 +95,214.87325400509656,254.39310436749193,5.506727817013678,3.986223925190019 +96,255.87095795884755,251.70990738025452,6.095777014998389,3.032297848733597 +97,255.63216745384443,251.63937961156105,6.119873150459129,3.4431842597866478 +98,256.06917412538536,251.38312888217393,6.172049945445992,3.0818160436840696 +99,256.44518378286506,252.4176024183597,6.2866487953086825,2.5551750914715052 +100,297.8311949255675,253.9653171752207,5.924725404966239,3.1672044636908576 +101,297.57833588228533,253.99818141838037,5.944381655046086,2.746686532181724 +102,297.50136975432514,253.68544368933334,5.860286142652836,2.8473861302268335 +103,297.7295288163928,253.7737365687886,6.239643764909305,3.2568997394492816 +104,336.7180543456296,252.55145794454867,5.584269888775618,3.3139652271056144 +105,338.49750522296745,252.07705913627754,5.543320366201012,5.442573748366097 +107,338.0150937851073,252.18608250396494,6.036908819248115,5.0311597932446395 +108,337.2951518337468,250.18224258519146,5.881938681047152,6.491905854296189 +113,273.4815993508197,307.6936923289109,3.1012639427533784,5.154672012501804 +114,275.70060000212146,308.5897280752863,3.9037828113839366,4.201910703737281 +115,275.8323442926472,308.5631016742169,4.908621601004965,3.639510737864438 +116,275.6606088252997,309.15745128264456,5.248785953237486,4.1594464461611045 +117,306.56743395611335,311.7534996826885,2.112121697069489,5.820314553091814 +118,319.6052247158424,309.2092876138521,3.0994427567914853,8.01149636027687 +119,308.98961216723023,310.3876530882548,1.9815028323151676,4.505358981721892 +120,307.0431037398603,309.3570250757065,2.1228582042961364,8.133763836800041 +121,364.6612653249806,312.867105648696,3.6082645560201403,4.907320783558812 +122,359.5565312405258,310.50474411241805,2.3300472525322222,3.6383073582313625 +123,359.67023843236564,311.274718807607,2.359429636308929,4.812109039516953 +124,359.55652211431163,309.9599256178089,2.821256013884825,3.8133629555932114 +125,444.4021410207277,317.8526352360211,4.078133482194948,3.9911353122263296 +126,439.64702159418067,315.15017744463006,2.254461458911636,5.747036062574868 +127,440.69585939100426,315.0579828759502,2.7149707354695605,5.752920657180591 +128,441.8625387527503,317.7326376075549,3.3446365437819154,4.190002229264773 +129,478.5750112776985,317.8659165254805,1.7655709538040265,3.094544391955392 +130,480.50423944788866,317.3650260367778,1.6290524950029868,3.015416485400363 +131,478.66450057520063,316.38942944947695,1.7953728376964107,2.42227888620822 +132,483.0153971429184,314.7305690623162,2.7300211118973263,3.080445570051542 +133,90.20291039246604,298.07507002916145,7.598743409857649,4.552890998174248 +134,57.81287299171998,292.38407844216607,2.514015918277811,5.136006470534924 +135,56.72481683615359,300.0118009139173,2.857620857781098,4.750166949488199 +136,45.96616366715866,299.693904996051,2.6917302124926694,4.645496991603487 +137,88.02035707489331,293.3669429657606,2.0117005484316364,3.9293747558559278 +138,160.04855077999034,293.33750956777976,2.7841652419514227,3.7908670426694497 +139,353.4092012789472,292.0076334322056,3.014363497918401,2.928043350479415 +140,89.97636900626323,292.9113392808752,2.65494720185284,2.8719276763310857 +141,115.9594791110215,297.7222868684274,1.9069874131620126,3.352456382715099 +142,132.15536640954062,297.2171229012815,2.706901698676143,2.9568780838711826 +143,127.1646193746793,298.2335745308878,2.769134247080161,4.01114038711725 +144,130.87079961636513,297.89834733182647,2.818953624476529,3.8997116282895603 +145,150.31209355255865,296.8214130757569,2.725175079922067,4.209022465413865 +146,148.97786084884208,296.6038327691481,2.7067927491075574,4.17492062013239 +147,150.24661339572495,296.7796929595484,2.810800536874064,4.312780918203187 +148,152.5470386382202,296.79763117851934,2.8754159917495565,3.731793392125523 +149,178.862609212918,295.9186248626812,2.5841961653378953,3.1991556673695176 +150,180.89610810712188,295.92807355671397,1.6842427525491304,3.8890257041235543 +151,180.40049251926752,295.77981228572037,2.6591704134491323,3.917421171009508 +152,179.72946886796663,296.05583778880305,2.564660161772704,3.9159370208085704 +153,185.76625246646185,327.4055525477087,1.9261688345955168,2.5002553115545973 +154,185.68007483081436,328.060632980561,2.609970861940605,1.946219519924639 +155,185.37113250572602,328.73195534315664,2.4795691921165655,3.2840453584363116 +156,185.5418021015136,327.6689562730928,2.375786778236521,2.651340769524802 +157,229.27152294423166,327.3561714417115,2.4437228704779783,3.2195371224858063 +158,232.28441597607784,328.09402673325656,1.357599811770978,3.094542048630364 +159,231.00284475154749,327.9998620514896,1.2108444033536565,2.66674404960965 +160,230.25470725406453,328.0859285158972,1.7316362106698195,2.88263756637543 +161,275.7222561716378,329.45078955534507,1.5401263844373954,1.7585024676985501 +162,747.2675063983792,324.7536431546597,2.1073598387590406,1.9846975991560125 +163,272.00721091330865,328.94613162616673,1.9128906508563452,2.480037037665106 +164,272.2943718583655,329.13463420388416,1.8135422013484646,2.333221321023227 +165,312.27917579462644,330.90999638474113,1.8158878550164057,1.9866753158839707 +166,312.63990435472545,330.70825140967025,1.9310585450982856,3.1257959767437193 +167,312.13911877602334,330.8661550202716,1.8464663431187927,1.573517775693253 +168,312.52858835763556,330.76426646797455,2.161251844547869,1.933118359992701 +169,395.14083600756334,331.87815070527694,1.448023063266429,2.3167851906782087 +170,396.5732738072064,331.21301140029664,2.7671279378720532,3.432678442805089 +171,395.3116027704574,331.9375695732541,1.4531763607459942,2.2989452818042047 +172,396.71305866511483,332.1630656147329,1.4224167184507017,2.910921037939185 +173,172.38094968570545,152.05413649604458,3.009792250294108,3.523757740020178 +174,173.8453388820814,151.9722418163993,2.4225092170582014,3.3547430273206764 +175,173.7469031569836,152.01702715147732,2.992197181370308,3.5878204759260535 +176,173.94321589450442,151.8994649734145,2.441865274900331,3.3191803731856986 +177,220.05954791045562,153.93486125597713,2.916964654294944,5.161796303421409 +178,219.06032109265325,153.8679197592309,3.02283014757281,5.214692401346838 +179,220.20248145797134,153.83037812747935,2.811916018641933,5.135768243874929 +180,219.8402257665675,153.69441590096454,2.365027188775977,5.195182563087241 +181,260.4380890463525,156.1736753615838,3.5506189837569733,4.210885005617385 +182,261.1508899611818,155.0680682988112,2.839394772014497,3.5985227200258616 +183,260.30310151802394,155.61059359790818,3.5432570320956893,3.1707993199082107 +184,260.4910132005214,155.66192708074522,3.478073697651597,3.1191145304607857 +185,300.5406946589481,154.9084556815696,2.3966410747454683,4.257306637411747 +186,301.78308068276635,155.27677811490247,3.0779278021862946,5.064316807047082 +187,302.2761713726962,155.27023677113314,2.993547760611472,5.214144626020445 +188,302.8236206973499,154.69674142960957,2.4778587529647105,4.640007316386941 +189,385.48180701984114,155.92489835616408,3.473675270188691,3.1517197697620283 +190,385.08967578482293,157.6459314691889,3.5586590950004457,2.667151842484689 +191,385.58591970819674,157.30125119156654,3.631613447401373,1.9082302724245561 +192,385.21072355609897,155.7094594652936,3.6798775544177063,3.5067454833259255 +2 +59,92.65376110690876,217.01497137821914,0.8683837090191788,4.157428729871967 +60,94.82990413785946,219.90540926030366,0.7890608958947835,6.846135813191627 +61,94.29121037749401,220.03685469388876,1.0749214557030176,6.838018547816678 +62,177.10956003057285,218.90103728250688,1.3905251660790856,2.7497320728371646 +63,177.74456263111466,220.06649622720403,1.2185587916549738,4.188825256215504 +64,177.4433366943884,223.83295887197295,1.371218908578905,5.2592726336887425 +65,265.6878095601755,206.65513281700575,5.33587015800756,16.669713322142147 +66,269.2923498741563,209.05824066438973,4.66895680216908,5.263799522185158 +67,264.42528410909586,207.364718342118,7.577757476106213,4.472335501339223 +73,280.9764776348652,202.68253855726255,1.6546267117994216,6.318822469408919 +74,274.03045869010333,206.973282686757,7.997571675272475,7.243843769359161 +75,276.0822341347654,205.61933530967025,6.510520268907271,10.3236022000293 +77,352.4139935670206,203.48156974798098,8.32458599948799,4.470725516378897 +78,352.6633237122737,201.43070660774114,8.497380645406677,5.377940688297667 +79,351.62852667070297,202.74208620682512,8.658775240139533,6.487198309406779 +80,310.6751701124307,204.64495746423012,8.062037456416205,7.444446872078048 +81,309.7010694340917,201.889057384221,9.465643221743878,4.651552993103335 +82,310.6335818256993,200.22299800671655,8.67387089777447,4.664159850458751 +83,310.8614265739441,199.458651883236,8.510118775528804,2.8724484284650633 +84,132.03262725456108,249.4924232903857,3.0768121962170567,5.169014220579259 +85,129.09144907108433,251.7203734728845,5.198191014751725,5.290792123590904 +86,128.11492684472694,253.65236303540686,5.978168978981718,4.352921913597757 +87,128.5504980446596,252.95544188750205,5.339963887657365,5.754904964464613 +88,173.85018852313817,255.81968964851026,6.482400441297941,3.4989983294150475 +89,172.52528902354035,249.2499609079768,7.275410666068803,2.2756893414086514 +90,172.38753943021908,247.6577135955906,7.222779487902638,1.831029568977615 +91,174.91415300342587,249.18228108995524,5.447412274608176,0.9909035227650256 +92,212.05665773319856,256.1820062089689,6.711658598234498,2.9976841684576496 +93,212.8172314127949,253.39712914171187,6.857530904039771,3.977160865721656 +94,211.8792430432469,255.82761299122967,7.222038595318558,3.1694534357454573 +95,215.0833848468073,256.1212830567826,8.467407782374746,1.9473456404121796 +96,256.9743035103019,254.71512762526666,7.44290569053337,2.68632372187447 +97,257.1457284865542,253.4535805850962,7.332108489145229,2.4944378698026863 +98,257.03430784028274,254.5812608515072,7.2764048131626184,2.4480433538371873 +99,257.11318563543705,254.84544472082902,7.423089718980076,2.5660592893878267 +100,297.53329552210926,253.81655725507431,6.852565823032563,2.567811443943226 +101,298.60461192426146,254.17438371162478,7.905691877078718,1.825741321015611 +102,297.69407107379396,254.4850393852944,6.836012542442264,1.946205259389151 +103,297.9023244730469,254.38868473138925,6.751896664205788,3.3116178759031087 +104,339.48285905633736,251.81900285371069,5.942208628240243,4.945594824336877 +105,339.1205482251966,251.30122032806455,6.500886426061445,4.808751958411583 +107,338.4272019992697,252.19848894388656,6.48687937625559,2.8213077726348095 +108,339.54299063145817,250.0031283857795,5.812146409240677,5.287653170857336 +113,275.910952296904,305.86738853882827,5.34030651381748,5.289299280058491 +114,276.35015397667075,312.1081102609041,5.162726712460268,6.6369445658697455 +115,279.0736812899919,311.07994680544203,4.951788309478035,5.01744381383027 +116,279.87420391551683,310.72506489150953,4.822827709017515,4.736286987210306 +117,304.24552486172325,309.69865127849215,3.00277312239498,4.555283930061753 +118,302.7212817727547,309.2230592598733,3.16363749983184,6.857616858633486 +119,327.09308351776593,310.69024753529516,5.288987908246067,4.6842841758469556 +120,301.0220842644409,308.7703307062073,3.8966104642189516,6.518991290453131 +121,367.6098676953658,314.58028508890305,9.39615711787979,5.649531231448145 +122,397.3328204276317,315.34567189868795,5.7108612456732715,3.258105059687543 +123,390.7453940415891,311.6470607282421,5.5964184306698455,6.030687385605649 +124,432.23467177419724,311.2122511991688,5.881307854257575,4.563765149392382 +125,446.24432082170046,315.27649965719536,6.395392871846412,2.4772515296514643 +126,438.8511287502254,316.37095567311974,1.799887035029369,6.635379091123845 +127,440.35515062380387,316.80874455617004,2.7747867554906676,6.796381592950393 +128,448.99707714791936,316.64328100115915,4.9199468672846844,3.6299256024726247 +129,480.21281513978687,318.2237602367352,1.939096401014579,3.836710322440239 +130,478.7339197387106,314.27301630895124,2.087142296065961,5.08374236725423 +131,479.4617027213679,318.2468896366567,1.5978214301813713,3.688680674174361 +132,484.13323268726947,316.73499335627196,2.002291195085977,3.781086788196597 +133,85.29652368782442,299.9267050080891,7.827458514431236,3.9374236627298966 +134,59.630826345700406,299.5528993065781,2.293779231438959,5.560856320277098 +135,55.11028578417307,298.40091605755845,2.4753999616786904,3.1001830452921184 +136,52.88374765283322,297.62420743734526,2.052251163735395,3.0356052182771274 +137,102.2627134309745,296.1781450112869,1.2262813798013208,5.212420406396804 +138,78.25837410035345,298.6824898421718,2.6075704778239923,3.377654496084566 +139,109.1163322762621,297.6290300025382,2.3024123744989207,3.1885843136710754 +140,48.41182620962574,297.1931703451722,2.625583107839479,2.7907983124386684 +141,119.51602776789325,300.10453175611184,3.4424531063915236,2.642126479181898 +142,118.1973619086592,298.0334936483938,4.076098186731008,2.6346682961879635 +143,115.46104139376924,297.8312691405318,4.279452761468254,3.2247085556456048 +144,119.86152598306575,298.3571523952646,3.493981329511576,2.953550317426917 +145,145.90006454487417,294.33120612383067,3.8031724141145062,2.4031438376062857 +146,145.39522138169184,293.9045479404022,4.534922195360379,2.5317897016901143 +147,145.56468242678977,294.28930454392895,4.470204993442609,3.0933985628535288 +148,139.98418133069634,294.72850928798835,4.278137116722635,3.048819187424443 +149,184.61384435804203,298.9796024091839,2.529497564999449,4.490567912543599 +150,184.64043155451438,298.7318610841073,2.6174338934133505,4.277160291745099 +151,184.44418125715643,298.25564342712596,2.4439277524700747,4.343490136232689 +152,184.66560803927564,298.18036927693134,2.564579983473208,4.385135450871558 +153,194.19362024463055,330.1400811375832,1.1767713277123986,2.6700939408054847 +154,174.86887852527403,329.979989704711,1.8484097857820594,2.591571956692586 +155,180.79865067404023,329.8562242828808,1.738097755840568,2.338466226674033 +156,179.56170004415435,330.31834841798707,1.7754061019312333,2.638869441184331 +157,231.71308757803595,328.672133593381,2.575835953649238,2.9234623232364685 +158,255.4632386220983,327.6416302142385,4.012448382356306,3.42068392727793 +159,205.50139246153256,329.9023818846584,1.9582108272811507,3.923308113475421 +160,235.88906246092358,329.0473855498786,3.444258781962619,2.6163214632167398 +161,276.3094789576173,330.4608109053376,3.4419490584726287,2.564981348675966 +162,285.59180034302733,329.7481991930167,1.8378511022559236,2.962363935958349 +163,276.28783266348086,330.4003933681143,2.1081569415614108,2.0262424617108703 +164,197.25002629984402,331.7884197277611,1.7077843114772655,1.9623226431578948 +165,288.0915533470578,330.8983776107492,2.6656921890922276,2.4733683795597825 +166,318.99404577369717,330.52622945989987,2.512905677477683,3.0041332311662914 +167,347.80228956810066,330.51035383722933,2.7357481343278547,2.6900125091285605 +168,295.96785278892344,330.8541466179879,2.7327133833859794,2.5553494567631065 +169,399.4046364026606,331.7493713707221,3.23644714671924,1.744053910168871 +170,397.57150520306647,333.3787113091005,2.0553328419425942,2.9972979280312493 +171,399.5202454111206,331.87094628141256,3.319483494438871,1.7408731153504877 +172,399.37556911546983,332.0970117083097,3.2770522011812937,2.0503115948740924 +173,167.59893809491587,154.3249244129017,3.578104764139934,3.3198423220094764 +174,172.84296794779806,154.0436851912386,4.065505613610561,3.1479614150013635 +175,172.53685506876784,153.5142164683417,4.048705697811711,2.906116813730039 +176,172.4903195543538,153.75399965885978,4.181462595099683,3.2085629045903814 +177,219.17346400289313,157.06361150991273,3.7208701762725958,3.977297645616966 +178,218.5571656670773,157.04802019919677,3.903522619785598,4.337287440506104 +179,219.08587325813014,157.06764805172753,3.794218226236283,4.170614188910467 +180,220.20815419984615,156.9157243686214,2.7714160963084615,4.408356106260135 +181,260.19885472358294,157.7365391738532,3.7452159562165885,4.8366413757834135 +182,241.9395975737316,156.28097820179985,3.450826603860176,5.030259376007136 +183,260.2353298294739,156.54302588067847,3.729468016831249,3.948234547478585 +184,260.7848372561543,157.9506538637672,3.5754121929574882,3.800985332770269 +185,302.7343292496292,155.53108168722034,3.3675563663327583,3.3417704291330135 +186,332.63645946919394,156.3859992454305,2.765786036774427,6.391527497892834 +187,284.71333669266966,157.72636771256072,3.3503763444766745,6.365038877320703 +188,304.3997409110315,156.17999029402282,3.740908409488698,2.700855536462382 +189,386.0604531581429,157.4606593487467,3.503153843484056,3.8679991937676528 +190,385.18009669613696,156.2333983389331,3.2976202226268665,3.788089778011118 +191,385.0925046602618,156.67041836007596,2.6210706316937795,3.2806588007554622 +192,386.2128341829654,156.16694016460218,3.3738623057156985,4.160360297012765 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std2.csv b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std2.csv new file mode 100644 index 0000000..9c454aa --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std2.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.33971469075367,218.50270598733297,0.6182377010412883,4.519603519601824 +60,94.65266061580076,212.6177146123835,0.765212453826913,3.6739543947311417 +61,95.41265351990087,214.21478810961165,1.1080389271434514,3.3611479966616367 +62,177.68104319925217,221.8562022028197,1.210105165576976,2.7273751079265014 +63,178.12474883940652,222.14572970009505,1.2756265672756038,2.657550420078367 +64,177.98709471591388,224.6454307841806,1.232576692361491,4.55962144903764 +65,262.5800156706123,202.10797896730915,3.9515122758252583,13.78987315189462 +66,263.12260735580236,208.6888275933953,3.996672369259087,3.8323992242499187 +67,263.2208458621908,207.81872361983278,4.431842546811981,4.012811725696324 +73,273.4831703233573,203.64459660353015,7.04945617162013,7.94901069703423 +74,273.07076432835294,204.06679372614934,6.89788799009703,8.626898083569905 +75,272.1738130844689,203.78689920903042,7.135173768291136,8.947454341776009 +77,351.28674760518,204.59842941618587,6.045106258240715,4.408743803212035 +78,351.93164737416873,203.26383152358028,6.757744778249452,3.4138998666946025 +79,351.51705628039196,203.5492416308136,6.8762860015843,3.019482596125626 +80,311.4321457450739,203.50054128359008,6.239505058348041,5.6340319630028475 +81,309.71370799855777,199.8072317333757,6.786112432854393,5.546655412414925 +82,311.0912672829532,199.1202501566774,6.892343194786746,5.054703376541651 +83,311.1638007195464,199.2269266475195,7.010045021779638,4.7578939104794555 +84,131.25454150771196,252.74638995613617,4.531133252555627,6.22007738425752 +85,130.00327880890623,253.73048027246645,5.394441049750279,5.395681634052309 +86,129.22821068759833,257.7545799264177,5.279052334030264,7.778585552031296 +87,129.85581048785428,254.17406429530502,5.674102333754549,5.78050786879303 +88,173.6706310017366,256.75225947929334,5.866553313440161,5.378715368726579 +89,173.19230063382054,252.91916601625073,6.879373651171615,3.4635068657166914 +90,172.94503754837874,251.33290936706462,7.047271185711796,3.2903077685151048 +91,175.02952167330142,257.0499364883758,5.235714833141598,4.602554026194267 +92,213.7890816038331,254.6249053619213,6.707076930736432,3.4712358181628 +93,213.4468844061598,254.50412813549863,6.518799611232329,3.278464480563131 +94,212.79962250914713,255.43887452853883,6.766022500672822,2.705140416783796 +95,215.7691494277275,256.0321075659609,11.50061919709342,2.706589746451831 +96,256.7694241536286,253.44332189577563,6.865986829223564,3.232990348543302 +97,256.72510650144056,252.79028393976105,6.828380413657813,2.603426429287444 +98,256.8442650233618,253.14460283696363,6.821267955887984,3.254494004204524 +99,256.9799728864509,253.50866793284385,6.8533044126794715,3.166075950840959 +100,298.0833417924816,255.11218204520893,6.68748523503982,2.5312282089724154 +101,298.2658386968296,255.0162251091937,6.972265462941957,2.391655492853278 +102,298.07594362921077,254.9831987261273,6.694673144383624,2.446242469655284 +103,298.1576505106038,253.88763222872188,6.715087554789903,3.885076107906952 +104,337.3091830161018,251.4473414930906,6.239563573099407,3.9949672494208963 +105,338.52343083029405,251.73143621714976,5.899400220598736,4.827509891673079 +107,338.1840923615987,251.65216202919063,5.969934007979263,3.751028655396448 +108,337.64939708910254,250.30336435438954,6.249968722123418,4.858284281787599 +113,273.95099656515106,308.7034217127645,4.47709247898054,5.982967845021163 +114,276.2427158717565,309.6243826995124,5.356119731482595,5.519574978016204 +115,276.84469790647285,310.1401260519893,5.002026768143788,3.605341196767828 +116,277.0444072504442,310.2242983789689,5.093238900500282,3.2415570106605673 +117,320.1389402262641,311.63009189142485,4.939108050053555,5.410806300828905 +118,320.02073795683015,309.86619068708495,5.027296431375431,8.060815849838507 +119,320.1219104879224,311.65149736236003,5.012337784903855,4.875094660414595 +120,320.07204598420145,309.7142498435185,5.096615721025626,7.995525189669432 +121,361.50564549283087,313.53985202649335,4.795734938117528,4.058166847376938 +122,361.26704674904295,312.86969370023394,4.911340820107842,5.091228854756303 +123,361.2967353862394,312.27740018121676,5.035196497174981,5.584514630261738 +124,361.10126473389414,312.0592776230653,4.783581913783201,5.306719192876605 +125,443.007863468424,317.0482807576108,5.010510348067979,3.2746926716250857 +126,440.19719004623624,315.5077064666447,2.501683625204251,5.638134747002355 +127,440.39835940889833,315.5795170075373,2.85606034332895,5.721606221790266 +128,441.67660517656856,316.6947608213303,3.639566862837229,4.302035563866815 +129,480.016363698198,317.9126206681539,2.233190012581438,3.490216783801077 +130,480.61644673663056,318.57621643309193,2.3716485330417605,4.382988558323238 +131,480.2151199142978,317.2082517588217,2.247293593796934,3.5149416209558377 +132,480.759709821911,316.6390215996198,1.8855815838100882,3.2368313913566618 +133,9.357026815909922,301.1394481670515,7.424860692299219,3.8886973359748533 +134,60.67253427636335,295.1565427193327,2.410669490697829,4.491297160618824 +135,60.246223227743805,300.40587765988005,2.610803253456402,3.8238226248434817 +136,59.58730981243586,299.348986354774,2.4093805788992184,3.557779220380588 +137,101.23721185167861,297.1740950583595,3.1474540219144633,4.890082550289469 +138,99.63203134966024,298.11971146106544,2.5218334720238236,4.231121185206979 +139,95.14237458574763,297.9444005267218,2.877040509030959,4.1131387022222885 +140,100.78477416100239,297.8704635718194,2.4143008563576176,4.154160490535302 +141,119.7250471805502,298.01476664170673,2.715209640937237,3.093112605602225 +142,117.02401243356974,298.35207687180383,3.08539437068056,3.0048819093528643 +143,115.80692312962971,302.2766266204045,2.8382177918151514,5.138019098209974 +144,117.37742445192025,299.4258416995056,3.1697222157479636,3.228779441784994 +145,142.90918088465534,297.6178016264094,3.0832619899763425,3.60199958241714 +146,143.99054736678715,297.3373199008806,2.9996657202962216,3.476044966382911 +147,142.68589497073927,297.6157999040096,3.132429288120055,3.6266815665628562 +148,140.49454000047197,298.03917216089854,3.0056568959849406,3.734214838274721 +149,181.1180739987013,297.45610301892515,2.9102280695661635,3.430326706550376 +150,179.8095562359686,297.27756454662233,3.021840744008918,3.4405430793578002 +151,180.86813470943852,297.15918644525635,2.8691980137577318,3.454347921701997 +152,181.2406356303146,297.2424283977706,2.9384917862774746,3.4319912000139534 +153,186.63497292825323,329.71520796854617,1.8343875090418584,3.3743188292573 +154,187.13559762838133,329.51685230643136,2.083912846195953,3.300784079309373 +155,187.40105015626258,329.53867670663755,2.14805160685666,3.2933937706575724 +156,187.47298980472146,329.56496093677737,2.1638184471687887,3.301333072095006 +157,231.53011125776158,328.40789450036294,2.6073775062440263,2.988502538747351 +158,232.95501178876998,327.80492336093096,2.424236811554027,2.350854989534598 +159,229.72646596258252,329.3298075897175,1.7204738903289671,3.0704923118251815 +160,231.2073236731834,328.6714932883225,2.4438861147678295,2.994769224677437 +161,272.85319893527105,329.5668274175589,2.341440048111982,2.0154389968753095 +162,282.2212417820937,329.4367762421606,1.6558383645274921,2.653180738201903 +163,272.98005102373446,329.914142628833,2.0535729706681347,2.386063407880205 +164,272.95435454694245,330.43431753911966,2.0639940112617947,2.36112135650202 +165,312.8967133138425,330.7228636434229,2.4191353299335647,2.683491777579408 +166,312.8953561925438,330.8465788842154,2.4840737872275156,2.6822749686071305 +167,313.02590086745846,330.8849995926087,2.3762208918687464,2.697650571027151 +168,312.9409779932792,330.75973451781795,1.7568824225422763,2.681011243704313 +169,395.70755072087877,331.7781381458078,2.4577717664195537,2.5638227463557386 +170,395.3337266028771,331.43381176706987,2.181281870585342,3.1337432803521126 +171,395.80626830723384,331.83504925004354,3.343168830623854,2.549566986608766 +172,395.9132452906355,331.8528749734858,3.487324246008807,2.5438283475869454 +173,172.9730835697278,153.07041804847032,2.9494726617733757,3.382217579007034 +174,174.54971679519662,153.38021154909217,2.9795452304182835,3.4124393018031505 +175,174.36354763148583,153.16813701756828,3.0454139103327917,3.4583182798940344 +176,174.35826919924722,153.1700612928826,3.0211141262576273,3.4091382049295103 +177,217.2505549073576,156.64130212161544,3.566395537735253,5.205239829046527 +178,217.6980323106648,156.20521332851527,3.441914436456696,5.052429489736655 +179,217.06819564151806,156.2917309214015,3.586543606555209,5.007013880138526 +180,217.747171393919,156.15624360378254,2.801603355598029,5.1577319803732085 +181,260.65829263531697,157.11165943543224,4.071932875596254,4.2654996092602575 +182,260.2873418729937,156.01133511605644,3.8080469436278466,4.739826748647123 +183,260.65241208670443,156.65264585083804,4.066095494476047,4.309005262298059 +184,260.7008275437579,157.3470048006293,4.0954566230931215,3.4845516638308904 +185,303.74815224402664,155.66355774568396,3.170947192231751,3.473866833204008 +186,302.12965337523497,155.7857969814269,2.9930059801075064,6.048866083796893 +187,300.60769039476713,155.76327680748759,3.9951348071403796,5.998453375045407 +188,303.74316048048706,155.85489621294607,2.9236413377489514,3.326076201679362 +189,384.93902681068244,157.58958174688522,3.689645238386051,3.2199234634363325 +190,385.6953493035584,155.9304125075569,3.6373602156895406,3.649388391215581 +191,384.52200141722733,157.28840768944934,4.29808384390818,2.2580181721891828 +192,385.00974793928197,156.45140110834245,3.6598188496146618,4.150545508756308 +1 +59,93.01404247432006,213.5226271525372,0.5227911458975513,6.748081819440171 +60,94.33424540812612,209.6207769002175,0.712959043184757,5.35016277729406 +61,96.49374458366215,210.39800263419923,1.1303680657085802,5.547156704495216 +62,176.2808701725152,230.63601199191507,1.0055010380867206,7.308688366893414 +63,177.7659470241458,230.15931042185892,1.1083723356140194,7.241140371768349 +64,177.32083639697316,228.6702361548934,0.9940812742434725,6.592321670041416 +65,261.4355459288758,202.518302086519,4.641943406474736,13.108375146006386 +66,261.77358521125467,208.71156784518865,4.228802506962239,2.433228596876354 +67,262.2239840728469,206.93200819390404,3.913133965048002,3.8722633351342384 +73,271.56840159049864,202.43979307690176,6.020267230118504,9.252928727047907 +74,271.7499513480728,203.11926113487155,6.298067280843489,9.460113190107432 +75,271.44195864454383,203.13378150076727,6.235685371158418,8.78878791063504 +77,350.3678386604973,205.31362830989096,5.486198418330991,5.167398353061708 +78,350.84767505700546,204.7348154139331,5.884173027734943,3.1267473645330095 +79,350.3672092162146,202.65537701706708,8.070802178703657,2.602867171044783 +80,311.14553424067776,202.4869088895573,6.8627096705514905,3.849897420660647 +81,308.52906773639614,197.89051485190024,6.52057770401923,6.5753546391985545 +82,310.7458930121221,195.62555942687163,5.367642235757289,7.169712735992463 +83,310.4462741092919,196.04905416426502,5.898927104709222,7.285208599925228 +84,132.59882836689548,252.18106881985727,9.792699149145234,6.074176114983168 +85,130.27271083469327,255.0125898993776,6.541689138699417,7.5432442383212415 +86,128.24730309169942,258.24673630933165,4.738368491228839,8.535578411913749 +87,130.45275524711,255.95852341410014,7.110134503566371,8.006575003774147 +88,170.36255985278285,256.37507510380607,5.690121369029169,6.698852732879058 +89,172.0725262476556,250.99873611079994,6.021708452291268,4.7312867200629105 +90,172.12065301401947,251.62393859671212,6.229499399540459,5.814534676493482 +91,176.161018968339,256.37597941761925,9.979846996542312,5.435649021007985 +92,212.93760785065032,253.73852022713282,4.877015070829818,4.420381137303506 +93,212.87022485654242,254.1472663576613,6.024553307028744,4.36937145736752 +94,212.6901735716537,254.11072679512063,6.253967049885242,4.460238419613106 +95,214.72029157599158,253.32794140075904,10.942416527294561,4.6292928147759165 +96,255.87095795884755,251.70990738025452,6.095777014998389,3.032297848733597 +97,255.65851168088042,252.1188764922263,6.119873150459129,4.2912655878809405 +98,256.06917412538536,251.38312888217393,6.172049945445992,3.0818160436840696 +99,256.4256676707784,252.06892690237498,6.2866487953086825,3.3887198764991386 +100,297.8256649973607,253.8462555802079,5.924725404966239,4.397206605295746 +101,297.5756213294392,253.9391774660706,5.944381655046086,4.005013371810662 +102,297.502368857641,253.7073727620472,5.860286142652836,4.041363460966722 +103,297.7274471303382,253.7310964744231,6.239643764909305,4.305568077335959 +104,336.6561093798173,251.17938258703765,5.584269888775618,4.812738974889911 +105,338.49750522296745,252.07705913627754,5.543320366201012,5.442573748366097 +107,338.0150937851073,252.18608250396494,6.036908819248115,5.0311597932446395 +108,337.2951518337468,250.18224258519146,5.881938681047152,6.491905854296189 +113,272.4491338841411,308.8369345911772,3.9306201818330053,5.901638358317446 +114,274.3616111627661,308.84705520975774,4.644046045611964,5.516775342288276 +115,276.16521348060496,307.7328192973856,5.477181608323385,4.274725827291863 +116,275.7219694287137,310.13716548933456,5.248785953237486,4.9634566528627255 +117,318.9497922417631,311.557654756341,4.404954111761173,5.820314553091814 +118,319.1412036522322,309.2162698967087,4.478984811722864,8.01149636027687 +119,319.0529158028501,311.2794691857636,4.084462770697858,5.557665052342318 +120,319.10116577059574,309.1842470522271,4.386098755065277,8.133763836800041 +121,361.7830962316519,312.9030603457879,4.571180054194281,4.907320783558812 +122,363.0043086937134,311.7292896961028,2.8960472677148883,5.951933529573732 +123,363.19625593743865,311.0733660860651,2.9383205358529714,6.1061913146876945 +124,359.63316117679994,311.552139939443,2.821256013884825,5.5763574754572796 +125,442.75956343881825,316.115466064729,4.778336574085548,5.530606828021713 +126,439.5856299442215,315.1505995864219,2.585590965608122,5.747036062574868 +127,440.69585939100426,315.0579828759502,2.7149707354695605,5.752920657180591 +128,442.14857834779656,315.935012126325,3.816863855176525,5.744951427518666 +129,480.0220424915058,318.0508150479775,2.545818620191014,3.655165569690837 +130,480.2961674860558,317.54390725750557,2.605035779868517,3.5415144855244005 +131,480.2157699796402,316.6071568907418,2.6092555233226427,3.3584986805507486 +132,483.0300110911751,315.06269628406767,2.7300211118973263,3.898312260468843 +133,87.11667489567593,294.14241735058243,7.598743409857649,5.19998245236602 +134,57.81287299171998,292.38407844216607,2.514015918277811,5.136006470534924 +135,56.72481683615359,300.0118009139173,2.857620857781098,4.750166949488199 +136,47.21055945404092,294.95922659039326,2.6917302124926694,5.369878030902169 +137,82.9740487845219,293.3928921084636,2.4848999003333803,3.9293747558559278 +138,161.9550663905005,295.0453226209086,2.7841652419514227,4.6158307977098305 +139,360.9021185534379,293.4515559554225,3.014363497918401,4.4291415710214785 +140,89.27996833990208,295.47084639542686,2.65494720185284,4.648541410028614 +141,116.08881622892042,295.90714432478194,1.9069874131620126,4.150080850969694 +142,132.15536640954062,297.2171229012815,2.706901698676143,2.9568780838711826 +143,127.63875390271042,301.4424845378769,2.769134247080161,5.578151587102764 +144,130.87079961636513,297.89834733182647,2.818953624476529,3.8997116282895603 +145,150.31209355255865,296.8214130757569,2.725175079922067,4.209022465413865 +146,148.97786084884208,296.6038327691481,2.7067927491075574,4.17492062013239 +147,150.24661339572495,296.7796929595484,2.810800536874064,4.312780918203187 +148,152.60600094096128,297.232015083595,2.8754159917495565,4.377707355346677 +149,210.67045705478267,296.141990804855,3.265568007984475,4.047456332372859 +150,197.09292075504828,296.3228305878953,3.180756798374725,4.46039907916231 +151,119.65069386862973,297.0907409886854,3.355490697464104,4.394699915307226 +152,227.24737645933865,295.9919464826721,3.29596076395495,4.365046047151038 +153,185.29407593743096,328.9756512787473,2.4739170556894745,3.6908535828009685 +154,187.84229703035945,328.67458417656786,3.441179047809909,3.032614629941614 +155,186.58809302809905,328.98652600447394,2.9369976692797604,3.5987191187020073 +156,186.9163443606333,328.6316285416275,2.8964425091038914,3.4524747234516604 +157,229.29082047745888,328.15179687646463,2.4437228704779783,3.75376327066602 +158,229.7362726809719,328.8007493567453,1.7377499391208846,3.510569661296656 +159,208.26809226199518,328.86828867681027,1.5607659119719737,3.1037014684154176 +160,229.09214710427673,328.6178358476461,2.260028006988348,3.6920398661292713 +161,272.30550005795965,329.31313118492073,2.228336338998844,3.1347450587831363 +162,744.7928105338103,324.23769166614653,2.1073598387590406,2.539759184702161 +163,271.92463381929605,329.4914525203367,2.354794935998881,3.3821523721928775 +164,272.0763070212753,329.43329625041076,2.2564082813073223,2.976824453200896 +165,312.5002968548282,330.6396470335998,2.4980562783012132,3.342049851550277 +166,312.6633003087961,330.708018763403,2.485750243447884,3.1257959767437193 +167,312.43290491220614,330.60640551938684,2.5861522827731918,3.1384938126252546 +168,312.53461746652715,330.59614144293295,2.6327977881534315,3.2738519720709336 +169,395.4235565349371,332.05857012716825,3.042284807396061,2.6618134827186033 +170,395.89575300552235,331.2204950674755,3.5075609281016074,3.432678442805089 +171,395.42995858598874,332.11325844782596,3.0389919063576745,2.634943595710816 +172,395.74810123344724,332.1696223944591,3.3020110174888058,2.910921037939185 +173,172.38094968570545,152.05413649604458,3.009792250294108,3.523757740020178 +174,173.8277034486298,151.97246989575592,2.927263574496173,3.3547430273206764 +175,173.7469031569836,152.01702715147732,2.992197181370308,3.5878204759260535 +176,173.87444349441117,151.90034527705913,3.001730291594699,3.3191803731856986 +177,220.05954791045562,153.93486125597713,2.916964654294944,5.161796303421409 +178,219.06032109265325,153.8679197592309,3.02283014757281,5.214692401346838 +179,220.20248145797134,153.83037812747935,2.811916018641933,5.135768243874929 +180,219.8662882177588,153.69386761094438,2.8932331677602288,5.195182563087241 +181,258.7941680380869,156.20170959987001,4.509844805839375,4.210885005617385 +182,260.70623290807583,155.5691133699838,3.9964474629559583,4.494356603934025 +183,258.66062861832245,156.13098164693182,4.524480095522743,4.217380456749666 +184,258.7614643354862,156.22967958243044,4.5086857868814425,4.199456605512427 +185,303.22935297897106,154.43469284754158,2.9235122344572497,5.0253634772759375 +186,301.737374625956,154.2611896143699,3.0779278021862946,6.153602357601281 +187,302.23615729321835,154.26453424384667,2.993547760611472,6.256352853265299 +188,303.7378760514983,154.33358903047713,3.094665979648467,5.269632450902677 +189,385.4931704373973,156.2752179977739,3.473675270188691,3.9607689131121706 +190,385.00254984000435,155.26821198570494,3.5586590950004457,5.391583365108707 +191,384.0813093792461,157.57737240690167,4.44594499401667,2.8998689471390326 +192,385.1801338588461,154.8206336674526,3.6798775544177063,5.162336041483175 +2 +59,91.30284200670633,218.07642242545626,1.1539219073226616,4.534512576080954 +60,94.47064527098745,219.916516135159,1.2005691862986814,6.846135813191627 +61,94.15679646295986,220.04095088976442,1.4155925768586246,6.838018547816678 +62,177.10956003057285,218.90103728250688,1.3905251660790856,2.7497320728371646 +63,177.74456263111466,220.06649622720403,1.2185587916549738,4.188825256215504 +64,177.49917127590462,225.5014059314746,1.662625480516144,6.3447162872422735 +65,260.83235784169676,206.768453469812,6.640373185442694,16.669713322142147 +66,264.61912522766306,211.23389035030604,6.418829493449439,6.7515824557814765 +67,264.56313646993567,208.898424261183,7.577757476106213,5.397905740603194 +73,275.0807583567399,203.46314981555653,7.529121753107468,7.79068598394073 +74,273.3391581028213,206.03543897900892,10.405037115613153,8.539004741937488 +75,273.12815716759474,205.75279846700272,10.383171899212439,10.3236022000293 +77,352.39736693776445,203.25064337648874,8.32458599948799,5.647682458487953 +78,352.6804091269042,201.66565569114204,8.497380645406677,6.217216240364239 +79,351.5731625392584,202.19179726341497,8.658775240139533,7.111128909229292 +80,310.6751701124307,204.64495746423012,8.062037456416205,7.444446872078048 +81,309.6670401069309,201.55447995655948,9.465643221743878,6.881819412692541 +82,310.6335818256993,200.22299800671655,8.67387089777447,4.664159850458751 +83,310.9019318418565,200.02015346830518,8.510118775528804,3.8829013885017067 +84,131.06337257497074,251.28475092908215,5.159471427859664,7.099566355433584 +85,129.09144907108433,251.7203734728845,5.198191014751725,5.290792123590904 +86,128.14221980812886,254.23635236985004,5.978168978981718,6.3363646857946305 +87,128.5504980446596,252.95544188750205,5.339963887657365,5.754904964464613 +88,173.96747545182777,257.59357552003803,6.482400441297941,5.234590780368996 +89,172.64797467848848,251.12847549296245,7.275410666068803,3.2555916560823848 +90,172.60455067578906,251.16298927626656,7.222779487902638,3.496102713076582 +91,178.63195743713817,256.00196219903546,8.724215688749194,4.5367531498363824 +92,213.30204486943944,254.65697701565333,7.662137596538662,4.165845349061372 +93,212.8172314127949,253.39712914171187,6.857530904039771,3.977160865721656 +94,211.8792430432469,255.82761299122967,7.222038595318558,3.1694534357454573 +95,213.7978436356281,256.0278412645292,15.452080822376551,2.4945072295635016 +96,256.93972703527453,254.22973688137205,7.44290569053337,3.428653114933794 +97,257.1457284865542,253.4535805850962,7.332108489145229,2.4944378698026863 +98,257.00282187401416,254.12419273967237,7.2764048131626184,3.3193016977855763 +99,257.04994365436653,253.94432494945963,7.423089718980076,2.973336749681888 +100,297.56026404755863,254.32212106774926,6.852565823032563,2.8493609623085123 +101,298.63371928814155,254.61437178101048,7.905691877078718,2.165690092942747 +102,297.69407107379396,254.4850393852944,6.836012542442264,1.946205259389151 +103,297.9023244730469,254.38868473138925,6.751896664205788,3.3116178759031087 +104,338.0053276434522,251.83336967087538,7.799885374056114,4.945594824336877 +105,339.1582769256123,251.94932873663424,6.500886426061445,6.047632898215193 +107,338.3102566581982,250.25272692617727,6.48687937625559,4.657479797529445 +108,337.9547753028731,250.03478792262877,7.680658310818983,5.287653170857336 +113,275.910952296904,305.86738853882827,5.34030651381748,5.289299280058491 +114,277.42120270272227,311.21743667247097,6.194812315610025,7.468012633884288 +115,278.93960224322814,309.638371888345,4.951788309478035,5.6357014265428536 +116,279.87420391551683,310.72506489150953,4.822827709017515,4.736286987210306 +117,319.79423896861897,311.2133693181722,5.668930716768623,6.682907491520234 +118,320.5540626961792,310.68709367641236,6.419719926410251,8.237770206306163 +119,319.33379454853355,310.70701535995903,6.465185367234193,7.897980684891891 +120,320.2722313120129,310.1782745929597,6.268219945694488,8.023329923606077 +121,367.6098676953658,314.58028508890305,9.39615711787979,5.649531231448145 +122,363.74508504031036,313.48439864622117,6.684116998496468,6.329996512810745 +123,363.29642172711425,312.67626164324315,6.400837328497925,6.909673033958756 +124,365.0277447799763,311.6147364893551,6.720810503358312,6.645516125018006 +125,446.2253017919773,314.99416404393594,6.395392871846412,3.382574041643381 +126,441.1237388588513,316.35150200412727,2.5546429518376508,6.635379091123845 +127,442.10117921669377,316.7934137028694,3.617061357493329,6.796381592950393 +128,446.6969923351063,318.5296550554647,5.9848567355794176,4.343944361749059 +129,479.94558754651956,318.22536134864447,2.220264608006834,3.836710322440239 +130,481.2539099375137,312.640306388908,2.593318771161441,6.6486224400214775 +131,479.45347062880376,318.2469542979415,2.0004364038172557,3.688680674174361 +132,484.13323268726947,316.73499335627196,2.002291195085977,3.781086788196597 +133,85.29652368782442,299.9267050080891,7.827458514431236,3.9374236627298966 +134,59.67355911737736,298.3611375665026,2.293779231438959,7.12389408216543 +135,54.93006667794998,299.54260321894077,2.4753999616786904,3.512718857180827 +136,52.88374765283322,297.62420743734526,2.052251163735395,3.0356052182771274 +137,100.22096248097169,296.1954497008577,4.3012641162676175,5.212420406396804 +138,77.57773257938949,300.1917036834339,2.6075704778239923,4.343174316530481 +139,114.23749297790368,298.69307716260715,2.9175645781194874,4.154406732926865 +140,45.03330152423734,300.5503452125839,2.625583107839479,4.294099847159548 +141,119.51809674004014,300.04111347523275,3.4424531063915236,3.6098269870345647 +142,118.45488030550041,293.42435614635554,4.076098186731008,5.934920124944857 +143,110.877037200568,302.13823496880946,4.847942451776839,5.374114325813509 +144,116.6620641371857,298.368278265185,4.685262545376076,2.953550317426917 +145,142.45731006430879,295.1000575604827,5.189856548842566,3.111987985605453 +146,143.20014617587012,294.78019680871137,6.0198625121087534,3.3010521003465834 +147,142.56298735658783,295.1170233357802,5.20261559459805,3.442242559647229 +148,139.89055528539328,295.48129747000496,4.278137116722635,3.3562006136085 +149,182.28248910013076,298.8925711419297,3.882958147572496,4.932530677517502 +150,181.93047252438868,298.64825753275414,4.0369897133739485,4.744932625303357 +151,181.98693496359542,298.1631625286757,3.8155850034361163,4.774725772494465 +152,182.3110519597161,298.0855672750618,3.9895325459128514,4.794576201460771 +153,259.4920457606562,329.2756913744665,2.454071420423271,3.5104389207411675 +154,191.55276246651394,330.10335406699386,2.7535159658488753,3.735374001963311 +155,194.48534159817734,329.9443292127414,2.1365830195361943,3.127947562092398 +156,193.39092086391267,330.38614167206975,2.1963679483715697,3.459040917080195 +157,236.17750038130092,329.0436536647159,3.1786720809581777,3.1430140286789383 +158,30.916842755515052,331.29060642770753,4.841452724981102,3.7495713033876124 +159,247.27788073241743,329.51692678380493,3.088707102960316,3.923308113475421 +160,250.22189392231115,329.26270263655886,4.2316219686433225,2.8273483917495277 +161,276.3128460929227,330.511230724005,3.4419490584726287,3.1926367377041047 +162,285.59180034302733,329.7481991930167,1.8378511022559236,2.962363935958349 +163,276.2745382801029,330.0900901745128,2.1081569415614108,2.3238295865477 +164,287.0159796232469,331.2727625321787,2.716127438341672,2.4485626997745595 +165,317.7395849994937,330.4138825095169,3.3757057306286984,2.8095989664256256 +166,314.6572377648183,330.5793633642782,3.194427388751986,3.0041332311662914 +167,317.00117777059165,330.6383247898892,3.201153763642872,3.0057526788151607 +168,319.284335249175,330.4196934261666,3.436552449874256,2.8793534460468897 +169,398.9491001935992,332.1016164460315,4.590701775382649,2.4853527290993047 +170,397.4873909051454,331.4430567330248,2.0553328419425942,5.097090036367185 +171,399.09113630168383,332.21159139918905,4.665806570428414,2.438404994920128 +172,397.7907669635104,332.21375146950754,4.160036511822063,2.302533773606481 +173,167.6549194927225,154.8195960714067,3.578104764139934,4.293948219715187 +174,172.8857977008767,154.73930238156944,4.065505613610561,4.397450234808648 +175,172.58520462200156,154.29013402780822,4.048705697811711,4.112000867673462 +176,172.5358949970105,154.45532035873933,4.181462595099683,4.211635985550709 +177,191.54370072344057,157.73353022270507,4.841190533624689,4.763972692389171 +178,204.05445279340313,157.37702899559486,4.494318996136587,4.337287440506104 +179,191.65543785128887,157.74655585598282,4.883158661002671,4.919623053094591 +180,189.28378158246906,157.63000871303564,3.5274346584972274,4.408356106260135 +181,260.37023207173655,157.73328509764173,4.261494343445461,4.8366413757834135 +182,256.12032377018954,156.0742352828994,4.281428257218825,5.030259376007136 +183,260.3960744140202,156.38669157075003,4.242232860054043,4.583829032686845 +184,260.6791000228129,157.9519422581545,4.2747999006513835,3.800985332770269 +185,302.4998205898764,155.53480279841136,4.116529613451282,3.3417704291330135 +186,294.8930629353272,157.4031130939023,3.9041732736595818,6.391527497892834 +187,297.53924094539656,157.38305310411857,4.3287195790389985,6.365038877320703 +188,294.8108560332771,156.29685130271133,4.759679064189887,2.700855536462382 +189,379.62100651919303,157.52580336807762,4.648970244832296,4.614333688454686 +190,385.0749564946942,156.23453384699377,4.097215876576247,3.788089778011118 +191,384.1197434977094,156.68532544972354,4.287357345412347,3.2806588007554622 +192,379.3432570533363,156.93410438422325,4.592318070059131,4.5896206349551 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std2_p20.csv b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std2_p20.csv new file mode 100644 index 0000000..2961aa4 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std2_p20.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392,0.9677151865944192,4.009449743264753 +60,95.68692886974831,217.86446645631813,0.7424975144337135,5.151973582834018 +61,95.27930768267886,218.4321212539979,0.7270480243366128,5.212134543408362 +62,179.68821344888678,221.21713400884485,1.1147842657503555,2.1332525060692515 +63,180.64677254143638,221.7765304937586,0.83092419657981,2.5740660863437568 +64,179.86073442223173,223.68541859670074,1.1381174020649096,3.626058878513354 +65,267.0750705461852,204.74717443096984,2.241840204786577,13.182457200661304 +66,267.19879488924516,209.60901887734772,2.3697667509990565,5.035545962902496 +67,266.1798697712201,208.51040145394091,3.540061676733699,4.595558869507625 +73,274.3400431870006,204.75610310411912,6.491531432619202,7.31888797087335 +74,273.44321864391185,205.81069417739437,8.261574847627143,7.257546441830887 +75,273.15099171429256,205.61817173382607,8.395328002698498,7.565385107130859 +77,353.2630018061804,204.6061088758629,5.493098240735283,4.29566322817894 +78,353.8852531441488,203.30592180203516,6.087365194189325,3.3836943891959814 +79,352.21840596322596,204.15679894425952,6.557195072515586,3.1954900594475086 +80,312.34313113441607,204.52530436142615,5.588158051911466,5.745243989851365 +81,313.1160349693985,201.4084182788836,6.025875449926955,3.654284157032464 +82,312.11840038067925,201.00669797880116,7.0864910249072635,4.406813194332426 +83,312.29317276741347,200.45780062295867,7.089188755441932,3.1660046223221405 +84,132.42237239805132,254.29214663519284,4.3067464843901515,6.417058493680035 +85,131.29521858798734,255.4865958538821,4.908850345384105,6.3671100735668835 +86,135.9988356956537,254.77748611685175,8.584433337345413,4.9941716761414146 +87,130.98094102950247,254.42187606024922,5.117211446405824,5.370134929913309 +88,174.56636927613675,254.4831815599854,4.7275771979909464,3.1678947409316813 +89,173.67935580024877,254.09783447631526,6.437695363099053,3.474606588647915 +90,173.36920502447623,252.290452181076,6.593885801251147,2.7873975371893436 +91,175.2895186608897,257.2751667704358,4.729209363054509,4.452820054846227 +92,215.07500705655937,253.80949363235624,6.334123387607411,1.9488808007329534 +93,216.94462220467622,255.47756358425315,8.080773269328214,2.7211585139427834 +94,217.3834915918711,256.4745644877478,8.267318853585852,2.211181525286066 +95,219.6648004345676,255.57239348461326,9.86068974730619,1.4652046608845635 +96,257.50957542067664,254.1259284055811,6.675780060232609,2.704136241957288 +97,257.570545197815,253.88751117668164,6.647657278502652,2.9140751377307628 +98,257.6089813372307,253.78662089019835,6.605179609252467,2.6809454420956143 +99,257.6936671647974,254.2498517060511,6.576722939133856,2.7069332019005827 +100,298.2952436151055,254.76909617478606,6.705809824561147,2.981349985017069 +101,298.1169393001307,255.21794911950758,6.624534032640799,2.181605220236403 +102,298.3189654536773,255.25096983760508,6.750900350115645,2.3083727544087247 +103,298.4415890038736,254.35763625124292,6.663590033871669,3.2667839890941295 +104,337.66969489877954,251.71635156144524,6.210728685673001,3.377413692122266 +105,338.1116560201459,251.7179090471175,6.338074391942699,3.587185716331372 +107,337.93979130669914,251.84264636476274,6.288961573364599,3.0282904644933937 +108,338.18833275957206,250.67508565210196,6.186589358792703,4.10107941402743 +113,274.2817559120019,308.9374117445766,3.892956777078502,4.794749659977309 +114,275.7421347767481,310.2555996702759,4.535765938235691,4.66622650744931 +115,276.0461325201841,310.02072804280994,4.545655403672037,2.2262514157125017 +116,276.2417374542582,310.24048782871637,4.6497847767530995,2.8951312130050146 +117,319.6559290654899,310.99105624588617,4.410519998245082,3.0198480458627897 +118,319.6313092726346,312.1826263203713,4.334709687203355,3.9909339754311914 +119,319.46776160473627,311.841371820779,4.471689460416843,3.8980513701355664 +120,319.76654338764155,311.98447027104925,4.4491853585047645,3.9716440216868176 +121,360.82585188540037,313.3258908241004,4.744138263484551,3.1950268933478396 +122,360.64739266264627,312.8307783296112,4.673876604017344,4.0505350195787555 +123,360.689270210389,312.2626467099784,4.717842951294665,4.331175918113057 +124,360.8335382258014,312.5428875466125,4.7257637014968825,4.238743771700391 +125,442.1542117060401,317.1277309025985,5.1708505304868275,2.8339991015485375 +126,441.42140737582423,315.78584607818385,2.592454459875001,4.6687701093869 +127,441.5300773440553,315.90717126090226,2.8050705738429227,4.687041451309435 +128,441.95769286933466,316.8407357397122,4.805859396667629,3.6325916039286454 +129,481.35090878368925,317.4272946632326,3.3586867882998677,3.2305216999009705 +130,481.4725819590857,316.6159681822135,3.546147101969164,3.2838056303462357 +131,481.1535576706723,316.8819465108059,3.263691605498864,3.2346725461032757 +132,482.21933609621834,316.90676933858305,3.3334111968000197,2.8211028940841043 +133,59.55768321914789,300.29871844382603,3.8761928423107794,3.6951665481304303 +134,61.376816545951996,298.3523691730104,2.113993300917673,3.899220174332725 +135,60.60960139542109,300.5877018018443,3.3916290934001863,3.597118842410694 +136,59.19985355062283,300.1851062687214,3.520034988226608,3.5453648546285197 +137,102.6280068014727,297.40383468175656,2.749638491064498,3.880988203100239 +138,102.40955557323258,298.7865911290351,2.7573372442370903,4.089700063188653 +139,100.57013333623348,296.8202762296189,2.9651756626973564,3.163333481381463 +140,102.67850653460079,298.5730025774653,2.656076828883503,4.008870765124035 +141,120.23221696171454,300.1898879495705,2.3495738375350714,3.7101386992401784 +142,118.10535832779757,301.85912326532906,2.662771758344228,4.434372354516663 +143,118.16700474619614,302.0417496311767,2.810926040633238,4.442752618047973 +144,118.19187121087131,302.5378510894045,2.8502302470584953,4.428574269320613 +145,143.380762851227,297.65106023170455,2.9029598644975594,2.9494319243206975 +146,142.46748228973178,297.3647432540817,3.516542953167025,2.7867411900804395 +147,143.2239805848247,297.5672414624104,2.925450223126345,2.8821527557517435 +148,140.51718892104998,297.9845023911149,3.134479693224828,3.0837592352072623 +149,182.6593569656309,298.1418468359333,2.648390300198232,3.275571713707499 +150,182.64828488417706,297.92582445480707,2.7260433370787203,3.287985243918374 +151,182.92797391602642,297.87455852433123,2.5754349127258473,3.303821768124996 +152,183.0029286817877,297.8637465373881,2.6850779296217095,3.268506780902108 +153,186.1728851830908,329.8083307385874,1.6988565395865438,3.2857803265960546 +154,186.5492243440529,329.1491955430002,1.9159248202789043,3.190026296337793 +155,186.0292302003802,329.23752125561214,1.630100824234192,3.143397778827556 +156,186.05706501583137,329.3191466220413,1.6185913035274193,3.18627620460259 +157,233.36795685970054,328.463961880729,2.643309826783174,1.9867341998292147 +158,232.82586842848798,327.60883484043825,2.477588134745834,2.5854098103097747 +159,229.71350413783279,328.3780985513343,1.4377331090494412,3.4686128953627313 +160,232.72525153041173,327.7700361791668,2.4530240891852237,2.5077492129850194 +161,273.76316751955034,329.73823826493043,2.394688280474286,1.806427127995776 +162,275.7575781134558,329.9125721193857,1.3584269354839966,2.5506427041479443 +163,273.60940070127293,330.0025820738042,2.4087695062685763,2.2557767070416954 +164,273.7244999819209,330.09757535831045,2.4201727937672897,1.7894497412511505 +165,313.3973669095876,330.59163642669836,2.5664663718925884,2.5175272820859127 +166,313.23094160288184,330.71155384663837,2.556749103943359,2.517895305394224 +167,313.2083786255443,330.77428522126553,2.440925958919023,2.523508078782979 +168,313.36106959216625,330.6523370232485,2.5105680868176643,2.5022918306323914 +169,396.3640143494862,332.05477157898144,2.544597691516881,2.2242293500191375 +170,395.617460222669,331.85554030819173,3.094183882820774,2.2794261534246627 +171,396.3911361968549,332.1303447002533,2.5527965384171347,2.1830363581679078 +172,395.89256887798285,332.16822339411516,3.601013097767017,2.1716024486759946 +173,176.02029170516317,153.71245910000232,2.3779159513262353,3.409134278667166 +174,176.10545306203875,155.20318481126037,2.4825478178566596,4.418906030455666 +175,176.03197440143745,154.95241321278883,2.42399408636437,4.430327097224612 +176,175.6846804297304,154.63359606135103,2.5997462043064927,4.219400830122209 +177,219.46327960613064,157.23609785750858,2.529672116014354,5.058864568041901 +178,221.0564853241154,157.3435472260885,2.2463229070198545,5.480115541197549 +179,219.62129396536662,157.2666553285107,2.5021134486595593,5.352065132338259 +180,219.69587995502016,157.1490063640601,2.516169881431476,5.470652636210902 +181,263.23636033723557,157.46707082247306,2.6921936322678013,4.204926201545835 +182,261.3833848255912,157.14497162705263,3.132796451668047,4.135023908563071 +183,263.2875985178052,157.05504332147794,2.6601053814719973,4.186611997777448 +184,263.16270089611913,157.68858593709763,2.7082086799182084,3.4205893941412424 +185,304.0771964580808,156.36708101762838,2.6882263261194885,3.319861960122729 +186,303.2325028543831,156.57995759281437,2.7961523629805916,5.391517197327435 +187,303.42630311491723,156.4924674158584,2.783092188384192,5.365203962414015 +188,304.6158660912609,156.4818813819881,2.506720194343099,3.179833381166062 +189,385.45560134261797,158.37035395252553,3.5085984360932585,2.735043850552565 +190,385.8286612719259,156.9884186905783,3.520976122354819,3.199129896839037 +191,386.1864174896063,157.19189241238993,3.2937940620339354,3.0663737335825165 +192,385.6347971660166,158.1411858434322,3.4609224939824603,2.846649085773437 +1 +59,93.1287423931208,218.29700908810787,0.586116217920642,4.982728971287442 +60,94.70512938803542,212.6540109552706,0.7530580888942188,5.342989457535182 +61,90.1361278577332,213.33121631876608,0.7741246171980174,5.183322455003788 +62,163.05397573990066,223.03302231371174,8.768671109743122,3.608965585949599 +63,178.56039861950646,222.19098474984543,0.900267664385944,2.917664454486164 +64,178.37920648184422,223.51557294327878,1.0988445958401813,3.973656567077689 +65,255.80438353417117,203.04815455047097,6.766813492476352,13.29699627358335 +66,262.478672605179,208.85138164100843,3.5774987545822987,3.7830932795933596 +67,263.60616955216886,207.2183121488101,3.5771988890480593,4.252166210585195 +73,272.29022155441146,203.26015396542505,7.667403148427107,8.484726496612334 +74,271.46793735704193,204.00075736023095,7.006836949843662,8.57906517149974 +75,271.0412882240347,203.67673019265595,6.9166949430129225,8.702335904677817 +77,350.53069989533947,205.1215453780687,6.3913113962364445,4.675912501749536 +78,351.5335450988067,203.6132402057685,6.914935781146339,3.647320534476688 +79,350.54080463471854,202.80860415043412,7.576153280744988,2.405442522969295 +80,310.84312359894454,203.07084060099984,7.338460358520777,5.637962269519666 +81,309.4303871248667,198.8260778916456,7.8402558918165015,5.732595151892859 +82,312.8487475083582,197.88498609405823,5.545843437300968,5.5454679231566235 +83,312.4494378330193,198.02482356912975,6.100953297862154,5.205602033075617 +84,129.73316120742015,252.31402870350382,5.182904459352007,5.7859701617993196 +85,130.09936826716955,255.07600217340146,5.535923397107699,7.036159941672144 +86,136.48684968097632,256.98593054341063,10.027649034484337,7.342825955920834 +87,129.96018632025633,253.63904238622214,5.660756401038712,5.8266843261131385 +88,180.12754728190527,256.91804818977533,10.57223062780983,6.228147264882277 +89,173.42291095269067,255.58833819764322,6.700532645820975,6.247923198559783 +90,173.0543226504001,252.5748838461415,6.760737603124655,5.231000998435721 +91,174.29585433427428,254.46270745029543,5.389533179624763,2.8578511182829476 +92,216.78511969207446,254.5914187233686,8.95047307481889,4.249360054724529 +93,215.97344562124545,254.7054640425066,8.196439917611718,4.011111129846635 +94,219.24024367384476,255.41662872012847,10.121690584983755,3.367632134220822 +95,213.81498670140752,252.60321047848737,6.581085797491111,2.395105254724356 +96,257.3830982530756,252.6691612485834,6.880768996147865,2.9353265504494703 +97,256.07878148245777,252.5850508469038,7.193370431289156,3.536434124406424 +98,256.6563709830754,252.14302077100646,7.020255474285572,2.742516414019443 +99,257.10274737541874,252.44669038983187,6.759367673913806,2.5065554147623534 +100,297.3527413648711,254.3197859755712,6.974691942771777,4.204342914024384 +101,297.36935919598676,254.31625883281748,7.003782434070834,3.8132099844257588 +102,297.45043676182286,253.29006124829388,7.147301062318091,3.0312100621116413 +103,297.15639353267426,254.26565823155238,7.3776805534006185,3.914660604118064 +104,337.0838455883894,250.64743017278894,5.921815081770851,4.024140676300613 +105,338.2943046084806,250.9606925384406,5.481575455905726,4.1053232838414155 +107,338.46927119138405,251.82861699933284,6.654167871317137,4.251478363049102 +108,337.6321115297869,249.87042147419172,6.005664399486008,5.04451473974955 +113,273.20050531167254,309.1760573916311,3.4219821116654865,4.957144824013617 +114,275.593658985165,308.5727448984995,4.702522493967433,4.008413607725532 +115,276.45985797306344,307.75120186662025,5.767076285351399,2.479883936569082 +116,276.6589541465393,307.7328403118153,6.184525915073467,3.409658651068851 +117,323.8680795155452,311.25555593462394,5.6467354698699,4.163445875643856 +118,323.990822160368,310.23497244583933,6.354306297639026,3.605863723170547 +119,324.4759468599942,310.5137190042532,5.951639025695133,3.8742178925550625 +120,325.7385894442358,310.39579583995135,7.723927817628718,3.904269142941334 +121,361.82046220765505,312.6906221126212,4.3915079798209895,3.595391320936084 +122,360.25109899783934,312.73975566628565,3.3364555278083112,2.7719078470887877 +123,361.13964194906663,312.4482596768938,4.009973777907947,3.338550731387954 +124,360.8021695665512,312.55731463103996,5.178975914859417,3.147724551644225 +125,443.60378722604213,316.81523544669056,5.441494217460369,5.859512902880808 +126,462.74164751366203,314.6397925160877,3.1723106571758315,4.673495905701873 +127,284.4684422338389,315.96181914108945,3.781047749264403,4.799446710082581 +128,451.0537747662026,315.05034330850094,4.165022446102917,5.582872998184059 +129,486.2262311408019,318.917422588962,4.360015955842124,4.24279052637777 +130,484.203371665194,317.155262043757,4.666439360195373,3.538660983437178 +131,493.1775485408943,316.3518621311899,4.495507964960477,4.044073143583547 +132,483.79815450187516,313.87456269013853,5.0513219188547716,3.976286497193232 +133,58.415796919717515,296.3367806354237,2.745318197812863,5.347714894650585 +134,59.66992690532717,295.46552315023496,3.0521020998678443,5.04724168228645 +135,58.30852857429605,301.14443002474417,3.0314355414314353,4.891148165556274 +136,57.19875149216512,296.2038703275876,3.0187024946676813,5.430283114579736 +137,101.88869112962361,295.36699152796956,3.0605704820563435,3.976231975252619 +138,97.74223572831934,296.64159635228486,2.388879471730324,4.818867004598817 +139,95.13971714462463,297.63279866894925,2.5874115321204054,5.108323412261206 +140,100.97448449522825,296.37143206657936,2.23273639508488,4.835560641819327 +141,119.6488680328135,295.99857882673734,2.945034185014498,4.051944183392203 +142,116.04630564586442,300.9428981940468,3.646493643610884,4.201903655805421 +143,115.93833802312685,301.4015147621542,2.7752574824028806,4.899750014060764 +144,117.66427038686425,301.67621994166734,3.2562262537824718,4.934112992862415 +145,143.61862339021508,296.87569921241607,2.9793460068872264,4.493879539069787 +146,143.84226240395634,296.5995702000957,2.6657882037152505,4.487866588043545 +147,143.41726284468888,296.4604242772443,2.892883624851368,4.50539522391336 +148,139.90710854861246,297.05847391439454,3.4669655178811123,4.588153704670423 +149,177.97012292111646,297.29360417935067,2.9817918310917375,3.750304964672955 +150,179.09943783225685,297.22176671479934,3.0286986838896457,3.881572977421466 +151,178.4595029850307,297.07969710485736,2.9749987384442655,3.775627144339658 +152,178.9990807254096,297.58186299960556,3.0418692927202193,3.8833402396923353 +153,187.06432524491635,327.5110792134713,1.9103539442817077,3.1747672773580633 +154,187.40611165319353,327.24266469486685,2.028936750132528,3.039992572908433 +155,187.48202253723917,328.1910452260973,2.046736087360523,4.07325152306089 +156,187.4554203440108,326.77537509295496,2.0468424040406785,3.0346527434557236 +157,230.1275716483488,327.66375493177526,1.3064642552426002,4.735119343666496 +158,230.19455285047118,329.6573791501422,1.6872246668899367,3.583570894848579 +159,236.39481488323716,328.4457905246168,2.716174379714519,3.4183380314351863 +160,230.1984260911562,328.23405030487964,1.818805777200218,4.578868396563749 +161,272.1545894887068,329.32912181766994,2.0716370234969204,3.1939556616595848 +162,272.8983988300567,328.70387641284987,2.430197123109527,3.1487498704390036 +163,271.6162444327857,329.4696874435773,2.203277751618005,4.017476086378616 +164,271.6290916788945,328.8920615225914,2.008299706725287,3.3041284732956586 +165,313.03716740034986,330.7975522275865,3.0420523810535003,3.7108953229128367 +166,312.7612082311074,331.01658878813123,2.756286496478564,3.635011569085448 +167,312.555857804164,330.94886104868783,2.895089352246948,3.630322203243039 +168,312.99233681057194,330.7594147506374,2.9514521257261572,3.7325921124368473 +169,395.6599712440442,331.38000769767353,3.6713668117121325,3.4549858187839337 +170,395.7269407162828,332.3551932767835,3.1249445864849728,3.2139419865878307 +171,395.64772093777225,331.19728501985406,3.652929258669073,3.3877347902405988 +172,394.5822232990254,331.28589367585266,3.5115519861174,3.4415616827579543 +173,172.19300877613125,153.8677984100333,2.9936489675181246,4.5406288069622285 +174,174.43739755929997,152.4534316026212,3.1172372976035665,3.3179648689547276 +175,174.29318678572136,152.18270882980445,3.1219958686591287,3.3048067882101986 +176,174.37774565459176,153.9168218422937,3.148891388697558,4.4895441435882795 +177,218.8977614990739,156.58401687998017,2.7063981074883805,5.2876376907111124 +178,218.82234457362887,155.93775870476483,2.6795499708167725,5.033370956683506 +179,218.14869261453913,156.17880976796908,2.747386160206801,5.050217973950996 +180,219.6136087965169,156.013833915525,2.654919821631967,5.093161539439035 +181,260.39420520785944,156.89107932316213,3.256704661733587,4.125191869561575 +182,260.75752017274766,156.5286129544145,3.674975253680245,4.728421517934744 +183,260.0769741828374,156.73605149236164,3.2485067302773727,4.2314614221050855 +184,260.3205919730126,156.89282130924727,3.016527309499428,4.22117756304117 +185,302.8007745851293,155.22452212795463,2.1986861092464727,4.536996509806027 +186,301.70658980492703,155.39202732491273,3.616906361622583,5.809560313914322 +187,301.9655960101498,155.27173302476598,3.5367891506442364,5.787704448891815 +188,307.3464400351471,155.7530563647103,1.0636861640988715,3.4615533986219376 +189,385.16837677047874,156.43907420157797,3.813439832275512,4.1547295279172625 +190,383.77693943350675,155.96991177533516,4.219569642219233,3.833536791723274 +191,384.2249550976313,157.41263864645526,4.594412135572423,2.424078159567562 +192,385.2223566829572,156.31521854739066,3.877568024165435,4.253414111013303 +2 +59,94.17681256320567,218.7493975260511,0.6672950811803234,4.0696236612012 +60,95.60291842116452,220.23420259378253,1.2432894303505535,6.268557799628915 +61,95.02957510532019,220.4523644522619,1.03897231445469,6.283961945108087 +62,177.79543145664374,219.57549575966527,1.1635891534947462,2.4336404189113736 +63,179.18294098400213,220.75147009194285,0.9073027108364632,4.022599904522527 +64,178.6879893390563,223.61664229341952,1.4338252285037825,4.345355288391667 +65,263.02108805781836,206.8238570753259,5.5378567029179875,16.167997116958563 +66,265.3281568315068,210.99878283626376,5.500522890838178,6.34492497544118 +67,264.9755279946045,209.25693017899349,6.61860699217799,5.010726338500632 +73,274.91234547074936,204.52721235111983,7.271387658815161,7.492660955010252 +74,273.0873606007509,206.72185414526035,10.116961928861889,7.92146394391769 +75,272.91870930424335,206.4183338799366,10.032578813526321,9.289382922896465 +77,352.6038013638071,203.61911600747297,7.436756719086957,5.005556173534007 +78,353.00800784867783,202.31796836001985,7.664430224814655,5.213297761872742 +79,351.746134852955,203.05786731461058,8.028743708479537,6.197058831659775 +80,311.08741311854095,205.08798593428077,7.289167841693958,7.075120130726391 +81,310.4676353064527,202.3951467032501,8.630027200417027,6.3233804917837135 +82,311.07935156741206,200.8328753632899,8.282608636183143,5.648212100237218 +83,311.4698975682484,201.29198895046432,8.073700564520845,3.988913299124529 +84,131.85526420446874,252.0193765605421,4.710522724823439,6.327903412535792 +85,130.09901692321196,252.49815518747823,4.810325247545613,4.925112427111756 +86,128.98108803670195,254.22164770572394,5.286838664341266,5.5052487948351745 +87,129.58841891167637,253.33496272524005,5.004724826446331,5.207955764055635 +88,174.3431769252481,257.67973667788516,5.936812237283513,5.016793813986966 +89,173.08617175672723,252.22705318297471,6.9528446346151735,2.9206960921180114 +90,173.16612346262423,251.83252079351362,6.7445812273675925,3.0963895698154125 +91,175.31435856398238,256.47051595889315,5.036171505418926,4.369569543933027 +92,214.0019796882893,255.64524660837301,6.840266287108221,3.3162161792801035 +93,213.6417614987187,254.76260041862824,6.181548205388113,3.4669409389809114 +94,212.59841286272757,256.77538398368796,6.642291270826204,2.865009376798548 +95,214.6340156872122,257.02599392382655,14.761579728638067,2.9573164604380775 +96,257.12202196483105,254.71576094200717,6.982679389033818,2.9625204035270136 +97,257.3916794657995,254.02867969902485,6.8307722895588965,2.3226285735907486 +98,257.2278305685032,254.5619736557002,6.809772888664755,2.8383983340571364 +99,257.16282933783424,254.477050995793,6.931960195707054,2.6611905102158038 +100,297.5612747805052,254.68621271243086,6.616832054817872,2.682409735201763 +101,298.3394946306158,254.9149917819558,7.4103859236839025,2.0032533635948298 +102,297.7037470787607,254.32926027245796,6.697390437340011,2.6035794639192695 +103,297.9018444784966,254.79769770872946,6.481459768864603,2.9116637606731044 +104,337.7041120241776,252.2287315192184,6.785308450450591,4.100479545727181 +105,338.43934115988196,252.2496982308047,6.235731773413765,4.82066583664529 +107,337.8271824583213,250.73973826046893,6.0034125806830785,3.931922093279878 +108,337.86197274862946,250.42655028770324,6.756971947757317,4.556599933768003 +113,275.3004995531795,306.83564646386503,4.779925536315024,4.424861919299598 +114,276.88576480308285,311.35434787217997,5.549501601726021,6.526755225085992 +115,277.14029465508577,309.65039091667654,4.580940412764937,5.080639071791438 +116,277.4324777875824,310.4960617480911,4.471359740657681,4.32292480362113 +117,319.3288258962187,311.6702225501444,5.058071424215753,5.61952659445947 +118,319.8591509274496,310.989524065149,5.676606774774989,7.467429803565788 +119,318.99005649592243,312.4173775749036,5.750237766169274,5.397366324681752 +120,319.6131328938472,310.5522979637107,5.5022885295904205,7.263578897387779 +121,365.29517640566365,314.6454813265486,8.460762409909734,4.6709015542721914 +122,361.82211363523294,313.68568720200915,5.985773405781822,5.263777316141343 +123,361.4480761928614,313.0382171673784,5.736550096606568,5.653009750209729 +124,362.77676743108657,312.1993102338357,5.979547887317892,5.588195075901747 +125,444.8280999329621,315.2874742212303,6.27290398703566,3.2254871043818376 +126,440.039105136866,316.4990582369399,2.717419411362314,5.5021381149114275 +127,440.1448707987162,316.91453325930746,3.591630687306421,5.692686701585921 +128,444.4735843873624,318.5837135172218,5.650865106238081,3.8098846947664695 +129,480.4945871932981,317.7789400812657,2.8473874205661946,3.2846798443123237 +130,480.34502455519726,313.1237155709503,2.8405711463483505,5.887133881466956 +131,479.79765238044547,317.8026694666446,2.5364142708665374,3.2181996809796747 +132,480.81626241860704,316.98435781490645,2.135649445640601,3.5315188723853113 +133,482.1126824365287,292.7236746644675,6.795795621748642,3.589777249851841 +134,60.57986058588791,298.3572263782008,2.0715574011265097,6.518875203291838 +135,60.26789543218528,299.7821310194954,2.4359457319030224,3.302053162843642 +136,59.50091999103519,298.34107118829087,2.338468862304903,3.0546922696738714 +137,101.38271621918946,296.483247325443,3.5173219751207268,4.497162712521202 +138,100.43332664554771,300.16356781590855,2.6915212734293545,4.145281353905138 +139,88.95536885340141,299.07746679015054,2.783698934533499,3.917152490131537 +140,100.29389089950519,299.8972675509202,2.566259282658186,4.137718806425782 +141,119.96308784890563,299.8312652747876,2.8076039128455625,3.487604969893026 +142,119.21634890704448,298.4258068241335,3.1000278549881677,4.175736792274726 +143,112.26314328941838,302.0132035682278,4.497193147167675,4.627836503294436 +144,118.63154926153814,299.5090092566827,3.3112468547584886,2.82625813066952 +145,140.22829557703238,295.83589398019353,4.880610377957939,2.876734137897074 +146,143.96502880541922,295.45158153676647,4.250115873207735,3.0733240603225105 +147,140.66008917985863,295.75005128745903,4.893542903008491,3.138028915535486 +148,141.21893535376495,296.1533805219746,3.774408848238054,3.0467012666428333 +149,183.47872058961224,299.0180109809012,3.257615072049357,4.1723220562822725 +150,183.1202811035564,298.79425325159076,3.469002943022174,3.997120410978376 +151,183.2016789609457,298.4838438451825,3.1679502308294953,4.084970750698522 +152,183.56716590770395,298.3764936397965,3.3471833496481467,4.077681465171855 +153,190.41048704769,330.4978785855013,2.083041500838133,3.4668015126104454 +154,188.96675676778156,329.9036439013521,1.9931882571475936,3.508215161643373 +155,188.33490314035438,329.81417912235116,1.8728073653310773,3.0484929469157747 +156,188.31414516895805,330.23186734474723,1.8830058285338804,3.3131134887294613 +157,231.30258441852257,329.2869590111576,2.1015883812262706,2.7686520980654414 +158,635.9719402081547,323.45669801247647,3.890586665705017,3.4262788642164947 +159,231.58692741290457,329.78511421313885,2.073756648357063,3.6457128678010338 +160,251.94245026669623,329.3621392921355,3.4400207042718804,2.525297437969197 +161,275.38274900691636,330.6582764942376,2.7758194307457162,2.781269710685483 +162,288.16094061378243,329.96864420502334,1.7425792225683983,2.7891999383989616 +163,273.9343912983064,330.28517683915425,1.88697235808454,2.153903027764216 +164,277.40318080027276,331.32724722075693,2.51910988134524,2.2364789702215044 +165,294.8273106877241,330.7078842677868,2.0202421142551663,2.645341711239525 +166,317.03626643514605,330.57896380392424,1.9865816645763301,2.776754699862097 +167,314.93276908458336,330.67614347282944,2.6509184944650532,2.7861880759516926 +168,299.640483801822,330.68496013319924,2.1034251306897223,2.6995826605586095 +169,397.31504374955824,332.3446123671715,4.011960577043935,2.119261063102862 +170,396.5580357804531,331.5612694467712,2.1013176840578547,4.345997085530413 +171,397.49205012933754,332.4442253933989,4.083617010295474,2.083000027123604 +172,396.4373476151805,332.4498304809778,3.6443064475289324,1.9520773323350806 +173,172.71708638362486,155.60703919548823,3.073597315308788,4.401620808681049 +174,174.69066860790247,155.66811371703272,3.3201919365119563,4.524189384907778 +175,174.36012639095586,155.21688748228445,3.313966666920818,4.280738433967948 +176,174.27542002212184,155.33243945954135,3.4684361769046457,4.3256192119148285 +177,211.35953547851577,157.84363965463723,3.719577632132569,4.52395842333967 +178,215.49817946473246,157.8061035073585,3.420835243071113,5.204301731036066 +179,211.58080964064885,157.9196266744007,3.750774395208928,4.781345943827068 +180,212.21010780634873,157.82655078622685,3.0477176203472505,5.171003834767582 +181,261.951692200774,158.03145626439886,3.3820588588480125,4.517024497962329 +182,258.53106462200054,156.41654274449266,3.610545283020404,4.607365869710835 +183,261.9931127261629,156.844374467896,3.3582923289081412,4.203836335498702 +184,261.97037263466234,158.27263012263947,3.4440759214867183,3.5700855150119994 +185,303.2394620820782,156.27343358354165,3.4728086741188746,3.133134636490943 +186,281.81947814044815,157.07330827651708,2.3587900891205402,7.458771102609963 +187,296.79672730554864,156.66963976209618,2.4956604990337636,7.422350136504288 +188,300.202613978401,156.83041886564462,3.6244136435867715,2.652614592092425 +189,383.13489230058434,158.29028886500078,3.9437889097096543,4.109817373692409 +190,385.65899984883004,157.07389261777607,3.7243534642349445,3.3291912053378807 +191,385.5178115620514,157.22774057918932,3.5586432492433517,3.220168950341415 +192,383.2113575049479,157.78585537067738,3.864821842971764,4.094143758353614 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std_1.2.csv b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std_1.2.csv new file mode 100644 index 0000000..5f851e0 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_naive_std_1.2.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical, +0,,,,, +59,93.31359188,216.1040838,0.618237701,2.897325933, +60,94.25152003,211.5127273,0.358870938,3.374833177, +61,94.64301786,213.3034423,0.841278395,3.062799586, +62,178.7915698,221.842599,0.620940525,2.727375108, +63,178.7793615,222.1382787,0.946339151,2.65755042, +64,178.9998276,224.6227623,0.61583784,4.559621449, +65,267.3253475,202.0759585,1.85039789,13.78987315, +66,267.6140114,206.8004802,1.867849351,1.710489483, +67,264.4386823,205.8818785,3.840233588,1.91476041, +73,274.5584796,203.6589219,4.505342013,7.217491136, +74,277.6065739,204.8403967,2.53813086,7.562467947, +75,273.475128,204.5665369,6.401795049,8.18811108, +77,350.1228767,205.4123371,5.43844845,2.525576348, +78,350.6271681,203.2043449,6.076846255,2.128968071, +79,353.5340449,203.7901342,5.894050026,2.029409224, +80,314.0476596,202.7447844,4.208062302,4.422405408, +81,303.4655309,200.20082,5.864841166,3.753278554, +82,309.7350728,199.2472142,6.146777379,3.229374023, +83,309.8136405,199.2700541,6.473807505,2.771201556, +84,131.8274832,250.45136,3.454262443,4.292952578, +85,130.5911362,251.9466741,5.088611576,3.864515618, +86,128.8594455,249.1550605,5.279052334,1.307516431, +87,129.6418099,249.7265599,5.674102334,2.163786429, +88,173.670631,256.7522595,5.866553313,5.378715369, +89,172.1209707,251.555845,6.337603661,2.552356252, +90,171.7976064,248.0992246,6.534417234,2.007986084, +91,175.4092531,250.5219813,4.288839034,0.449640845, +92,212.7821633,254.033097,4.812117576,1.782691476, +93,207.3837324,254.5046734,0.604104252,3.278464481, +94,205.878535,255.4463699,1.55981283,2.705140417, +95,215.1501942,255.6424315,6.824346381,1.148906305, +96,255.9885149,253.6259804,6.494243171,2.421806172, +97,255.9826219,253.3646297,6.468647931,2.314616274, +98,256.1173538,253.322848,6.512173805,2.525898973, +99,256.2712916,253.7108958,6.57082344,2.465309527, +100,298.0833418,255.112182,6.687485235,2.531228209, +101,298.2465484,254.6691023,6.972265463,2.244339125, +102,298.0574205,254.6292176,6.694673144,2.290234567, +103,298.2353999,255.3627222,6.715087555,2.480896289, +104,338.9662203,251.6682432,4.494612613,2.181306735, +105,338.561305,252.5513452,5.899400221,2.549982168, +107,338.2423486,252.9079453,5.969934008,2.233318369, +108,338.5868489,250.286223,5.33707157,4.858284282, +113,277.5107012,307.0031736,3.046533561,4.079715047, +114,255.1425714,309.5914535,2.510342558,4.047091188, +115,163.3300795,311.0088971,1.739802853,2.119176746, +116,280.0267197,310.1878877,3.540974806,3.241557011, +117,309.0100015,310.4995789,2.279200941,3.89632061, +118,308.5100407,310.6270883,2.394103014,3.880968022, +119,308.7154325,310.6634883,2.330905714,3.520600361, +120,308.2952932,310.4657549,2.470183202,3.733393577, +121,343.0092421,313.7186642,2.116047292,4.058166847, +122,349.1493542,314.0310377,2.329671674,2.776838945, +123,349.1687586,313.2820578,2.324583878,3.911303408, +124,349.4798254,312.2673706,2.167920266,2.618473133, +125,447.2714051,317.0089575,2.288747629,2.283465886, +126,502.0743419,314.9331407,1.859257159,5.638134747, +127,442.2191901,315.5624488,2.275416429,5.721606222, +128,440.9195945,316.1320465,1.959733233,2.12793613, +129,482.4868589,317.7187731,1.760711011,2.837186752, +130,485.077771,315.7744691,1.876571793,2.865671883, +131,482.3554415,316.9661161,1.737629421,2.691241938, +132,480.7531236,316.3363629,1.885581584,2.381456819, +133,9.357026816,301.1394482,7.424860692,3.888697336, +134,60.72228834,293.4657307,2.410669491,2.816753402, +135,60.53625758,293.2506041,2.610803253,2.504754891, +136,59.62145759,298.4361014,2.409380579,3.230447055, +137,103.2748467,295.0002111,2.285610091,3.448504993, +138,108.7313646,294.0818247,1.941384263,2.600507881, +139,98.77723689,295.1770333,2.394266051,2.756924387, +140,109.8090092,293.9924853,1.789054477,2.547258237, +141,121.6681385,299.5494119,1.285859505,2.314668892, +142,117.0240124,298.3520769,3.085394371,3.004881909, +143,118.231263,298.9916067,2.3397467,3.279021573, +144,119.3795533,299.4061851,2.582789129,3.228779442, +145,145.2816959,296.1970142,2.38417805,2.058778107, +146,20.45948253,296.5421431,2.681947682,2.011036224, +147,145.2227435,296.1268899,2.395705671,2.043939485, +148,140.6543991,296.4875091,3.005656896,2.058048941, +149,176.9462544,296.4796109,2.24719876,2.122544254, +150,148.5858476,296.4403641,2.206492677,2.144769353, +151,65.25284426,296.7475332,2.121864812,2.069698061, +152,178.3156184,296.2248128,2.213752826,2.117494282, +153,181.1171007,328.9279925,1.042514147,2.315998788, +154,159.2464172,329.6605288,0.722943069,2.202447441, +155,181.1092004,329.3955388,0.942331973,2.157325361, +156,181.3698422,329.4487599,0.935400997,2.159791188, +157,231.0298311,328.6050525,1.743400369,2.014717548, +158,240.4715846,328.1027257,1.297159757,1.643873703, +159,230.7677404,328.3139315,1.058343333,2.111095523, +160,229.5831095,328.8765845,1.186522348,2.087957983, +161,274.5137789,329.787221,1.746109884,1.564619793, +162,282.1821412,329.1227352,1.655838365,1.70307133, +163,274.4928638,329.3941296,1.454030821,1.270915558, +164,273.8955019,330.3408954,1.582117708,1.359498013, +165,313.5529536,331.0516411,1.516937377,1.509223594, +166,313.3897344,330.8407781,1.689424981,2.682274969, +167,313.7752015,331.2133122,1.484833323,1.572483211, +168,313.5745346,331.0747921,1.494009096,1.508575908, +169,396.3749593,331.9599787,2.151936274,1.343475157, +170,395.4237167,331.4329569,1.38376668,3.13374328, +171,396.5362021,332.0594479,2.233402524,1.33687979, +172,396.1637403,332.0628234,2.324809169,1.357494946, +173,159.2585618,152.0587907,2.454979661,2.419010121, +174,167.764136,151.9791958,2.249078383,2.39506924, +175,174.3513505,152.8927439,3.04541391,3.046012787, +176,163.8593125,152.1163908,2.245850906,2.431233894, +177,205.7580054,155.8305562,1.827178353,3.281469065, +178,214.6691565,155.4932254,2.282992011,3.193875104, +179,181.5625169,155.9851325,1.905636989,3.261743342, +180,222.7501825,155.2467436,0.53759681,3.263462486, +181,262.2540038,157.0830956,2.25298472,4.265499609, +182,259.441742,154.8143458,2.740600452,3.54091322, +183,262.3021049,155.3844415,2.205532074,1.69929688, +184,262.2291226,157.3954305,2.293182978,2.60561097, +185,304.5189197,156.0942392,1.719384081,2.919789238, +186,303.0823173,157.2681966,1.029613582,3.819098347, +187,301.7653099,157.2055926,2.575352453,3.818184906, +188,304.453398,156.148651,1.750578234,2.570731724, +189,384.9615182,156.8279163,3.147447988,2.436219831, +190,385.142509,155.9370708,3.034486866,3.649388391, +191,386.1865606,157.1308598,3.021833082,1.681812081, +192,385.0689288,156.5647839,3.129473983,2.464805802, +1,,,,, +59,92.98020296,210.7301638,0.522791146,3.672149354, +60,94.33424541,209.6207769,0.712959043,5.350162777, +61,92.64802764,210.5177497,0.595418733,5.547156704, +62,207.5747279,229.3538544,0.572121859,7.308688367, +63,178.2643509,230.1392843,0.916307827,7.241140372, +64,178.1218968,228.6406397,0.596703167,6.59232167, +65,263.1356007,202.5171299,2.993282392,13.10837515, +66,263.5498432,207.7381358,3.121060979,1.878113055, +67,263.39403,208.059889,3.084362941,2.375246951, +73,271.8260844,202.3394456,4.989389367,8.076149884, +74,271.8410755,202.8123375,5.31885568,8.053726527, +75,271.4096589,203.2728694,5.377230076,7.871267788, +77,349.9253798,206.1879045,4.582862379,3.702027552, +78,350.3296416,205.0583594,4.842890663,1.299663431, +79,350.0649697,202.2775243,5.79411775,1.942694674, +80,309.6366463,202.5052936,5.826833998,3.849897421, +81,304.2156432,197.8316841,5.835220622,4.295831468, +82,309.9442683,195.4976857,4.627150851,6.342731115, +83,309.7147295,197.0265133,5.058831189,5.889513251, +84,130.7344064,251.8116871,6.430453555,5.341680351, +85,129.1112752,251.1902156,6.008621382,4.323092999, +86,127.9831913,250.8210973,4.738368491,2.572218628, +87,130.1965719,252.2844149,7.110134504,5.09323269, +88,170.3002318,255.161434,5.690121369,4.700436401, +89,171.2585947,250.0133249,5.680641798,3.776527602, +90,172.1235758,251.6800326,6.2294994,4.20315816, +91,173.3400802,254.5386511,5.543590958,3.91363343, +92,213.2603045,252.3008681,2.335677624,2.872250524, +93,215.0902707,254.1583026,4.339354721,4.369371457, +94,211.9678785,254.1058558,4.275784379,4.46023842, +95,214.8368785,253.4169863,5.506727817,1.911466032, +96,256.517454,252.3881478,5.815407196,2.550431856, +97,255.6478728,251.9252364,6.11987315,2.152700053, +98,256.1374083,252.0516904,5.782654633,2.667395102, +99,257.7228752,252.1299079,5.335083237,2.128049929, +100,297.8311949,253.9653172,5.924725405,3.167204464, +101,297.5128414,253.9978911,5.638642622,2.746686532, +102,297.4725186,253.0521962,5.860286143,2.352795437, +103,297.3362522,254.4734242,5.715730646,2.516042898, +104,337.4351662,252.5457049,4.125562667,3.313965227, +105,337.8624427,251.5183513,4.989598867,3.12923061, +107,338.2193223,252.1032549,5.515561111,2.99820905, +108,336.3124802,250.2062703,4.716755758,6.491905854, +113,273.4054239,309.0245598,2.007529628,4.545176202, +114,275.7006,308.5897281,3.903782811,4.201910704, +115,275.6098701,308.5642409,4.631427944,3.639510738, +116,277.3921761,308.2813594,3.80169276,3.534953726, +117,293.8297693,310.7195738,1.521629374,4.613201387, +118,291.7659335,310.0988882,1.468614673,3.891663176, +119,309.4115342,310.3821357,1.182104119,4.505358982, +120,292.5515413,310.0542368,1.424775019,4.061589902, +121,347.8690582,312.263906,2.086860469,4.058200539, +122,359.5565312,310.5047441,2.330047253,3.638307358, +123,359.6470891,310.5270923,2.359429636,4.285573798, +124,361.5717357,311.4896921,2.501565545,3.082805746, +125,445.1246388,317.8559644,2.770881273,3.991135312, +126,416.7634163,315.3075299,1.770909628,5.747036063, +127,446.3346171,315.0196018,2.263014967,5.752920657, +128,442.282108,318.1603279,3.090257217,3.581681297, +129,478.5480048,315.9810021,1.765570954,2.41855109, +130,479.1318974,315.5731843,1.398148504,2.403118465, +131,478.6645006,316.3894294,1.795372838,2.422278886, +132,485.0663804,314.7146343,2.330786814,3.08044557, +133,87.59543272,294.7524772,7.59874341,3.091737517, +134,57.18983221,299.3908146,2.514015918,4.165559587, +135,57.04702337,296.9718239,2.857620858,3.649136041, +136,46.33616939,298.2861068,2.691730212,4.096440805, +137,100.69449,290.5774527,1.724170339,3.065422071, +138,159.3624208,292.72289,2.784165242,2.962548105, +139,353.4092013,292.0076334,3.014363498,2.92804335, +140,89.97636901,292.9113393,2.654947202,2.871927676, +141,122.0853563,297.6938028,0.685452566,3.352456383, +142,132.1553664,297.2171229,2.706901699,2.956878084, +143,127.1646194,298.2335745,2.769134247,4.011140387, +144,130.8707996,297.8983473,2.818953624,3.899711628, +145,150.2748279,296.4426353,2.72517508,3.718234377, +146,148.9487989,296.2260643,2.706792749,3.704570535, +147,150.1580396,295.8625463,2.810800537,2.960921611, +148,152.5470386,296.7976312,2.875415992,3.731793392, +149,178.2623154,295.1070469,1.566658642,2.765605075, +150,180.9716772,294.9012941,1.684242753,3.139648254, +151,182.3315967,293.1571828,1.88832792,2.268070032, +152,181.137088,293.5579351,1.671971687,2.330347328, +153,185.9711466,327.425234,1.691859372,2.387374111, +154,185.6800748,328.060633,2.609970862,1.94621952, +155,185.8166898,327.7405073,1.727258135,1.871705694, +156,186.4702702,327.2910587,1.608306647,1.866211656, +157,232.0471896,327.1305533,1.526798514,2.151252107, +158,229.4438949,328.3898306,1.156559873,2.225493584, +159,231.0122446,328.2692359,1.210844403,2.221420963, +160,244.7640449,328.8696047,1.374765582,1.935943501, +161,272.0799492,329.052411,1.166202217,1.28745393, +162,752.5860223,325.8625051,2.107359839,1.609035927, +163,272.5343254,328.9438388,1.464422622,2.480037038, +164,283.0401036,328.6492917,1.198989734,1.977731191, +165,314.9483725,330.5771118,0.672009898,1.622968038, +166,313.958339,330.6951411,1.098557555,3.125795977, +167,312.3748044,330.5081672,1.235648115,0.963304922, +168,312.8132723,330.7618727,1.348540765,1.93311836, +169,395.1307954,331.5074481,1.448023063,1.892084895, +170,378.9013814,331.4082092,1.792713799,3.432678443, +171,395.3009462,331.5620671,1.453176361,1.84090791, +172,396.6957515,331.684604,1.422416718,2.181389097, +173,172.4328077,153.1365897,3.00979225,3.273591347, +174,174.8689464,151.9590035,1.271482898,3.354743027, +175,173.7469032,152.0170272,2.992197181,3.587820476, +176,175.0489368,152.9142709,1.273711372,3.067651219, +177,220.2914705,153.9301722,2.661722075,5.161796303, +178,218.8061959,153.873329,2.751169022,5.214692401, +179,220.2111266,153.8301993,2.528867915,5.135768244, +180,221.0904806,153.6681136,1.36428459,5.195182563, +181,260.2185867,156.1774186,3.167143162,4.210885006, +182,276.9192779,155.752447,2.098877657,3.126639131, +183,260.0002443,154.9000065,3.142718258,2.746624899, +184,260.1158035,154.8963762,3.210429251,2.62793041, +185,298.167749,156.5262689,2.118650858,2.472370547, +186,303.7104855,155.0312339,2.739066062,3.598984306, +187,302.2662231,155.0201999,2.993547761,3.828128242, +188,168.6937164,157.3888805,0.989603153,4.043452094, +189,380.4478403,157.1834126,2.567599568,2.068498326, +190,385.0896758,157.6459315,3.558659095,2.667151842, +191,385.9717948,157.3015558,2.616974703,1.908230272, +192,379.9755719,157.0348278,2.624845194,2.4242362, +2,,,,, +59,92.80774775,223.3561377,0.63373947,3.204356685, +60,94.82990414,219.9054093,0.789060896,6.846135813, +61,90.4092595,220.1551552,0.922257111,6.838018548, +62,177.10956,218.9010373,1.390525166,2.749732073, +63,177.7445626,220.0664962,1.218558792,4.188825256, +64,177.3811761,221.4094598,1.295990619,3.612508185, +65,265.6878096,206.6551328,5.335870158,16.66971332, +66,273.1624412,205.5267621,2.216267652,3.574602068, +67,266.4284457,207.3593812,7.16312328,4.472335501, +73,280.9659797,202.1605676,1.654626712,5.681306637, +74,280.0193239,205.0374117,2.330531985,6.377333876, +75,280.9384725,204.351971,1.646830184,7.965623143, +77,354.887108,203.2393539,7.442012113,3.928986671, +78,355.1071844,201.8006435,7.656540481,5.190365035, +79,354.3451992,201.3442388,7.686501926,5.138973819, +80,289.243447,204.0055532,4.58144207,5.795627738, +81,302.5452164,202.0428129,8.253331974,4.651552993, +82,308.7167046,199.8020174,7.194696682,4.047995764, +83,308.8793972,199.482231,6.945358429,2.872448428, +84,131.9672656,247.4466899,3.076812196,3.459870992, +85,129.8883587,249.5830759,4.540042819,3.450294622, +86,128.1149268,253.652363,5.978168979,4.352921914, +87,128.537252,252.6585171,5.339963888,4.941548474, +88,174.7763496,255.8013916,5.728268852,3.498998329, +89,172.4531156,250.0851165,6.313071019,1.962531993, +90,171.3409715,247.6560238,6.581855503,1.831029569, +91,174.6659473,249.1824453,4.505611672,0.990903523, +92,212.1155467,257.1963349,6.711658598,2.240845082, +93,214.992281,253.3937445,4.95745259,3.977160866, +94,204.873601,255.8708178,2.120263764,3.169453436, +95,215.0833848,256.1212831,8.467407782,1.94734564, +96,255.92502,254.9921917,6.763112158,2.141438665, +97,256.1940783,254.3374307,6.713514562,2.121641996, +98,256.0021708,254.8322904,6.607905276,2.023401889, +99,256.0562427,254.8473944,6.760889792,2.566059289, +100,297.8613113,254.3084187,6.299358006,1.871267236, +101,297.5090684,254.1732975,7.403403204,1.825741321, +102,297.570531,254.484813,6.393439895,1.946205259, +103,298.2356864,254.3132468,6.191791543,2.014387656, +104,339.4930838,252.0286054,5.942208628,3.19529963, +105,339.8235924,252.7216561,5.056927498,3.013043648, +107,337.8947682,251.0496843,5.760272081,2.151022333, +108,339.5429906,250.0031284,5.812146409,5.287653171, +113,278.5304079,306.5030719,4.761955088,2.589866432, +114,276.3287806,311.8059975,5.162726712,5.347412476, +115,279.5195273,309.7197114,3.678439981,3.528386683, +116,277.8341863,310.7569919,3.685601883,4.736286987, +117,304.2455249,309.6986513,3.002773122,4.55528393, +118,302.5910518,310.8630341,3.1636375,4.959892925, +119,296.4299281,310.9683457,3.025514328,4.684284176, +120,303.1474392,308.7545195,3.172637676,6.51899129, +121,365.2154226,314.6041009,4.98222295,5.649531231, +122,341.3097453,313.954716,4.082311959,2.23304854, +123,341.7161701,313.5306694,3.968339357,2.174027249, +124,345.5257173,313.0220584,3.990163672,3.578776944, +125,469.1330131,315.0513307,4.437377537,2.47725153, +126,438.8511288,316.3709557,1.799887035,6.635379091, +127,437.9643787,316.8297365,2.404378501,6.796381593, +128,456.5949916,316.0343792,3.316370103,3.022194886, +129,478.3667044,317.5900476,1.477074747,2.534323472, +130,478.6797334,315.61719,1.885919089,3.697683958, +131,484.2348696,317.9951215,0.962093158,3.007330919, +132,484.1170489,316.4021371,2.002291195,2.919700186, +133,85.29652369,299.926705,7.827458514,3.937423663, +134,59.67047635,298.4471118,2.293779231,4.907606339, +135,55.46090118,296.1797692,2.475399962,2.485135918, +136,52.88374765,297.6242074,2.052251164,3.035605218, +137,102.2355224,295.6763876,1.22628138,4.920419862, +138,107.0183407,296.2388908,2.187701543,2.202721291, +139,108.9649908,296.1444929,2.302412374,2.209906061, +140,106.7279343,296.3701875,2.251034343,2.356004223, +141,120.9447868,299.1646936,2.931034996,1.870227654, +142,118.1973619,298.0334936,4.076098187,2.634668296, +143,117.626087,297.8252302,2.900494158,3.224708556, +144,119.861526,298.3571524,3.49398133,2.953550317, +145,145.9000645,294.3312061,3.803172414,2.403143838, +146,145.4214846,294.4868154,3.267697342,1.825315104, +147,145.7428138,294.1450033,3.987455312,2.437598704, +148,143.0284346,294.5618795,3.649189497,2.401468767, +149,185.8282608,298.0425231,1.272428277,3.643826725, +150,185.9498776,297.7664853,1.248367103,3.441098707, +151,185.6174834,297.1887106,1.024053665,3.507686463, +152,185.7795824,297.0711508,1.20747523,3.5087149, +153,194.1877708,330.071149,1.176771328,2.255752122, +154,189.2603762,329.3370618,1.370351835,2.119976972, +155,183.5303914,329.4293977,1.576418861,2.023661479, +156,183.3754904,329.9333334,1.585241848,2.049146037, +157,232.8780299,328.5197502,1.546698079,2.435561977, +158,255.3837334,327.39891,4.012448382,2.890275591, +159,205.5013925,329.9023819,1.958210827,3.923308113, +160,216.4453637,329.1893338,2.373852392,2.222571188, +161,277.1390123,330.8696438,2.264039169,2.174324696, +162,273.7246411,328.1831137,1.667751192,0.989783278, +163,322.3699595,329.7367532,1.852350787,1.37665533, +164,197.2500263,331.7884197,1.707784311,1.962322643, +165,301.3391123,330.7070529,2.05808286,1.699031874, +166,318.9940458,330.5262295,2.512905677,3.004133231, +167,285.6755255,330.6208442,2.005104058,1.510838797, +168,303.3766759,330.6890426,2.123836632,1.561502074, +169,399.4469649,332.5112476,3.236447147,1.345904021, +170,399.4479821,332.1869344,1.78598569,2.110197381, +171,399.5666501,332.7032035,3.319483494,1.271894754, +172,403.9857431,332.7091106,2.841535249,1.352866247, +173,272.0791472,152.2310031,3.137638063,3.319842322, +174,171.1803293,154.0741983,3.043033059,3.147961415, +175,172.5368551,153.5142165,4.048705698,2.906116814, +176,173.5537003,153.7359113,3.18246475,3.208562905, +177,220.452141,156.7383818,2.725644558,3.229124685, +178,219.9369118,157.0167193,2.929832633,4.337287441, +179,220.2700191,156.7580906,2.801366932,3.436425987, +180,220.212808,156.9960205,2.771416096,3.551997, +181,260.8297065,157.7245607,2.864867836,4.836641376, +182,299.4671643,156.5779657,3.042758034,4.175090355, +183,260.8703321,155.9495176,2.856985202,3.724198165, +184,261.1959859,157.7695767,2.671200412,2.608809478, +185,303.7898051,155.2967427,1.996466596,2.949035097, +186,312.0293319,157.0403841,2.517021055,4.306578124, +187,335.3153106,156.695305,2.879498971,4.237238691, +188,304.3482421,155.9405605,3.14362489,2.311963161, +189,386.0460662,157.1564715,3.503153843,3.344989582, +190,383.2598233,156.2541372,2.931096625,3.788089778, +191,385.0925047,156.6704184,2.621070632,3.280658801, +192,386.2252536,156.4378146,3.373862306,3.19857897, \ No newline at end of file diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/convergence_prime.csv b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_prime.csv new file mode 100644 index 0000000..54b1f8f --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/convergence_prime.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392,0.9677151865944192,4.009449743264753 +60,95.68692886974831,217.86446645631813,0.7424975144337135,5.151973582834018 +61,95.27930768267886,218.4321212539979,0.7270480243366128,5.212134543408362 +62,179.76038347611592,223.31234892921998,1.1147842657503555,4.609101395283265 +63,180.6656249576765,223.71898099246778,0.83092419657981,4.560940210510493 +64,179.89926897794987,225.49954804120625,1.1381174020649096,5.315085189344285 +65,267.2846565814505,205.23349976223787,2.3312417949986513,12.645312337636021 +66,267.49589526309217,209.85177109164337,2.394374307275872,4.5107503315754 +67,266.1835519250078,208.6210325552379,3.540061676733699,4.360052044157361 +73,274.3400431870006,204.75610310411912,6.491531432619202,7.31888797087335 +74,273.48666750879767,206.22331690671257,8.261574847627143,6.971589386730805 +75,273.15099171429256,205.61817173382607,8.395328002698498,7.565385107130859 +77,353.2863004930388,205.14959199780805,5.493098240735283,4.2828384868245655 +78,353.9238420531685,204.12742442066988,6.087365194189325,3.791338436749506 +79,352.21840596322596,204.15679894425952,6.557195072515586,3.1954900594475086 +80,312.16235018388227,202.94043465851004,5.386818198872637,9.493830520912068 +81,313.14659922988295,201.99717866560937,6.025875449926955,4.661460417025812 +82,312.11840038067925,201.00669797880116,7.0864910249072635,4.406813194332426 +83,312.29317276741347,200.45780062295867,7.089188755441932,3.1660046223221405 +84,132.42237239805132,254.29214663519284,4.3067464843901515,6.417058493680035 +85,131.29521858798734,255.4865958538821,4.908850345384105,6.3671100735668835 +86,136.03545039679358,255.0814813071878,8.584433337345413,4.807018608010044 +87,130.98094102950247,254.42187606024922,5.117211446405824,5.370134929913309 +88,174.55795757665564,254.28580927665664,4.7275771979909464,2.9159640887010574 +89,173.67935580024877,254.09783447631526,6.437695363099053,3.474606588647915 +90,173.43573264703227,253.47071779954354,6.593885801251147,3.4291368786010663 +91,182.2241727196623,255.67658212128163,9.720017436299852,2.9496717195778195 +92,215.12055072666627,254.67325551865426,6.334123387607411,3.0867909122735444 +93,216.94462220467622,255.47756358425315,8.080773269328214,2.7211585139427834 +94,217.3834915918711,256.4745644877478,8.267318853585852,2.211181525286066 +95,221.02053888484144,254.6506021697632,9.359150594815015,2.1628014762683434 +96,257.50957542067664,254.1259284055811,6.675780060232609,2.704136241957288 +97,257.570545197815,253.88751117668164,6.647657278502652,2.9140751377307628 +98,257.6089813372307,253.78662089019835,6.605179609252467,2.6809454420956143 +99,257.6936671647974,254.2498517060511,6.576722939133856,2.7069332019005827 +100,298.2952436151055,254.76909617478606,6.705809824561147,2.981349985017069 +101,298.1169393001307,255.21794911950758,6.624534032640799,2.181605220236403 +102,298.3189654536773,255.25096983760508,6.750900350115645,2.3083727544087247 +103,298.4415890038736,254.35763625124292,6.663590033871669,3.2667839890941295 +104,337.61901332805763,250.6788168722553,6.210728685673001,4.844297880273439 +105,338.06248003559915,250.78747044533233,6.338074391942699,5.000637757727747 +107,337.90938740495653,251.25867480332388,6.288961573364599,3.8152539451454097 +108,338.18833275957206,250.67508565210196,6.186589358792703,4.10107941402743 +113,274.2817559120019,308.9374117445766,3.892956777078502,4.794749659977309 +114,275.7421347767481,310.2555996702759,4.535765938235691,4.66622650744931 +115,276.0461325201841,310.02072804280994,4.545655403672037,2.2262514157125017 +116,276.2417374542582,310.24048782871637,4.6497847767530995,2.8951312130050146 +117,319.70071456271313,311.8764440530121,4.410519998245082,4.1053878934009775 +118,319.6313092726346,312.1826263203713,4.334709687203355,3.9909339754311914 +119,319.3774988742649,309.9857812246406,4.471689460416843,7.048323199965066 +120,319.76654338764155,311.98447027104925,4.4491853585047645,3.9716440216868176 +121,360.8050494733246,312.9126753058037,4.744138263484551,3.2959591069664484 +122,360.64739266264627,312.8307783296112,4.673876604017344,4.0505350195787555 +123,360.689270210389,312.2626467099784,4.717842951294665,4.331175918113057 +124,360.8335382258014,312.5428875466125,4.7257637014968825,4.238743771700391 +125,442.06586848771724,315.54047492369574,5.1708505304868275,4.096628870255675 +126,441.42140737582423,315.78584607818385,2.592454459875001,4.6687701093869 +127,441.5300773440553,315.90717126090226,2.8050705738429227,4.687041451309435 +128,441.95769286933466,316.8407357397122,4.805859396667629,3.6325916039286454 +129,481.35090878368925,317.4272946632326,3.3586867882998677,3.2305216999009705 +130,481.4725819590857,316.6159681822135,3.546147101969164,3.2838056303462357 +131,481.2522465836884,319.49752085243165,3.263691605498864,4.032091628707869 +132,482.31846086642565,319.45748209732994,3.3334111968000197,3.4001948797889874 +133,59.55768321914789,300.29871844382603,3.8761928423107794,3.6951665481304303 +134,61.376816545951996,298.3523691730104,2.113993300917673,3.899220174332725 +135,60.796935680150746,298.09076040109204,3.3916290934001863,3.4328323193984733 +136,59.19985355062283,300.1851062687214,3.520034988226608,3.5453648546285197 +137,102.6280068014727,297.40383468175656,2.749638491064498,3.880988203100239 +138,102.40955557323258,298.7865911290351,2.7573372442370903,4.089700063188653 +139,100.57013333623348,296.8202762296189,2.9651756626973564,3.163333481381463 +140,102.67850653460079,298.5730025774653,2.656076828883503,4.008870765124035 +141,120.23221696171454,300.1898879495705,2.3495738375350714,3.7101386992401784 +142,118.10535832779757,301.85912326532906,2.662771758344228,4.434372354516663 +143,118.16700474619614,302.0417496311767,2.810926040633238,4.442752618047973 +144,118.19187121087131,302.5378510894045,2.8502302470584953,4.428574269320613 +145,143.380762851227,297.65106023170455,2.9029598644975594,2.9494319243206975 +146,142.46748228973178,297.3647432540817,3.516542953167025,2.7867411900804395 +147,143.2239805848247,297.5672414624104,2.925450223126345,2.8821527557517435 +148,140.51718892104998,297.9845023911149,3.134479693224828,3.0837592352072623 +149,182.6593569656309,298.1418468359333,2.648390300198232,3.275571713707499 +150,182.64828488417706,297.92582445480707,2.7260433370787203,3.287985243918374 +151,182.92797391602642,297.87455852433123,2.5754349127258473,3.303821768124996 +152,183.0029286817877,297.8637465373881,2.6850779296217095,3.268506780902108 +153,186.1728851830908,329.8083307385874,1.6988565395865438,3.2857803265960546 +154,186.5492243440529,329.1491955430002,1.9159248202789043,3.190026296337793 +155,186.0292302003802,329.23752125561214,1.630100824234192,3.143397778827556 +156,186.05706501583137,329.3191466220413,1.6185913035274193,3.18627620460259 +157,233.36795685970054,328.463961880729,2.643309826783174,1.9867341998292147 +158,232.82586842848798,327.60883484043825,2.477588134745834,2.5854098103097747 +159,229.71350413783279,328.3780985513343,1.4377331090494412,3.4686128953627313 +160,232.72525153041173,327.7700361791668,2.4530240891852237,2.5077492129850194 +161,273.76316751955034,329.73823826493043,2.394688280474286,1.806427127995776 +162,275.7575781134558,329.9125721193857,1.3584269354839966,2.5506427041479443 +163,273.60940070127293,330.0025820738042,2.4087695062685763,2.2557767070416954 +164,273.7244999819209,330.09757535831045,2.4201727937672897,1.7894497412511505 +165,313.3973669095876,330.59163642669836,2.5664663718925884,2.5175272820859127 +166,313.23094160288184,330.71155384663837,2.556749103943359,2.517895305394224 +167,313.2083786255443,330.77428522126553,2.440925958919023,2.523508078782979 +168,313.36106959216625,330.6523370232485,2.5105680868176643,2.5022918306323914 +169,396.3640143494862,332.05477157898144,2.544597691516881,2.2242293500191375 +170,395.617460222669,331.85554030819173,3.094183882820774,2.2794261534246627 +171,396.3911361968549,332.1303447002533,2.5527965384171347,2.1830363581679078 +172,395.89256887798285,332.16822339411516,3.601013097767017,2.1716024486759946 +173,176.02029170516317,153.71245910000232,2.3779159513262353,3.409134278667166 +174,176.10545306203875,155.20318481126037,2.4825478178566596,4.418906030455666 +175,176.03197440143745,154.95241321278883,2.42399408636437,4.430327097224612 +176,175.6846804297304,154.63359606135103,2.5997462043064927,4.219400830122209 +177,219.46327960613064,157.23609785750858,2.529672116014354,5.058864568041901 +178,221.0564853241154,157.3435472260885,2.2463229070198545,5.480115541197549 +179,219.62129396536662,157.2666553285107,2.5021134486595593,5.352065132338259 +180,219.69587995502016,157.1490063640601,2.516169881431476,5.470652636210902 +181,263.23636033723557,157.46707082247306,2.6921936322678013,4.204926201545835 +182,261.4098116420003,157.70610911447298,3.132796451668047,4.302605485582752 +183,263.2875985178052,157.05504332147794,2.6601053814719973,4.186611997777448 +184,263.16270089611913,157.68858593709763,2.7082086799182084,3.4205893941412424 +185,304.06394490620954,155.96888190631856,2.6882263261194885,4.294769105680108 +186,303.2325028543831,156.57995759281437,2.7961523629805916,5.391517197327435 +187,303.42630311491723,156.4924674158584,2.783092188384192,5.365203962414015 +188,304.6158660912609,156.4818813819881,2.506720194343099,3.179833381166062 +189,385.42176721515784,157.40021026648142,3.5085984360932585,3.721190877059472 +190,385.8286612719259,156.9884186905783,3.520976122354819,3.199129896839037 +191,386.21040345226567,157.9321486459702,3.2937940620339354,3.184759624897468 +192,385.60316481175545,157.2028302886849,3.4609224939824603,3.763410712575745 +1 +59,93.1287423931208,218.29700908810787,0.586116217920642,4.982728971287442 +60,94.70512938803542,212.6540109552706,0.7530580888942188,5.342989457535182 +61,90.1361278577332,213.33121631876608,0.7741246171980174,5.183322455003788 +62,165.64289497225215,225.874391036669,8.768671109743122,6.55018459819764 +63,178.59192480601794,225.09457355443593,0.900267664385944,6.339222495180265 +64,178.41449448989624,226.08373120485984,1.0988445958401813,6.645297501896177 +65,260.3568485015321,203.21378596696644,6.531586140510156,12.691771056267052 +66,263.21633393064695,208.05235410434855,3.3776181785676784,3.91127933981223 +67,263.60509933731674,207.1941441096728,3.5771988890480593,4.045622146226897 +73,272.29022155441146,203.26015396542505,7.667403148427107,8.484726496612334 +74,271.44632269355435,203.63647815827935,7.006836949843662,8.247800147818172 +75,271.0412882240347,203.67673019265595,6.9166949430129225,8.702335904677817 +77,350.55117323928704,205.53824540412742,6.3913113962364445,4.535767728612248 +78,351.5831370996324,204.56554912486993,6.914935781146339,4.208591544669765 +79,350.54080463471854,202.80860415043412,7.576153280744988,2.405442522969295 +80,310.6203346770107,198.9727284928463,7.295908168915119,8.99449222675377 +81,309.4303871248667,198.8260778916456,7.8402558918165015,5.732595151892859 +82,312.8487475083582,197.88498609405823,5.545843437300968,5.5454679231566235 +83,312.4494378330193,198.02482356912975,6.100953297862154,5.205602033075617 +84,129.73316120742015,252.31402870350382,5.182904459352007,5.7859701617993196 +85,130.09936826716955,255.07600217340146,5.535923397107699,7.036159941672144 +86,135.81702697516587,252.10204054872278,10.027649034484337,4.399918094601206 +87,129.96018632025633,253.63904238622214,5.660756401038712,5.8266843261131385 +88,179.7261278913035,255.3456126662452,10.57223062780983,5.845563121104949 +89,173.42291095269067,255.58833819764322,6.700532645820975,6.247923198559783 +90,173.10761109611573,253.5025139362306,6.760737603124655,5.536745737424702 +91,174.12745797775463,253.2601960722921,4.897753124735466,2.522716607958386 +92,216.78511969207446,254.5914187233686,8.95047307481889,4.249360054724529 +93,215.97344562124545,254.7054640425066,8.196439917611718,4.011111129846635 +94,219.24024367384476,255.41662872012847,10.121690584983755,3.367632134220822 +95,213.91037600886813,255.01236900202147,6.258734602959029,3.284512606242694 +96,257.3830982530756,252.6691612485834,6.880768996147865,2.9353265504494703 +97,256.07878148245777,252.5850508469038,7.193370431289156,3.536434124406424 +98,256.6563709830754,252.14302077100646,7.020255474285572,2.742516414019443 +99,257.10274737541874,252.44669038983187,6.759367673913806,2.5065554147623534 +100,297.3527413648711,254.3197859755712,6.974691942771777,4.204342914024384 +101,297.36935919598676,254.31625883281748,7.003782434070834,3.8132099844257588 +102,297.45043676182286,253.29006124829388,7.147301062318091,3.0312100621116413 +103,297.15639353267426,254.26565823155238,7.3776805534006185,3.914660604118064 +104,337.0467224043386,249.84436792649663,5.921815081770851,5.271202014540857 +105,338.2530319319246,250.01216730218792,5.481575455905726,5.469000206273413 +107,338.4288143610566,251.12173304980342,6.654167871317137,5.370828824572206 +108,337.6321115297869,249.87042147419172,6.005664399486008,5.04451473974955 +113,273.20050531167254,309.1760573916311,3.4219821116654865,4.957144824013617 +114,275.593658985165,308.5727448984995,4.702522493967433,4.008413607725532 +115,276.45985797306344,307.75120186662025,5.767076285351399,2.479883936569082 +116,276.6589541465393,307.7328403118153,6.184525915073467,3.409658651068851 +117,323.8680795155452,311.25555593462394,5.6467354698699,4.163445875643856 +118,323.990822160368,310.23497244583933,6.354306297639026,3.605863723170547 +119,324.32484229774974,308.2748476589923,5.951639025695133,8.081943297913417 +120,325.7385894442358,310.39579583995135,7.723927817628718,3.904269142941334 +121,361.79131456676873,312.1771387146637,4.3915079798209895,3.778217894990519 +122,360.25109899783934,312.73975566628565,3.3364555278083112,2.7719078470887877 +123,361.13964194906663,312.4482596768938,4.009973777907947,3.338550731387954 +124,360.8021695665512,312.55731463103996,5.178975914859417,3.147724551644225 +125,443.6146844651626,316.9499823437052,5.441494217460369,5.589514223334737 +126,462.74164751366203,314.6397925160877,3.1723106571758315,4.673495905701873 +127,284.4684422338389,315.96181914108945,3.781047749264403,4.799446710082581 +128,451.0537747662026,315.05034330850094,4.165022446102917,5.582872998184059 +129,486.2262311408019,318.917422588962,4.360015955842124,4.24279052637777 +130,484.203371665194,317.155262043757,4.666439360195373,3.538660983437178 +131,493.89209637934295,319.54817622659806,4.495507964960477,5.054370244042043 +132,483.79815450187516,313.87456269013853,5.0513219188547716,3.976286497193232 +133,58.415796919717515,296.3367806354237,2.745318197812863,5.347714894650585 +134,59.66992690532717,295.46552315023496,3.0521020998678443,5.04724168228645 +135,58.43814573925214,299.01257928228273,3.0314355414314353,4.680341029748839 +136,57.19875149216512,296.2038703275876,3.0187024946676813,5.430283114579736 +137,101.88869112962361,295.36699152796956,3.0605704820563435,3.976231975252619 +138,97.74223572831934,296.64159635228486,2.388879471730324,4.818867004598817 +139,95.13971714462463,297.63279866894925,2.5874115321204054,5.108323412261206 +140,100.97448449522825,296.37143206657936,2.23273639508488,4.835560641819327 +141,119.46912848294882,301.03987366288305,2.945034185014498,5.579249063467622 +142,116.04630564586442,300.9428981940468,3.646493643610884,4.201903655805421 +143,115.93833802312685,301.4015147621542,2.7752574824028806,4.899750014060764 +144,117.66427038686425,301.67621994166734,3.2562262537824718,4.934112992862415 +145,143.61862339021508,296.87569921241607,2.9793460068872264,4.493879539069787 +146,143.84226240395634,296.5995702000957,2.6657882037152505,4.487866588043545 +147,143.41726284468888,296.4604242772443,2.892883624851368,4.50539522391336 +148,139.90710854861246,297.05847391439454,3.4669655178811123,4.588153704670423 +149,177.97012292111646,297.29360417935067,2.9817918310917375,3.750304964672955 +150,179.09943783225685,297.22176671479934,3.0286986838896457,3.881572977421466 +151,178.4595029850307,297.07969710485736,2.9749987384442655,3.775627144339658 +152,178.9990807254096,297.58186299960556,3.0418692927202193,3.8833402396923353 +153,187.06432524491635,327.5110792134713,1.9103539442817077,3.1747672773580633 +154,187.40611165319353,327.24266469486685,2.028936750132528,3.039992572908433 +155,187.48202253723917,328.1910452260973,2.046736087360523,4.07325152306089 +156,187.4554203440108,326.77537509295496,2.0468424040406785,3.0346527434557236 +157,230.1275716483488,327.66375493177526,1.3064642552426002,4.735119343666496 +158,230.19455285047118,329.6573791501422,1.6872246668899367,3.583570894848579 +159,236.39481488323716,328.4457905246168,2.716174379714519,3.4183380314351863 +160,230.1984260911562,328.23405030487964,1.818805777200218,4.578868396563749 +161,272.1545894887068,329.32912181766994,2.0716370234969204,3.1939556616595848 +162,272.8983988300567,328.70387641284987,2.430197123109527,3.1487498704390036 +163,271.6162444327857,329.4696874435773,2.203277751618005,4.017476086378616 +164,271.6290916788945,328.8920615225914,2.008299706725287,3.3041284732956586 +165,313.03716740034986,330.7975522275865,3.0420523810535003,3.7108953229128367 +166,312.7612082311074,331.01658878813123,2.756286496478564,3.635011569085448 +167,312.555857804164,330.94886104868783,2.895089352246948,3.630322203243039 +168,312.99233681057194,330.7594147506374,2.9514521257261572,3.7325921124368473 +169,395.6599712440442,331.38000769767353,3.6713668117121325,3.4549858187839337 +170,395.7269407162828,332.3551932767835,3.1249445864849728,3.2139419865878307 +171,395.64772093777225,331.19728501985406,3.652929258669073,3.3877347902405988 +172,395.7526488830209,331.2745983423243,3.9055257304944306,3.4415616827579543 +173,172.19300877613125,153.8677984100333,2.9936489675181246,4.5406288069622285 +174,174.43739755929997,152.4534316026212,3.1172372976035665,3.3179648689547276 +175,174.29318678572136,152.18270882980445,3.1219958686591287,3.3048067882101986 +176,174.37774565459176,153.9168218422937,3.148891388697558,4.4895441435882795 +177,218.92125782027884,157.06267339391565,2.7063981074883805,5.4304455216655905 +178,218.85237431972325,156.51579863987993,2.6795499708167725,5.289366508551004 +179,218.17652673671887,156.67648159701702,2.747386160206801,5.224977213644244 +180,219.63668315938992,156.54252374150602,2.654919821631967,5.2993336248236345 +181,260.39420520785944,156.89107932316213,3.256704661733587,4.125191869561575 +182,260.7451262620054,156.26061389330727,3.674975253680245,4.673081143856457 +183,260.0769741828374,156.73605149236164,3.2485067302773727,4.2314614221050855 +184,260.3205919730126,156.89282130924727,3.016527309499428,4.22117756304117 +185,302.8007745851293,155.22452212795463,2.1986861092464727,4.536996509806027 +186,301.70658980492703,155.39202732491273,3.616906361622583,5.809560313914322 +187,301.9655960101498,155.27173302476598,3.5367891506442364,5.787704448891815 +188,307.3464400351471,155.7530563647103,1.0636861640988715,3.4615533986219376 +189,385.2275499165649,158.1706520863393,3.813439832275512,3.640361036690412 +190,383.77693943350675,155.96991177533516,4.219569642219233,3.833536791723274 +191,384.1919840339305,156.6889394336518,4.594412135572423,2.0156822112075097 +192,385.249022040249,157.09793266480662,3.877568024165435,4.522637183712553 +2 +59,94.17681256320567,218.7493975260511,0.6672950811803234,4.0696236612012 +60,95.60291842116452,220.23420259378253,1.2432894303505535,6.268557799628915 +61,95.02957510532019,220.4523644522619,1.03897231445469,6.283961945108087 +62,177.88668491962127,221.41680696479915,1.1635891534947462,4.266168737180917 +63,179.2047201008017,222.0714847243557,0.9073027108364632,4.622657461501109 +64,178.76685855250403,226.32660678265475,1.4338252285037825,6.163194163231048 +65,254.59096062439968,207.56765796649344,6.468811941167413,15.484181828020908 +66,262.3514299707784,211.47058512229123,6.200035074796359,5.723850290560224 +67,265.06237168987434,210.4005448238059,6.61860699217799,5.422654412058275 +73,274.91234547074936,204.52721235111983,7.271387658815161,7.492660955010252 +74,273.2143306337384,207.55888389096398,10.116961928861889,7.899368121489383 +75,272.91870930424335,206.4183338799366,10.032578813526321,9.289382922896465 +77,352.6324668691135,204.06675998471425,7.436756719086957,4.8581936941677935 +78,353.05135609325134,202.98520282433685,7.664430224814655,5.142377982862242 +79,351.746134852955,203.05786731461058,8.028743708479537,6.197058831659775 +80,310.21870253063406,204.63993652062547,6.829422420637117,11.038982037055565 +81,310.5482455608953,203.3161899769199,8.630027200417027,6.825063086136599 +82,311.07935156741206,200.8328753632899,8.282608636183143,5.648212100237218 +83,311.4698975682484,201.29198895046432,8.073700564520845,3.988913299124529 +84,131.85526420446874,252.0193765605421,4.710522724823439,6.327903412535792 +85,130.09901692321196,252.49815518747823,4.810325247545613,4.925112427111756 +86,129.09877923534668,257.0902057833205,5.286838664341266,6.0960063153090545 +87,129.58841891167637,253.33496272524005,5.004724826446331,5.207955764055635 +88,174.34014870627018,257.6293741682174,5.936812237283513,4.578268483473221 +89,173.08617175672723,252.22705318297471,6.9528446346151735,2.9206960921180114 +90,173.29362621289272,254.03640143495207,6.7445812273675925,4.594746547363893 +91,183.93566207705527,256.40769459187646,11.366675081342697,4.086344657301128 +92,214.000238044348,255.61808278157844,6.840266287108221,3.162185843886936 +93,213.6417614987187,254.76260041862824,6.181548205388113,3.4669409389809114 +94,212.59841286272757,256.77538398368796,6.642291270826204,2.865009376798548 +95,219.36862273251444,256.7917930393642,15.042021453799604,2.839050343283112 +96,257.12202196483105,254.71576094200717,6.982679389033818,2.9625204035270136 +97,257.3916794657995,254.02867969902485,6.8307722895588965,2.3226285735907486 +98,257.2278305685032,254.5619736557002,6.809772888664755,2.8383983340571364 +99,257.16282933783424,254.477050995793,6.931960195707054,2.6611905102158038 +100,297.5612747805052,254.68621271243086,6.616832054817872,2.682409735201763 +101,298.3394946306158,254.9149917819558,7.4103859236839025,2.0032533635948298 +102,297.7037470787607,254.32926027245796,6.697390437340011,2.6035794639192695 +103,297.9018444784966,254.79769770872946,6.481459768864603,2.9116637606731044 +104,337.7041120241776,252.2287315192184,6.785308450450591,4.100479545727181 +105,338.5071288183876,253.47618492583723,6.235731773413765,5.665420262300457 +107,337.8271824583213,250.73973826046893,6.0034125806830785,3.931922093279878 +108,337.86197274862946,250.42655028770324,6.756971947757317,4.556599933768003 +113,275.3004995531795,306.83564646386503,4.779925536315024,4.424861919299598 +114,276.88576480308285,311.35434787217997,5.549501601726021,6.526755225085992 +115,277.14029465508577,309.65039091667654,4.580940412764937,5.080639071791438 +116,277.4324777875824,310.4960617480911,4.471359740657681,4.32292480362113 +117,319.2852262928977,311.077818303166,5.058071424215753,5.709272247895537 +118,319.8591509274496,310.989524065149,5.676606774774989,7.467429803565788 +119,319.02916641933683,312.90617379038326,5.750237766169274,5.40025366381934 +120,319.6131328938472,310.5522979637107,5.5022885295904205,7.263578897387779 +121,365.2832995228827,314.5597006669066,8.460762409909734,4.458496704270642 +122,361.82211363523294,313.68568720200915,5.985773405781822,5.263777316141343 +123,361.4480761928614,313.0382171673784,5.736550096606568,5.653009750209729 +124,362.77676743108657,312.1993102338357,5.979547887317892,5.588195075901747 +125,444.73301900096925,313.7677536345598,6.27290398703566,4.75455241049808 +126,440.039105136866,316.4990582369399,2.717419411362314,5.5021381149114275 +127,440.1448707987162,316.91453325930746,3.591630687306421,5.692686701585921 +128,444.4735843873624,318.5837135172218,5.650865106238081,3.8098846947664695 +129,480.4945871932981,317.7789400812657,2.8473874205661946,3.2846798443123237 +130,480.34502455519726,313.1237155709503,2.8405711463483505,5.887133881466956 +131,479.84017942259044,319.58019508589905,2.5364142708665374,3.470339268830257 +132,480.860280231984,318.72555273736816,2.135649445640601,3.5691704658960353 +133,482.1126824365287,292.7236746644675,6.795795621748642,3.589777249851841 +134,60.57986058588791,298.3572263782008,2.0715574011265097,6.518875203291838 +135,60.46461499266122,295.5965103880334,2.4359457319030224,3.521159186195473 +136,59.50091999103519,298.34107118829087,2.338468862304903,3.0546922696738714 +137,101.38271621918946,296.483247325443,3.5173219751207268,4.497162712521202 +138,100.43332664554771,300.16356781590855,2.6915212734293545,4.145281353905138 +139,88.95536885340141,299.07746679015054,2.783698934533499,3.917152490131537 +140,100.29389089950519,299.8972675509202,2.566259282658186,4.137718806425782 +141,119.97612156854062,299.369658232651,2.8076039128455625,3.339917039106144 +142,119.21634890704448,298.4258068241335,3.1000278549881677,4.175736792274726 +143,112.26314328941838,302.0132035682278,4.497193147167675,4.627836503294436 +144,118.63154926153814,299.5090092566827,3.3112468547584886,2.82625813066952 +145,140.22829557703238,295.83589398019353,4.880610377957939,2.876734137897074 +146,143.96502880541922,295.45158153676647,4.250115873207735,3.0733240603225105 +147,140.66008917985863,295.75005128745903,4.893542903008491,3.138028915535486 +148,141.21893535376495,296.1533805219746,3.774408848238054,3.0467012666428333 +149,183.47872058961224,299.0180109809012,3.257615072049357,4.1723220562822725 +150,183.1202811035564,298.79425325159076,3.469002943022174,3.997120410978376 +151,183.2016789609457,298.4838438451825,3.1679502308294953,4.084970750698522 +152,183.56716590770395,298.3764936397965,3.3471833496481467,4.077681465171855 +153,190.41048704769,330.4978785855013,2.083041500838133,3.4668015126104454 +154,188.96675676778156,329.9036439013521,1.9931882571475936,3.508215161643373 +155,188.33490314035438,329.81417912235116,1.8728073653310773,3.0484929469157747 +156,188.31414516895805,330.23186734474723,1.8830058285338804,3.3131134887294613 +157,231.30258441852257,329.2869590111576,2.1015883812262706,2.7686520980654414 +158,635.9719402081547,323.45669801247647,3.890586665705017,3.4262788642164947 +159,231.58692741290457,329.78511421313885,2.073756648357063,3.6457128678010338 +160,251.94245026669623,329.3621392921355,3.4400207042718804,2.525297437969197 +161,275.38274900691636,330.6582764942376,2.7758194307457162,2.781269710685483 +162,288.16094061378243,329.96864420502334,1.7425792225683983,2.7891999383989616 +163,273.9343912983064,330.28517683915425,1.88697235808454,2.153903027764216 +164,277.40318080027276,331.32724722075693,2.51910988134524,2.2364789702215044 +165,294.8273106877241,330.7078842677868,2.0202421142551663,2.645341711239525 +166,317.03626643514605,330.57896380392424,1.9865816645763301,2.776754699862097 +167,314.93276908458336,330.67614347282944,2.6509184944650532,2.7861880759516926 +168,299.640483801822,330.68496013319924,2.1034251306897223,2.6995826605586095 +169,397.31504374955824,332.3446123671715,4.011960577043935,2.119261063102862 +170,396.5580357804531,331.5612694467712,2.1013176840578547,4.345997085530413 +171,397.49205012933754,332.4442253933989,4.083617010295474,2.083000027123604 +172,396.4373476151805,332.4498304809778,3.6443064475289324,1.9520773323350806 +173,172.71708638362486,155.60703919548823,3.073597315308788,4.401620808681049 +174,174.69066860790247,155.66811371703272,3.3201919365119563,4.524189384907778 +175,174.36012639095586,155.21688748228445,3.313966666920818,4.280738433967948 +176,174.27542002212184,155.33243945954135,3.4684361769046457,4.3256192119148285 +177,211.35953547851577,157.84363965463723,3.719577632132569,4.52395842333967 +178,215.49817946473246,157.8061035073585,3.420835243071113,5.204301731036066 +179,211.58080964064885,157.9196266744007,3.750774395208928,4.781345943827068 +180,212.21010780634873,157.82655078622685,3.0477176203472505,5.171003834767582 +181,261.951692200774,158.03145626439886,3.3820588588480125,4.517024497962329 +182,258.6077504340104,157.3952123759144,3.610545283020404,5.537995823967975 +183,261.9931127261629,156.844374467896,3.3582923289081412,4.203836335498702 +184,261.97037263466234,158.27263012263947,3.4440759214867183,3.5700855150119994 +185,303.22094845720875,155.75474871290248,3.4728086741188746,4.537460217001407 +186,281.81947814044815,157.07330827651708,2.3587900891205402,7.458771102609963 +187,296.79672730554864,156.66963976209618,2.4956604990337636,7.422350136504288 +188,300.202613978401,156.83041886564462,3.6244136435867715,2.652614592092425 +189,383.13489230058434,158.29028886500078,3.9437889097096543,4.109817373692409 +190,385.65899984883004,157.07389261777607,3.7243534642349445,3.3291912053378807 +191,385.5898403232217,158.93279796052937,3.5586432492433517,4.719422333593461 +192,383.2113575049479,157.78585537067738,3.864821842971764,4.094143758353614 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 200).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 200).txt new file mode 100644 index 0000000..06ac13b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 291.03499068467625, poly: 289.2972972972973, gaussian: 289.8178178178178; +y: edge_centroid: 250.59977810650898, poly: 256.96096096096096, gaussian: 216.0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 300).txt new file mode 100644 index 0000000..c66127c --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(100, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 291.03499068467625, poly: 289.2972972972973, gaussian: 289.8408408408408; +y: edge_centroid: -1, poly: 0, gaussian: 0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(120, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(120, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(490, 50).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_100_{0}/img_100_{0}_(490, 50).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_10_{0}/img_10_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_10_{0}/img_10_{0}_(240, 320).txt new file mode 100644 index 0000000..0aa7bd9 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_10_{0}/img_10_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 275.7147319104633, poly: 277.54654654654655, gaussian: 276.4354354354354; +y: edge_centroid: 218.90439189189192, poly: 219.87387387387386, gaussian: 219.96996996996998 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(100, 150).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(100, 150).txt new file mode 100644 index 0000000..5cc8360 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(100, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.0200477822787, poly: 474.4554554554555, gaussian: 475.0960960960961; +y: edge_centroid: 319.75075987841956, poly: 352.0, gaussian: 317.5045045045045 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(150, 200).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(150, 200).txt new file mode 100644 index 0000000..c181231 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(150, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 483.1316033979296, poly: 479.963963963964, gaussian: 472.96596596596595; +y: edge_centroid: 326.8176090597337, poly: 325.0900900900901, gaussian: 325.9259259259259 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(20, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(20, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 250).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 250).txt new file mode 100644 index 0000000..8e70bbf --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 324.4145637296835, poly: 318.4034034034034, gaussian: 328.4984984984985 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 300).txt new file mode 100644 index 0000000..0858c20 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 315.5961538461538, poly: 301.93293293293294, gaussian: 314.3693693693694 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 500).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 500).txt new file mode 100644 index 0000000..f65380f --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 307.213521344408, poly: 323.22522522522524, gaussian: 322.5015015015015 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(250, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(250, 300).txt new file mode 100644 index 0000000..41d732a --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(250, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.7974399164053, poly: 480.7717717717718, gaussian: 478.4754754754755; +y: edge_centroid: 315.5961538461538, poly: 301.93293293293294, gaussian: 314.3693693693694 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(30, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(30, 100).txt new file mode 100644 index 0000000..9a0a702 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(30, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7408469342743, poly: 474.3133133133133, gaussian: 475.96296296296293; +y: edge_centroid: 312.8755548978987, poly: 312.6666666666667, gaussian: 313.2162162162162 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 350).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 350).txt new file mode 100644 index 0000000..9fcb0bd --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 478.06332670022255, poly: 479.2022022022022, gaussian: 478.8808808808809; +y: edge_centroid: 315.1341000267452, poly: 314.23823823823824, gaussian: 347.0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 400).txt new file mode 100644 index 0000000..002895d --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 478.06332670022255, poly: 479.2022022022022, gaussian: 478.8808808808809; +y: edge_centroid: 310.42203052422025, poly: 313.1111111111111, gaussian: 312.4864864864865 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(350, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(350, 400).txt new file mode 100644 index 0000000..99ae642 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(350, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.5766195632225, poly: 479.4594594594595, gaussian: 477.3223223223223; +y: edge_centroid: 310.42203052422025, poly: 313.1111111111111, gaussian: 312.4864864864865 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(400, 450).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(400, 450).txt new file mode 100644 index 0000000..0101161 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(400, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 481.25031779661015, poly: 481.04804804804803, gaussian: 480.36036036036035; +y: edge_centroid: 320.51106920874355, poly: 322.13113113113116, gaussian: 321.7687687687688 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(450, 550).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(450, 550).txt new file mode 100644 index 0000000..f859e85 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(450, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 480.90588235294115, poly: 479.13613613613614, gaussian: 479.12312312312315; +y: edge_centroid: 316.68044077134977, poly: 313.73273273273276, gaussian: 315.5095095095095 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(50, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(50, 100).txt new file mode 100644 index 0000000..c0a15fe --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_130_{0}/img_130_{0}_(50, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 474.3070001323277, poly: 472.996996996997, gaussian: 472.81081081081084; +y: edge_centroid: 312.8755548978987, poly: 312.6666666666667, gaussian: 313.2162162162162 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 100).txt new file mode 100644 index 0000000..f2af609 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 277.76777028087247, poly: 281.1461461461461, gaussian: 278.5765765765766; +y: edge_centroid: 302.41199200532964, poly: 296.71771771771773, gaussian: 299.7837837837838 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 50).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 50).txt new file mode 100644 index 0000000..b79b4f9 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(250, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 277.76777028087247, poly: 281.1461461461461, gaussian: 278.5765765765766; +y: edge_centroid: 266.9218650877565, poly: 284.07207207207205, gaussian: 279.6546546546547 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(300, 550).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(300, 550).txt new file mode 100644 index 0000000..84b1934 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_133_{0}/img_133_{0}.png_(300, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 81.92717111682785, poly: 81.3933933933934, gaussian: 81.24724724724724; +y: edge_centroid: 289.13216374268995, poly: 286.6216216216216, gaussian: 288.1381381381381 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_134_{0}/img_134_{0}.png_(200, 150).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_134_{0}/img_134_{0}.png_(200, 150).txt new file mode 100644 index 0000000..0d980c5 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_134_{0}/img_134_{0}.png_(200, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 58.87142186766776, poly: 57.72372372372372, gaussian: 58.56256256256256; +y: edge_centroid: 298.5141452126122, poly: 298.53453453453454, gaussian: 299.05505505505505 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_13_{0}/img_13_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_13_{0}/img_13_{0}_(240, 320).txt new file mode 100644 index 0000000..f932d1e --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_13_{0}/img_13_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 52.44813278008298, poly: 53.77977977977978, gaussian: 53.35935935935936; +y: edge_centroid: 215.0489725113424, poly: 217.44444444444446, gaussian: 216.44444444444446 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_157_{0}/img_157_{0}.png_(250, 450).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_157_{0}/img_157_{0}.png_(250, 450).txt new file mode 100644 index 0000000..bc8985f --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_157_{0}/img_157_{0}.png_(250, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 231.9349172144786, poly: 229.16516516516518, gaussian: 230.4204204204204; +y: edge_centroid: 324.7964368509638, poly: 320.92092092092093, gaussian: 322.7027027027027 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(100, 500).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(100, 500).txt new file mode 100644 index 0000000..7b9d1b7 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(100, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 225.6382858488344, poly: 219.85385385385385, gaussian: 223.6846846846847; +y: edge_centroid: 326.9082845283447, poly: 329.64864864864865, gaussian: 329.45245245245246 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(300, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(300, 400).txt new file mode 100644 index 0000000..a009916 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 218.77561608300925, poly: 224.71471471471472, gaussian: 223.88388388388387; +y: edge_centroid: 325.48699770378875, poly: 323.76576576576576, gaussian: 321.72972972972974 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(350, 450).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(350, 450).txt new file mode 100644 index 0000000..7dca8cd --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_160_{0}/img_160_{0}_(350, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 221.86800998243837, poly: 223.86086086086087, gaussian: 222.33833833833833; +y: edge_centroid: 324.95901767558263, poly: 319.3243243243243, gaussian: 320.1621621621622 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 350).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 350).txt new file mode 100644 index 0000000..deecda3 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 392.6319532908705, poly: 390.93993993993996, gaussian: 391.22222222222223; +y: edge_centroid: 332.7505637119807, poly: 333.94494494494495, gaussian: 333.13613613613614 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 450).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 450).txt new file mode 100644 index 0000000..b69498b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_170_{0}/img_170_{0}_(200, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 392.6319532908705, poly: 390.93993993993996, gaussian: 391.22222222222223; +y: edge_centroid: 340.36645473811694, poly: 333.6066066066066, gaussian: 333.86686686686687 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(100, 150).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(100, 150).txt new file mode 100644 index 0000000..0564307 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(100, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 220.7910065139735, poly: 217.15515515515517, gaussian: 220.11711711711712; +y: edge_centroid: 160.24814595075648, poly: 158.1981981981982, gaussian: 155.2112112112112 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(150, 200).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(150, 200).txt new file mode 100644 index 0000000..1f815cd --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(150, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 226.56943727413525, poly: 233.0, gaussian: 231.61461461461462; +y: edge_centroid: -1, poly: 157.03003003003002, gaussian: 159.97997997998 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 250).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 250).txt new file mode 100644 index 0000000..7084079 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 224.38829323735553, poly: 221.4204204204204, gaussian: 222.997997997998; +y: edge_centroid: -1, poly: 136.21621621621622, gaussian: 153.43543543543544 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 50).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 50).txt new file mode 100644 index 0000000..751271c --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(200, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 224.38829323735553, poly: 221.4204204204204, gaussian: 222.997997997998; +y: edge_centroid: 159.31560235197594, poly: 147.12512512512512, gaussian: 138.0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(250, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(250, 300).txt new file mode 100644 index 0000000..e2f1dfc --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(250, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.60011869116025, poly: 215.4144144144144, gaussian: 201.0; +y: edge_centroid: 155.03382867757378, poly: 157.1791791791792, gaussian: 158.998998998999 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(300, 350).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(300, 350).txt new file mode 100644 index 0000000..238ae5c --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(300, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.2786542650262, poly: 231.36236236236238, gaussian: 224.34534534534535; +y: edge_centroid: -1, poly: 139.21621621621622, gaussian: 139.81581581581582 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(350, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(350, 400).txt new file mode 100644 index 0000000..c508eef --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(350, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 218.11615628299896, poly: 221.07207207207207, gaussian: 219.3013013013013; +y: edge_centroid: 155.50516848445383, poly: 152.59459459459458, gaussian: 152.37137137137137 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(400, 450).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(400, 450).txt new file mode 100644 index 0000000..4c33dde --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(400, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.5702052689802, poly: 220.84284284284286, gaussian: 200.0; +y: edge_centroid: 148.5988915951851, poly: 134.5095095095095, gaussian: 135.5895895895896 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(50, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(50, 100).txt new file mode 100644 index 0000000..45a7482 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_180_{0}/img_180_{0}_(50, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 225.69889181411875, poly: 219.86186186186185, gaussian: 228.002002002002; +y: edge_centroid: 156.60606647930996, poly: 154.3803803803804, gaussian: 151.83083083083082 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_19_3/img_19_3_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_19_3/img_19_3_(240, 320).txt new file mode 100644 index 0000000..5d569df --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_19_3/img_19_3_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 354.17105263157896; +y: zero_crossing: 264.9651162790698, edge_converge: 252.34375 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 355.72727272727275, edge_converge: 353.32894736842104; +y: zero_crossing: 265.5, edge_converge: 269.3763586956522 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 355.76190476190476, edge_converge: 349.5; +y: zero_crossing: 265.5, edge_converge: 239.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 356.1034482758621, edge_converge: 371.0; +y: zero_crossing: 265.37254901960785, edge_converge: 300.0 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 346.65625; +y: zero_crossing: 265.4313725490196, edge_converge: 238.5 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 356.40625, edge_converge: 422.36538461538464; +y: zero_crossing: 265.40845070422534, edge_converge: 294.36538461538464 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 356.3095238095238, edge_converge: 256.4673913043478; +y: zero_crossing: 265.37254901960785, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 356.09375, edge_converge: 317.0; +y: zero_crossing: 265.3333333333333, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_19_{0}/img_19_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_19_{0}/img_19_{0}_(240, 320).txt new file mode 100644 index 0000000..84c72a9 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_19_{0}/img_19_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 356.46369710467707, poly: 356.40440440440443, gaussian: 356.67667667667666; +y: edge_centroid: 264.30495510475555, poly: 263.84384384384384, gaussian: 264.1141141141141 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_1_1/img_1_1_(600, 960).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_1_1/img_1_1_(600, 960).txt new file mode 100644 index 0000000..1495c39 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_1_1/img_1_1_(600, 960).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1033.5062801932368; +y: zero_crossing: -1, edge_converge: 671.6582417582417 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 285.5, edge_converge: 286.10200668896323; +y: zero_crossing: -1, edge_converge: -1 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 285.5, edge_converge: 276.20913461538464; +y: zero_crossing: -1, edge_converge: 771.828947368421 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 278.8111413043478; +y: zero_crossing: -1, edge_converge: 607.5 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 285.5, edge_converge: 284.02163461538464; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 284.5, edge_converge: 279.5; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 283.8615560640732; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 306.5; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(240, 320).txt new file mode 100644 index 0000000..d00a799 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 383.30516277540283, poly: 383.17317317317315, gaussian: 383.2852852852853; +y: edge_centroid: 129.78768233387356, poly: 129.64064064064064, gaussian: 129.4164164164164 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(600, 960).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(600, 960).txt new file mode 100644 index 0000000..1df54e1 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_1_{0}/img_1_{0}_(600, 960).txt @@ -0,0 +1,6 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 282.80022496724126; +y: zero_crossing: -1, edge_converge: -1 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 277.11846281807; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_20_1/img_20_1_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_20_1/img_20_1_(240, 320).txt new file mode 100644 index 0000000..7f8ccc7 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_20_1/img_20_1_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 225.33333333333334, edge_converge: 222.40969899665552; +y: zero_crossing: 222.44086021505376, edge_converge: 232.5 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 224.90625, edge_converge: 212.425; +y: zero_crossing: 222.7012987012987, edge_converge: 244.8653846153846 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 224.55172413793105, edge_converge: 225.7096153846154; +y: zero_crossing: 222.8507462686567, edge_converge: 233.3653846153846 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 224.86363636363637, edge_converge: 207.6159420289855; +y: zero_crossing: 223.22413793103448, edge_converge: 215.5216346153846 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.37254901960785, edge_converge: 238.5 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: -1; +y: zero_crossing: 223.33333333333334, edge_converge: 309.4673913043478 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 220.5; +y: zero_crossing: 223.46341463414635, edge_converge: 210.0 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 224.56521739130434, edge_converge: -1; +y: zero_crossing: 223.57894736842104, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_20_1/img_20_1_(900, 1400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_20_1/img_20_1_(900, 1400).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(200, 500).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(200, 500).txt new file mode 100644 index 0000000..b5bbd3d --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(200, 500).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1178.6311475409836; +y: zero_crossing: -1, edge_converge: 376.4716202270382 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 635.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1582.0; +y: zero_crossing: -1, edge_converge: 723.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1682.4423076923076; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 72.5, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 600.4166666666666 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(400, 700).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(400, 700).txt new file mode 100644 index 0000000..5799b85 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(400, 700).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1114.8653846153848; +y: zero_crossing: -1, edge_converge: 920.8071348940914 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 1120.671052631579; +y: zero_crossing: -1, edge_converge: 604.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 886.5258620689655; +y: zero_crossing: -1, edge_converge: 614.671052631579 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 847.671052631579; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 1025.9558823529412 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 94.1875, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(600, 960).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(600, 960).txt new file mode 100644 index 0000000..9b33d97 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(600, 960).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 316.76911544227886; +y: zero_crossing: -1, edge_converge: 646.7335664335665 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 360.91666666666663; +y: zero_crossing: -1, edge_converge: 910.05625 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 919.5; +y: zero_crossing: -1, edge_converge: 568.328947368421 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 422.0326086956522; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 782.0326086956521; +y: zero_crossing: -1, edge_converge: 1111.5 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 231.65625; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(800, 900).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(800, 900).txt new file mode 100644 index 0000000..85e0c4d --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(800, 900).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 94.49201474201475; +y: zero_crossing: -1, edge_converge: 612.9423076923077 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 97.05847076461768; +y: zero_crossing: -1, edge_converge: 615.672697368421 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 95.59030100334448; +y: zero_crossing: -1, edge_converge: 626.328947368421 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 96.23076923076923, edge_converge: 104.08333333333333; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 72.65625; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 105.76923076923077, edge_converge: 135.17105263157896; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 106.5, edge_converge: 264.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 1700).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 1700).txt new file mode 100644 index 0000000..51550d1 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 1700).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 992.733709273183; +y: zero_crossing: -1, edge_converge: 779.3782051282051 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 968.26875; +y: zero_crossing: -1, edge_converge: -1 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 953.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 198.43478260869566, edge_converge: 189.65625; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 197.5, edge_converge: 207.5; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 200.55172413793105, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 207.40969899665552; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 900).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 900).txt new file mode 100644 index 0000000..4e5269e --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_1/img_2_1_(900, 900).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 992.733709273183; +y: zero_crossing: -1, edge_converge: 612.9423076923077 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 968.26875; +y: zero_crossing: -1, edge_converge: 615.672697368421 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 953.0; +y: zero_crossing: -1, edge_converge: 626.328947368421 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 198.43478260869566, edge_converge: 189.65625; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 197.5, edge_converge: 207.5; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 200.55172413793105, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 207.40969899665552; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_4/img_2_4_(1400, 900).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_4/img_2_4_(1400, 900).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_4/img_2_4_(600, 960).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_4/img_2_4_(600, 960).txt new file mode 100644 index 0000000..725c811 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_4/img_2_4_(600, 960).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1100.8305555555555; +y: zero_crossing: 468.88853503184714, edge_converge: 468.9624718174986 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 1284.6410256410256; +y: zero_crossing: -1, edge_converge: 472.02868852459017 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1086.828947368421; +y: zero_crossing: 468.9056603773585, edge_converge: 469.513210927004 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1086.6; +y: zero_crossing: -1, edge_converge: 526.828947368421 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 1092.3333333333333, edge_converge: 1189.2003676470588; +y: zero_crossing: -1, edge_converge: 445.3327759197324 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 1092.157894736842, edge_converge: 1190.0; +y: zero_crossing: -1, edge_converge: 439.0 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1046.8653846153848; +y: zero_crossing: -1, edge_converge: 503.0326086956522 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 1072.84375; +y: zero_crossing: -1, edge_converge: 517.84375 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_4/img_2_4_(900, 1400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_4/img_2_4_(900, 1400).txt new file mode 100644 index 0000000..b979bb5 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_4/img_2_4_(900, 1400).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1296.632183836245; +y: zero_crossing: -1, edge_converge: 683.452135931303 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 1295.6363633216238; +y: zero_crossing: 690.1150168914178, edge_converge: 693.2398839220738 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1295.3653844696842; +y: zero_crossing: -1, edge_converge: 693.9883644021885 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1278.906249850798; +y: zero_crossing: 688.6590191104578, edge_converge: 700.2655993429721 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 1174.4999998716144; +y: zero_crossing: -1, edge_converge: 964.4428415672992 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 1161.4999997817608; +y: zero_crossing: -1, edge_converge: 940.947694754178 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1160.9999998929734; +y: zero_crossing: -1, edge_converge: 941.7896120081671 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 1186.0000001232456, edge_converge: 1174.4999996450306; +y: zero_crossing: -1, edge_converge: 962.456256071665 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_5/img_2_5_(600, 960).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_5/img_2_5_(600, 960).txt new file mode 100644 index 0000000..d1de3a8 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_5/img_2_5_(600, 960).txt @@ -0,0 +1,21 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: 1158.301886792453, edge_converge: 1158.0; +y: zero_crossing: 423.6167664670659, edge_converge: 425.51180555555555 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 1158.3440860215053, edge_converge: 1166.740170940171; +y: zero_crossing: -1, edge_converge: 385.2810276679842 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 1158.134328358209, edge_converge: 1188.467391304348; +y: zero_crossing: -1, edge_converge: 326.3781954887218 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 1158.2131147540983, edge_converge: 1194.753947368421; +y: zero_crossing: 423.44827586206895, edge_converge: 374.91666666666663 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 1170.5; +y: zero_crossing: 423.1578947368421, edge_converge: 351.5 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1255.0; +y: zero_crossing: -1, edge_converge: 700.0326086956521 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 1218.532608695652; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(240, 320).txt new file mode 100644 index 0000000..d77b164 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 383.569200132758, poly: 382.83083083083085, gaussian: 383.4114114114114; +y: edge_centroid: 128.77362969356932, poly: 129.4084084084084, gaussian: 129.21021021021022 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(600, 960).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(600, 960).txt new file mode 100644 index 0000000..d22680c --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_2_{0}/img_2_{0}_(600, 960).txt @@ -0,0 +1 @@ +ksize:(7, 7), sigmax:0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_3_3/img_3_3_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_3/img_3_3_(240, 320).txt new file mode 100644 index 0000000..15cad33 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_3/img_3_3_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 388.0; +y: zero_crossing: 129.02597402597402, edge_converge: 125.57692307692308 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 384.1578947368421, edge_converge: 389.5364372469636; +y: zero_crossing: 129.47297297297297, edge_converge: 129.40969899665552 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 384.23809523809524, edge_converge: 371.13461538461536; +y: zero_crossing: 129.62337662337663, edge_converge: 129.21517027863777 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 401.32894736842104; +y: zero_crossing: 129.66666666666666, edge_converge: 199.6346153846154 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 405.3327759197324; +y: zero_crossing: 129.72916666666666, edge_converge: 123.56414473684211 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 129.60416666666666, edge_converge: 125.0 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 383.8421052631579, edge_converge: -1; +y: zero_crossing: 129.5, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 383.59375, edge_converge: -1; +y: zero_crossing: 129.46341463414635, edge_converge: 105.46739130434783 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_3_3/img_3_3_new_(600, 960).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_3/img_3_3_new_(600, 960).txt new file mode 100644 index 0000000..85506ff --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_3/img_3_3_new_(600, 960).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 627.2624342255776; +y: zero_crossing: 282.9597701149425, edge_converge: 280.3083778966132 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 626.3650177462289; +y: zero_crossing: -1, edge_converge: 283.4423076923077 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 608.9765275707898; +y: zero_crossing: 287.3333333333333, edge_converge: 284.86538461538464 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 650.8565573770492; +y: zero_crossing: -1, edge_converge: 296.0326086956522 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 652.203125; +y: zero_crossing: -1, edge_converge: 689.3056680161943 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 659.8423913043478; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 631.6904761904761, edge_converge: 597.0326086956522; +y: zero_crossing: -1, edge_converge: 683.5 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 645.0; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(240, 320).txt new file mode 100644 index 0000000..056b176 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 383.6794588625068, poly: 383.2082082082082, gaussian: 383.5855855855856; +y: edge_centroid: 128.72770467836258, poly: 129.44144144144144, gaussian: 129.17717717717719 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(300, 573).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(300, 573).txt new file mode 100644 index 0000000..6a9be15 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(300, 573).txt @@ -0,0 +1,21 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 551.1085016945578; +y: zero_crossing: -1, edge_converge: 401.2614005098476 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 551.0790923034685; +y: zero_crossing: -1, edge_converge: 401.1959898455841 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 551.3164486248141; +y: zero_crossing: -1, edge_converge: 396.65866001765227 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 553.6140783045154; +y: zero_crossing: 385.44129158264957, edge_converge: 391.39592471066015 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 554.2854352720954, edge_converge: 553.3228366624788; +y: zero_crossing: 385.28612080628454, edge_converge: 391.30816089061875 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 554.0283816103325, edge_converge: 552.9026715626205; +y: zero_crossing: 385.12690508006284, edge_converge: 391.2389474584604 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 553.7215989908605, edge_converge: 552.4769129699359; +y: zero_crossing: 384.9703803392806, edge_converge: 391.0686695466003 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(600, 960).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(600, 960).txt new file mode 100644 index 0000000..eebe206 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_3_{0}/img_3_{0}_(600, 960).txt @@ -0,0 +1,6 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 629.1857205127992; +y: zero_crossing: -1, edge_converge: 303.2178917674522 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 626.2193034291377; +y: zero_crossing: -1, edge_converge: 279.055693080456 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_4_1/img_4_1_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_4_1/img_4_1_(240, 320).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_4_1/img_4_1_(500, 1200).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_4_1/img_4_1_(500, 1200).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_4_{0}/img_4_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_4_{0}/img_4_{0}_(240, 320).txt new file mode 100644 index 0000000..7808d12 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_4_{0}/img_4_{0}_(240, 320).txt @@ -0,0 +1,6 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: 236.92774193101968, edge_converge: 237.5228648141686; +y: zero_crossing: 325.7458333221428, edge_converge: 321.11252693875815 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 237.21044902427207, edge_converge: 234.45920213005442; +y: zero_crossing: 325.6826399612562, edge_converge: 321.13169019760346 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(200, 50).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(200, 50).txt new file mode 100644 index 0000000..cb9440f --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(200, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 93.01701701701703, gaussian: 92.54954954954955; +y: edge_centroid: 220.67972613160907, poly: 205.44544544544544, gaussian: 220.13513513513513 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 100).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 150).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 150).txt new file mode 100644 index 0000000..4e7e731 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 207.25707213578505, poly: 211.72972972972974, gaussian: 210.05605605605606 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 250).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 250).txt new file mode 100644 index 0000000..0b0c80e --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 218.612658674189, poly: 210.37037037037038, gaussian: 216.64864864864865 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 550).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 550).txt new file mode 100644 index 0000000..5d716b8 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(250, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 208.3091801113311, poly: 194.96096096096096, gaussian: 207.03603603603602 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(300, 500).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(300, 500).txt new file mode 100644 index 0000000..7669241 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}.png_(300, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.85585585585585, gaussian: 94.37537537537537; +y: edge_centroid: 211.19331646152077, poly: 195.86786786786786, gaussian: 209.42642642642642 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 10).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 10).txt new file mode 100644 index 0000000..c7c4711 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 10).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.53349610865254, poly: 90.78078078078079, gaussian: 90.11711711711712; +y: edge_centroid: 221.0741458686698, poly: 244.62762762762765, gaussian: 258.0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 400).txt new file mode 100644 index 0000000..e9008a5 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(100, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.53349610865254, poly: 92.03003003003003, gaussian: 92.93793793793793; +y: edge_centroid: 214.17900156837212, poly: 209.03203203203202, gaussian: 214.83483483483485 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 100).txt new file mode 100644 index 0000000..34f75b7 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64864864864865; +y: edge_centroid: -1, poly: 196.7027027027027, gaussian: 220.20220220220222 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 300).txt new file mode 100644 index 0000000..b1e658b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 215.8282069593912, poly: 200.8108108108108, gaussian: 203.97297297297297 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 350).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 350).txt new file mode 100644 index 0000000..ae51c4c --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 215.93902685241267, poly: 199.14814814814815, gaussian: 201.96296296296296 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 40).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 40).txt new file mode 100644 index 0000000..35d04b6 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 40).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 213.46588200238375, poly: 187.52852852852854, gaussian: 250.0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 400).txt new file mode 100644 index 0000000..dd9188e --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 93.01701701701703, gaussian: 92.54954954954955; +y: edge_centroid: 214.17900156837212, poly: 209.03203203203202, gaussian: 214.83483483483485 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(240, 320).txt new file mode 100644 index 0000000..beaeadc --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.95545171339562, poly: 92.43843843843844, gaussian: 92.54054054054055; +y: edge_centroid: 216.32595947660937, poly: 197.66066066066065, gaussian: 203.43843843843842 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(250, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(250, 100).txt new file mode 100644 index 0000000..d73fc36 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(250, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: -1, poly: 198.59459459459458, gaussian: 236.03003003003005 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(30, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(30, 300).txt new file mode 100644 index 0000000..8c9068f --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(30, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 106.90241734802697, poly: 130.08608608608608, gaussian: 137.0; +y: edge_centroid: 215.8282069593912, poly: 200.8108108108108, gaussian: 203.94794794794794 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 150).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 150).txt new file mode 100644 index 0000000..00f639b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.85585585585585, gaussian: 94.37537537537537; +y: edge_centroid: 207.25707213578505, poly: 211.72972972972974, gaussian: 210.05605605605606 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 400).txt new file mode 100644 index 0000000..07a7d5e --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.72372372372372, gaussian: 94.26126126126127; +y: edge_centroid: 214.17900156837212, poly: 194.24424424424424, gaussian: 197.8028028028028 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(350, 200).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(350, 200).txt new file mode 100644 index 0000000..031f3ef --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(350, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30997090716743, poly: 92.7907907907908, gaussian: 93.55555555555556; +y: edge_centroid: 219.13322627053438, poly: 210.43043043043042, gaussian: 218.1951951951952 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(400, 250).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(400, 250).txt new file mode 100644 index 0000000..525a96e --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(400, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.80265120132562, poly: 93.7977977977978, gaussian: 93.90190190190191; +y: edge_centroid: 218.612658674189, poly: 210.37037037037038, gaussian: 216.64864864864865 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(450, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(450, 300).txt new file mode 100644 index 0000000..013cc84 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(450, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.75074524191695, poly: 94.30530530530531, gaussian: 94.26426426426427; +y: edge_centroid: 215.8282069593912, poly: 211.35135135135135, gaussian: 215.15915915915917 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(50, 550).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(50, 550).txt new file mode 100644 index 0000000..7db67f4 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_59_{0}/img_59_{0}_(50, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.89583756345176, poly: 92.57657657657657, gaussian: 92.48648648648648; +y: edge_centroid: 208.3091801113311, poly: 189.6096096096096, gaussian: 209.03303303303304 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_5_1/img_5_1_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_5_1/img_5_1_(240, 320).txt new file mode 100644 index 0000000..aed0952 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_5_1/img_5_1_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 556.6842105263158, edge_converge: -1; +y: zero_crossing: 301.9344262295082, edge_converge: 308.5 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 555.8125, edge_converge: -1; +y: zero_crossing: 301.94444444444446, edge_converge: 301.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 555.4347826086956, edge_converge: -1; +y: zero_crossing: 301.84375, edge_converge: 293.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 555.5, edge_converge: -1; +y: zero_crossing: 301.75, edge_converge: 318.4673913043478 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 555.5, edge_converge: -1; +y: zero_crossing: 301.6862745098039, edge_converge: 280.9673913043478 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 446.17105263157896; +y: zero_crossing: 301.7291666666667, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 301.7291666666667, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 301.6666666666667, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_5_1/img_5_1_(900, 1400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_5_1/img_5_1_(900, 1400).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_5_{0}/img_5_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_5_{0}/img_5_{0}_(240, 320).txt new file mode 100644 index 0000000..65e1696 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_5_{0}/img_5_{0}_(240, 320).txt @@ -0,0 +1,21 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: 555.6464323051268, edge_converge: 568.4630895970322; +y: zero_crossing: 302.34291829038295, edge_converge: 304.5181313275549 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 555.4526325366787, edge_converge: 566.8934642695242; +y: zero_crossing: 302.34965401891816, edge_converge: 304.4386691292941 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 555.2960595115023, edge_converge: 563.5356471927093; +y: zero_crossing: 302.33803803307313, edge_converge: 304.27810760651005 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 555.1849293811231, edge_converge: 563.5416332228492; +y: zero_crossing: 302.3176065339906, edge_converge: 300.31359690803674 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 555.1016003888399, edge_converge: 563.6004921726214; +y: zero_crossing: 302.29189598827344, edge_converge: 300.16238390552815 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 555.0360469257112, edge_converge: 563.6160702558284; +y: zero_crossing: 302.26525876715635, edge_converge: 296.30288208863885 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 554.9834021944725, edge_converge: 554.5573053432411; +y: zero_crossing: 302.24049538378574, edge_converge: 308.2023326126082 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}.png_(200, 600).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}.png_(200, 600).txt new file mode 100644 index 0000000..ed07d5f --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}.png_(200, 600).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.32846573208725, poly: 92.23423423423424, gaussian: 92.21921921921921; +y: edge_centroid: 196.4742684157417, poly: 195.8928928928929, gaussian: 196.3783783783784 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(200, 500).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(200, 500).txt new file mode 100644 index 0000000..a483322 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.32846573208725, poly: 92.03003003003003, gaussian: 92.08708708708708; +y: edge_centroid: 210.0317535296279, poly: 189.0990990990991, gaussian: 212.75375375375376 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(240, 320).txt new file mode 100644 index 0000000..302af08 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.0877174261018, poly: 92.41741741741741, gaussian: 92.28528528528528; +y: edge_centroid: 221.40502732240432, poly: 205.07807807807808, gaussian: 206.8998998998999 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 100).txt new file mode 100644 index 0000000..b340acb --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30595634480204, poly: 94.14414414414415, gaussian: 93.81681681681681; +y: edge_centroid: 307.8291557805356, poly: 354.0, gaussian: 308.5155155155155 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 400).txt new file mode 100644 index 0000000..461ddb4 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_60_{0}/img_60_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30595634480204, poly: 94.14414414414415, gaussian: 93.81681681681681; +y: edge_centroid: 212.21240264432728, poly: 190.33833833833833, gaussian: 193.35135135135135 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(240, 320).txt new file mode 100644 index 0000000..750c5f3 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.9518581931715, poly: 92.18618618618618, gaussian: 91.98798798798799; +y: edge_centroid: 218.40512573697507, poly: 201.44444444444446, gaussian: 206.24924924924926 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(400, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(400, 400).txt new file mode 100644 index 0000000..7978897 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_61_{0}/img_61_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.19376913380157, poly: 94.17417417417417, gaussian: 94.03603603603604; +y: edge_centroid: 212.52264302981456, poly: 190.97897897897897, gaussian: 194.45845845845847 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_62_{0}/img_62_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_62_{0}/img_62_{0}_(240, 320).txt new file mode 100644 index 0000000..d58a228 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_62_{0}/img_62_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 178.91803535934721, poly: 178.44144144144144, gaussian: 178.33333333333334; +y: edge_centroid: -1, poly: 184.47747747747746, gaussian: 265.93293293293294 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_63_{0}/img_63_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_63_{0}/img_63_{0}_(240, 320).txt new file mode 100644 index 0000000..52cbf69 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_63_{0}/img_63_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 178.97878718007834, poly: 178.87387387387386, gaussian: 178.72972972972974; +y: edge_centroid: -1, poly: 182.97297297297297, gaussian: 227.4954954954955 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_6_{0}/img_6_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_6_{0}/img_6_{0}_(240, 320).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_73_{0}/img_73_{0}_(400, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_73_{0}/img_73_{0}_(400, 400).txt new file mode 100644 index 0000000..3c97a4b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_73_{0}/img_73_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 283.485064401206, poly: 323.0, gaussian: 286.4864864864865; +y: edge_centroid: 195.9362609551483, poly: 189.6016016016016, gaussian: 190.22222222222223 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(100, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(100, 300).txt new file mode 100644 index 0000000..462740a --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(100, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 278.09682467236087, poly: 268.2682682682683, gaussian: 274.5575575575576; +y: edge_centroid: 174.44361763022326, poly: 175.0990990990991, gaussian: 174.0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(150, 350).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(150, 350).txt new file mode 100644 index 0000000..3abe0ab --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(150, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 264.6934011476264, poly: 267.4674674674675, gaussian: 265.3213213213213; +y: edge_centroid: 212.65002063557583, poly: 193.16216216216216, gaussian: 205.15315315315314 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 100).txt new file mode 100644 index 0000000..ec7eba6 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 299.2048811389324, poly: 298.0, gaussian: 299.0900900900901; +y: edge_centroid: 212.06545603775513, poly: 211.82282282282281, gaussian: 212.06006006006007 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 400).txt new file mode 100644 index 0000000..0fc7e6b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 299.2048811389324, poly: 298.0, gaussian: 299.0900900900901; +y: edge_centroid: 216.82302078726215, poly: 193.26126126126127, gaussian: 186.53453453453454 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(250, 150).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(250, 150).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(250, 450).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_74_{0}/img_74_{0}_(250, 450).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_78_{0}/img_78_{0}_(400, 260).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_78_{0}/img_78_{0}_(400, 260).txt new file mode 100644 index 0000000..6892c16 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_78_{0}/img_78_{0}_(400, 260).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 366.0705646776132, poly: 403.0, gaussian: 402.0; +y: edge_centroid: 206.59396835595538, poly: 198.7157157157157, gaussian: 201.34434434434434 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(100, 200).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(100, 200).txt new file mode 100644 index 0000000..de27310 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(100, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 361.17140024783157, poly: 351.23423423423424, gaussian: 355.06006006006004; +y: edge_centroid: 206.05061553818015, poly: 197.32232232232232, gaussian: 204.25025025025025 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(200, 200).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_79_{0}/img_79_{0}_(200, 200).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_7_{0}/img_7_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_7_{0}/img_7_{0}_(240, 320).txt new file mode 100644 index 0000000..43ad63f --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_7_{0}/img_7_{0}_(240, 320).txt @@ -0,0 +1,21 @@ +ksize:(7, 7), sigmax:0 +x: zero_crossing: 157.8389116826965, edge_converge: 158.45130962399327; +y: zero_crossing: -1, edge_converge: 411.79259030140565 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 157.75410480327545, edge_converge: 158.32429639754088; +y: zero_crossing: -1, edge_converge: 411.6718763916268 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 157.7245284134464, edge_converge: 155.54913028965618; +y: zero_crossing: -1, edge_converge: 411.593647090896 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 157.76000829765138, edge_converge: 158.15343806061153; +y: zero_crossing: -1, edge_converge: 411.5797965685118 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 157.83060827808885, edge_converge: 157.98016047257528; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 157.90853193451255, edge_converge: 157.6948902708295; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 157.98721999268648, edge_converge: 157.47066779723983; +y: zero_crossing: -1, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(200, 300).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(200, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(300, 280).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(300, 280).txt new file mode 100644 index 0000000..5df82f5 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_80_{0}/img_80_{0}_(300, 280).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 311.3298049296839, poly: 319.7637637637638, gaussian: 319.5735735735736; +y: edge_centroid: -1, poly: 0, gaussian: 0 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(150, 100).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(150, 100).txt new file mode 100644 index 0000000..639b64b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(150, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 122.42161046111492, poly: 124.84684684684684, gaussian: 124.58358358358359; +y: edge_centroid: 268.99951226309923, poly: 263.5865865865866, gaussian: 263.9189189189189 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(200, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(200, 400).txt new file mode 100644 index 0000000..34cfc9d --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_86_{0}/img_86_{0}.png_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 326.7772293517605, poly: 326.3703703703704, gaussian: 326.84684684684686; +y: edge_centroid: 247.36609869795853, poly: 246.3783783783784, gaussian: 244.63563563563565 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_97_{0}/img_97_{0}_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_97_{0}/img_97_{0}_(240, 320).txt new file mode 100644 index 0000000..5d771cc --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_97_{0}/img_97_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 249.44900531810134, poly: 248.6956956956957, gaussian: 249.67667667667666; +y: edge_centroid: 259.66796296933614, poly: 261.015015015015, gaussian: 261.4074074074074 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(200, 500).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(200, 500).txt new file mode 100644 index 0000000..653e98a --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 248.7235796541028, poly: 252.58858858858858, gaussian: 249.82882882882882; +y: edge_centroid: 262.84957891453524, poly: 258.80680680680683, gaussian: 260.3963963963964 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(373, 234).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(373, 234).txt new file mode 100644 index 0000000..550694b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(373, 234).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 246.9395417318486, poly: 256.96296296296293, gaussian: 253.03203203203202; +y: edge_centroid: 280.6590576754352, poly: 258.1631631631632, gaussian: 257.65765765765764 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(400, 400).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(400, 400).txt new file mode 100644 index 0000000..ceb5b0e --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_99_{0}/img_99_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 263.7749063060128, poly: 262.6166166166166, gaussian: 263.40440440440443; +y: edge_centroid: 255.54966073622904, poly: 253.15915915915917, gaussian: 254.85185185185185 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/img_9_1/img_9_1_(240, 320).txt b/Nov_27/Manual/Camera/img_rec_module/meas/img_9_1/img_9_1_(240, 320).txt new file mode 100644 index 0000000..501f1b1 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/img_9_1/img_9_1_(240, 320).txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 243.84375; +y: zero_crossing: 211.51459854014598, edge_converge: 204.6346153846154 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 241.55172413793105, edge_converge: 250.5; +y: zero_crossing: 211.45945945945945, edge_converge: 205.6346153846154 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 241.59375, edge_converge: 243.8653846153846; +y: zero_crossing: 211.30208333333334, edge_converge: 233.08333333333334 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 241.76190476190476, edge_converge: 252.2848297213622; +y: zero_crossing: -1, edge_converge: 145.15625 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 241.86363636363637, edge_converge: 252.4673913043478; +y: zero_crossing: 210.77586206896552, edge_converge: 218.0 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 252.5; +y: zero_crossing: 210.64814814814815, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 241.63888888888889, edge_converge: 217.0; +y: zero_crossing: 210.5, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 249.52586206896552; +y: zero_crossing: 210.52727272727273, edge_converge: -1 diff --git a/Nov_27/Manual/Camera/img_rec_module/meas/truth.txt b/Nov_27/Manual/Camera/img_rec_module/meas/truth.txt new file mode 100644 index 0000000..dcf364f --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/meas/truth.txt @@ -0,0 +1,32 @@ +new_test +img_4 237, 325 + +calib +img_29 140, 203 + +testpic +img_1 385, 130 E: (2, 1) +img_2 385, 130 E: (2, 1) +img_3 385, 130 E: (2, 1) +img_4 -2, -2 175, 113 E: (4, 7) (DATA) +img_5 176, 52 E: (1, 3) +img_6 174, -1 E: (1, 0) +img_7 158, -1 E: (0, 0) +img_8 -2, -2 159, -1 E: (F, 0) (DATA) +img_9 242, 212 E: (0, 2) +img_10 278, 215 E: (1, 3) +img_11 -2, -2 325, 218 E: (1, 4) (DATA) +img_12 143, 215 E: (0, 1) +img_13 53, 219 E: (0, 4) +img_14 -1, 17 E: (0, 0) +img_15 138, 19 E: (0, 0) +img_16 355, 14 E: (1, 0) +img_17 288, -1 E: (1, 0) +img_18 369, 180 E: (1, 0) +img_19 357, 265 E: (0, 1) +img_20 225, 224 E: (3, 1) +img_21 41, 224 E: (0, 1) +img_22 -1, 59 E: (0, 3) +img_23 -2, -2 -1, -1 E: (0, T) (DATA) +img_24 -1, 160 E: (0, 1) +img_25 445, 166 E: (2, 4) diff --git a/Nov_27/Manual/Camera/img_rec_module/sig_proc.py b/Nov_27/Manual/Camera/img_rec_module/sig_proc.py new file mode 100644 index 0000000..9640c3b --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/sig_proc.py @@ -0,0 +1,958 @@ +import cv2 +import numpy as np +import csv +from scipy.optimize import curve_fit +from math import atan, sqrt, tan, radians, acos, asin, degrees, sin, cos + +""" =================================== +========== ANALYTIC GEOMETRY ========== +======================================= """ + + +class Line: + inf = float('inf') + + def __init__(self, a=inf, b=inf, p1=None, p2=None, data=None): + if p1 and p2: + self.point(p1, p2) + elif data: + self.reg(data) + else: + self.a = a + self.b = b + + def reg(self, data): + D = np.array([[d[0], 1] for d in data]) + y = np.array([d[1] for d in data]) + self.a, self.b = leastSquares(D, y) + + def point(self, p1, p2): + self.a = 1 + + @staticmethod + def intersect(l1, l2): + x = (l2.b - l1.b) / (l1.a - l2.a) + y = l1.a * x + l1.b + return x, y + + +class HoughLine: + def __init__(self, rho_rad=0, theta=0, x=None, data=None): + if data is not None and x is not None: + self.reg(x, data) + else: + self._r = degrees(rho_rad) + self._t = theta + self._s = sin(rho_rad) + self._c = cos(rho_rad) + + def reg(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + x1, x2 = x[0], x[-1] + y1, y2 = data[0], data[-1] + theta0 = theta_pred(x1, y1, x2, y2) + # print(degrees(theta0)) + p0 = [theta0, x1 * cos(theta0) + y1 * sin(theta0)] + pm, vm = curve_fit(hough_line, x, data, p0=p0) + # data_pred = hough_line(x, *pm) + # print('PRED', data_pred) + # res = data_pred - data + # print("RES", res) + # stderr = np.linalg.norm(res, 2) + # print("ERR", stderr) + # rankerr = res / stderr + # print("Z", rankerr) + if pm[1] < 0: + pm[1] = -pm[1] + pm[0] -= HC + # pm[0] = 2 * np.pi + angle = normalize_angle(pm[0]) + self._t = angle + self._r = pm[1] + self._s = sin(angle) + self._c = cos(angle) + + def extract_points(self, x_input): + x1 = int(x_input[0]) + x2 = int(x_input[-1]) + y1 = int(self.fit_x(x1)) + y2 = int(self.fit_x(x2)) + return (x1, y1), (x2, y2) + + def fit_x(self, x): + # print(self._r, self._t) + return (self._r - x * self._c) / self._s + + def __str__(self): + return 'hough line with cos:{0}, sin:{1}, rho:{2}, theta:{3}'.format(self._c, self._s, + self._r, degrees(self._t)) + + @staticmethod + def intersect(l1, l2): + x = (l2._r / l2._s - l1._r / l1._s) / (l2._c / l2._s - l1._c / l1._s) + y = l1.fit_x(x) + return x, y + + +# QC: QUARTER_CYCLE, HC: HALF_CYCLE, TQC: THIRD_QUARTER_CYCLE, FC: FULL_CYCLE +QC = np.pi / 2 +HC = np.pi +TQC = 3 * np.pi / 2 +FC = 2 * np.pi + + +def angle_interp(s, c): + if c == 1.0: + return 0 + elif s == 1.0: + return np.pi / 2 + elif c == -1.0: + return np.pi + elif s == -1.0: + return np.pi * 3 / 2 + elif c < 0 < s: + return acos(c) + elif s < 0 and c < 0: + return 2 * np.pi - acos(c) + elif s < 0 < c: + return asin(s) + 2 * np.pi + else: + return asin(s) + + +def normalize_angle(angle): + res = angle - (angle // FC) * FC + return res + """ + if QC < res < HC: + return res + HC + elif HC <= res <= TQC: + return res - HC + else: + return res""" + + +def theta_pred(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + angle = sin_angle_from_points(dx, dy) + if dx * dy <= 0: + return np.pi / 2 - angle + else: + root = root_finding(x1, x2, y1, y2) + if root < 0: + return np.pi / 2 + angle + else: + return angle + 3 * np.pi / 2 + + +def sin_angle_from_points(dx, dy): + return asin(abs(dy) / sqrt(dx ** 2 + dy ** 2)) + + +def poly_curve(params, x_input): + # params contains the coefficients that multiply the polynomial terms, in degree of lowest degree to highest degree + degree = len(params) - 1 + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = x * 0 + + for k in range(0, degree + 1): + coeff = params[k] + y = y + list(map(lambda z: coeff * z ** k, x)) + return x, y + + +def gauss_2d(x, y, a, b1, c_s1, b2, c_s2): + return a * np.exp(- ((x - b1) ** 2 / (2 * c_s1) + (y - b2) ** 2) / (2 * c_s2)) + + +def gauss_hat(x, a, b, c_s): + return a * np.exp(- (x - b) ** 2 / (2 * c_s)) + + +def gaussian_curve(x_input, a, b, c_s): + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = a * np.exp(- (x - b) ** 2 / (2 * c_s)) + return x, y + + +def hough_line(x, theta, rho): + return (rho - x * cos(theta)) / sin(theta) + + +""" =================================== +========== MATRIX-ARRAY UTIL ========== +======================================= """ + + +class FastDataMatrix2D: + # TODO: HANDLE THE CASE WHEN IT WRAPS 1D + + HOR = 1 + VER = 0 + + def __init__(self, data, ax, index): + self._data = data + self._ax = ax + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + self.itr = 0 + self.initialize() + + def segmentize(self, start, end): + assert 0 <= start < end <= self._data.shape[self._ax], "start: {0}, end: {1}, ax: {2}, index: {3}".format(start, + end, + self._ax, + self._index) + self.start = start + self.end = end + + def initialize(self): + self.segmentize(0, self._data.shape[self._ax]) + + def irange(self): + # index range of the fast matrix array + return self._data.shape[1 - self._ax] + + def set_axis(self, ax): + """USE copy when trying to switch axis and index""" + self._ax = ax + if self._index >= self.irange(): + raise IndexError("Old index {0} is too large for the new axis".format(self._index)) + self.initialize() + + def set_index(self, index): + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + + def extract_array(self): + """Optimize later for better performance""" + arr = self._data[self._index, self.start:self.end] if self._ax == FastDataMatrix2D.HOR \ + else self._data[self.start:self.end, self._index] + return np.array(arr) + + def copy(self, ax=None, index=None): + if ax is not None and index is not None: + return FastDataMatrix2D(self._data, ax, index) + else: + return FastDataMatrix2D(self._data, self._ax, self._index) + + def __iter__(self): + raise RuntimeError("You need the ITER method!") + + def __next__(self): + raise RuntimeError("You need the NEXT method!") + + def __getitem__(self, item): + return self._data[self._index, item + self.start] if self._ax == FastDataMatrix2D.HOR else self._data[item + self.start, self._index] + + def __setitem__(self, key, value): + if self._ax == FastDataMatrix2D.HOR: + self._data[self._index, key + self.start] = value + else: + self._data[key + self.start, self._index] = value + + def __len__(self): + return self.end - self.start + + +""" =================================== +=========== REGRESSION UTILS ========== +======================================= """ + + +# Generic Regression Tools 128-133 +def leastSquares(D, y): + return np.linalg.lstsq(D, y, rcond=None)[0] + + +def MSE(y, y_hat, N): + return np.linalg.norm(y - y_hat) ** 2 / N + + +def std_dev(data): + std_dev = 0 + len_data = len(data) + mean = sum(data) / len_data + for i in range(len_data): + std_dev += (data[i] - mean) ** 2 + return sqrt(std_dev / len_data) + + +def reg_pre_debias(ind, data): + sd = np.std(data) + miu = np.mean(data) + debiased_data = [] + debiased_ind = [] + for i in range(len(data)): + dev = abs((data[i] - miu) / sd) + if dev < 2: + debiased_data.append(data[i]) + debiased_ind.append(ind[i]) + return debiased_ind, debiased_data + + +# Polynomial Regression Tools 137-171 +def poly_data_matrix(input_data, degree): + # degree is the degree of the polynomial you plan to fit the data with + Data = np.zeros((len(input_data), degree + 1)) + + for k in range(0, degree + 1): + Data[:, k] = (list(map(lambda x: x ** k, input_data))) + + return Data + + +def poly_error(params, D_a, y_a): + '''degree=len(params)-1 + y=x_a*0 + + for k in range(0,degree+1): + coeff=params[k] + y=y+list(map(lambda z:coeff*z**k,x_a))''' + y = np.dot(D_a, params) + return np.linalg.norm(y - y_a) ** 2 + + +def improvedCost(x, y, x_test, y_test, start, end): + """Given a set of x and y points training points, + this function calculates polynomial approximations of varying + degrees from start to end. Then it returns the cost, with + the polynomial tested on test points of each degree in an array""" + c = [] + degrees = range(start, end) + ps = [] + for degree in degrees: + # YOUR CODE HERE + D = poly_data_matrix(x, degree) + p = leastSquares(D, y) + ps.append(p) + D_t = poly_data_matrix(x_test, degree) + y_hat = np.dot(D_t, p) + c.append(MSE(y_test, y_hat, len(x_test))) + return np.array(degrees), ps, np.array(c) + + +# Gaussian Regression Tools 184-210 +def gauss_data_matrix(data): + return np.array([[1, x ** 2, x, 1] for x in data]) + + +def gauss_reg(x, y, p0): + """Given a set of x and y training points, this function + calculates the gaussian approximation function""" + """skip_x = np.array([x[i] for i in range(len(y)) if y[i] != 0]) + y_prime = np.array([y[i] for i in range(len(y)) if y[i] != 0]) + logy = np.log(y_prime) + + sol = leastSquares(gauss_data_matrix(skip_x), logy) + alp, bet, gam, lam = sol + a = np.e ** alp + c_s = - 1 / (2 * bet) + b = gam * c_s + maxi, mini = max_min(y) + pred = gauss_hat(maxi, a, b, c_s) + real = y[maxi] + a = real / pred // 1000000000 * 10""" + # timeb = datetime.now() + param, vm = curve_fit(gauss_hat, x, y, p0=p0) + # timea = datetime.now() + # print(timea - timeb) + return param + + +def gauss_mat(shape, a, b1, c_s1, b2, c_s2): + mat = np.zeros(shape) + for r in range(mat.shape[0]): + for c in range(mat.shape[1]): + mat[r, c] = gauss_2d(c, r, a, b1, c_s1, b2, c_s2) + + return mat + + +# Hough Transform Regression Tools +def hough_data_matrix(x, y): + dim = len(x) + mat = np.full((dim, 3), -1.0) + for i in range(dim): + mat[i][0] = x[i] + mat[i][1] = y[i] + return mat + + +""" ======================================= +========= EDGE DETECTION UTILS ============ +=========================================== """ + + +# Generic Helper +def max_min(data): + # Returns the maximum and minimum for the data + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + return max_ind, min_ind + + +def edge_max_min(data): + # Returns a *safe* edge maxi, mini for the data + # TODO: OPTIMIZE THE WIDTH AND VALUE THRESHOLD + width_thres = 90 + value_thres = 20 + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + maxi, mini = max_ind, min_ind + assert data[maxi] >= value_thres and mini - maxi <= width_thres and maxi < mini + return maxi, mini + + +def min_max(data, max, min): + """ Converts the data to min max space. """ + g_diff = max - min + return [(d - min) / g_diff for d in data] + + +def root_finding(x1, x2, y1, y2): + """Given two points on a line, finds its zero crossing root.""" + return - y1 * (x2 - x1) / (y2 - y1) + x1 + + +def check_cross(a, b): + # Checks whether two points are of opposite signs + return a * b < 0 + + +def round_up(num): + down = int(num) + if num - down > 0: + return num + 1 + else: + return num + + +def smart_interval(start, end, data): + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + return start, end + + +def edge_preprocess(data, padding): + maxi, mini = edge_max_min(data) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end + + +# ZERO CROSSING (PEAK FINDING) +def zero_crossing(data): + # Yields the center with zero-crossing method + maxi, mini = max_min(data) + cross = -1 + cross_count = 0 + for j in range(maxi, mini): + y1 = data[j] + x2 = j + 1 + y2 = data[x2] + if check_cross(y1, y2): + cross = root_finding(j, x2, y1, y2) # change to function later + cross_count += 1 + return -1 if cross_count > 1 else cross + + +# AVERAGE METHOD FOR EDGE CENTER FINDING +def edge_converge_base(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + else: + return (maxi + mini) / 2 + + +# PSEUDO EDGE (closest noise gradient change) CENTER FINDING +def edge_converge_extreme(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + emax = -1 + emin = -1 + maxflag = True + minflag = True + cmax = maxi + cmin = mini + while cmax > 0 and cmin < len(data) - 1 and (maxflag or minflag): + max2 = cmax - 1 + maxy1, maxy2 = data[cmax], data[max2] + min2 = cmin + 1 + miny1, miny2 = data[cmin], data[min2] + if check_cross(maxy1, maxy2) and maxflag: + emax = root_finding(cmax, max2, maxy1, maxy2) + maxflag = False + if check_cross(miny1, miny2) and minflag: + emin = root_finding(cmin, min2, miny1, miny2) + minflag = False + if maxflag: + cmax -= 1 + if minflag: + cmin += 1 + return -1 if (emax == -1 or emin == -1) else (emax + emin) / 2 + + +def extract_extrema(data): + len_data = len(data) + mean = sum(data) / len_data + std_dev = 0 + for x in data: + std_dev += (x - mean) ** 2 + std_dev = sqrt(std_dev / len_data) + signifmax = [] + signifmin = [] + coeff = 3 + for i, x in enumerate(data): + diff = (x - mean) / std_dev + if diff >= coeff: + signifmax.append(i) + elif diff <= -coeff: + signifmin.append(i) + return signifmax, signifmin + + +# CENTROID METHOD FOR EDGE CENTER FINDING +def edge_centroid(data, img_data, padding=20): + # With Gaussian Blur might achieve the best performance + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + isums = 0 + total = 0 + for i in range(start, end): + isums += img_data[i] * i + total += img_data[i] + return isums / total if total else -1 + + +def centroid_seg(data, start, end): + """ Given a segment (start, end) of the data, + find the centroid. """ + isums = 0 + total = 0 + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + for i in range(start, end): + isums += data[i] * i + total += data[i] + return isums / total if total else -1 + + +# POLYNOMIAL FITTING +def poly_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + #y = np.array(img_data[start:end]) + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + curve_x, curve_y = poly_curve(param, x) + center_id = np.argmax(curve_y) + return curve_x[center_id] + + +def poly_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + 1 + start, end = smart_interval(start, end, data) + if start > end: + try: + print(maxi, mini, img_data._ax, start, end) + except: + print("else", maxi, mini, start, end) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + return param, x + + +DEGREES = {} + + +def degree_register(elem): + if elem in DEGREES: + DEGREES[elem] += 1 + else: + DEGREES[elem] = 1 + + +# GAUSSIAN FITTING +def gaussian_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + try: + maxi, mini = edge_max_min(data) + except AssertionError: + return -1 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end-start) + for i in range(start, end): + idata[i-start] = img_data[i] + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +def gaussian_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 # TODO: CONSOLIDATE THIS VALUE + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + start, end = smart_interval(start, end, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i-start] = img_data[i] + return gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]), x + + +"""====================================== +======== IMAGE PROCESSING UTIL ========== +========================================= """ + + +def gauss_bg_deduce(x, img_data): + # TODO: OPTIMIZE PERFORMANCE + idata = img_data.extract_array() + p0 = [1, len(img_data) / 2, std_dev(idata)] + a, b, c_s = gauss_reg(x, idata, p0=p0) + rem_gauss = gauss_hat(x, a, b, c_s) + new_y = idata - rem_gauss + return x, rem_gauss, new_y + + +def significance_test(data, val): + """Outputs whether the maximum or minimum value is a significant value.""" + return val in extract_extrema(data)[0] or val in extract_extrema(data)[1] + + +def edge_detect_expr(edges, original): + """ + TODO: 1. SIMPLE Approach: pairwise mask over original image, then compute total + 2. Traverse the image to mark the image. + """ + se = 0 + row_sum = 0 + col_sum = 0 + tot_sum = 0 + for i in range(edges.shape[0]): + for j in range(edges.shape[1]): + if edges[i][j] > 0: + row_sum += i * original[i][j] + col_sum += j * original[i][j] + tot_sum += original[i][j] + se += 1 + print(se) + if tot_sum != 0: + print(row_sum / tot_sum) + print(col_sum / tot_sum) + + +def hori(img, i, j, d): + dest = j + d + if dest < 0 or dest >= img.shape[1]: + return img.item(i, j) + return img.item(i, dest) + + +def verti(img, i, j, d): + dest = i + d + if dest < 0 or dest >= img.shape[0]: + return img.item(i, j) + return img.item(dest, j) + + +def test_blur_then_nr(iname): + imgs = iname + numIMG = 5 + imgr = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + target = cv2.GaussianBlur(target, (9, 9), 0) + if i == 1: + imgr = np.uint16(target) + else: + imgr = imgr + target + return imgr / numIMG + + +def get_center_val(img): + return img.item(img.shape[0] // 2, img.shape[1] // 2) + + +def test_noise_reduce(iname, numIMG=5): + imgs = iname + imgr = None + original = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + if target is None: + raise AttributeError("File {0} not found".format(iname)) + if i == 1: + imgr = np.uint16(target) + original = target + else: + imgr = imgr + target + return imgr / numIMG, original + + +def img_add(dest, src): + """Destructive!""" + row, col = dest.shape + for i in range(row): + for j in range(col): + dest[i][j] += src[i][j] + + +FM = FastDataMatrix2D + + +def folder_to_imgs(img_name_scheme, num_sample): + """This function takes img files and return cv imgs""" + return [cv2.imread(img_name_scheme.format(i)) for i in range(1, num_sample + 1)] + + +# The image taken is flipped horizontally, result x should be img.shape[1] - x +# The image sometimes has two peaks, try experimenting with different gaussian kernels +def center_detect(img_name_scheme, num_sample, sample_int=50, gk=9, ks=-1, m=0, p=20, + b=1, c=0): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # ------------------------------------------------------------ + # Parameter Setting + METHODS = {0: gaussian_fitting, 1: poly_fitting, 2: edge_centroid, + 3: zero_crossing, 4: edge_converge_base, 5: edge_converge_extreme} + edge_method = METHODS[m] + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + # ------------------------------------------------------------ + # Gathering Data + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + if m < 3: + ec_x = edge_method(data_x, FM(img, FM.HOR, nr), p) + else: + ec_x = edge_method(data_x) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, ec_x)) + + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + if m < 3: + ec_y = edge_method(data_y, FM(img, FM.VER, nc), p) + else: + ec_y = edge_method(data_y) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, ec_y)) + len_hs = len(hs) + len_vs = len(vs) + # ------------------------------------------------------------ + # --------------- PRE-CHECK DATA VALUES ---------------------- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + x_valid = False + y_valid = False + # OUTLIER DETECTION TODO: OPTIMIZE, THIS IS NAIVE + if len_hs >= r_thresh: + x_valid = True + hys, hxs = reg_pre_debias(hys, hxs) + line_a = HoughLine(x=hxs, data=hys) + if len_vs >= c_thresh: + y_valid = True + vxs, vys = reg_pre_debias(vxs, vys) + line_b = HoughLine(x=vxs, data=vys) + # ------------------------------------------------------------ + # ----- Following Modules Handles Hough Line Drawing --------- + # ------------------------------------------------------------ + # DATA RECORDING AND PROCESSING + if c == 1: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + else: + if x_valid and y_valid: + center_x, center_y = HoughLine.intersect(line_a, line_b) + else: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + # --------------------------------------------------------- + return center_x, center_y + + + +def convergence_test_final(folder, ns): + offset = '../' + convergence = {} + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + # print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + msepv = sqrt(pv / pvs) + cvg = {'PicConsistency': msepv} + convergence[m] = cvg + variations.append(msepv) + print(convergence) + fwrite.close() + +if __name__ == '__main__': + convergence_test_final('calib4/', 'img_{0}') + +#print(center_detect('../calib4/img_59_{0}.png', 5)) + diff --git a/Nov_27/Manual/Camera/img_rec_module/sig_proc_test.py b/Nov_27/Manual/Camera/img_rec_module/sig_proc_test.py new file mode 100644 index 0000000..459fec9 --- /dev/null +++ b/Nov_27/Manual/Camera/img_rec_module/sig_proc_test.py @@ -0,0 +1,2371 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from scipy.optimize import curve_fit +#from img_rec_module import img_rec +from random import randint +import os +import csv +from datetime import datetime +from math import atan, sqrt, tan, radians, acos, asin, degrees, sin, cos + + +""" =================================== +========== ANALYTIC GEOMETRY ========== +======================================= """ + + +class Line: + + inf = float('inf') + + def __init__(self, a=inf, b=inf, p1=None, p2=None, data=None): + if p1 and p2: + self.point(p1, p2) + elif data: + self.reg(data) + else: + self.a = a + self.b = b + + def reg(self, data): + D = np.array([[d[0], 1] for d in data]) + y = np.array([d[1] for d in data]) + self.a, self.b = leastSquares(D, y) + + def point(self, p1, p2): + self.a = 1 + + @staticmethod + def intersect(l1, l2): + x = (l2.b - l1.b) / (l1.a - l2.a) + y = l1.a * x + l1.b + return x, y + + +class HoughLine: + + def __init__(self, rho_rad=0, theta=0, x=None, data=None): + if data is not None and x is not None: + self.reg(x, data) + else: + self._r = degrees(rho_rad) + self._t = theta + self._s = sin(rho_rad) + self._c = cos(rho_rad) + + def reg(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + x1, x2 = x[0], x[-1] + y1, y2 = data[0], data[-1] + theta0 = theta_pred(x1, y1, x2, y2) + #print(degrees(theta0)) + p0 = [theta0, x1 * cos(theta0) + y1 * sin(theta0)] + pm, vm = curve_fit(hough_line, x, data, p0=p0) + #data_pred = hough_line(x, *pm) + #print('PRED', data_pred) + #res = data_pred - data + #print("RES", res) + #stderr = np.linalg.norm(res, 2) + #print("ERR", stderr) + #rankerr = res / stderr + #print("Z", rankerr) + if pm[1] < 0: + pm[1] = -pm[1] + pm[0] -= HC + #pm[0] = 2 * np.pi + angle = normalize_angle(pm[0]) + self._t = angle + self._r = pm[1] + self._s = sin(angle) + self._c = cos(angle) + + def extract_points(self, x_input): + x1 = int(x_input[0]) + x2 = int(x_input[-1]) + y1 = int(self.fit_x(x1)) + y2 = int(self.fit_x(x2)) + return (x1, y1), (x2, y2) + + def fit_x(self, x): + #print(self._r, self._t) + return (self._r - x * self._c) / self._s + + def __str__(self): + return 'hough line with cos:{0}, sin:{1}, rho:{2}, theta:{3}'.format(self._c, self._s, + self._r, degrees(self._t)) + + @staticmethod + def intersect(l1, l2): + x = (l2._r / l2._s - l1._r / l1._s) / (l2._c / l2._s - l1._c / l1._s) + y = l1.fit_x(x) + return x, y + + +# QC: QUARTER_CYCLE, HC: HALF_CYCLE, TQC: THIRD_QUARTER_CYCLE, FC: FULL_CYCLE +QC = np.pi / 2 +HC = np.pi +TQC = 3 * np.pi / 2 +FC = 2 * np.pi + + +def angle_interp(s, c): + if c == 1.0: + return 0 + elif s == 1.0: + return np.pi / 2 + elif c == -1.0: + return np.pi + elif s == -1.0: + return np.pi * 3 / 2 + elif c < 0 < s: + return acos(c) + elif s < 0 and c < 0: + return 2 * np.pi - acos(c) + elif s < 0 < c: + return asin(s) + 2 * np.pi + else: + return asin(s) + + +def normalize_angle(angle): + res = angle - (angle // FC) * FC + return res + """ + if QC < res < HC: + return res + HC + elif HC <= res <= TQC: + return res - HC + else: + return res""" + + +def theta_pred(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + angle = sin_angle_from_points(dx, dy) + if dx * dy <= 0: + return np.pi / 2 - angle + else: + root = root_finding(x1, x2, y1, y2) + if root < 0: + return np.pi / 2 + angle + else: + return angle + 3 * np.pi / 2 + + +def sin_angle_from_points(dx, dy): + return asin(abs(dy) / sqrt(dx ** 2 + dy ** 2)) + + +def poly_curve(params, x_input): + # params contains the coefficients that multiply the polynomial terms, in degree of lowest degree to highest degree + degree = len(params) - 1 + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = x * 0 + + for k in range(0, degree + 1): + coeff = params[k] + y = y + list(map(lambda z: coeff * z ** k, x)) + return x, y + + +def gauss_2d(x, y, a, b1, c_s1, b2, c_s2): + return a * np.exp(- ((x - b1) ** 2 / (2 * c_s1) + (y - b2) ** 2) / (2 * c_s2)) + + +def gauss_hat(x, a, b, c_s): + return a * np.exp(- (x - b) ** 2 / (2 * c_s)) + + +def gaussian_curve(x_input, a, b, c_s): + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = a * np.exp(- (x - b) ** 2 / (2 * c_s)) + return x, y + + +def hough_line(x, theta, rho): + return (rho - x * cos(theta)) / sin(theta) + + +""" =================================== +========== MATRIX-ARRAY UTIL ========== +======================================= """ + + +class FastDataMatrix2D: + # TODO: HANDLE THE CASE WHEN IT WRAPS 1D + + HOR = 1 + VER = 0 + + def __init__(self, data, ax, index): + self._data = data + self._ax = ax + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + self.itr = 0 + self.initialize() + + def segmentize(self, start, end): + assert 0 <= start < end <= self._data.shape[self._ax], "start: {0}, end: {1}, ax: {2}, index: {3}".format(start, end, self._ax, self._index) + self.start = start + self.end = end + + def initialize(self): + self.segmentize(0, self._data.shape[self._ax]) + + def irange(self): + # index range of the fast matrix array + return self._data.shape[1 - self._ax] + + def set_axis(self, ax): + """USE copy when trying to switch axis and index""" + self._ax = ax + if self._index >= self.irange(): + raise IndexError("Old index {0} is too large for the new axis".format(self._index)) + self.initialize() + + def set_index(self, index): + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, self._ax, index) + self._index = index + + def extract_array(self): + """Optimize later for better performance""" + arr = self._data[self._index, self.start:self.end] if self._ax == FastDataMatrix2D.HOR \ + else self._data[self.start:self.end, self._index] + return np.array(arr) + + def copy(self, ax=None, index=None): + if ax is not None and index is not None: + return FastDataMatrix2D(self._data, ax, index) + else: + return FastDataMatrix2D(self._data, self._ax, self._index) + + def __iter__(self): + raise RuntimeError("You need the ITER method!") + + def __next__(self): + raise RuntimeError("You need the NEXT method!") + + def __getitem__(self, item): + return self._data[self._index, item + self.start] if self._ax == FastDataMatrix2D.HOR \ + else self._data[item + self.start, self._index] + + def __setitem__(self, key, value): + if self._ax == FastDataMatrix2D.HOR: + self._data[self._index, key + self.start] = value + else: + self._data[key + self.start, self._index] = value + + def __len__(self): + return self.end - self.start + + +""" =================================== +=========== REGRESSION UTILS ========== +======================================= """ + + +# Generic Regression Tools 128-133 +def leastSquares(D, y): + return np.linalg.lstsq(D, y, rcond=None)[0] + + +def MSE(y, y_hat, N): + return np.linalg.norm(y - y_hat) ** 2 / N + + +def std_dev(data): + std_dev = 0 + len_data = len(data) + mean = sum(data) / len_data + for i in range(len_data): + std_dev += (data[i] - mean) ** 2 + return sqrt(std_dev / len_data) + + +def reg_pre_debias(ind, data): + sd = np.std(data) + miu = np.mean(data) + debiased_data = [] + debiased_ind = [] + for i in range(len(data)): + dev = abs((data[i] - miu) / sd) + if dev < 2: + debiased_data.append(data[i]) + debiased_ind.append(ind[i]) + return debiased_ind, debiased_data + + +# Polynomial Regression Tools 137-171 +def poly_data_matrix(input_data, degree): + # degree is the degree of the polynomial you plan to fit the data with + Data = np.zeros((len(input_data), degree + 1)) + + for k in range(0, degree + 1): + Data[:, k] = (list(map(lambda x: x ** k, input_data))) + + return Data + + +def poly_error(params, D_a, y_a): + '''degree=len(params)-1 + y=x_a*0 + + for k in range(0,degree+1): + coeff=params[k] + y=y+list(map(lambda z:coeff*z**k,x_a))''' + y = np.dot(D_a, params) + return np.linalg.norm(y - y_a) ** 2 + + +def improvedCost(x, y, x_test, y_test, start, end): + """Given a set of x and y points training points, + this function calculates polynomial approximations of varying + degrees from start to end. Then it returns the cost, with + the polynomial tested on test points of each degree in an array""" + c = [] + degrees = range(start, end) + ps = [] + for degree in degrees: + # YOUR CODE HERE + D = poly_data_matrix(x, degree) + p = leastSquares(D, y) + ps.append(p) + D_t = poly_data_matrix(x_test, degree) + y_hat = np.dot(D_t, p) + c.append(MSE(y_test, y_hat, len(x_test))) + return np.array(degrees), ps, np.array(c) + + +# Gaussian Regression Tools 184-210 +def gauss_data_matrix(data): + return np.array([[1, x ** 2, x, 1] for x in data]) + + +def gauss_reg(x, y, p0): + """Given a set of x and y training points, this function + calculates the gaussian approximation function""" + """skip_x = np.array([x[i] for i in range(len(y)) if y[i] != 0]) + y_prime = np.array([y[i] for i in range(len(y)) if y[i] != 0]) + logy = np.log(y_prime) + + sol = leastSquares(gauss_data_matrix(skip_x), logy) + alp, bet, gam, lam = sol + a = np.e ** alp + c_s = - 1 / (2 * bet) + b = gam * c_s + maxi, mini = max_min(y) + pred = gauss_hat(maxi, a, b, c_s) + real = y[maxi] + a = real / pred // 1000000000 * 10""" + #timeb = datetime.now() + param, vm = curve_fit(gauss_hat, x, y, p0=p0) + #timea = datetime.now() + #print(timea - timeb) + return param + + +def gauss_mat(shape, a, b1, c_s1, b2, c_s2): + mat = np.zeros(shape) + for r in range(mat.shape[0]): + for c in range(mat.shape[1]): + mat[r, c] = gauss_2d(c, r, a, b1, c_s1, b2, c_s2) + + return mat + + +# Hough Transform Regression Tools +def hough_data_matrix(x, y): + dim = len(x) + mat = np.full((dim, 3), -1.0) + for i in range(dim): + mat[i][0] = x[i] + mat[i][1] = y[i] + return mat + + +""" ======================================= +========= EDGE DETECTION UTILS ============ +=========================================== """ + + +# Generic Helper +def max_min(data): + # Returns the maximum and minimum for the data + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + return max_ind, min_ind + + +def edge_max_min(data): + # Returns a *safe* edge maxi, mini for the data + # TODO: OPTIMIZE THE WIDTH AND VALUE THRESHOLD + width_thres = 90 + value_thres = 20 + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + maxi, mini = max_ind, min_ind + assert data[maxi] >= value_thres and mini - maxi <= width_thres and maxi < mini + return maxi, mini + + +def min_max(data, max, min): + """ Converts the data to min max space. """ + g_diff = max - min + return [(d - min) / g_diff for d in data] + + +def root_finding(x1, x2, y1, y2): + """Given two points on a line, finds its zero crossing root.""" + return - y1 * (x2 - x1) / (y2 - y1) + x1 + + +def check_cross(a, b): + # Checks whether two points are of opposite signs + return a * b < 0 + + +def round_up(num): + down = int(num) + if num - down > 0: + return num + 1 + else: + return num + + +def smart_interval(start, end, data): + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + return start, end + + +def edge_preprocess(data, padding): + maxi, mini = edge_max_min(data) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end + + +# ZERO CROSSING (PEAK FINDING) +def zero_crossing(data): + # Yields the center with zero-crossing method + maxi, mini = max_min(data) + cross = -1 + cross_count = 0 + for j in range(maxi, mini): + y1 = data[j] + x2 = j + 1 + y2 = data[x2] + if check_cross(y1, y2): + cross = root_finding(j, x2, y1, y2) # change to function later + cross_count += 1 + return -1 if cross_count > 1 else cross + + +# AVERAGE METHOD FOR EDGE CENTER FINDING +def edge_converge_base(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + else: + return (maxi + mini) / 2 + + +# PSEUDO EDGE (closest noise gradient change) CENTER FINDING +def edge_converge_extreme(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + emax = -1 + emin = -1 + maxflag = True + minflag = True + cmax = maxi + cmin = mini + while cmax > 0 and cmin < len(data) - 1 and (maxflag or minflag): + max2 = cmax - 1 + maxy1, maxy2 = data[cmax], data[max2] + min2 = cmin + 1 + miny1, miny2 = data[cmin], data[min2] + if check_cross(maxy1, maxy2) and maxflag: + emax = root_finding(cmax, max2, maxy1, maxy2) + maxflag = False + if check_cross(miny1, miny2) and minflag: + emin = root_finding(cmin, min2, miny1, miny2) + minflag = False + if maxflag: + cmax -= 1 + if minflag: + cmin += 1 + return -1 if (emax == -1 or emin == -1) else (emax + emin) / 2 + + +def extract_extrema(data): + len_data = len(data) + mean = sum(data) / len_data + std_dev = 0 + for x in data: + std_dev += (x - mean) ** 2 + std_dev = sqrt(std_dev / len_data) + signifmax = [] + signifmin = [] + coeff = 3 + for i, x in enumerate(data): + diff = (x - mean) / std_dev + if diff >= coeff: + signifmax.append(i) + elif diff <= -coeff: + signifmin.append(i) + return signifmax, signifmin + + +# CENTROID METHOD FOR EDGE CENTER FINDING +def edge_centroid(data, img_data, padding=10): + # With Gaussian Blur might achieve the best performance + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + isums = 0 + total = 0 + for i in range(start, end): + isums += img_data[i] * i + total += img_data[i] + return isums / total if total else -1 + + +def centroid_seg(data, start, end): + """ Given a segment (start, end) of the data, + find the centroid. """ + isums = 0 + total = 0 + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + for i in range(start, end): + isums += data[i] * i + total += data[i] + return isums / total if total else -1 + + +# POLYNOMIAL FITTING +def poly_fitting(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + y = np.array(img_data[start:end]) + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + curve_x, curve_y = poly_curve(param, x) + center_id = np.argmax(curve_y) + return curve_x[center_id] + + +def poly_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + 1 + start, end = smart_interval(start, end, data) + if start > end: + try: + print(maxi, mini, img_data._ax, start, end) + except: + print("else", maxi, mini, start, end) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + y = np.array(img_data[start:end]) + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + return param, x + + +DEGREES = {} + + +def degree_register(elem): + if elem in DEGREES: + DEGREES[elem] += 1 + else: + DEGREES[elem] = 1 + + +# GAUSSIAN FITTING +def gaussian_fitting(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + try: + maxi, mini = edge_max_min(data) + except AssertionError: + return -1 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.array(img_data[start:end]) + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +def gaussian_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 # TODO: CONSOLIDATE THIS VALUE + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + start, end = smart_interval(start, end, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.array(img_data[start:end]) + return gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]), x + + +"""====================================== +======== IMAGE PROCESSING UTIL ========== +========================================= """ + + +def gauss_bg_deduce(x, img_data): + # TODO: OPTIMIZE PERFORMANCE + idata = img_data.extract_array() + p0 = [1, len(img_data) / 2, std_dev(idata)] + a, b, c_s = gauss_reg(x, idata, p0=p0) + rem_gauss = gauss_hat(x, a, b, c_s) + new_y = idata - rem_gauss + return x, rem_gauss, new_y + + +def sobel_process(imgr, gks, sig): + gksize = (gks, gks) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(imgr.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + return img, sobelx, sobely + + +def test_canny_detect(): + imgn = "img_89_{0}.png" + IMGDIR = "../calib4/" + NAME = IMGDIR + imgn + + while True: + lowp = input("Type the Lower Bound or c to cancel: ") + if lowp == 'c': + break + while True: + try: + low = int(lowp) + break + except ValueError: + lowp = input("Bad input Try again! ") + highp = input("Type the Upper Bound or c to cancel: ") + if highp == 'c': + break + while True: + try: + high = int(highp) + break + except ValueError: + highp = input("Bad input Try again! ") + + denoised, original = test_noise_reduce(NAME) + print(get_center_val(denoised)) + NL_denoised = cv2.fastNlMeansDenoising(original) + bdenoise = test_blur_then_nr(NAME) + + dblur, sobelx, sobely = sobel_process(denoised, 9, 0) + nldblur = sobel_process(NL_denoised, 9, 0)[0] + pblur, sobelx, sobely = sobel_process(original, 9, 0) + + de_edges = canny_detect(denoised, low, high) + db_edges = canny_detect(dblur, low, high) + nld_edges = canny_detect(nldblur, low, high) + blur_denoise = canny_detect(bdenoise, low, high) + blur_edges = canny_detect(pblur, low, high) + #edge_detect_expr(db_edges, original) + """compare_images((imgr, 'Original'), (edges, 'Canny Edge'), + (sobelx, 'Sobel X'), (sobely, 'Sobel Y'))""" + compare_images((original, 'Original'), (NL_denoised, "NLMEANS"), (de_edges, 'DENOISE Edges'), + (blur_edges, 'Plain Blur Edges'), (denoised, 'Denoised'), (nld_edges, 'NIDE-BLUR Edges'), + (db_edges, 'DE-BLUR Edges'), (blur_denoise, "BDENOISE Edges"), color_map='gray') + + +def canny_detect(src, low=4, high=10): + return cv2.Canny(np.uint8(src), 4, 10, L2gradient=True) + + +def extract_verge(edges, i, j, max_blank, dir, axis): + """ + :param edges: img MAT resulting from canny edge procedure + :param i: starting row i + :param j: starting col j + :param max_blank: maximum number of blanks to rule out the existence of a verge outside of the current verge (in which case would be a fake verge) + :param dir: Directions of movement, 1 for right or down, -1 for left or up + :param axis: + :return: (r, c) index of the verge on the given 'axis' in the given 'dir' from the starting point (i, j) + """ + + +def significance_test(data, val): + """Outputs whether the maximum or minimum value is a significant value.""" + return val in extract_extrema(data)[0] or val in extract_extrema(data)[1] + + +def edge_detect_expr(edges, original): + """ + TODO: 1. SIMPLE Approach: pairwise mask over original image, then compute total + 2. Traverse the image to mark the image. + """ + se = 0 + row_sum = 0 + col_sum = 0 + tot_sum = 0 + for i in range(edges.shape[0]): + for j in range(edges.shape[1]): + if edges[i][j] > 0: + row_sum += i * original[i][j] + col_sum += j * original[i][j] + tot_sum += original[i][j] + se += 1 + print(se) + if tot_sum != 0: + print(row_sum / tot_sum) + print(col_sum / tot_sum) + + +def hori(img, i, j, d): + dest = j + d + if dest < 0 or dest >= img.shape[1]: + return img.item(i, j) + return img.item(i, dest) + + +def verti(img, i, j, d): + dest = i + d + if dest < 0 or dest >= img.shape[0]: + return img.item(i, j) + return img.item(dest, j) + + +def test_blur_then_nr(iname): + imgs = iname + numIMG = 5 + imgr = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + target = cv2.GaussianBlur(target, (9, 9), 0) + if i == 1: + imgr = np.uint16(target) + else: + imgr = imgr + target + return imgr / numIMG + + +def get_center_val(img): + return img.item(img.shape[0] // 2, img.shape[1] // 2) + + +def test_noise_reduce(iname, numIMG=5): + imgs = iname + imgr = None + original = None + for i in range(1, numIMG+1): + target = cv2.imread(imgs.format(i), 0) + if target is None: + raise AttributeError("File {0} not found".format(iname)) + if i == 1: + imgr = np.uint16(target) + original = target + else: + imgr = imgr + target + return imgr / numIMG, original + + +def img_add(dest, src): + """Destructive!""" + row, col = dest.shape + for i in range(row): + for j in range(col): + dest[i][j] += src[i][j] + + +""" =================================== + ============ PLOTTING ============= + ============= HELPER ============== + =================================== """ + + +def quick_plot(data, xs=None): + plt.figure() + if xs: + plt.plot(xs, data, 'bo-') + else: + plt.plot(data, 'bo-') + plt.show() + plt.close() + + +def compare_images(*args, ilist=None, color_map=None): + # Takes in a sequence of IMG(Gray) and TITLE pairs and plot them side by side + if ilist: + args = ilist + graph_amount = len(args) + row = int(sqrt(graph_amount)) + col = round_up(float(graph_amount) / row) + plt.figure(figsize=(16, 8)) + for i, pair in enumerate(args): + plt.subplot(row, col, i+1) + if color_map: + plt.imshow(pair[0], cmap=color_map) + plt.xticks([]), plt.yticks([]) + plt.title(pair[1]) + plt.show() + + +def compare_data_plots(*args, ilist=None, suptitle=None): + # Takes in a sequence of tuples with data, xs, and title pairs + if ilist: + args = ilist + graph_amount = len(args) + row = int(sqrt(graph_amount)) + col = round_up(float(graph_amount) / row) + plt.figure(figsize=(16, 8)) + if suptitle: + plt.suptitle(suptitle, fontsize=14) + for i, pair in enumerate(args): + plt.subplot(row, col, i + 1) + if len(pair) == 2: + plt.plot(pair[0], 'bo-') + plt.title(pair[1]) + else: + plt.plot(pair[1], pair[0], 'bo-') + plt.title(pair[2]) + plt.show() + + +def line_graph_contrast(img, xs, ys): + line = HoughLine(x=xs, data=ys) + #print(xs) + x0 = line._c * line._r + y0 = line._s * line._r + + print('x0:{0}, y0:{1}, cos:{2}, sin:{3}, rho:{4}, theta:{5}'.format(x0, y0, line._c, line._s, line._r, degrees(line._t))) + x1 = int(x0 + 1000 * (-line._s)) + y1 = int(y0 + 1000 * (line._c)) + x2 = int(x0 - 1000 * (-line._s)) + y2 = int(y0 - 1000 * (line._c)) + p1, p2 = (x1, y1), (x2, y2) + cv2.line(img, p1, p2, (255, 0, 0), 1) + return p1, p2, line + + +""" =================================== + ====== DATA RECORDING HELPER ====== + =================================== """ + +# 1. Try Noise Reduction: +# ---- 1.1 Reduction By Averaging, without FastNIMEANS ~~ GOOD +# ---- 1.2 Reduction By FastNIMEANS ~~ INFERIOR +# ---- 1.3 Reduction By Combination ~~ INFERIOR +# ---- 1 NOTE: USE PLOTTING OF ORIGINAL GRAPH TO SEE RESULT +# 2. Try Di-Axial Scharr Kernel +# ---- 2.1 Add To Name Scheme, record graphs and compare them +# ---- 2 NOTE: GRAPH TO SAVE: 4-CONTRAST, TRANSITION PLOTS +# 3. Optimizing Data Processing: +# ---- 3.1 Marking point as edge maxima and minima according to STD Dev values +# ---- 3.2 Taking Sequential Samples +# ---- 3.3 Explore Thresholding Techniques + + +def register(img): + lval = [] + for i in range(img.shape[0]): + for j in range(img.shape[1]): + if img.item(i, j) > 250: + lval.append((i, j, img.item(i, j))) + print(lval) + + +""" TEST GAUSSIAN BLUR'S influence on noise distribution: + Method: + 1. Preliminary + 1. Generate a random noise matrix with n * n, change shape to a vector + 2. Gaussian blur applied, change shape to a vector + 3. Compare noise level + 2. Secondary + 1. Generate a Gaussian / Cosine Matrix and add random noise matrix + 2. Gaussian blur applied + 3. Compare a randomly selected row of each one +""" + + +def test_old(): + # SETTINGS + imgn = "img_4_{0}" + IMGDIR = "../new_test/" + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS+imgn + "/" + #imgr = cv2.imread(IMGDIR + imgn + ".png") + imgr, ori = test_noise_reduce(IMGDIR + imgn + ".png") + dimc = imgr.shape[1] + dimr = imgr.shape[0] + r_int = dimr // 2 + c_int = dimc // 2 + start = 7 + end = 10 + sig = 0 + ins = range(start, end, 2) + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + + # INITIALIZATION + cenvalsx = [] + cenvalsy = [] + edgvalsx = [] + edgvalsy = [] + ebvalsx = [] + ebvalsy = [] + ecvalsx = [] + ecvalsy = [] + ecbvalsx = [] + ecbvalsy = [] + #cv2.imshow("denoised", np.uint8(imgr)) # REMOVES TO SHOW IMAGE + x = np.array(range(dimc)) + x2 = np.array(range(dimr)) + + for i in ins: + # INITIALIZATION + gksize = (i, i) + sigmaX = sig + blur = cv2.GaussianBlur(imgr,gksize,sigmaX) + #cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + """kernel = np.array([[-1, -1, -1], + [-1, 8, -1], + [-1, -1, -1]]) + kerneled = cv2.filter2D(img, -1, kernel) + cv2.imshow("kerneled", kerneled)""" # KERNEL EXPERIMENT + #laplacian = cv2.Laplacian(img,cv2.CV_64F) # LAPLACIAN FILTERING + """plt.subplot(2,2,1),plt.imshow(cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY),cmap = 'gray') + plt.title('Original'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,2),plt.imshow(img,cmap = 'gray') + plt.title('Gaussian Filter'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') + plt.title('Scharr X'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') + plt.title('Scharr Y'), plt.xticks([]), plt.yticks([])""" + #plt.savefig(NAME_HEADER + "filters.png") + #plt.savefig(NAME_HEADER + "2D_filters.png") + #plt.close() # REMOVES TO SHOW CONTRAST OF FILTERS + + + # DETECTION INIT + gk_setting = "ksize:{0}, sigmax:{1}".format(gksize, sigmaX) + y_s_x = np.array([sobelx.item(r_int, c) for c in x]) + y_s_y = np.array([sobely.item(r, c_int) for r in x2]) + imgx = [imgr.item(r_int, c) for c in x] + imgy = [imgr.item(r, c_int) for r in x2] + blurimgx = [img.item(r_int, c) for c in x] + blurimgy = [img.item(r, c_int) for r in x2] + print(gk_setting) + print(extract_extrema(y_s_x)) + print(extract_extrema(y_s_y)) + fwrite.write(gk_setting) + fwrite.write('\n') + + # EDGE DETECTION + zx = zero_crossing(y_s_x) + cenvalsx.append(zx) + ex = edge_converge_extreme(y_s_x) + edgvalsx.append(ex) + ebx = edge_converge_base(y_s_x) + ebvalsx.append(ebx) + ecx = edge_centroid(y_s_x, imgx) + ecvalsx.append(ecx) + ecbx = edge_centroid(y_s_x, blurimgx) + ecbvalsx.append(ecbx) + + zy = zero_crossing(y_s_y) + cenvalsy.append(zy) + ey = edge_converge_extreme(y_s_y) + edgvalsy.append(ey) + eby = edge_converge_base(y_s_y) + ebvalsy.append(eby) + ecy = edge_centroid(y_s_y, imgy) + ecvalsy.append(ecy) + ecby = edge_centroid(y_s_y, blurimgy) + ecbvalsy.append(ecby) + + # DATA RECORDING + fwrite.write("x: zero_crossing: {0}, edge_converge: {1}; ".format(zx, ex)) + fwrite.write('\n') + fwrite.write("y: zero_crossing: {0}, edge_converge: {1}\n".format(zy, ey)) + + # GK_PLOT + """if i == 9: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + #plt.savefig(NAME_HEADER + "_" + gk_setting + ".png")""" + + #if i >= 13: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + plt.show() + # plt.savefig(NAME_HEADER + "_" + gk_setting + ".png") # UNCOMMENT WHEN SAVING PLOTS + + # USING MIN-MAX + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(221) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(222) + plt.plot(min_max(y_s_x, max(y_s_x), min(y_s_x)), 'b-') + plt.subplot(223) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + plt.xlabel("Plain") + plt.subplot(224) + plt.plot(min_max(y_s_y, max(y_s_y), min(y_s_y)), 'b-') + plt.xlabel("MINMAX") + plt.show() + + + fig = plt.figure(figsize=(16, 8)) + plt.subplot(2, 1, 1) + #plt.plot(ins, cenvalsx, 'b-', ins, edgvalsx, 'r-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + #plt.legend(['zero crossing', 'edge_converging_extreme', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + #plt.plot(ins, cenvalsx, 'b-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + #plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'],loc="lower left") + plt.plot(ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'],loc="lower left") + plt.ylabel("x_meas") + plt.subplot(2, 1, 2) + #plt.plot(ins, cenvalsy, 'b-', ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + #plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.plot(ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.ylabel("y_meas") + plt.xlabel("kernel size") + plt.show() + #fig.savefig(plot_save) + #plt.savefig(plot_save) + + +def test_interactive(): + # TODO: TEST OUT FACET MODEL AND CONDITIONAL CONVOLUTIONAL KERNEL + # SETTINGS + while True: + number = input("type the picture number u wanna test or c to cancel: ") + if number == 'c': + break + imgn = "img_%d_{0}" % int(number) + print(imgn) + IMGDIR = "../testpic/" + IMGDIR = "../calib4/" + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS + imgn + "/" + # imgr = cv2.imread(IMGDIR + imgn + ".png") + + imgr, ori = test_noise_reduce(IMGDIR + imgn + ".png", numIMG=5) + dimc = imgr.shape[1] + dimr = imgr.shape[0] + r_prompt = input("Type in the index for horizontal slice: (range: [0, {0}]) ".format(dimr - 1)) #dimr // 2 + c_prompt = input("Type in the index for vertical slice: (range: [0, {0}]) ".format(dimc - 1)) #dimc // 2 + while True: + try: + r_int = int(r_prompt) + assert 0 <= r_int < dimr + break + except ValueError: + r_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + except AssertionError: + r_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimr - 1)) + while True: + try: + c_int = int(c_prompt) + assert 0 <= c_int < dimc + break + except ValueError: + c_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + except AssertionError: + c_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + #start = 7 + #end = 10 + sig = 0 + gk = 9 + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + # INITIALIZATION + # cv2.imshow("denoised", np.uint8(imgr)) # REMOVES TO SHOW IMAGE + #x = np.array(range(dimc)) + #x2 = np.array(range(dimr)) + + # INITIALIZATION + gksize = (gk, gk) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + """kernel = np.array([[-1, -1, -1], + [-1, 8, -1], + [-1, -1, -1]]) + kerneled = cv2.filter2D(img, -1, kernel) + cv2.imshow("kerneled", kerneled)""" # KERNEL EXPERIMENT + # laplacian = cv2.Laplacian(img,cv2.CV_64F) # LAPLACIAN FILTERING + """plt.subplot(2,2,1),plt.imshow(cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY),cmap = 'gray') + plt.title('Original'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,2),plt.imshow(img,cmap = 'gray') + plt.title('Gaussian Filter'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') + plt.title('Scharr X'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') + plt.title('Scharr Y'), plt.xticks([]), plt.yticks([])""" + # plt.savefig(NAME_HEADER + "filters.png") + # plt.savefig(NAME_HEADER + "2D_filters.png") + # plt.close() # REMOVES TO SHOW CONTRAST OF FILTERS + + + # DETECTION INIT + xh = np.array(range(dimc)) + xv = np.array(range(dimr)) + zeroh = np.zeros(dimc) + zerov = np.zeros(dimr) + y_s_x = FM(sobelx, FM.HOR, r_int) + y_s_y = FM(sobely, FM.VER, c_int) + imgx = FM(imgr, FM.HOR, r_int) + imgy = FM(imgr, FM.VER, c_int) + blurimgx = FM(img, FM.HOR, r_int) + blurimgy = FM(img, FM.VER, c_int) + gx, bgx, deducedx = gauss_bg_deduce(xh, imgx) + gy, bgy, deducedy = gauss_bg_deduce(xv, imgy) + + #print(extract_extrema(y_s_x)) + #print(extract_extrema(y_s_y)) + + # EDGE DETECTION + zx = zero_crossing(y_s_x) + ex = edge_converge_extreme(y_s_x) + ebx = edge_converge_base(y_s_x) + ecbx = edge_centroid(y_s_x, blurimgx) + ecx = edge_centroid(y_s_x, imgx) + try: + #paramhp, xp1 = poly_fitting_params(y_s_x, deducedx) + #paramhg, xg1 = gaussian_fitting_params(y_s_x, deducedx) + paramhp, xp1 = poly_fitting_params(y_s_x, imgx) + paramhg, xg1 = gaussian_fitting_params(y_s_x, imgx) + xp_h_plot, yp_h_plot = poly_curve(paramhp, xp1) + xg_h_plot, yg_h_plot = gaussian_curve(xg1, paramhg[0], paramhg[1], paramhg[2]) + except AssertionError: + print("No image data for horizontal slice!") + xp_h_plot, yp_h_plot = xh, zeroh + xg_h_plot, yg_h_plot = xh, zeroh + + px, gx = xp_h_plot[np.argmax(yp_h_plot)], xg_h_plot[np.argmax(yg_h_plot)] + print("edge: {0}, poly:{1}, gaussian:{2}".format(ecx, px, gx)) + + zy = zero_crossing(y_s_y) + ey = edge_converge_extreme(y_s_y) + eby = edge_converge_base(y_s_y) + ecby = edge_centroid(y_s_y, blurimgy) + ecy = edge_centroid(y_s_y, imgy) + try: + paramvp, xp2 = poly_fitting_params(y_s_y, imgy) + paramvg, xg2 = gaussian_fitting_params(y_s_y, imgy) + xp_v_plot, yp_v_plot = poly_curve(paramvp, xp2) + xg_v_plot, yg_v_plot = gaussian_curve(xg2, paramvg[0], paramvg[1], paramvg[2]) + except AssertionError: + print("No image data for vertical slice!") + xp_v_plot, yp_v_plot = xv, zerov + xg_v_plot, yg_v_plot = xv, zerov + py, gy = xp_v_plot[np.argmax(yp_v_plot)], xg_v_plot[np.argmax(yg_v_plot)] + print("edge: {0} poly:{1}, gaussian:{2}".format(ecy, py, gy)) + + + # DATA RECORDING + fwrite.write("x: edge_centroid: {0}, poly: {1}, gaussian: {2}; ".format(ecx, px, gx)) + fwrite.write('\n') + fwrite.write("y: edge_centroid: {0}, poly: {1}, gaussian: {2}\n".format(ecy, py, gy)) + + # GK_PLOT + """if i == 9: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + #plt.savefig(NAME_HEADER + "_" + gk_setting + ".png")""" + + # if i >= 13: + fig = plt.figure(figsize=(16, 8)) + plt.subplot(211) + imgx.initialize() + plt.plot(xh, imgx.extract_array(), 'b-', xh, bgx, 'm-', xh, deducedx, 'c-', xp_h_plot, yp_h_plot, 'g-', xg_h_plot, yg_h_plot, 'r-') + plt.ylabel("Horizontal Slice, ECX: {0}".format(ecx)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.subplot(212) + imgy.initialize() + plt.plot(xv, imgy.extract_array(), 'b-', xv, bgy, 'm-', xv, deducedy, 'c-', xp_v_plot, yp_v_plot, 'g-', xg_v_plot, yg_v_plot, 'r-') + plt.ylabel("Vertical Slice, ECY: {0}".format(ecy)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.show() + # plt.savefig(NAME_HEADER + "_" + gk_setting + ".png") # UNCOMMENT WHEN SAVING PLOTS + + """fig = plt.figure(figsize=(16, 8)) + plt.subplot(2, 1, 1)""" + # plt.plot(ins, cenvalsx, 'b-', ins, edgvalsx, 'r-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + # plt.legend(['zero crossing', 'edge_converging_extreme', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + # plt.plot(ins, cenvalsx, 'b-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + # plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'],loc="lower left") + """plt.plot(ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.ylabel("x_meas") + plt.subplot(2, 1, 2) + # plt.plot(ins, cenvalsy, 'b-', ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + # plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.plot(ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.ylabel("y_meas") + plt.xlabel("kernel size") + plt.show() + # fig.savefig(plot_save) + # plt.savefig(plot_save)""" + + +def test(folder, imgn): + # TODO: TEST OUT FACET MODEL AND CONDITIONAL CONVOLUTIONAL KERNEL + # SETTINGS + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS + imgn[:-4] + "/" + # imgr = cv2.imread(IMGDIR + imgn + ".png") + + imgr, ori = test_noise_reduce(folder + imgn, numIMG=5) + dimc = imgr.shape[1] + dimr = imgr.shape[0] + while True: + r_prompt = input("Type in the index for horizontal slice or c to cancel: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + c_prompt = input("Type in the index for vertical slice: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + if r_prompt == 'c': + break + while True: + try: + r_int = int(r_prompt) + assert 0 <= r_int < dimr + break + except ValueError: + r_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + except AssertionError: + r_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimr - 1)) + while True: + try: + c_int = int(c_prompt) + assert 0 <= c_int < dimc + break + except ValueError: + c_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + except AssertionError: + c_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + # start = 7 + # end = 10 + sig = 0 + gk = 9 + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + # INITIALIZATION + # cv2.imshow("denoised", np.uint8(imgr)) # REMOVES TO SHOW IMAGE + # x = np.array(range(dimc)) + # x2 = np.array(range(dimr)) + + # INITIALIZATION + gksize = (gk, gk) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + + + # DETECTION INIT + xh = np.array(range(dimc)) + xv = np.array(range(dimr)) + zeroh = np.zeros(dimc) + zerov = np.zeros(dimr) + y_s_x = FM(sobelx, FM.HOR, r_int) + y_s_y = FM(sobely, FM.VER, c_int) + imgx = FM(imgr, FM.HOR, r_int) + imgy = FM(imgr, FM.VER, c_int) + blurimgx = FM(img, FM.HOR, r_int) + blurimgy = FM(img, FM.VER, c_int) + gx, bgx, deducedx = gauss_bg_deduce(xh, imgx) + gy, bgy, deducedy = gauss_bg_deduce(xv, imgy) + # print(extract_extrema(y_s_x)) + # print(extract_extrema(y_s_y)) + # EDGE DETECTION + ecx = edge_centroid(y_s_x, imgx) + try: + # paramhp, xp1 = poly_fitting_params(y_s_x, deducedx) + # paramhg, xg1 = gaussian_fitting_params(y_s_x, deducedx) + paramhp, xp1 = poly_fitting_params(y_s_x, imgx) + paramhg, xg1 = gaussian_fitting_params(y_s_x, imgx) + xp_h_plot, yp_h_plot = poly_curve(paramhp, xp1) + xg_h_plot, yg_h_plot = gaussian_curve(xg1, paramhg[0], paramhg[1], paramhg[2]) + except AssertionError: + print("No image data for horizontal slice!") + xp_h_plot, yp_h_plot = xh, zeroh + xg_h_plot, yg_h_plot = xh, zeroh + + px, gx = xp_h_plot[np.argmax(yp_h_plot)], xg_h_plot[np.argmax(yg_h_plot)] + print("edge: {0}, poly:{1}, gaussian:{2}".format(ecx, px, gx)) + + ecy = edge_centroid(y_s_y, imgy) + try: + paramvp, xp2 = poly_fitting_params(y_s_y, imgy) + paramvg, xg2 = gaussian_fitting_params(y_s_y, imgy) + xp_v_plot, yp_v_plot = poly_curve(paramvp, xp2) + xg_v_plot, yg_v_plot = gaussian_curve(xg2, paramvg[0], paramvg[1], paramvg[2]) + except AssertionError: + print("No image data for vertical slice!") + xp_v_plot, yp_v_plot = xv, zerov + xg_v_plot, yg_v_plot = xv, zerov + py, gy = xp_v_plot[np.argmax(yp_v_plot)], xg_v_plot[np.argmax(yg_v_plot)] + print("edge: {0} poly:{1}, gaussian:{2}".format(ecy, py, gy)) + + # DATA RECORDING + fwrite.write("x: edge_centroid: {0}, poly: {1}, gaussian: {2}; ".format(ecx, px, gx)) + fwrite.write('\n') + fwrite.write("y: edge_centroid: {0}, poly: {1}, gaussian: {2}\n".format(ecy, py, gy)) + + # if i >= 13: + fig = plt.figure(figsize=(16, 8)) + plt.subplot(411) + plt.plot(y_s_x.extract_array(), 'b-') + plt.ylabel("sobel_x") + plt.subplot(412) + imgx.initialize() + plt.plot(xh, imgx.extract_array(), 'b-', xh, bgx, 'm-', xh, deducedx, 'c-', xp_h_plot, yp_h_plot, 'g-', + xg_h_plot, yg_h_plot, 'r-') + plt.ylabel("Horizontal Slice, ECX: {0}".format(ecx)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.subplot(413) + plt.plot(y_s_y.extract_array(), 'b-') + plt.ylabel("sobel_y") + plt.subplot(414) + imgy.initialize() + plt.plot(xv, imgy.extract_array(), 'b-', xv, bgy, 'm-', xv, deducedy, 'c-', xp_v_plot, yp_v_plot, 'g-', + xg_v_plot, yg_v_plot, 'r-') + plt.ylabel("Vertical Slice, ECY: {0}".format(ecy)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.show() + # plt.savefig(NAME_HEADER + "_" + gk_setting + ".png") # UNCOMMENT WHEN SAVING PLOTS + + +FM = FastDataMatrix2D + + +def folder_to_imgs(img_name_scheme, num_sample): + """This function takes img files and return cv imgs""" + return [cv2.imread(img_name_scheme.format(i)) for i in range(1, num_sample+1)] + + +def center_detect_old(img_name_scheme, num_sample, sample_int=50): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair""" + imgs = folder_to_imgs(img_name_scheme, num_sample) + num_imgs = len(imgs) + dimr = imgs[0].shape[0] + dimc = imgs[0].shape[1] + xnum_imgs = num_imgs + ynum_imgs = num_imgs + xsum = 0 + ysum = 0 + zw = 0 + ew = 1 + gk = 9 + count = 1 + for imgr in imgs: + if count == num_sample: + imgshow = imgr + count += 1 + #print(imgr.shape) + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + # Gathering Data + nr = sample_int + r_thresh = dimr * 2.0 / (sample_int * 3) + xs = [] + xdummies = [] + ys = [] + ydummies = [] + while nr < dimr: + data_x = sobelx[nr, :] + zc_x = zero_crossing(data_x) + print("row:", nr) + ed_x = edge_centroid(data_x, FM(img, FM.HOR, nr)) + print("At {0}: {1}".format(nr, ed_x)) + nr += sample_int + xdummies.append(zc_x * zw + ed_x * ew) + if zc_x == -1: + continue + else: + xs.append(zc_x * zw + ed_x * ew) + nc = sample_int + c_thresh = dimc * 2.0 / (sample_int * 3) + while nc < dimc: + data_y = sobely[:, nc] + zc_y = zero_crossing(data_y) + ed_y = edge_centroid(data_y, FM(img, FM.VER, nc)) + nc += sample_int + ydummies.append(zc_y * zw + ed_y * ew) + if zc_y == -1: + continue + else: + ys.append(zc_y * zw + ed_y * ew) + #print("x") + #print(xdummies) + #print(xs) + #print("y") + #print(ydummies) + #print(ys) + len_xs = len(xs) + len_ys = len(ys) + print("img {0}: {1}".format(count - 1, xs)) + if len_xs < r_thresh: + xnum_imgs -= 1 + else: + xsum += sum(xs) / len(xs) + if len_ys < c_thresh: + ynum_imgs -= 1 + else: + ysum += sum(ys) / len(ys) + + plt.show() + + center_x = -1 if xnum_imgs == 0 else xsum / xnum_imgs + center_y = -1 if ynum_imgs == 0 else ysum / ynum_imgs + return center_x, center_y + +# The image taken is flipped horizontally, result x should be img.shape[1] - x +# The image sometimes has two peaks, try experimenting with different gaussian kernels + + +def center_detect_test(folder_path, img_name_scheme, num_sample, sample_int=50, debug=False, gk=9, ks=-1, m=0, p=20, b=1, c=0, hough=True): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(folder_path + img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # ------------------------------------------------------------ + # Parameter Setting + METHODS = {0: gaussian_fitting, 1: poly_fitting, 2: edge_centroid, + 3: zero_crossing, 4: edge_converge_base, 5: edge_converge_extreme} + edge_method = METHODS[m] + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + # ------------------------------------------------------------ + # Gathering Data + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + if m < 3: + ec_x = edge_method(data_x, FM(img, FM.HOR, nr), p) + else: + ec_x = edge_method(data_x) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, ec_x)) + + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + if m < 3: + ec_y = edge_method(data_y, FM(img, FM.VER, nc), p) + else: + ec_y = edge_method(data_y) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, ec_y)) + len_hs = len(hs) + len_vs = len(vs) + # --------------- PRE-CHECK DATA VALUES ---------------------- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + x_valid = False + y_valid = False + stdh = -1 + stdv = -1 + #valuesH = [d[1] for d in hs] + #valuesV = [d[1] for d in vs] + if len_hs >= r_thresh: + x_valid = True + stdh = std_dev(hxs) + if len_vs >= c_thresh: + y_valid = True + stdv = std_dev(vys) + #hough_img = img_name_scheme.format(1) + + # OUTLIER DETECTION TODO: OPTIMIZE, THIS IS NAIVE + if x_valid: # NAIVE + hys, hxs = reg_pre_debias(hys, hxs) + if y_valid: + vxs, vys = reg_pre_debias(vxs, vys) + # --------------------------------------------------------- + # ----- Following Modules Handles Hough Line Drawing --------- + if hough: + hough_img = folder_path + img_name_scheme.format(1) + print(hough_img) + img_h = cv2.imread(hough_img) + if len_hs: + hp1, hp2, line_a = line_graph_contrast(img_h, hxs, hys) + print('Drawn H') + if len_vs: + vp1, vp2, line_b = line_graph_contrast(img_h, vxs, vys) + print('Drawn V') + namespace = 'houghs/hough_{0}{1}_{2}'.format(folder_path[3:], m, img_name_scheme.format(1)) + if len_hs: + print(hp1, hp2) + if len_vs: + print(vp1, vp2) + print(namespace) + cv2.imwrite(namespace, img_h) + else: + #print("MEAS", hys) + line_a = HoughLine(x=hxs, data=hys) + #print("MEAS", vys) + line_b = HoughLine(x=vxs, data=vys) + # ------------------------------------------------------------ + # DEBUG MODULE + if debug: + print((dimr, dimc)) + print("imgX(BEFORE):", hs) + print("imgX:", list(zip(hys, hxs))) + print("imgY(BEFORE):", vs) + print("imgY:", list(zip(vxs, vys))) + compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), color_map='gray') + test(folder_path, img_name_scheme) + # -------------------------------------------------------- + # DATA RECORDING AND PROCESSING + if len_hs >= r_thresh: + x_valid = True + stdh = std_dev(hxs) + if len_vs >= c_thresh: + y_valid = True + stdv = std_dev(vys) + if c == 1: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + else: + if x_valid and y_valid: + center_x, center_y = HoughLine.intersect(line_a, line_b) + else: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + # --------------------------------------------------------- + return center_x, center_y, stdh, stdv + + +def center_detect(img_name_scheme, num_sample, sample_int=50, debug=False, gk=9, ks=-1, m=1, p=10, b=1): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + zw = 0 + ew = 1 + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # Gathering Data + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + zc_x = zero_crossing(data_x) + ec_x = edge_centroid(data_x, FM(img, FM.HOR, nr)) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, zc_x * zw + ec_x * ew)) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + zc_y = zero_crossing(data_y) + ec_y = edge_centroid(data_y, FM(img, FM.VER, nc)) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, zc_y * zw + ec_y * ew)) + len_hs = len(hs) + len_vs = len(vs) + if debug: + print((dimr, dimc)) + print("imgX:", hs) + print("imgY:", vs) + compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), color_map='gray') + while True: + ax = input("Input the axis you wanna debug, h for horizontal, v for vertical, or c to cancel: ") + if ax == 'c': + break + inds = input("Input the index you wanna debug: ") + while True: + try: + index = int(inds) + axis = FM.HOR if ax == 'h' else FM.VER + assert 0 <= index < imgr.shape[1 - axis] + break + except ValueError: + inds = input("Invalid input, do it again: ") + except AssertionError: + inds = input("Index Out of Bound, do it again: {0} ".format(imgr.shape)) + sobelop = sobelx if axis else sobely + quick_plot(FM(sobelop, axis, index).extract_array()) + + # ----- Following Modules Handles Hough Line Drawing ----- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + + hough_img = img_name_scheme.format(1) + img_h = cv2.imread(hough_img) + if len_hs: + hp1, hp2, lina = line_graph_contrast(img_h, hxs, hys) + print('Drawn H') + if len_vs: + vp1, vp2, linb = line_graph_contrast(img_h, vxs, vys) + print('Drawn V') + namespace = 'houghs/hough_{0}'.format(hough_img[3:]) + if len_hs: + print(hp1, hp2) + if len_vs: + print(vp1, vp2) + print(namespace) + cv2.imwrite(namespace, img_h) + # -------------------------------------------------------- + x_invalid = False + y_invalid = False + if len_hs < r_thresh: + x_invalid = True + if len_vs < c_thresh: + y_invalid = True + + center_x = -1 if x_invalid else sum([d[1] for d in hs]) / len_hs + center_y = -1 if y_invalid else sum([d[1] for d in vs]) / len_vs + return center_x, center_y + + +def random_test(): + data = [27, 21, 22, 21, 21, 18, 41, 69, 83, 62, 38, 16, 21, 20, 18, 17] + print(len(data)) + ids = 0 + gs = 0 + for i, d in enumerate(data): + if d == 83: + print(i) + ids += i * d + gs += d + print(ids / gs) + + +TEST_PIC_TRUTH = [(385, 130), + (385, 130), + (385, 130), + (-2, -2), + (176, 52), + (174, -1), + (158, -1), + (159, -1), + (242, 212), + (278, 215), + (325, 218), + (143, 215), + (53, 219), + (-1, 17), + (138, 19), + (355, 14), + (288, -1), + (369, 180), + (357, 265), + (225, 224), + (-1, 195), + (-1, 59), + (-1, -1), + (-1, 160), + (445, 166)] + + +def read_truth(filename): + with open(filename) as truth: + TRUTH = {} + active = None + for line in truth: + meas = line.replace(',', ' ').split() + if len(meas) == 0: + pass + elif len(meas) == 1: + active = {} + TRUTH[meas[0]] = active + + else: + tp = (int(meas[1]), int(meas[2])) + active[meas[0]] = tp + return TRUTH + + +def error_calc(meas, truth): + E = 0 + T = 0 + F = 0 + terms = 0 + #ls = ['img_5', 'img_6', 'img_7', 'img_12', 'img_13', 'img_14', 'img_15', 'img_16', 'img_17', 'img_18', 'img_20', 'img_21', 'img_22', 'img_25'] + #ms = [] + #es = [] + for m, vals in meas.items(): + """if m in ls: + continue""" + mx, my = vals + tx, ty = truth[m] + if tx == -2 or ty == -2: + pass + elif (mx == -1 and tx != -1) or (my == -1 and ty != -1): + F += 1 + #ms.append(m) + elif (mx != -1 and tx == -1) or (my != -1 and ty == -1): + T += 1 + else: + dx = mx - tx + dy = my - ty + E += (dx) ** 2 + (dy) ** 2 + #es.append((dx, dy)) + terms += 2 + # print(ms) + # print(es) + error = sqrt(E / terms) if terms else float('inf') + return {'E': error, 'T': T, 'F': F} + + +TRUTH_FILE = "meas/truth.txt" +TRUTH = read_truth(TRUTH_FILE) + + +""" ================================= +============= Parameter ============= +=========== Optimization ============ +===================================== """ + + +# TODO: OPTIMIZE ON THE THE GAUSSIAN KERNEL PARAMETER. WHAT HAPPENED THAT MAKES THE SMALL KERNEL BETTER??? +def gaussian_kernel_expr(folder, ns): + offset = '../' + truth_doc = TRUTH[folder] + error = {} + gs = range(1, 20, 2) + Es = [] + Ts = [] + Fs = [] + for g in gs: + meas = {} + #print(g) + for i in range(1, 26): + img_name = ns.format(i) + imgfile = offset + folder + "/%s_{0}.png" % img_name + # if i in [11, 13, 21, 23, 25]: + if i == 0: + val = center_detect(imgfile, 3, debug=True, gk=g) + else: + val = center_detect(imgfile, 3, gk=g) + #print(str(i), val) + meas[img_name] = val + # print(str(i), val) + + ed = error_calc(meas, truth_doc) + Es.append(ed['E']) + Ts.append(ed['T']) + Fs.append(ed['F']) + error[g] = ed + print(error) + compare_data_plots((Es, gs, 'Error'), (Ts, gs, 'False Positive'), (Fs, gs, 'False Negative'), suptitle="Gaussian Blur Test") + + +def sobel_kernel_expr(folder, ns): + offset = '../' + truth_doc = TRUTH[folder] + error = {} + #ks = [-1] + #ks.extend(list(range(3, 8, 2))) + ks = range(-1, 8, 2) + Es = [] + Ts = [] + Fs = [] + for k in ks: + # print(k) + meas = {} + for i in range(1, 26): + img_name = ns.format(i) + imgfile = offset + folder + "/%s_{0}.png" % img_name + # if i in [11, 13, 21, 23, 25]: + if i == 0: + val = center_detect(imgfile, 3, debug=True, ks=k) + else: + val = center_detect(imgfile, 3, ks=k) + #print(str(i), val) + meas[img_name] = val + # print(str(i), val) + + ed = error_calc(meas, truth_doc) + Es.append(ed['E']) + Ts.append(ed['T']) + Fs.append(ed['F']) + error[k] = ed + print(error) + compare_data_plots((Es, ks, 'Error'), (Ts, ks, 'False Positive'), (Fs, ks, 'False Negative'), suptitle="Sobel Kernel Test") + + +def convergence_test(folder, ns): + offset = '../' + convergence = {} + line_stdh = [] + line_stdv = [] + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Convergence + lrh = 0 + lrhs = 0 + lrv = 0 + lrvs = 0 + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + #print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y, stdh, stdv = center_detect_test(fpath, imgfile, 5, debug=False, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y), str(stdh), str(stdv)]) + # CONVERGENCE + if x != -1: + lrh += stdh ** 2 + lrhs += 1 + if y != -1: + lrv += stdv ** 2 + lrvs += 1 + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y, stdh, stdv = center_detect_test(fpath, imgfile, 5, debug=False, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y), str(stdh), str(stdv)]) + # CONVERGENCE + if x != -1: + lrh += stdh ** 2 + lrhs += 1 + if y != -1: + lrv += stdv ** 2 + lrvs += 1 + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + mselrh = sqrt(lrh / lrhs) + mselrv = sqrt(lrv / lrvs) + msepv = sqrt(pv / pvs) + cvg = {'LineConvergenceH': mselrh if lrhs else float('inf'), + 'LineConvergenceV': mselrv if lrvs else float('inf'), + 'PicConsistency': msepv} + convergence[m] = cvg + line_stdh.append(mselrh) + line_stdv.append(mselrv) + variations.append(msepv) + print(convergence) + compare_data_plots((line_stdh, ms, 'Line Convergence Hor'), (line_stdv, ms, 'Line Convergence Ver'), + (variations, ms, 'Reading Consistency'), suptitle="Convergence/Consistency Test") + fwrite.close() + + +def convergence_test_final(folder, ns): + offset = '../' + convergence = {} + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + # print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + msepv = sqrt(pv / pvs) + cvg = {'PicConsistency': msepv} + convergence[m] = cvg + variations.append(msepv) + print(convergence) + fwrite.close() +"""""" + + +def parameter_convert(method, padding, blur): + return method + 2 * padding + blur * 100 + + +def main(): + # TODO: HANDLE THE MAXI MINI LEFT AND RIGHT PROBLEM (2 PEAKS) + folder = "../calib4/" + img_name = "img_59_{0}.jpg" + ns = "img_%d_{0}.png" + # print("Center Detection yields: ") + # gaussian_kernel_expr('testpic', 'img_{0}') + #sobel_kernel_expr('testpic', 'img_{0}') + convergence_test('calib4/', 'img_{0}') + """for i in range(59, 193): + #if i in [29]: + try: + if i in [133, 134, 157, 158, 159, 160]: + print(i) + val = center_detect_test(folder, ns % i, 5, debug=True, hough=False) + print(str(i), val) + #val = center_detect_test(folder, ns % i, 5, hough=False) + #print(str(i), val) + except AttributeError: + print('No image {0}!'.format(i)) + print('------------------------------------------------------')""" + # convergence_test_final('calib4/', 'img_{0}') + + +def case_calc(): + hori_lower = 53.50 - 0.13 + hori_upper = 53.50 + 0.13 + verti_lower = 41.41 - 0.11 + verti_upper = 41.41 + 0.11 + height = 3 + width = 4 + print('hori_lower: {0}'.format(distance(width / 2, hori_lower / 2))) + print('hori_upper: {0}'.format(distance(width / 2, hori_upper / 2))) + print('verti_lower: {0}'.format(distance(height / 2, verti_lower / 2))) + print('verti_upper: {0}'.format(distance(height / 2, verti_upper / 2))) + + +def distance(h, angle): + return 2.54 * (h / tan(radians(angle))) + + + #print(center_detect(folder + img_name, 10, debug=True)) + + + + #print("Center Detection yields: ") + #print(center_detect("../new_test/img_3_{0}.png", 5)) + #2.5 + 13 = 15.5 / 2 = 7.75 + + """plt.figure() + plt.plot([1,2 ,3]) + plt.show()""" + + #print(atan(56 / 200) * 180 / 3.1415926535) + #print(atan(134 / 537) * 180 / 3.1415926535) + + #test() + #test_canny_detect() + #random_test() + + +if __name__ == '__main__': + main() + #print(DEGREES) + #test_interactive() + #test_canny_detect() + + + +# INSIGHT: +"""Might be able to solve the problem by auto-thresholding and converting to binary. +Alternative: + 1. Mark the maximum and minimum that are certain multitudes of standard deviation above + +=========================================== +========= THE FOLLOWING FUNCTIONS ========= +============== ARE DEPRECATED ============= +==========================================- + +def OMP(imDims, sparsity, measurements, A): + display = None + numPixels = 0 + r = measurements.copy() + indices = [] + + # Threshold to check error. If error is below this value, stop. + THRESHOLD = 0.1 + + # For iterating to recover all signal + i = 0 + + while i < sparsity and np.linalg.norm(r) > THRESHOLD: + # Calculate the correlations + print('%d - ' % i, end="", flush=True) + corrs = A.T.dot(r) + + # Choose highest-correlated pixel location and add to collection + # COMPLETE THE LINE BELOW + best_index = np.argmax(np.abs(corrs)) + indices.append(best_index) + + # Build the matrix made up of selected indices so far + # COMPLETE THE LINE BELOW + Atrunc = A[:, indices] + + # Find orthogonal projection of measurements to subspace + # spanned by recovered codewords + b = measurements + # COMPLETE THE LINE BELOW + xhat = np.linalg.lstsq(Atrunc, b)[0] + + # Find component orthogonal to subspace to use for next measurement + # COMPLETE THE LINE BELOW + r = b - Atrunc.dot(xhat) + + # This is for viewing the recovery process + if i % 10 == 0 or i == sparsity - 1 or np.linalg.norm(r) <= THRESHOLD: + recovered_signal = np.zeros(numPixels) + for j, x in zip(indices, xhat): + recovered_signal[j] = x + Ihat = recovered_signal.reshape(imDims) + plt.title('estimated image') + plt.imshow(Ihat, cmap=plt.cm.gray, interpolation='nearest') + display.clear_output(wait=True) + display.display(plt.gcf()) + + i = i + 1 + + display.clear_output(wait=True) + + # Fill in the recovered signal + recovered_signal = np.zeros(numPixels) + for i, x in zip(indices, xhat): + recovered_signal[i] = x + + return recovered_signal + +if ori == 'h': + x = np.array(range(img.shape[1])) + y = np.array([img_rec.rel_lumin(img, p, c) for c in x]) +else: + x = np.array(range(img.shape[0])) + y = np.array([img_rec.rel_lumin(img, r, p) for r in x]) +""" + +CALK = 166.1861 diff --git a/Nov_27/Manual/Camera/img_rec_module/~$log.docx b/Nov_27/Manual/Camera/img_rec_module/~$log.docx new file mode 100644 index 0000000..0430bb4 Binary files /dev/null and b/Nov_27/Manual/Camera/img_rec_module/~$log.docx differ diff --git a/Nov_27/Manual/Camera/transfer_test_correct_config/._RPI_C.py b/Nov_27/Manual/Camera/transfer_test_correct_config/._RPI_C.py new file mode 100644 index 0000000..dbdfc51 Binary files /dev/null and b/Nov_27/Manual/Camera/transfer_test_correct_config/._RPI_C.py differ diff --git a/Nov_27/Manual/Camera/transfer_test_correct_config/RPI_C.py b/Nov_27/Manual/Camera/transfer_test_correct_config/RPI_C.py new file mode 100644 index 0000000..85d7fcb --- /dev/null +++ b/Nov_27/Manual/Camera/transfer_test_correct_config/RPI_C.py @@ -0,0 +1,85 @@ +#Code for communications, sensor actions, and calculations for RPi on camera module +#Assume that RPI_C and RPI_L codes are implemented at same time (synced) +#Below code will execute at startup of RPI_C + +from SETTINGS import * +import RPi.GPIO as GPIO +import sys, traceback +import time +from Read_Accel import read_accel +sys.path.insert(0,IMG_REC) +from sig_proc import center_detect +sys.path.insert(0,IMG_CAM) +from img_capture import ImgCollector +sys.path.insert(0,COMM) +from communication import send_data_to_server + +#See SETTINGS.py + +def main(): + + try: + try: + img_collector = ImgCollector(IMG_DIR, NAME_SCHEME, FILE_FORMAT, RAW_IMAGE, NUM_SAMPLES) + except: + print('Error: Camera Not Setup') + while True: + pic = raw_input('Press [y] to continue to picture taking [Ambient]: ') + if pic == 'y': + try: + print('Taking Picture...') + img_collector.capture() + time.sleep(2) + print('Picture Taken, img_collector shutdown') + except: + print('Error Taking Photo...') + traceback.print_exc(file=sys.stdout) + finally: + break + else: + print('Please try again') + + while True: + pic = raw_input('Press [y] to continue to picture taking [Laser]: ') + if pic == 'y': + try: + print('Taking Picture...') + img_collector.capture() + time.sleep(2) + img_collector.shutdown() + print('Picture Taken, img_collector shutdown') + except: + print('Error Taking Photo...') + traceback.print_exc(file=sys.stdout) + finally: + break + else: + print('Please try again') + + while True: + accel = raw_input('Press [y] to continue to accel_1 taking: ') + if accel == 'y': + try: + print('Taking Accel_1 Value...') + Ax,Ay,Az,pitch = read_accel() + print("Ax: " + str(Ax) + " Ay: " + str(Ay) + "Az: " + str(Az) + "Pitch [deg]: " + str(pitch*180/pi)) + except: + print('Error Taking Accel_1 Value...') + finally: + break + else: + print('Please try again') + + print('Program Done, Proceeding to Program Exit...') + GPIO.cleanup() + sys.exit(0) + + except KeyboardInterrupt: + img_collector.shutdown() + GPIO.cleanup() + print('User KeyBoard Interrupt, Proceeding to Program Exit') + time.sleep(2) + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/Nov_27/Manual/Camera/transfer_test_correct_config/Read_Accel.py b/Nov_27/Manual/Camera/transfer_test_correct_config/Read_Accel.py new file mode 100644 index 0000000..826ded4 --- /dev/null +++ b/Nov_27/Manual/Camera/transfer_test_correct_config/Read_Accel.py @@ -0,0 +1,19 @@ +from SETTINGS import * +import sys +from math import atan,sin,cos,sqrt +sys.path.insert(0,ACCELEROMETER) +from accel import extract_meas + +grav = 9.81 + +def read_accel(): + x_vec,y_vec,z_vec = extract_meas() + x = float(sum(x_vec[2:]))/float(len(x_vec[2:])) + y = float(sum(y_vec[2:]))/float(len(y_vec[2:])) + z = float(sum(z_vec[2:]))/float(len(z_vec[2:])) + pitch = atan(x/(sqrt(z**2 + y**2))) #angle forward from vert [x,y flat, z up] + #roll = atan(y/(sqrt(x**2 + z**2))) #angle side from vert [x,y flat, z up] + return x,y,z,pitch + + + diff --git a/Nov_27/Manual/Camera/transfer_test_correct_config/SETTINGS.py b/Nov_27/Manual/Camera/transfer_test_correct_config/SETTINGS.py new file mode 100644 index 0000000..86726e8 --- /dev/null +++ b/Nov_27/Manual/Camera/transfer_test_correct_config/SETTINGS.py @@ -0,0 +1,31 @@ +import os + +BASE_DIR = "/home/pi/Desktop/Manual/" + +IMG_DIR = os.path.join(BASE_DIR, "images") +ACCELEROMETER = os.path.join(BASE_DIR, "accel_correct_config") +IMG_REC = os.path.join(BASE_DIR, "img_rec_module") +IMG_CAM = os.path.join(BASE_DIR, "RPiCam") +COMM = os.path.join(BASE_DIR,"communication_module") +NAME_SCHEME = "img" +FILE_FORMAT = "png" +RAW_IMAGE = False +NUM_SAMPLES = 1 +NAME_FORMAT = IMG_DIR + NAME_SCHEME + "_{0}" + FILE_FORMAT + +BRIDGE_NAME = 'dummy' +SERVER = "http://192.168.15.101:8000/sensors/"+BRIDGE_NAME+"/update/" +PASSWORD = "djioewfj34jod2jdoi3jr0jl983jsa" + +#For RPI_C.py + +RPI_L_IP = "192.168.15.103" #when hooked to Netgear Switch (Phil) +RPI_C_IP = "0.0.0.0" +RPI_C_Port = 1234 +marker = "?" +units = "mm" +span = 10*1000 +pi = 3.1415926535897932 +query_time = 2 + +pMap = {3:2,5:3,7:4,8:14,10:15,11:17,12:18,13:27,15:22,16:23,18:24,19:10,21:9,22:25,23:11,24:8,26:7} diff --git a/Nov_27/Manual/Camera/transfer_test_correct_config/accel_test.py b/Nov_27/Manual/Camera/transfer_test_correct_config/accel_test.py new file mode 100644 index 0000000..fb6ff49 --- /dev/null +++ b/Nov_27/Manual/Camera/transfer_test_correct_config/accel_test.py @@ -0,0 +1,15 @@ +from Read_Accel import read_accel + +while True: + accel = raw_input('Press [y] to continue to acceL_test taking: ') + if accel == 'y': + try: + print('Taking Accel Value...') + Ax, Ay, Az = read_accel() + print("Ax: " + str(Ax) + " Ay: " + str(Ay) + "Az: " + str(Az)) + except: + print('Error Taking Accel Value...') + finally: + break + else: + print('Please try again') \ No newline at end of file diff --git a/Nov_27/Manual/Laser/accel_correct_config/LICENSE b/Nov_27/Manual/Laser/accel_correct_config/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/Nov_27/Manual/Laser/accel_correct_config/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Nov_27/Manual/Laser/accel_correct_config/accel.py b/Nov_27/Manual/Laser/accel_correct_config/accel.py new file mode 100644 index 0000000..331c0c6 --- /dev/null +++ b/Nov_27/Manual/Laser/accel_correct_config/accel.py @@ -0,0 +1,739 @@ +#!/usr/bin/env python +# -*- coding:utf-8, indent=tab, tabstop=4 -*- +# +# See 'LICENSE' for copying +# +# Revision history +# Date Author Version Details +# ---------------------------------------------------------------------------------- +# 2016-12-31 Massimo Di Primio V.0.04 Fixed some basic functionality +# +# 2017-01-03 Massimo Di Primio 0.05 Added Interrut handler +# +# 2018-01-10 Massimo Di Primio 0.06 Added config file parser + +"""Simple code example for Adafruit MMA8452 3-axis Accelerometer + +This experimental code is intended for measuring gravity acceleration trough Adafruit(c) MMA8451, connected +to a Raspberry Pi Model 2A, 2B, 2B+ or 3 (not yet tested with RPi Zero). +Through this code we will demonstrate the ability of the 3-axis sensor MMA8451 to efficiently measure +gravity acceleration, so that we can identify the spatial orientation of the device. +Further and even more useful application can start from this minimal basic code. +""" + +import smbus +import time +import datetime +import os +import sys +import logging +import threading +import RPi.GPIO as GPIO +import rss_cli_config as clicfg +from collections import deque + +__author__ = "Massimo Di Primio" +__copyright__ = "Copyright 2016, dpmiictc" +__credits__ = ["Massimo Di Primio", "Dario Dalla Libera"] +__license__ = "GNU GENERAL PUBLIC LICENSE Version 3" +__version__ = "0.0.1" +__deprecated__ = "None so far" +__date__ = "2017-01-03" +__maintainer__ = "Massimo Di Primio" +__email__ = "massimo@diprimio.com" +__status__ = "Testing" +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# User Configuration Options (UCO) +# This section will be repaced soon by an external configuration file +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CFG_INTERRUPT = 1 +# MMA8451_RANGE = {} + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Application Definition Constants (ADC) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Useful definitions +EARTH_GRAVITY_MS2 = 9.80665 + +# Range values +RANGE_8_G = 0b10 # +/- 8g +RANGE_4_G = 0b01 # +/- 4g +RANGE_2_G = 0b00 # +/- 2g (default value) + +RANGE_DIVIDER = { + RANGE_2_G: 4096 / EARTH_GRAVITY_MS2, + RANGE_4_G: 2048 / EARTH_GRAVITY_MS2, + RANGE_8_G: 1024 / EARTH_GRAVITY_MS2, +} + +# Some static values +deviceName = 0x1a + +# Various addresses +i2caddr = 0x1D +# +# Useful Register Address +REG_STATUS = 0x00 # Read-Only +REG_WHOAMI = 0x0d # Read-Only +REG_DEVID = 0x1A # Read-Only +REG_OUT_X_MSB = 0x01 # Read-Only +REG_OUT_X_LSB = 0x02 # Read-Only +REG_OUT_Y_MSB = 0x03 # Read-Only +REG_OUT_Y_LSB = 0x04 # Read-Only +REG_OUT_Z_MSB = 0x05 # Read-Only +REG_OUT_Z_LSB = 0x06 # Read-Only +REG_F_SETUP = 0x09 # Read/Write +REG_XYZ_DATA_CFG = 0x0e # Read/Write +REG_PL_STATUS = 0x10 # Read-Only +REG_PL_CFG = 0x11 # Read/Write +REG_CTRL_REG1 = 0x2A # Read/Write +REG_CTRL_REG2 = 0x2B # Read/Write +REG_CTRL_REG3 = 0x2C # Read/Write +REG_CTRL_REG4 = 0x2D # Read/Write +REG_CTRL_REG5 = 0x2E # Read/Write + +REDUCED_NOISE_MODE = 0 +OVERSAMPLING_MODE = 1 +HIGH_RES_MODE = { + REDUCED_NOISE_MODE: [REG_CTRL_REG1, 0x4], + OVERSAMPLING_MODE: [REG_CTRL_REG2, 0x2], +} + +# Auto-Wake Sample Frequencies for Register CTRL_REG1 (0x2A) (Read/Write) +# sample frequency when the device is in SLEEP Mode. Default value: 00. +ASLP_RATE_FREQ_50_HZ = 0x00 +ASLP_RATE_FREQ_12_5_HZ = 0x40 +ASLP_RATE_FREQ_6_25HZ = 0x80 +ASLP_RATE_FREQ_1_56_HZ = 0xc0 + +# Data rate values +DATARATE_800_HZ = 0x00 # 800Hz +DATARATE_400_HZ = 0x08 # 400Hz +DATARATE_200_HZ = 0x10 # 200Hz +DATARATE_100_HZ = 0x18 # 100Hz +DATARATE_50_HZ = 0x20 # 50Hz +DATARATE_12_5_HZ = 0x28 # 12.5Hz +DATARATE_6_25HZ = 0x30 # 6.25Hz +DATARATE_1_56_HZ = 0x38 # 1.56Hz + +# Orientation labeling +PL_PUF = 0 +PL_PUB = 1 +PL_PDF = 2 +PL_PDB = 3 +PL_LRF = 4 +PL_LRB = 5 +PL_LLF = 6 +PL_LLB = 7 + +# Precision +PRECISION_14_BIT = 14 +PRECISION_08_BIT = 8 + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define Register Flags +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Register CTRL_REG1 (0x2a) R/W - System Control 1 Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | ASLPRATE1 | ASLPRATE0 | DR2 | DR1 | DR0 | LNOISE | F_READ | ACTIVE | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Auto-Wake Sample frequency Selection +FLAG_ASLPRATE_50_HZ = 0x00 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 50 Hz +FLAG_ASLPRATE_12_5_HZ = 0x40 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 12.5 Hz +FLAG_ASLPRATE_6_25_HZ = 0x80 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 6.25 Hz +FLAG_ASLPRATE_1_56_HZ = 0xc0 # Auto-Wake Sample frequency (Sleep Mode Rate Detection) 1.56 Hz +# System Output Data Rates Selection +FLAG_ODR_800_HZ = 0x00 # System Output Data Rate 800 Hz +FLAG_ODR_400_HZ = 0x08 # System Output Data Rate 400 Hz +FLAG_ODR_200_HZ = 0x10 # System Output Data Rate 200 Hz +FLAG_ODR_100_HZ = 0x18 # System Output Data Rate 100 Hz +FLAG_ODR_50_HZ = 0x20 # System Output Data Rate 50 Hz +FLAG_ODR_12_5_HZ = 0x28 # System Output Data Rate 12.5 Hz +FLAG_ODR_6_25_HZ = 0x30 # System Output Data Rate 6.25 Hz +FLAG_ODR_1_56_HZ = 0x38 # System Output Data Rate 1.56 Hz +# Other Flags +FLAG_LNOISE = 0x04 # Low Noise (1: Reduced Noise, 0: Normal Mode) +FLAG_F_READ = 0x02 # Fast Read (1: 8 bit sample, 0: 14 bit Sample) +FLAG_ACTIVE = 0x01 # Active (1: ACTIVE Mode, 0: STANDBY Mode) + +# Register CTRL_REG2 (0x2b) R/W - System Control 2 Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | ST | RST | 0 | SMODS1 | SMODS0 | SLPE | MODS1 | MODS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Other Flags +FLAG_STEST = 0x80 # Self Test (1: Self-Test enabled, 0: Self-Test disabled) +FLAG_RESET = 0x40 # Reset (1: Reset enabled, 0: Reset disabled) +# Sleep Mode Power Scheme Selection +FLAG_SMODS_NORM = 0x00 # Sleep Mode Power Scheme Selection: Normal +FLAG_SMODS_LNLP = 0x0a # Sleep Mode Power Scheme Selection: Low-Noise Low Power +FLAG_SMODS_HR = 0x12 # Sleep Mode Power Scheme Selection: High Resolution +FLAG_SMODS_LP = 0x1b # Sleep Mode Power Scheme Selection: Low Power +# Other Flags +FLAG_SLPE = 0x04 # Auto-Sleep (1: Auto-Sleep enabled, 0: Auto-Sleep Disabled) +# Active Mode Power Scheme Selection (for both: Sleep and Active mode) +FLAG_MODS_NORM = 0x00 # Active Mode Power Scheme Selection: Normal +FLAG_MODS_LNLP = 0x09 # Active Mode Power Scheme Selection: Low-Noise Low Power +FLAG_MODS_HR = 0x12 # Active Mode Power Scheme Selection: High Resolution +FLAG_MODS_LP = 0x1b # Active Mode Power Scheme Selection: Low Power + +# Register CTRL_REG4 (0x2d) R/W - Interrupt Enable Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | INT_EN_ASLP | INT_EN_FIFO |INT_EN_TRANS |INT_EN_LNDPR |INT_EN_PULSE |INT_EN_FF_MT | - | INT_EN_DRDY | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_INT_EN_ASLP = 0x80 # Interrupt Auto SLEEP/WAKE (0: Disabled, 1: Enabled) +FLAG_INT_EN_FIFO = 0x40 # Interrupt FIFO (0: Disabled, 1: Enabled) +FLAG_INT_EN_TRANS = 0x20 # Interrupt Transient (0: Disabled, 1: Enabled) +FLAG_INT_EN_LNDPRT = 0x10 # Interrupt Orientation (0: Disabled, 1: Enabled) +FLAG_INT_EN_PULSE = 0x08 # Interrupt Pulse Detection (0: Disabled, 1: Enabled) +FLAG_INT_EN_FF_MT = 0x04 # Interrupt Freefall/Motion (0: Disabled, 1: Enabled) +FLAG_INT_EN_BIT1 = 0x00 # Not Used +FLAG_INT_EN_DRDY = 0x01 # Interrupt Data Ready (0: Disabled, 1: Enabled) + +# Register CTRL_REG5 (0x2e) R/W - Interrupt Configuration Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | INT_CFG_ASLP | INT_CFG_FIFO |INT_CFG_TRANS |INT_CFG_LNDPRT|INT_CFG_PULSE |INT_CFG_FF_MT | - | INT_CFG_DRDY | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_INT_CFG_ASLP = 0x80 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_FIFO = 0x40 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_TRANS = 0x20 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_LNDPRT = 0x10 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_PULSE = 0x08 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_FF_MT = 0x04 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) +FLAG_INT_CFG_BIT1 = 0x00 # Not Used +FLAG_INT_CFG_DRDY = 0x01 # INT1/INT2 Configuration (0: Interrupt is routed to INT2 pin; 1: Interrupt is routed to INT1 pin) + +# Register XYZ_DATA_CFG (0x0e) R/W +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | 0 | 0 | 0 | HPF_OUT | 0 | 0 | FS1 | FS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# Other Flags +FLAG_XYZ_DATA_BIT_7 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_6 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_5 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_HPF_OUT = 0x00 # High-Pass Filter (1: output data High-pass filtered, 0: output data High-pass NOT filtered) +FLAG_XYZ_DATA_BIT_3 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_2 = 0x00 # 0 (Zero): Not Used +FLAG_XYZ_DATA_BIT_FS_2G = 0x00 # Full Scale Range 2g +FLAG_XYZ_DATA_BIT_FS_4G = 0x01 # Full Scale Range 4g +FLAG_XYZ_DATA_BIT_FS_8G = 0x02 # Full Scale Range 8g +FLAG_XYZ_DATA_BIT_FS_RSVD = 0x03 # Reserved + +# Register F_SETUP (0x09) R/W - FIFO Setup Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | F_MODE1 | F_MODE0 | F_WMRK5 | F_WMRK4 | F_WMRK3 | F_WMRK2 | F_WMRK1 | F_WMRK0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_F_MODE_FIFO_NO = 0x00 # FIFO is disabled. +FLAG_F_MODE_FIFO_RECNT = 0x40 # FIFO contains the most recent samples when overflowed (circular buffer) +FLAG_F_MODE_FIFO_STOP = 0x80 # FIFO stops accepting new samples when overflowed. +FLAG_F_MODE_FIFO_TRIGGER = 0xc0 # FIFO Trigger mode + +# Register PL_STATUS (0x010) R/O - Portrait/Landscape Status Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | NEWLP | LO | - | - | - | LAPO[1] | LAPO[0] | BAFRO | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_PL_NEWLP = 0x80 # Landscape/Portrait status change flag. +FLAG_PL_LO = 0x40 # Z-Tilt Angle Lockout. +FLAG_PL_LAPO_PU = 0x00 # 00: Portrait Up: Equipment standing vertically in the normal orientation +FLAG_PL_LAPO_PD = 0x02 # 01: Portrait Down: Equipment standing vertically in the inverted orientation +FLAG_PL_LAPO_LR = 0x04 # 10: Landscape Right: Equipment is in landscape mode to the right +FLAG_PL_LAPO_LL = 0x06 # 11: Landscape Left: Equipment is in landscape mode to the left. +FLAG_PL_BAFRO = 0x01 # Back or Front orientation. (0: Front: Equipment is in the front facing orientation, 1: Back) + +# Register PL_CFG (0x011) R/W - Portrait/Landscape Configuration Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | DBCNTM | PL_EN | - | - | - | - | - | - | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_PL_CFG_DBCNTM = 0x80 # Debounce counter mode selection (0: Decrements debounce, 1: Clears counter) +FLAG_PL_CFG_PL_EN = 0x40 # Portrait/Landscape Detection Enable (0: P/L Detection Disabled, 1: P/L Detection Enabled) + +# Register TRANSIENT_CFG (0x1d) R/W - Transient_CFG Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | - | - | - | ELE | ZTEFE | YTEFE | XTEFE | HPF_BYP | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_TRANSIENT_CFG_ELE = 0x10 # Transient event flags (0: Event flag latch disabled; 1: Event flag latch enabled) +FLAG_TRANSIENT_CFG_ZTEFE = 0x08 # Event flag enable on Z (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_YTEFE = 0x04 # Event flag enable on Y (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_XTEFE = 0x02 # Event flag enable on X (0: Event detection disabled; 1: Raise event flag) +FLAG_TRANSIENT_CFG_HPF_BYP = 0x01 # Bypass High-Pass filter/Motion Detection + +# Register TRANSIENT_SCR (0x01e) R/O - TRANSIENT_SRC Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | - | EA | ZTRANSE | Z_Trans_Pol | YTRANSE | Y_Trans_Pol | XTRANSE | X_Trans_Pol | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +FLAG_TRANSIENT_SCR_EA = 0x40 # Event Active Flag (0: no event flag has been asserted; 1: one or more event flag has been asserted) +FLAG_TRANSIENT_SCR_ZTRANSE = 0x20 # Z transient event (0: no interrupt, 1: Z Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_ZTR_POL = 0x10 # Polarity of Z Transient Event that triggered interrupt (0: Z event Positive g, 1: Z event Negative g) +FLAG_TRANSIENT_SCR_YTRANSE = 0x08 # Y transient event (0: no interrupt, 1: Y Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_YTR_POL = 0x04 # Polarity of Y Transient Event that triggered interrupt (0: Y event Positive g, 1: Y event Negative g) +FLAG_TRANSIENT_SCR_XTRANSE = 0x02 # X transient event (0: no interrupt, 1: X Transient acceleration > than TRANSIENT_THS event has occurred +FLAG_TRANSIENT_SCR_XTR_POL = 0x01 # Polarity of X Transient Event that triggered interrupt (0: X event Positive g, 1: X event Negative g) + +# Register FF_MT_THS (0x017) R/W - Freefall and Motion Threshold Register +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ +# | DBCNTM | THS6 | THS5 | THS4 | THS3 | THS2 | THS1 | THS0 | +# +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define SOME GLOBAL VARIABLES +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define the acceleration FIFO buffer +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# The acceleration FIFO buffer is a list of records containing all meaningful acceleration data plus some +# other useful information, whose format il as described below +# +# 1. curTime as returned by: datetime.datetime.now(). Format is: 'YYYY-MM-DD hh:mi:ss.uuuuuuu' +# 2. xAccel Current X acceleration value in row format +# 3. yAccel Current Y acceleration value in row format +# 4. xAccel Current Z acceleration value in row format +# 5. plo Current Portrait/Landscape orientation +#accelBuffer = [0, 0, 0, 0, 0] +accelBuffer = [] +#accelBuffer.append([0, 0, 0, 0, 0]) + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define the threaded interrupt vector +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +def my_callback(channel): + """ + my_callback is the threaded callback functions for interrupt events. + These will run in another thread when our events are detected + + :param channel: The GPIO channel where the interrupt event was risen + :return: None + """ + # Please nte that, for performance reasons, axis data are not convertd in m/s2, + # Although, all 6 registers containing acceleration data are read and formatted appropriately + bus = smbus.SMBus(1) + axisData = bus.read_i2c_block_data(i2caddr, REG_OUT_X_MSB, 6) + # + #print ("!"), #print("Falling edge detected on GPIO channel: " + str(channel)) + # + runTimeConfigObject.NumInterrupts = runTimeConfigObject.NumInterrupts + 1 + # + xAccel = ((axisData[0] << 8) | axisData[1]) >> 2 + yAccel = ((axisData[2] << 8) | axisData[3]) >> 2 + zAccel = ((axisData[4] << 8) | axisData[5]) >> 2 + plo = bus.read_byte_data(i2caddr, REG_PL_STATUS) & 0x7 + # Append data to the accelBuffer + accelBuffer.append([str(datetime.datetime.now()), xAccel, yAccel, zAccel, plo]) + pass + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define a class called Accel +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +import ConfigParser +class Accel(): + raspiBus = -1 # The Raspberry Pi Bus (dpends on hardware model) + raspiIntEnabled = 0 # 0 = Interrupt routine was not enabled after initialization, 1 = Interrupt routine enabled successfully + raspiInfo = "" # Raspberry Pi Info + + def __init__(self): + + # + # Setup RPI specific bus + # + myBus = "" + if GPIO.RPI_INFO['P1_REVISION'] == 1: + myBus = 0 + else: + myBus = 1 + #print('myBus=' + str(myBus)) + self.raspiBus = myBus + + self.b = smbus.SMBus(myBus) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1) + self.a = i2caddr + self.high_res_mode = OVERSAMPLING_MODE + self.sensor_range = RANGE_4_G + self.raspiInfo = GPIO.RPI_INFO + + + def whoAmI(self): + return self.b.read_byte_data(i2caddr, REG_WHOAMI) + + def init(self): + # Preliminary actions + # sudo chmod 666 /sys/module/i2c_bcm2708/parameters/combined + # sudo echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined + # + # the above 2 sh commands can be replaced with the following statements, in the case this program is ran as root (sudo) + # (For more information, please see: http://raspberrypi.znix.com/hipidocs/topic_i2c_rs_and_cs.htm) + # + # BCM2708_COMBINED_PARAM_PATH = '/sys/module/i2c_bcm2708/parameters/combined' + # os.chmod(BCM2708_COMBINED_PARAM_PATH, 666) + # os.system('echo -n 1 > {!s}'.format(BCM2708_COMBINED_PARAM_PATH)) + # sudo i2cdetect -y 1 # this sh cmmand will search /dev/i2c-1 for all address + # sudo i2cget -y 1 0x1d 0x0d # This sh command should return 0x1a for MMA8451 + # + # Setup all registers appropriately + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_RESET) # Reset + # self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_STEST) # SelfTest + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) & ~FLAG_ACTIVE) # Put the device in Standby + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) & ~FLAG_F_READ) # No Fast-Read (14-bits), Fast-Read (8-Bits) + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_ODR_50_HZ) # Data Rate + self.writeRegister(REG_XYZ_DATA_CFG, self.readRegister(REG_XYZ_DATA_CFG) | FLAG_XYZ_DATA_BIT_FS_4G) # Full Scale Range 2g, 4g or 8g + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_LNOISE) # Low Noise + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) & ~FLAG_SLPE) # No Auto-Sleep + self.writeRegister(REG_CTRL_REG2, self.readRegister(REG_CTRL_REG2) | FLAG_SMODS_HR) # High Resolution + self.writeRegister(REG_PL_CFG, self.readRegister(REG_PL_CFG) | FLAG_PL_CFG_PL_EN) # P/L Detection Enabled + + # Setup interrupts + if CFG_INTERRUPT == 1: + GPIO.setmode(GPIO.BCM) + # GPIO 23 & 17 set up as inputs, pulled up to avoid false detection. + # Both ports are wired to connect to GND on button press. + # So we'll be setting up falling edge detection for both + GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP) + # when a falling edge is detected on port 17, regardless of whatever + # else is happening in the program, the function my_callback will be run + # GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback, bouncetime=300) + GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback) + #print("Interrupt OK") + self.raspiIntEnabled = 1 # Interrupt enabled successfully + # Force 1st sensor read + my_callback(0) + + + # Configure register for interrupt + self.writeRegister(REG_CTRL_REG4, 0x00) # Reset all interrupt enabled flags + self.writeRegister(REG_CTRL_REG4, self.readRegister(REG_CTRL_REG4) | FLAG_INT_EN_DRDY) # Data Ready Interrupt Enabled + self.writeRegister(REG_CTRL_REG5, 0x00) # Reset all interrupt config flags + self.writeRegister(REG_CTRL_REG5, self.readRegister(REG_CTRL_REG5) | FLAG_INT_CFG_DRDY) # Data Ready Interrupt is routed to INT1 pin + + # Initialize the accelBuffer + accelBuffer = deque() + + + # Finally, Activate the sensor + self.writeRegister(REG_CTRL_REG1, self.readRegister(REG_CTRL_REG1) | FLAG_ACTIVE) # Activate the device + + def writeRegister(self, regNumber, regData): + """ + Writes one byte (8-bts) of data passed in 'regData', into the register 'regNumber' + """ + try: + self.b.write_byte_data(self.a, regNumber, regData) + time.sleep(0.01) + except IOError: + print("Error detected in function writeRegister() [IOError = " + str(IOError) + "]") + sys.exit() + + def readRegister(self, regNumber): + """ + Retrieves one byte (8-bits) of data from register 'regNumber' returning to the caller + """ + try: + return self.b.read_byte_data(self.a, regNumber) + except IOError: + print("Error detected in function readRegister() [IOError = " + str(IOError) + "]") + sys.exit() + + def block_read(self, offset, length): + """ + Performs a burst-read on the device registers retrieving the requested amount of data + Read a block of bytes from offset + """ + try: + return self.b.read_i2c_block_data(i2caddr, offset, length) + except IOError: + print("Error detected in function block_read() [IOError = " + str(IOError) + "]") + sys.exit() + + def get_orientation(self): + """ + Get current orientation of the sensor. + :return: orientation. Orientation number for the sensor. + """ + orientation = self.b.read_byte_data(self.a, REG_PL_STATUS) & 0x7 + return orientation + + def getAxisValue(self): + """ + Retrieves axis values and converts into a readable format (i.e. m/s2) + :return: None + """ + # Make sure F_READ and F_MODE are disabled. + f_read = self.b.read_byte_data(self.a, REG_CTRL_REG1) & FLAG_F_READ + assert f_read == 0, 'F_READ mode is not disabled. : %s' % (f_read) + f_mode = self.b.read_byte_data(self.a, REG_F_SETUP) & FLAG_F_MODE_FIFO_TRIGGER + assert f_mode == 0, 'F_MODE mode is not disabled. : %s' % (f_mode) + + # + self.xyzdata = self.block_read(REG_OUT_X_MSB, 6) + if self.high_res_mode is not None: + x = ((self.xyzdata[0] << 8) | self.xyzdata[1]) >> 2 + y = ((self.xyzdata[2] << 8) | self.xyzdata[3]) >> 2 + z = ((self.xyzdata[4] << 8) | self.xyzdata[5]) >> 2 + precision = PRECISION_14_BIT # Precision 14 bit data + else: + x = (self.xyzdata[0] << 8) + y = (self.xyzdata[1] << 8) + z = (self.xyzdata[2] << 8) + precision = PRECISION_08_BIT # Precision 08 bit data + max_val = 2 ** (precision - 1) - 1 + signed_max = 2 ** precision + # + x -= signed_max if x > max_val else 0 + y -= signed_max if y > max_val else 0 + z -= signed_max if z > max_val else 0 + # + x = round((float(x)) / RANGE_DIVIDER[self.sensor_range], 3) + y = round((float(y)) / RANGE_DIVIDER[self.sensor_range], 3) + z = round((float(z)) / RANGE_DIVIDER[self.sensor_range], 3) + + return {"x": x, "y": y, "z": z} + + def debugShowRpiInfo(self): + #print("Raspberry Info = " + str(GPIO.RPI_INFO)) + print("Raspberry Info = " + str(self.raspiInfo)) + + def debugShowRegisters(self): + print("REG_STATUS (0x00):" + str(format(self.readRegister(REG_STATUS), '#04x')) + " | Binary: " + format(self.readRegister(REG_STATUS), 'b').zfill(8)) + print("REG_WHOAMI (0x0d):" + str(format(self.readRegister(REG_WHOAMI), '#04x')) + " | Binary: " + format(self.readRegister(REG_WHOAMI), 'b').zfill(8)) + print("REG_F_SETUP (0x09):" + str(format(self.readRegister(REG_F_SETUP), '#04x')) + " | Binary: " + format(self.readRegister(REG_F_SETUP), 'b').zfill(8)) + print("REG_XYZ_DATA_CFG (0x0e):" + str(format(self.readRegister(REG_XYZ_DATA_CFG), '#04x')) + " | Binary: " + format(self.readRegister(REG_XYZ_DATA_CFG), 'b').zfill(8)) + print("REG_CTRL_REG1 (0x2a):" + str(format(self.readRegister(REG_CTRL_REG1), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG1), 'b').zfill(8)) + print("REG_CTRL_REG2 (0x2b):" + str(format(self.readRegister(REG_CTRL_REG2), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG2), 'b').zfill(8)) + print("REG_CTRL_REG3 (0x2c):" + str(format(self.readRegister(REG_CTRL_REG3), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG3), 'b').zfill(8)) + print("REG_CTRL_REG4 (0x2d):" + str(format(self.readRegister(REG_CTRL_REG4), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG4), 'b').zfill(8)) + print("REG_CTRL_REG5 (0x2e):" + str(format(self.readRegister(REG_CTRL_REG5), '#04x')) + " | Binary: " + format(self.readRegister(REG_CTRL_REG5), 'b').zfill(8)) + print("REG_PL_STATUS (0x10):" + str(format(self.readRegister(REG_PL_STATUS), '#04x')) + " | Binary: " + format(self.readRegister(REG_PL_STATUS), 'b').zfill(8)) + print ("debugRealTime " + str(runTimeConfigObject.debugRealTime)) + print ("NumInterrupts " + str(runTimeConfigObject.NumInterrupts)) + + def debugShowOrientation(self): + print("Position = %d" % (self.get_orientation())) + + def debugShowAxisAcceleration(self, xaccel, yaccel, zaccel): + print(" x (m/s2)= %+.3f" % (xaccel)) + print(" y (m/s2)= %+.3f" % (yaccel)) + print(" z (m/s2)= %+.3f" % (zaccel)) + + def debugRealTimeBuffer(self): + n = 0 + for elements in accelBuffer: + myData = accelBuffer.pop() + n += 1 + print ("N=" + str(n) + " myData=" + str(myData)) # + "Element=" + str(elements)) + try: + print("End of printout\n") + #time.sleep(1.0) + # os.system("clear") + except KeyboardInterrupt: + print("Program Termination Requested") + sys.exit() + +############################################################################### +# Threading functions +############################################################################### +#def rssClient(): +# """Manage data shipping over th network, in a separate thread.""" +# #logger.debug('Thread Starting') +# while True: +# time.sleep(1.0) +# print ("This is thread rssClient()") +# +############################################################################### +# Useful functions +############################################################################### +def printHelp(): + print ("\n") + print ("usage: accel.py [options]") + print ("Available options:") + print (" -h \t\t Print this help and exit") + print (" -d \t\t Show debug realtime interrupt data") + print (" -s \t\t Execute silently (no screen output)") + print (" -L \t Set Log level. where is the log level (0 = NONE - 8 = DEBUG)") + print ("") + + +def main(argv): + import sys, getopt, logging + # + try: + opts, args = getopt.getopt(argv,"hdsL:") + except getopt.GetoptError: + print ("\nInvalid option requested on command line") + printHelp() + sys.exit(2) + + for opt, arg in opts: + if opt == '-h': + printHelp() + sys.exit() + elif opt == '-d': + runTimeConfigObject.debugRealTime = 1 + elif opt == '-s': + runTimeConfigObject.executeSilently = 1 + elif opt == '-L': + if (int(arg) == 0) or (int(arg) > 5): + pass + #logger.setLevel(logger.NOTSET) # Same as value 0 + elif int(arg) == 1: + logger.setLevel(logging.CRITICAL) # Same as value 50 + elif int(arg) == 2: + logger.setLevel(logging.ERROR) # Same as value 40 + elif int(arg) == 3: + logger.setLevel(logging.WARNING) # Same as value 30 + elif int(arg) == 4: + logger.setLevel(logging.INFO) # Same as value 20 + elif int(arg) == 5: + logger.setLevel(logging.DEBUG) # Same as value 10 + + +##################################################################################### +# M A I N +##################################################################################### +class runTimeConfigObject(object): + pass +#if __name__ == "__main__": +def extract_meas(): + + #class runTimeConfigObject(object): + #pass + # + # Setup Logger + # + #logger = logging.basicConfig(level=logging.DEBUG, format='[%(asctime)15s].%(levelname)s] (%(threadName)-10s) %(message)s', ) + #logger.basicConfig(level=logging.DEBUG,format='[%(asctime)15s].%(levelname)s] (%(threadName)-10s) %(message)s',) + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + # create console handler and set level to debug + ch = logging.StreamHandler() + ch.setLevel(logging.DEBUG) + # create formatter + formatter = logging.Formatter('[%(asctime)s.%(levelname)s] (%(name)s.%(threadName)-10s) : %(message)s') + # add formatter to ch + ch.setFormatter(formatter) + # add ch to logger + logger.addHandler(ch) + + # + # Set some default command line options + # + runTimeConfig = runTimeConfigObject() + runTimeConfigObject.debugRealTime = 0 # 1 = Show debug realtime interrupt data + runTimeConfigObject.executeSilently = 0 # 1 = Execute silently (no sceen output) + runTimeConfigObject.NumInterrupts = 0 # keep Nbr of sensor interrupts withi the main loop + + main(sys.argv[1:]) + + # + # Read configuration file + # + configFile = "./rss_config.dat" + #logger.debug('Reading Config file: ' + configFile) #Commented out by Henry + sections = {'GeoData', 'DeviceInfo', 'Networking'} + #configParameters = {} + #Config = ConfigParser.ConfigParser() + #Config.read(configFile) + #for section in sections: + # try: + # options = Config.options(section) + # except: + # print ("ERROR: Section '" + section + "' Not found in config file: '" + configFile + "'.") + # sys.exit() + # for option in options: + # try: + # configParameters[option] = Config.get(section, option) + # except: + # configParameters[option] = None + # logger.debug("Config Section: " + section + " / Option: " + option + " => " + configParameters[option]) + + MMA8451 = Accel() + #os.system("clear") + MMA8451.init() + + if MMA8451.whoAmI() != deviceName: + print("Error! Device not recognized! (" + str(deviceName) + ")") + sys.exit() + + # + # Thread client start + # Commented out by Henry + ''' + import rss_client + pill2kill = threading.Event() + #threadClient = threading.Thread(name='netClientWorker', target=rss_client.cli_worker, args=(pill2kill, configParameters, accelBuffer)) + threadClient = threading.Thread(name='netClientWorker', target=rss_client.cli_worker, args=(pill2kill, accelBuffer)) + threadClient.setDaemon(False) #threadClient.daemon = False + threadClient.start() + myThread = [] + myThread.append('netClientWorker') + ''' + + #Added by Henry: + count_samples = 8 #num of samples we want + count_taken = 0 + xvals = [] + yvals = [] + zvals = [] + while count_taken < count_samples: + if runTimeConfigObject.executeSilently == 0: + axes = MMA8451.getAxisValue() + print("X: " + str(axes['x']) + ", Y: " + str(axes['y']) + ", Z: " + str(axes['z'])) + xvals.append(axes['x']) + yvals.append(axes['y']) + zvals.append(axes['z']) + count_taken = count_taken + 1 + return xvals,yvals,zvals + + #Commented Out by Henry: + ''' + while True: # forever loop + if runTimeConfigObject.executeSilently == 0: + print ("\nCurrent Date-Time: " + str(datetime.datetime.now())) + print ("Raspberry Bus = " + str(MMA8451.raspiBus)) + print ("Raspberry Interrupt = " + str(MMA8451.raspiIntEnabled)) + print ("Number of elemets = " + str(len(accelBuffer))) + MMA8451.debugShowRpiInfo() + MMA8451.debugShowRegisters() + MMA8451.debugShowOrientation() + axes = MMA8451.getAxisValue() + MMA8451.debugShowAxisAcceleration(axes['x'], axes['y'], axes['z']) + # + if runTimeConfigObject.debugRealTime != 0: + MMA8451.debugRealTimeBuffer() + + runTimeConfigObject.NumInterrupts = 0 + try: + time.sleep(1.0) + except KeyboardInterrupt: + logger.debug ("Killing threads...") + pill2kill.set() + threadClient.join() + time.sleep(1.0) + + logger.debug("\nUser termination requested!\n") + sys.exit() + + sys.exit() + ''' + diff --git a/Nov_27/Manual/Laser/accel_correct_config/raspidata.py b/Nov_27/Manual/Laser/accel_correct_config/raspidata.py new file mode 100644 index 0000000..fb99cbb --- /dev/null +++ b/Nov_27/Manual/Laser/accel_correct_config/raspidata.py @@ -0,0 +1,48 @@ +""" A Raspberry Pi class. +To access some of the most useful hardware information +""" + + +#class RaspiData(): + + + # Get Raspberry Serial Number + # You can do it in bash: + # cat /proc/cpuinfo | perl -n -e '/^Serial[ ]*: ([0-9a-f]{16})$/ && print "$1\n"' + # Or with perl: + # cat cpuinfo | perl -n -e '/^Serial[ ]*: ([0-9a-f]{16})$/ && print "$1\n"' + # + # + + +# def __init__(self): +# pass +from uuid import getnode as get_mac + +# @staticmethod +# def get_serial(self): +def get_serial(): + """Extract serial from cpuinfo file""" + cpu_serial= "0000000000000000" + try: + f = open('/proc/cpuinfo','r') + for line in f: + if line[0:6]=='Serial': + cpu_serial = line[10:26] + f.close() + except: + cpu_serial = "ERROR000000000" + return cpu_serial + + +def mac_address(): + """Extract rth0 MAC address""" + # mac = '00:00:00:00:00:00' + # mac = '00:00:00:00:00:00' + try: + t = get_mac() + except: + t = "000000000000" + mac = ':'.join(("%012X" % t)[i:i+2] for i in range(0, 12, 2)) + return mac + diff --git a/Nov_27/Manual/Laser/accel_correct_config/rss_cli_config.py b/Nov_27/Manual/Laser/accel_correct_config/rss_cli_config.py new file mode 100644 index 0000000..e10aa53 --- /dev/null +++ b/Nov_27/Manual/Laser/accel_correct_config/rss_cli_config.py @@ -0,0 +1,21 @@ +# [GeoData] +City = 'Rome' +cityname = 'Rome' +latitude = 41.947550 +longitude = 12.469794 +deviceorientation = 'L' + +# [DeviceInfo] +devicetype = 'raspberry' +devicename = 'rssd0001' +sensorname = 'mma8451' +sensortheshold = 20 +logfile = './rssd.log' + +# [Networking] +#serveraddress = 'www.diprimio.com' +serveraddress = 'localhost' +serverprotocol = 'tcp' +servertcpport = 15000 +serverhearthbit = 100 +receivebuffersize = 1024 diff --git a/Nov_27/Manual/Laser/accel_correct_config/rss_client.py b/Nov_27/Manual/Laser/accel_correct_config/rss_client.py new file mode 100644 index 0000000..a2a4d1b --- /dev/null +++ b/Nov_27/Manual/Laser/accel_correct_config/rss_client.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# -*- coding:utf-8, indent=tab, tabstop=4 -*- +# +# See 'LICENSE' for copying +# +# This file contains the code for the client module of 'accel.py' +# +# Revision history +# Date Author Version Details +# ---------------------------------------------------------------------------------- +# 2018-01-18 Massimo Di Primio 0.06 1st file implementation + +"""Client thread worker - This is a simple client code example for 'accel'.py' program""" + +import logging +import time +import datetime +import socket +import json +import rss_client_messages as climsg +import rss_cli_config as ccfg +import raspidata + + +#def cli_connect(params): +def cli_connect(): + """Open connection to the server""" + server_address = (str(ccfg.serveraddress), int(ccfg.servertcpport)) + logging.debug('Trying to connect to server ' + str(server_address)) + # Create a TCP/IP socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + # Connect the socket to the port where the server is listening + s.connect(server_address) + logging.debug('Connection Established to server ' + str(server_address)) + except: + logging.debug( + "Failed to open connection: " + str(ccfg.serverprotocol) + + ", to IP: " + str(ccfg.serveraddress) + + ", on port: " + str(ccfg.servertcpport) + ) + return(-1) + return(s) + + +def cli_close(s): + """Close the server connection""" + if s > -1: + s.close() + + +# def cli_worker(stopEvent, config, accelBuffer): +def cli_worker(stopEvent, accelBuffer): + """A client worker as thread""" + logging.debug('Thread Starting') + s = cli_connect() # s = cli_connect(config) + send_client_hello(s) + time.sleep(0.5) + send_config_affirm_message(s) + + ts = int(time.time()) + te = ts + while not stopEvent.wait(0.3): + if len(accelBuffer) > 0: + send_accel_data(s, accelBuffer) + te = int(time.time()) + if (te - ts) > 10: + send_client_heartbit(s) + ts = int(time.time()) + + time.sleep(0.5) + send_zap_message(s) + cli_close(s) + logging.debug("Thread cliWorker is terminating as per your request.") + + +def send_accel_data(s, accelBuffer): + """Send acceleration data to the server""" + #msg = dict(cmd='ADM', timestamp=str(datetime.datetime.now()), clid=raspidata.get_serial()) + #a = 123 #str(datetime.datetime.now()) + pbuf = parse_accel_data(accelBuffer) + msg = dict(cmd = 'ADM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial(), data = pbuf) + # if len(pbuf) > 0: # this sometimes returns error (when buf is empty, it has None type) + if (pbuf is not None) and (len(pbuf) > 0): + #str = climsg.accel_data_message(pbuf) + try: + logging.debug("Sending Acceleration data to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(str) + "\n") + except: + logging.debug("Failed to send Acceleration-Data to the server") + + +def send_client_hello(s): + """Send Hello message to the server""" + msg = dict(cmd = 'CHM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial()) + try: + logging.debug("Sending Hello to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.hello_message()) + "\n") + except: + logging.debug("Failed to send Hello to the server") + + +def send_zap_message(s): + """Send Zap message to the server""" + msg = dict(cmd = 'CZM', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial()) + try: + logging.debug("Sending Zap to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.zap_message()) + "\n") + except: + logging.debug("Failed to send Zap to the server") + + +def send_config_affirm_message(s): #def send_config_affirm_message(s, config): + msg_data = dict(city = ccfg.cityname, latitude = ccfg.latitude,longitude = ccfg.longitude) + msg = dict(cmd = 'CCA', timestamp = str(datetime.datetime.now()), clid = raspidata.get_serial(), config = msg_data) + try: + logging.debug("Sending client configuration to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(climsg.config_affirm_message(cfg_data)) + except: + logging.debug("Failed to send client configuration to the server") + + +def send_client_heartbit(s): + """Send Heartbit to the server""" + msg = dict(cmd = 'CHB', timestamp = str(datetime.datetime.now()), clid=raspidata.get_serial()) + try: + logging.debug("Sending Heartbit to the server") + s.sendall(str(json.dumps(msg)) + "\n") #s.sendall(json.dumps(climsg.heart_bit()) + "\n") + except: + logging.debug("Failed to send Heartbit to the server") + + +def parse_accel_data(b): + """Parse acceleration data to make sure we only send meaningfull data to the server""" + tsh = 10 + tbuf = [] + # tbuf.append([0, 0, 0, 0, 0]) + # bLength = len(b) + # logging.debug("parseAccelData(b) # of elements = " + str(len(b))) + if len(b) > 1: + logging.debug("parseAccelData: In AccelData/BufLen: " + str(len(b)) + "/" +str(len(tbuf))) + firstTime = 1 + prow = None + for row in b: + crow = b.pop(0) # Get the oldest record + if firstTime == 1: + prow = crow + firstTime = 0 + if ( (abs(abs(int(crow[1])) - abs(int(prow[1]))) > tsh) or + (abs(abs(int(crow[2])) - abs(int(prow[2]))) > tsh) or + (abs(abs(int(crow[3])) - abs(int(prow[3]))) > tsh) + ): + tbuf.append(crow) + prow = crow + print ("Again PROW/CROW/TBUFLEN:" + str(prow) + " / " + str(crow) + " / " + str(len(tbuf))) + + logging.debug("parseAccelData: Out AccelData/BufLen: " + str(len(b)) + "/" +str(len(tbuf))) + return(tbuf) + diff --git a/Nov_27/Manual/Laser/accel_correct_config/rss_client_messages.py b/Nov_27/Manual/Laser/accel_correct_config/rss_client_messages.py new file mode 100644 index 0000000..4a507d7 --- /dev/null +++ b/Nov_27/Manual/Laser/accel_correct_config/rss_client_messages.py @@ -0,0 +1,113 @@ + +import datetime +import raspidata +import json +import rss_cli_config as ccfg + + +# +# All client messages are handled in here. +# +# Message Formats +# --------------- +# 1 - Timestamp +# 2 - Device ID +# 3 - Message Type +# +# Client message types +# -------------------- +# 0001 CHB - Client Heart Bit (Client is alive) +# 0002 CHM - Client Hello Message (Client is online) +# 0003 CZM - Client Zap Message (Client is shut down) +# 0004 ADM - Acceleration Data Message (Acceleration data) +# 0005 CCA - Client Config Affirm +# ... (other to come) +# +# Data message Format for all Client Message Types +# ------------------------------------------------ +# +# # 0001 - CHB - Client Heart Bit +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0001 | Var | Literally 'CHB' | +# # +-------------------------------------------------------------------------------+ +# +# 0002 CHM - Client Hello Message +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0002 | Var | Literally 'CHM' | +# +--------------+-------+--------------------------------------------------------+ +# +# 0003 CZM - Client Zap Message (Client is shut down) +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0003 | Var | Literally 'CZM' | +# +--------------+-------+--------------------------------------------------------+ +# +# 0004 ADM - Acceleration Data Message (Acceleration data) +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0004 | Var | Literally 'ADM' | +# | Accel Data | Var | Array containing acceleration data (X,Y,Z.O) | +# +--------------+-------+--------------------------------------------------------+ +# +# 0005 CCA - Client Configuration Affirm +# +--------------+-------+--------------------------------------------------------+ +# | Field |Length | Description | +# +--------------+-------+--------------------------------------------------------+ +# | Datetime | 16 | 'HH/MM/DD hh:mi:ss.uuuuuu' | +# | Device ID | 16 | 16 byte device ID | +# | 0004 | Var | Literally 'CCA' | +# | Config Data | Var | Array containing client configuration | +# +--------------+-------+--------------------------------------------------------+ + +########################################################################### +# WARNIG ! THIS FILE IS NOT CURRENTLY USED ! +# Its presence it is for debugging/testing only +# Althought, it will be used in some future version +########################################################################### + +#def heart_bit(): +# """Client Heart Bit""" +# msg = {'cmd': 'CHB', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def hello_message(): +# """Client Hello Message""" +# msg = {'cmd': 'CHM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def zap_message(): +# """Client Zap Message""" +# msg = {'cmd': 'CZM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial()} +# return msg +# +# +#def accel_data_message(data): +# """Acceleration Data Message""" +# msg = {'cmd': 'ADM', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial(), 'acceldata': str(data)} +# return msg +# +# +#def config_affirm_message(data): #def config_affirm_message(data): +# """Client Configuration Affirm""" +# ### +# pkt_hdr = {'cmd': 'CCA', 'timestamp': str(datetime.datetime.now()), 'clid': raspidata.get_serial(), 'data' : data} +# +# msg = dict(city = ccfg.cityname, latitude = ccfg.latitude, longitude = ccfg.longitude, config = data) +# return msg + diff --git a/Nov_27/Manual/Laser/transfer_test_correct_config/._RPI_L.py b/Nov_27/Manual/Laser/transfer_test_correct_config/._RPI_L.py new file mode 100644 index 0000000..a34d731 Binary files /dev/null and b/Nov_27/Manual/Laser/transfer_test_correct_config/._RPI_L.py differ diff --git a/Nov_27/Manual/Laser/transfer_test_correct_config/._Read_Accel.py b/Nov_27/Manual/Laser/transfer_test_correct_config/._Read_Accel.py new file mode 100644 index 0000000..4f96332 Binary files /dev/null and b/Nov_27/Manual/Laser/transfer_test_correct_config/._Read_Accel.py differ diff --git a/Nov_27/Manual/Laser/transfer_test_correct_config/RPI_L.py b/Nov_27/Manual/Laser/transfer_test_correct_config/RPI_L.py new file mode 100644 index 0000000..076e061 --- /dev/null +++ b/Nov_27/Manual/Laser/transfer_test_correct_config/RPI_L.py @@ -0,0 +1,74 @@ +#Code for communications, sensor actions, and calculations for RPi on laser module +#Assume that RPI_C and RPI_L codes are implemented at same time (synced) +#Below code will execute at startup of RPI_L + +from SETTINGS import * +import sys +import RPi.GPIO as GPIO +import time +from Read_Accel import read_accel + +#Givens + +# See: SETTINGS.py + +def main(): + + try: + while True: + las_o = raw_input('Press [y] to turn on laser: ') + if las_o == 'y': + try: + print('Turning on laser...') + GPIO.setmode(GPIO.BCM) + GPIO.setup(pMap[Laser_Port], GPIO.OUT) + GPIO.output(pMap[Laser_Port], True) + except: + print('Error turning on laser') + finally: + break + else: + print('Please try again') + + + while True: + las = raw_input('Press [y] to turn off laser: ') + if las == "y": + try: + print('Turning off laser...') + GPIO.output(pMap[Laser_Port],False) + GPIO.cleanup() + except: + print('Error turning off laser') + finally: + break + else: + print('Please try again') + + while True: + accel = raw_input('Press [y] to continue to accel_2 taking: ') + if accel == 'y': + try: + print('Taking Accel_1 Value...') + Ax, Ay, Az, Pitch = read_accel() + print("Ax: " + str(Ax) + " Ay: " + str(Ay) + "Az: " + str(Az) + "Pitch: " + str(Pitch*180/pi)) + except: + print('Error taking Accel_1 value') + finally: + break + else: + print('Please try again') + + print('Program Done, Proceeding to Program Exit...') + GPIO.cleanup() + sys.exit(0) + + except KeyboardInterrupt: + print('User KeyBoard Interrupt, Proceeding to Program Exit') + GPIO.cleanup() + time.sleep(2) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/Nov_27/Manual/Laser/transfer_test_correct_config/Read_Accel.py b/Nov_27/Manual/Laser/transfer_test_correct_config/Read_Accel.py new file mode 100644 index 0000000..4a50ada --- /dev/null +++ b/Nov_27/Manual/Laser/transfer_test_correct_config/Read_Accel.py @@ -0,0 +1,16 @@ +from SETTINGS import * +import sys +from math import atan,sqrt,sin,cos +sys.path.insert(0,ACCELEROMETER) +from accel import extract_meas + +grav = 9.81 + +def read_accel(): + x_vec,y_vec,z_vec = extract_meas() + x = float(sum(x_vec[2:]))/float(len(x_vec[2:])) + y = float(sum(y_vec[2:]))/float(len(y_vec[2:])) + z = float(sum(z_vec[2:]))/float(len(z_vec[2:])) + pitch = atan(x/(sqrt(z**2 + y**2))) #angle forward from vert [x,y flat, z vert] + #roll = atan(y/(sqrt(x**2 + z**2))) #angle side from vert [x,y flat, z vert] + return x,y,z,pitch diff --git a/Nov_27/Manual/Laser/transfer_test_correct_config/SETTINGS.py b/Nov_27/Manual/Laser/transfer_test_correct_config/SETTINGS.py new file mode 100644 index 0000000..7764aa7 --- /dev/null +++ b/Nov_27/Manual/Laser/transfer_test_correct_config/SETTINGS.py @@ -0,0 +1,19 @@ +import os + +BASE_DIR = '/home/pi/Desktop/Manual/' + +ACCELEROMETER = os.path.join(BASE_DIR, "accel_correct_config") + +#For RPI_L.py + +#RPI_L_IP = "192.168.3.3" #address of cam module (client) +RPI_C_IP = "192.168.15.104" #when hooked to Netgear Switch (Phil) +RPI_L_IP = "192.168.15.103" #when hooked to Netgear Switch (Phil) +RPI_L_Port = 1234 +RPI_C_Port = 1234 +Laser_Port = 11 +marker = "?" +query_time = 3 +pi = 3.1415926535897932 + +pMap = {3:2,5:3,7:4,8:14,10:15,11:17,12:18,13:27,15:22,16:23,18:24,19:10,21:9,22:25,23:11,24:8,26:7} diff --git a/Nov_27/Manual/Laser/transfer_test_correct_config/accel_test.py b/Nov_27/Manual/Laser/transfer_test_correct_config/accel_test.py new file mode 100644 index 0000000..fb6ff49 --- /dev/null +++ b/Nov_27/Manual/Laser/transfer_test_correct_config/accel_test.py @@ -0,0 +1,15 @@ +from Read_Accel import read_accel + +while True: + accel = raw_input('Press [y] to continue to acceL_test taking: ') + if accel == 'y': + try: + print('Taking Accel Value...') + Ax, Ay, Az = read_accel() + print("Ax: " + str(Ax) + " Ay: " + str(Ay) + "Az: " + str(Az)) + except: + print('Error Taking Accel Value...') + finally: + break + else: + print('Please try again') \ No newline at end of file diff --git a/RPiCam/RPiCM.py b/RPiCam/RPiCM.py new file mode 100644 index 0000000..ca837ac --- /dev/null +++ b/RPiCam/RPiCM.py @@ -0,0 +1,174 @@ +# Author: Alex R. Mead +# Date: May 2016 +# Description: +# This code will run on the Raspberry Pi 2 with Camera Module (RPiCM) to interact with the MacBookPro (MBP). It will +# wait for the MBP to request a measurement, take a measurement, then wait for the MBP to request the latest +# measurement, at which time it will send the measurement to the MBP. + +# Same as the MBP this system is designed to run like finite state machine. + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) + +import sys +import socket +import io +import subprocess +import picamera +import numpy as np +import gc +from time import sleep + +# Constants +#IP = '127.0.0.1' # Testing on a single machine +IP = '0.0.0.0' # Actual run time. +port1 = 1234 +port2 = 2345 +marker = "?" + +MAX_PIXEL_VALUE = 1023 # 2^10 = 1024 +PIXEL_HEIGHT = 1944 +PIXEL_WIDTH = 2592 + +# Takes in the Camera object instantiated at the beginning of the run and takes the desired SS expsoures with it. +def HDRI(SS,camera): + + size = len(SS) + print("Taking %i measurements.\n",size) + names = [] + + # Loop through for each shutter speed requested + for index, shutterSpeed in enumerate(SS): + fileName = str(shutterSpeed) + ".data" + camera.shutter_speed = shutterSpeed + sleep(1) + print(str(camera.shutter_speed)) + camera.capture(fileName,format='jpeg',bayer=True) + names.append(fileName) + + # Return the list of filenames to the calling function. + return names + +def main(): + + STATE = "idle" + RUNNING = [True,0] + + # First declare the camera object and configure it as needed + camera = picamera.PiCamera() + camera.framerate=1 + sleep(1.0) + + camera.led = False + camera.iso = 100 + sleep(10.0) + # This longer sleep is needed so analog_gain and digital_gains settle so when I turn them off in the next step + # they will have settled and not be in their initial 'low' values. + + camera.exposure_mode = 'off' # Fixes analog_gain and digital_gain values + g = camera.awb_gains + camera.aws_mode = 'off' + camera.awb_gains = [1.0,1.0] # typical values 0.9-1.9 according to documentation, I picked these for consistency. + camera.rotation = 180 + sleep(2.0) + + while(RUNNING[0]): + + if("idle" == STATE): + print("We're in idle state waiting to hear from the MacBookPro...") + + # Start up a connection listening for the MBP. + sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) + sock.bind((IP,port1)) + sock.listen(1) + connection, client_address = sock.accept() + + rcv_msg = [] + while True: + data = connection.recv(1) + if marker in data: + rcv_msg.append(data[:data.find(marker)]) + break + rcv_msg.append(data) + + # Check the message received from the MBP, if correct, continue, else exit. + rpl = ''.join(rcv_msg) + if rpl == "True": + print("Now going to acknowledge measurement.") + + # elif used to teminate remotely. + elif rpl == "c": + print("Big John called it for me...") + sys.exit(0) + + # Acknowledge the MBP so it knows a measurement will be taking place. + connection.send("True?") + connection.close() + + # Change state: Continue on and take measurement + STATE ="Measuring" + + elif ("Measuring" == STATE): + print("Engaging the Camera Module to measure the output of the CFS under test...") + # Here is the function call to take the measurement of the CFS inside CUBE2.0 + + # List of the shutter speeds in microseconds to be used + #SS = [1000000, 100000, 10000, 1000, 100, 10]; + SS = [1000000, 100000, 10000]; + + # Take the measurements with the above stated shutter speeds + files = HDRI(SS,camera) + + print("...Measurement taken of CFS.\n") + + # Continue to the next state and wait for MBP to query for the 145 measurements. + STATE = "waitToSend" + + elif("waitToSend" == STATE): + print("Waiting to send to MBP...") + # Setup connection to wait for the request from the MBP + # This maybe a short wait as the MBP may be trying to connect already if the Measurememt was a long time. + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind((IP, port2)) + sock.listen(1) + connection, client_address = sock.accept() + + rcv_msg = [] + while True: + data = connection.recv(1) + if marker in data: + rcv_msg.append(data[:data.find(marker)]) + break + rcv_msg.append(data) + + # Check the message received from the MBP, if correct, continue, else exit. + rpl = ''.join(rcv_msg) + if rpl == "True": + print("Send measurement.") + + # Now use the same connection to let the MBP know it can grab the .jpg+RAW + # files and run RPiCM_C.c locally over there, which is MUCH faster. + connection.sendall("True?") + connection.close() + + print("...measurment has been sent.\n") + + # Change state: measurement has been sent, change state back to idle + STATE = "idle" + + # Cycle counter for the finite state machine + RUNNING[1] = RUNNING[1] + 1 + print("Cycle number: " + str(RUNNING[1])) + + print("Little John called it...") + sys.exit(0) + +if __name__ == "__main__": + main() + diff --git a/RPiCam/cam.py b/RPiCam/cam.py new file mode 100644 index 0000000..c91e666 --- /dev/null +++ b/RPiCam/cam.py @@ -0,0 +1,32 @@ +import picamera +from fractions import Fraction + +cam = picamera.PiCamera(resolution=(640, 480)) +cam.exposure_mode = 'off' +DEBUG_DIR = 'debug/' +filename = DEBUG_DIR + 'shutter_{0}_iso_{1}_expo_{2}.png' +cam.capture("base.png") +cam.framerate = Fraction(1, 6) +while True: + try: + exp = input("Run experiment?[y/n] ") + if exp == 'y': + ss = input("shutter speed: ") + iso = input("iso: ") + options = {'a': 'off', 'b': 'auto', 'c': 'night', 'd': 'night_preview', 'e': 'sports'} + expo = input("exposure mode: " + str(options) + " ") + #bright = input("brightness: ") + ss, iso, opt = int(ss), int(iso), options[expo] + cam.shutter_speed = ss + cam.iso = iso + cam.exposure_mode = options[expo] + #cam.brightness = bright + cam.capture(filename.format(ss, iso, opt)) + else: + cam.close() + break + except ValueError: + pass + + + diff --git a/RPiCam/img_capture.py b/RPiCam/img_capture.py new file mode 100644 index 0000000..86fd14a --- /dev/null +++ b/RPiCam/img_capture.py @@ -0,0 +1,186 @@ +import picamera +import os +from fractions import Fraction +import sys, traceback +import time + + +class ImgCollector: + + def __init__(self, dir='', ns='img', form='png', raw=False, num=1, serialize=True): + if dir: + if not os.path.exists(dir): + os.mkdir(dir) + if dir[len(dir)-1] != '/': + dir += '/' + + self.name_scheme = dir + ns + '_{0}.' + form + self._dir = dir + self._ns = ns + self._form = form + self._raw = raw + self._num = num + self.init_cam() + if serialize: + if os.path.exists("img_log.txt"): + rfile = open("img_log.txt", "r") + try: + self.counter = int(rfile.read()) + except ValueError: + self.counter = 1 + else: + rfile = open("img_log.txt", "w") + self.counter = 1 + rfile.close() + else: + self.counter = 1 + + + def change_ns(self, ns): + self._ns = ns + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_format(self, form): + self._form = form + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_dir(self, dir): + self._dir = dir + self.name_scheme = self._dir + self._ns + '_{0}.' + self._form + + def change_num(self, num): + self._num = num + if self._num == 1: + self.capture = self.uni_capture + else: + self.capture = self.multi_capture + + def init_cam(self): + self.cam = picamera.PiCamera(resolution=(640, 480)) + time.sleep(2) + self.cam.led = False + self.cam.framerate = Fraction(1, 6) + self.cam.rotation = 180 + self.cam.shutter_speed = 800000 + self.cam.iso = 100 + self.cam.exposure_mode = 'off' + time.sleep(3) + if self._num == 1: + self.capture = self.uni_capture + else: + self.capture = self.multi_capture + + def get_last_meas(self): + if self._num == 1: + return self.name_scheme.format(self.counter - 1) + else: + return self._dir + self._ns + '_%d_{0}.' % (self.counter - 1) + self._form + + def shutdown(self): + self.cam.close() + wfile = open("img_log.txt", "w") + wfile.write(str(self.counter)) + wfile.close() + + def uni_capture(self): + self.cam.capture(self.name_scheme.format(self.counter), bayer=self._raw) + self.counter += 1 + + def multi_capture(self): + file_list = [self.name_scheme.format("%d_%d" % (self.counter, i)) for i in range(1, self._num+1)] + self.cam.capture_sequence(file_list, bayer=self._raw) + self.counter += 1 + + +def main(): + prompt = input("Welcome to the RPiCam Module. Type q for quick test, d for debug, or f / [other inputs] for full test.\n") + global recur + if prompt == 'q': + directory = 'quick_test' + name_pattern = 'img' + pic_format = 'png' + raw_image = False + num_meas = 1 + recur = True + elif prompt == 'd': + camera_debug() + sys.exit() + else: + directory = input("Input a directory:\n") + name_pattern = input("Input a name pattern:\n") + pic_format = input("Input a picture format:\n") + raw_image = input("Raw image?[y/n]\n") in ['y', 'yes'] + num_meas = int(input("Number of image samples for one measurement?\n")) + recur = False + + while True: + try: + ic = ImgCollector(dir=directory, ns=name_pattern, form=pic_format, raw=raw_image, num=num_meas) + break + except: + directory = input("Ill-formated directory, type in another one: ") + traceback.print_exc(file=sys.stdout) + + while True: + if recur: + ic.shutdown() + break + + option = input("Type in an action or h for help:\n") + if option == 'h': + print("m: take measurement\n" + + "r: show raw image status\n" + + "cr: change raw image status\n" + + "cf: change image format\n" + + "cd: change directory\n" + + "cn: change name\n" + + "cm: change number of measurement\n" + + "e: end the program") + elif option == 'm': + ic.capture() + elif option == 'r': + print(ic._raw) + elif option == 'cr': + ic._raw = input("Raw image?[y/n]\n") in ['y', 'yes'] + elif option == 'cf': + ic.change_format(input("Input a picture format:\n")) + elif option == 'cd': + ic.change_dir(input("Input a directory:\n")) + elif option == 'cn': + ic.change_ns(input("Input a name pattern:\n")) + elif option == 'cm': + ic.change_num(int(input("Number of image samples for one measurement?\n"))) + elif option == 'e': + ic.shutdown() + break + + +def camera_debug(): + DEBUG_DIR = 'debug/' + filename = DEBUG_DIR + 'shutter_{0}_iso_{1}_bright_{2}.jpeg' + analog = 'analog_gain: ' + awb_gain = 'awb_gain: ' + expo_modes = ['night', 'night_preview', 'very_long'] + #flash_modes = ['off', 'redeye'] + flash_modes = ['off'] + shutter = [600000, 800000, 1000000] + with picamera.PiCamera(resolution=(640, 480)) as cam: + time.sleep(1) + print(analog + str(cam.analog_gain)) + print(awb_gain + str(cam.awb_gains)) + cam.framerate = Fraction(1, 6) + for ss in shutter: + #for br in brightness: + time.sleep(0.1) + cam.shutter_speed = ss + cam.brightness = 50 + cam.capture(filename.format(ss), bayer=False) + + +if __name__ == "__main__": + recur = True + while recur: + main() + + + diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..88b97b5 --- /dev/null +++ b/__init__.py @@ -0,0 +1,2 @@ +# Test + diff --git a/calbridgesensors/calbridgesensors/__init__.py b/calbridgesensors/calbridgesensors/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/calbridgesensors/calbridgesensors/settings.py b/calbridgesensors/calbridgesensors/settings.py new file mode 100644 index 0000000..b089ea7 --- /dev/null +++ b/calbridgesensors/calbridgesensors/settings.py @@ -0,0 +1,137 @@ +""" +Django settings for calbridgesensors project. + +Generated by 'django-admin startproject' using Django 2.0.3. + +For more information on this file, see +https://docs.djangoproject.com/en/2.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.0/ref/settings/ +""" + +import os + + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '&vuf$!t_6n7_z^0pfj-gdmk2k^8(^4%thu&&i-a)5=na_klw!!' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = ["127.0.0.1", "192.168.15.101", "10.142.156.122", "192.168.0.12"] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + "sensors.apps.SensorsConfig" +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'calbridgesensors.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(BASE_DIR, "templates")], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'calbridgesensors.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.0/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'America/Los_Angeles' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.0/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'var/static/') +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, 'static/') +] +STATICFILE_FINDERS = [ + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder' +] + + +# AUTHENTICATION URL Dispatchers + +LOGIN_URL = 'login' +LOGIN_REDIRECT_URL = 'sensors:index' +LOGOUT_REDIRECT_URL = 'home' diff --git a/calbridgesensors/calbridgesensors/urls.py b/calbridgesensors/calbridgesensors/urls.py new file mode 100644 index 0000000..88c765e --- /dev/null +++ b/calbridgesensors/calbridgesensors/urls.py @@ -0,0 +1,29 @@ +"""calbridgesensors URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/2.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.views.generic.base import TemplateView +from django.urls import path, include +from django.conf import settings +from django.conf.urls.static import static + + +urlpatterns = [ + path('', TemplateView.as_view(template_name="home.html"), name='home'), + path('admin/', admin.site.urls), + path('accounts/', include('django.contrib.auth.urls')), + path('sensors/', include("sensors.urls")) +] + diff --git a/calbridgesensors/calbridgesensors/wsgi.py b/calbridgesensors/calbridgesensors/wsgi.py new file mode 100644 index 0000000..cca3138 --- /dev/null +++ b/calbridgesensors/calbridgesensors/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for calbridgesensors project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "calbridgesensors.settings") + +application = get_wsgi_application() diff --git a/calbridgesensors/manage.py b/calbridgesensors/manage.py new file mode 100755 index 0000000..12bb361 --- /dev/null +++ b/calbridgesensors/manage.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "calbridgesensors.settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) diff --git a/calbridgesensors/runserver.sh b/calbridgesensors/runserver.sh new file mode 100755 index 0000000..155f968 --- /dev/null +++ b/calbridgesensors/runserver.sh @@ -0,0 +1,9 @@ +#!/bin/bash/ + +line=`ifconfig |grep broadcast` +echo $line +set -- $line +ip=$2 +echo $ip +python manage.py runserver $ip:8000 + diff --git a/calbridgesensors/sensors/__init__.py b/calbridgesensors/sensors/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/calbridgesensors/sensors/admin.py b/calbridgesensors/sensors/admin.py new file mode 100644 index 0000000..ca58d9b --- /dev/null +++ b/calbridgesensors/sensors/admin.py @@ -0,0 +1,7 @@ +from django.contrib import admin +from .models import Bridge, BridgeLog, BrokenFlag + +# Register your models here. +admin.site.register(Bridge) +admin.site.register(BridgeLog) +admin.site.register(BrokenFlag) \ No newline at end of file diff --git a/calbridgesensors/sensors/apps.py b/calbridgesensors/sensors/apps.py new file mode 100644 index 0000000..41b5c2e --- /dev/null +++ b/calbridgesensors/sensors/apps.py @@ -0,0 +1,13 @@ +from django.apps import AppConfig +from decimal import Decimal + + +class SensorsConfig(AppConfig): + name = 'sensors' + +CONNECTION_PASSWORD = "djioewfj34jod2jdoi3jr0jl983jsa" +BUFFER_TIME = 3 +RECENT_PERIOD = 10 +THRESHOLD_DIS = 1 +THRESHOLD_ROT = 1 +CALIB_VAL = Decimal(166.1861) diff --git a/calbridgesensors/sensors/converters.py b/calbridgesensors/sensors/converters.py new file mode 100644 index 0000000..ff311d1 --- /dev/null +++ b/calbridgesensors/sensors/converters.py @@ -0,0 +1,8 @@ +class BridgeNameConverter: + regex = '[\w-]+' + + def to_python(self, value): + return value.replace("-", " ").title() + + def to_url(self, value): + return str(value).replace(" ", "-").lower() \ No newline at end of file diff --git a/calbridgesensors/sensors/migrations/0001_initial.py b/calbridgesensors/sensors/migrations/0001_initial.py new file mode 100644 index 0000000..faceee4 --- /dev/null +++ b/calbridgesensors/sensors/migrations/0001_initial.py @@ -0,0 +1,65 @@ +# Generated by Django 2.0.5 on 2018-06-23 01:15 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Bridge', + fields=[ + ('name', models.CharField(max_length=40, primary_key=True, serialize=False)), + ('anomaly', models.BooleanField(default=False)), + ('validated', models.BooleanField(default=False)), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='BridgeLog', + fields=[ + ('log_type', models.CharField(choices=[('D', 'Damage Record'), ('R', 'Repair Record')], max_length=1)), + ('log_time', models.DateTimeField(auto_now_add=True, primary_key=True, serialize=False)), + ('bridge', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sensors.Bridge', unique_for_date='log_time')), + ], + options={ + 'ordering': [], + }, + ), + migrations.CreateModel( + name='BrokenFlag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('bridge', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='sensors.Bridge')), + ('record', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='sensors.BridgeLog')), + ], + options={ + 'ordering': [], + }, + ), + migrations.CreateModel( + name='Reading', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('x', models.DecimalField(decimal_places=2, max_digits=4)), + ('y', models.DecimalField(decimal_places=2, max_digits=4)), + ('z', models.DecimalField(decimal_places=2, max_digits=4)), + ('theta', models.DecimalField(decimal_places=2, max_digits=4)), + ('phi', models.DecimalField(decimal_places=2, max_digits=4)), + ('psi', models.DecimalField(decimal_places=2, max_digits=4)), + ('time_taken', models.DateTimeField(auto_now_add=True)), + ('bridge', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sensors.Bridge', unique_for_date='time_taken')), + ], + options={ + 'verbose_name': 'Bridge sensor reading', + }, + ), + ] diff --git a/calbridgesensors/sensors/migrations/0002_auto_20180623_0133.py b/calbridgesensors/sensors/migrations/0002_auto_20180623_0133.py new file mode 100644 index 0000000..d923aed --- /dev/null +++ b/calbridgesensors/sensors/migrations/0002_auto_20180623_0133.py @@ -0,0 +1,17 @@ +# Generated by Django 2.0.5 on 2018-06-23 01:33 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('sensors', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='reading', + options={'ordering': ['-time_taken'], 'verbose_name': 'Bridge sensor reading'}, + ), + ] diff --git a/calbridgesensors/sensors/migrations/0003_auto_20180624_0658.py b/calbridgesensors/sensors/migrations/0003_auto_20180624_0658.py new file mode 100644 index 0000000..fda13cd --- /dev/null +++ b/calbridgesensors/sensors/migrations/0003_auto_20180624_0658.py @@ -0,0 +1,33 @@ +# Generated by Django 2.0.5 on 2018-06-24 06:58 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('sensors', '0002_auto_20180623_0133'), + ] + + operations = [ + migrations.AlterModelOptions( + name='bridgelog', + options={'ordering': ['-log_time', 'log_type', 'bridge__name']}, + ), + migrations.AlterModelOptions( + name='brokenflag', + options={'ordering': ['bridge__name']}, + ), + migrations.AlterModelOptions( + name='reading', + options={'ordering': ['bridge__name', '-time_taken'], 'verbose_name': 'Bridge Sensor Reading'}, + ), + migrations.RemoveField( + model_name='bridge', + name='anomaly', + ), + migrations.RemoveField( + model_name='bridge', + name='validated', + ), + ] diff --git a/calbridgesensors/sensors/migrations/0004_auto_20180626_0607.py b/calbridgesensors/sensors/migrations/0004_auto_20180626_0607.py new file mode 100644 index 0000000..9aead8a --- /dev/null +++ b/calbridgesensors/sensors/migrations/0004_auto_20180626_0607.py @@ -0,0 +1,22 @@ +# Generated by Django 2.0.5 on 2018-06-26 06:07 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('sensors', '0003_auto_20180624_0658'), + ] + + operations = [ + migrations.AlterModelOptions( + name='bridgelog', + options={'ordering': ['bridge__name', 'log_type', '-log_time']}, + ), + migrations.RenameField( + model_name='brokenflag', + old_name='record', + new_name='first_broken_record', + ), + ] diff --git a/calbridgesensors/sensors/migrations/0005_auto_20180628_1815.py b/calbridgesensors/sensors/migrations/0005_auto_20180628_1815.py new file mode 100644 index 0000000..f916970 --- /dev/null +++ b/calbridgesensors/sensors/migrations/0005_auto_20180628_1815.py @@ -0,0 +1,18 @@ +# Generated by Django 2.0.5 on 2018-06-28 18:15 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('sensors', '0004_auto_20180626_0607'), + ] + + operations = [ + migrations.RenameField( + model_name='brokenflag', + old_name='first_broken_record', + new_name='damage_record', + ), + ] diff --git a/calbridgesensors/sensors/migrations/__init__.py b/calbridgesensors/sensors/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/calbridgesensors/sensors/models.py b/calbridgesensors/sensors/models.py new file mode 100644 index 0000000..15f1cec --- /dev/null +++ b/calbridgesensors/sensors/models.py @@ -0,0 +1,131 @@ +from django.db import models +from django.utils import timezone +from .utils import name_validate, max_val, succinct_time_str +from .apps import THRESHOLD_DIS, THRESHOLD_ROT, BUFFER_TIME, RECENT_PERIOD + + +class Bridge(models.Model): + # Field: reading + name = models.CharField(max_length=40, primary_key=True) + + class Meta: + ordering = ["name"] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.name = name_validate(self.name) + + def __str__(self): + return self.name + + def latest_reading(self): + r_set = self.reading_set.all() + return r_set[0] if r_set else None + + def get_damage_records(self): + return self.bridgelog_set.filter(log_type="D") + + def get_repair_records(self): + return self.bridgelog_set.filter(log_type="R") + + def is_broken(self): + try: + return self.brokenflag + except AttributeError: + return False + + def update(self, data): + """ Creates new reading, checks anomaly; + --> Raises Broken Flag if showing anomaly for longer than BUFFER_TIME; + --> Marks bridge as repaired when repaired. """ + new_reading = self.reading_set.create(x=float(data['x']), y=float(data['y']), z=float(data['z']), + theta=float(data['theta']), phi=float(data['phi']), + psi=float(data['psi']), bridge=self) + if new_reading.shows_anomaly(): + # Check whether it has a broken flag, whether it is new anomaly + if not self.is_broken(): + # Means it's new. Checks latest damage record, don't raise alarm if it is within buffer time + damage_recs = self.get_damage_records() + if damage_recs: + latest_damage = damage_recs[0] + offset = latest_damage.time_elapsed().days + if offset > BUFFER_TIME: + # Latest Damage Record not created yet + self.bridgelog_set.create(log_type='D', bridge=self) + elif offset == BUFFER_TIME: + # Already over the buffer time, time to raise alarm + self.mark_broken(latest_damage) + # Else it is within the buffer time, wait for sometime + else: + # No Damage Record Yet + self.bridgelog_set.create(log_type='D', bridge=self) + # Else it's old. No need to create new records. Also no need to raise alarm again + else: + # Now it seems normal. Three scenerios: 1) Repaired, 2) False Alarm Previously, 3) Good In the First Place + if self.is_broken(): + self.mark_repaired() + + def mark_repaired(self): + self.bridgelog_set.create(log_type='R', bridge=self) + self.brokenflag.delete() + + def mark_broken(self, damage_rec): + BrokenFlag.objects.create(bridge=self, damage_record=damage_rec) + + +class Reading(models.Model): + x = models.DecimalField(max_digits=4, decimal_places=2) + y = models.DecimalField(max_digits=4, decimal_places=2) + z = models.DecimalField(max_digits=4, decimal_places=2) + theta = models.DecimalField(max_digits=4, decimal_places=2) + phi = models.DecimalField(max_digits=4, decimal_places=2) + psi = models.DecimalField(max_digits=4, decimal_places=2) + bridge = models.ForeignKey(Bridge, on_delete=models.CASCADE, unique_for_date="time_taken") + time_taken = models.DateTimeField(auto_now_add=True) + + class Meta: + verbose_name = "Bridge Sensor Reading" + ordering = ["bridge__name", "-time_taken"] + + def __str__(self): + return "Reading for " + self.bridge.name + " at " + succinct_time_str(self.time_taken) + + def shows_anomaly(self): + return max_val(self.x, self.y, self.z) > THRESHOLD_DIS \ + or max_val(self.theta, self.phi, self.psi) > THRESHOLD_ROT + + +class BridgeLog(models.Model): + DAMAGE = "D" + REPAIR = "R" + LOG_TYPES = ((DAMAGE, "Damage Record"), + (REPAIR, "Repair Record")) + log_type = models.CharField(max_length=1, choices=LOG_TYPES) + log_time = models.DateTimeField(auto_now_add=True, primary_key=True) + bridge = models.ForeignKey(Bridge, on_delete=models.CASCADE, unique_for_date="log_time") + + class Meta: + ordering = ["bridge__name", "log_type", "-log_time"] + + def __str__(self): + return self.get_log_type_display() + " for " + self.bridge.name + " at " + succinct_time_str(self.log_time) + + def description(self): + return self.get_log_type_display() + " at " + str(self.log_time) + + def time_elapsed(self): + return timezone.now() - self.log_time + + def is_recent(self): + return self.time_elapsed() <= RECENT_PERIOD + + +class BrokenFlag(models.Model): + bridge = models.OneToOneField(Bridge, on_delete=models.CASCADE) + damage_record = models.OneToOneField(BridgeLog, on_delete=models.PROTECT) + + class Meta: + ordering = ["bridge__name"] + + def broken_time(self): + return self.damage_record.time_elapsed() diff --git a/calbridgesensors/sensors/signals.py b/calbridgesensors/sensors/signals.py new file mode 100644 index 0000000..e69de29 diff --git a/calbridgesensors/sensors/templatetags/__init__.py b/calbridgesensors/sensors/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/calbridgesensors/sensors/templatetags/sensors_filters.py b/calbridgesensors/sensors/templatetags/sensors_filters.py new file mode 100644 index 0000000..0fee682 --- /dev/null +++ b/calbridgesensors/sensors/templatetags/sensors_filters.py @@ -0,0 +1,10 @@ +from django import template +from django.template.defaultfilters import stringfilter + +register = template.Library() + + +@stringfilter +@register.filter(name='tourl') +def name_to_url(value): + return value.replace(" ", "-").lower() diff --git a/calbridgesensors/sensors/tests.py b/calbridgesensors/sensors/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/calbridgesensors/sensors/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/calbridgesensors/sensors/urls.py b/calbridgesensors/sensors/urls.py new file mode 100644 index 0000000..4703d90 --- /dev/null +++ b/calbridgesensors/sensors/urls.py @@ -0,0 +1,14 @@ +from django.urls import path, re_path, register_converter +from .converters import BridgeNameConverter +from . import views + +register_converter(BridgeNameConverter, 'brn') + +app_name = "sensors" + +urlpatterns = [ + path('', views.SensorsHomeView.as_view(), name='index'), + path('/', views.bridge_view, name='detail'), + #re_path(r'^(?P[\w-]+)/$', views.BridgeView.as_view(), name='detail'), + path('/update/', views.bridge_update) +] diff --git a/calbridgesensors/sensors/utils.py b/calbridgesensors/sensors/utils.py new file mode 100644 index 0000000..ac24743 --- /dev/null +++ b/calbridgesensors/sensors/utils.py @@ -0,0 +1,72 @@ +import re +import json +from .apps import CONNECTION_PASSWORD, CALIB_VAL +from dateutil import parser +from datetime import datetime + + +def name_validate(s): + target = r'[^ A-Za-z0-9]' + return re.sub(target, " ", s).title() + + +def check_abnomaly(r1, r2): + return True + + +def minv(a, b): + return a if a < b else b + + +def maxv(a, b): + return a if a > b else b + + +def min_val(a, b, c): + return minv(a, minv(b, c)) + + +def max_val(a, b, c): + return maxv(a, maxv(b, c)) + + +def verify_request(ck): + time_sign = parser.parse(ck['time']) + len_pw = len(CONNECTION_PASSWORD) + quest = ck['csrftoken'] + index = code_expr(time_sign) % len_pw + for i in range(len_pw): + if i != index and quest[i] != CONNECTION_PASSWORD[i]: + return False + return True + + +def code_expr(time_sign): + return time_sign.year + time_sign.month * 100 + time_sign.day \ + + time_sign.hour * time_sign.minute * time_sign.second + + +def succinct_time_str(dt): + return str(dt)[:19] + + +def calib_dp_to_di(dp): + return dp / CALIB_VAL + + +def decimal_rep(n): + return "%.4f" % n + + +def parse_db_time_string(time_string): + date = datetime.strptime(time_string.split('.')[0], '%Y-%m-%d %H:%M:%S') # String to object + return datetime.strftime(date, '%d %b %Y %H:%M:%S') + + +def parse_db_time(db_time): + date = datetime.strftime(db_time, '%Y-%m-%d %H:%M:%S') + return date + + + + diff --git a/calbridgesensors/sensors/views.py b/calbridgesensors/sensors/views.py new file mode 100644 index 0000000..fd6f91c --- /dev/null +++ b/calbridgesensors/sensors/views.py @@ -0,0 +1,97 @@ +from django.shortcuts import render, get_object_or_404 +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.decorators import login_required +from django.views.generic import DetailView +from django.http import HttpResponse +from django.views.generic.base import TemplateView +from .models import Bridge, BrokenFlag, Reading +from .utils import verify_request, calib_dp_to_di, decimal_rep, parse_db_time +from django.views.decorators.csrf import csrf_exempt, csrf_protect +import json + + +class SensorsHomeView(LoginRequiredMixin, TemplateView): + """View for home page""" + template_name = "sensors/index.html" + login_url = "/accounts/login/" + + def get_context_data(self, **kwargs): + broken_bridges = BrokenFlag.objects.all() + return {"user": self.request.user, "broken_bridges": broken_bridges, "bridges": Bridge.objects.all()} + + +"""class BridgeView(LoginRequiredMixin, DetailView): + model = Bridge + template_name = "sensors/detail.html" + login_url = "/accounts/login/" + context_object_name = "bridge" + + def get_context_data(self, **kwargs): + return {"user": self.request.user}.update(super().get_context_data(**kwargs))""" + + +@login_required(login_url='/accounts/login/') +def bridge_view(request, pk): + bridge = get_object_or_404(Bridge, pk=pk) + readings = bridge.reading_set.all() + len_reading = len(readings) + ground_zero = readings[len_reading - 1] + ground_zero_x = ground_zero.x + ground_zero_y = ground_zero.y + calibrated = [(0.0, 0.0, None)] * len_reading + calibratedx = [0.0] * len_reading + calibratedy = [0.0] * len_reading + dates = [None] * len_reading + for i in range(len_reading): + curr = readings[i] + dx = decimal_rep(calib_dp_to_di(curr.x - ground_zero_x)) + dy = decimal_rep(calib_dp_to_di(curr.y - ground_zero_y)) + dt = curr.time_taken + calibrated[len_reading - i - 1] = (dx, dy, parse_db_time(dt)) + calibratedx[i] = dx + calibratedy[i] = dy + calib_json = json.dumps(calibrated) + #print(calibrated[-10:]) + #json_readings = json.dumps(readings) + context = {"user": request.user, + "damage_recs": bridge.get_damage_records(), + "repair_recs": bridge.get_repair_records(), + "bridge": bridge, + "reading": bridge.latest_reading(), + "readings": calib_json, + "readingsx": calibratedx, + "readingsy": calibratedy + } + return render(request, "sensors/detail.html", context=context) + + +@csrf_exempt +def bridge_update(request, pk): + """JSON""" + def update_procedure(): + # Connects the front-end request with backend database process + try: + br = Bridge.objects.get(pk=pk) + except Bridge.DoesNotExist: + return HttpResponse(content='Bridge Unregistered', status=412) + br.update(request.POST) # Should resolve all sorts of issues by passing a dictionary in + return HttpResponse('BONJOUR') + + @csrf_protect + def protected_update(r, p): + return update_procedure() + + if verify_request(request.COOKIES): + return update_procedure() + else: + return protected_update(request, pk) + + + + + + + + + + diff --git a/calbridgesensors/static/plotly.js b/calbridgesensors/static/plotly.js new file mode 100644 index 0000000..6753b8d --- /dev/null +++ b/calbridgesensors/static/plotly.js @@ -0,0 +1,7 @@ +/** +* plotly.js v1.39.3 +* Copyright 2012-2018, Plotly, Inc. +* All rights reserved. +* Licensed under the MIT license +*/ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Plotly=t()}}(function(){return function(){return function t(e,r,n){function i(o,s){if(!r[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var u=r[o]={exports:{}};e[o][0].call(u.exports,function(t){var r=e[o][1][t];return i(r||t)},u,u.exports,t,e,r,n)}return r[o].exports}for(var a="function"==typeof require&&require,o=0;oMath.abs(e))c.rotate(o,0,0,-t*i*Math.PI*d.rotateSpeed/window.innerWidth);else{var s=d.zoomSpeed*a*e/window.innerHeight*(o-c.lastT())/100;c.pan(o,0,0,h*(Math.exp(s)-1))}},!0),d};var n=t("right-now"),i=t("3d-view"),a=t("mouse-change"),o=t("mouse-wheel"),s=t("mouse-event-offset"),l=t("has-passive-events")},{"3d-view":43,"has-passive-events":379,"mouse-change":402,"mouse-event-offset":403,"mouse-wheel":405,"right-now":465}],43:[function(t,e,r){"use strict";e.exports=function(t){var e=(t=t||{}).eye||[0,0,1],r=t.center||[0,0,0],s=t.up||[0,1,0],l=t.distanceLimits||[0,1/0],c=t.mode||"turntable",u=n(),h=i(),f=a();return u.setDistanceLimits(l[0],l[1]),u.lookAt(0,e,r,s),h.setDistanceLimits(l[0],l[1]),h.lookAt(0,e,r,s),f.setDistanceLimits(l[0],l[1]),f.lookAt(0,e,r,s),new o({turntable:u,orbit:h,matrix:f},c)};var n=t("turntable-camera-controller"),i=t("orbit-camera-controller"),a=t("matrix-camera-controller");function o(t,e){this._controllerNames=Object.keys(t),this._controllerList=this._controllerNames.map(function(e){return t[e]}),this._mode=e,this._active=t[e],this._active||(this._mode="turntable",this._active=t.turntable),this.modes=this._controllerNames,this.computedMatrix=this._active.computedMatrix,this.computedEye=this._active.computedEye,this.computedUp=this._active.computedUp,this.computedCenter=this._active.computedCenter,this.computedRadius=this._active.computedRadius}var s=o.prototype;[["flush",1],["idle",1],["lookAt",4],["rotate",4],["pan",4],["translate",4],["setMatrix",2],["setDistanceLimits",2],["setDistance",2]].forEach(function(t){for(var e=t[0],r=[],n=0;n halfCharStep + halfCharWidth ||\n\t\t\t\t\tfloor(uv.x) < halfCharStep - halfCharWidth) return;\n\n\t\t\t\tuv += charId * charStep;\n\t\t\t\tuv = uv / atlasSize;\n\n\t\t\t\tvec4 color = fontColor;\n\t\t\t\tvec4 mask = texture2D(atlas, uv);\n\n\t\t\t\tfloat maskY = lightness(mask);\n\t\t\t\t// float colorY = lightness(color);\n\t\t\t\tcolor.a *= maskY;\n\t\t\t\tcolor.a *= opacity;\n\n\t\t\t\t// color.a += .1;\n\n\t\t\t\t// antialiasing, see yiq color space y-channel formula\n\t\t\t\t// color.rgb += (1. - color.rgb) * (1. - mask.rgb);\n\n\t\t\t\tgl_FragColor = color;\n\t\t\t}"});return{regl:t,draw:e,atlas:{}}},w.prototype.update=function(t){var e=this;if("string"==typeof t)t={text:t};else if(!t)return;null!=(t=i(t,{position:"position positions coord coords coordinates",font:"font fontFace fontface typeface cssFont css-font family fontFamily",fontSize:"fontSize fontsize size font-size",text:"text texts chars characters value values symbols",align:"align alignment textAlign textbaseline",baseline:"baseline textBaseline textbaseline",direction:"dir direction textDirection",color:"color colour fill fill-color fillColor textColor textcolor",kerning:"kerning kern",range:"range dataBox",viewport:"vp viewport viewBox viewbox viewPort",opacity:"opacity alpha transparency visible visibility opaque",offset:"offset positionOffset padding shift indent indentation"},!0)).opacity&&(Array.isArray(t.opacity)?this.opacity=t.opacity.map(function(t){return parseFloat(t)}):this.opacity=parseFloat(t.opacity)),null!=t.viewport&&(this.viewport=h(t.viewport),w.normalViewport&&(this.viewport.y=this.canvas.height-this.viewport.y-this.viewport.height),this.viewportArray=[this.viewport.x,this.viewport.y,this.viewport.width,this.viewport.height]),null==this.viewport&&(this.viewport={x:0,y:0,width:this.gl.drawingBufferWidth,height:this.gl.drawingBufferHeight},this.viewportArray=[this.viewport.x,this.viewport.y,this.viewport.width,this.viewport.height]),null!=t.kerning&&(this.kerning=t.kerning),null!=t.offset&&("number"==typeof t.offset&&(t.offset=[t.offset,0]),this.positionOffset=y(t.offset)),t.direction&&(this.direction=t.direction),t.range&&(this.range=t.range,this.scale=[1/(t.range[2]-t.range[0]),1/(t.range[3]-t.range[1])],this.translate=[-t.range[0],-t.range[1]]),t.scale&&(this.scale=t.scale),t.translate&&(this.translate=t.translate),this.scale||(this.scale=[1/this.viewport.width,1/this.viewport.height]),this.translate||(this.translate=[0,0]),this.font.length||t.font||(t.font=w.baseFontSize+"px sans-serif");var r,a=!1,o=!1;if(t.font&&(Array.isArray(t.font)?t.font:[t.font]).forEach(function(t,r){if("string"==typeof t)try{t=n.parse(t)}catch(e){t=n.parse(w.baseFontSize+"px "+t)}else t=n.parse(n.stringify(t));var i=n.stringify({size:w.baseFontSize,family:t.family,stretch:b?t.stretch:void 0,variant:t.variant,weight:t.weight,style:t.style}),s=p(t.size),l=Math.round(s[0]*d(s[1]));if(l!==e.fontSize[r]&&(o=!0,e.fontSize[r]=l),!(e.font[r]&&i==e.font[r].baseString||(a=!0,e.font[r]=w.fonts[i],e.font[r]))){var c=t.family.join(", "),u=[t.style];t.style!=t.variant&&u.push(t.variant),t.variant!=t.weight&&u.push(t.weight),b&&t.weight!=t.stretch&&u.push(t.stretch),e.font[r]={baseString:i,family:c,weight:t.weight,stretch:t.stretch,style:t.style,variant:t.variant,width:{},kerning:{},metrics:v(c,{origin:"top",fontSize:w.baseFontSize,fontStyle:u.join(" ")})},w.fonts[i]=e.font[r]}}),(a||o)&&this.font.forEach(function(r,i){var a=n.stringify({size:e.fontSize[i],family:r.family,stretch:b?r.stretch:void 0,variant:r.variant,weight:r.weight,style:r.style});if(e.fontAtlas[i]=e.shader.atlas[a],!e.fontAtlas[i]){var o=r.metrics;e.shader.atlas[a]=e.fontAtlas[i]={fontString:a,step:2*Math.ceil(e.fontSize[i]*o.bottom*.5),em:e.fontSize[i],cols:0,rows:0,height:0,width:0,chars:[],ids:{},texture:e.regl.texture()}}null==t.text&&(t.text=e.text)}),"string"==typeof t.text&&t.position&&t.position.length>2){for(var s=Array(.5*t.position.length),f=0;f2){for(var _=!t.position[0].length,k=u.mallocFloat(2*this.count),M=0,A=0;M1?e.align[r]:e.align[0]:e.align;if("number"==typeof n)return n;switch(n){case"right":case"end":return-t;case"center":case"centre":case"middle":return.5*-t}return 0})),null==this.baseline&&null==t.baseline&&(t.baseline=0),null!=t.baseline&&(this.baseline=t.baseline,Array.isArray(this.baseline)||(this.baseline=[this.baseline]),this.baselineOffset=this.baseline.map(function(t,r){var n=(e.font[r]||e.font[0]).metrics,i=0;return i+=.5*n.bottom,i+="number"==typeof t?t-n.baseline:-n[t],w.normalViewport||(i*=-1),i})),null!=t.color)if(t.color||(t.color="transparent"),"string"!=typeof t.color&&isNaN(t.color)){var q;if("number"==typeof t.color[0]&&t.color.length>this.counts.length){var H=t.color.length;q=u.mallocUint8(H);for(var G=(t.color.subarray||t.color.slice).bind(t.color),W=0;W4||this.baselineOffset.length>1||this.align&&this.align.length>1||this.fontAtlas.length>1||this.positionOffset.length>2){var Z=Math.max(.5*this.position.length||0,.25*this.color.length||0,this.baselineOffset.length||0,this.alignOffset.length||0,this.font.length||0,this.opacity.length||0,.5*this.positionOffset.length||0);this.batch=Array(Z);for(var $=0;$1?e.counts[$]:e.counts[0],offset:e.textOffsets.length>1?e.textOffsets[$]:e.textOffsets[0],color:e.color?e.color.length<=4?e.color:e.color.subarray(4*$,4*$+4):[0,0,0,255],opacity:Array.isArray(e.opacity)?e.opacity[$]:e.opacity,baseline:null!=e.baselineOffset[$]?e.baselineOffset[$]:e.baselineOffset[0],align:e.align?null!=e.alignOffset[$]?e.alignOffset[$]:e.alignOffset[0]:0,atlas:e.fontAtlas[$]||e.fontAtlas[0],positionOffset:e.positionOffset.length>2?e.positionOffset.subarray(2*$,2*$+2):e.positionOffset}}else this.count?this.batch=[{count:this.count,offset:0,color:this.color||[0,0,0,255],opacity:Array.isArray(this.opacity)?this.opacity[0]:this.opacity,baseline:this.baselineOffset[0],align:this.alignOffset?this.alignOffset[0]:0,atlas:this.fontAtlas[0],positionOffset:this.positionOffset}]:this.batch=[]},w.prototype.destroy=function(){},w.prototype.kerning=!0,w.prototype.position={constant:new Float32Array(2)},w.prototype.translate=null,w.prototype.scale=null,w.prototype.font=null,w.prototype.text="",w.prototype.positionOffset=[0,0],w.prototype.opacity=1,w.prototype.color=new Uint8Array([0,0,0,255]),w.prototype.alignOffset=[0,0],w.normalViewport=!1,w.maxAtlasSize=1024,w.atlasCanvas=document.createElement("canvas"),w.atlasContext=w.atlasCanvas.getContext("2d",{alpha:!1}),w.baseFontSize=64,w.fonts={},e.exports=w},{"color-normalize":45,"css-font":126,"detect-kerning":150,"es6-weak-map":208,"flatten-vertex-data":48,"font-atlas":217,"font-measure":218,"gl-util/context":304,"is-plain-obj":390,"object-assign":421,"parse-rect":426,"parse-unit":428,"pick-by-alias":432,regl:463,"to-px":501,"typedarray-pool":507}],45:[function(t,e,r){"use strict";var n=t("color-rgba"),i=t("clamp"),a=t("dtype");e.exports=function(t,e){"float"!==e&&e||(e="array"),"uint"===e&&(e="uint8"),"uint_clamped"===e&&(e="uint8_clamped");var r=a(e),o=new r(4);if(t instanceof r)return Array.isArray(t)?t.slice():(o.set(t),o);var s="uint8"!==e&&"uint8_clamped"!==e;return t instanceof Uint8Array||t instanceof Uint8ClampedArray?(o[0]=t[0],o[1]=t[1],o[2]=t[2],o[3]=null!=t[3]?t[3]:255,s&&(o[0]/=255,o[1]/=255,o[2]/=255,o[3]/=255),o):(t.length&&"string"!=typeof t||((t=n(t))[0]/=255,t[1]/=255,t[2]/=255),s?(o[0]=t[0],o[1]=t[1],o[2]=t[2],o[3]=null!=t[3]?t[3]:1):(o[0]=i(Math.round(255*t[0]),0,255),o[1]=i(Math.round(255*t[1]),0,255),o[2]=i(Math.round(255*t[2]),0,255),o[3]=null==t[3]?255:i(Math.floor(255*t[3]),0,255)),o)}},{clamp:102,"color-rgba":47,dtype:153}],46:[function(t,e,r){(function(r){"use strict";var n=t("color-name"),i=t("is-plain-obj"),a=t("defined");e.exports=function(t){var e,s,l=[],c=1;if("string"==typeof t)if(n[t])l=n[t].slice(),s="rgb";else if("transparent"===t)c=0,s="rgb",l=[0,0,0];else if(/^#[A-Fa-f0-9]+$/.test(t)){var u=t.slice(1),h=u.length,f=h<=4;c=1,f?(l=[parseInt(u[0]+u[0],16),parseInt(u[1]+u[1],16),parseInt(u[2]+u[2],16)],4===h&&(c=parseInt(u[3]+u[3],16)/255)):(l=[parseInt(u[0]+u[1],16),parseInt(u[2]+u[3],16),parseInt(u[4]+u[5],16)],8===h&&(c=parseInt(u[6]+u[7],16)/255)),l[0]||(l[0]=0),l[1]||(l[1]=0),l[2]||(l[2]=0),s="rgb"}else if(e=/^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(t)){var p=e[1],u=p.replace(/a$/,"");s=u;var h="cmyk"===u?4:"gray"===u?1:3;l=e[2].trim().split(/\s*,\s*/).map(function(t,e){if(/%$/.test(t))return e===h?parseFloat(t)/100:"rgb"===u?255*parseFloat(t)/100:parseFloat(t);if("h"===u[e]){if(/deg$/.test(t))return parseFloat(t);if(void 0!==o[t])return o[t]}return parseFloat(t)}),p===u&&l.push(1),c=void 0===l[h]?1:l[h],l=l.slice(0,h)}else t.length>10&&/[0-9](?:\s|\/)/.test(t)&&(l=t.match(/([0-9]+)/g).map(function(t){return parseFloat(t)}),s=t.match(/([a-z])/ig).join("").toLowerCase());else if(isNaN(t))if(i(t)){var d=a(t.r,t.red,t.R,null);null!==d?(s="rgb",l=[d,a(t.g,t.green,t.G),a(t.b,t.blue,t.B)]):(s="hsl",l=[a(t.h,t.hue,t.H),a(t.s,t.saturation,t.S),a(t.l,t.lightness,t.L,t.b,t.brightness)]),c=a(t.a,t.alpha,t.opacity,1),null!=t.opacity&&(c/=100)}else(Array.isArray(t)||r.ArrayBuffer&&ArrayBuffer.isView&&ArrayBuffer.isView(t))&&(l=[t[0],t[1],t[2]],s="rgb",c=4===t.length?t[3]:1);else s="rgb",l=[t>>>16,(65280&t)>>>8,255&t];return{space:s,values:l,alpha:c}};var o={red:0,orange:60,yellow:120,green:180,blue:240,purple:300}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"color-name":106,defined:148,"is-plain-obj":390}],47:[function(t,e,r){"use strict";var n=t("color-parse"),i=t("color-space/hsl"),a=t("clamp");e.exports=function(t){var e,r=n(t);return r.space?((e=Array(3))[0]=a(r.values[0],0,255),e[1]=a(r.values[1],0,255),e[2]=a(r.values[2],0,255),"h"===r.space[0]&&(e=i.rgb(e)),e.push(a(r.alpha,0,1)),e):[]}},{clamp:102,"color-parse":46,"color-space/hsl":110}],48:[function(t,e,r){var n=t("dtype");e.exports=function(t,e,r){if(!t)throw new TypeError("must specify data as first parameter");if(r=0|+(r||0),Array.isArray(t)&&t[0]&&"number"==typeof t[0][0]){var i,a,o,s,l=t[0].length,c=t.length*l;e&&"string"!=typeof e||(e=new(n(e||"float32"))(c+r));var u=e.length-r;if(c!==u)throw new Error("source length "+c+" ("+l+"x"+t.length+") does not match destination length "+u);for(i=0,o=r;i0;--t)p(c*=.99),d(),f(c),d();function f(t){function r(t){return u(t.source)*t.value}i.forEach(function(n){n.forEach(function(n){if(n.targetLinks.length){var i=e.sum(n.targetLinks,r)/e.sum(n.targetLinks,h);n.y+=(i-u(n))*t}})})}function p(t){function r(t){return u(t.target)*t.value}i.slice().reverse().forEach(function(n){n.forEach(function(n){if(n.sourceLinks.length){var i=e.sum(n.sourceLinks,r)/e.sum(n.sourceLinks,h);n.y+=(i-u(n))*t}})})}function d(){i.forEach(function(t){var e,r,n,i=0,s=t.length;for(t.sort(g),n=0;n0&&(e.y+=r),i=e.y+e.dy+a;if((r=i-a-o[1])>0)for(i=e.y-=r,n=s-2;n>=0;--n)e=t[n],(r=e.y+e.dy+a-i)>0&&(e.y-=r),i=e.y})}function g(t,e){return t.y-e.y}}(n),c(),t},t.relayout=function(){return c(),t},t.link=function(){var t=.5;function e(e){var r=e.source.x+e.source.dx,i=e.target.x,a=n.interpolateNumber(r,i),o=a(t),s=a(1-t),l=e.source.y+e.sy,c=l+e.dy,u=e.target.y+e.ty,h=u+e.dy;return"M"+r+","+l+"C"+o+","+l+" "+s+","+u+" "+i+","+u+"L"+i+","+h+"C"+s+","+h+" "+o+","+c+" "+r+","+c+"Z"}return e.curvature=function(r){return arguments.length?(t=+r,e):t},e},t},Object.defineProperty(t,"__esModule",{value:!0})},"object"==typeof r&&"undefined"!=typeof e?i(r,t("d3-array"),t("d3-collection"),t("d3-interpolate")):i(n.d3=n.d3||{},n.d3,n.d3,n.d3)},{"d3-array":139,"d3-collection":140,"d3-interpolate":144}],50:[function(t,e,r){"use strict";var n="undefined"==typeof WeakMap?t("weak-map"):WeakMap,i=t("gl-buffer"),a=t("gl-vao"),o=new n;e.exports=function(t){var e=o.get(t),r=e&&(e._triangleBuffer.handle||e._triangleBuffer.buffer);if(!r||!t.isBuffer(r)){var n=i(t,new Float32Array([-1,-1,-1,4,4,-1]));(e=a(t,[{buffer:n,type:t.FLOAT,size:2}]))._triangleBuffer=n,o.set(t,e)}e.bind(),t.drawArrays(t.TRIANGLES,0,3),e.unbind()}},{"gl-buffer":230,"gl-vao":308,"weak-map":517}],51:[function(t,e,r){e.exports=function(t){var e=0,r=0,n=0,i=0;return t.map(function(t){var a=(t=t.slice())[0],o=a.toUpperCase();if(a!=o)switch(t[0]=o,a){case"a":t[6]+=n,t[7]+=i;break;case"v":t[1]+=i;break;case"h":t[1]+=n;break;default:for(var s=1;si&&(i=t[o]),t[o]=0;c--)if(u[c]!==h[c])return!1;for(c=u.length-1;c>=0;c--)if(l=u[c],!y(t[l],e[l],r,n))return!1;return!0}(t,e,r,o))}return r?t===e:t==e}function x(t){return"[object Arguments]"==Object.prototype.toString.call(t)}function b(t,e){if(!t||!e)return!1;if("[object RegExp]"==Object.prototype.toString.call(e))return e.test(t);try{if(t instanceof e)return!0}catch(t){}return!Error.isPrototypeOf(e)&&!0===e.call({},t)}function _(t,e,r,n){var i;if("function"!=typeof e)throw new TypeError('"block" argument must be a function');"string"==typeof r&&(n=r,r=null),i=function(t){var e;try{t()}catch(t){e=t}return e}(e),n=(r&&r.name?" ("+r.name+").":".")+(n?" "+n:"."),t&&!i&&m(i,r,"Missing expected exception"+n);var o="string"==typeof n,s=!t&&i&&!r;if((!t&&a.isError(i)&&o&&b(i,r)||s)&&m(i,r,"Got unwanted exception"+n),t&&i&&r&&!b(i,r)||!t&&i)throw i}h.AssertionError=function(t){var e;this.name="AssertionError",this.actual=t.actual,this.expected=t.expected,this.operator=t.operator,t.message?(this.message=t.message,this.generatedMessage=!1):(this.message=d(g((e=this).actual),128)+" "+e.operator+" "+d(g(e.expected),128),this.generatedMessage=!0);var r=t.stackStartFunction||m;if(Error.captureStackTrace)Error.captureStackTrace(this,r);else{var n=new Error;if(n.stack){var i=n.stack,a=p(r),o=i.indexOf("\n"+a);if(o>=0){var s=i.indexOf("\n",o+1);i=i.substring(s+1)}this.stack=i}}},a.inherits(h.AssertionError,Error),h.fail=m,h.ok=v,h.equal=function(t,e,r){t!=e&&m(t,e,r,"==",h.equal)},h.notEqual=function(t,e,r){t==e&&m(t,e,r,"!=",h.notEqual)},h.deepEqual=function(t,e,r){y(t,e,!1)||m(t,e,r,"deepEqual",h.deepEqual)},h.deepStrictEqual=function(t,e,r){y(t,e,!0)||m(t,e,r,"deepStrictEqual",h.deepStrictEqual)},h.notDeepEqual=function(t,e,r){y(t,e,!1)&&m(t,e,r,"notDeepEqual",h.notDeepEqual)},h.notDeepStrictEqual=function t(e,r,n){y(e,r,!0)&&m(e,r,n,"notDeepStrictEqual",t)},h.strictEqual=function(t,e,r){t!==e&&m(t,e,r,"===",h.strictEqual)},h.notStrictEqual=function(t,e,r){t===e&&m(t,e,r,"!==",h.notStrictEqual)},h.throws=function(t,e,r){_(!0,t,e,r)},h.doesNotThrow=function(t,e,r){_(!1,t,e,r)},h.ifError=function(t){if(t)throw t};var w=Object.keys||function(t){var e=[];for(var r in t)o.call(t,r)&&e.push(r);return e}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"util/":514}],60:[function(t,e,r){e.exports=function(t){return atob(t)}},{}],61:[function(t,e,r){"use strict";e.exports=function(t,e){for(var r=e.length,a=new Array(r+1),o=0;o0?l-4:l;var u=0;for(e=0;e>16&255,s[u++]=n>>8&255,s[u++]=255&n;2===o?(n=i[t.charCodeAt(e)]<<2|i[t.charCodeAt(e+1)]>>4,s[u++]=255&n):1===o&&(n=i[t.charCodeAt(e)]<<10|i[t.charCodeAt(e+1)]<<4|i[t.charCodeAt(e+2)]>>2,s[u++]=n>>8&255,s[u++]=255&n);return s},r.fromByteArray=function(t){for(var e,r=t.length,i=r%3,a="",o=[],s=0,l=r-i;sl?l:s+16383));1===i?(e=t[r-1],a+=n[e>>2],a+=n[e<<4&63],a+="=="):2===i&&(e=(t[r-2]<<8)+t[r-1],a+=n[e>>10],a+=n[e>>4&63],a+=n[e<<2&63],a+="=");return o.push(a),o.join("")};for(var n=[],i=[],a="undefined"!=typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,l=o.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");return"="===t[e-2]?2:"="===t[e-1]?1:0}function u(t,e,r){for(var i,a,o=[],s=e;s>18&63]+n[a>>12&63]+n[a>>6&63]+n[63&a]);return o.join("")}i["-".charCodeAt(0)]=62,i["_".charCodeAt(0)]=63},{}],63:[function(t,e,r){"use strict";var n=t("./lib/rationalize");e.exports=function(t,e){return n(t[0].mul(e[1]).add(e[0].mul(t[1])),t[1].mul(e[1]))}},{"./lib/rationalize":73}],64:[function(t,e,r){"use strict";e.exports=function(t,e){return t[0].mul(e[1]).cmp(e[0].mul(t[1]))}},{}],65:[function(t,e,r){"use strict";var n=t("./lib/rationalize");e.exports=function(t,e){return n(t[0].mul(e[1]),t[1].mul(e[0]))}},{"./lib/rationalize":73}],66:[function(t,e,r){"use strict";var n=t("./is-rat"),i=t("./lib/is-bn"),a=t("./lib/num-to-bn"),o=t("./lib/str-to-bn"),s=t("./lib/rationalize"),l=t("./div");e.exports=function t(e,r){if(n(e))return r?l(e,t(r)):[e[0].clone(),e[1].clone()];var c=0;var u,h;if(i(e))u=e.clone();else if("string"==typeof e)u=o(e);else{if(0===e)return[a(0),a(1)];if(e===Math.floor(e))u=a(e);else{for(;e!==Math.floor(e);)e*=Math.pow(2,256),c-=256;u=a(e)}}if(n(r))u.mul(r[1]),h=r[0].clone();else if(i(r))h=r.clone();else if("string"==typeof r)h=o(r);else if(r)if(r===Math.floor(r))h=a(r);else{for(;r!==Math.floor(r);)r*=Math.pow(2,256),c+=256;h=a(r)}else h=a(1);c>0?u=u.ushln(c):c<0&&(h=h.ushln(-c));return s(u,h)}},{"./div":65,"./is-rat":67,"./lib/is-bn":71,"./lib/num-to-bn":72,"./lib/rationalize":73,"./lib/str-to-bn":74}],67:[function(t,e,r){"use strict";var n=t("./lib/is-bn");e.exports=function(t){return Array.isArray(t)&&2===t.length&&n(t[0])&&n(t[1])}},{"./lib/is-bn":71}],68:[function(t,e,r){"use strict";var n=t("bn.js");e.exports=function(t){return t.cmp(new n(0))}},{"bn.js":82}],69:[function(t,e,r){"use strict";var n=t("./bn-sign");e.exports=function(t){var e=t.length,r=t.words,i=0;if(1===e)i=r[0];else if(2===e)i=r[0]+67108864*r[1];else for(var a=0;a20)return 52;return r+32}},{"bit-twiddle":80,"double-bits":151}],71:[function(t,e,r){"use strict";t("bn.js");e.exports=function(t){return t&&"object"==typeof t&&Boolean(t.words)}},{"bn.js":82}],72:[function(t,e,r){"use strict";var n=t("bn.js"),i=t("double-bits");e.exports=function(t){var e=i.exponent(t);return e<52?new n(t):new n(t*Math.pow(2,52-e)).ushln(e-52)}},{"bn.js":82,"double-bits":151}],73:[function(t,e,r){"use strict";var n=t("./num-to-bn"),i=t("./bn-sign");e.exports=function(t,e){var r=i(t),a=i(e);if(0===r)return[n(0),n(1)];if(0===a)return[n(0),n(0)];a<0&&(t=t.neg(),e=e.neg());var o=t.gcd(e);if(o.cmpn(1))return[t.div(o),e.div(o)];return[t,e]}},{"./bn-sign":68,"./num-to-bn":72}],74:[function(t,e,r){"use strict";var n=t("bn.js");e.exports=function(t){return new n(t)}},{"bn.js":82}],75:[function(t,e,r){"use strict";var n=t("./lib/rationalize");e.exports=function(t,e){return n(t[0].mul(e[0]),t[1].mul(e[1]))}},{"./lib/rationalize":73}],76:[function(t,e,r){"use strict";var n=t("./lib/bn-sign");e.exports=function(t){return n(t[0])*n(t[1])}},{"./lib/bn-sign":68}],77:[function(t,e,r){"use strict";var n=t("./lib/rationalize");e.exports=function(t,e){return n(t[0].mul(e[1]).sub(t[1].mul(e[0])),t[1].mul(e[1]))}},{"./lib/rationalize":73}],78:[function(t,e,r){"use strict";var n=t("./lib/bn-to-num"),i=t("./lib/ctz");e.exports=function(t){var e=t[0],r=t[1];if(0===e.cmpn(0))return 0;var a=e.abs().divmod(r.abs()),o=a.div,s=n(o),l=a.mod,c=e.negative!==r.negative?-1:1;if(0===l.cmpn(0))return c*s;if(s){var u=i(s)+4,h=n(l.ushln(u).divRound(r));return c*(s+h*Math.pow(2,-u))}var f=r.bitLength()-l.bitLength()+53,h=n(l.ushln(f).divRound(r));return f<1023?c*h*Math.pow(2,-f):(h*=Math.pow(2,-1023),c*h*Math.pow(2,1023-f))}},{"./lib/bn-to-num":69,"./lib/ctz":70}],79:[function(t,e,r){"use strict";function n(t,e,r,n,i,a){var o=["function ",t,"(a,l,h,",n.join(","),"){",a?"":"var i=",r?"l-1":"h+1",";while(l<=h){var m=(l+h)>>>1,x=a",i?".get(m)":"[m]"];return a?e.indexOf("c")<0?o.push(";if(x===y){return m}else if(x<=y){"):o.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){"):o.push(";if(",e,"){i=m;"),r?o.push("l=m+1}else{h=m-1}"):o.push("h=m-1}else{l=m+1}"),o.push("}"),a?o.push("return -1};"):o.push("return i};"),o.join("")}function i(t,e,r,i){return new Function([n("A","x"+t+"y",e,["y"],!1,i),n("B","x"+t+"y",e,["y"],!0,i),n("P","c(x,y)"+t+"0",e,["y","c"],!1,i),n("Q","c(x,y)"+t+"0",e,["y","c"],!0,i),"function dispatchBsearch",r,"(a,y,c,l,h){if(a.shape){if(typeof(c)==='function'){return Q(a,(l===undefined)?0:l|0,(h===undefined)?a.shape[0]-1:h|0,y,c)}else{return B(a,(c===undefined)?0:c|0,(l===undefined)?a.shape[0]-1:l|0,y)}}else{if(typeof(c)==='function'){return P(a,(l===undefined)?0:l|0,(h===undefined)?a.length-1:h|0,y,c)}else{return A(a,(c===undefined)?0:c|0,(l===undefined)?a.length-1:l|0,y)}}}return dispatchBsearch",r].join(""))()}e.exports={ge:i(">=",!1,"GE"),gt:i(">",!1,"GT"),lt:i("<",!0,"LT"),le:i("<=",!0,"LE"),eq:i("-",!0,"EQ",!0)}},{}],80:[function(t,e,r){"use strict";"use restrict";function n(t){var e=32;return(t&=-t)&&e--,65535&t&&(e-=16),16711935&t&&(e-=8),252645135&t&&(e-=4),858993459&t&&(e-=2),1431655765&t&&(e-=1),e}r.INT_BITS=32,r.INT_MAX=2147483647,r.INT_MIN=-1<<31,r.sign=function(t){return(t>0)-(t<0)},r.abs=function(t){var e=t>>31;return(t^e)-e},r.min=function(t,e){return e^(t^e)&-(t65535)<<4,e|=r=((t>>>=e)>255)<<3,e|=r=((t>>>=r)>15)<<2,(e|=r=((t>>>=r)>3)<<1)|(t>>>=r)>>1},r.log10=function(t){return t>=1e9?9:t>=1e8?8:t>=1e7?7:t>=1e6?6:t>=1e5?5:t>=1e4?4:t>=1e3?3:t>=100?2:t>=10?1:0},r.popCount=function(t){return 16843009*((t=(858993459&(t-=t>>>1&1431655765))+(t>>>2&858993459))+(t>>>4)&252645135)>>>24},r.countTrailingZeros=n,r.nextPow2=function(t){return t+=0===t,--t,t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,(t|=t>>>16)+1},r.prevPow2=function(t){return t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,(t|=t>>>16)-(t>>>1)},r.parity=function(t){return t^=t>>>16,t^=t>>>8,t^=t>>>4,27030>>>(t&=15)&1};var i=new Array(256);!function(t){for(var e=0;e<256;++e){var r=e,n=e,i=7;for(r>>>=1;r;r>>>=1)n<<=1,n|=1&r,--i;t[e]=n<>>8&255]<<16|i[t>>>16&255]<<8|i[t>>>24&255]},r.interleave2=function(t,e){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t&=65535)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e&=65535)|e<<8))|e<<4))|e<<2))|e<<1))<<1},r.deinterleave2=function(t,e){return(t=65535&((t=16711935&((t=252645135&((t=858993459&((t=t>>>e&1431655765)|t>>>1))|t>>>2))|t>>>4))|t>>>16))<<16>>16},r.interleave3=function(t,e,r){return t=1227133513&((t=3272356035&((t=251719695&((t=4278190335&((t&=1023)|t<<16))|t<<8))|t<<4))|t<<2),(t|=(e=1227133513&((e=3272356035&((e=251719695&((e=4278190335&((e&=1023)|e<<16))|e<<8))|e<<4))|e<<2))<<1)|(r=1227133513&((r=3272356035&((r=251719695&((r=4278190335&((r&=1023)|r<<16))|r<<8))|r<<4))|r<<2))<<2},r.deinterleave3=function(t,e){return(t=1023&((t=4278190335&((t=251719695&((t=3272356035&((t=t>>>e&1227133513)|t>>>2))|t>>>4))|t>>>8))|t>>>16))<<22>>22},r.nextCombination=function(t){var e=t|t-1;return e+1|(~e&-~e)-1>>>n(t)+1}},{}],81:[function(t,e,r){"use strict";var n=t("clamp");e.exports=function(t,e){e||(e={});var r,o,s,l,c,u,h,f,p,d,g,m=null==e.cutoff?.25:e.cutoff,v=null==e.radius?8:e.radius,y=e.channel||0;if(ArrayBuffer.isView(t)||Array.isArray(t)){if(!e.width||!e.height)throw Error("For raw data width and height should be provided by options");r=e.width,o=e.height,l=t,u=e.stride?e.stride:Math.floor(t.length/r/o)}else window.HTMLCanvasElement&&t instanceof window.HTMLCanvasElement?(h=(f=t).getContext("2d"),r=f.width,o=f.height,p=h.getImageData(0,0,r,o),l=p.data,u=4):window.CanvasRenderingContext2D&&t instanceof window.CanvasRenderingContext2D?(f=t.canvas,h=t,r=f.width,o=f.height,p=h.getImageData(0,0,r,o),l=p.data,u=4):window.ImageData&&t instanceof window.ImageData&&(p=t,r=t.width,o=t.height,l=p.data,u=4);if(s=Math.max(r,o),window.Uint8ClampedArray&&l instanceof window.Uint8ClampedArray||window.Uint8Array&&l instanceof window.Uint8Array)for(c=l,l=Array(r*o),d=0,g=c.length;d=49&&o<=54?o-49+10:o>=17&&o<=22?o-17+10:15&o}return n}function l(t,e,r,n){for(var i=0,a=Math.min(t.length,r),o=e;o=49?s-49+10:s>=17?s-17+10:s}return i}a.isBN=function(t){return t instanceof a||null!==t&&"object"==typeof t&&t.constructor.wordSize===a.wordSize&&Array.isArray(t.words)},a.max=function(t,e){return t.cmp(e)>0?t:e},a.min=function(t,e){return t.cmp(e)<0?t:e},a.prototype._init=function(t,e,r){if("number"==typeof t)return this._initNumber(t,e,r);if("object"==typeof t)return this._initArray(t,e,r);"hex"===e&&(e=16),n(e===(0|e)&&e>=2&&e<=36);var i=0;"-"===(t=t.toString().replace(/\s+/g,""))[0]&&i++,16===e?this._parseHex(t,i):this._parseBase(t,e,i),"-"===t[0]&&(this.negative=1),this.strip(),"le"===r&&this._initArray(this.toArray(),e,r)},a.prototype._initNumber=function(t,e,r){t<0&&(this.negative=1,t=-t),t<67108864?(this.words=[67108863&t],this.length=1):t<4503599627370496?(this.words=[67108863&t,t/67108864&67108863],this.length=2):(n(t<9007199254740992),this.words=[67108863&t,t/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),e,r)},a.prototype._initArray=function(t,e,r){if(n("number"==typeof t.length),t.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(t.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)o=t[i]|t[i-1]<<8|t[i-2]<<16,this.words[a]|=o<>>26-s&67108863,(s+=24)>=26&&(s-=26,a++);else if("le"===r)for(i=0,a=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,a++);return this.strip()},a.prototype._parseHex=function(t,e){this.length=Math.ceil((t.length-e)/6),this.words=new Array(this.length);for(var r=0;r=e;r-=6)i=s(t,r,r+6),this.words[n]|=i<>>26-a&4194303,(a+=24)>=26&&(a-=26,n++);r+6!==e&&(i=s(t,e,r+6),this.words[n]|=i<>>26-a&4194303),this.strip()},a.prototype._parseBase=function(t,e,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=e)n++;n--,i=i/e|0;for(var a=t.length-r,o=a%n,s=Math.min(a,a-o)+r,c=0,u=r;u1&&0===this.words[this.length-1];)this.length--;return this._normSign()},a.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},a.prototype.inspect=function(){return(this.red?""};var c=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],u=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function f(t,e,r){r.negative=e.negative^t.negative;var n=t.length+e.length|0;r.length=n,n=n-1|0;var i=0|t.words[0],a=0|e.words[0],o=i*a,s=67108863&o,l=o/67108864|0;r.words[0]=s;for(var c=1;c>>26,h=67108863&l,f=Math.min(c,e.length-1),p=Math.max(0,c-t.length+1);p<=f;p++){var d=c-p|0;u+=(o=(i=0|t.words[d])*(a=0|e.words[p])+h)/67108864|0,h=67108863&o}r.words[c]=0|h,l=0|u}return 0!==l?r.words[c]=0|l:r.length--,r.strip()}a.prototype.toString=function(t,e){var r;if(e=0|e||1,16===(t=t||10)||"hex"===t){r="";for(var i=0,a=0,o=0;o>>24-i&16777215)||o!==this.length-1?c[6-l.length]+l+r:l+r,(i+=2)>=26&&(i-=26,o--)}for(0!==a&&(r=a.toString(16)+r);r.length%e!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(t===(0|t)&&t>=2&&t<=36){var f=u[t],p=h[t];r="";var d=this.clone();for(d.negative=0;!d.isZero();){var g=d.modn(p).toString(t);r=(d=d.idivn(p)).isZero()?g+r:c[f-g.length]+g+r}for(this.isZero()&&(r="0"+r);r.length%e!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},a.prototype.toNumber=function(){var t=this.words[0];return 2===this.length?t+=67108864*this.words[1]:3===this.length&&1===this.words[2]?t+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-t:t},a.prototype.toJSON=function(){return this.toString(16)},a.prototype.toBuffer=function(t,e){return n("undefined"!=typeof o),this.toArrayLike(o,t,e)},a.prototype.toArray=function(t,e){return this.toArrayLike(Array,t,e)},a.prototype.toArrayLike=function(t,e,r){var i=this.byteLength(),a=r||Math.max(1,i);n(i<=a,"byte array longer than desired length"),n(a>0,"Requested array length <= 0"),this.strip();var o,s,l="le"===e,c=new t(a),u=this.clone();if(l){for(s=0;!u.isZero();s++)o=u.andln(255),u.iushrn(8),c[s]=o;for(;s=4096&&(r+=13,e>>>=13),e>=64&&(r+=7,e>>>=7),e>=8&&(r+=4,e>>>=4),e>=2&&(r+=2,e>>>=2),r+e},a.prototype._zeroBits=function(t){if(0===t)return 26;var e=t,r=0;return 0==(8191&e)&&(r+=13,e>>>=13),0==(127&e)&&(r+=7,e>>>=7),0==(15&e)&&(r+=4,e>>>=4),0==(3&e)&&(r+=2,e>>>=2),0==(1&e)&&r++,r},a.prototype.bitLength=function(){var t=this.words[this.length-1],e=this._countBits(t);return 26*(this.length-1)+e},a.prototype.zeroBits=function(){if(this.isZero())return 0;for(var t=0,e=0;et.length?this.clone().ior(t):t.clone().ior(this)},a.prototype.uor=function(t){return this.length>t.length?this.clone().iuor(t):t.clone().iuor(this)},a.prototype.iuand=function(t){var e;e=this.length>t.length?t:this;for(var r=0;rt.length?this.clone().iand(t):t.clone().iand(this)},a.prototype.uand=function(t){return this.length>t.length?this.clone().iuand(t):t.clone().iuand(this)},a.prototype.iuxor=function(t){var e,r;this.length>t.length?(e=this,r=t):(e=t,r=this);for(var n=0;nt.length?this.clone().ixor(t):t.clone().ixor(this)},a.prototype.uxor=function(t){return this.length>t.length?this.clone().iuxor(t):t.clone().iuxor(this)},a.prototype.inotn=function(t){n("number"==typeof t&&t>=0);var e=0|Math.ceil(t/26),r=t%26;this._expand(e),r>0&&e--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this.strip()},a.prototype.notn=function(t){return this.clone().inotn(t)},a.prototype.setn=function(t,e){n("number"==typeof t&&t>=0);var r=t/26|0,i=t%26;return this._expand(r+1),this.words[r]=e?this.words[r]|1<t.length?(r=this,n=t):(r=t,n=this);for(var i=0,a=0;a>>26;for(;0!==i&&a>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;at.length?this.clone().iadd(t):t.clone().iadd(this)},a.prototype.isub=function(t){if(0!==t.negative){t.negative=0;var e=this.iadd(t);return t.negative=1,e._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(t),this.negative=1,this._normSign();var r,n,i=this.cmp(t);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=t):(r=t,n=this);for(var a=0,o=0;o>26,this.words[o]=67108863&e;for(;0!==a&&o>26,this.words[o]=67108863&e;if(0===a&&o>>13,p=0|o[1],d=8191&p,g=p>>>13,m=0|o[2],v=8191&m,y=m>>>13,x=0|o[3],b=8191&x,_=x>>>13,w=0|o[4],k=8191&w,M=w>>>13,A=0|o[5],T=8191&A,S=A>>>13,E=0|o[6],C=8191&E,L=E>>>13,z=0|o[7],P=8191&z,I=z>>>13,O=0|o[8],D=8191&O,R=O>>>13,B=0|o[9],F=8191&B,N=B>>>13,j=0|s[0],V=8191&j,U=j>>>13,q=0|s[1],H=8191&q,G=q>>>13,W=0|s[2],Y=8191&W,X=W>>>13,Z=0|s[3],$=8191&Z,J=Z>>>13,K=0|s[4],Q=8191&K,tt=K>>>13,et=0|s[5],rt=8191&et,nt=et>>>13,it=0|s[6],at=8191&it,ot=it>>>13,st=0|s[7],lt=8191&st,ct=st>>>13,ut=0|s[8],ht=8191&ut,ft=ut>>>13,pt=0|s[9],dt=8191&pt,gt=pt>>>13;r.negative=t.negative^e.negative,r.length=19;var mt=(c+(n=Math.imul(h,V))|0)+((8191&(i=(i=Math.imul(h,U))+Math.imul(f,V)|0))<<13)|0;c=((a=Math.imul(f,U))+(i>>>13)|0)+(mt>>>26)|0,mt&=67108863,n=Math.imul(d,V),i=(i=Math.imul(d,U))+Math.imul(g,V)|0,a=Math.imul(g,U);var vt=(c+(n=n+Math.imul(h,H)|0)|0)+((8191&(i=(i=i+Math.imul(h,G)|0)+Math.imul(f,H)|0))<<13)|0;c=((a=a+Math.imul(f,G)|0)+(i>>>13)|0)+(vt>>>26)|0,vt&=67108863,n=Math.imul(v,V),i=(i=Math.imul(v,U))+Math.imul(y,V)|0,a=Math.imul(y,U),n=n+Math.imul(d,H)|0,i=(i=i+Math.imul(d,G)|0)+Math.imul(g,H)|0,a=a+Math.imul(g,G)|0;var yt=(c+(n=n+Math.imul(h,Y)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,Y)|0))<<13)|0;c=((a=a+Math.imul(f,X)|0)+(i>>>13)|0)+(yt>>>26)|0,yt&=67108863,n=Math.imul(b,V),i=(i=Math.imul(b,U))+Math.imul(_,V)|0,a=Math.imul(_,U),n=n+Math.imul(v,H)|0,i=(i=i+Math.imul(v,G)|0)+Math.imul(y,H)|0,a=a+Math.imul(y,G)|0,n=n+Math.imul(d,Y)|0,i=(i=i+Math.imul(d,X)|0)+Math.imul(g,Y)|0,a=a+Math.imul(g,X)|0;var xt=(c+(n=n+Math.imul(h,$)|0)|0)+((8191&(i=(i=i+Math.imul(h,J)|0)+Math.imul(f,$)|0))<<13)|0;c=((a=a+Math.imul(f,J)|0)+(i>>>13)|0)+(xt>>>26)|0,xt&=67108863,n=Math.imul(k,V),i=(i=Math.imul(k,U))+Math.imul(M,V)|0,a=Math.imul(M,U),n=n+Math.imul(b,H)|0,i=(i=i+Math.imul(b,G)|0)+Math.imul(_,H)|0,a=a+Math.imul(_,G)|0,n=n+Math.imul(v,Y)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(y,Y)|0,a=a+Math.imul(y,X)|0,n=n+Math.imul(d,$)|0,i=(i=i+Math.imul(d,J)|0)+Math.imul(g,$)|0,a=a+Math.imul(g,J)|0;var bt=(c+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,tt)|0)+Math.imul(f,Q)|0))<<13)|0;c=((a=a+Math.imul(f,tt)|0)+(i>>>13)|0)+(bt>>>26)|0,bt&=67108863,n=Math.imul(T,V),i=(i=Math.imul(T,U))+Math.imul(S,V)|0,a=Math.imul(S,U),n=n+Math.imul(k,H)|0,i=(i=i+Math.imul(k,G)|0)+Math.imul(M,H)|0,a=a+Math.imul(M,G)|0,n=n+Math.imul(b,Y)|0,i=(i=i+Math.imul(b,X)|0)+Math.imul(_,Y)|0,a=a+Math.imul(_,X)|0,n=n+Math.imul(v,$)|0,i=(i=i+Math.imul(v,J)|0)+Math.imul(y,$)|0,a=a+Math.imul(y,J)|0,n=n+Math.imul(d,Q)|0,i=(i=i+Math.imul(d,tt)|0)+Math.imul(g,Q)|0,a=a+Math.imul(g,tt)|0;var _t=(c+(n=n+Math.imul(h,rt)|0)|0)+((8191&(i=(i=i+Math.imul(h,nt)|0)+Math.imul(f,rt)|0))<<13)|0;c=((a=a+Math.imul(f,nt)|0)+(i>>>13)|0)+(_t>>>26)|0,_t&=67108863,n=Math.imul(C,V),i=(i=Math.imul(C,U))+Math.imul(L,V)|0,a=Math.imul(L,U),n=n+Math.imul(T,H)|0,i=(i=i+Math.imul(T,G)|0)+Math.imul(S,H)|0,a=a+Math.imul(S,G)|0,n=n+Math.imul(k,Y)|0,i=(i=i+Math.imul(k,X)|0)+Math.imul(M,Y)|0,a=a+Math.imul(M,X)|0,n=n+Math.imul(b,$)|0,i=(i=i+Math.imul(b,J)|0)+Math.imul(_,$)|0,a=a+Math.imul(_,J)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,tt)|0)+Math.imul(y,Q)|0,a=a+Math.imul(y,tt)|0,n=n+Math.imul(d,rt)|0,i=(i=i+Math.imul(d,nt)|0)+Math.imul(g,rt)|0,a=a+Math.imul(g,nt)|0;var wt=(c+(n=n+Math.imul(h,at)|0)|0)+((8191&(i=(i=i+Math.imul(h,ot)|0)+Math.imul(f,at)|0))<<13)|0;c=((a=a+Math.imul(f,ot)|0)+(i>>>13)|0)+(wt>>>26)|0,wt&=67108863,n=Math.imul(P,V),i=(i=Math.imul(P,U))+Math.imul(I,V)|0,a=Math.imul(I,U),n=n+Math.imul(C,H)|0,i=(i=i+Math.imul(C,G)|0)+Math.imul(L,H)|0,a=a+Math.imul(L,G)|0,n=n+Math.imul(T,Y)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(S,Y)|0,a=a+Math.imul(S,X)|0,n=n+Math.imul(k,$)|0,i=(i=i+Math.imul(k,J)|0)+Math.imul(M,$)|0,a=a+Math.imul(M,J)|0,n=n+Math.imul(b,Q)|0,i=(i=i+Math.imul(b,tt)|0)+Math.imul(_,Q)|0,a=a+Math.imul(_,tt)|0,n=n+Math.imul(v,rt)|0,i=(i=i+Math.imul(v,nt)|0)+Math.imul(y,rt)|0,a=a+Math.imul(y,nt)|0,n=n+Math.imul(d,at)|0,i=(i=i+Math.imul(d,ot)|0)+Math.imul(g,at)|0,a=a+Math.imul(g,ot)|0;var kt=(c+(n=n+Math.imul(h,lt)|0)|0)+((8191&(i=(i=i+Math.imul(h,ct)|0)+Math.imul(f,lt)|0))<<13)|0;c=((a=a+Math.imul(f,ct)|0)+(i>>>13)|0)+(kt>>>26)|0,kt&=67108863,n=Math.imul(D,V),i=(i=Math.imul(D,U))+Math.imul(R,V)|0,a=Math.imul(R,U),n=n+Math.imul(P,H)|0,i=(i=i+Math.imul(P,G)|0)+Math.imul(I,H)|0,a=a+Math.imul(I,G)|0,n=n+Math.imul(C,Y)|0,i=(i=i+Math.imul(C,X)|0)+Math.imul(L,Y)|0,a=a+Math.imul(L,X)|0,n=n+Math.imul(T,$)|0,i=(i=i+Math.imul(T,J)|0)+Math.imul(S,$)|0,a=a+Math.imul(S,J)|0,n=n+Math.imul(k,Q)|0,i=(i=i+Math.imul(k,tt)|0)+Math.imul(M,Q)|0,a=a+Math.imul(M,tt)|0,n=n+Math.imul(b,rt)|0,i=(i=i+Math.imul(b,nt)|0)+Math.imul(_,rt)|0,a=a+Math.imul(_,nt)|0,n=n+Math.imul(v,at)|0,i=(i=i+Math.imul(v,ot)|0)+Math.imul(y,at)|0,a=a+Math.imul(y,ot)|0,n=n+Math.imul(d,lt)|0,i=(i=i+Math.imul(d,ct)|0)+Math.imul(g,lt)|0,a=a+Math.imul(g,ct)|0;var Mt=(c+(n=n+Math.imul(h,ht)|0)|0)+((8191&(i=(i=i+Math.imul(h,ft)|0)+Math.imul(f,ht)|0))<<13)|0;c=((a=a+Math.imul(f,ft)|0)+(i>>>13)|0)+(Mt>>>26)|0,Mt&=67108863,n=Math.imul(F,V),i=(i=Math.imul(F,U))+Math.imul(N,V)|0,a=Math.imul(N,U),n=n+Math.imul(D,H)|0,i=(i=i+Math.imul(D,G)|0)+Math.imul(R,H)|0,a=a+Math.imul(R,G)|0,n=n+Math.imul(P,Y)|0,i=(i=i+Math.imul(P,X)|0)+Math.imul(I,Y)|0,a=a+Math.imul(I,X)|0,n=n+Math.imul(C,$)|0,i=(i=i+Math.imul(C,J)|0)+Math.imul(L,$)|0,a=a+Math.imul(L,J)|0,n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,tt)|0)+Math.imul(S,Q)|0,a=a+Math.imul(S,tt)|0,n=n+Math.imul(k,rt)|0,i=(i=i+Math.imul(k,nt)|0)+Math.imul(M,rt)|0,a=a+Math.imul(M,nt)|0,n=n+Math.imul(b,at)|0,i=(i=i+Math.imul(b,ot)|0)+Math.imul(_,at)|0,a=a+Math.imul(_,ot)|0,n=n+Math.imul(v,lt)|0,i=(i=i+Math.imul(v,ct)|0)+Math.imul(y,lt)|0,a=a+Math.imul(y,ct)|0,n=n+Math.imul(d,ht)|0,i=(i=i+Math.imul(d,ft)|0)+Math.imul(g,ht)|0,a=a+Math.imul(g,ft)|0;var At=(c+(n=n+Math.imul(h,dt)|0)|0)+((8191&(i=(i=i+Math.imul(h,gt)|0)+Math.imul(f,dt)|0))<<13)|0;c=((a=a+Math.imul(f,gt)|0)+(i>>>13)|0)+(At>>>26)|0,At&=67108863,n=Math.imul(F,H),i=(i=Math.imul(F,G))+Math.imul(N,H)|0,a=Math.imul(N,G),n=n+Math.imul(D,Y)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(R,Y)|0,a=a+Math.imul(R,X)|0,n=n+Math.imul(P,$)|0,i=(i=i+Math.imul(P,J)|0)+Math.imul(I,$)|0,a=a+Math.imul(I,J)|0,n=n+Math.imul(C,Q)|0,i=(i=i+Math.imul(C,tt)|0)+Math.imul(L,Q)|0,a=a+Math.imul(L,tt)|0,n=n+Math.imul(T,rt)|0,i=(i=i+Math.imul(T,nt)|0)+Math.imul(S,rt)|0,a=a+Math.imul(S,nt)|0,n=n+Math.imul(k,at)|0,i=(i=i+Math.imul(k,ot)|0)+Math.imul(M,at)|0,a=a+Math.imul(M,ot)|0,n=n+Math.imul(b,lt)|0,i=(i=i+Math.imul(b,ct)|0)+Math.imul(_,lt)|0,a=a+Math.imul(_,ct)|0,n=n+Math.imul(v,ht)|0,i=(i=i+Math.imul(v,ft)|0)+Math.imul(y,ht)|0,a=a+Math.imul(y,ft)|0;var Tt=(c+(n=n+Math.imul(d,dt)|0)|0)+((8191&(i=(i=i+Math.imul(d,gt)|0)+Math.imul(g,dt)|0))<<13)|0;c=((a=a+Math.imul(g,gt)|0)+(i>>>13)|0)+(Tt>>>26)|0,Tt&=67108863,n=Math.imul(F,Y),i=(i=Math.imul(F,X))+Math.imul(N,Y)|0,a=Math.imul(N,X),n=n+Math.imul(D,$)|0,i=(i=i+Math.imul(D,J)|0)+Math.imul(R,$)|0,a=a+Math.imul(R,J)|0,n=n+Math.imul(P,Q)|0,i=(i=i+Math.imul(P,tt)|0)+Math.imul(I,Q)|0,a=a+Math.imul(I,tt)|0,n=n+Math.imul(C,rt)|0,i=(i=i+Math.imul(C,nt)|0)+Math.imul(L,rt)|0,a=a+Math.imul(L,nt)|0,n=n+Math.imul(T,at)|0,i=(i=i+Math.imul(T,ot)|0)+Math.imul(S,at)|0,a=a+Math.imul(S,ot)|0,n=n+Math.imul(k,lt)|0,i=(i=i+Math.imul(k,ct)|0)+Math.imul(M,lt)|0,a=a+Math.imul(M,ct)|0,n=n+Math.imul(b,ht)|0,i=(i=i+Math.imul(b,ft)|0)+Math.imul(_,ht)|0,a=a+Math.imul(_,ft)|0;var St=(c+(n=n+Math.imul(v,dt)|0)|0)+((8191&(i=(i=i+Math.imul(v,gt)|0)+Math.imul(y,dt)|0))<<13)|0;c=((a=a+Math.imul(y,gt)|0)+(i>>>13)|0)+(St>>>26)|0,St&=67108863,n=Math.imul(F,$),i=(i=Math.imul(F,J))+Math.imul(N,$)|0,a=Math.imul(N,J),n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,tt)|0)+Math.imul(R,Q)|0,a=a+Math.imul(R,tt)|0,n=n+Math.imul(P,rt)|0,i=(i=i+Math.imul(P,nt)|0)+Math.imul(I,rt)|0,a=a+Math.imul(I,nt)|0,n=n+Math.imul(C,at)|0,i=(i=i+Math.imul(C,ot)|0)+Math.imul(L,at)|0,a=a+Math.imul(L,ot)|0,n=n+Math.imul(T,lt)|0,i=(i=i+Math.imul(T,ct)|0)+Math.imul(S,lt)|0,a=a+Math.imul(S,ct)|0,n=n+Math.imul(k,ht)|0,i=(i=i+Math.imul(k,ft)|0)+Math.imul(M,ht)|0,a=a+Math.imul(M,ft)|0;var Et=(c+(n=n+Math.imul(b,dt)|0)|0)+((8191&(i=(i=i+Math.imul(b,gt)|0)+Math.imul(_,dt)|0))<<13)|0;c=((a=a+Math.imul(_,gt)|0)+(i>>>13)|0)+(Et>>>26)|0,Et&=67108863,n=Math.imul(F,Q),i=(i=Math.imul(F,tt))+Math.imul(N,Q)|0,a=Math.imul(N,tt),n=n+Math.imul(D,rt)|0,i=(i=i+Math.imul(D,nt)|0)+Math.imul(R,rt)|0,a=a+Math.imul(R,nt)|0,n=n+Math.imul(P,at)|0,i=(i=i+Math.imul(P,ot)|0)+Math.imul(I,at)|0,a=a+Math.imul(I,ot)|0,n=n+Math.imul(C,lt)|0,i=(i=i+Math.imul(C,ct)|0)+Math.imul(L,lt)|0,a=a+Math.imul(L,ct)|0,n=n+Math.imul(T,ht)|0,i=(i=i+Math.imul(T,ft)|0)+Math.imul(S,ht)|0,a=a+Math.imul(S,ft)|0;var Ct=(c+(n=n+Math.imul(k,dt)|0)|0)+((8191&(i=(i=i+Math.imul(k,gt)|0)+Math.imul(M,dt)|0))<<13)|0;c=((a=a+Math.imul(M,gt)|0)+(i>>>13)|0)+(Ct>>>26)|0,Ct&=67108863,n=Math.imul(F,rt),i=(i=Math.imul(F,nt))+Math.imul(N,rt)|0,a=Math.imul(N,nt),n=n+Math.imul(D,at)|0,i=(i=i+Math.imul(D,ot)|0)+Math.imul(R,at)|0,a=a+Math.imul(R,ot)|0,n=n+Math.imul(P,lt)|0,i=(i=i+Math.imul(P,ct)|0)+Math.imul(I,lt)|0,a=a+Math.imul(I,ct)|0,n=n+Math.imul(C,ht)|0,i=(i=i+Math.imul(C,ft)|0)+Math.imul(L,ht)|0,a=a+Math.imul(L,ft)|0;var Lt=(c+(n=n+Math.imul(T,dt)|0)|0)+((8191&(i=(i=i+Math.imul(T,gt)|0)+Math.imul(S,dt)|0))<<13)|0;c=((a=a+Math.imul(S,gt)|0)+(i>>>13)|0)+(Lt>>>26)|0,Lt&=67108863,n=Math.imul(F,at),i=(i=Math.imul(F,ot))+Math.imul(N,at)|0,a=Math.imul(N,ot),n=n+Math.imul(D,lt)|0,i=(i=i+Math.imul(D,ct)|0)+Math.imul(R,lt)|0,a=a+Math.imul(R,ct)|0,n=n+Math.imul(P,ht)|0,i=(i=i+Math.imul(P,ft)|0)+Math.imul(I,ht)|0,a=a+Math.imul(I,ft)|0;var zt=(c+(n=n+Math.imul(C,dt)|0)|0)+((8191&(i=(i=i+Math.imul(C,gt)|0)+Math.imul(L,dt)|0))<<13)|0;c=((a=a+Math.imul(L,gt)|0)+(i>>>13)|0)+(zt>>>26)|0,zt&=67108863,n=Math.imul(F,lt),i=(i=Math.imul(F,ct))+Math.imul(N,lt)|0,a=Math.imul(N,ct),n=n+Math.imul(D,ht)|0,i=(i=i+Math.imul(D,ft)|0)+Math.imul(R,ht)|0,a=a+Math.imul(R,ft)|0;var Pt=(c+(n=n+Math.imul(P,dt)|0)|0)+((8191&(i=(i=i+Math.imul(P,gt)|0)+Math.imul(I,dt)|0))<<13)|0;c=((a=a+Math.imul(I,gt)|0)+(i>>>13)|0)+(Pt>>>26)|0,Pt&=67108863,n=Math.imul(F,ht),i=(i=Math.imul(F,ft))+Math.imul(N,ht)|0,a=Math.imul(N,ft);var It=(c+(n=n+Math.imul(D,dt)|0)|0)+((8191&(i=(i=i+Math.imul(D,gt)|0)+Math.imul(R,dt)|0))<<13)|0;c=((a=a+Math.imul(R,gt)|0)+(i>>>13)|0)+(It>>>26)|0,It&=67108863;var Ot=(c+(n=Math.imul(F,dt))|0)+((8191&(i=(i=Math.imul(F,gt))+Math.imul(N,dt)|0))<<13)|0;return c=((a=Math.imul(N,gt))+(i>>>13)|0)+(Ot>>>26)|0,Ot&=67108863,l[0]=mt,l[1]=vt,l[2]=yt,l[3]=xt,l[4]=bt,l[5]=_t,l[6]=wt,l[7]=kt,l[8]=Mt,l[9]=At,l[10]=Tt,l[11]=St,l[12]=Et,l[13]=Ct,l[14]=Lt,l[15]=zt,l[16]=Pt,l[17]=It,l[18]=Ot,0!==c&&(l[19]=c,r.length++),r};function d(t,e,r){return(new g).mulp(t,e,r)}function g(t,e){this.x=t,this.y=e}Math.imul||(p=f),a.prototype.mulTo=function(t,e){var r=this.length+t.length;return 10===this.length&&10===t.length?p(this,t,e):r<63?f(this,t,e):r<1024?function(t,e,r){r.negative=e.negative^t.negative,r.length=t.length+e.length;for(var n=0,i=0,a=0;a>>26)|0)>>>26,o&=67108863}r.words[a]=s,n=o,o=i}return 0!==n?r.words[a]=n:r.length--,r.strip()}(this,t,e):d(this,t,e)},g.prototype.makeRBT=function(t){for(var e=new Array(t),r=a.prototype._countBits(t)-1,n=0;n>=1;return n},g.prototype.permute=function(t,e,r,n,i,a){for(var o=0;o>>=1)i++;return 1<>>=13,r[2*o+1]=8191&a,a>>>=13;for(o=2*e;o>=26,e+=i/67108864|0,e+=a>>>26,this.words[r]=67108863&a}return 0!==e&&(this.words[r]=e,this.length++),this},a.prototype.muln=function(t){return this.clone().imuln(t)},a.prototype.sqr=function(){return this.mul(this)},a.prototype.isqr=function(){return this.imul(this.clone())},a.prototype.pow=function(t){var e=function(t){for(var e=new Array(t.bitLength()),r=0;r>>i}return e}(t);if(0===e.length)return new a(1);for(var r=this,n=0;n=0);var e,r=t%26,i=(t-r)/26,a=67108863>>>26-r<<26-r;if(0!==r){var o=0;for(e=0;e>>26-r}o&&(this.words[e]=o,this.length++)}if(0!==i){for(e=this.length-1;e>=0;e--)this.words[e+i]=this.words[e];for(e=0;e=0),i=e?(e-e%26)/26:0;var a=t%26,o=Math.min((t-a)/26,this.length),s=67108863^67108863>>>a<o)for(this.length-=o,c=0;c=0&&(0!==u||c>=i);c--){var h=0|this.words[c];this.words[c]=u<<26-a|h>>>a,u=h&s}return l&&0!==u&&(l.words[l.length++]=u),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},a.prototype.ishrn=function(t,e,r){return n(0===this.negative),this.iushrn(t,e,r)},a.prototype.shln=function(t){return this.clone().ishln(t)},a.prototype.ushln=function(t){return this.clone().iushln(t)},a.prototype.shrn=function(t){return this.clone().ishrn(t)},a.prototype.ushrn=function(t){return this.clone().iushrn(t)},a.prototype.testn=function(t){n("number"==typeof t&&t>=0);var e=t%26,r=(t-e)/26,i=1<=0);var e=t%26,r=(t-e)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==e&&r++,this.length=Math.min(r,this.length),0!==e){var i=67108863^67108863>>>e<=67108864;e++)this.words[e]-=67108864,e===this.length-1?this.words[e+1]=1:this.words[e+1]++;return this.length=Math.max(this.length,e+1),this},a.prototype.isubn=function(t){if(n("number"==typeof t),n(t<67108864),t<0)return this.iaddn(-t);if(0!==this.negative)return this.negative=0,this.iaddn(t),this.negative=1,this;if(this.words[0]-=t,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var e=0;e>26)-(l/67108864|0),this.words[i+r]=67108863&a}for(;i>26,this.words[i+r]=67108863&a;if(0===s)return this.strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&a;return this.negative=1,this.strip()},a.prototype._wordDiv=function(t,e){var r=(this.length,t.length),n=this.clone(),i=t,o=0|i.words[i.length-1];0!==(r=26-this._countBits(o))&&(i=i.ushln(r),n.iushln(r),o=0|i.words[i.length-1]);var s,l=n.length-i.length;if("mod"!==e){(s=new a(null)).length=l+1,s.words=new Array(s.length);for(var c=0;c=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/o|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s.strip(),n.strip(),"div"!==e&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},a.prototype.divmod=function(t,e,r){return n(!t.isZero()),this.isZero()?{div:new a(0),mod:new a(0)}:0!==this.negative&&0===t.negative?(s=this.neg().divmod(t,e),"mod"!==e&&(i=s.div.neg()),"div"!==e&&(o=s.mod.neg(),r&&0!==o.negative&&o.iadd(t)),{div:i,mod:o}):0===this.negative&&0!==t.negative?(s=this.divmod(t.neg(),e),"mod"!==e&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&t.negative)?(s=this.neg().divmod(t.neg(),e),"div"!==e&&(o=s.mod.neg(),r&&0!==o.negative&&o.isub(t)),{div:s.div,mod:o}):t.length>this.length||this.cmp(t)<0?{div:new a(0),mod:this}:1===t.length?"div"===e?{div:this.divn(t.words[0]),mod:null}:"mod"===e?{div:null,mod:new a(this.modn(t.words[0]))}:{div:this.divn(t.words[0]),mod:new a(this.modn(t.words[0]))}:this._wordDiv(t,e);var i,o,s},a.prototype.div=function(t){return this.divmod(t,"div",!1).div},a.prototype.mod=function(t){return this.divmod(t,"mod",!1).mod},a.prototype.umod=function(t){return this.divmod(t,"mod",!0).mod},a.prototype.divRound=function(t){var e=this.divmod(t);if(e.mod.isZero())return e.div;var r=0!==e.div.negative?e.mod.isub(t):e.mod,n=t.ushrn(1),i=t.andln(1),a=r.cmp(n);return a<0||1===i&&0===a?e.div:0!==e.div.negative?e.div.isubn(1):e.div.iaddn(1)},a.prototype.modn=function(t){n(t<=67108863);for(var e=(1<<26)%t,r=0,i=this.length-1;i>=0;i--)r=(e*r+(0|this.words[i]))%t;return r},a.prototype.idivn=function(t){n(t<=67108863);for(var e=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*e;this.words[r]=i/t|0,e=i%t}return this.strip()},a.prototype.divn=function(t){return this.clone().idivn(t)},a.prototype.egcd=function(t){n(0===t.negative),n(!t.isZero());var e=this,r=t.clone();e=0!==e.negative?e.umod(t):e.clone();for(var i=new a(1),o=new a(0),s=new a(0),l=new a(1),c=0;e.isEven()&&r.isEven();)e.iushrn(1),r.iushrn(1),++c;for(var u=r.clone(),h=e.clone();!e.isZero();){for(var f=0,p=1;0==(e.words[0]&p)&&f<26;++f,p<<=1);if(f>0)for(e.iushrn(f);f-- >0;)(i.isOdd()||o.isOdd())&&(i.iadd(u),o.isub(h)),i.iushrn(1),o.iushrn(1);for(var d=0,g=1;0==(r.words[0]&g)&&d<26;++d,g<<=1);if(d>0)for(r.iushrn(d);d-- >0;)(s.isOdd()||l.isOdd())&&(s.iadd(u),l.isub(h)),s.iushrn(1),l.iushrn(1);e.cmp(r)>=0?(e.isub(r),i.isub(s),o.isub(l)):(r.isub(e),s.isub(i),l.isub(o))}return{a:s,b:l,gcd:r.iushln(c)}},a.prototype._invmp=function(t){n(0===t.negative),n(!t.isZero());var e=this,r=t.clone();e=0!==e.negative?e.umod(t):e.clone();for(var i,o=new a(1),s=new a(0),l=r.clone();e.cmpn(1)>0&&r.cmpn(1)>0;){for(var c=0,u=1;0==(e.words[0]&u)&&c<26;++c,u<<=1);if(c>0)for(e.iushrn(c);c-- >0;)o.isOdd()&&o.iadd(l),o.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(l),s.iushrn(1);e.cmp(r)>=0?(e.isub(r),o.isub(s)):(r.isub(e),s.isub(o))}return(i=0===e.cmpn(1)?o:s).cmpn(0)<0&&i.iadd(t),i},a.prototype.gcd=function(t){if(this.isZero())return t.abs();if(t.isZero())return this.abs();var e=this.clone(),r=t.clone();e.negative=0,r.negative=0;for(var n=0;e.isEven()&&r.isEven();n++)e.iushrn(1),r.iushrn(1);for(;;){for(;e.isEven();)e.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=e.cmp(r);if(i<0){var a=e;e=r,r=a}else if(0===i||0===r.cmpn(1))break;e.isub(r)}return r.iushln(n)},a.prototype.invm=function(t){return this.egcd(t).a.umod(t)},a.prototype.isEven=function(){return 0==(1&this.words[0])},a.prototype.isOdd=function(){return 1==(1&this.words[0])},a.prototype.andln=function(t){return this.words[0]&t},a.prototype.bincn=function(t){n("number"==typeof t);var e=t%26,r=(t-e)/26,i=1<>>26,s&=67108863,this.words[o]=s}return 0!==a&&(this.words[o]=a,this.length++),this},a.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},a.prototype.cmpn=function(t){var e,r=t<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this.strip(),this.length>1)e=1;else{r&&(t=-t),n(t<=67108863,"Number is too big");var i=0|this.words[0];e=i===t?0:it.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|t.words[r];if(n!==i){ni&&(e=1);break}}return e},a.prototype.gtn=function(t){return 1===this.cmpn(t)},a.prototype.gt=function(t){return 1===this.cmp(t)},a.prototype.gten=function(t){return this.cmpn(t)>=0},a.prototype.gte=function(t){return this.cmp(t)>=0},a.prototype.ltn=function(t){return-1===this.cmpn(t)},a.prototype.lt=function(t){return-1===this.cmp(t)},a.prototype.lten=function(t){return this.cmpn(t)<=0},a.prototype.lte=function(t){return this.cmp(t)<=0},a.prototype.eqn=function(t){return 0===this.cmpn(t)},a.prototype.eq=function(t){return 0===this.cmp(t)},a.red=function(t){return new w(t)},a.prototype.toRed=function(t){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),t.convertTo(this)._forceRed(t)},a.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},a.prototype._forceRed=function(t){return this.red=t,this},a.prototype.forceRed=function(t){return n(!this.red,"Already a number in reduction context"),this._forceRed(t)},a.prototype.redAdd=function(t){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,t)},a.prototype.redIAdd=function(t){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,t)},a.prototype.redSub=function(t){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,t)},a.prototype.redISub=function(t){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,t)},a.prototype.redShl=function(t){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,t)},a.prototype.redMul=function(t){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,t),this.red.mul(this,t)},a.prototype.redIMul=function(t){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,t),this.red.imul(this,t)},a.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},a.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},a.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},a.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},a.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},a.prototype.redPow=function(t){return n(this.red&&!t.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,t)};var m={k256:null,p224:null,p192:null,p25519:null};function v(t,e){this.name=t,this.p=new a(e,16),this.n=this.p.bitLength(),this.k=new a(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function x(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function b(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function _(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function w(t){if("string"==typeof t){var e=a._prime(t);this.m=e.p,this.prime=e}else n(t.gtn(1),"modulus must be greater than 1"),this.m=t,this.prime=null}function k(t){w.call(this,t),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new a(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var t=new a(null);return t.words=new Array(Math.ceil(this.n/13)),t},v.prototype.ireduce=function(t){var e,r=t;do{this.split(r,this.tmp),e=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(e>this.n);var n=e0?r.isub(this.p):r.strip(),r},v.prototype.split=function(t,e){t.iushrn(this.n,0,e)},v.prototype.imulK=function(t){return t.imul(this.k)},i(y,v),y.prototype.split=function(t,e){for(var r=Math.min(t.length,9),n=0;n>>22,i=a}i>>>=22,t.words[n-10]=i,0===i&&t.length>10?t.length-=10:t.length-=9},y.prototype.imulK=function(t){t.words[t.length]=0,t.words[t.length+1]=0,t.length+=2;for(var e=0,r=0;r>>=26,t.words[r]=i,e=n}return 0!==e&&(t.words[t.length++]=e),t},a._prime=function(t){if(m[t])return m[t];var e;if("k256"===t)e=new y;else if("p224"===t)e=new x;else if("p192"===t)e=new b;else{if("p25519"!==t)throw new Error("Unknown prime "+t);e=new _}return m[t]=e,e},w.prototype._verify1=function(t){n(0===t.negative,"red works only with positives"),n(t.red,"red works only with red numbers")},w.prototype._verify2=function(t,e){n(0==(t.negative|e.negative),"red works only with positives"),n(t.red&&t.red===e.red,"red works only with red numbers")},w.prototype.imod=function(t){return this.prime?this.prime.ireduce(t)._forceRed(this):t.umod(this.m)._forceRed(this)},w.prototype.neg=function(t){return t.isZero()?t.clone():this.m.sub(t)._forceRed(this)},w.prototype.add=function(t,e){this._verify2(t,e);var r=t.add(e);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},w.prototype.iadd=function(t,e){this._verify2(t,e);var r=t.iadd(e);return r.cmp(this.m)>=0&&r.isub(this.m),r},w.prototype.sub=function(t,e){this._verify2(t,e);var r=t.sub(e);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},w.prototype.isub=function(t,e){this._verify2(t,e);var r=t.isub(e);return r.cmpn(0)<0&&r.iadd(this.m),r},w.prototype.shl=function(t,e){return this._verify1(t),this.imod(t.ushln(e))},w.prototype.imul=function(t,e){return this._verify2(t,e),this.imod(t.imul(e))},w.prototype.mul=function(t,e){return this._verify2(t,e),this.imod(t.mul(e))},w.prototype.isqr=function(t){return this.imul(t,t.clone())},w.prototype.sqr=function(t){return this.mul(t,t)},w.prototype.sqrt=function(t){if(t.isZero())return t.clone();var e=this.m.andln(3);if(n(e%2==1),3===e){var r=this.m.add(new a(1)).iushrn(2);return this.pow(t,r)}for(var i=this.m.subn(1),o=0;!i.isZero()&&0===i.andln(1);)o++,i.iushrn(1);n(!i.isZero());var s=new a(1).toRed(this),l=s.redNeg(),c=this.m.subn(1).iushrn(1),u=this.m.bitLength();for(u=new a(2*u*u).toRed(this);0!==this.pow(u,c).cmp(l);)u.redIAdd(l);for(var h=this.pow(u,i),f=this.pow(t,i.addn(1).iushrn(1)),p=this.pow(t,i),d=o;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();n(m=0;n--){for(var c=e.words[n],u=l-1;u>=0;u--){var h=c>>u&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==o?(o<<=1,o|=h,(4===++s||0===n&&0===u)&&(i=this.mul(i,r[o]),s=0,o=0)):s=0}l=26}return i},w.prototype.convertTo=function(t){var e=t.umod(this.m);return e===t?e.clone():e},w.prototype.convertFrom=function(t){var e=t.clone();return e.red=null,e},a.mont=function(t){return new k(t)},i(k,w),k.prototype.convertTo=function(t){return this.imod(t.ushln(this.shift))},k.prototype.convertFrom=function(t){var e=this.imod(t.mul(this.rinv));return e.red=null,e},k.prototype.imul=function(t,e){if(t.isZero()||e.isZero())return t.words[0]=0,t.length=1,t;var r=t.imul(e),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},k.prototype.mul=function(t,e){if(t.isZero()||e.isZero())return new a(0)._forceRed(this);var r=t.mul(e),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},k.prototype.invm=function(t){return this.imod(t._invmp(this.m).mul(this.r2))._forceRed(this)}}("undefined"==typeof e||e,this)},{buffer:91}],83:[function(t,e,r){"use strict";e.exports=function(t){var e,r,n,i=t.length,a=0;for(e=0;e>>1;if(!(u<=0)){var h,f=i.mallocDouble(2*u*s),p=i.mallocInt32(s);if((s=l(t,u,f,p))>0){if(1===u&&n)a.init(s),h=a.sweepComplete(u,r,0,s,f,p,0,s,f,p);else{var d=i.mallocDouble(2*u*c),g=i.mallocInt32(c);(c=l(e,u,d,g))>0&&(a.init(s+c),h=1===u?a.sweepBipartite(u,r,0,s,f,p,0,c,d,g):o(u,r,n,s,f,p,c,d,g),i.free(d),i.free(g))}i.free(f),i.free(p)}return h}}}function u(t,e){n.push([t,e])}},{"./lib/intersect":86,"./lib/sweep":90,"typedarray-pool":507}],85:[function(t,e,r){"use strict";var n="d",i="ax",a="vv",o="fp",s="es",l="rs",c="re",u="rb",h="ri",f="rp",p="bs",d="be",g="bb",m="bi",v="bp",y="rv",x="Q",b=[n,i,a,l,c,u,h,p,d,g,m];function _(t){var e="bruteForce"+(t?"Full":"Partial"),r=[],_=b.slice();t||_.splice(3,0,o);var w=["function "+e+"("+_.join()+"){"];function k(e,o){var _=function(t,e,r){var o="bruteForce"+(t?"Red":"Blue")+(e?"Flip":"")+(r?"Full":""),_=["function ",o,"(",b.join(),"){","var ",s,"=2*",n,";"],w="for(var i="+l+","+f+"="+s+"*"+l+";i<"+c+";++i,"+f+"+="+s+"){var x0="+u+"["+i+"+"+f+"],x1="+u+"["+i+"+"+f+"+"+n+"],xi="+h+"[i];",k="for(var j="+p+","+v+"="+s+"*"+p+";j<"+d+";++j,"+v+"+="+s+"){var y0="+g+"["+i+"+"+v+"],"+(r?"y1="+g+"["+i+"+"+v+"+"+n+"],":"")+"yi="+m+"[j];";return t?_.push(w,x,":",k):_.push(k,x,":",w),r?_.push("if(y1"+d+"-"+p+"){"),t?(k(!0,!1),w.push("}else{"),k(!1,!1)):(w.push("if("+o+"){"),k(!0,!0),w.push("}else{"),k(!0,!1),w.push("}}else{if("+o+"){"),k(!1,!0),w.push("}else{"),k(!1,!1),w.push("}")),w.push("}}return "+e);var M=r.join("")+w.join("");return new Function(M)()}r.partial=_(!1),r.full=_(!0)},{}],86:[function(t,e,r){"use strict";e.exports=function(t,e,r,a,u,S,E,C,L){!function(t,e){var r=8*i.log2(e+1)*(t+1)|0,a=i.nextPow2(b*r);w.length0;){var O=(P-=1)*b,D=w[O],R=w[O+1],B=w[O+2],F=w[O+3],N=w[O+4],j=w[O+5],V=P*_,U=k[V],q=k[V+1],H=1&j,G=!!(16&j),W=u,Y=S,X=C,Z=L;if(H&&(W=C,Y=L,X=u,Z=S),!(2&j&&(B=m(t,D,R,B,W,Y,q),R>=B)||4&j&&(R=v(t,D,R,B,W,Y,U))>=B)){var $=B-R,J=N-F;if(G){if(t*$*($+J)=p0)&&!(p1>=hi)",["p0","p1"]),g=u("lo===p0",["p0"]),m=u("lo>>1,f=2*t,p=h,d=s[f*h+e];for(;c=x?(p=y,d=x):v>=_?(p=m,d=v):(p=b,d=_):x>=_?(p=y,d=x):_>=v?(p=m,d=v):(p=b,d=_);for(var w=f*(u-1),k=f*p,M=0;Mr&&i[h+e]>c;--u,h-=o){for(var f=h,p=h+o,d=0;d=0&&i.push("lo=e[k+n]");t.indexOf("hi")>=0&&i.push("hi=e[k+o]");return r.push(n.replace("_",i.join()).replace("$",t)),Function.apply(void 0,r)};var n="for(var j=2*a,k=j*c,l=k,m=c,n=b,o=a+b,p=c;d>p;++p,k+=j){var _;if($)if(m===p)m+=1,l+=j;else{for(var s=0;j>s;++s){var t=e[k+s];e[k+s]=e[l],e[l++]=t}var u=f[p];f[p]=f[m],f[m++]=u}}return m"},{}],89:[function(t,e,r){"use strict";e.exports=function(t,e){e<=4*n?i(0,e-1,t):function t(e,r,h){var f=(r-e+1)/6|0,p=e+f,d=r-f,g=e+r>>1,m=g-f,v=g+f,y=p,x=m,b=g,_=v,w=d,k=e+1,M=r-1,A=0;c(y,x,h)&&(A=y,y=x,x=A);c(_,w,h)&&(A=_,_=w,w=A);c(y,b,h)&&(A=y,y=b,b=A);c(x,b,h)&&(A=x,x=b,b=A);c(y,_,h)&&(A=y,y=_,_=A);c(b,_,h)&&(A=b,b=_,_=A);c(x,w,h)&&(A=x,x=w,w=A);c(x,b,h)&&(A=x,x=b,b=A);c(_,w,h)&&(A=_,_=w,w=A);var T=h[2*x];var S=h[2*x+1];var E=h[2*_];var C=h[2*_+1];var L=2*y;var z=2*b;var P=2*w;var I=2*p;var O=2*g;var D=2*d;for(var R=0;R<2;++R){var B=h[L+R],F=h[z+R],N=h[P+R];h[I+R]=B,h[O+R]=F,h[D+R]=N}o(m,e,h);o(v,r,h);for(var j=k;j<=M;++j)if(u(j,T,S,h))j!==k&&a(j,k,h),++k;else if(!u(j,E,C,h))for(;;){if(u(M,E,C,h)){u(M,T,S,h)?(s(j,k,M,h),++k,--M):(a(j,M,h),--M);break}if(--Mt;){var c=r[l-2],u=r[l-1];if(cr[e+1])}function u(t,e,r,n){var i=n[t*=2];return i>>1;a(p,S);for(var E=0,C=0,k=0;k=o)d(c,u,C--,L=L-o|0);else if(L>=0)d(s,l,E--,L);else if(L<=-o){L=-L-o|0;for(var z=0;z>>1;a(p,E);for(var C=0,L=0,z=0,M=0;M>1==p[2*M+3]>>1&&(I=2,M+=1),P<0){for(var O=-(P>>1)-1,D=0;D>1)-1;0===I?d(s,l,C--,O):1===I?d(c,u,L--,O):2===I&&d(h,f,z--,O)}}},scanBipartite:function(t,e,r,n,i,c,u,h,f,m,v,y){var x=0,b=2*t,_=e,w=e+t,k=1,M=1;n?M=o:k=o;for(var A=i;A>>1;a(p,C);for(var L=0,A=0;A=o?(P=!n,T-=o):(P=!!n,T-=1),P)g(s,l,L++,T);else{var I=y[T],O=b*T,D=v[O+e+1],R=v[O+e+1+t];t:for(var B=0;B>>1;a(p,k);for(var M=0,x=0;x=o)s[M++]=b-o;else{var T=d[b-=1],S=m*b,E=f[S+e+1],C=f[S+e+1+t];t:for(var L=0;L=0;--L)if(s[L]===b){for(var O=L+1;Oa)throw new RangeError("Invalid typed array length");var e=new Uint8Array(t);return e.__proto__=s.prototype,e}function s(t,e,r){if("number"==typeof t){if("string"==typeof e)throw new Error("If encoding is specified then the first argument must be a string");return u(t)}return l(t,e,r)}function l(t,e,r){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return j(t)||t&&j(t.buffer)?function(t,e,r){if(e<0||t.byteLength=a)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a.toString(16)+" bytes");return 0|t}function p(t,e){if(s.isBuffer(t))return t.length;if(ArrayBuffer.isView(t)||j(t))return t.byteLength;"string"!=typeof t&&(t=""+t);var r=t.length;if(0===r)return 0;for(var n=!1;;)switch(e){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return B(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return F(t).length;default:if(n)return B(t).length;e=(""+e).toLowerCase(),n=!0}}function d(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function g(t,e,r,n,i){if(0===t.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),V(r=+r)&&(r=i?0:t.length-1),r<0&&(r=t.length+r),r>=t.length){if(i)return-1;r=t.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof e&&(e=s.from(e,n)),s.isBuffer(e))return 0===e.length?-1:m(t,e,r,n,i);if("number"==typeof e)return e&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,e,r):Uint8Array.prototype.lastIndexOf.call(t,e,r):m(t,[e],r,n,i);throw new TypeError("val must be string, number or Buffer")}function m(t,e,r,n,i){var a,o=1,s=t.length,l=e.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;o=2,s/=2,l/=2,r/=2}function c(t,e){return 1===o?t[e]:t.readUInt16BE(e*o)}if(i){var u=-1;for(a=r;as&&(r=s-l),a=r;a>=0;a--){for(var h=!0,f=0;fi&&(n=i):n=i;var a=e.length;n>a/2&&(n=a/2);for(var o=0;o>8,i=r%256,a.push(i),a.push(n);return a}(e,t.length-r),t,r,n)}function k(t,e,r){return 0===e&&r===t.length?n.fromByteArray(t):n.fromByteArray(t.slice(e,r))}function M(t,e,r){r=Math.min(t.length,r);for(var n=[],i=e;i239?4:c>223?3:c>191?2:1;if(i+h<=r)switch(h){case 1:c<128&&(u=c);break;case 2:128==(192&(a=t[i+1]))&&(l=(31&c)<<6|63&a)>127&&(u=l);break;case 3:a=t[i+1],o=t[i+2],128==(192&a)&&128==(192&o)&&(l=(15&c)<<12|(63&a)<<6|63&o)>2047&&(l<55296||l>57343)&&(u=l);break;case 4:a=t[i+1],o=t[i+2],s=t[i+3],128==(192&a)&&128==(192&o)&&128==(192&s)&&(l=(15&c)<<18|(63&a)<<12|(63&o)<<6|63&s)>65535&&l<1114112&&(u=l)}null===u?(u=65533,h=1):u>65535&&(u-=65536,n.push(u>>>10&1023|55296),u=56320|1023&u),n.push(u),i+=h}return function(t){var e=t.length;if(e<=A)return String.fromCharCode.apply(String,t);var r="",n=0;for(;nthis.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return E(this,e,r);case"utf8":case"utf-8":return M(this,e,r);case"ascii":return T(this,e,r);case"latin1":case"binary":return S(this,e,r);case"base64":return k(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}.apply(this,arguments)},s.prototype.toLocaleString=s.prototype.toString,s.prototype.equals=function(t){if(!s.isBuffer(t))throw new TypeError("Argument must be a Buffer");return this===t||0===s.compare(this,t)},s.prototype.inspect=function(){var t="",e=r.INSPECT_MAX_BYTES;return this.length>0&&(t=this.toString("hex",0,e).match(/.{2}/g).join(" "),this.length>e&&(t+=" ... ")),""},s.prototype.compare=function(t,e,r,n,i){if(!s.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===r&&(r=t?t.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),e<0||r>t.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&e>=r)return 0;if(n>=i)return-1;if(e>=r)return 1;if(this===t)return 0;for(var a=(i>>>=0)-(n>>>=0),o=(r>>>=0)-(e>>>=0),l=Math.min(a,o),c=this.slice(n,i),u=t.slice(e,r),h=0;h>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0)}var i=this.length-e;if((void 0===r||r>i)&&(r=i),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var a=!1;;)switch(n){case"hex":return v(this,t,e,r);case"utf8":case"utf-8":return y(this,t,e,r);case"ascii":return x(this,t,e,r);case"latin1":case"binary":return b(this,t,e,r);case"base64":return _(this,t,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return w(this,t,e,r);default:if(a)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),a=!0}},s.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var A=4096;function T(t,e,r){var n="";r=Math.min(t.length,r);for(var i=e;in)&&(r=n);for(var i="",a=e;ar)throw new RangeError("Trying to access beyond buffer length")}function z(t,e,r,n,i,a){if(!s.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>i||et.length)throw new RangeError("Index out of range")}function P(t,e,r,n,i,a){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function I(t,e,r,n,a){return e=+e,r>>>=0,a||P(t,0,r,4),i.write(t,e,r,n,23,4),r+4}function O(t,e,r,n,a){return e=+e,r>>>=0,a||P(t,0,r,8),i.write(t,e,r,n,52,8),r+8}s.prototype.slice=function(t,e){var r=this.length;(t=~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),(e=void 0===e?r:~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),e>>=0,e>>>=0,r||L(t,e,this.length);for(var n=this[t],i=1,a=0;++a>>=0,e>>>=0,r||L(t,e,this.length);for(var n=this[t+--e],i=1;e>0&&(i*=256);)n+=this[t+--e]*i;return n},s.prototype.readUInt8=function(t,e){return t>>>=0,e||L(t,1,this.length),this[t]},s.prototype.readUInt16LE=function(t,e){return t>>>=0,e||L(t,2,this.length),this[t]|this[t+1]<<8},s.prototype.readUInt16BE=function(t,e){return t>>>=0,e||L(t,2,this.length),this[t]<<8|this[t+1]},s.prototype.readUInt32LE=function(t,e){return t>>>=0,e||L(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},s.prototype.readUInt32BE=function(t,e){return t>>>=0,e||L(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},s.prototype.readIntLE=function(t,e,r){t>>>=0,e>>>=0,r||L(t,e,this.length);for(var n=this[t],i=1,a=0;++a=(i*=128)&&(n-=Math.pow(2,8*e)),n},s.prototype.readIntBE=function(t,e,r){t>>>=0,e>>>=0,r||L(t,e,this.length);for(var n=e,i=1,a=this[t+--n];n>0&&(i*=256);)a+=this[t+--n]*i;return a>=(i*=128)&&(a-=Math.pow(2,8*e)),a},s.prototype.readInt8=function(t,e){return t>>>=0,e||L(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},s.prototype.readInt16LE=function(t,e){t>>>=0,e||L(t,2,this.length);var r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},s.prototype.readInt16BE=function(t,e){t>>>=0,e||L(t,2,this.length);var r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},s.prototype.readInt32LE=function(t,e){return t>>>=0,e||L(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},s.prototype.readInt32BE=function(t,e){return t>>>=0,e||L(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},s.prototype.readFloatLE=function(t,e){return t>>>=0,e||L(t,4,this.length),i.read(this,t,!0,23,4)},s.prototype.readFloatBE=function(t,e){return t>>>=0,e||L(t,4,this.length),i.read(this,t,!1,23,4)},s.prototype.readDoubleLE=function(t,e){return t>>>=0,e||L(t,8,this.length),i.read(this,t,!0,52,8)},s.prototype.readDoubleBE=function(t,e){return t>>>=0,e||L(t,8,this.length),i.read(this,t,!1,52,8)},s.prototype.writeUIntLE=function(t,e,r,n){(t=+t,e>>>=0,r>>>=0,n)||z(this,t,e,r,Math.pow(2,8*r)-1,0);var i=1,a=0;for(this[e]=255&t;++a>>=0,r>>>=0,n)||z(this,t,e,r,Math.pow(2,8*r)-1,0);var i=r-1,a=1;for(this[e+i]=255&t;--i>=0&&(a*=256);)this[e+i]=t/a&255;return e+r},s.prototype.writeUInt8=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,1,255,0),this[e]=255&t,e+1},s.prototype.writeUInt16LE=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,2,65535,0),this[e]=255&t,this[e+1]=t>>>8,e+2},s.prototype.writeUInt16BE=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,2,65535,0),this[e]=t>>>8,this[e+1]=255&t,e+2},s.prototype.writeUInt32LE=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,4,4294967295,0),this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t,e+4},s.prototype.writeUInt32BE=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,4,4294967295,0),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},s.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e>>>=0,!n){var i=Math.pow(2,8*r-1);z(this,t,e,r,i-1,-i)}var a=0,o=1,s=0;for(this[e]=255&t;++a>0)-s&255;return e+r},s.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e>>>=0,!n){var i=Math.pow(2,8*r-1);z(this,t,e,r,i-1,-i)}var a=r-1,o=1,s=0;for(this[e+a]=255&t;--a>=0&&(o*=256);)t<0&&0===s&&0!==this[e+a+1]&&(s=1),this[e+a]=(t/o>>0)-s&255;return e+r},s.prototype.writeInt8=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,1,127,-128),t<0&&(t=255+t+1),this[e]=255&t,e+1},s.prototype.writeInt16LE=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,2,32767,-32768),this[e]=255&t,this[e+1]=t>>>8,e+2},s.prototype.writeInt16BE=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,2,32767,-32768),this[e]=t>>>8,this[e+1]=255&t,e+2},s.prototype.writeInt32LE=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,4,2147483647,-2147483648),this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24,e+4},s.prototype.writeInt32BE=function(t,e,r){return t=+t,e>>>=0,r||z(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},s.prototype.writeFloatLE=function(t,e,r){return I(this,t,e,!0,r)},s.prototype.writeFloatBE=function(t,e,r){return I(this,t,e,!1,r)},s.prototype.writeDoubleLE=function(t,e,r){return O(this,t,e,!0,r)},s.prototype.writeDoubleBE=function(t,e,r){return O(this,t,e,!1,r)},s.prototype.copy=function(t,e,r,n){if(!s.isBuffer(t))throw new TypeError("argument should be a Buffer");if(r||(r=0),n||0===n||(n=this.length),e>=t.length&&(e=t.length),e||(e=0),n>0&&n=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-e=0;--a)t[a+e]=this[a+r];else Uint8Array.prototype.set.call(t,this.subarray(r,n),e);return i},s.prototype.fill=function(t,e,r,n){if("string"==typeof t){if("string"==typeof e?(n=e,e=0,r=this.length):"string"==typeof r&&(n=r,r=this.length),void 0!==n&&"string"!=typeof n)throw new TypeError("encoding must be a string");if("string"==typeof n&&!s.isEncoding(n))throw new TypeError("Unknown encoding: "+n);if(1===t.length){var i=t.charCodeAt(0);("utf8"===n&&i<128||"latin1"===n)&&(t=i)}}else"number"==typeof t&&(t&=255);if(e<0||this.length>>=0,r=void 0===r?this.length:r>>>0,t||(t=0),"number"==typeof t)for(a=e;a55295&&r<57344){if(!i){if(r>56319){(e-=3)>-1&&a.push(239,191,189);continue}if(o+1===n){(e-=3)>-1&&a.push(239,191,189);continue}i=r;continue}if(r<56320){(e-=3)>-1&&a.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320)}else i&&(e-=3)>-1&&a.push(239,191,189);if(i=null,r<128){if((e-=1)<0)break;a.push(r)}else if(r<2048){if((e-=2)<0)break;a.push(r>>6|192,63&r|128)}else if(r<65536){if((e-=3)<0)break;a.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;a.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return a}function F(t){return n.toByteArray(function(t){if((t=(t=t.split("=")[0]).trim().replace(D,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function N(t,e,r,n){for(var i=0;i=e.length||i>=t.length);++i)e[i+r]=t[i];return i}function j(t){return t instanceof ArrayBuffer||null!=t&&null!=t.constructor&&"ArrayBuffer"===t.constructor.name&&"number"==typeof t.byteLength}function V(t){return t!=t}},{"base64-js":62,ieee754:380}],93:[function(t,e,r){"use strict";var n=t("./lib/monotone"),i=t("./lib/triangulation"),a=t("./lib/delaunay"),o=t("./lib/filter");function s(t){return[Math.min(t[0],t[1]),Math.max(t[0],t[1])]}function l(t,e){return t[0]-e[0]||t[1]-e[1]}function c(t,e,r){return e in t?t[e]:r}e.exports=function(t,e,r){Array.isArray(e)?(r=r||{},e=e||[]):(r=e||{},e=[]);var u=!!c(r,"delaunay",!0),h=!!c(r,"interior",!0),f=!!c(r,"exterior",!0),p=!!c(r,"infinity",!1);if(!h&&!f||0===t.length)return[];var d=n(t,e);if(u||h!==f||p){for(var g=i(t.length,function(t){return t.map(s).sort(l)}(e)),m=0;m0;){for(var u=r.pop(),s=r.pop(),h=-1,f=-1,l=o[s],d=1;d=0||(e.flip(s,u),i(t,e,r,h,s,f),i(t,e,r,s,f,h),i(t,e,r,f,u,h),i(t,e,r,u,h,f)))}}},{"binary-search-bounds":98,"robust-in-sphere":469}],95:[function(t,e,r){"use strict";var n,i=t("binary-search-bounds");function a(t,e,r,n,i,a,o){this.cells=t,this.neighbor=e,this.flags=n,this.constraint=r,this.active=i,this.next=a,this.boundary=o}function o(t,e){return t[0]-e[0]||t[1]-e[1]||t[2]-e[2]}e.exports=function(t,e,r){var n=function(t,e){for(var r=t.cells(),n=r.length,i=0;i0||l.length>0;){for(;s.length>0;){var p=s.pop();if(c[p]!==-i){c[p]=i;u[p];for(var d=0;d<3;++d){var g=f[3*p+d];g>=0&&0===c[g]&&(h[3*p+d]?l.push(g):(s.push(g),c[g]=i))}}}var m=l;l=s,s=m,l.length=0,i=-i}var v=function(t,e,r){for(var n=0,i=0;i1&&i(r[f[p-2]],r[f[p-1]],a)>0;)t.push([f[p-1],f[p-2],o]),p-=1;f.length=p,f.push(o);var d=u.upperIds;for(p=d.length;p>1&&i(r[d[p-2]],r[d[p-1]],a)<0;)t.push([d[p-2],d[p-1],o]),p-=1;d.length=p,d.push(o)}}function p(t,e){var r;return(r=t.a[0]v[0]&&i.push(new c(v,m,s,h),new c(m,v,o,h))}i.sort(u);for(var y=i[0].a[0]-(1+Math.abs(i[0].a[0]))*Math.pow(2,-52),x=[new l([y,1],[y,0],-1,[],[],[],[])],b=[],h=0,_=i.length;h<_;++h){var w=i[h],k=w.type;k===a?f(b,x,t,w.a,w.idx):k===s?d(x,t,w):g(x,t,w)}return b}},{"binary-search-bounds":98,"robust-orientation":471}],97:[function(t,e,r){"use strict";var n=t("binary-search-bounds");function i(t,e){this.stars=t,this.edges=e}e.exports=function(t,e){for(var r=new Array(t),n=0;n=0}}(),a.removeTriangle=function(t,e,r){var n=this.stars;o(n[t],e,r),o(n[e],r,t),o(n[r],t,e)},a.addTriangle=function(t,e,r){var n=this.stars;n[t].push(e,r),n[e].push(r,t),n[r].push(t,e)},a.opposite=function(t,e){for(var r=this.stars[e],n=1,i=r.length;n>>1,x=a[m]"];return i?e.indexOf("c")<0?a.push(";if(x===y){return m}else if(x<=y){"):a.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){"):a.push(";if(",e,"){i=m;"),r?a.push("l=m+1}else{h=m-1}"):a.push("h=m-1}else{l=m+1}"),a.push("}"),i?a.push("return -1};"):a.push("return i};"),a.join("")}function i(t,e,r,i){return new Function([n("A","x"+t+"y",e,["y"],i),n("P","c(x,y)"+t+"0",e,["y","c"],i),"function dispatchBsearch",r,"(a,y,c,l,h){if(typeof(c)==='function'){return P(a,(l===void 0)?0:l|0,(h===void 0)?a.length-1:h|0,y,c)}else{return A(a,(c===void 0)?0:c|0,(l===void 0)?a.length-1:l|0,y)}}return dispatchBsearch",r].join(""))()}e.exports={ge:i(">=",!1,"GE"),gt:i(">",!1,"GT"),lt:i("<",!0,"LT"),le:i("<=",!0,"LE"),eq:i("-",!0,"EQ",!0)}},{}],99:[function(t,e,r){"use strict";e.exports=function(t){for(var e=1,r=1;rr?r:t:te?e:t}},{}],103:[function(t,e,r){"use strict";e.exports=function(t,e,r){var n;if(r){n=e;for(var i=new Array(e.length),a=0;ae[2]?1:0)}function v(t,e,r){if(0!==t.length){if(e)for(var n=0;n=0;--a){var x=e[u=(S=n[a])[0]],b=x[0],_=x[1],w=t[b],k=t[_];if((w[0]-k[0]||w[1]-k[1])<0){var M=b;b=_,_=M}x[0]=b;var A,T=x[1]=S[1];for(i&&(A=x[2]);a>0&&n[a-1][0]===u;){var S,E=(S=n[--a])[1];i?e.push([T,E,A]):e.push([T,E]),T=E}i?e.push([T,_,A]):e.push([T,_])}return f}(t,e,f,m,r));return v(e,y,r),!!y||(f.length>0||m.length>0)}},{"./lib/rat-seg-intersect":104,"big-rat":66,"big-rat/cmp":64,"big-rat/to-float":78,"box-intersect":84,nextafter:418,"rat-vec":453,"robust-segment-intersect":474,"union-find":508}],104:[function(t,e,r){"use strict";e.exports=function(t,e,r,n){var a=s(e,t),h=s(n,r),f=u(a,h);if(0===o(f))return null;var p=s(t,r),d=u(h,p),g=i(d,f),m=c(a,g);return l(t,m)};var n=t("big-rat/mul"),i=t("big-rat/div"),a=t("big-rat/sub"),o=t("big-rat/sign"),s=t("rat-vec/sub"),l=t("rat-vec/add"),c=t("rat-vec/muls");function u(t,e){return a(n(t[0],e[1]),n(t[1],e[0]))}},{"big-rat/div":65,"big-rat/mul":75,"big-rat/sign":76,"big-rat/sub":77,"rat-vec/add":452,"rat-vec/muls":454,"rat-vec/sub":455}],105:[function(t,e,r){"use strict";var n=t("clamp");function i(t,e){null==e&&(e=!0);var r=t[0],i=t[1],a=t[2],o=t[3];return null==o&&(o=e?1:255),e&&(r*=255,i*=255,a*=255,o*=255),16777216*(r=255&n(r,0,255))+((i=255&n(i,0,255))<<16)+((a=255&n(a,0,255))<<8)+(o=255&n(o,0,255))}e.exports=i,e.exports.to=i,e.exports.from=function(t,e){var r=(t=+t)>>>24,n=(16711680&t)>>>16,i=(65280&t)>>>8,a=255&t;return!1===e?[r,n,i,a]:[r/255,n/255,i/255,a/255]}},{clamp:102}],106:[function(t,e,r){"use strict";e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],107:[function(t,e,r){"use strict";var n=t("color-rgba"),i=t("clamp"),a=t("dtype");e.exports=function(t,e){"float"!==e&&e||(e="array"),"uint"===e&&(e="uint8"),"uint_clamped"===e&&(e="uint8_clamped");var r=a(e),o=new r(4);if(t instanceof r)return Array.isArray(t)?t.slice():(o.set(t),o);var s="uint8"!==e&&"uint8_clamped"!==e;return t instanceof Uint8Array||t instanceof Uint8ClampedArray?(o[0]=t[0],o[1]=t[1],o[2]=t[2],o[3]=null!=t[3]?t[3]:255,s&&(o[0]/=255,o[1]/=255,o[2]/=255,o[3]/=255),o):(t.length&&"string"!=typeof t||((t=n(t))[0]/=255,t[1]/=255,t[2]/=255),s?(o[0]=t[0],o[1]=t[1],o[2]=t[2],o[3]=null!=t[3]?t[3]:1):(o[0]=i(Math.round(255*t[0]),0,255),o[1]=i(Math.round(255*t[1]),0,255),o[2]=i(Math.round(255*t[2]),0,255),o[3]=null==t[3]?255:i(Math.floor(255*t[3]),0,255)),o)}},{clamp:102,"color-rgba":109,dtype:153}],108:[function(t,e,r){(function(r){"use strict";var n=t("color-name"),i=t("is-plain-obj"),a=t("defined");e.exports=function(t){var e,s,l=[],c=1;if("string"==typeof t)if(n[t])l=n[t].slice(),s="rgb";else if("transparent"===t)c=0,s="rgb",l=[0,0,0];else if(/^#[A-Fa-f0-9]+$/.test(t)){var u=t.slice(1),h=u.length,f=h<=4;c=1,f?(l=[parseInt(u[0]+u[0],16),parseInt(u[1]+u[1],16),parseInt(u[2]+u[2],16)],4===h&&(c=parseInt(u[3]+u[3],16)/255)):(l=[parseInt(u[0]+u[1],16),parseInt(u[2]+u[3],16),parseInt(u[4]+u[5],16)],8===h&&(c=parseInt(u[6]+u[7],16)/255)),l[0]||(l[0]=0),l[1]||(l[1]=0),l[2]||(l[2]=0),s="rgb"}else if(e=/^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(t)){var p=e[1],u=p.replace(/a$/,"");s=u;var h="cmyk"===u?4:"gray"===u?1:3;l=e[2].trim().split(/\s*,\s*/).map(function(t,e){if(/%$/.test(t))return e===h?parseFloat(t)/100:"rgb"===u?255*parseFloat(t)/100:parseFloat(t);if("h"===u[e]){if(/deg$/.test(t))return parseFloat(t);if(void 0!==o[t])return o[t]}return parseFloat(t)}),p===u&&l.push(1),c=void 0===l[h]?1:l[h],l=l.slice(0,h)}else t.length>10&&/[0-9](?:\s|\/)/.test(t)&&(l=t.match(/([0-9]+)/g).map(function(t){return parseFloat(t)}),s=t.match(/([a-z])/ig).join("").toLowerCase());else if("number"==typeof t)s="rgb",l=[t>>>16,(65280&t)>>>8,255&t];else if(i(t)){var d=a(t.r,t.red,t.R,null);null!==d?(s="rgb",l=[d,a(t.g,t.green,t.G),a(t.b,t.blue,t.B)]):(s="hsl",l=[a(t.h,t.hue,t.H),a(t.s,t.saturation,t.S),a(t.l,t.lightness,t.L,t.b,t.brightness)]),c=a(t.a,t.alpha,t.opacity,1),null!=t.opacity&&(c/=100)}else(Array.isArray(t)||r.ArrayBuffer&&ArrayBuffer.isView&&ArrayBuffer.isView(t))&&(l=[t[0],t[1],t[2]],s="rgb",c=4===t.length?t[3]:1);return{space:s,values:l,alpha:c}};var o={red:0,orange:60,yellow:120,green:180,blue:240,purple:300}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"color-name":106,defined:148,"is-plain-obj":390}],109:[function(t,e,r){"use strict";var n=t("color-parse"),i=t("color-space/hsl"),a=t("clamp");e.exports=function(t){var e;if("string"!=typeof t)throw Error("Argument should be a string");var r=n(t);return r.space?((e=Array(3))[0]=a(r.values[0],0,255),e[1]=a(r.values[1],0,255),e[2]=a(r.values[2],0,255),"h"===r.space[0]&&(e=i.rgb(e)),e.push(a(r.alpha,0,1)),e):[]}},{clamp:102,"color-parse":108,"color-space/hsl":110}],110:[function(t,e,r){"use strict";var n=t("./rgb");e.exports={name:"hsl",min:[0,0,0],max:[360,100,100],channel:["hue","saturation","lightness"],alias:["HSL"],rgb:function(t){var e,r,n,i,a,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[a=255*l,a,a];e=2*l-(r=l<.5?l*(1+s):l+s-l*s),i=[0,0,0];for(var c=0;c<3;c++)(n=o+1/3*-(c-1))<0?n++:n>1&&n--,a=6*n<1?e+6*(r-e)*n:2*n<1?r:3*n<2?e+(r-e)*(2/3-n)*6:e,i[c]=255*a;return i}},n.hsl=function(t){var e,r,n=t[0]/255,i=t[1]/255,a=t[2]/255,o=Math.min(n,i,a),s=Math.max(n,i,a),l=s-o;return s===o?e=0:n===s?e=(i-a)/l:i===s?e=2+(a-n)/l:a===s&&(e=4+(n-i)/l),(e=Math.min(60*e,360))<0&&(e+=360),r=(o+s)/2,[e,100*(s===o?0:r<=.5?l/(s+o):l/(2-s-o)),100*r]}},{"./rgb":111}],111:[function(t,e,r){"use strict";e.exports={name:"rgb",min:[0,0,0],max:[255,255,255],channel:["red","green","blue"],alias:["RGB"]}},{}],112:[function(t,e,r){e.exports={jet:[{index:0,rgb:[0,0,131]},{index:.125,rgb:[0,60,170]},{index:.375,rgb:[5,255,255]},{index:.625,rgb:[255,255,0]},{index:.875,rgb:[250,0,0]},{index:1,rgb:[128,0,0]}],hsv:[{index:0,rgb:[255,0,0]},{index:.169,rgb:[253,255,2]},{index:.173,rgb:[247,255,2]},{index:.337,rgb:[0,252,4]},{index:.341,rgb:[0,252,10]},{index:.506,rgb:[1,249,255]},{index:.671,rgb:[2,0,253]},{index:.675,rgb:[8,0,253]},{index:.839,rgb:[255,0,251]},{index:.843,rgb:[255,0,245]},{index:1,rgb:[255,0,6]}],hot:[{index:0,rgb:[0,0,0]},{index:.3,rgb:[230,0,0]},{index:.6,rgb:[255,210,0]},{index:1,rgb:[255,255,255]}],cool:[{index:0,rgb:[0,255,255]},{index:1,rgb:[255,0,255]}],spring:[{index:0,rgb:[255,0,255]},{index:1,rgb:[255,255,0]}],summer:[{index:0,rgb:[0,128,102]},{index:1,rgb:[255,255,102]}],autumn:[{index:0,rgb:[255,0,0]},{index:1,rgb:[255,255,0]}],winter:[{index:0,rgb:[0,0,255]},{index:1,rgb:[0,255,128]}],bone:[{index:0,rgb:[0,0,0]},{index:.376,rgb:[84,84,116]},{index:.753,rgb:[169,200,200]},{index:1,rgb:[255,255,255]}],copper:[{index:0,rgb:[0,0,0]},{index:.804,rgb:[255,160,102]},{index:1,rgb:[255,199,127]}],greys:[{index:0,rgb:[0,0,0]},{index:1,rgb:[255,255,255]}],yignbu:[{index:0,rgb:[8,29,88]},{index:.125,rgb:[37,52,148]},{index:.25,rgb:[34,94,168]},{index:.375,rgb:[29,145,192]},{index:.5,rgb:[65,182,196]},{index:.625,rgb:[127,205,187]},{index:.75,rgb:[199,233,180]},{index:.875,rgb:[237,248,217]},{index:1,rgb:[255,255,217]}],greens:[{index:0,rgb:[0,68,27]},{index:.125,rgb:[0,109,44]},{index:.25,rgb:[35,139,69]},{index:.375,rgb:[65,171,93]},{index:.5,rgb:[116,196,118]},{index:.625,rgb:[161,217,155]},{index:.75,rgb:[199,233,192]},{index:.875,rgb:[229,245,224]},{index:1,rgb:[247,252,245]}],yiorrd:[{index:0,rgb:[128,0,38]},{index:.125,rgb:[189,0,38]},{index:.25,rgb:[227,26,28]},{index:.375,rgb:[252,78,42]},{index:.5,rgb:[253,141,60]},{index:.625,rgb:[254,178,76]},{index:.75,rgb:[254,217,118]},{index:.875,rgb:[255,237,160]},{index:1,rgb:[255,255,204]}],bluered:[{index:0,rgb:[0,0,255]},{index:1,rgb:[255,0,0]}],rdbu:[{index:0,rgb:[5,10,172]},{index:.35,rgb:[106,137,247]},{index:.5,rgb:[190,190,190]},{index:.6,rgb:[220,170,132]},{index:.7,rgb:[230,145,90]},{index:1,rgb:[178,10,28]}],picnic:[{index:0,rgb:[0,0,255]},{index:.1,rgb:[51,153,255]},{index:.2,rgb:[102,204,255]},{index:.3,rgb:[153,204,255]},{index:.4,rgb:[204,204,255]},{index:.5,rgb:[255,255,255]},{index:.6,rgb:[255,204,255]},{index:.7,rgb:[255,153,255]},{index:.8,rgb:[255,102,204]},{index:.9,rgb:[255,102,102]},{index:1,rgb:[255,0,0]}],rainbow:[{index:0,rgb:[150,0,90]},{index:.125,rgb:[0,0,200]},{index:.25,rgb:[0,25,255]},{index:.375,rgb:[0,152,255]},{index:.5,rgb:[44,255,150]},{index:.625,rgb:[151,255,0]},{index:.75,rgb:[255,234,0]},{index:.875,rgb:[255,111,0]},{index:1,rgb:[255,0,0]}],portland:[{index:0,rgb:[12,51,131]},{index:.25,rgb:[10,136,186]},{index:.5,rgb:[242,211,56]},{index:.75,rgb:[242,143,56]},{index:1,rgb:[217,30,30]}],blackbody:[{index:0,rgb:[0,0,0]},{index:.2,rgb:[230,0,0]},{index:.4,rgb:[230,210,0]},{index:.7,rgb:[255,255,255]},{index:1,rgb:[160,200,255]}],earth:[{index:0,rgb:[0,0,130]},{index:.1,rgb:[0,180,180]},{index:.2,rgb:[40,210,40]},{index:.4,rgb:[230,230,50]},{index:.6,rgb:[120,70,20]},{index:1,rgb:[255,255,255]}],electric:[{index:0,rgb:[0,0,0]},{index:.15,rgb:[30,0,100]},{index:.4,rgb:[120,0,100]},{index:.6,rgb:[160,90,0]},{index:.8,rgb:[230,200,0]},{index:1,rgb:[255,250,220]}],alpha:[{index:0,rgb:[255,255,255,0]},{index:1,rgb:[255,255,255,1]}],viridis:[{index:0,rgb:[68,1,84]},{index:.13,rgb:[71,44,122]},{index:.25,rgb:[59,81,139]},{index:.38,rgb:[44,113,142]},{index:.5,rgb:[33,144,141]},{index:.63,rgb:[39,173,129]},{index:.75,rgb:[92,200,99]},{index:.88,rgb:[170,220,50]},{index:1,rgb:[253,231,37]}],inferno:[{index:0,rgb:[0,0,4]},{index:.13,rgb:[31,12,72]},{index:.25,rgb:[85,15,109]},{index:.38,rgb:[136,34,106]},{index:.5,rgb:[186,54,85]},{index:.63,rgb:[227,89,51]},{index:.75,rgb:[249,140,10]},{index:.88,rgb:[249,201,50]},{index:1,rgb:[252,255,164]}],magma:[{index:0,rgb:[0,0,4]},{index:.13,rgb:[28,16,68]},{index:.25,rgb:[79,18,123]},{index:.38,rgb:[129,37,129]},{index:.5,rgb:[181,54,122]},{index:.63,rgb:[229,80,100]},{index:.75,rgb:[251,135,97]},{index:.88,rgb:[254,194,135]},{index:1,rgb:[252,253,191]}],plasma:[{index:0,rgb:[13,8,135]},{index:.13,rgb:[75,3,161]},{index:.25,rgb:[125,3,168]},{index:.38,rgb:[168,34,150]},{index:.5,rgb:[203,70,121]},{index:.63,rgb:[229,107,93]},{index:.75,rgb:[248,148,65]},{index:.88,rgb:[253,195,40]},{index:1,rgb:[240,249,33]}],warm:[{index:0,rgb:[125,0,179]},{index:.13,rgb:[172,0,187]},{index:.25,rgb:[219,0,170]},{index:.38,rgb:[255,0,130]},{index:.5,rgb:[255,63,74]},{index:.63,rgb:[255,123,0]},{index:.75,rgb:[234,176,0]},{index:.88,rgb:[190,228,0]},{index:1,rgb:[147,255,0]}],cool:[{index:0,rgb:[125,0,179]},{index:.13,rgb:[116,0,218]},{index:.25,rgb:[98,74,237]},{index:.38,rgb:[68,146,231]},{index:.5,rgb:[0,204,197]},{index:.63,rgb:[0,247,146]},{index:.75,rgb:[0,255,88]},{index:.88,rgb:[40,255,8]},{index:1,rgb:[147,255,0]}],"rainbow-soft":[{index:0,rgb:[125,0,179]},{index:.1,rgb:[199,0,180]},{index:.2,rgb:[255,0,121]},{index:.3,rgb:[255,108,0]},{index:.4,rgb:[222,194,0]},{index:.5,rgb:[150,255,0]},{index:.6,rgb:[0,255,55]},{index:.7,rgb:[0,246,150]},{index:.8,rgb:[50,167,222]},{index:.9,rgb:[103,51,235]},{index:1,rgb:[124,0,186]}],bathymetry:[{index:0,rgb:[40,26,44]},{index:.13,rgb:[59,49,90]},{index:.25,rgb:[64,76,139]},{index:.38,rgb:[63,110,151]},{index:.5,rgb:[72,142,158]},{index:.63,rgb:[85,174,163]},{index:.75,rgb:[120,206,163]},{index:.88,rgb:[187,230,172]},{index:1,rgb:[253,254,204]}],cdom:[{index:0,rgb:[47,15,62]},{index:.13,rgb:[87,23,86]},{index:.25,rgb:[130,28,99]},{index:.38,rgb:[171,41,96]},{index:.5,rgb:[206,67,86]},{index:.63,rgb:[230,106,84]},{index:.75,rgb:[242,149,103]},{index:.88,rgb:[249,193,135]},{index:1,rgb:[254,237,176]}],chlorophyll:[{index:0,rgb:[18,36,20]},{index:.13,rgb:[25,63,41]},{index:.25,rgb:[24,91,59]},{index:.38,rgb:[13,119,72]},{index:.5,rgb:[18,148,80]},{index:.63,rgb:[80,173,89]},{index:.75,rgb:[132,196,122]},{index:.88,rgb:[175,221,162]},{index:1,rgb:[215,249,208]}],density:[{index:0,rgb:[54,14,36]},{index:.13,rgb:[89,23,80]},{index:.25,rgb:[110,45,132]},{index:.38,rgb:[120,77,178]},{index:.5,rgb:[120,113,213]},{index:.63,rgb:[115,151,228]},{index:.75,rgb:[134,185,227]},{index:.88,rgb:[177,214,227]},{index:1,rgb:[230,241,241]}],"freesurface-blue":[{index:0,rgb:[30,4,110]},{index:.13,rgb:[47,14,176]},{index:.25,rgb:[41,45,236]},{index:.38,rgb:[25,99,212]},{index:.5,rgb:[68,131,200]},{index:.63,rgb:[114,156,197]},{index:.75,rgb:[157,181,203]},{index:.88,rgb:[200,208,216]},{index:1,rgb:[241,237,236]}],"freesurface-red":[{index:0,rgb:[60,9,18]},{index:.13,rgb:[100,17,27]},{index:.25,rgb:[142,20,29]},{index:.38,rgb:[177,43,27]},{index:.5,rgb:[192,87,63]},{index:.63,rgb:[205,125,105]},{index:.75,rgb:[216,162,148]},{index:.88,rgb:[227,199,193]},{index:1,rgb:[241,237,236]}],oxygen:[{index:0,rgb:[64,5,5]},{index:.13,rgb:[106,6,15]},{index:.25,rgb:[144,26,7]},{index:.38,rgb:[168,64,3]},{index:.5,rgb:[188,100,4]},{index:.63,rgb:[206,136,11]},{index:.75,rgb:[220,174,25]},{index:.88,rgb:[231,215,44]},{index:1,rgb:[248,254,105]}],par:[{index:0,rgb:[51,20,24]},{index:.13,rgb:[90,32,35]},{index:.25,rgb:[129,44,34]},{index:.38,rgb:[159,68,25]},{index:.5,rgb:[182,99,19]},{index:.63,rgb:[199,134,22]},{index:.75,rgb:[212,171,35]},{index:.88,rgb:[221,210,54]},{index:1,rgb:[225,253,75]}],phase:[{index:0,rgb:[145,105,18]},{index:.13,rgb:[184,71,38]},{index:.25,rgb:[186,58,115]},{index:.38,rgb:[160,71,185]},{index:.5,rgb:[110,97,218]},{index:.63,rgb:[50,123,164]},{index:.75,rgb:[31,131,110]},{index:.88,rgb:[77,129,34]},{index:1,rgb:[145,105,18]}],salinity:[{index:0,rgb:[42,24,108]},{index:.13,rgb:[33,50,162]},{index:.25,rgb:[15,90,145]},{index:.38,rgb:[40,118,137]},{index:.5,rgb:[59,146,135]},{index:.63,rgb:[79,175,126]},{index:.75,rgb:[120,203,104]},{index:.88,rgb:[193,221,100]},{index:1,rgb:[253,239,154]}],temperature:[{index:0,rgb:[4,35,51]},{index:.13,rgb:[23,51,122]},{index:.25,rgb:[85,59,157]},{index:.38,rgb:[129,79,143]},{index:.5,rgb:[175,95,130]},{index:.63,rgb:[222,112,101]},{index:.75,rgb:[249,146,66]},{index:.88,rgb:[249,196,65]},{index:1,rgb:[232,250,91]}],turbidity:[{index:0,rgb:[34,31,27]},{index:.13,rgb:[65,50,41]},{index:.25,rgb:[98,69,52]},{index:.38,rgb:[131,89,57]},{index:.5,rgb:[161,112,59]},{index:.63,rgb:[185,140,66]},{index:.75,rgb:[202,174,88]},{index:.88,rgb:[216,209,126]},{index:1,rgb:[233,246,171]}],"velocity-blue":[{index:0,rgb:[17,32,64]},{index:.13,rgb:[35,52,116]},{index:.25,rgb:[29,81,156]},{index:.38,rgb:[31,113,162]},{index:.5,rgb:[50,144,169]},{index:.63,rgb:[87,173,176]},{index:.75,rgb:[149,196,189]},{index:.88,rgb:[203,221,211]},{index:1,rgb:[254,251,230]}],"velocity-green":[{index:0,rgb:[23,35,19]},{index:.13,rgb:[24,64,38]},{index:.25,rgb:[11,95,45]},{index:.38,rgb:[39,123,35]},{index:.5,rgb:[95,146,12]},{index:.63,rgb:[152,165,18]},{index:.75,rgb:[201,186,69]},{index:.88,rgb:[233,216,137]},{index:1,rgb:[255,253,205]}],cubehelix:[{index:0,rgb:[0,0,0]},{index:.07,rgb:[22,5,59]},{index:.13,rgb:[60,4,105]},{index:.2,rgb:[109,1,135]},{index:.27,rgb:[161,0,147]},{index:.33,rgb:[210,2,142]},{index:.4,rgb:[251,11,123]},{index:.47,rgb:[255,29,97]},{index:.53,rgb:[255,54,69]},{index:.6,rgb:[255,85,46]},{index:.67,rgb:[255,120,34]},{index:.73,rgb:[255,157,37]},{index:.8,rgb:[241,191,57]},{index:.87,rgb:[224,220,93]},{index:.93,rgb:[218,241,142]},{index:1,rgb:[227,253,198]}]}},{}],113:[function(t,e,r){"use strict";var n=t("./colorScale"),i=t("lerp");function a(t){return[t[0]/255,t[1]/255,t[2]/255,t[3]]}function o(t){for(var e,r="#",n=0;n<3;++n)r+=("00"+(e=(e=t[n]).toString(16))).substr(e.length);return r}function s(t){return"rgba("+t.join(",")+")"}e.exports=function(t){var e,r,l,c,u,h,f,p,d,g;t||(t={});p=(t.nshades||72)-1,f=t.format||"hex",(h=t.colormap)||(h="jet");if("string"==typeof h){if(h=h.toLowerCase(),!n[h])throw Error(h+" not a supported colorscale");u=n[h]}else{if(!Array.isArray(h))throw Error("unsupported colormap option",h);u=h.slice()}if(u.length>p)throw new Error(h+" map requires nshades to be at least size "+u.length);d=Array.isArray(t.alpha)?2!==t.alpha.length?[1,1]:t.alpha.slice():"number"==typeof t.alpha?[t.alpha,t.alpha]:[1,1];e=u.map(function(t){return Math.round(t.index*p)}),d[0]=Math.min(Math.max(d[0],0),1),d[1]=Math.min(Math.max(d[1],0),1);var m=u.map(function(t,e){var r=u[e].index,n=u[e].rgb.slice();return 4===n.length&&n[3]>=0&&n[3]<=1?n:(n[3]=d[0]+(d[1]-d[0])*r,n)}),v=[];for(g=0;g0?-1:l(t,e,a)?-1:1:0===s?c>0?1:l(t,e,r)?1:-1:i(c-s)}var f=n(t,e,r);if(f>0)return o>0&&n(t,e,a)>0?1:-1;if(f<0)return o>0||n(t,e,a)>0?1:-1;var p=n(t,e,a);return p>0?1:l(t,e,r)?1:-1};var n=t("robust-orientation"),i=t("signum"),a=t("two-sum"),o=t("robust-product"),s=t("robust-sum");function l(t,e,r){var n=a(t[0],-e[0]),i=a(t[1],-e[1]),l=a(r[0],-e[0]),c=a(r[1],-e[1]),u=s(o(n,l),o(i,c));return u[u.length-1]>=0}},{"robust-orientation":471,"robust-product":472,"robust-sum":476,signum:477,"two-sum":506}],115:[function(t,e,r){e.exports=function(t,e){var r=t.length,a=t.length-e.length;if(a)return a;switch(r){case 0:return 0;case 1:return t[0]-e[0];case 2:return t[0]+t[1]-e[0]-e[1]||n(t[0],t[1])-n(e[0],e[1]);case 3:var o=t[0]+t[1],s=e[0]+e[1];if(a=o+t[2]-(s+e[2]))return a;var l=n(t[0],t[1]),c=n(e[0],e[1]);return n(l,t[2])-n(c,e[2])||n(l+t[2],o)-n(c+e[2],s);case 4:var u=t[0],h=t[1],f=t[2],p=t[3],d=e[0],g=e[1],m=e[2],v=e[3];return u+h+f+p-(d+g+m+v)||n(u,h,f,p)-n(d,g,m,v,d)||n(u+h,u+f,u+p,h+f,h+p,f+p)-n(d+g,d+m,d+v,g+m,g+v,m+v)||n(u+h+f,u+h+p,u+f+p,h+f+p)-n(d+g+m,d+g+v,d+m+v,g+m+v);default:for(var y=t.slice().sort(i),x=e.slice().sort(i),b=0;bt[r][0]&&(r=n);return er?[[r],[e]]:[[e]]}},{}],119:[function(t,e,r){"use strict";e.exports=function(t){var e=n(t),r=e.length;if(r<=2)return[];for(var i=new Array(r),a=e[r-1],o=0;o=e[l]&&(s+=1);a[o]=s}}return t}(o,r)}};var n=t("incremental-convex-hull"),i=t("affine-hull")},{"affine-hull":53,"incremental-convex-hull":381}],121:[function(t,e,r){e.exports={AFG:"afghan",ALA:"\\b\\wland",ALB:"albania",DZA:"algeria",ASM:"^(?=.*americ).*samoa",AND:"andorra",AGO:"angola",AIA:"anguill?a",ATA:"antarctica",ATG:"antigua",ARG:"argentin",ARM:"armenia",ABW:"^(?!.*bonaire).*\\baruba",AUS:"australia",AUT:"^(?!.*hungary).*austria|\\baustri.*\\bemp",AZE:"azerbaijan",BHS:"bahamas",BHR:"bahrain",BGD:"bangladesh|^(?=.*east).*paki?stan",BRB:"barbados",BLR:"belarus|byelo",BEL:"^(?!.*luxem).*belgium",BLZ:"belize|^(?=.*british).*honduras",BEN:"benin|dahome",BMU:"bermuda",BTN:"bhutan",BOL:"bolivia",BES:"^(?=.*bonaire).*eustatius|^(?=.*carib).*netherlands|\\bbes.?islands",BIH:"herzegovina|bosnia",BWA:"botswana|bechuana",BVT:"bouvet",BRA:"brazil",IOT:"british.?indian.?ocean",BRN:"brunei",BGR:"bulgaria",BFA:"burkina|\\bfaso|upper.?volta",BDI:"burundi",CPV:"verde",KHM:"cambodia|kampuchea|khmer",CMR:"cameroon",CAN:"canada",CYM:"cayman",CAF:"\\bcentral.african.republic",TCD:"\\bchad",CHL:"\\bchile",CHN:"^(?!.*\\bmac)(?!.*\\bhong)(?!.*\\btai)(?!.*\\brep).*china|^(?=.*peo)(?=.*rep).*china",CXR:"christmas",CCK:"\\bcocos|keeling",COL:"colombia",COM:"comoro",COG:"^(?!.*\\bdem)(?!.*\\bd[\\.]?r)(?!.*kinshasa)(?!.*zaire)(?!.*belg)(?!.*l.opoldville)(?!.*free).*\\bcongo",COK:"\\bcook",CRI:"costa.?rica",CIV:"ivoire|ivory",HRV:"croatia",CUB:"\\bcuba",CUW:"^(?!.*bonaire).*\\bcura(c|\xe7)ao",CYP:"cyprus",CSK:"czechoslovakia",CZE:"^(?=.*rep).*czech|czechia|bohemia",COD:"\\bdem.*congo|congo.*\\bdem|congo.*\\bd[\\.]?r|\\bd[\\.]?r.*congo|belgian.?congo|congo.?free.?state|kinshasa|zaire|l.opoldville|drc|droc|rdc",DNK:"denmark",DJI:"djibouti",DMA:"dominica(?!n)",DOM:"dominican.rep",ECU:"ecuador",EGY:"egypt",SLV:"el.?salvador",GNQ:"guine.*eq|eq.*guine|^(?=.*span).*guinea",ERI:"eritrea",EST:"estonia",ETH:"ethiopia|abyssinia",FLK:"falkland|malvinas",FRO:"faroe|faeroe",FJI:"fiji",FIN:"finland",FRA:"^(?!.*\\bdep)(?!.*martinique).*france|french.?republic|\\bgaul",GUF:"^(?=.*french).*guiana",PYF:"french.?polynesia|tahiti",ATF:"french.?southern",GAB:"gabon",GMB:"gambia",GEO:"^(?!.*south).*georgia",DDR:"german.?democratic.?republic|democratic.?republic.*germany|east.germany",DEU:"^(?!.*east).*germany|^(?=.*\\bfed.*\\brep).*german",GHA:"ghana|gold.?coast",GIB:"gibraltar",GRC:"greece|hellenic|hellas",GRL:"greenland",GRD:"grenada",GLP:"guadeloupe",GUM:"\\bguam",GTM:"guatemala",GGY:"guernsey",GIN:"^(?!.*eq)(?!.*span)(?!.*bissau)(?!.*portu)(?!.*new).*guinea",GNB:"bissau|^(?=.*portu).*guinea",GUY:"guyana|british.?guiana",HTI:"haiti",HMD:"heard.*mcdonald",VAT:"holy.?see|vatican|papal.?st",HND:"^(?!.*brit).*honduras",HKG:"hong.?kong",HUN:"^(?!.*austr).*hungary",ISL:"iceland",IND:"india(?!.*ocea)",IDN:"indonesia",IRN:"\\biran|persia",IRQ:"\\biraq|mesopotamia",IRL:"(^ireland)|(^republic.*ireland)",IMN:"^(?=.*isle).*\\bman",ISR:"israel",ITA:"italy",JAM:"jamaica",JPN:"japan",JEY:"jersey",JOR:"jordan",KAZ:"kazak",KEN:"kenya|british.?east.?africa|east.?africa.?prot",KIR:"kiribati",PRK:"^(?=.*democrat|people|north|d.*p.*.r).*\\bkorea|dprk|korea.*(d.*p.*r)",KWT:"kuwait",KGZ:"kyrgyz|kirghiz",LAO:"\\blaos?\\b",LVA:"latvia",LBN:"lebanon",LSO:"lesotho|basuto",LBR:"liberia",LBY:"libya",LIE:"liechtenstein",LTU:"lithuania",LUX:"^(?!.*belg).*luxem",MAC:"maca(o|u)",MDG:"madagascar|malagasy",MWI:"malawi|nyasa",MYS:"malaysia",MDV:"maldive",MLI:"\\bmali\\b",MLT:"\\bmalta",MHL:"marshall",MTQ:"martinique",MRT:"mauritania",MUS:"mauritius",MYT:"\\bmayotte",MEX:"\\bmexic",FSM:"fed.*micronesia|micronesia.*fed",MCO:"monaco",MNG:"mongolia",MNE:"^(?!.*serbia).*montenegro",MSR:"montserrat",MAR:"morocco|\\bmaroc",MOZ:"mozambique",MMR:"myanmar|burma",NAM:"namibia",NRU:"nauru",NPL:"nepal",NLD:"^(?!.*\\bant)(?!.*\\bcarib).*netherlands",ANT:"^(?=.*\\bant).*(nether|dutch)",NCL:"new.?caledonia",NZL:"new.?zealand",NIC:"nicaragua",NER:"\\bniger(?!ia)",NGA:"nigeria",NIU:"niue",NFK:"norfolk",MNP:"mariana",NOR:"norway",OMN:"\\boman|trucial",PAK:"^(?!.*east).*paki?stan",PLW:"palau",PSE:"palestin|\\bgaza|west.?bank",PAN:"panama",PNG:"papua|new.?guinea",PRY:"paraguay",PER:"peru",PHL:"philippines",PCN:"pitcairn",POL:"poland",PRT:"portugal",PRI:"puerto.?rico",QAT:"qatar",KOR:"^(?!.*d.*p.*r)(?!.*democrat)(?!.*people)(?!.*north).*\\bkorea(?!.*d.*p.*r)",MDA:"moldov|b(a|e)ssarabia",REU:"r(e|\xe9)union",ROU:"r(o|u|ou)mania",RUS:"\\brussia|soviet.?union|u\\.?s\\.?s\\.?r|socialist.?republics",RWA:"rwanda",BLM:"barth(e|\xe9)lemy",SHN:"helena",KNA:"kitts|\\bnevis",LCA:"\\blucia",MAF:"^(?=.*collectivity).*martin|^(?=.*france).*martin(?!ique)|^(?=.*french).*martin(?!ique)",SPM:"miquelon",VCT:"vincent",WSM:"^(?!.*amer).*samoa",SMR:"san.?marino",STP:"\\bs(a|\xe3)o.?tom(e|\xe9)",SAU:"\\bsa\\w*.?arabia",SEN:"senegal",SRB:"^(?!.*monte).*serbia",SYC:"seychell",SLE:"sierra",SGP:"singapore",SXM:"^(?!.*martin)(?!.*saba).*maarten",SVK:"^(?!.*cze).*slovak",SVN:"slovenia",SLB:"solomon",SOM:"somali",ZAF:"south.africa|s\\\\..?africa",SGS:"south.?georgia|sandwich",SSD:"\\bs\\w*.?sudan",ESP:"spain",LKA:"sri.?lanka|ceylon",SDN:"^(?!.*\\bs(?!u)).*sudan",SUR:"surinam|dutch.?guiana",SJM:"svalbard",SWZ:"swaziland",SWE:"sweden",CHE:"switz|swiss",SYR:"syria",TWN:"taiwan|taipei|formosa|^(?!.*peo)(?=.*rep).*china",TJK:"tajik",THA:"thailand|\\bsiam",MKD:"macedonia|fyrom",TLS:"^(?=.*leste).*timor|^(?=.*east).*timor",TGO:"togo",TKL:"tokelau",TON:"tonga",TTO:"trinidad|tobago",TUN:"tunisia",TUR:"turkey",TKM:"turkmen",TCA:"turks",TUV:"tuvalu",UGA:"uganda",UKR:"ukrain",ARE:"emirates|^u\\.?a\\.?e\\.?$|united.?arab.?em",GBR:"united.?kingdom|britain|^u\\.?k\\.?$",TZA:"tanzania",USA:"united.?states\\b(?!.*islands)|\\bu\\.?s\\.?a\\.?\\b|^\\s*u\\.?s\\.?\\b(?!.*islands)",UMI:"minor.?outlying.?is",URY:"uruguay",UZB:"uzbek",VUT:"vanuatu|new.?hebrides",VEN:"venezuela",VNM:"^(?!.*republic).*viet.?nam|^(?=.*socialist).*viet.?nam",VGB:"^(?=.*\\bu\\.?\\s?k).*virgin|^(?=.*brit).*virgin|^(?=.*kingdom).*virgin",VIR:"^(?=.*\\bu\\.?\\s?s).*virgin|^(?=.*states).*virgin",WLF:"futuna|wallis",ESH:"western.sahara",YEM:"^(?!.*arab)(?!.*north)(?!.*sana)(?!.*peo)(?!.*dem)(?!.*south)(?!.*aden)(?!.*\\bp\\.?d\\.?r).*yemen",YMD:"^(?=.*peo).*yemen|^(?!.*rep)(?=.*dem).*yemen|^(?=.*south).*yemen|^(?=.*aden).*yemen|^(?=.*\\bp\\.?d\\.?r).*yemen",YUG:"yugoslavia",ZMB:"zambia|northern.?rhodesia",EAZ:"zanzibar",ZWE:"zimbabwe|^(?!.*northern).*rhodesia"}},{}],122:[function(t,e,r){e.exports=["xx-small","x-small","small","medium","large","x-large","xx-large","larger","smaller"]},{}],123:[function(t,e,r){e.exports=["normal","condensed","semi-condensed","extra-condensed","ultra-condensed","expanded","semi-expanded","extra-expanded","ultra-expanded"]},{}],124:[function(t,e,r){e.exports=["normal","italic","oblique"]},{}],125:[function(t,e,r){e.exports=["normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900"]},{}],126:[function(t,e,r){"use strict";e.exports={parse:t("./parse"),stringify:t("./stringify")}},{"./parse":128,"./stringify":129}],127:[function(t,e,r){"use strict";var n=t("css-font-size-keywords");e.exports={isSize:function(t){return/^[\d\.]/.test(t)||-1!==t.indexOf("/")||-1!==n.indexOf(t)}}},{"css-font-size-keywords":122}],128:[function(t,e,r){"use strict";var n=t("unquote"),i=t("css-global-keywords"),a=t("css-system-font-keywords"),o=t("css-font-weight-keywords"),s=t("css-font-style-keywords"),l=t("css-font-stretch-keywords"),c=t("string-split-by"),u=t("./lib/util").isSize;e.exports=f;var h=f.cache={};function f(t){if("string"!=typeof t)throw new Error("Font argument must be a string.");if(h[t])return h[t];if(""===t)throw new Error("Cannot parse an empty string.");if(-1!==a.indexOf(t))return h[t]={system:t};for(var e,r={style:"normal",variant:"normal",weight:"normal",stretch:"normal",lineHeight:"normal",size:"1rem",family:["serif"]},f=c(t,/\s+/);e=f.shift();){if(-1!==i.indexOf(e))return["style","variant","weight","stretch"].forEach(function(t){r[t]=e}),h[t]=r;if(-1===s.indexOf(e))if("normal"!==e&&"small-caps"!==e)if(-1===l.indexOf(e)){if(-1===o.indexOf(e)){if(u(e)){var d=c(e,"/");if(r.size=d[0],null!=d[1]?r.lineHeight=p(d[1]):"/"===f[0]&&(f.shift(),r.lineHeight=p(f.shift())),!f.length)throw new Error("Missing required font-family.");return r.family=c(f.join(" "),/\s*,\s*/).map(n),h[t]=r}throw new Error("Unknown or unsupported font token: "+e)}r.weight=e}else r.stretch=e;else r.variant=e;else r.style=e}throw new Error("Missing required font-size.")}function p(t){var e=parseFloat(t);return e.toString()===t?e:t}},{"./lib/util":127,"css-font-stretch-keywords":123,"css-font-style-keywords":124,"css-font-weight-keywords":125,"css-global-keywords":130,"css-system-font-keywords":131,"string-split-by":490,unquote:510}],129:[function(t,e,r){"use strict";var n=t("pick-by-alias"),i=t("./lib/util").isSize,a=g(t("css-global-keywords")),o=g(t("css-system-font-keywords")),s=g(t("css-font-weight-keywords")),l=g(t("css-font-style-keywords")),c=g(t("css-font-stretch-keywords")),u={normal:1,"small-caps":1},h={serif:1,"sans-serif":1,monospace:1,cursive:1,fantasy:1,"system-ui":1},f="1rem",p="serif";function d(t,e){if(t&&!e[t]&&!a[t])throw Error("Unknown keyword `"+t+"`");return t}function g(t){for(var e={},r=0;r=0;--p)a[p]=c*t[p]+u*e[p]+h*r[p]+f*n[p];return a}return c*t+u*e+h*r+f*n},e.exports.derivative=function(t,e,r,n,i,a){var o=6*i*i-6*i,s=3*i*i-4*i+1,l=-6*i*i+6*i,c=3*i*i-2*i;if(t.length){a||(a=new Array(t.length));for(var u=t.length-1;u>=0;--u)a[u]=o*t[u]+s*e[u]+l*r[u]+c*n[u];return a}return o*t+s*e+l*r[u]+c*n}},{}],133:[function(t,e,r){"use strict";var n=t("./lib/thunk.js");function i(){this.argTypes=[],this.shimArgs=[],this.arrayArgs=[],this.arrayBlockIndices=[],this.scalarArgs=[],this.offsetArgs=[],this.offsetArgIndex=[],this.indexArgs=[],this.shapeArgs=[],this.funcName="",this.pre=null,this.body=null,this.post=null,this.debug=!1}e.exports=function(t){var e=new i;e.pre=t.pre,e.body=t.body,e.post=t.post;var r=t.args.slice(0);e.argTypes=r;for(var a=0;a0)throw new Error("cwise: pre() block may not reference array args");if(a0)throw new Error("cwise: post() block may not reference array args")}else if("scalar"===o)e.scalarArgs.push(a),e.shimArgs.push("scalar"+a);else if("index"===o){if(e.indexArgs.push(a),a0)throw new Error("cwise: pre() block may not reference array index");if(a0)throw new Error("cwise: post() block may not reference array index")}else if("shape"===o){if(e.shapeArgs.push(a),ar.length)throw new Error("cwise: Too many arguments in pre() block");if(e.body.args.length>r.length)throw new Error("cwise: Too many arguments in body() block");if(e.post.args.length>r.length)throw new Error("cwise: Too many arguments in post() block");return e.debug=!!t.printCode||!!t.debug,e.funcName=t.funcName||"cwise",e.blockSize=t.blockSize||64,n(e)}},{"./lib/thunk.js":135}],134:[function(t,e,r){"use strict";var n=t("uniq");function i(t,e,r){var n,i,a=t.length,o=e.arrayArgs.length,s=e.indexArgs.length>0,l=[],c=[],u=0,h=0;for(n=0;n0&&l.push("var "+c.join(",")),n=a-1;n>=0;--n)u=t[n],l.push(["for(i",n,"=0;i",n,"0&&l.push(["index[",h,"]-=s",h].join("")),l.push(["++index[",u,"]"].join(""))),l.push("}")}return l.join("\n")}function a(t,e,r){for(var n=t.body,i=[],a=[],o=0;o0&&y.push("shape=SS.slice(0)"),t.indexArgs.length>0){var x=new Array(r);for(l=0;l0&&v.push("var "+y.join(",")),l=0;l3&&v.push(a(t.pre,t,s));var k=a(t.body,t,s),M=function(t){for(var e=0,r=t[0].length;e0,c=[],u=0;u0;){"].join("")),c.push(["if(j",u,"<",s,"){"].join("")),c.push(["s",e[u],"=j",u].join("")),c.push(["j",u,"=0"].join("")),c.push(["}else{s",e[u],"=",s].join("")),c.push(["j",u,"-=",s,"}"].join("")),l&&c.push(["index[",e[u],"]=j",u].join(""));for(u=0;u3&&v.push(a(t.post,t,s)),t.debug&&console.log("-----Generated cwise routine for ",e,":\n"+v.join("\n")+"\n----------");var A=[t.funcName||"unnamed","_cwise_loop_",o[0].join("s"),"m",M,function(t){for(var e=new Array(t.length),r=!0,n=0;n0&&(r=r&&e[n]===e[n-1])}return r?e[0]:e.join("")}(s)].join("");return new Function(["function ",A,"(",m.join(","),"){",v.join("\n"),"} return ",A].join(""))()}},{uniq:509}],135:[function(t,e,r){"use strict";var n=t("./compile.js");e.exports=function(t){var e=["'use strict'","var CACHED={}"],r=[],i=t.funcName+"_cwise_thunk";e.push(["return function ",i,"(",t.shimArgs.join(","),"){"].join(""));for(var a=[],o=[],s=[["array",t.arrayArgs[0],".shape.slice(",Math.max(0,t.arrayBlockIndices[0]),t.arrayBlockIndices[0]<0?","+t.arrayBlockIndices[0]+")":")"].join("")],l=[],c=[],u=0;u0&&(l.push("array"+t.arrayArgs[0]+".shape.length===array"+h+".shape.length+"+(Math.abs(t.arrayBlockIndices[0])-Math.abs(t.arrayBlockIndices[u]))),c.push("array"+t.arrayArgs[0]+".shape[shapeIndex+"+Math.max(0,t.arrayBlockIndices[0])+"]===array"+h+".shape[shapeIndex+"+Math.max(0,t.arrayBlockIndices[u])+"]"))}for(t.arrayArgs.length>1&&(e.push("if (!("+l.join(" && ")+")) throw new Error('cwise: Arrays do not all have the same dimensionality!')"),e.push("for(var shapeIndex=array"+t.arrayArgs[0]+".shape.length-"+Math.abs(t.arrayBlockIndices[0])+"; shapeIndex--\x3e0;) {"),e.push("if (!("+c.join(" && ")+")) throw new Error('cwise: Arrays do not all have the same shape!')"),e.push("}")),u=0;ue?1:t>=e?0:NaN},r=function(t){var r;return 1===t.length&&(r=t,t=function(t,n){return e(r(t),n)}),{left:function(e,r,n,i){for(null==n&&(n=0),null==i&&(i=e.length);n>>1;t(e[a],r)<0?n=a+1:i=a}return n},right:function(e,r,n,i){for(null==n&&(n=0),null==i&&(i=e.length);n>>1;t(e[a],r)>0?i=a:n=a+1}return n}}};var n=r(e),i=n.right,a=n.left;function o(t,e){return[t,e]}var s=function(t){return null===t?NaN:+t},l=function(t,e){var r,n,i=t.length,a=0,o=-1,l=0,c=0;if(null==e)for(;++o1)return c/(a-1)},c=function(t,e){var r=l(t,e);return r?Math.sqrt(r):r},u=function(t,e){var r,n,i,a=t.length,o=-1;if(null==e){for(;++o=r)for(n=i=r;++or&&(n=r),i=r)for(n=i=r;++or&&(n=r),i=0?(a>=v?10:a>=y?5:a>=x?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=v?10:a>=y?5:a>=x?2:1)}function _(t,e,r){var n=Math.abs(e-t)/Math.max(0,r),i=Math.pow(10,Math.floor(Math.log(n)/Math.LN10)),a=n/i;return a>=v?i*=10:a>=y?i*=5:a>=x&&(i*=2),e=1)return+r(t[n-1],n-1,t);var n,i=(n-1)*e,a=Math.floor(i),o=+r(t[a],a,t);return o+(+r(t[a+1],a+1,t)-o)*(i-a)}},M=function(t,e){var r,n,i=t.length,a=-1;if(null==e){for(;++a=r)for(n=r;++ar&&(n=r)}else for(;++a=r)for(n=r;++ar&&(n=r);return n},A=function(t){if(!(i=t.length))return[];for(var e=-1,r=M(t,T),n=new Array(r);++et?1:e>=t?0:NaN},t.deviation=c,t.extent=u,t.histogram=function(){var t=g,e=u,r=w;function n(n){var a,o,s=n.length,l=new Array(s);for(a=0;ah;)f.pop(),--p;var d,g=new Array(p+1);for(a=0;a<=p;++a)(d=g[a]=[]).x0=a>0?f[a-1]:u,d.x1=a=r)for(n=r;++an&&(n=r)}else for(;++a=r)for(n=r;++an&&(n=r);return n},t.mean=function(t,e){var r,n=t.length,i=n,a=-1,o=0;if(null==e)for(;++a=0;)for(e=(n=t[i]).length;--e>=0;)r[--o]=n[e];return r},t.min=M,t.pairs=function(t,e){null==e&&(e=o);for(var r=0,n=t.length-1,i=t[0],a=new Array(n<0?0:n);r0)return[t];if((n=e0)for(t=Math.ceil(t/o),e=Math.floor(e/o),a=new Array(i=Math.ceil(e-t+1));++s=l.length)return null!=t&&n.sort(t),null!=e?e(n):n;for(var s,c,h,f=-1,p=n.length,d=l[i++],g=r(),m=a();++fl.length)return r;var i,a=c[n-1];return null!=e&&n>=l.length?i=r.entries():(i=[],r.each(function(e,r){i.push({key:r,values:t(e,n)})})),null!=a?i.sort(function(t,e){return a(t.key,e.key)}):i}(u(t,0,a,o),0)},key:function(t){return l.push(t),s},sortKeys:function(t){return c[l.length-1]=t,s},sortValues:function(e){return t=e,s},rollup:function(t){return e=t,s}}},t.set=c,t.map=r,t.keys=function(t){var e=[];for(var r in t)e.push(r);return e},t.values=function(t){var e=[];for(var r in t)e.push(t[r]);return e},t.entries=function(t){var e=[];for(var r in t)e.push({key:r,value:t[r]});return e},Object.defineProperty(t,"__esModule",{value:!0})}("object"==typeof r&&"undefined"!=typeof e?r:n.d3=n.d3||{})},{}],141:[function(t,e,r){var n;n=this,function(t){"use strict";var e=function(t,e,r){t.prototype=e.prototype=r,r.constructor=t};function r(t,e){var r=Object.create(t.prototype);for(var n in e)r[n]=e[n];return r}function n(){}var i="\\s*([+-]?\\d+)\\s*",a="\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",o="\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",s=/^#([0-9a-f]{3})$/,l=/^#([0-9a-f]{6})$/,c=new RegExp("^rgb\\("+[i,i,i]+"\\)$"),u=new RegExp("^rgb\\("+[o,o,o]+"\\)$"),h=new RegExp("^rgba\\("+[i,i,i,a]+"\\)$"),f=new RegExp("^rgba\\("+[o,o,o,a]+"\\)$"),p=new RegExp("^hsl\\("+[a,o,o]+"\\)$"),d=new RegExp("^hsla\\("+[a,o,o,a]+"\\)$"),g={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,rebeccapurple:6697881,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};function m(t){var e;return t=(t+"").trim().toLowerCase(),(e=s.exec(t))?new _((e=parseInt(e[1],16))>>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):(e=l.exec(t))?v(parseInt(e[1],16)):(e=c.exec(t))?new _(e[1],e[2],e[3],1):(e=u.exec(t))?new _(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=h.exec(t))?y(e[1],e[2],e[3],e[4]):(e=f.exec(t))?y(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=p.exec(t))?w(e[1],e[2]/100,e[3]/100,1):(e=d.exec(t))?w(e[1],e[2]/100,e[3]/100,e[4]):g.hasOwnProperty(t)?v(g[t]):"transparent"===t?new _(NaN,NaN,NaN,0):null}function v(t){return new _(t>>16&255,t>>8&255,255&t,1)}function y(t,e,r,n){return n<=0&&(t=e=r=NaN),new _(t,e,r,n)}function x(t){return t instanceof n||(t=m(t)),t?new _((t=t.rgb()).r,t.g,t.b,t.opacity):new _}function b(t,e,r,n){return 1===arguments.length?x(t):new _(t,e,r,null==n?1:n)}function _(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}function w(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new M(t,e,r,n)}function k(t,e,r,i){return 1===arguments.length?function(t){if(t instanceof M)return new M(t.h,t.s,t.l,t.opacity);if(t instanceof n||(t=m(t)),!t)return new M;if(t instanceof M)return t;var e=(t=t.rgb()).r/255,r=t.g/255,i=t.b/255,a=Math.min(e,r,i),o=Math.max(e,r,i),s=NaN,l=o-a,c=(o+a)/2;return l?(s=e===o?(r-i)/l+6*(r0&&c<1?0:s,new M(s,l,c,t.opacity)}(t):new M(t,e,r,null==i?1:i)}function M(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}function A(t,e,r){return 255*(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)}e(n,m,{displayable:function(){return this.rgb().displayable()},toString:function(){return this.rgb()+""}}),e(_,b,r(n,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new _(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new _(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&this.r<=255&&0<=this.g&&this.g<=255&&0<=this.b&&this.b<=255&&0<=this.opacity&&this.opacity<=1},toString:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}})),e(M,k,r(n,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new M(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new M(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,i=2*r-n;return new _(A(t>=240?t-240:t+120,i,n),A(t,i,n),A(t<120?t+240:t-120,i,n),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var T=Math.PI/180,S=180/Math.PI,E=.95047,C=1,L=1.08883,z=4/29,P=6/29,I=3*P*P,O=P*P*P;function D(t){if(t instanceof B)return new B(t.l,t.a,t.b,t.opacity);if(t instanceof q){var e=t.h*T;return new B(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}t instanceof _||(t=x(t));var r=V(t.r),n=V(t.g),i=V(t.b),a=F((.4124564*r+.3575761*n+.1804375*i)/E),o=F((.2126729*r+.7151522*n+.072175*i)/C);return new B(116*o-16,500*(a-o),200*(o-F((.0193339*r+.119192*n+.9503041*i)/L)),t.opacity)}function R(t,e,r,n){return 1===arguments.length?D(t):new B(t,e,r,null==n?1:n)}function B(t,e,r,n){this.l=+t,this.a=+e,this.b=+r,this.opacity=+n}function F(t){return t>O?Math.pow(t,1/3):t/I+z}function N(t){return t>P?t*t*t:I*(t-z)}function j(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function V(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function U(t,e,r,n){return 1===arguments.length?function(t){if(t instanceof q)return new q(t.h,t.c,t.l,t.opacity);t instanceof B||(t=D(t));var e=Math.atan2(t.b,t.a)*S;return new q(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}(t):new q(t,e,r,null==n?1:n)}function q(t,e,r,n){this.h=+t,this.c=+e,this.l=+r,this.opacity=+n}e(B,R,r(n,{brighter:function(t){return new B(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker:function(t){return new B(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb:function(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,r=isNaN(this.b)?t:t-this.b/200;return t=C*N(t),new _(j(3.2404542*(e=E*N(e))-1.5371385*t-.4985314*(r=L*N(r))),j(-.969266*e+1.8760108*t+.041556*r),j(.0556434*e-.2040259*t+1.0572252*r),this.opacity)}})),e(q,U,r(n,{brighter:function(t){return new q(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker:function(t){return new q(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb:function(){return D(this).rgb()}}));var H=-.14861,G=1.78277,W=-.29227,Y=-.90649,X=1.97294,Z=X*Y,$=X*G,J=G*W-Y*H;function K(t,e,r,n){return 1===arguments.length?function(t){if(t instanceof Q)return new Q(t.h,t.s,t.l,t.opacity);t instanceof _||(t=x(t));var e=t.r/255,r=t.g/255,n=t.b/255,i=(J*n+Z*e-$*r)/(J+Z-$),a=n-i,o=(X*(r-i)-W*a)/Y,s=Math.sqrt(o*o+a*a)/(X*i*(1-i)),l=s?Math.atan2(o,a)*S-120:NaN;return new Q(l<0?l+360:l,s,i,t.opacity)}(t):new Q(t,e,r,null==n?1:n)}function Q(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}e(Q,K,r(n,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new Q(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Q(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=isNaN(this.h)?0:(this.h+120)*T,e=+this.l,r=isNaN(this.s)?0:this.s*e*(1-e),n=Math.cos(t),i=Math.sin(t);return new _(255*(e+r*(H*n+G*i)),255*(e+r*(W*n+Y*i)),255*(e+r*(X*n)),this.opacity)}})),t.color=m,t.rgb=b,t.hsl=k,t.lab=R,t.hcl=U,t.cubehelix=K,Object.defineProperty(t,"__esModule",{value:!0})}("object"==typeof r&&"undefined"!=typeof e?r:n.d3=n.d3||{})},{}],142:[function(t,e,r){var n;n=this,function(t){"use strict";var e={value:function(){}};function r(){for(var t,e=0,r=arguments.length,i={};e=0&&(e=t.slice(r+1),t=t.slice(0,r)),t&&!n.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}})),l=-1,c=s.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++l0)for(var r,n,i=new Array(r),a=0;af+c||np+c||au.index){var h=f-s.x-s.vx,m=p-s.y-s.vy,v=h*h+m*m;vt.r&&(t.r=t[e].r)}function f(){if(r){var e,i,a=r.length;for(n=new Array(a),e=0;e=c)){(t.data!==r||t.next)&&(0===h&&(d+=(h=o())*h),0===f&&(d+=(f=o())*f),d1?(null==r?u.remove(t):u.set(t,y(r)),e):u.get(t)},find:function(e,r,n){var i,a,o,s,l,c=0,u=t.length;for(null==n?n=1/0:n*=n,c=0;c1?(f.on(t,r),e):f.on(t)}}},t.forceX=function(t){var e,r,n,i=a(.1);function o(t){for(var i,a=0,o=e.length;a=1?(n=1,e-1):Math.floor(n*e),a=t[i],o=t[i+1],s=i>0?t[i-1]:2*a-o,l=i180||r<-180?r-360*Math.round(r/360):r):a(isNaN(t)?e:t)}function l(t){return 1==(t=+t)?c:function(e,r){return r-e?function(t,e,r){return t=Math.pow(t,r),e=Math.pow(e,r)-t,r=1/r,function(n){return Math.pow(t+n*e,r)}}(e,r,t):a(isNaN(e)?r:e)}}function c(t,e){var r=e-t;return r?o(t,r):a(isNaN(t)?e:t)}var u=function t(r){var n=l(r);function i(t,r){var i=n((t=e.rgb(t)).r,(r=e.rgb(r)).r),a=n(t.g,r.g),o=n(t.b,r.b),s=c(t.opacity,r.opacity);return function(e){return t.r=i(e),t.g=a(e),t.b=o(e),t.opacity=s(e),t+""}}return i.gamma=t,i}(1);function h(t){return function(r){var n,i,a=r.length,o=new Array(a),s=new Array(a),l=new Array(a);for(n=0;na&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(r=r[0])===(n=n[0])?s[o]?s[o]+=n:s[++o]=n:(s[++o]=null,l.push({i:o,x:m(r,n)})),a=x.lastIndex;return a180?e+=360:e-t>180&&(t+=360),a.push({i:r.push(i(r)+"rotate(",null,n)-2,x:m(t,e)})):e&&r.push(i(r)+"rotate("+e+n)}(a.rotate,o.rotate,s,l),function(t,e,r,a){t!==e?a.push({i:r.push(i(r)+"skewX(",null,n)-2,x:m(t,e)}):e&&r.push(i(r)+"skewX("+e+n)}(a.skewX,o.skewX,s,l),function(t,e,r,n,a,o){if(t!==r||e!==n){var s=a.push(i(a)+"scale(",null,",",null,")");o.push({i:s-4,x:m(t,r)},{i:s-2,x:m(e,n)})}else 1===r&&1===n||a.push(i(a)+"scale("+r+","+n+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,l),a=o=null,function(t){for(var e,r=-1,n=l.length;++r=(a=(g+v)/2))?g=a:v=a,(u=r>=(o=(m+y)/2))?m=o:y=o,i=p,!(p=p[h=u<<1|c]))return i[h]=d,t;if(s=+t._x.call(null,p.data),l=+t._y.call(null,p.data),e===s&&r===l)return d.next=p,i?i[h]=d:t._root=d,t;do{i=i?i[h]=new Array(4):t._root=new Array(4),(c=e>=(a=(g+v)/2))?g=a:v=a,(u=r>=(o=(m+y)/2))?m=o:y=o}while((h=u<<1|c)==(f=(l>=o)<<1|s>=a));return i[f]=p,i[h]=d,t}var r=function(t,e,r,n,i){this.node=t,this.x0=e,this.y0=r,this.x1=n,this.y1=i};function n(t){return t[0]}function i(t){return t[1]}function a(t,e,r){var a=new o(null==e?n:e,null==r?i:r,NaN,NaN,NaN,NaN);return null==t?a:a.addAll(t)}function o(t,e,r,n,i,a){this._x=t,this._y=e,this._x0=r,this._y0=n,this._x1=i,this._y1=a,this._root=void 0}function s(t){for(var e={data:t.data},r=e;t=t.next;)r=r.next={data:t.data};return e}var l=a.prototype=o.prototype;l.copy=function(){var t,e,r=new o(this._x,this._y,this._x0,this._y0,this._x1,this._y1),n=this._root;if(!n)return r;if(!n.length)return r._root=s(n),r;for(t=[{source:n,target:r._root=new Array(4)}];n=t.pop();)for(var i=0;i<4;++i)(e=n.source[i])&&(e.length?t.push({source:e,target:n.target[i]=new Array(4)}):n.target[i]=s(e));return r},l.add=function(t){var r=+this._x.call(null,t),n=+this._y.call(null,t);return e(this.cover(r,n),r,n,t)},l.addAll=function(t){var r,n,i,a,o=t.length,s=new Array(o),l=new Array(o),c=1/0,u=1/0,h=-1/0,f=-1/0;for(n=0;nh&&(h=i),af&&(f=a));for(ht||t>i||n>e||e>a))return this;var o,s,l=i-r,c=this._root;switch(s=(e<(n+a)/2)<<1|t<(r+i)/2){case 0:do{(o=new Array(4))[s]=c,c=o}while(a=n+(l*=2),t>(i=r+l)||e>a);break;case 1:do{(o=new Array(4))[s]=c,c=o}while(a=n+(l*=2),(r=i-l)>t||e>a);break;case 2:do{(o=new Array(4))[s]=c,c=o}while(n=a-(l*=2),t>(i=r+l)||n>e);break;case 3:do{(o=new Array(4))[s]=c,c=o}while(n=a-(l*=2),(r=i-l)>t||n>e)}this._root&&this._root.length&&(this._root=c)}return this._x0=r,this._y0=n,this._x1=i,this._y1=a,this},l.data=function(){var t=[];return this.visit(function(e){if(!e.length)do{t.push(e.data)}while(e=e.next)}),t},l.extent=function(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},l.find=function(t,e,n){var i,a,o,s,l,c,u,h=this._x0,f=this._y0,p=this._x1,d=this._y1,g=[],m=this._root;for(m&&g.push(new r(m,h,f,p,d)),null==n?n=1/0:(h=t-n,f=e-n,p=t+n,d=e+n,n*=n);c=g.pop();)if(!(!(m=c.node)||(a=c.x0)>p||(o=c.y0)>d||(s=c.x1)=y)<<1|t>=v)&&(c=g[g.length-1],g[g.length-1]=g[g.length-1-u],g[g.length-1-u]=c)}else{var x=t-+this._x.call(null,m.data),b=e-+this._y.call(null,m.data),_=x*x+b*b;if(_=(s=(d+m)/2))?d=s:m=s,(u=o>=(l=(g+v)/2))?g=l:v=l,e=p,!(p=p[h=u<<1|c]))return this;if(!p.length)break;(e[h+1&3]||e[h+2&3]||e[h+3&3])&&(r=e,f=h)}for(;p.data!==t;)if(n=p,!(p=p.next))return this;return(i=p.next)&&delete p.next,n?(i?n.next=i:delete n.next,this):e?(i?e[h]=i:delete e[h],(p=e[0]||e[1]||e[2]||e[3])&&p===(e[3]||e[2]||e[1]||e[0])&&!p.length&&(r?r[f]=p:this._root=p),this):(this._root=i,this)},l.removeAll=function(t){for(var e=0,r=t.length;e=0&&r._call.call(null,t),r=r._next;--n}function v(){l=(s=u.now())+c,n=i=0;try{m()}finally{n=0,function(){var t,n,i=e,a=1/0;for(;i;)i._call?(a>i._time&&(a=i._time),t=i,i=i._next):(n=i._next,i._next=null,i=t?t._next=n:e=n);r=t,x(a)}(),l=0}}function y(){var t=u.now(),e=t-s;e>o&&(c-=e,s=t)}function x(t){n||(i&&(i=clearTimeout(i)),t-l>24?(t<1/0&&(i=setTimeout(v,t-u.now()-c)),a&&(a=clearInterval(a))):(a||(s=u.now(),a=setInterval(y,o)),n=1,h(v)))}d.prototype=g.prototype={constructor:d,restart:function(t,n,i){if("function"!=typeof t)throw new TypeError("callback is not a function");i=(null==i?f():+i)+(null==n?0:+n),this._next||r===this||(r?r._next=this:e=this,r=this),this._call=t,this._time=i,x()},stop:function(){this._call&&(this._call=null,this._time=1/0,x())}};t.now=f,t.timer=g,t.timerFlush=m,t.timeout=function(t,e,r){var n=new d;return e=null==e?0:+e,n.restart(function(r){n.stop(),t(r+e)},e,r),n},t.interval=function(t,e,r){var n=new d,i=e;return null==e?(n.restart(t,e,r),n):(e=+e,r=null==r?f():+r,n.restart(function a(o){o+=i,n.restart(a,i+=e,r),t(o)},e,r),n)},Object.defineProperty(t,"__esModule",{value:!0})}("object"==typeof r&&"undefined"!=typeof e?r:n.d3=n.d3||{})},{}],147:[function(t,e,r){!function(){var t={version:"3.5.17"},r=[].slice,n=function(t){return r.call(t)},i=this.document;function a(t){return t&&(t.ownerDocument||t.document||t).documentElement}function o(t){return t&&(t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView)}if(i)try{n(i.documentElement.childNodes)[0].nodeType}catch(t){n=function(t){for(var e=t.length,r=new Array(e);e--;)r[e]=t[e];return r}}if(Date.now||(Date.now=function(){return+new Date}),i)try{i.createElement("DIV").style.setProperty("opacity",0,"")}catch(t){var s=this.Element.prototype,l=s.setAttribute,c=s.setAttributeNS,u=this.CSSStyleDeclaration.prototype,h=u.setProperty;s.setAttribute=function(t,e){l.call(this,t,e+"")},s.setAttributeNS=function(t,e,r){c.call(this,t,e,r+"")},u.setProperty=function(t,e,r){h.call(this,t,e+"",r)}}function f(t,e){return te?1:t>=e?0:NaN}function p(t){return null===t?NaN:+t}function d(t){return!isNaN(t)}function g(t){return{left:function(e,r,n,i){for(arguments.length<3&&(n=0),arguments.length<4&&(i=e.length);n>>1;t(e[a],r)<0?n=a+1:i=a}return n},right:function(e,r,n,i){for(arguments.length<3&&(n=0),arguments.length<4&&(i=e.length);n>>1;t(e[a],r)>0?i=a:n=a+1}return n}}}t.ascending=f,t.descending=function(t,e){return et?1:e>=t?0:NaN},t.min=function(t,e){var r,n,i=-1,a=t.length;if(1===arguments.length){for(;++i=n){r=n;break}for(;++in&&(r=n)}else{for(;++i=n){r=n;break}for(;++in&&(r=n)}return r},t.max=function(t,e){var r,n,i=-1,a=t.length;if(1===arguments.length){for(;++i=n){r=n;break}for(;++ir&&(r=n)}else{for(;++i=n){r=n;break}for(;++ir&&(r=n)}return r},t.extent=function(t,e){var r,n,i,a=-1,o=t.length;if(1===arguments.length){for(;++a=n){r=i=n;break}for(;++an&&(r=n),i=n){r=i=n;break}for(;++an&&(r=n),i1)return o/(l-1)},t.deviation=function(){var e=t.variance.apply(this,arguments);return e?Math.sqrt(e):e};var m=g(f);function v(t){return t.length}t.bisectLeft=m.left,t.bisect=t.bisectRight=m.right,t.bisector=function(t){return g(1===t.length?function(e,r){return f(t(e),r)}:t)},t.shuffle=function(t,e,r){(a=arguments.length)<3&&(r=t.length,a<2&&(e=0));for(var n,i,a=r-e;a;)i=Math.random()*a--|0,n=t[a+e],t[a+e]=t[i+e],t[i+e]=n;return t},t.permute=function(t,e){for(var r=e.length,n=new Array(r);r--;)n[r]=t[e[r]];return n},t.pairs=function(t){for(var e=0,r=t.length-1,n=t[0],i=new Array(r<0?0:r);e=0;)for(e=(n=t[i]).length;--e>=0;)r[--o]=n[e];return r};var y=Math.abs;function x(t,e){for(var r in e)Object.defineProperty(t.prototype,r,{value:e[r],enumerable:!1})}function b(){this._=Object.create(null)}t.range=function(t,e,r){if(arguments.length<3&&(r=1,arguments.length<2&&(e=t,t=0)),(e-t)/r==1/0)throw new Error("infinite range");var n,i=[],a=function(t){var e=1;for(;t*e%1;)e*=10;return e}(y(r)),o=-1;if(t*=a,e*=a,(r*=a)<0)for(;(n=t+r*++o)>e;)i.push(n/a);else for(;(n=t+r*++o)=i.length)return r?r.call(n,a):e?a.sort(e):a;for(var l,c,u,h,f=-1,p=a.length,d=i[s++],g=new b;++f=i.length)return e;var n=[],o=a[r++];return e.forEach(function(e,i){n.push({key:e,values:t(i,r)})}),o?n.sort(function(t,e){return o(t.key,e.key)}):n}(o(t.map,e,0),0)},n.key=function(t){return i.push(t),n},n.sortKeys=function(t){return a[i.length-1]=t,n},n.sortValues=function(t){return e=t,n},n.rollup=function(t){return r=t,n},n},t.set=function(t){var e=new L;if(t)for(var r=0,n=t.length;r=0&&(n=t.slice(r+1),t=t.slice(0,r)),t)return arguments.length<2?this[t].on(n):this[t].on(n,e);if(2===arguments.length){if(null==e)for(t in this)this.hasOwnProperty(t)&&this[t].on(n,null);return this}},t.event=null,t.requote=function(t){return t.replace(V,"\\$&")};var V=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,U={}.__proto__?function(t,e){t.__proto__=e}:function(t,e){for(var r in e)t[r]=e[r]};function q(t){return U(t,Y),t}var H=function(t,e){return e.querySelector(t)},G=function(t,e){return e.querySelectorAll(t)},W=function(t,e){var r=t.matches||t[I(t,"matchesSelector")];return(W=function(t,e){return r.call(t,e)})(t,e)};"function"==typeof Sizzle&&(H=function(t,e){return Sizzle(t,e)[0]||null},G=Sizzle,W=Sizzle.matchesSelector),t.selection=function(){return t.select(i.documentElement)};var Y=t.selection.prototype=[];function X(t){return"function"==typeof t?t:function(){return H(t,this)}}function Z(t){return"function"==typeof t?t:function(){return G(t,this)}}Y.select=function(t){var e,r,n,i,a=[];t=X(t);for(var o=-1,s=this.length;++o=0&&"xmlns"!==(r=t.slice(0,e))&&(t=t.slice(e+1)),J.hasOwnProperty(r)?{space:J[r],local:t}:t}},Y.attr=function(e,r){if(arguments.length<2){if("string"==typeof e){var n=this.node();return(e=t.ns.qualify(e)).local?n.getAttributeNS(e.space,e.local):n.getAttribute(e)}for(r in e)this.each(K(r,e[r]));return this}return this.each(K(e,r))},Y.classed=function(t,e){if(arguments.length<2){if("string"==typeof t){var r=this.node(),n=(t=et(t)).length,i=-1;if(e=r.classList){for(;++i=0;)(r=n[i])&&(a&&a!==r.nextSibling&&a.parentNode.insertBefore(r,a),a=r);return this},Y.sort=function(t){t=function(t){arguments.length||(t=f);return function(e,r){return e&&r?t(e.__data__,r.__data__):!e-!r}}.apply(this,arguments);for(var e=-1,r=this.length;++e0&&(e=e.slice(0,o));var l=dt.get(e);function c(){var t=this[a];t&&(this.removeEventListener(e,t,t.$),delete this[a])}return l&&(e=l,s=mt),o?r?function(){var t=s(r,n(arguments));c.call(this),this.addEventListener(e,this[a]=t,t.$=i),t._=r}:c:r?D:function(){var r,n=new RegExp("^__on([^.]+)"+t.requote(e)+"$");for(var i in this)if(r=i.match(n)){var a=this[i];this.removeEventListener(r[1],a,a.$),delete this[i]}}}t.selection.enter=ht,t.selection.enter.prototype=ft,ft.append=Y.append,ft.empty=Y.empty,ft.node=Y.node,ft.call=Y.call,ft.size=Y.size,ft.select=function(t){for(var e,r,n,i,a,o=[],s=-1,l=this.length;++s=n&&(n=e+1);!(o=s[n])&&++n0?1:t<0?-1:0}function Pt(t,e,r){return(e[0]-t[0])*(r[1]-t[1])-(e[1]-t[1])*(r[0]-t[0])}function It(t){return t>1?0:t<-1?At:Math.acos(t)}function Ot(t){return t>1?Et:t<-1?-Et:Math.asin(t)}function Dt(t){return((t=Math.exp(t))+1/t)/2}function Rt(t){return(t=Math.sin(t/2))*t}var Bt=Math.SQRT2;t.interpolateZoom=function(t,e){var r,n,i=t[0],a=t[1],o=t[2],s=e[0],l=e[1],c=e[2],u=s-i,h=l-a,f=u*u+h*h;if(f0&&(e=e.transition().duration(g)),e.call(w.event)}function S(){c&&c.domain(l.range().map(function(t){return(t-f.x)/f.k}).map(l.invert)),h&&h.domain(u.range().map(function(t){return(t-f.y)/f.k}).map(u.invert))}function E(t){m++||t({type:"zoomstart"})}function C(t){S(),t({type:"zoom",scale:f.k,translate:[f.x,f.y]})}function L(t){--m||(t({type:"zoomend"}),r=null)}function z(){var e=this,r=_.of(e,arguments),n=0,i=t.select(o(e)).on(y,function(){n=1,A(t.mouse(e),a),C(r)}).on(x,function(){i.on(y,null).on(x,null),s(n),L(r)}),a=k(t.mouse(e)),s=xt(e);hs.call(e),E(r)}function P(){var e,r=this,n=_.of(r,arguments),i={},a=0,o=".zoom-"+t.event.changedTouches[0].identifier,l="touchmove"+o,c="touchend"+o,u=[],h=t.select(r),p=xt(r);function d(){var n=t.touches(r);return e=f.k,n.forEach(function(t){t.identifier in i&&(i[t.identifier]=k(t))}),n}function g(){var e=t.event.target;t.select(e).on(l,m).on(c,y),u.push(e);for(var n=t.event.changedTouches,o=0,h=n.length;o1){v=p[0];var x=p[1],b=v[0]-x[0],_=v[1]-x[1];a=b*b+_*_}}function m(){var o,l,c,u,h=t.touches(r);hs.call(r);for(var f=0,p=h.length;f360?t-=360:t<0&&(t+=360),t<60?n+(i-n)*t/60:t<180?i:t<240?n+(i-n)*(240-t)/60:n}(t))}return t=isNaN(t)?0:(t%=360)<0?t+360:t,e=isNaN(e)?0:e<0?0:e>1?1:e,n=2*(r=r<0?0:r>1?1:r)-(i=r<=.5?r*(1+e):r+e-r*e),new ae(a(t+120),a(t),a(t-120))}function Gt(e,r,n){return this instanceof Gt?(this.h=+e,this.c=+r,void(this.l=+n)):arguments.length<2?e instanceof Gt?new Gt(e.h,e.c,e.l):ee(e instanceof Xt?e.l:(e=fe((e=t.rgb(e)).r,e.g,e.b)).l,e.a,e.b):new Gt(e,r,n)}qt.brighter=function(t){return t=Math.pow(.7,arguments.length?t:1),new Ut(this.h,this.s,this.l/t)},qt.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),new Ut(this.h,this.s,t*this.l)},qt.rgb=function(){return Ht(this.h,this.s,this.l)},t.hcl=Gt;var Wt=Gt.prototype=new Vt;function Yt(t,e,r){return isNaN(t)&&(t=0),isNaN(e)&&(e=0),new Xt(r,Math.cos(t*=Ct)*e,Math.sin(t)*e)}function Xt(t,e,r){return this instanceof Xt?(this.l=+t,this.a=+e,void(this.b=+r)):arguments.length<2?t instanceof Xt?new Xt(t.l,t.a,t.b):t instanceof Gt?Yt(t.h,t.c,t.l):fe((t=ae(t)).r,t.g,t.b):new Xt(t,e,r)}Wt.brighter=function(t){return new Gt(this.h,this.c,Math.min(100,this.l+Zt*(arguments.length?t:1)))},Wt.darker=function(t){return new Gt(this.h,this.c,Math.max(0,this.l-Zt*(arguments.length?t:1)))},Wt.rgb=function(){return Yt(this.h,this.c,this.l).rgb()},t.lab=Xt;var Zt=18,$t=.95047,Jt=1,Kt=1.08883,Qt=Xt.prototype=new Vt;function te(t,e,r){var n=(t+16)/116,i=n+e/500,a=n-r/200;return new ae(ie(3.2404542*(i=re(i)*$t)-1.5371385*(n=re(n)*Jt)-.4985314*(a=re(a)*Kt)),ie(-.969266*i+1.8760108*n+.041556*a),ie(.0556434*i-.2040259*n+1.0572252*a))}function ee(t,e,r){return t>0?new Gt(Math.atan2(r,e)*Lt,Math.sqrt(e*e+r*r),t):new Gt(NaN,NaN,t)}function re(t){return t>.206893034?t*t*t:(t-4/29)/7.787037}function ne(t){return t>.008856?Math.pow(t,1/3):7.787037*t+4/29}function ie(t){return Math.round(255*(t<=.00304?12.92*t:1.055*Math.pow(t,1/2.4)-.055))}function ae(t,e,r){return this instanceof ae?(this.r=~~t,this.g=~~e,void(this.b=~~r)):arguments.length<2?t instanceof ae?new ae(t.r,t.g,t.b):ue(""+t,ae,Ht):new ae(t,e,r)}function oe(t){return new ae(t>>16,t>>8&255,255&t)}function se(t){return oe(t)+""}Qt.brighter=function(t){return new Xt(Math.min(100,this.l+Zt*(arguments.length?t:1)),this.a,this.b)},Qt.darker=function(t){return new Xt(Math.max(0,this.l-Zt*(arguments.length?t:1)),this.a,this.b)},Qt.rgb=function(){return te(this.l,this.a,this.b)},t.rgb=ae;var le=ae.prototype=new Vt;function ce(t){return t<16?"0"+Math.max(0,t).toString(16):Math.min(255,t).toString(16)}function ue(t,e,r){var n,i,a,o=0,s=0,l=0;if(n=/([a-z]+)\((.*)\)/.exec(t=t.toLowerCase()))switch(i=n[2].split(","),n[1]){case"hsl":return r(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return e(de(i[0]),de(i[1]),de(i[2]))}return(a=ge.get(t))?e(a.r,a.g,a.b):(null==t||"#"!==t.charAt(0)||isNaN(a=parseInt(t.slice(1),16))||(4===t.length?(o=(3840&a)>>4,o|=o>>4,s=240&a,s|=s>>4,l=15&a,l|=l<<4):7===t.length&&(o=(16711680&a)>>16,s=(65280&a)>>8,l=255&a)),e(o,s,l))}function he(t,e,r){var n,i,a=Math.min(t/=255,e/=255,r/=255),o=Math.max(t,e,r),s=o-a,l=(o+a)/2;return s?(i=l<.5?s/(o+a):s/(2-o-a),n=t==o?(e-r)/s+(e0&&l<1?0:n),new Ut(n,i,l)}function fe(t,e,r){var n=ne((.4124564*(t=pe(t))+.3575761*(e=pe(e))+.1804375*(r=pe(r)))/$t),i=ne((.2126729*t+.7151522*e+.072175*r)/Jt);return Xt(116*i-16,500*(n-i),200*(i-ne((.0193339*t+.119192*e+.9503041*r)/Kt)))}function pe(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function de(t){var e=parseFloat(t);return"%"===t.charAt(t.length-1)?Math.round(2.55*e):e}le.brighter=function(t){t=Math.pow(.7,arguments.length?t:1);var e=this.r,r=this.g,n=this.b,i=30;return e||r||n?(e&&e=200&&e<300||304===e){try{t=i.call(o,c)}catch(t){return void s.error.call(o,t)}s.load.call(o,t)}else s.error.call(o,c)}return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(e)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=h:c.onreadystatechange=function(){c.readyState>3&&h()},c.onprogress=function(e){var r=t.event;t.event=e;try{s.progress.call(o,c)}finally{t.event=r}},o.header=function(t,e){return t=(t+"").toLowerCase(),arguments.length<2?l[t]:(null==e?delete l[t]:l[t]=e+"",o)},o.mimeType=function(t){return arguments.length?(r=null==t?null:t+"",o):r},o.responseType=function(t){return arguments.length?(u=t,o):u},o.response=function(t){return i=t,o},["get","post"].forEach(function(t){o[t]=function(){return o.send.apply(o,[t].concat(n(arguments)))}}),o.send=function(t,n,i){if(2===arguments.length&&"function"==typeof n&&(i=n,n=null),c.open(t,e,!0),null==r||"accept"in l||(l.accept=r+",*/*"),c.setRequestHeader)for(var a in l)c.setRequestHeader(a,l[a]);return null!=r&&c.overrideMimeType&&c.overrideMimeType(r),null!=u&&(c.responseType=u),null!=i&&o.on("error",i).on("load",function(t){i(null,t)}),s.beforesend.call(o,c),c.send(null==n?null:n),o},o.abort=function(){return c.abort(),o},t.rebind(o,s,"on"),null==a?o:o.get(function(t){return 1===t.length?function(e,r){t(null==e?r:null)}:t}(a))}ge.forEach(function(t,e){ge.set(t,oe(e))}),t.functor=me,t.xhr=ve(z),t.dsv=function(t,e){var r=new RegExp('["'+t+"\n]"),n=t.charCodeAt(0);function i(t,r,n){arguments.length<3&&(n=r,r=null);var i=ye(t,e,null==r?a:o(r),n);return i.row=function(t){return arguments.length?i.response(null==(r=t)?a:o(t)):r},i}function a(t){return i.parse(t.responseText)}function o(t){return function(e){return i.parse(e.responseText,t)}}function s(e){return e.map(l).join(t)}function l(t){return r.test(t)?'"'+t.replace(/\"/g,'""')+'"':t}return i.parse=function(t,e){var r;return i.parseRows(t,function(t,n){if(r)return r(t,n-1);var i=new Function("d","return {"+t.map(function(t,e){return JSON.stringify(t)+": d["+e+"]"}).join(",")+"}");r=e?function(t,r){return e(i(t),r)}:i})},i.parseRows=function(t,e){var r,i,a={},o={},s=[],l=t.length,c=0,u=0;function h(){if(c>=l)return o;if(i)return i=!1,a;var e=c;if(34===t.charCodeAt(e)){for(var r=e;r++24?(isFinite(e)&&(clearTimeout(we),we=setTimeout(Ae,e)),_e=0):(_e=1,ke(Ae))}function Te(){for(var t=Date.now(),e=xe;e;)t>=e.t&&e.c(t-e.t)&&(e.c=null),e=e.n;return t}function Se(){for(var t,e=xe,r=1/0;e;)e.c?(e.t8?function(t){return t/r}:function(t){return t*r},symbol:t}});t.formatPrefix=function(e,r){var n=0;return(e=+e)&&(e<0&&(e*=-1),r&&(e=t.round(e,Ee(e,r))),n=1+Math.floor(1e-12+Math.log(e)/Math.LN10),n=Math.max(-24,Math.min(24,3*Math.floor((n-1)/3)))),Ce[8+n/3]};var Le=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,ze=t.map({b:function(t){return t.toString(2)},c:function(t){return String.fromCharCode(t)},o:function(t){return t.toString(8)},x:function(t){return t.toString(16)},X:function(t){return t.toString(16).toUpperCase()},g:function(t,e){return t.toPrecision(e)},e:function(t,e){return t.toExponential(e)},f:function(t,e){return t.toFixed(e)},r:function(e,r){return(e=t.round(e,Ee(e,r))).toFixed(Math.max(0,Math.min(20,Ee(e*(1+1e-15),r))))}});function Pe(t){return t+""}var Ie=t.time={},Oe=Date;function De(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}De.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(){Re.setUTCDate.apply(this._,arguments)},setDay:function(){Re.setUTCDay.apply(this._,arguments)},setFullYear:function(){Re.setUTCFullYear.apply(this._,arguments)},setHours:function(){Re.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){Re.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){Re.setUTCMinutes.apply(this._,arguments)},setMonth:function(){Re.setUTCMonth.apply(this._,arguments)},setSeconds:function(){Re.setUTCSeconds.apply(this._,arguments)},setTime:function(){Re.setTime.apply(this._,arguments)}};var Re=Date.prototype;function Be(t,e,r){function n(e){var r=t(e),n=a(r,1);return e-r1)for(;o68?1900:2e3),r+i[0].length):-1}function $e(t,e,r){return/^[+-]\d{4}$/.test(e=e.slice(r,r+5))?(t.Z=-e,r+5):-1}function Je(t,e,r){je.lastIndex=0;var n=je.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function Ke(t,e,r){je.lastIndex=0;var n=je.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function Qe(t,e,r){je.lastIndex=0;var n=je.exec(e.slice(r,r+3));return n?(t.j=+n[0],r+n[0].length):-1}function tr(t,e,r){je.lastIndex=0;var n=je.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function er(t,e,r){je.lastIndex=0;var n=je.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function rr(t,e,r){je.lastIndex=0;var n=je.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function nr(t,e,r){je.lastIndex=0;var n=je.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function ir(t){var e=t.getTimezoneOffset(),r=e>0?"-":"+",n=y(e)/60|0,i=y(e)%60;return r+Ue(n,"0",2)+Ue(i,"0",2)}function ar(t,e,r){Ve.lastIndex=0;var n=Ve.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function or(t){for(var e=t.length,r=-1;++r0&&s>0&&(l+s+1>e&&(s=Math.max(1,e-l)),a.push(t.substring(r-=s,r+s)),!((l+=s+1)>e));)s=i[o=(o+1)%i.length];return a.reverse().join(n)}:z;return function(e){var n=Le.exec(e),i=n[1]||" ",s=n[2]||">",l=n[3]||"-",c=n[4]||"",u=n[5],h=+n[6],f=n[7],p=n[8],d=n[9],g=1,m="",v="",y=!1,x=!0;switch(p&&(p=+p.substring(1)),(u||"0"===i&&"="===s)&&(u=i="0",s="="),d){case"n":f=!0,d="g";break;case"%":g=100,v="%",d="f";break;case"p":g=100,v="%",d="r";break;case"b":case"o":case"x":case"X":"#"===c&&(m="0"+d.toLowerCase());case"c":x=!1;case"d":y=!0,p=0;break;case"s":g=-1,d="r"}"$"===c&&(m=a[0],v=a[1]),"r"!=d||p||(d="g"),null!=p&&("g"==d?p=Math.max(1,Math.min(21,p)):"e"!=d&&"f"!=d||(p=Math.max(0,Math.min(20,p)))),d=ze.get(d)||Pe;var b=u&&f;return function(e){var n=v;if(y&&e%1)return"";var a=e<0||0===e&&1/e<0?(e=-e,"-"):"-"===l?"":l;if(g<0){var c=t.formatPrefix(e,p);e=c.scale(e),n=c.symbol+v}else e*=g;var _,w,k=(e=d(e,p)).lastIndexOf(".");if(k<0){var M=x?e.lastIndexOf("e"):-1;M<0?(_=e,w=""):(_=e.substring(0,M),w=e.substring(M))}else _=e.substring(0,k),w=r+e.substring(k+1);!u&&f&&(_=o(_,1/0));var A=m.length+_.length+w.length+(b?0:a.length),T=A"===s?T+a+e:"^"===s?T.substring(0,A>>=1)+a+e+T.substring(A):a+(b?e:T+e))+n}}}(e),timeFormat:function(e){var r=e.dateTime,n=e.date,i=e.time,a=e.periods,o=e.days,s=e.shortDays,l=e.months,c=e.shortMonths;function u(t){var e=t.length;function r(r){for(var n,i,a,o=[],s=-1,l=0;++s=c)return-1;if(37===(i=e.charCodeAt(s++))){if(o=e.charAt(s++),!(a=w[o in Ne?e.charAt(s++):o])||(n=a(t,r,n))<0)return-1}else if(i!=r.charCodeAt(n++))return-1}return n}u.utc=function(t){var e=u(t);function r(t){try{var r=new(Oe=De);return r._=t,e(r)}finally{Oe=Date}}return r.parse=function(t){try{Oe=De;var r=e.parse(t);return r&&r._}finally{Oe=Date}},r.toString=e.toString,r},u.multi=u.utc.multi=or;var f=t.map(),p=qe(o),d=He(o),g=qe(s),m=He(s),v=qe(l),y=He(l),x=qe(c),b=He(c);a.forEach(function(t,e){f.set(t.toLowerCase(),e)});var _={a:function(t){return s[t.getDay()]},A:function(t){return o[t.getDay()]},b:function(t){return c[t.getMonth()]},B:function(t){return l[t.getMonth()]},c:u(r),d:function(t,e){return Ue(t.getDate(),e,2)},e:function(t,e){return Ue(t.getDate(),e,2)},H:function(t,e){return Ue(t.getHours(),e,2)},I:function(t,e){return Ue(t.getHours()%12||12,e,2)},j:function(t,e){return Ue(1+Ie.dayOfYear(t),e,3)},L:function(t,e){return Ue(t.getMilliseconds(),e,3)},m:function(t,e){return Ue(t.getMonth()+1,e,2)},M:function(t,e){return Ue(t.getMinutes(),e,2)},p:function(t){return a[+(t.getHours()>=12)]},S:function(t,e){return Ue(t.getSeconds(),e,2)},U:function(t,e){return Ue(Ie.sundayOfYear(t),e,2)},w:function(t){return t.getDay()},W:function(t,e){return Ue(Ie.mondayOfYear(t),e,2)},x:u(n),X:u(i),y:function(t,e){return Ue(t.getFullYear()%100,e,2)},Y:function(t,e){return Ue(t.getFullYear()%1e4,e,4)},Z:ir,"%":function(){return"%"}},w={a:function(t,e,r){g.lastIndex=0;var n=g.exec(e.slice(r));return n?(t.w=m.get(n[0].toLowerCase()),r+n[0].length):-1},A:function(t,e,r){p.lastIndex=0;var n=p.exec(e.slice(r));return n?(t.w=d.get(n[0].toLowerCase()),r+n[0].length):-1},b:function(t,e,r){x.lastIndex=0;var n=x.exec(e.slice(r));return n?(t.m=b.get(n[0].toLowerCase()),r+n[0].length):-1},B:function(t,e,r){v.lastIndex=0;var n=v.exec(e.slice(r));return n?(t.m=y.get(n[0].toLowerCase()),r+n[0].length):-1},c:function(t,e,r){return h(t,_.c.toString(),e,r)},d:Ke,e:Ke,H:tr,I:tr,j:Qe,L:nr,m:Je,M:er,p:function(t,e,r){var n=f.get(e.slice(r,r+=2).toLowerCase());return null==n?-1:(t.p=n,r)},S:rr,U:We,w:Ge,W:Ye,x:function(t,e,r){return h(t,_.x.toString(),e,r)},X:function(t,e,r){return h(t,_.X.toString(),e,r)},y:Ze,Y:Xe,Z:$e,"%":ar};return u}(e)}};var sr=t.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"]});function lr(){}t.format=sr.numberFormat,t.geo={},lr.prototype={s:0,t:0,add:function(t){ur(t,this.t,cr),ur(cr.s,this.s,this),this.s?this.t+=cr.t:this.s=cr.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cr=new lr;function ur(t,e,r){var n=r.s=t+e,i=n-t,a=n-i;r.t=t-a+(e-i)}function hr(t,e){t&&pr.hasOwnProperty(t.type)&&pr[t.type](t,e)}t.geo.stream=function(t,e){t&&fr.hasOwnProperty(t.type)?fr[t.type](t,e):hr(t,e)};var fr={Feature:function(t,e){hr(t.geometry,e)},FeatureCollection:function(t,e){for(var r=t.features,n=-1,i=r.length;++n=0?1:-1,s=o*a,l=Math.cos(e),c=Math.sin(e),u=i*c,h=n*l+u*Math.cos(s),f=u*o*Math.sin(s);Er.add(Math.atan2(f,h)),r=t,n=l,i=c}Cr.point=function(o,s){Cr.point=a,r=(t=o)*Ct,n=Math.cos(s=(e=s)*Ct/2+At/4),i=Math.sin(s)},Cr.lineEnd=function(){a(t,e)}}function zr(t){var e=t[0],r=t[1],n=Math.cos(r);return[n*Math.cos(e),n*Math.sin(e),Math.sin(r)]}function Pr(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function Ir(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function Or(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function Dr(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function Rr(t){var e=Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}function Br(t){return[Math.atan2(t[1],t[0]),Ot(t[2])]}function Fr(t,e){return y(t[0]-e[0])kt?i=90:c<-kt&&(r=-90),h[0]=e,h[1]=n}};function p(t,a){u.push(h=[e=t,n=t]),ai&&(i=a)}function d(t,o){var s=zr([t*Ct,o*Ct]);if(l){var c=Ir(l,s),u=Ir([c[1],-c[0],0],c);Rr(u),u=Br(u);var h=t-a,f=h>0?1:-1,d=u[0]*Lt*f,g=y(h)>180;if(g^(f*ai&&(i=m);else if(g^(f*a<(d=(d+360)%360-180)&&di&&(i=o);g?t_(e,n)&&(n=t):_(t,n)>_(e,n)&&(e=t):n>=e?(tn&&(n=t)):t>a?_(e,t)>_(e,n)&&(n=t):_(t,n)>_(e,n)&&(e=t)}else p(t,o);l=s,a=t}function g(){f.point=d}function m(){h[0]=e,h[1]=n,f.point=p,l=null}function v(t,e){if(l){var r=t-a;c+=y(r)>180?r+(r>0?360:-360):r}else o=t,s=e;Cr.point(t,e),d(t,e)}function x(){Cr.lineStart()}function b(){v(o,s),Cr.lineEnd(),y(c)>kt&&(e=-(n=180)),h[0]=e,h[1]=n,l=null}function _(t,e){return(e-=t)<0?e+360:e}function w(t,e){return t[0]-e[0]}function k(t,e){return e[0]<=e[1]?e[0]<=t&&t<=e[1]:t_(g[0],g[1])&&(g[1]=p[1]),_(p[0],g[1])>_(g[0],g[1])&&(g[0]=p[0])):s.push(g=p);for(var l,c,p,d=-1/0,g=(o=0,s[c=s.length-1]);o<=c;g=p,++o)p=s[o],(l=_(g[1],p[0]))>d&&(d=l,e=p[0],n=g[1])}return u=h=null,e===1/0||r===1/0?[[NaN,NaN],[NaN,NaN]]:[[e,r],[n,i]]}}(),t.geo.centroid=function(e){vr=yr=xr=br=_r=wr=kr=Mr=Ar=Tr=Sr=0,t.geo.stream(e,Nr);var r=Ar,n=Tr,i=Sr,a=r*r+n*n+i*i;return a=0;--s)i.point((h=u[s])[0],h[1]);else n(p.x,p.p.x,-1,i);p=p.p}u=(p=p.o).z,d=!d}while(!p.v);i.lineEnd()}}}function Xr(t){if(e=t.length){for(var e,r,n=0,i=t[0];++n=0?1:-1,k=w*_,M=k>At,A=d*x;if(Er.add(Math.atan2(A*w*Math.sin(k),g*b+A*Math.cos(k))),a+=M?_+w*Tt:_,M^f>=r^v>=r){var T=Ir(zr(h),zr(t));Rr(T);var S=Ir(i,T);Rr(S);var E=(M^_>=0?-1:1)*Ot(S[2]);(n>E||n===E&&(T[0]||T[1]))&&(o+=M^_>=0?1:-1)}if(!m++)break;f=v,d=x,g=b,h=t}}return(a<-kt||a0){for(x||(o.polygonStart(),x=!0),o.lineStart();++a1&&2&e&&r.push(r.pop().concat(r.shift())),s.push(r.filter(Jr))}return u}}function Jr(t){return t.length>1}function Kr(){var t,e=[];return{lineStart:function(){e.push(t=[])},point:function(e,r){t.push([e,r])},lineEnd:D,buffer:function(){var r=e;return e=[],t=null,r},rejoin:function(){e.length>1&&e.push(e.pop().concat(e.shift()))}}}function Qr(t,e){return((t=t.x)[0]<0?t[1]-Et-kt:Et-t[1])-((e=e.x)[0]<0?e[1]-Et-kt:Et-e[1])}var tn=$r(Wr,function(t){var e,r=NaN,n=NaN,i=NaN;return{lineStart:function(){t.lineStart(),e=1},point:function(a,o){var s=a>0?At:-At,l=y(a-r);y(l-At)0?Et:-Et),t.point(i,n),t.lineEnd(),t.lineStart(),t.point(s,n),t.point(a,n),e=0):i!==s&&l>=At&&(y(r-i)kt?Math.atan((Math.sin(e)*(a=Math.cos(n))*Math.sin(r)-Math.sin(n)*(i=Math.cos(e))*Math.sin(t))/(i*a*o)):(e+n)/2}(r,n,a,o),t.point(i,n),t.lineEnd(),t.lineStart(),t.point(s,n),e=0),t.point(r=a,n=o),i=s},lineEnd:function(){t.lineEnd(),r=n=NaN},clean:function(){return 2-e}}},function(t,e,r,n){var i;if(null==t)i=r*Et,n.point(-At,i),n.point(0,i),n.point(At,i),n.point(At,0),n.point(At,-i),n.point(0,-i),n.point(-At,-i),n.point(-At,0),n.point(-At,i);else if(y(t[0]-e[0])>kt){var a=t[0]0)){if(a/=f,f<0){if(a0){if(a>h)return;a>u&&(u=a)}if(a=r-l,f||!(a<0)){if(a/=f,f<0){if(a>h)return;a>u&&(u=a)}else if(f>0){if(a0)){if(a/=p,p<0){if(a0){if(a>h)return;a>u&&(u=a)}if(a=n-c,p||!(a<0)){if(a/=p,p<0){if(a>h)return;a>u&&(u=a)}else if(p>0){if(a0&&(i.a={x:l+u*f,y:c+u*p}),h<1&&(i.b={x:l+h*f,y:c+h*p}),i}}}}}}var rn=1e9;function nn(e,r,n,i){return function(l){var c,u,h,f,p,d,g,m,v,y,x,b=l,_=Kr(),w=en(e,r,n,i),k={point:T,lineStart:function(){k.point=S,u&&u.push(h=[]);y=!0,v=!1,g=m=NaN},lineEnd:function(){c&&(S(f,p),d&&v&&_.rejoin(),c.push(_.buffer()));k.point=T,v&&l.lineEnd()},polygonStart:function(){l=_,c=[],u=[],x=!0},polygonEnd:function(){l=b,c=t.merge(c);var r=function(t){for(var e=0,r=u.length,n=t[1],i=0;in&&Pt(c,a,t)>0&&++e:a[1]<=n&&Pt(c,a,t)<0&&--e,c=a;return 0!==e}([e,i]),n=x&&r,a=c.length;(n||a)&&(l.polygonStart(),n&&(l.lineStart(),M(null,null,1,l),l.lineEnd()),a&&Yr(c,o,r,M,l),l.polygonEnd()),c=u=h=null}};function M(t,o,l,c){var u=0,h=0;if(null==t||(u=a(t,l))!==(h=a(o,l))||s(t,o)<0^l>0)do{c.point(0===u||3===u?e:n,u>1?i:r)}while((u=(u+l+4)%4)!==h);else c.point(o[0],o[1])}function A(t,a){return e<=t&&t<=n&&r<=a&&a<=i}function T(t,e){A(t,e)&&l.point(t,e)}function S(t,e){var r=A(t=Math.max(-rn,Math.min(rn,t)),e=Math.max(-rn,Math.min(rn,e)));if(u&&h.push([t,e]),y)f=t,p=e,d=r,y=!1,r&&(l.lineStart(),l.point(t,e));else if(r&&v)l.point(t,e);else{var n={a:{x:g,y:m},b:{x:t,y:e}};w(n)?(v||(l.lineStart(),l.point(n.a.x,n.a.y)),l.point(n.b.x,n.b.y),r||l.lineEnd(),x=!1):r&&(l.lineStart(),l.point(t,e),x=!1)}g=t,m=e,v=r}return k};function a(t,i){return y(t[0]-e)0?0:3:y(t[0]-n)0?2:1:y(t[1]-r)0?1:0:i>0?3:2}function o(t,e){return s(t.x,e.x)}function s(t,e){var r=a(t,1),n=a(e,1);return r!==n?r-n:0===r?e[1]-t[1]:1===r?t[0]-e[0]:2===r?t[1]-e[1]:e[0]-t[0]}}function an(t){var e=0,r=At/3,n=Cn(t),i=n(e,r);return i.parallels=function(t){return arguments.length?n(e=t[0]*At/180,r=t[1]*At/180):[e/At*180,r/At*180]},i}function on(t,e){var r=Math.sin(t),n=(r+Math.sin(e))/2,i=1+r*(2*n-r),a=Math.sqrt(i)/n;function o(t,e){var r=Math.sqrt(i-2*n*Math.sin(e))/n;return[r*Math.sin(t*=n),a-r*Math.cos(t)]}return o.invert=function(t,e){var r=a-e;return[Math.atan2(t,r)/n,Ot((i-(t*t+r*r)*n*n)/(2*n))]},o}t.geo.clipExtent=function(){var t,e,r,n,i,a,o={stream:function(t){return i&&(i.valid=!1),(i=a(t)).valid=!0,i},extent:function(s){return arguments.length?(a=nn(t=+s[0][0],e=+s[0][1],r=+s[1][0],n=+s[1][1]),i&&(i.valid=!1,i=null),o):[[t,e],[r,n]]}};return o.extent([[0,0],[960,500]])},(t.geo.conicEqualArea=function(){return an(on)}).raw=on,t.geo.albers=function(){return t.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},t.geo.albersUsa=function(){var e,r,n,i,a=t.geo.albers(),o=t.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),s=t.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(t,r){e=[t,r]}};function c(t){var a=t[0],o=t[1];return e=null,r(a,o),e||(n(a,o),e)||i(a,o),e}return c.invert=function(t){var e=a.scale(),r=a.translate(),n=(t[0]-r[0])/e,i=(t[1]-r[1])/e;return(i>=.12&&i<.234&&n>=-.425&&n<-.214?o:i>=.166&&i<.234&&n>=-.214&&n<-.115?s:a).invert(t)},c.stream=function(t){var e=a.stream(t),r=o.stream(t),n=s.stream(t);return{point:function(t,i){e.point(t,i),r.point(t,i),n.point(t,i)},sphere:function(){e.sphere(),r.sphere(),n.sphere()},lineStart:function(){e.lineStart(),r.lineStart(),n.lineStart()},lineEnd:function(){e.lineEnd(),r.lineEnd(),n.lineEnd()},polygonStart:function(){e.polygonStart(),r.polygonStart(),n.polygonStart()},polygonEnd:function(){e.polygonEnd(),r.polygonEnd(),n.polygonEnd()}}},c.precision=function(t){return arguments.length?(a.precision(t),o.precision(t),s.precision(t),c):a.precision()},c.scale=function(t){return arguments.length?(a.scale(t),o.scale(.35*t),s.scale(t),c.translate(a.translate())):a.scale()},c.translate=function(t){if(!arguments.length)return a.translate();var e=a.scale(),u=+t[0],h=+t[1];return r=a.translate(t).clipExtent([[u-.455*e,h-.238*e],[u+.455*e,h+.238*e]]).stream(l).point,n=o.translate([u-.307*e,h+.201*e]).clipExtent([[u-.425*e+kt,h+.12*e+kt],[u-.214*e-kt,h+.234*e-kt]]).stream(l).point,i=s.translate([u-.205*e,h+.212*e]).clipExtent([[u-.214*e+kt,h+.166*e+kt],[u-.115*e-kt,h+.234*e-kt]]).stream(l).point,c},c.scale(1070)};var sn,ln,cn,un,hn,fn,pn={point:D,lineStart:D,lineEnd:D,polygonStart:function(){ln=0,pn.lineStart=dn},polygonEnd:function(){pn.lineStart=pn.lineEnd=pn.point=D,sn+=y(ln/2)}};function dn(){var t,e,r,n;function i(t,e){ln+=n*t-r*e,r=t,n=e}pn.point=function(a,o){pn.point=i,t=r=a,e=n=o},pn.lineEnd=function(){i(t,e)}}var gn={point:function(t,e){thn&&(hn=t);efn&&(fn=e)},lineStart:D,lineEnd:D,polygonStart:D,polygonEnd:D};function mn(){var t=vn(4.5),e=[],r={point:n,lineStart:function(){r.point=i},lineEnd:o,polygonStart:function(){r.lineEnd=s},polygonEnd:function(){r.lineEnd=o,r.point=n},pointRadius:function(e){return t=vn(e),r},result:function(){if(e.length){var t=e.join("");return e=[],t}}};function n(r,n){e.push("M",r,",",n,t)}function i(t,n){e.push("M",t,",",n),r.point=a}function a(t,r){e.push("L",t,",",r)}function o(){r.point=n}function s(){e.push("Z")}return r}function vn(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}var yn,xn={point:bn,lineStart:_n,lineEnd:wn,polygonStart:function(){xn.lineStart=kn},polygonEnd:function(){xn.point=bn,xn.lineStart=_n,xn.lineEnd=wn}};function bn(t,e){xr+=t,br+=e,++_r}function _n(){var t,e;function r(r,n){var i=r-t,a=n-e,o=Math.sqrt(i*i+a*a);wr+=o*(t+r)/2,kr+=o*(e+n)/2,Mr+=o,bn(t=r,e=n)}xn.point=function(n,i){xn.point=r,bn(t=n,e=i)}}function wn(){xn.point=bn}function kn(){var t,e,r,n;function i(t,e){var i=t-r,a=e-n,o=Math.sqrt(i*i+a*a);wr+=o*(r+t)/2,kr+=o*(n+e)/2,Mr+=o,Ar+=(o=n*t-r*e)*(r+t),Tr+=o*(n+e),Sr+=3*o,bn(r=t,n=e)}xn.point=function(a,o){xn.point=i,bn(t=r=a,e=n=o)},xn.lineEnd=function(){i(t,e)}}function Mn(t){var e=4.5,r={point:n,lineStart:function(){r.point=i},lineEnd:o,polygonStart:function(){r.lineEnd=s},polygonEnd:function(){r.lineEnd=o,r.point=n},pointRadius:function(t){return e=t,r},result:D};function n(r,n){t.moveTo(r+e,n),t.arc(r,n,e,0,Tt)}function i(e,n){t.moveTo(e,n),r.point=a}function a(e,r){t.lineTo(e,r)}function o(){r.point=n}function s(){t.closePath()}return r}function An(t){var e=.5,r=Math.cos(30*Ct),n=16;function i(e){return(n?function(e){var r,i,o,s,l,c,u,h,f,p,d,g,m={point:v,lineStart:y,lineEnd:b,polygonStart:function(){e.polygonStart(),m.lineStart=_},polygonEnd:function(){e.polygonEnd(),m.lineStart=y}};function v(r,n){r=t(r,n),e.point(r[0],r[1])}function y(){h=NaN,m.point=x,e.lineStart()}function x(r,i){var o=zr([r,i]),s=t(r,i);a(h,f,u,p,d,g,h=s[0],f=s[1],u=r,p=o[0],d=o[1],g=o[2],n,e),e.point(h,f)}function b(){m.point=v,e.lineEnd()}function _(){y(),m.point=w,m.lineEnd=k}function w(t,e){x(r=t,e),i=h,o=f,s=p,l=d,c=g,m.point=x}function k(){a(h,f,u,p,d,g,i,o,r,s,l,c,n,e),m.lineEnd=b,b()}return m}:function(e){return Sn(e,function(r,n){r=t(r,n),e.point(r[0],r[1])})})(e)}function a(n,i,o,s,l,c,u,h,f,p,d,g,m,v){var x=u-n,b=h-i,_=x*x+b*b;if(_>4*e&&m--){var w=s+p,k=l+d,M=c+g,A=Math.sqrt(w*w+k*k+M*M),T=Math.asin(M/=A),S=y(y(M)-1)e||y((x*z+b*P)/_-.5)>.3||s*p+l*d+c*g0&&16,i):Math.sqrt(e)},i}function Tn(t){this.stream=t}function Sn(t,e){return{point:e,sphere:function(){t.sphere()},lineStart:function(){t.lineStart()},lineEnd:function(){t.lineEnd()},polygonStart:function(){t.polygonStart()},polygonEnd:function(){t.polygonEnd()}}}function En(t){return Cn(function(){return t})()}function Cn(e){var r,n,i,a,o,s,l=An(function(t,e){return[(t=r(t,e))[0]*c+a,o-t[1]*c]}),c=150,u=480,h=250,f=0,p=0,d=0,g=0,m=0,v=tn,x=z,b=null,_=null;function w(t){return[(t=i(t[0]*Ct,t[1]*Ct))[0]*c+a,o-t[1]*c]}function k(t){return(t=i.invert((t[0]-a)/c,(o-t[1])/c))&&[t[0]*Lt,t[1]*Lt]}function M(){i=Gr(n=In(d,g,m),r);var t=r(f,p);return a=u-t[0]*c,o=h+t[1]*c,A()}function A(){return s&&(s.valid=!1,s=null),w}return w.stream=function(t){return s&&(s.valid=!1),(s=Ln(v(n,l(x(t))))).valid=!0,s},w.clipAngle=function(t){return arguments.length?(v=null==t?(b=t,tn):function(t){var e=Math.cos(t),r=e>0,n=y(e)>kt;return $r(i,function(t){var e,s,l,c,u;return{lineStart:function(){c=l=!1,u=1},point:function(h,f){var p,d=[h,f],g=i(h,f),m=r?g?0:o(h,f):g?o(h+(h<0?At:-At),f):0;if(!e&&(c=l=g)&&t.lineStart(),g!==l&&(p=a(e,d),(Fr(e,p)||Fr(d,p))&&(d[0]+=kt,d[1]+=kt,g=i(d[0],d[1]))),g!==l)u=0,g?(t.lineStart(),p=a(d,e),t.point(p[0],p[1])):(p=a(e,d),t.point(p[0],p[1]),t.lineEnd()),e=p;else if(n&&e&&r^g){var v;m&s||!(v=a(d,e,!0))||(u=0,r?(t.lineStart(),t.point(v[0][0],v[0][1]),t.point(v[1][0],v[1][1]),t.lineEnd()):(t.point(v[1][0],v[1][1]),t.lineEnd(),t.lineStart(),t.point(v[0][0],v[0][1])))}!g||e&&Fr(e,d)||t.point(d[0],d[1]),e=d,l=g,s=m},lineEnd:function(){l&&t.lineEnd(),e=null},clean:function(){return u|(c&&l)<<1}}},Bn(t,6*Ct),r?[0,-t]:[-At,t-At]);function i(t,r){return Math.cos(t)*Math.cos(r)>e}function a(t,r,n){var i=[1,0,0],a=Ir(zr(t),zr(r)),o=Pr(a,a),s=a[0],l=o-s*s;if(!l)return!n&&t;var c=e*o/l,u=-e*s/l,h=Ir(i,a),f=Dr(i,c);Or(f,Dr(a,u));var p=h,d=Pr(f,p),g=Pr(p,p),m=d*d-g*(Pr(f,f)-1);if(!(m<0)){var v=Math.sqrt(m),x=Dr(p,(-d-v)/g);if(Or(x,f),x=Br(x),!n)return x;var b,_=t[0],w=r[0],k=t[1],M=r[1];w<_&&(b=_,_=w,w=b);var A=w-_,T=y(A-At)0^x[1]<(y(x[0]-_)At^(_<=x[0]&&x[0]<=w)){var S=Dr(p,(-d+v)/g);return Or(S,f),[x,Br(S)]}}}function o(e,n){var i=r?t:At-t,a=0;return e<-i?a|=1:e>i&&(a|=2),n<-i?a|=4:n>i&&(a|=8),a}}((b=+t)*Ct),A()):b},w.clipExtent=function(t){return arguments.length?(_=t,x=t?nn(t[0][0],t[0][1],t[1][0],t[1][1]):z,A()):_},w.scale=function(t){return arguments.length?(c=+t,M()):c},w.translate=function(t){return arguments.length?(u=+t[0],h=+t[1],M()):[u,h]},w.center=function(t){return arguments.length?(f=t[0]%360*Ct,p=t[1]%360*Ct,M()):[f*Lt,p*Lt]},w.rotate=function(t){return arguments.length?(d=t[0]%360*Ct,g=t[1]%360*Ct,m=t.length>2?t[2]%360*Ct:0,M()):[d*Lt,g*Lt,m*Lt]},t.rebind(w,l,"precision"),function(){return r=e.apply(this,arguments),w.invert=r.invert&&k,M()}}function Ln(t){return Sn(t,function(e,r){t.point(e*Ct,r*Ct)})}function zn(t,e){return[t,e]}function Pn(t,e){return[t>At?t-Tt:t<-At?t+Tt:t,e]}function In(t,e,r){return t?e||r?Gr(Dn(t),Rn(e,r)):Dn(t):e||r?Rn(e,r):Pn}function On(t){return function(e,r){return[(e+=t)>At?e-Tt:e<-At?e+Tt:e,r]}}function Dn(t){var e=On(t);return e.invert=On(-t),e}function Rn(t,e){var r=Math.cos(t),n=Math.sin(t),i=Math.cos(e),a=Math.sin(e);function o(t,e){var o=Math.cos(e),s=Math.cos(t)*o,l=Math.sin(t)*o,c=Math.sin(e),u=c*r+s*n;return[Math.atan2(l*i-u*a,s*r-c*n),Ot(u*i+l*a)]}return o.invert=function(t,e){var o=Math.cos(e),s=Math.cos(t)*o,l=Math.sin(t)*o,c=Math.sin(e),u=c*i-l*a;return[Math.atan2(l*i+c*a,s*r+u*n),Ot(u*r-s*n)]},o}function Bn(t,e){var r=Math.cos(t),n=Math.sin(t);return function(i,a,o,s){var l=o*e;null!=i?(i=Fn(r,i),a=Fn(r,a),(o>0?ia)&&(i+=o*Tt)):(i=t+o*Tt,a=t-.5*l);for(var c,u=i;o>0?u>a:u2?t[2]*Ct:0),e.invert=function(e){return(e=t.invert(e[0]*Ct,e[1]*Ct))[0]*=Lt,e[1]*=Lt,e},e},Pn.invert=zn,t.geo.circle=function(){var t,e,r=[0,0],n=6;function i(){var t="function"==typeof r?r.apply(this,arguments):r,n=In(-t[0]*Ct,-t[1]*Ct,0).invert,i=[];return e(null,null,1,{point:function(t,e){i.push(t=n(t,e)),t[0]*=Lt,t[1]*=Lt}}),{type:"Polygon",coordinates:[i]}}return i.origin=function(t){return arguments.length?(r=t,i):r},i.angle=function(r){return arguments.length?(e=Bn((t=+r)*Ct,n*Ct),i):t},i.precision=function(r){return arguments.length?(e=Bn(t*Ct,(n=+r)*Ct),i):n},i.angle(90)},t.geo.distance=function(t,e){var r,n=(e[0]-t[0])*Ct,i=t[1]*Ct,a=e[1]*Ct,o=Math.sin(n),s=Math.cos(n),l=Math.sin(i),c=Math.cos(i),u=Math.sin(a),h=Math.cos(a);return Math.atan2(Math.sqrt((r=h*o)*r+(r=c*u-l*h*s)*r),l*u+c*h*s)},t.geo.graticule=function(){var e,r,n,i,a,o,s,l,c,u,h,f,p=10,d=p,g=90,m=360,v=2.5;function x(){return{type:"MultiLineString",coordinates:b()}}function b(){return t.range(Math.ceil(i/g)*g,n,g).map(h).concat(t.range(Math.ceil(l/m)*m,s,m).map(f)).concat(t.range(Math.ceil(r/p)*p,e,p).filter(function(t){return y(t%g)>kt}).map(c)).concat(t.range(Math.ceil(o/d)*d,a,d).filter(function(t){return y(t%m)>kt}).map(u))}return x.lines=function(){return b().map(function(t){return{type:"LineString",coordinates:t}})},x.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(f(s).slice(1),h(n).reverse().slice(1),f(l).reverse().slice(1))]}},x.extent=function(t){return arguments.length?x.majorExtent(t).minorExtent(t):x.minorExtent()},x.majorExtent=function(t){return arguments.length?(i=+t[0][0],n=+t[1][0],l=+t[0][1],s=+t[1][1],i>n&&(t=i,i=n,n=t),l>s&&(t=l,l=s,s=t),x.precision(v)):[[i,l],[n,s]]},x.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],o=+t[0][1],a=+t[1][1],r>e&&(t=r,r=e,e=t),o>a&&(t=o,o=a,a=t),x.precision(v)):[[r,o],[e,a]]},x.step=function(t){return arguments.length?x.majorStep(t).minorStep(t):x.minorStep()},x.majorStep=function(t){return arguments.length?(g=+t[0],m=+t[1],x):[g,m]},x.minorStep=function(t){return arguments.length?(p=+t[0],d=+t[1],x):[p,d]},x.precision=function(t){return arguments.length?(v=+t,c=Nn(o,a,90),u=jn(r,e,v),h=Nn(l,s,90),f=jn(i,n,v),x):v},x.majorExtent([[-180,-90+kt],[180,90-kt]]).minorExtent([[-180,-80-kt],[180,80+kt]])},t.geo.greatArc=function(){var e,r,n=Vn,i=Un;function a(){return{type:"LineString",coordinates:[e||n.apply(this,arguments),r||i.apply(this,arguments)]}}return a.distance=function(){return t.geo.distance(e||n.apply(this,arguments),r||i.apply(this,arguments))},a.source=function(t){return arguments.length?(n=t,e="function"==typeof t?null:t,a):n},a.target=function(t){return arguments.length?(i=t,r="function"==typeof t?null:t,a):i},a.precision=function(){return arguments.length?a:0},a},t.geo.interpolate=function(t,e){return r=t[0]*Ct,n=t[1]*Ct,i=e[0]*Ct,a=e[1]*Ct,o=Math.cos(n),s=Math.sin(n),l=Math.cos(a),c=Math.sin(a),u=o*Math.cos(r),h=o*Math.sin(r),f=l*Math.cos(i),p=l*Math.sin(i),d=2*Math.asin(Math.sqrt(Rt(a-n)+o*l*Rt(i-r))),g=1/Math.sin(d),(m=d?function(t){var e=Math.sin(t*=d)*g,r=Math.sin(d-t)*g,n=r*u+e*f,i=r*h+e*p,a=r*s+e*c;return[Math.atan2(i,n)*Lt,Math.atan2(a,Math.sqrt(n*n+i*i))*Lt]}:function(){return[r*Lt,n*Lt]}).distance=d,m;var r,n,i,a,o,s,l,c,u,h,f,p,d,g,m},t.geo.length=function(e){return yn=0,t.geo.stream(e,qn),yn};var qn={sphere:D,point:D,lineStart:function(){var t,e,r;function n(n,i){var a=Math.sin(i*=Ct),o=Math.cos(i),s=y((n*=Ct)-t),l=Math.cos(s);yn+=Math.atan2(Math.sqrt((s=o*Math.sin(s))*s+(s=r*a-e*o*l)*s),e*a+r*o*l),t=n,e=a,r=o}qn.point=function(i,a){t=i*Ct,e=Math.sin(a*=Ct),r=Math.cos(a),qn.point=n},qn.lineEnd=function(){qn.point=qn.lineEnd=D}},lineEnd:D,polygonStart:D,polygonEnd:D};function Hn(t,e){function r(e,r){var n=Math.cos(e),i=Math.cos(r),a=t(n*i);return[a*i*Math.sin(e),a*Math.sin(r)]}return r.invert=function(t,r){var n=Math.sqrt(t*t+r*r),i=e(n),a=Math.sin(i),o=Math.cos(i);return[Math.atan2(t*a,n*o),Math.asin(n&&r*a/n)]},r}var Gn=Hn(function(t){return Math.sqrt(2/(1+t))},function(t){return 2*Math.asin(t/2)});(t.geo.azimuthalEqualArea=function(){return En(Gn)}).raw=Gn;var Wn=Hn(function(t){var e=Math.acos(t);return e&&e/Math.sin(e)},z);function Yn(t,e){var r=Math.cos(t),n=function(t){return Math.tan(At/4+t/2)},i=t===e?Math.sin(t):Math.log(r/Math.cos(e))/Math.log(n(e)/n(t)),a=r*Math.pow(n(t),i)/i;if(!i)return $n;function o(t,e){a>0?e<-Et+kt&&(e=-Et+kt):e>Et-kt&&(e=Et-kt);var r=a/Math.pow(n(e),i);return[r*Math.sin(i*t),a-r*Math.cos(i*t)]}return o.invert=function(t,e){var r=a-e,n=zt(i)*Math.sqrt(t*t+r*r);return[Math.atan2(t,r)/i,2*Math.atan(Math.pow(a/n,1/i))-Et]},o}function Xn(t,e){var r=Math.cos(t),n=t===e?Math.sin(t):(r-Math.cos(e))/(e-t),i=r/n+t;if(y(n)1&&Pt(t[r[n-2]],t[r[n-1]],t[i])<=0;)--n;r[n++]=i}return r.slice(0,n)}function ii(t,e){return t[0]-e[0]||t[1]-e[1]}(t.geo.stereographic=function(){return En(Qn)}).raw=Qn,ti.invert=function(t,e){return[-e,2*Math.atan(Math.exp(t))-Et]},(t.geo.transverseMercator=function(){var t=Jn(ti),e=t.center,r=t.rotate;return t.center=function(t){return t?e([-t[1],t[0]]):[(t=e())[1],-t[0]]},t.rotate=function(t){return t?r([t[0],t[1],t.length>2?t[2]+90:90]):[(t=r())[0],t[1],t[2]-90]},r([0,0,90])}).raw=ti,t.geom={},t.geom.hull=function(t){var e=ei,r=ri;if(arguments.length)return n(t);function n(t){if(t.length<3)return[];var n,i=me(e),a=me(r),o=t.length,s=[],l=[];for(n=0;n=0;--n)p.push(t[s[c[n]][2]]);for(n=+h;nkt)s=s.L;else{if(!((i=a-wi(s,o))>kt)){n>-kt?(e=s.P,r=s):i>-kt?(e=s,r=s.N):e=r=s;break}if(!s.R){e=s;break}s=s.R}var l=vi(t);if(hi.insert(e,l),e||r){if(e===r)return Si(e),r=vi(e.site),hi.insert(l,r),l.edge=r.edge=Li(e.site,l.site),Ti(e),void Ti(r);if(r){Si(e),Si(r);var c=e.site,u=c.x,h=c.y,f=t.x-u,p=t.y-h,d=r.site,g=d.x-u,m=d.y-h,v=2*(f*m-p*g),y=f*f+p*p,x=g*g+m*m,b={x:(m*y-p*x)/v+u,y:(f*x-g*y)/v+h};zi(r.edge,c,d,b),l.edge=Li(c,t,null,b),r.edge=Li(t,d,null,b),Ti(e),Ti(r)}else l.edge=Li(e.site,l.site)}}function _i(t,e){var r=t.site,n=r.x,i=r.y,a=i-e;if(!a)return n;var o=t.P;if(!o)return-1/0;var s=(r=o.site).x,l=r.y,c=l-e;if(!c)return s;var u=s-n,h=1/a-1/c,f=u/c;return h?(-f+Math.sqrt(f*f-2*h*(u*u/(-2*c)-l+c/2+i-a/2)))/h+n:(n+s)/2}function wi(t,e){var r=t.N;if(r)return _i(r,e);var n=t.site;return n.y===e?n.x:1/0}function ki(t){this.site=t,this.edges=[]}function Mi(t,e){return e.angle-t.angle}function Ai(){Oi(this),this.x=this.y=this.arc=this.site=this.cy=null}function Ti(t){var e=t.P,r=t.N;if(e&&r){var n=e.site,i=t.site,a=r.site;if(n!==a){var o=i.x,s=i.y,l=n.x-o,c=n.y-s,u=a.x-o,h=2*(l*(m=a.y-s)-c*u);if(!(h>=-Mt)){var f=l*l+c*c,p=u*u+m*m,d=(m*f-c*p)/h,g=(l*p-u*f)/h,m=g+s,v=gi.pop()||new Ai;v.arc=t,v.site=i,v.x=d+o,v.y=m+Math.sqrt(d*d+g*g),v.cy=m,t.circle=v;for(var y=null,x=pi._;x;)if(v.y=s)return;if(f>d){if(a){if(a.y>=c)return}else a={x:m,y:l};r={x:m,y:c}}else{if(a){if(a.y1)if(f>d){if(a){if(a.y>=c)return}else a={x:(l-i)/n,y:l};r={x:(c-i)/n,y:c}}else{if(a){if(a.y=s)return}else a={x:o,y:n*o+i};r={x:s,y:n*s+i}}else{if(a){if(a.xkt||y(i-r)>kt)&&(s.splice(o,0,new Pi((v=a.site,x=u,b=y(n-h)kt?{x:h,y:y(e-h)kt?{x:y(r-d)kt?{x:f,y:y(e-f)kt?{x:y(r-p)=r&&c.x<=i&&c.y>=n&&c.y<=o?[[r,o],[i,o],[i,n],[r,n]]:[]).point=t[s]}),e}function s(t){return t.map(function(t,e){return{x:Math.round(n(t,e)/kt)*kt,y:Math.round(i(t,e)/kt)*kt,i:e}})}return o.links=function(t){return Fi(s(t)).edges.filter(function(t){return t.l&&t.r}).map(function(e){return{source:t[e.l.i],target:t[e.r.i]}})},o.triangles=function(t){var e=[];return Fi(s(t)).cells.forEach(function(r,n){for(var i,a,o,s,l=r.site,c=r.edges.sort(Mi),u=-1,h=c.length,f=c[h-1].edge,p=f.l===l?f.r:f.l;++ua&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(r=r[0])===(n=n[0])?s[o]?s[o]+=n:s[++o]=n:(s[++o]=null,l.push({i:o,x:Gi(r,n)})),a=Xi.lastIndex;return ag&&(g=l.x),l.y>m&&(m=l.y),c.push(l.x),u.push(l.y);else for(h=0;hg&&(g=b),_>m&&(m=_),c.push(b),u.push(_)}var w=g-p,k=m-d;function M(t,e,r,n,i,a,o,s){if(!isNaN(r)&&!isNaN(n))if(t.leaf){var l=t.x,c=t.y;if(null!=l)if(y(l-r)+y(c-n)<.01)A(t,e,r,n,i,a,o,s);else{var u=t.point;t.x=t.y=t.point=null,A(t,u,l,c,i,a,o,s),A(t,e,r,n,i,a,o,s)}else t.x=r,t.y=n,t.point=e}else A(t,e,r,n,i,a,o,s)}function A(t,e,r,n,i,a,o,s){var l=.5*(i+o),c=.5*(a+s),u=r>=l,h=n>=c,f=h<<1|u;t.leaf=!1,u?i=l:o=l,h?a=c:s=c,M(t=t.nodes[f]||(t.nodes[f]={leaf:!0,nodes:[],point:null,x:null,y:null,add:function(t){M(T,t,+v(t,++h),+x(t,h),p,d,g,m)}}),e,r,n,i,a,o,s)}w>k?m=d+w:g=p+k;var T={leaf:!0,nodes:[],point:null,x:null,y:null,add:function(t){M(T,t,+v(t,++h),+x(t,h),p,d,g,m)}};if(T.visit=function(t){!function t(e,r,n,i,a,o){if(!e(r,n,i,a,o)){var s=.5*(n+a),l=.5*(i+o),c=r.nodes;c[0]&&t(e,c[0],n,i,s,l),c[1]&&t(e,c[1],s,i,a,l),c[2]&&t(e,c[2],n,l,s,o),c[3]&&t(e,c[3],s,l,a,o)}}(t,T,p,d,g,m)},T.find=function(t){return function(t,e,r,n,i,a,o){var s,l=1/0;return function t(c,u,h,f,p){if(!(u>a||h>o||f=_)<<1|e>=b,k=w+4;w=0&&!(n=t.interpolators[i](e,r)););return n}function $i(t,e){var r,n=[],i=[],a=t.length,o=e.length,s=Math.min(t.length,e.length);for(r=0;r=1)return 1;var e=t*t,r=e*t;return 4*(t<.5?r:3*(t-e)+r-.75)}function aa(t){return 1-Math.cos(t*Et)}function oa(t){return Math.pow(2,10*(t-1))}function sa(t){return 1-Math.sqrt(1-t*t)}function la(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}function ca(t,e){return e-=t,function(r){return Math.round(t+e*r)}}function ua(t){var e,r,n,i=[t.a,t.b],a=[t.c,t.d],o=fa(i),s=ha(i,a),l=fa(((e=a)[0]+=(n=-s)*(r=i)[0],e[1]+=n*r[1],e))||0;i[0]*a[1]=0?t.slice(0,n):t,a=n>=0?t.slice(n+1):"in";return i=Ki.get(i)||Ji,a=Qi.get(a)||z,e=a(i.apply(null,r.call(arguments,1))),function(t){return t<=0?0:t>=1?1:e(t)}},t.interpolateHcl=function(e,r){e=t.hcl(e),r=t.hcl(r);var n=e.h,i=e.c,a=e.l,o=r.h-n,s=r.c-i,l=r.l-a;isNaN(s)&&(s=0,i=isNaN(i)?r.c:i);isNaN(o)?(o=0,n=isNaN(n)?r.h:n):o>180?o-=360:o<-180&&(o+=360);return function(t){return Yt(n+o*t,i+s*t,a+l*t)+""}},t.interpolateHsl=function(e,r){e=t.hsl(e),r=t.hsl(r);var n=e.h,i=e.s,a=e.l,o=r.h-n,s=r.s-i,l=r.l-a;isNaN(s)&&(s=0,i=isNaN(i)?r.s:i);isNaN(o)?(o=0,n=isNaN(n)?r.h:n):o>180?o-=360:o<-180&&(o+=360);return function(t){return Ht(n+o*t,i+s*t,a+l*t)+""}},t.interpolateLab=function(e,r){e=t.lab(e),r=t.lab(r);var n=e.l,i=e.a,a=e.b,o=r.l-n,s=r.a-i,l=r.b-a;return function(t){return te(n+o*t,i+s*t,a+l*t)+""}},t.interpolateRound=ca,t.transform=function(e){var r=i.createElementNS(t.ns.prefix.svg,"g");return(t.transform=function(t){if(null!=t){r.setAttribute("transform",t);var e=r.transform.baseVal.consolidate()}return new ua(e?e.matrix:pa)})(e)},ua.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var pa={a:1,b:0,c:0,d:1,e:0,f:0};function da(t){return t.length?t.pop()+",":""}function ga(e,r){var n=[],i=[];return e=t.transform(e),r=t.transform(r),function(t,e,r,n){if(t[0]!==e[0]||t[1]!==e[1]){var i=r.push("translate(",null,",",null,")");n.push({i:i-4,x:Gi(t[0],e[0])},{i:i-2,x:Gi(t[1],e[1])})}else(e[0]||e[1])&&r.push("translate("+e+")")}(e.translate,r.translate,n,i),function(t,e,r,n){t!==e?(t-e>180?e+=360:e-t>180&&(t+=360),n.push({i:r.push(da(r)+"rotate(",null,")")-2,x:Gi(t,e)})):e&&r.push(da(r)+"rotate("+e+")")}(e.rotate,r.rotate,n,i),function(t,e,r,n){t!==e?n.push({i:r.push(da(r)+"skewX(",null,")")-2,x:Gi(t,e)}):e&&r.push(da(r)+"skewX("+e+")")}(e.skew,r.skew,n,i),function(t,e,r,n){if(t[0]!==e[0]||t[1]!==e[1]){var i=r.push(da(r)+"scale(",null,",",null,")");n.push({i:i-4,x:Gi(t[0],e[0])},{i:i-2,x:Gi(t[1],e[1])})}else 1===e[0]&&1===e[1]||r.push(da(r)+"scale("+e+")")}(e.scale,r.scale,n,i),e=r=null,function(t){for(var e,r=-1,a=i.length;++r0?n=t:(e.c=null,e.t=NaN,e=null,l.end({type:"end",alpha:n=0})):t>0&&(l.start({type:"start",alpha:n=t}),e=Me(s.tick)),s):n},s.start=function(){var t,e,r,n=v.length,l=y.length,u=c[0],d=c[1];for(t=0;t=0;)r.push(i[n])}function Ca(t,e){for(var r=[t],n=[];null!=(t=r.pop());)if(n.push(t),(a=t.children)&&(i=a.length))for(var i,a,o=-1;++o=0;)o.push(u=c[l]),u.parent=a,u.depth=a.depth+1;r&&(a.value=0),a.children=c}else r&&(a.value=+r.call(n,a,a.depth)||0),delete a.children;return Ca(i,function(e){var n,i;t&&(n=e.children)&&n.sort(t),r&&(i=e.parent)&&(i.value+=e.value)}),s}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&&(Ea(t,function(t){t.children&&(t.value=0)}),Ca(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},t.layout.partition=function(){var e=t.layout.hierarchy(),r=[1,1];function n(t,n){var i=e.call(this,t,n);return function t(e,r,n,i){var a=e.children;if(e.x=r,e.y=e.depth*i,e.dx=n,e.dy=i,a&&(o=a.length)){var o,s,l,c=-1;for(n=e.value?n/e.value:0;++cs&&(s=n),o.push(n)}for(r=0;ri&&(n=r,i=e);return n}function qa(t){return t.reduce(Ha,0)}function Ha(t,e){return t+e[1]}function Ga(t,e){return Wa(t,Math.ceil(Math.log(e.length)/Math.LN2+1))}function Wa(t,e){for(var r=-1,n=+t[0],i=(t[1]-n)/e,a=[];++r<=e;)a[r]=i*r+n;return a}function Ya(e){return[t.min(e),t.max(e)]}function Xa(t,e){return t.value-e.value}function Za(t,e){var r=t._pack_next;t._pack_next=e,e._pack_prev=t,e._pack_next=r,r._pack_prev=e}function $a(t,e){t._pack_next=e,e._pack_prev=t}function Ja(t,e){var r=e.x-t.x,n=e.y-t.y,i=t.r+e.r;return.999*i*i>r*r+n*n}function Ka(t){if((e=t.children)&&(l=e.length)){var e,r,n,i,a,o,s,l,c=1/0,u=-1/0,h=1/0,f=-1/0;if(e.forEach(Qa),(r=e[0]).x=-r.r,r.y=0,x(r),l>1&&((n=e[1]).x=n.r,n.y=0,x(n),l>2))for(eo(r,n,i=e[2]),x(i),Za(r,i),r._pack_prev=i,Za(i,n),n=r._pack_next,a=3;a0)for(o=-1;++o=h[0]&&l<=h[1]&&((s=c[t.bisect(f,l,1,d)-1]).y+=g,s.push(a[o]));return c}return a.value=function(t){return arguments.length?(r=t,a):r},a.range=function(t){return arguments.length?(n=me(t),a):n},a.bins=function(t){return arguments.length?(i="number"==typeof t?function(e){return Wa(e,t)}:me(t),a):i},a.frequency=function(t){return arguments.length?(e=!!t,a):e},a},t.layout.pack=function(){var e,r=t.layout.hierarchy().sort(Xa),n=0,i=[1,1];function a(t,a){var o=r.call(this,t,a),s=o[0],l=i[0],c=i[1],u=null==e?Math.sqrt:"function"==typeof e?e:function(){return e};if(s.x=s.y=0,Ca(s,function(t){t.r=+u(t.value)}),Ca(s,Ka),n){var h=n*(e?1:Math.max(2*s.r/l,2*s.r/c))/2;Ca(s,function(t){t.r+=h}),Ca(s,Ka),Ca(s,function(t){t.r-=h})}return function t(e,r,n,i){var a=e.children;e.x=r+=i*e.x;e.y=n+=i*e.y;e.r*=i;if(a)for(var o=-1,s=a.length;++op.x&&(p=t),t.depth>d.depth&&(d=t)});var g=r(f,p)/2-f.x,m=n[0]/(p.x+r(p,f)/2+g),v=n[1]/(d.depth||1);Ea(u,function(t){t.x=(t.x+g)*m,t.y=t.depth*v})}return c}function o(t){var e=t.children,n=t.parent.children,i=t.i?n[t.i-1]:null;if(e.length){!function(t){var e,r=0,n=0,i=t.children,a=i.length;for(;--a>=0;)(e=i[a]).z+=r,e.m+=r,r+=e.s+(n+=e.c)}(t);var a=(e[0].z+e[e.length-1].z)/2;i?(t.z=i.z+r(t._,i._),t.m=t.z-a):t.z=a}else i&&(t.z=i.z+r(t._,i._));t.parent.A=function(t,e,n){if(e){for(var i,a=t,o=t,s=e,l=a.parent.children[0],c=a.m,u=o.m,h=s.m,f=l.m;s=io(s),a=no(a),s&&a;)l=no(l),(o=io(o)).a=t,(i=s.z+h-a.z-c+r(s._,a._))>0&&(ao(oo(s,t,n),t,i),c+=i,u+=i),h+=s.m,c+=a.m,f+=l.m,u+=o.m;s&&!io(o)&&(o.t=s,o.m+=h-u),a&&!no(l)&&(l.t=a,l.m+=c-f,n=t)}return n}(t,i,t.parent.A||n[0])}function s(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function l(t){t.x*=n[0],t.y=t.depth*n[1]}return a.separation=function(t){return arguments.length?(r=t,a):r},a.size=function(t){return arguments.length?(i=null==(n=t)?l:null,a):i?null:n},a.nodeSize=function(t){return arguments.length?(i=null==(n=t)?null:l,a):i?n:null},Sa(a,e)},t.layout.cluster=function(){var e=t.layout.hierarchy().sort(null).value(null),r=ro,n=[1,1],i=!1;function a(a,o){var s,l=e.call(this,a,o),c=l[0],u=0;Ca(c,function(e){var n=e.children;n&&n.length?(e.x=function(t){return t.reduce(function(t,e){return t+e.x},0)/t.length}(n),e.y=function(e){return 1+t.max(e,function(t){return t.y})}(n)):(e.x=s?u+=r(e,s):0,e.y=0,s=e)});var h=function t(e){var r=e.children;return r&&r.length?t(r[0]):e}(c),f=function t(e){var r,n=e.children;return n&&(r=n.length)?t(n[r-1]):e}(c),p=h.x-r(h,f)/2,d=f.x+r(f,h)/2;return Ca(c,i?function(t){t.x=(t.x-c.x)*n[0],t.y=(c.y-t.y)*n[1]}:function(t){t.x=(t.x-p)/(d-p)*n[0],t.y=(1-(c.y?t.y/c.y:1))*n[1]}),l}return a.separation=function(t){return arguments.length?(r=t,a):r},a.size=function(t){return arguments.length?(i=null==(n=t),a):i?null:n},a.nodeSize=function(t){return arguments.length?(i=null!=(n=t),a):i?n:null},Sa(a,e)},t.layout.treemap=function(){var e,r=t.layout.hierarchy(),n=Math.round,i=[1,1],a=null,o=so,s=!1,l="squarify",c=.5*(1+Math.sqrt(5));function u(t,e){for(var r,n,i=-1,a=t.length;++i0;)s.push(r=c[i-1]),s.area+=r.area,"squarify"!==l||(n=p(s,g))<=f?(c.pop(),f=n):(s.area-=s.pop().area,d(s,g,a,!1),g=Math.min(a.dx,a.dy),s.length=s.area=0,f=1/0);s.length&&(d(s,g,a,!0),s.length=s.area=0),e.forEach(h)}}function f(t){var e=t.children;if(e&&e.length){var r,n=o(t),i=e.slice(),a=[];for(u(i,n.dx*n.dy/t.value),a.area=0;r=i.pop();)a.push(r),a.area+=r.area,null!=r.z&&(d(a,r.z?n.dx:n.dy,n,!i.length),a.length=a.area=0);e.forEach(f)}}function p(t,e){for(var r,n=t.area,i=0,a=1/0,o=-1,s=t.length;++oi&&(i=r));return e*=e,(n*=n)?Math.max(e*i*c/n,n/(e*a*c)):1/0}function d(t,e,r,i){var a,o=-1,s=t.length,l=r.x,c=r.y,u=e?n(t.area/e):0;if(e==r.dx){for((i||u>r.dy)&&(u=r.dy);++or.dx)&&(u=r.dx);++o1);return t+e*r*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var e=t.random.normal.apply(t,arguments);return function(){return Math.exp(e())}},bates:function(e){var r=t.random.irwinHall(e);return function(){return r()/e}},irwinHall:function(t){return function(){for(var e=0,r=0;r2?mo:ho,s=i?va:ma;return a=t(e,r,s,n),o=t(r,e,s,Zi),l}function l(t){return a(t)}l.invert=function(t){return o(t)};l.domain=function(t){return arguments.length?(e=t.map(Number),s()):e};l.range=function(t){return arguments.length?(r=t,s()):r};l.rangeRound=function(t){return l.range(t).interpolate(ca)};l.clamp=function(t){return arguments.length?(i=t,s()):i};l.interpolate=function(t){return arguments.length?(n=t,s()):n};l.ticks=function(t){return bo(e,t)};l.tickFormat=function(t,r){return _o(e,t,r)};l.nice=function(t){return yo(e,t),s()};l.copy=function(){return t(e,r,n,i)};return s()}([0,1],[0,1],Zi,!1)};var wo={s:1,g:1,p:1,r:1,e:1};function ko(t){return-Math.floor(Math.log(t)/Math.LN10+.01)}t.scale.log=function(){return function e(r,n,i,a){function o(t){return(i?Math.log(t<0?0:t):-Math.log(t>0?0:-t))/Math.log(n)}function s(t){return i?Math.pow(n,t):-Math.pow(n,-t)}function l(t){return r(o(t))}l.invert=function(t){return s(r.invert(t))};l.domain=function(t){return arguments.length?(i=t[0]>=0,r.domain((a=t.map(Number)).map(o)),l):a};l.base=function(t){return arguments.length?(n=+t,r.domain(a.map(o)),l):n};l.nice=function(){var t=fo(a.map(o),i?Math:Ao);return r.domain(t),a=t.map(s),l};l.ticks=function(){var t=co(a),e=[],r=t[0],l=t[1],c=Math.floor(o(r)),u=Math.ceil(o(l)),h=n%1?2:n;if(isFinite(u-c)){if(i){for(;c0;f--)e.push(s(c)*f);for(c=0;e[c]l;u--);e=e.slice(c,u)}return e};l.tickFormat=function(e,r){if(!arguments.length)return Mo;arguments.length<2?r=Mo:"function"!=typeof r&&(r=t.format(r));var i=Math.max(1,n*e/l.ticks().length);return function(t){var e=t/s(Math.round(o(t)));return e*n0?i[t-1]:r[0],th?0:1;if(c=St)return l(c,p)+(s?l(s,1-p):"")+"Z";var d,g,m,v,y,x,b,_,w,k,M,A,T=0,S=0,E=[];if((v=(+o.apply(this,arguments)||0)/2)&&(m=n===Po?Math.sqrt(s*s+c*c):+n.apply(this,arguments),p||(S*=-1),c&&(S=Ot(m/c*Math.sin(v))),s&&(T=Ot(m/s*Math.sin(v)))),c){y=c*Math.cos(u+S),x=c*Math.sin(u+S),b=c*Math.cos(h-S),_=c*Math.sin(h-S);var C=Math.abs(h-u-2*S)<=At?0:1;if(S&&Fo(y,x,b,_)===p^C){var L=(u+h)/2;y=c*Math.cos(L),x=c*Math.sin(L),b=_=null}}else y=x=0;if(s){w=s*Math.cos(h-T),k=s*Math.sin(h-T),M=s*Math.cos(u+T),A=s*Math.sin(u+T);var z=Math.abs(u-h+2*T)<=At?0:1;if(T&&Fo(w,k,M,A)===1-p^z){var P=(u+h)/2;w=s*Math.cos(P),k=s*Math.sin(P),M=A=null}}else w=k=0;if(f>kt&&(d=Math.min(Math.abs(c-s)/2,+r.apply(this,arguments)))>.001){g=s0?0:1}function No(t,e,r,n,i){var a=t[0]-e[0],o=t[1]-e[1],s=(i?n:-n)/Math.sqrt(a*a+o*o),l=s*o,c=-s*a,u=t[0]+l,h=t[1]+c,f=e[0]+l,p=e[1]+c,d=(u+f)/2,g=(h+p)/2,m=f-u,v=p-h,y=m*m+v*v,x=r-n,b=u*p-f*h,_=(v<0?-1:1)*Math.sqrt(Math.max(0,x*x*y-b*b)),w=(b*v-m*_)/y,k=(-b*m-v*_)/y,M=(b*v+m*_)/y,A=(-b*m+v*_)/y,T=w-d,S=k-g,E=M-d,C=A-g;return T*T+S*S>E*E+C*C&&(w=M,k=A),[[w-l,k-c],[w*r/x,k*r/x]]}function jo(t){var e=ei,r=ri,n=Wr,i=Uo,a=i.key,o=.7;function s(a){var s,l=[],c=[],u=-1,h=a.length,f=me(e),p=me(r);function d(){l.push("M",i(t(c),o))}for(;++u1&&i.push("H",n[0]);return i.join("")},"step-before":Ho,"step-after":Go,basis:Xo,"basis-open":function(t){if(t.length<4)return Uo(t);var e,r=[],n=-1,i=t.length,a=[0],o=[0];for(;++n<3;)e=t[n],a.push(e[0]),o.push(e[1]);r.push(Zo(Ko,a)+","+Zo(Ko,o)),--n;for(;++n9&&(i=3*e/Math.sqrt(i),o[s]=i*r,o[s+1]=i*n));s=-1;for(;++s<=l;)i=(t[Math.min(l,s+1)][0]-t[Math.max(0,s-1)][0])/(6*(1+o[s]*o[s])),a.push([i||0,o[s]*i||0]);return a}(t))}});function Uo(t){return t.length>1?t.join("L"):t+"Z"}function qo(t){return t.join("L")+"Z"}function Ho(t){for(var e=0,r=t.length,n=t[0],i=[n[0],",",n[1]];++e1){s=e[1],a=t[l],l++,n+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(a[0]-s[0])+","+(a[1]-s[1])+","+a[0]+","+a[1];for(var c=2;cAt)+",1 "+e}function l(t,e,r,n){return"Q 0,0 "+n}return a.radius=function(t){return arguments.length?(r=me(t),a):r},a.source=function(e){return arguments.length?(t=me(e),a):t},a.target=function(t){return arguments.length?(e=me(t),a):e},a.startAngle=function(t){return arguments.length?(n=me(t),a):n},a.endAngle=function(t){return arguments.length?(i=me(t),a):i},a},t.svg.diagonal=function(){var t=Vn,e=Un,r=is;function n(n,i){var a=t.call(this,n,i),o=e.call(this,n,i),s=(a.y+o.y)/2,l=[a,{x:a.x,y:s},{x:o.x,y:s},o];return"M"+(l=l.map(r))[0]+"C"+l[1]+" "+l[2]+" "+l[3]}return n.source=function(e){return arguments.length?(t=me(e),n):t},n.target=function(t){return arguments.length?(e=me(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},t.svg.diagonal.radial=function(){var e=t.svg.diagonal(),r=is,n=e.projection;return e.projection=function(t){return arguments.length?n(function(t){return function(){var e=t.apply(this,arguments),r=e[0],n=e[1]-Et;return[r*Math.cos(n),r*Math.sin(n)]}}(r=t)):r},e},t.svg.symbol=function(){var t=os,e=as;function r(r,n){return(ls.get(t.call(this,r,n))||ss)(e.call(this,r,n))}return r.type=function(e){return arguments.length?(t=me(e),r):t},r.size=function(t){return arguments.length?(e=me(t),r):e},r};var ls=t.map({circle:ss,cross:function(t){var e=Math.sqrt(t/5)/2;return"M"+-3*e+","+-e+"H"+-e+"V"+-3*e+"H"+e+"V"+-e+"H"+3*e+"V"+e+"H"+e+"V"+3*e+"H"+-e+"V"+e+"H"+-3*e+"Z"},diamond:function(t){var e=Math.sqrt(t/(2*us)),r=e*us;return"M0,"+-e+"L"+r+",0 0,"+e+" "+-r+",0Z"},square:function(t){var e=Math.sqrt(t)/2;return"M"+-e+","+-e+"L"+e+","+-e+" "+e+","+e+" "+-e+","+e+"Z"},"triangle-down":function(t){var e=Math.sqrt(t/cs),r=e*cs/2;return"M0,"+r+"L"+e+","+-r+" "+-e+","+-r+"Z"},"triangle-up":function(t){var e=Math.sqrt(t/cs),r=e*cs/2;return"M0,"+-r+"L"+e+","+r+" "+-e+","+r+"Z"}});t.svg.symbolTypes=ls.keys();var cs=Math.sqrt(3),us=Math.tan(30*Ct);Y.transition=function(t){for(var e,r,n=ds||++vs,i=bs(t),a=[],o=gs||{time:Date.now(),ease:ia,delay:0,duration:250},s=-1,l=this.length;++s0;)c[--f].call(t,o);if(a>=1)return h.event&&h.event.end.call(t,t.__data__,e),--u.count?delete u[n]:delete t[r],1}h||(a=i.time,o=Me(function(t){var e=h.delay;if(o.t=e+a,e<=t)return f(t-e);o.c=f},0,a),h=u[n]={tween:new b,time:a,timer:o,delay:i.delay,duration:i.duration,ease:i.ease,index:e},i=null,++u.count)}ms.call=Y.call,ms.empty=Y.empty,ms.node=Y.node,ms.size=Y.size,t.transition=function(e,r){return e&&e.transition?ds?e.transition(r):e:t.selection().transition(e)},t.transition.prototype=ms,ms.select=function(t){var e,r,n,i=this.id,a=this.namespace,o=[];t=X(t);for(var s=-1,l=this.length;++srect,.s>rect").attr("width",s[1]-s[0])}function g(t){t.select(".extent").attr("y",l[0]),t.selectAll(".extent,.e>rect,.w>rect").attr("height",l[1]-l[0])}function m(){var h,m,v=this,y=t.select(t.event.target),x=n.of(v,arguments),b=t.select(v),_=y.datum(),w=!/^(n|s)$/.test(_)&&i,k=!/^(e|w)$/.test(_)&&a,M=y.classed("extent"),A=xt(v),T=t.mouse(v),S=t.select(o(v)).on("keydown.brush",function(){32==t.event.keyCode&&(M||(h=null,T[0]-=s[1],T[1]-=l[1],M=2),F())}).on("keyup.brush",function(){32==t.event.keyCode&&2==M&&(T[0]+=s[1],T[1]+=l[1],M=0,F())});if(t.event.changedTouches?S.on("touchmove.brush",L).on("touchend.brush",P):S.on("mousemove.brush",L).on("mouseup.brush",P),b.interrupt().selectAll("*").interrupt(),M)T[0]=s[0]-T[0],T[1]=l[0]-T[1];else if(_){var E=+/w$/.test(_),C=+/^n/.test(_);m=[s[1-E]-T[0],l[1-C]-T[1]],T[0]=s[E],T[1]=l[C]}else t.event.altKey&&(h=T.slice());function L(){var e=t.mouse(v),r=!1;m&&(e[0]+=m[0],e[1]+=m[1]),M||(t.event.altKey?(h||(h=[(s[0]+s[1])/2,(l[0]+l[1])/2]),T[0]=s[+(e[0]1?{floor:function(e){for(;s(e=t.floor(e));)e=Is(e-1);return e},ceil:function(e){for(;s(e=t.ceil(e));)e=Is(+e+1);return e}}:t))},i.ticks=function(t,e){var r=co(i.domain()),n=null==t?a(r,10):"number"==typeof t?a(r,t):!t.range&&[{range:t},e];return n&&(t=n[0],e=n[1]),t.range(r[0],Is(+r[1]+1),e<1?1:e)},i.tickFormat=function(){return n},i.copy=function(){return Ps(e.copy(),r,n)},vo(i,e)}function Is(t){return new Date(t)}Es.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?zs:Ls,zs.parse=function(t){var e=new Date(t);return isNaN(e)?null:e},zs.toString=Ls.toString,Ie.second=Be(function(t){return new Oe(1e3*Math.floor(t/1e3))},function(t,e){t.setTime(t.getTime()+1e3*Math.floor(e))},function(t){return t.getSeconds()}),Ie.seconds=Ie.second.range,Ie.seconds.utc=Ie.second.utc.range,Ie.minute=Be(function(t){return new Oe(6e4*Math.floor(t/6e4))},function(t,e){t.setTime(t.getTime()+6e4*Math.floor(e))},function(t){return t.getMinutes()}),Ie.minutes=Ie.minute.range,Ie.minutes.utc=Ie.minute.utc.range,Ie.hour=Be(function(t){var e=t.getTimezoneOffset()/60;return new Oe(36e5*(Math.floor(t/36e5-e)+e))},function(t,e){t.setTime(t.getTime()+36e5*Math.floor(e))},function(t){return t.getHours()}),Ie.hours=Ie.hour.range,Ie.hours.utc=Ie.hour.utc.range,Ie.month=Be(function(t){return(t=Ie.day(t)).setDate(1),t},function(t,e){t.setMonth(t.getMonth()+e)},function(t){return t.getMonth()}),Ie.months=Ie.month.range,Ie.months.utc=Ie.month.utc.range;var Os=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ds=[[Ie.second,1],[Ie.second,5],[Ie.second,15],[Ie.second,30],[Ie.minute,1],[Ie.minute,5],[Ie.minute,15],[Ie.minute,30],[Ie.hour,1],[Ie.hour,3],[Ie.hour,6],[Ie.hour,12],[Ie.day,1],[Ie.day,2],[Ie.week,1],[Ie.month,1],[Ie.month,3],[Ie.year,1]],Rs=Es.multi([[".%L",function(t){return t.getMilliseconds()}],[":%S",function(t){return t.getSeconds()}],["%I:%M",function(t){return t.getMinutes()}],["%I %p",function(t){return t.getHours()}],["%a %d",function(t){return t.getDay()&&1!=t.getDate()}],["%b %d",function(t){return 1!=t.getDate()}],["%B",function(t){return t.getMonth()}],["%Y",Wr]]),Bs={range:function(e,r,n){return t.range(Math.ceil(e/n)*n,+r,n).map(Is)},floor:z,ceil:z};Ds.year=Ie.year,Ie.scale=function(){return Ps(t.scale.linear(),Ds,Rs)};var Fs=Ds.map(function(t){return[t[0].utc,t[1]]}),Ns=Cs.multi([[".%L",function(t){return t.getUTCMilliseconds()}],[":%S",function(t){return t.getUTCSeconds()}],["%I:%M",function(t){return t.getUTCMinutes()}],["%I %p",function(t){return t.getUTCHours()}],["%a %d",function(t){return t.getUTCDay()&&1!=t.getUTCDate()}],["%b %d",function(t){return 1!=t.getUTCDate()}],["%B",function(t){return t.getUTCMonth()}],["%Y",Wr]]);function js(t){return JSON.parse(t.responseText)}function Vs(t){var e=i.createRange();return e.selectNode(i.body),e.createContextualFragment(t.responseText)}Fs.year=Ie.year.utc,Ie.scale.utc=function(){return Ps(t.scale.linear(),Fs,Ns)},t.text=ve(function(t){return t.responseText}),t.json=function(t,e){return ye(t,"application/json",js,e)},t.html=function(t,e){return ye(t,"text/html",Vs,e)},t.xml=ve(function(t){return t.responseXML}),"object"==typeof e&&e.exports?e.exports=t:this.d3=t}()},{}],148:[function(t,e,r){e.exports=function(){for(var t=0;t=2)return!1;t[r]=n}return!0}):_.filter(function(t){for(var e=0;e<=s;++e){var r=v[t[e]];if(r<0)return!1;t[e]=r}return!0});if(1&s)for(var u=0;u<_.length;++u){var b=_[u],f=b[0];b[0]=b[1],b[1]=f}return _}},{"incremental-convex-hull":381,uniq:509}],150:[function(t,e,r){"use strict";e.exports=a;var n=(a.canvas=document.createElement("canvas")).getContext("2d"),i=o([32,126]);function a(t,e){Array.isArray(t)&&(t=t.join(", "));var r,a={},s=16,l=.05;e&&(2===e.length&&"number"==typeof e[0]?r=o(e):Array.isArray(e)?r=e:(e.o?r=o(e.o):e.pairs&&(r=e.pairs),e.fontSize&&(s=e.fontSize),null!=e.threshold&&(l=e.threshold))),r||(r=i),n.font=s+"px "+t;for(var c=0;cs*l){var p=(f-h)/s;a[u]=1e3*p}}return a}function o(t){for(var e=[],r=t[0];r<=t[1];r++)for(var n=String.fromCharCode(r),i=t[0];i>>31},e.exports.exponent=function(t){return(e.exports.hi(t)<<1>>>21)-1023},e.exports.fraction=function(t){var r=e.exports.lo(t),n=e.exports.hi(t),i=1048575&n;return 2146435072&n&&(i+=1<<20),[r,i]},e.exports.denormalized=function(t){return!(2146435072&e.exports.hi(t))}}).call(this,t("buffer").Buffer)},{buffer:92}],152:[function(t,e,r){var n=t("abs-svg-path"),i=t("normalize-svg-path"),a={M:"moveTo",C:"bezierCurveTo"};e.exports=function(t,e){t.beginPath(),i(n(e)).forEach(function(e){var r=e[0],n=e.slice(1);t[a[r]].apply(t,n)}),t.closePath()}},{"abs-svg-path":51,"normalize-svg-path":419}],153:[function(t,e,r){e.exports=function(t){switch(t){case"int8":return Int8Array;case"int16":return Int16Array;case"int32":return Int32Array;case"uint8":return Uint8Array;case"uint16":return Uint16Array;case"uint32":return Uint32Array;case"float32":return Float32Array;case"float64":return Float64Array;case"array":return Array;case"uint8_clamped":return Uint8ClampedArray}}},{}],154:[function(t,e,r){"use strict";e.exports=function(t,e){switch("undefined"==typeof e&&(e=0),typeof t){case"number":if(t>0)return function(t,e){var r,n;for(r=new Array(t),n=0;n80*r){n=l=t[0],s=c=t[1];for(var b=r;bl&&(l=u),p>c&&(c=p);g=0!==(g=Math.max(l-n,c-s))?1/g:0}return o(y,x,r,n,s,g),x}function i(t,e,r,n,i){var a,o;if(i===A(t,e,r,n)>0)for(a=e;a=e;a-=n)o=w(a,t[a],t[a+1],o);return o&&y(o,o.next)&&(k(o),o=o.next),o}function a(t,e){if(!t)return t;e||(e=t);var r,n=t;do{if(r=!1,n.steiner||!y(n,n.next)&&0!==v(n.prev,n,n.next))n=n.next;else{if(k(n),(n=e=n.prev)===n.next)break;r=!0}}while(r||n!==e);return e}function o(t,e,r,n,i,h,f){if(t){!f&&h&&function(t,e,r,n){var i=t;do{null===i.z&&(i.z=p(i.x,i.y,e,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==t);i.prevZ.nextZ=null,i.prevZ=null,function(t){var e,r,n,i,a,o,s,l,c=1;do{for(r=t,t=null,a=null,o=0;r;){for(o++,n=r,s=0,e=0;e0||l>0&&n;)0!==s&&(0===l||!n||r.z<=n.z)?(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,l--),a?a.nextZ=i:t=i,i.prevZ=a,a=i;r=n}a.nextZ=null,c*=2}while(o>1)}(i)}(t,n,i,h);for(var d,g,m=t;t.prev!==t.next;)if(d=t.prev,g=t.next,h?l(t,n,i,h):s(t))e.push(d.i/r),e.push(t.i/r),e.push(g.i/r),k(t),t=g.next,m=g.next;else if((t=g)===m){f?1===f?o(t=c(t,e,r),e,r,n,i,h,2):2===f&&u(t,e,r,n,i,h):o(a(t),e,r,n,i,h,1);break}}}function s(t){var e=t.prev,r=t,n=t.next;if(v(e,r,n)>=0)return!1;for(var i=t.next.next;i!==t.prev;){if(g(e.x,e.y,r.x,r.y,n.x,n.y,i.x,i.y)&&v(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function l(t,e,r,n){var i=t.prev,a=t,o=t.next;if(v(i,a,o)>=0)return!1;for(var s=i.xa.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,u=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,h=p(s,l,e,r,n),f=p(c,u,e,r,n),d=t.prevZ,m=t.nextZ;d&&d.z>=h&&m&&m.z<=f;){if(d!==t.prev&&d!==t.next&&g(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&v(d.prev,d,d.next)>=0)return!1;if(d=d.prevZ,m!==t.prev&&m!==t.next&&g(i.x,i.y,a.x,a.y,o.x,o.y,m.x,m.y)&&v(m.prev,m,m.next)>=0)return!1;m=m.nextZ}for(;d&&d.z>=h;){if(d!==t.prev&&d!==t.next&&g(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&v(d.prev,d,d.next)>=0)return!1;d=d.prevZ}for(;m&&m.z<=f;){if(m!==t.prev&&m!==t.next&&g(i.x,i.y,a.x,a.y,o.x,o.y,m.x,m.y)&&v(m.prev,m,m.next)>=0)return!1;m=m.nextZ}return!0}function c(t,e,r){var n=t;do{var i=n.prev,a=n.next.next;!y(i,a)&&x(i,n,n.next,a)&&b(i,a)&&b(a,i)&&(e.push(i.i/r),e.push(n.i/r),e.push(a.i/r),k(n),k(n.next),n=t=a),n=n.next}while(n!==t);return n}function u(t,e,r,n,i,s){var l=t;do{for(var c=l.next.next;c!==l.prev;){if(l.i!==c.i&&m(l,c)){var u=_(l,c);return l=a(l,l.next),u=a(u,u.next),o(l,e,r,n,i,s),void o(u,e,r,n,i,s)}c=c.next}l=l.next}while(l!==t)}function h(t,e){return t.x-e.x}function f(t,e){if(e=function(t,e){var r,n=e,i=t.x,a=t.y,o=-1/0;do{if(a<=n.y&&a>=n.next.y&&n.next.y!==n.y){var s=n.x+(a-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(s<=i&&s>o){if(o=s,s===i){if(a===n.y)return n;if(a===n.next.y)return n.next}r=n.x=n.x&&n.x>=u&&i!==n.x&&g(ar.x)&&b(n,t)&&(r=n,f=l),n=n.next;return r}(t,e)){var r=_(e,t);a(r,r.next)}}function p(t,e,r,n,i){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=32767*(t-r)*i)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=32767*(e-n)*i)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function d(t){var e=t,r=t;do{e.x=0&&(t-o)*(n-s)-(r-o)*(e-s)>=0&&(r-o)*(a-s)-(i-o)*(n-s)>=0}function m(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var r=t;do{if(r.i!==t.i&&r.next.i!==t.i&&r.i!==e.i&&r.next.i!==e.i&&x(r,r.next,t,e))return!0;r=r.next}while(r!==t);return!1}(t,e)&&b(t,e)&&b(e,t)&&function(t,e){var r=t,n=!1,i=(t.x+e.x)/2,a=(t.y+e.y)/2;do{r.y>a!=r.next.y>a&&r.next.y!==r.y&&i<(r.next.x-r.x)*(a-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==t);return n}(t,e)}function v(t,e,r){return(e.y-t.y)*(r.x-e.x)-(e.x-t.x)*(r.y-e.y)}function y(t,e){return t.x===e.x&&t.y===e.y}function x(t,e,r,n){return!!(y(t,e)&&y(r,n)||y(t,n)&&y(r,e))||v(t,e,r)>0!=v(t,e,n)>0&&v(r,n,t)>0!=v(r,n,e)>0}function b(t,e){return v(t.prev,t,t.next)<0?v(t,e,t.next)>=0&&v(t,t.prev,e)>=0:v(t,e,t.prev)<0||v(t,t.next,e)<0}function _(t,e){var r=new M(t.i,t.x,t.y),n=new M(e.i,e.x,e.y),i=t.next,a=e.prev;return t.next=e,e.prev=t,r.next=i,i.prev=r,n.next=r,r.prev=n,a.next=n,n.prev=a,n}function w(t,e,r,n){var i=new M(t,e,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function k(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function M(t,e,r){this.i=t,this.x=e,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function A(t,e,r,n){for(var i=0,a=e,o=r-n;a0&&(n+=t[i-1].length,r.holes.push(n))}return r}},{}],156:[function(t,e,r){"use strict";e.exports=function(t,e){var r=t.length;if("number"!=typeof e){e=0;for(var i=0;i=55296&&y<=56319&&(w+=t[++r]),w=k?f.call(k,M,w,g):w,e?(p.value=w,d(m,g,p)):m[g]=w,++g;v=g}if(void 0===v)for(v=o(t.length),e&&(m=new e(v)),r=0;r0?1:-1}},{}],167:[function(t,e,r){"use strict";var n=t("../math/sign"),i=Math.abs,a=Math.floor;e.exports=function(t){return isNaN(t)?0:0!==(t=Number(t))&&isFinite(t)?n(t)*a(i(t)):t}},{"../math/sign":164}],168:[function(t,e,r){"use strict";var n=t("./to-integer"),i=Math.max;e.exports=function(t){return i(0,n(t))}},{"./to-integer":167}],169:[function(t,e,r){"use strict";var n=t("./valid-callable"),i=t("./valid-value"),a=Function.prototype.bind,o=Function.prototype.call,s=Object.keys,l=Object.prototype.propertyIsEnumerable;e.exports=function(t,e){return function(r,c){var u,h=arguments[2],f=arguments[3];return r=Object(i(r)),n(c),u=s(r),f&&u.sort("function"==typeof f?a.call(f,r):void 0),"function"!=typeof t&&(t=u[t]),o.call(t,u,function(t,n){return l.call(r,t)?o.call(c,h,r[t],t,r,n):e})}}},{"./valid-callable":187,"./valid-value":189}],170:[function(t,e,r){"use strict";e.exports=t("./is-implemented")()?Object.assign:t("./shim")},{"./is-implemented":171,"./shim":172}],171:[function(t,e,r){"use strict";e.exports=function(){var t,e=Object.assign;return"function"==typeof e&&(e(t={foo:"raz"},{bar:"dwa"},{trzy:"trzy"}),t.foo+t.bar+t.trzy==="razdwatrzy")}},{}],172:[function(t,e,r){"use strict";var n=t("../keys"),i=t("../valid-value"),a=Math.max;e.exports=function(t,e){var r,o,s,l=a(arguments.length,2);for(t=Object(i(t)),s=function(n){try{t[n]=e[n]}catch(t){r||(r=t)}},o=1;o-1}},{}],193:[function(t,e,r){"use strict";var n=Object.prototype.toString,i=n.call("");e.exports=function(t){return"string"==typeof t||t&&"object"==typeof t&&(t instanceof String||n.call(t)===i)||!1}},{}],194:[function(t,e,r){"use strict";var n=Object.create(null),i=Math.random;e.exports=function(){var t;do{t=i().toString(36).slice(2)}while(n[t]);return t}},{}],195:[function(t,e,r){"use strict";var n,i=t("es5-ext/object/set-prototype-of"),a=t("es5-ext/string/#/contains"),o=t("d"),s=t("es6-symbol"),l=t("./"),c=Object.defineProperty;n=e.exports=function(t,e){if(!(this instanceof n))throw new TypeError("Constructor requires 'new'");l.call(this,t),e=e?a.call(e,"key+value")?"key+value":a.call(e,"key")?"key":"value":"value",c(this,"__kind__",o("",e))},i&&i(n,l),delete n.prototype.constructor,n.prototype=Object.create(l.prototype,{_resolve:o(function(t){return"value"===this.__kind__?this.__list__[t]:"key+value"===this.__kind__?[t,this.__list__[t]]:t})}),c(n.prototype,s.toStringTag,o("c","Array Iterator"))},{"./":198,d:138,"es5-ext/object/set-prototype-of":184,"es5-ext/string/#/contains":190,"es6-symbol":203}],196:[function(t,e,r){"use strict";var n=t("es5-ext/function/is-arguments"),i=t("es5-ext/object/valid-callable"),a=t("es5-ext/string/is-string"),o=t("./get"),s=Array.isArray,l=Function.prototype.call,c=Array.prototype.some;e.exports=function(t,e){var r,u,h,f,p,d,g,m,v=arguments[2];if(s(t)||n(t)?r="array":a(t)?r="string":t=o(t),i(e),h=function(){f=!0},"array"!==r)if("string"!==r)for(u=t.next();!u.done;){if(l.call(e,v,u.value,h),f)return;u=t.next()}else for(d=t.length,p=0;p=55296&&m<=56319&&(g+=t[++p]),l.call(e,v,g,h),!f);++p);else c.call(t,function(t){return l.call(e,v,t,h),f})}},{"./get":197,"es5-ext/function/is-arguments":161,"es5-ext/object/valid-callable":187,"es5-ext/string/is-string":193}],197:[function(t,e,r){"use strict";var n=t("es5-ext/function/is-arguments"),i=t("es5-ext/string/is-string"),a=t("./array"),o=t("./string"),s=t("./valid-iterable"),l=t("es6-symbol").iterator;e.exports=function(t){return"function"==typeof s(t)[l]?t[l]():n(t)?new a(t):i(t)?new o(t):new a(t)}},{"./array":195,"./string":200,"./valid-iterable":201,"es5-ext/function/is-arguments":161,"es5-ext/string/is-string":193,"es6-symbol":203}],198:[function(t,e,r){"use strict";var n,i=t("es5-ext/array/#/clear"),a=t("es5-ext/object/assign"),o=t("es5-ext/object/valid-callable"),s=t("es5-ext/object/valid-value"),l=t("d"),c=t("d/auto-bind"),u=t("es6-symbol"),h=Object.defineProperty,f=Object.defineProperties;e.exports=n=function(t,e){if(!(this instanceof n))throw new TypeError("Constructor requires 'new'");f(this,{__list__:l("w",s(t)),__context__:l("w",e),__nextIndex__:l("w",0)}),e&&(o(e.on),e.on("_add",this._onAdd),e.on("_delete",this._onDelete),e.on("_clear",this._onClear))},delete n.prototype.constructor,f(n.prototype,a({_next:l(function(){var t;if(this.__list__)return this.__redo__&&void 0!==(t=this.__redo__.shift())?t:this.__nextIndex__=this.__nextIndex__||(++this.__nextIndex__,this.__redo__?(this.__redo__.forEach(function(e,r){e>=t&&(this.__redo__[r]=++e)},this),this.__redo__.push(t)):h(this,"__redo__",l("c",[t])))}),_onDelete:l(function(t){var e;t>=this.__nextIndex__||(--this.__nextIndex__,this.__redo__&&(-1!==(e=this.__redo__.indexOf(t))&&this.__redo__.splice(e,1),this.__redo__.forEach(function(e,r){e>t&&(this.__redo__[r]=--e)},this)))}),_onClear:l(function(){this.__redo__&&i.call(this.__redo__),this.__nextIndex__=0})}))),h(n.prototype,u.iterator,l(function(){return this}))},{d:138,"d/auto-bind":137,"es5-ext/array/#/clear":157,"es5-ext/object/assign":170,"es5-ext/object/valid-callable":187,"es5-ext/object/valid-value":189,"es6-symbol":203}],199:[function(t,e,r){"use strict";var n=t("es5-ext/function/is-arguments"),i=t("es5-ext/object/is-value"),a=t("es5-ext/string/is-string"),o=t("es6-symbol").iterator,s=Array.isArray;e.exports=function(t){return!!i(t)&&(!!s(t)||(!!a(t)||(!!n(t)||"function"==typeof t[o])))}},{"es5-ext/function/is-arguments":161,"es5-ext/object/is-value":178,"es5-ext/string/is-string":193,"es6-symbol":203}],200:[function(t,e,r){"use strict";var n,i=t("es5-ext/object/set-prototype-of"),a=t("d"),o=t("es6-symbol"),s=t("./"),l=Object.defineProperty;n=e.exports=function(t){if(!(this instanceof n))throw new TypeError("Constructor requires 'new'");t=String(t),s.call(this,t),l(this,"__length__",a("",t.length))},i&&i(n,s),delete n.prototype.constructor,n.prototype=Object.create(s.prototype,{_next:a(function(){if(this.__list__)return this.__nextIndex__=55296&&e<=56319?r+this.__list__[this.__nextIndex__++]:r})}),l(n.prototype,o.toStringTag,a("c","String Iterator"))},{"./":198,d:138,"es5-ext/object/set-prototype-of":184,"es6-symbol":203}],201:[function(t,e,r){"use strict";var n=t("./is-iterable");e.exports=function(t){if(!n(t))throw new TypeError(t+" is not iterable");return t}},{"./is-iterable":199}],202:[function(t,e,r){(function(n,i){!function(t,n){"object"==typeof r&&"undefined"!=typeof e?e.exports=n():t.ES6Promise=n()}(this,function(){"use strict";function e(t){return"function"==typeof t}var r=Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},a=0,o=void 0,s=void 0,l=function(t,e){g[a]=t,g[a+1]=e,2===(a+=2)&&(s?s(m):_())};var c="undefined"!=typeof window?window:void 0,u=c||{},h=u.MutationObserver||u.WebKitMutationObserver,f="undefined"==typeof self&&"undefined"!=typeof n&&"[object process]"==={}.toString.call(n),p="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function d(){var t=setTimeout;return function(){return t(m,1)}}var g=new Array(1e3);function m(){for(var t=0;t0&&this._events[t].length>r&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace()),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(t,e){if(!i(e))throw TypeError("listener must be a function");var r=!1;function n(){this.removeListener(t,n),r||(r=!0,e.apply(this,arguments))}return n.listener=e,this.on(t,n),this},n.prototype.removeListener=function(t,e){var r,n,o,s;if(!i(e))throw TypeError("listener must be a function");if(!this._events||!this._events[t])return this;if(o=(r=this._events[t]).length,n=-1,r===e||i(r.listener)&&r.listener===e)delete this._events[t],this._events.removeListener&&this.emit("removeListener",t,e);else if(a(r)){for(s=o;s-- >0;)if(r[s]===e||r[s].listener&&r[s].listener===e){n=s;break}if(n<0)return this;1===r.length?(r.length=0,delete this._events[t]):r.splice(n,1),this._events.removeListener&&this.emit("removeListener",t,e)}return this},n.prototype.removeAllListeners=function(t){var e,r;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)"removeListener"!==e&&this.removeAllListeners(e);return this.removeAllListeners("removeListener"),this._events={},this}if(i(r=this._events[t]))this.removeListener(t,r);else if(r)for(;r.length;)this.removeListener(t,r[r.length-1]);return delete this._events[t],this},n.prototype.listeners=function(t){return this._events&&this._events[t]?i(this._events[t])?[this._events[t]]:this._events[t].slice():[]},n.prototype.listenerCount=function(t){if(this._events){var e=this._events[t];if(i(e))return 1;if(e)return e.length}return 0},n.listenerCount=function(t,e){return t.listenerCount(e)}},{}],213:[function(t,e,r){"use strict";e.exports=function(t,e,r){var n=e||0,i=r||1;return[[t[12]+t[0],t[13]+t[1],t[14]+t[2],t[15]+t[3]],[t[12]-t[0],t[13]-t[1],t[14]-t[2],t[15]-t[3]],[t[12]+t[4],t[13]+t[5],t[14]+t[6],t[15]+t[7]],[t[12]-t[4],t[13]-t[5],t[14]-t[6],t[15]-t[7]],[n*t[12]+t[8],n*t[13]+t[9],n*t[14]+t[10],n*t[15]+t[11]],[i*t[12]-t[8],i*t[13]-t[9],i*t[14]-t[10],i*t[15]-t[11]]]}},{}],214:[function(t,e,r){"use strict";e.exports=function(t){var e=typeof t;if("string"===e){var r=t;if(0===(t=+t)&&function(t){for(var e,r=t.length,n=0;n13)&&32!==e&&133!==e&&160!==e&&5760!==e&&6158!==e&&(e<8192||e>8205)&&8232!==e&&8233!==e&&8239!==e&&8287!==e&&8288!==e&&12288!==e&&65279!==e)return!1;return!0}(r))return!1}else if("number"!==e)return!1;return t-t<1}},{}],215:[function(t,e,r){"use strict";e.exports=function(t,e,r){switch(arguments.length){case 0:return new o([0],[0],0);case 1:if("number"==typeof t){var n=l(t);return new o(n,n,0)}return new o(t,l(t.length),0);case 2:if("number"==typeof e){var n=l(t.length);return new o(t,n,+e)}r=0;case 3:if(t.length!==e.length)throw new Error("state and velocity lengths must match");return new o(t,e,r)}};var n=t("cubic-hermite"),i=t("binary-search-bounds");function a(t,e,r){return Math.min(e,Math.max(t,r))}function o(t,e,r){this.dimension=t.length,this.bounds=[new Array(this.dimension),new Array(this.dimension)];for(var n=0;n=r-1){f=l.length-1;var d=t-e[r-1];for(p=0;p=r-1)for(var u=s.length-1,h=(e[r-1],0);h=0;--r)if(t[--e])return!1;return!0},s.jump=function(t){var e=this.lastT(),r=this.dimension;if(!(t0;--h)n.push(a(l[h-1],c[h-1],arguments[h])),i.push(0)}},s.push=function(t){var e=this.lastT(),r=this.dimension;if(!(t1e-6?1/s:0;this._time.push(t);for(var f=r;f>0;--f){var p=a(c[f-1],u[f-1],arguments[f]);n.push(p),i.push((p-n[o++])*h)}}},s.set=function(t){var e=this.dimension;if(!(t0;--l)r.push(a(o[l-1],s[l-1],arguments[l])),n.push(0)}},s.move=function(t){var e=this.lastT(),r=this.dimension;if(!(t<=e||arguments.length!==r+1)){var n=this._state,i=this._velocity,o=n.length-this.dimension,s=this.bounds,l=s[0],c=s[1],u=t-e,h=u>1e-6?1/u:0;this._time.push(t);for(var f=r;f>0;--f){var p=arguments[f];n.push(a(l[f-1],c[f-1],n[o++]+p)),i.push(p*h)}}},s.idle=function(t){var e=this.lastT();if(!(t=0;--h)n.push(a(l[h],c[h],n[o]+u*i[o])),i.push(0),o+=1}}},{"binary-search-bounds":79,"cubic-hermite":132}],216:[function(t,e,r){var n=t("dtype");e.exports=function(t,e,r){if(!t)throw new TypeError("must specify data as first parameter");if(r=0|+(r||0),Array.isArray(t)&&Array.isArray(t[0])){var i=t[0].length,a=t.length*i;e&&"string"!=typeof e||(e=new(n(e||"float32"))(a+r));var o=e.length-r;if(a!==o)throw new Error("source length "+a+" ("+i+"x"+t.length+") does not match destination length "+o);for(var s=0,l=r;se[0]-o[0]/2&&(f=o[0]/2,p+=o[1]);return r}},{"css-font/stringify":129}],218:[function(t,e,r){"use strict";function n(t,e){e||(e={}),("string"==typeof t||Array.isArray(t))&&(e.family=t);var r=Array.isArray(e.family)?e.family.join(", "):e.family;if(!r)throw Error("`family` must be defined");var s=e.size||e.fontSize||e.em||48,l=e.weight||e.fontWeight||"",c=(t=[e.style||e.fontStyle||"",l,s].join(" ")+"px "+r,e.origin||"top");if(n.cache[r]&&s<=n.cache[r].em)return i(n.cache[r],c);var u=e.canvas||n.canvas,h=u.getContext("2d"),f={upper:void 0!==e.upper?e.upper:"H",lower:void 0!==e.lower?e.lower:"x",descent:void 0!==e.descent?e.descent:"p",ascent:void 0!==e.ascent?e.ascent:"h",tittle:void 0!==e.tittle?e.tittle:"i",overshoot:void 0!==e.overshoot?e.overshoot:"O"},p=Math.ceil(1.5*s);u.height=p,u.width=.5*p,h.font=t;var d={top:0};h.clearRect(0,0,p,p),h.textBaseline="top",h.fillStyle="black",h.fillText("H",0,0);var g=a(h.getImageData(0,0,p,p));h.clearRect(0,0,p,p),h.textBaseline="bottom",h.fillText("H",0,p);var m=a(h.getImageData(0,0,p,p));d.lineHeight=d.bottom=p-m+g,h.clearRect(0,0,p,p),h.textBaseline="alphabetic",h.fillText("H",0,p);var v=p-a(h.getImageData(0,0,p,p))-1+g;d.baseline=d.alphabetic=v,h.clearRect(0,0,p,p),h.textBaseline="middle",h.fillText("H",0,.5*p);var y=a(h.getImageData(0,0,p,p));d.median=d.middle=p-y-1+g-.5*p,h.clearRect(0,0,p,p),h.textBaseline="hanging",h.fillText("H",0,.5*p);var x=a(h.getImageData(0,0,p,p));d.hanging=p-x-1+g-.5*p,h.clearRect(0,0,p,p),h.textBaseline="ideographic",h.fillText("H",0,p);var b=a(h.getImageData(0,0,p,p));if(d.ideographic=p-b-1+g,f.upper&&(h.clearRect(0,0,p,p),h.textBaseline="top",h.fillText(f.upper,0,0),d.upper=a(h.getImageData(0,0,p,p)),d.capHeight=d.baseline-d.upper),f.lower&&(h.clearRect(0,0,p,p),h.textBaseline="top",h.fillText(f.lower,0,0),d.lower=a(h.getImageData(0,0,p,p)),d.xHeight=d.baseline-d.lower),f.tittle&&(h.clearRect(0,0,p,p),h.textBaseline="top",h.fillText(f.tittle,0,0),d.tittle=a(h.getImageData(0,0,p,p))),f.ascent&&(h.clearRect(0,0,p,p),h.textBaseline="top",h.fillText(f.ascent,0,0),d.ascent=a(h.getImageData(0,0,p,p))),f.descent&&(h.clearRect(0,0,p,p),h.textBaseline="top",h.fillText(f.descent,0,0),d.descent=o(h.getImageData(0,0,p,p))),f.overshoot){h.clearRect(0,0,p,p),h.textBaseline="top",h.fillText(f.overshoot,0,0);var _=o(h.getImageData(0,0,p,p));d.overshoot=_-v}for(var w in d)d[w]/=s;return d.em=s,n.cache[r]=d,i(d,c)}function i(t,e){var r={};for(var n in"string"==typeof e&&(e=t[e]),t)"em"!==n&&(r[n]=t[n]-e);return r}function a(t){for(var e=t.height,r=t.data,n=3;n0;n-=4)if(0!==r[n])return Math.floor(.25*(n-3)/e)}e.exports=n,n.canvas=document.createElement("canvas"),n.cache={}},{}],219:[function(t,e,r){"use strict";e.exports=function(t){return new c(t||d,null)};var n=0,i=1;function a(t,e,r,n,i,a){this._color=t,this.key=e,this.value=r,this.left=n,this.right=i,this._count=a}function o(t){return new a(t._color,t.key,t.value,t.left,t.right,t._count)}function s(t,e){return new a(t,e.key,e.value,e.left,e.right,e._count)}function l(t){t._count=1+(t.left?t.left._count:0)+(t.right?t.right._count:0)}function c(t,e){this._compare=t,this.root=e}var u=c.prototype;function h(t,e){this.tree=t,this._stack=e}Object.defineProperty(u,"keys",{get:function(){var t=[];return this.forEach(function(e,r){t.push(e)}),t}}),Object.defineProperty(u,"values",{get:function(){var t=[];return this.forEach(function(e,r){t.push(r)}),t}}),Object.defineProperty(u,"length",{get:function(){return this.root?this.root._count:0}}),u.insert=function(t,e){for(var r=this._compare,o=this.root,u=[],h=[];o;){var f=r(t,o.key);u.push(o),h.push(f),o=f<=0?o.left:o.right}u.push(new a(n,t,e,null,null,1));for(var p=u.length-2;p>=0;--p){o=u[p];h[p]<=0?u[p]=new a(o._color,o.key,o.value,u[p+1],o.right,o._count+1):u[p]=new a(o._color,o.key,o.value,o.left,u[p+1],o._count+1)}for(p=u.length-1;p>1;--p){var d=u[p-1];o=u[p];if(d._color===i||o._color===i)break;var g=u[p-2];if(g.left===d)if(d.left===o){if(!(m=g.right)||m._color!==n){if(g._color=n,g.left=d.right,d._color=i,d.right=g,u[p-2]=d,u[p-1]=o,l(g),l(d),p>=3)(v=u[p-3]).left===g?v.left=d:v.right=d;break}d._color=i,g.right=s(i,m),g._color=n,p-=1}else{if(!(m=g.right)||m._color!==n){if(d.right=o.left,g._color=n,g.left=o.right,o._color=i,o.left=d,o.right=g,u[p-2]=o,u[p-1]=d,l(g),l(d),l(o),p>=3)(v=u[p-3]).left===g?v.left=o:v.right=o;break}d._color=i,g.right=s(i,m),g._color=n,p-=1}else if(d.right===o){if(!(m=g.left)||m._color!==n){if(g._color=n,g.right=d.left,d._color=i,d.left=g,u[p-2]=d,u[p-1]=o,l(g),l(d),p>=3)(v=u[p-3]).right===g?v.right=d:v.left=d;break}d._color=i,g.left=s(i,m),g._color=n,p-=1}else{var m;if(!(m=g.left)||m._color!==n){var v;if(d.left=o.right,g._color=n,g.right=o.left,o._color=i,o.right=d,o.left=g,u[p-2]=o,u[p-1]=d,l(g),l(d),l(o),p>=3)(v=u[p-3]).right===g?v.right=o:v.left=o;break}d._color=i,g.left=s(i,m),g._color=n,p-=1}}return u[0]._color=i,new c(r,u[0])},u.forEach=function(t,e,r){if(this.root)switch(arguments.length){case 1:return function t(e,r){var n;if(r.left&&(n=t(e,r.left)))return n;return(n=e(r.key,r.value))||(r.right?t(e,r.right):void 0)}(t,this.root);case 2:return function t(e,r,n,i){if(r(e,i.key)<=0){var a;if(i.left&&(a=t(e,r,n,i.left)))return a;if(a=n(i.key,i.value))return a}if(i.right)return t(e,r,n,i.right)}(e,this._compare,t,this.root);case 3:if(this._compare(e,r)>=0)return;return function t(e,r,n,i,a){var o,s=n(e,a.key),l=n(r,a.key);if(s<=0){if(a.left&&(o=t(e,r,n,i,a.left)))return o;if(l>0&&(o=i(a.key,a.value)))return o}if(l>0&&a.right)return t(e,r,n,i,a.right)}(e,r,this._compare,t,this.root)}},Object.defineProperty(u,"begin",{get:function(){for(var t=[],e=this.root;e;)t.push(e),e=e.left;return new h(this,t)}}),Object.defineProperty(u,"end",{get:function(){for(var t=[],e=this.root;e;)t.push(e),e=e.right;return new h(this,t)}}),u.at=function(t){if(t<0)return new h(this,[]);for(var e=this.root,r=[];;){if(r.push(e),e.left){if(t=e.right._count)break;e=e.right}return new h(this,[])},u.ge=function(t){for(var e=this._compare,r=this.root,n=[],i=0;r;){var a=e(t,r.key);n.push(r),a<=0&&(i=n.length),r=a<=0?r.left:r.right}return n.length=i,new h(this,n)},u.gt=function(t){for(var e=this._compare,r=this.root,n=[],i=0;r;){var a=e(t,r.key);n.push(r),a<0&&(i=n.length),r=a<0?r.left:r.right}return n.length=i,new h(this,n)},u.lt=function(t){for(var e=this._compare,r=this.root,n=[],i=0;r;){var a=e(t,r.key);n.push(r),a>0&&(i=n.length),r=a<=0?r.left:r.right}return n.length=i,new h(this,n)},u.le=function(t){for(var e=this._compare,r=this.root,n=[],i=0;r;){var a=e(t,r.key);n.push(r),a>=0&&(i=n.length),r=a<0?r.left:r.right}return n.length=i,new h(this,n)},u.find=function(t){for(var e=this._compare,r=this.root,n=[];r;){var i=e(t,r.key);if(n.push(r),0===i)return new h(this,n);r=i<=0?r.left:r.right}return new h(this,[])},u.remove=function(t){var e=this.find(t);return e?e.remove():this},u.get=function(t){for(var e=this._compare,r=this.root;r;){var n=e(t,r.key);if(0===n)return r.value;r=n<=0?r.left:r.right}};var f=h.prototype;function p(t,e){t.key=e.key,t.value=e.value,t.left=e.left,t.right=e.right,t._color=e._color,t._count=e._count}function d(t,e){return te?1:0}Object.defineProperty(f,"valid",{get:function(){return this._stack.length>0}}),Object.defineProperty(f,"node",{get:function(){return this._stack.length>0?this._stack[this._stack.length-1]:null},enumerable:!0}),f.clone=function(){return new h(this.tree,this._stack.slice())},f.remove=function(){var t=this._stack;if(0===t.length)return this.tree;var e=new Array(t.length),r=t[t.length-1];e[e.length-1]=new a(r._color,r.key,r.value,r.left,r.right,r._count);for(var u=t.length-2;u>=0;--u){(r=t[u]).left===t[u+1]?e[u]=new a(r._color,r.key,r.value,e[u+1],r.right,r._count):e[u]=new a(r._color,r.key,r.value,r.left,e[u+1],r._count)}if((r=e[e.length-1]).left&&r.right){var h=e.length;for(r=r.left;r.right;)e.push(r),r=r.right;var f=e[h-1];e.push(new a(r._color,f.key,f.value,r.left,r.right,r._count)),e[h-1].key=r.key,e[h-1].value=r.value;for(u=e.length-2;u>=h;--u)r=e[u],e[u]=new a(r._color,r.key,r.value,r.left,e[u+1],r._count);e[h-1].left=e[h]}if((r=e[e.length-1])._color===n){var d=e[e.length-2];d.left===r?d.left=null:d.right===r&&(d.right=null),e.pop();for(u=0;u=0;--u){if(e=t[u],0===u)return void(e._color=i);if((r=t[u-1]).left===e){if((a=r.right).right&&a.right._color===n)return c=(a=r.right=o(a)).right=o(a.right),r.right=a.left,a.left=r,a.right=c,a._color=r._color,e._color=i,r._color=i,c._color=i,l(r),l(a),u>1&&((h=t[u-2]).left===r?h.left=a:h.right=a),void(t[u-1]=a);if(a.left&&a.left._color===n)return c=(a=r.right=o(a)).left=o(a.left),r.right=c.left,a.left=c.right,c.left=r,c.right=a,c._color=r._color,r._color=i,a._color=i,e._color=i,l(r),l(a),l(c),u>1&&((h=t[u-2]).left===r?h.left=c:h.right=c),void(t[u-1]=c);if(a._color===i){if(r._color===n)return r._color=i,void(r.right=s(n,a));r.right=s(n,a);continue}a=o(a),r.right=a.left,a.left=r,a._color=r._color,r._color=n,l(r),l(a),u>1&&((h=t[u-2]).left===r?h.left=a:h.right=a),t[u-1]=a,t[u]=r,u+11&&((h=t[u-2]).right===r?h.right=a:h.left=a),void(t[u-1]=a);if(a.right&&a.right._color===n)return c=(a=r.left=o(a)).right=o(a.right),r.left=c.right,a.right=c.left,c.right=r,c.left=a,c._color=r._color,r._color=i,a._color=i,e._color=i,l(r),l(a),l(c),u>1&&((h=t[u-2]).right===r?h.right=c:h.left=c),void(t[u-1]=c);if(a._color===i){if(r._color===n)return r._color=i,void(r.left=s(n,a));r.left=s(n,a);continue}var h;a=o(a),r.left=a.right,a.right=r,a._color=r._color,r._color=n,l(r),l(a),u>1&&((h=t[u-2]).right===r?h.right=a:h.left=a),t[u-1]=a,t[u]=r,u+10)return this._stack[this._stack.length-1].key},enumerable:!0}),Object.defineProperty(f,"value",{get:function(){if(this._stack.length>0)return this._stack[this._stack.length-1].value},enumerable:!0}),Object.defineProperty(f,"index",{get:function(){var t=0,e=this._stack;if(0===e.length){var r=this.tree.root;return r?r._count:0}e[e.length-1].left&&(t=e[e.length-1].left._count);for(var n=e.length-2;n>=0;--n)e[n+1]===e[n].right&&(++t,e[n].left&&(t+=e[n].left._count));return t},enumerable:!0}),f.next=function(){var t=this._stack;if(0!==t.length){var e=t[t.length-1];if(e.right)for(e=e.right;e;)t.push(e),e=e.left;else for(t.pop();t.length>0&&t[t.length-1].right===e;)e=t[t.length-1],t.pop()}},Object.defineProperty(f,"hasNext",{get:function(){var t=this._stack;if(0===t.length)return!1;if(t[t.length-1].right)return!0;for(var e=t.length-1;e>0;--e)if(t[e-1].left===t[e])return!0;return!1}}),f.update=function(t){var e=this._stack;if(0===e.length)throw new Error("Can't update empty node!");var r=new Array(e.length),n=e[e.length-1];r[r.length-1]=new a(n._color,n.key,t,n.left,n.right,n._count);for(var i=e.length-2;i>=0;--i)(n=e[i]).left===e[i+1]?r[i]=new a(n._color,n.key,n.value,r[i+1],n.right,n._count):r[i]=new a(n._color,n.key,n.value,n.left,r[i+1],n._count);return new c(this.tree._compare,r[0])},f.prev=function(){var t=this._stack;if(0!==t.length){var e=t[t.length-1];if(e.left)for(e=e.left;e;)t.push(e),e=e.right;else for(t.pop();t.length>0&&t[t.length-1].left===e;)e=t[t.length-1],t.pop()}},Object.defineProperty(f,"hasPrev",{get:function(){var t=this._stack;if(0===t.length)return!1;if(t[t.length-1].left)return!0;for(var e=t.length-1;e>0;--e)if(t[e-1].right===t[e])return!0;return!1}})},{}],220:[function(t,e,r){var n=[.9999999999998099,676.5203681218851,-1259.1392167224028,771.3234287776531,-176.6150291621406,12.507343278686905,-.13857109526572012,9984369578019572e-21,1.5056327351493116e-7],i=607/128,a=[.9999999999999971,57.15623566586292,-59.59796035547549,14.136097974741746,-.4919138160976202,3399464998481189e-20,4652362892704858e-20,-9837447530487956e-20,.0001580887032249125,-.00021026444172410488,.00021743961811521265,-.0001643181065367639,8441822398385275e-20,-26190838401581408e-21,36899182659531625e-22];function o(t){if(t<0)return Number("0/0");for(var e=a[0],r=a.length-1;r>0;--r)e+=a[r]/(t+r);var n=t+i+.5;return.5*Math.log(2*Math.PI)+(t+.5)*Math.log(n)-n+Math.log(e)-Math.log(t)}e.exports=function t(e){if(e<.5)return Math.PI/(Math.sin(Math.PI*e)*t(1-e));if(e>100)return Math.exp(o(e));e-=1;for(var r=n[0],i=1;i<9;i++)r+=n[i]/(e+i);var a=e+7+.5;return Math.sqrt(2*Math.PI)*Math.pow(a,e+.5)*Math.exp(-a)*r},e.exports.log=o},{}],221:[function(t,e,r){e.exports=function(t,e){if("string"!=typeof t)throw new TypeError("must specify type string");if(e=e||{},"undefined"==typeof document&&!e.canvas)return null;var r=e.canvas||document.createElement("canvas");"number"==typeof e.width&&(r.width=e.width);"number"==typeof e.height&&(r.height=e.height);var n,i=e;try{var a=[t];0===t.indexOf("webgl")&&a.push("experimental-"+t);for(var o=0;o0?(p[u]=-1,d[u]=0):(p[u]=0,d[u]=1)}}var g=[0,0,0],m={model:l,view:l,projection:l};h.isOpaque=function(){return!0},h.isTransparent=function(){return!1},h.drawTransparent=function(t){};var v=[0,0,0],y=[0,0,0],x=[0,0,0];h.draw=function(t){t=t||m;for(var e=this.gl,r=t.model||l,n=t.view||l,i=t.projection||l,a=this.bounds,s=o(r,n,i,a),u=s.cubeEdges,h=s.axis,f=n[12],b=n[13],_=n[14],w=n[15],k=this.pixelRatio*(i[3]*f+i[7]*b+i[11]*_+i[15]*w)/e.drawingBufferHeight,M=0;M<3;++M)this.lastCubeProps.cubeEdges[M]=u[M],this.lastCubeProps.axis[M]=h[M];var A=p;for(M=0;M<3;++M)d(p[M],M,this.bounds,u,h);e=this.gl;var T=g;for(M=0;M<3;++M)this.backgroundEnable[M]?T[M]=h[M]:T[M]=0;this._background.draw(r,n,i,a,T,this.backgroundColor),this._lines.bind(r,n,i,this);for(M=0;M<3;++M){var S=[0,0,0];h[M]>0?S[M]=a[1][M]:S[M]=a[0][M];for(var E=0;E<2;++E){var C=(M+1+E)%3,L=(M+1+(1^E))%3;this.gridEnable[C]&&this._lines.drawGrid(C,L,this.bounds,S,this.gridColor[C],this.gridWidth[C]*this.pixelRatio)}for(E=0;E<2;++E){C=(M+1+E)%3,L=(M+1+(1^E))%3;this.zeroEnable[L]&&a[0][L]<=0&&a[1][L]>=0&&this._lines.drawZero(C,L,this.bounds,S,this.zeroLineColor[L],this.zeroLineWidth[L]*this.pixelRatio)}}for(M=0;M<3;++M){this.lineEnable[M]&&this._lines.drawAxisLine(M,this.bounds,A[M].primalOffset,this.lineColor[M],this.lineWidth[M]*this.pixelRatio),this.lineMirror[M]&&this._lines.drawAxisLine(M,this.bounds,A[M].mirrorOffset,this.lineColor[M],this.lineWidth[M]*this.pixelRatio);var z=c(v,A[M].primalMinor),P=c(y,A[M].mirrorMinor),I=this.lineTickLength;for(E=0;E<3;++E){var O=k/r[5*E];z[E]*=I[E]*O,P[E]*=I[E]*O}this.lineTickEnable[M]&&this._lines.drawAxisTicks(M,A[M].primalOffset,z,this.lineTickColor[M],this.lineTickWidth[M]*this.pixelRatio),this.lineTickMirror[M]&&this._lines.drawAxisTicks(M,A[M].mirrorOffset,P,this.lineTickColor[M],this.lineTickWidth[M]*this.pixelRatio)}this._lines.unbind(),this._text.bind(r,n,i,this.pixelRatio);for(M=0;M<3;++M){var D=A[M].primalMinor,R=c(x,A[M].primalOffset);for(E=0;E<3;++E)this.lineTickEnable[M]&&(R[E]+=k*D[E]*Math.max(this.lineTickLength[E],0)/r[5*E]);if(this.tickEnable[M]){for(E=0;E<3;++E)R[E]+=k*D[E]*this.tickPad[E]/r[5*E];this._text.drawTicks(M,this.tickSize[M],this.tickAngle[M],R,this.tickColor[M])}if(this.labelEnable[M]){for(E=0;E<3;++E)R[E]+=k*D[E]*this.labelPad[E]/r[5*E];R[M]+=.5*(a[0][M]+a[1][M]),this._text.drawLabel(M,this.labelSize[M],this.labelAngle[M],R,this.labelColor[M])}}this._text.unbind()},h.dispose=function(){this._text.dispose(),this._lines.dispose(),this._background.dispose(),this._lines=null,this._text=null,this._background=null,this.gl=null}},{"./lib/background.js":223,"./lib/cube.js":224,"./lib/lines.js":225,"./lib/text.js":227,"./lib/ticks.js":228}],223:[function(t,e,r){"use strict";e.exports=function(t){for(var e=[],r=[],s=0,l=0;l<3;++l)for(var c=(l+1)%3,u=(l+2)%3,h=[0,0,0],f=[0,0,0],p=-1;p<=1;p+=2){r.push(s,s+2,s+1,s+1,s+2,s+3),h[l]=p,f[l]=p;for(var d=-1;d<=1;d+=2){h[c]=d;for(var g=-1;g<=1;g+=2)h[u]=g,e.push(h[0],h[1],h[2],f[0],f[1],f[2]),s+=1}var m=c;c=u,u=m}var v=n(t,new Float32Array(e)),y=n(t,new Uint16Array(r),t.ELEMENT_ARRAY_BUFFER),x=i(t,[{buffer:v,type:t.FLOAT,size:3,offset:0,stride:24},{buffer:v,type:t.FLOAT,size:3,offset:12,stride:24}],y),b=a(t);return b.attributes.position.location=0,b.attributes.normal.location=1,new o(t,v,x,b)};var n=t("gl-buffer"),i=t("gl-vao"),a=t("./shaders").bg;function o(t,e,r,n){this.gl=t,this.buffer=e,this.vao=r,this.shader=n}var s=o.prototype;s.draw=function(t,e,r,n,i,a){for(var o=!1,s=0;s<3;++s)o=o||i[s];if(o){var l=this.gl;l.enable(l.POLYGON_OFFSET_FILL),l.polygonOffset(1,2),this.shader.bind(),this.shader.uniforms={model:t,view:e,projection:r,bounds:n,enable:i,colors:a},this.vao.bind(),this.vao.draw(this.gl.TRIANGLES,36),this.vao.unbind(),l.disable(l.POLYGON_OFFSET_FILL)}},s.dispose=function(){this.vao.dispose(),this.buffer.dispose(),this.shader.dispose()}},{"./shaders":226,"gl-buffer":230,"gl-vao":308}],224:[function(t,e,r){"use strict";e.exports=function(t,e,r,a){i(s,e,t),i(s,r,s);for(var p=0,y=0;y<2;++y){u[2]=a[y][2];for(var x=0;x<2;++x){u[1]=a[x][1];for(var b=0;b<2;++b)u[0]=a[b][0],f(l[p],u,s),p+=1}}for(var _=-1,y=0;y<8;++y){for(var w=l[y][3],k=0;k<3;++k)c[y][k]=l[y][k]/w;w<0&&(_<0?_=y:c[y][2]S&&(_|=1<S&&(_|=1<c[y][1]&&(D=y));for(var R=-1,y=0;y<3;++y){var B=D^1<c[F][0]&&(F=B)}}var N=g;N[0]=N[1]=N[2]=0,N[n.log2(R^D)]=D&R,N[n.log2(D^F)]=D&F;var j=7^F;j===_||j===O?(j=7^R,N[n.log2(F^j)]=j&F):N[n.log2(R^j)]=j&R;for(var V=m,U=_,M=0;M<3;++M)V[M]=U&1< 0.0) {\n vec3 nPosition = mix(bounds[0], bounds[1], 0.5 * (position + 1.0));\n gl_Position = projection * view * model * vec4(nPosition, 1.0);\n } else {\n gl_Position = vec4(0,0,0,0);\n }\n colorChannel = abs(normal);\n}"]),u=n(["precision mediump float;\n#define GLSLIFY 1\n\nuniform vec4 colors[3];\n\nvarying vec3 colorChannel;\n\nvoid main() {\n gl_FragColor = colorChannel.x * colors[0] + \n colorChannel.y * colors[1] +\n colorChannel.z * colors[2];\n}"]);r.bg=function(t){return i(t,c,u,null,[{name:"position",type:"vec3"},{name:"normal",type:"vec3"}])}},{"gl-shader":287,glslify:377}],227:[function(t,e,r){(function(r){"use strict";e.exports=function(t,e,r,a,s,l){var u=n(t),h=i(t,[{buffer:u,size:3}]),f=o(t);f.attributes.position.location=0;var p=new c(t,f,u,h);return p.update(e,r,a,s,l),p};var n=t("gl-buffer"),i=t("gl-vao"),a=t("vectorize-text"),o=t("./shaders").text,s=window||r.global||{},l=s.__TEXT_CACHE||{};s.__TEXT_CACHE={};function c(t,e,r,n){this.gl=t,this.shader=e,this.buffer=r,this.vao=n,this.tickOffset=this.tickCount=this.labelOffset=this.labelCount=null}var u=c.prototype,h=[0,0];u.bind=function(t,e,r,n){this.vao.bind(),this.shader.bind();var i=this.shader.uniforms;i.model=t,i.view=e,i.projection=r,i.pixelScale=n,h[0]=this.gl.drawingBufferWidth,h[1]=this.gl.drawingBufferHeight,this.shader.uniforms.resolution=h},u.unbind=function(){this.vao.unbind()},u.update=function(t,e,r,n,i){this.gl;var o=[];function s(t,e,r,n){var i=l[r];i||(i=l[r]={});var s=i[e];s||(s=i[e]=function(t,e){try{return a(t,e)}catch(t){return console.warn("error vectorizing text:",t),{cells:[],positions:[]}}}(e,{triangles:!0,font:r,textAlign:"center",textBaseline:"middle"}));for(var c=(n||12)/12,u=s.positions,h=s.cells,f=0,p=h.length;f=0;--g){var m=u[d[g]];o.push(c*m[0],-c*m[1],t)}}for(var c=[0,0,0],u=[0,0,0],h=[0,0,0],f=[0,0,0],p=0;p<3;++p){h[p]=o.length/3|0,s(.5*(t[0][p]+t[1][p]),e[p],r),f[p]=(o.length/3|0)-h[p],c[p]=o.length/3|0;for(var d=0;d=0&&(i=r.length-n-1);var a=Math.pow(10,i),o=Math.round(t*e*a),s=o+"";if(s.indexOf("e")>=0)return s;var l=o/a,c=o%a;o<0?(l=0|-Math.ceil(l),c=0|-c):(l=0|Math.floor(l),c|=0);var u=""+l;if(o<0&&(u="-"+u),i){for(var h=""+c;h.length=t[0][i];--o)a.push({x:o*e[i],text:n(e[i],o)});r.push(a)}return r},r.equal=function(t,e){for(var r=0;r<3;++r){if(t[r].length!==e[r].length)return!1;for(var n=0;nr)throw new Error("gl-buffer: If resizing buffer, must not specify offset");return t.bufferSubData(e,a,i),r}function u(t,e){for(var r=n.malloc(t.length,e),i=t.length,a=0;a=0;--n){if(e[n]!==r)return!1;r*=t[n]}return!0}(t.shape,t.stride))0===t.offset&&t.data.length===t.shape[0]?this.length=c(this.gl,this.type,this.length,this.usage,t.data,e):this.length=c(this.gl,this.type,this.length,this.usage,t.data.subarray(t.offset,t.shape[0]),e);else{var s=n.malloc(t.size,r),l=a(s,t.shape);i.assign(l,t),this.length=c(this.gl,this.type,this.length,this.usage,e<0?s:s.subarray(0,t.size),e),n.free(s)}}else if(Array.isArray(t)){var h;h=this.type===this.gl.ELEMENT_ARRAY_BUFFER?u(t,"uint16"):u(t,"float32"),this.length=c(this.gl,this.type,this.length,this.usage,e<0?h:h.subarray(0,t.length),e),n.free(h)}else if("object"==typeof t&&"number"==typeof t.length)this.length=c(this.gl,this.type,this.length,this.usage,t,e);else{if("number"!=typeof t&&void 0!==t)throw new Error("gl-buffer: Invalid data type");if(e>=0)throw new Error("gl-buffer: Cannot specify offset when resizing buffer");(t|=0)<=0&&(t=1),this.gl.bufferData(this.type,0|t,this.usage),this.length=t}},e.exports=function(t,e,r,n){if(r=r||t.ARRAY_BUFFER,n=n||t.DYNAMIC_DRAW,r!==t.ARRAY_BUFFER&&r!==t.ELEMENT_ARRAY_BUFFER)throw new Error("gl-buffer: Invalid type for webgl buffer, must be either gl.ARRAY_BUFFER or gl.ELEMENT_ARRAY_BUFFER");if(n!==t.DYNAMIC_DRAW&&n!==t.STATIC_DRAW&&n!==t.STREAM_DRAW)throw new Error("gl-buffer: Invalid usage for buffer, must be either gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW");var i=t.createBuffer(),a=new s(t,r,i,0,n);return a.update(e),a}},{ndarray:417,"ndarray-ops":411,"typedarray-pool":507}],231:[function(t,e,r){"use strict";var n=t("gl-vec3"),i=(t("gl-vec4"),function(t,e){for(var r=0;r=e)return r-1;return r}),a=n.create(),o=n.create(),s=function(t,e,r){return tr?r:t},l=function(t,e,r,l){var c=t[0],u=t[1],h=t[2],f=r[0].length,p=r[1].length,d=r[2].length,g=i(r[0],c),m=i(r[1],u),v=i(r[2],h),y=g+1,x=m+1,b=v+1;if(l&&(g=s(g,0,f-1),y=s(y,0,f-1),m=s(m,0,p-1),x=s(x,0,p-1),v=s(v,0,d-1),b=s(b,0,d-1)),g<0||m<0||v<0||y>=f||x>=p||b>=d)return n.create();var _=(c-r[0][g])/(r[0][y]-r[0][g]),w=(u-r[1][m])/(r[1][x]-r[1][m]),k=(h-r[2][v])/(r[2][b]-r[2][v]);(_<0||_>1||isNaN(_))&&(_=0),(w<0||w>1||isNaN(w))&&(w=0),(k<0||k>1||isNaN(k))&&(k=0);var M=v*f*p,A=b*f*p,T=m*f,S=x*f,E=g,C=y,L=e[T+M+E],z=e[T+M+C],P=e[S+M+E],I=e[S+M+C],O=e[T+A+E],D=e[T+A+C],R=e[S+A+E],B=e[S+A+C],F=n.create();return n.lerp(F,L,z,_),n.lerp(a,P,I,_),n.lerp(F,F,a,w),n.lerp(a,O,D,_),n.lerp(o,R,B,_),n.lerp(a,a,o,w),n.lerp(F,F,a,k),F};e.exports=function(t,e){var r;r=t.positions?t.positions:function(t){for(var e=t[0],r=t[1],n=t[2],i=[],a=0;as&&(s=n.length(b)),x&&(y=Math.min(y,2*n.distance(g,_)/(n.length(m)+n.length(b)))),g=_,m=b,v.push(b)}var w=[c,h,p],k=[u,f,d];e&&(e[0]=w,e[1]=k),0===s&&(s=1);var M=1/s;isFinite(y)&&!isNaN(y)||(y=1),o.vectorScale=y;var A=function(t,e,r){var i=n.create();return void 0!==t&&n.set(i,t,e,r),i}(0,1,0),T=t.coneSize||.5;t.absoluteConeSize&&(T=t.absoluteConeSize*M),o.coneScale=T;x=0;for(var S=0;x1.0001)return null;m+=g[u]}if(Math.abs(m-1)>.001)return null;return[h,function(t,e){for(var r=[0,0,0],n=0;n=1},x.isTransparent=function(){return this.opacity<1},x.pickSlots=1,x.setPickBase=function(t){this.pickId=t},x.highlight=function(t){if(t&&this.contourEnable){for(var e=f(this.cells,this.intensity,t.intensity),r=e.cells,n=e.vertexIds,i=e.vertexWeights,a=r.length,o=p.mallocFloat32(6*a),s=0,l=0;l0&&((h=this.triShader).bind(),h.uniforms=s,this.triangleVAO.bind(),e.drawArrays(e.TRIANGLES,0,3*this.triangleCount),this.triangleVAO.unbind());this.edgeCount>0&&this.lineWidth>0&&((h=this.lineShader).bind(),h.uniforms=s,this.edgeVAO.bind(),e.lineWidth(this.lineWidth),e.drawArrays(e.LINES,0,2*this.edgeCount),this.edgeVAO.unbind());this.pointCount>0&&((h=this.pointShader).bind(),h.uniforms=s,this.pointVAO.bind(),e.drawArrays(e.POINTS,0,this.pointCount),this.pointVAO.unbind());this.contourEnable&&this.contourCount>0&&this.contourLineWidth>0&&((h=this.contourShader).bind(),h.uniforms=s,this.contourVAO.bind(),e.drawArrays(e.LINES,0,this.contourCount),this.contourVAO.unbind())},x.drawPick=function(t){t=t||{};for(var e=this.gl,r=t.model||v,n=t.view||v,i=t.projection||v,a=[[-1e6,-1e6,-1e6],[1e6,1e6,1e6]],o=0;o<3;++o)a[0][o]=Math.max(a[0][o],this.clipBounds[0][o]),a[1][o]=Math.min(a[1][o],this.clipBounds[1][o]);this._model=[].slice.call(r),this._view=[].slice.call(n),this._projection=[].slice.call(i),this._resolution=[e.drawingBufferWidth,e.drawingBufferHeight];var s,l={model:r,view:n,projection:i,clipBounds:a,vectorScale:this.vectorScale,coneScale:this.coneScale,coneOffset:this.coneOffset,pickId:this.pickId/255};((s=this.pickShader).bind(),s.uniforms=l,this.triangleCount>0&&(this.triangleVAO.bind(),e.drawArrays(e.TRIANGLES,0,3*this.triangleCount),this.triangleVAO.unbind()),this.edgeCount>0&&(this.edgeVAO.bind(),e.lineWidth(this.lineWidth),e.drawArrays(e.LINES,0,2*this.edgeCount),this.edgeVAO.unbind()),this.pointCount>0)&&((s=this.pointPickShader).bind(),s.uniforms=l,this.pointVAO.bind(),e.drawArrays(e.POINTS,0,this.pointCount),this.pointVAO.unbind())},x.pick=function(t){if(!t)return null;if(t.id!==this.pickId)return null;var e=t.value[0]+256*t.value[1]+65536*t.value[2],r=this.cells[e],n=this.positions[r[1]].slice(0,3);return{index:Math.floor(r[1]/48),position:n,dataCoordinate:n}},x.dispose=function(){this.texture.dispose(),this.triShader.dispose(),this.pickShader.dispose(),this.triangleVAO.dispose(),this.trianglePositions.dispose(),this.triangleVectors.dispose(),this.triangleColors.dispose(),this.triangleUVs.dispose(),this.triangleNormals.dispose(),this.triangleIds.dispose(),this.edgeVAO.dispose(),this.edgePositions.dispose(),this.edgeColors.dispose(),this.edgeUVs.dispose(),this.edgeIds.dispose(),this.pointVAO.dispose(),this.pointPositions.dispose(),this.pointColors.dispose(),this.pointUVs.dispose(),this.pointSizes.dispose(),this.pointIds.dispose(),this.contourVAO.dispose(),this.contourPositions.dispose()},e.exports=function(t,e){1===arguments.length&&(t=(e=t).gl);var r=e.triShader||function(t){var e=n(t,g.vertex,g.fragment,null,g.attributes);return e.attributes.position.location=0,e.attributes.color.location=2,e.attributes.uv.location=3,e.attributes.vector.location=5,e}(t),s=b(t),l=o(t,u(new Uint8Array([255,255,255,255]),[1,1,4]));l.generateMipmap(),l.minFilter=t.LINEAR_MIPMAP_LINEAR,l.magFilter=t.LINEAR;var c=i(t),h=i(t),f=i(t),p=i(t),d=i(t),m=i(t),v=a(t,[{buffer:c,type:t.FLOAT,size:4},{buffer:m,type:t.UNSIGNED_BYTE,size:4,normalized:!0},{buffer:f,type:t.FLOAT,size:4},{buffer:p,type:t.FLOAT,size:2},{buffer:d,type:t.FLOAT,size:3},{buffer:h,type:t.FLOAT,size:3}]),x=i(t),_=i(t),w=i(t),k=i(t),M=a(t,[{buffer:x,type:t.FLOAT,size:3},{buffer:k,type:t.UNSIGNED_BYTE,size:4,normalized:!0},{buffer:_,type:t.FLOAT,size:4},{buffer:w,type:t.FLOAT,size:2}]),A=i(t),T=i(t),S=i(t),E=i(t),C=i(t),L=a(t,[{buffer:A,type:t.FLOAT,size:3},{buffer:C,type:t.UNSIGNED_BYTE,size:4,normalized:!0},{buffer:T,type:t.FLOAT,size:4},{buffer:S,type:t.FLOAT,size:2},{buffer:E,type:t.FLOAT,size:1}]),z=i(t),P=new y(t,l,r,null,null,s,null,null,c,h,m,f,p,d,v,x,k,_,w,M,A,C,T,S,E,L,z,a(t,[{buffer:z,type:t.FLOAT,size:3}]));return P.update(e),P}},{"./closest-point":232,"./shaders":234,colormap:113,"gl-buffer":230,"gl-mat4/invert":254,"gl-mat4/multiply":256,"gl-shader":287,"gl-texture2d":303,"gl-vao":308,ndarray:417,normals:420,"simplicial-complex-contour":479,"typedarray-pool":507}],234:[function(t,e,r){var n=t("glslify"),i=n(["precision mediump float;\n#define GLSLIFY 1\n\nfloat inverse(float m) {\n return 1.0 / m;\n}\n\nmat2 inverse(mat2 m) {\n return mat2(m[1][1],-m[0][1],\n -m[1][0], m[0][0]) / (m[0][0]*m[1][1] - m[0][1]*m[1][0]);\n}\n\nmat3 inverse(mat3 m) {\n float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];\n float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];\n float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];\n\n float b01 = a22 * a11 - a12 * a21;\n float b11 = -a22 * a10 + a12 * a20;\n float b21 = a21 * a10 - a11 * a20;\n\n float det = a00 * b01 + a01 * b11 + a02 * b21;\n\n return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),\n b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),\n b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;\n}\n\nmat4 inverse(mat4 m) {\n float\n a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],\n a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],\n a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],\n a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],\n\n b00 = a00 * a11 - a01 * a10,\n b01 = a00 * a12 - a02 * a10,\n b02 = a00 * a13 - a03 * a10,\n b03 = a01 * a12 - a02 * a11,\n b04 = a01 * a13 - a03 * a11,\n b05 = a02 * a13 - a03 * a12,\n b06 = a20 * a31 - a21 * a30,\n b07 = a20 * a32 - a22 * a30,\n b08 = a20 * a33 - a23 * a30,\n b09 = a21 * a32 - a22 * a31,\n b10 = a21 * a33 - a23 * a31,\n b11 = a22 * a33 - a23 * a32,\n\n det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n return mat4(\n a11 * b11 - a12 * b10 + a13 * b09,\n a02 * b10 - a01 * b11 - a03 * b09,\n a31 * b05 - a32 * b04 + a33 * b03,\n a22 * b04 - a21 * b05 - a23 * b03,\n a12 * b08 - a10 * b11 - a13 * b07,\n a00 * b11 - a02 * b08 + a03 * b07,\n a32 * b02 - a30 * b05 - a33 * b01,\n a20 * b05 - a22 * b02 + a23 * b01,\n a10 * b10 - a11 * b08 + a13 * b06,\n a01 * b08 - a00 * b10 - a03 * b06,\n a30 * b04 - a31 * b02 + a33 * b00,\n a21 * b02 - a20 * b04 - a23 * b00,\n a11 * b07 - a10 * b09 - a12 * b06,\n a00 * b09 - a01 * b07 + a02 * b06,\n a31 * b01 - a30 * b03 - a32 * b00,\n a20 * b03 - a21 * b01 + a22 * b00) / det;\n}\n\nvec3 getOrthogonalVector(vec3 v) {\n // Return up-vector for only-z vector.\n // Return ax + by + cz = 0, a point that lies on the plane that has v as a normal and that isn't (0,0,0).\n // From the above if-statement we have ||a|| > 0 U ||b|| > 0.\n // Assign z = 0, x = -b, y = a:\n // a*-b + b*a + c*0 = -ba + ba + 0 = 0\n if (v.x*v.x > v.z*v.z || v.y*v.y > v.z*v.z) {\n return normalize(vec3(-v.y, v.x, 0.0));\n } else {\n return normalize(vec3(0.0, v.z, -v.y));\n }\n}\n\n// Calculate the cone vertex and normal at the given index.\n//\n// The returned vertex is for a cone with its top at origin and height of 1.0,\n// pointing in the direction of the vector attribute.\n//\n// Each cone is made up of a top vertex, a center base vertex and base perimeter vertices.\n// These vertices are used to make up the triangles of the cone by the following:\n// segment + 0 top vertex\n// segment + 1 perimeter vertex a+1\n// segment + 2 perimeter vertex a\n// segment + 3 center base vertex\n// segment + 4 perimeter vertex a\n// segment + 5 perimeter vertex a+1\n// Where segment is the number of the radial segment * 6 and a is the angle at that radial segment.\n// To go from index to segment, floor(index / 6)\n// To go from segment to angle, 2*pi * (segment/segmentCount)\n// To go from index to segment index, index - (segment*6)\n//\nvec3 getConePosition(vec3 d, float index, float coneOffset, out vec3 normal) {\n\n const float segmentCount = 8.0;\n\n index = mod(index, segmentCount * 6.0);\n\n float segment = floor(index/6.0);\n float segmentIndex = index - (segment*6.0);\n\n normal = -normalize(d);\n\n if (segmentIndex == 3.0) {\n return mix(vec3(0.0), -d, coneOffset);\n }\n\n // angle = 2pi * ((segment + ((segmentIndex == 1.0 || segmentIndex == 5.0) ? 1.0 : 0.0)) / segmentCount)\n float nextAngle = float(segmentIndex == 1.0 || segmentIndex == 5.0);\n float angle = 2.0 * 3.14159 * ((segment + nextAngle) / segmentCount);\n\n vec3 v1 = mix(d, vec3(0.0), coneOffset);\n vec3 v2 = v1 - d;\n\n vec3 u = getOrthogonalVector(d);\n vec3 v = normalize(cross(u, d));\n\n vec3 x = u * cos(angle) * length(d)*0.25;\n vec3 y = v * sin(angle) * length(d)*0.25;\n vec3 v3 = v2 + x + y;\n if (segmentIndex <= 2.0) {\n vec3 tx = u * sin(angle);\n vec3 ty = v * -cos(angle);\n vec3 tangent = tx + ty;\n normal = normalize(cross(v3 - v1, tangent));\n }\n\n if (segmentIndex == 0.0) {\n return mix(d, vec3(0.0), coneOffset);\n }\n return v3;\n}\n\nattribute vec3 vector;\nattribute vec4 color, position;\nattribute vec2 uv;\nuniform float vectorScale;\nuniform float coneScale;\n\nuniform float coneOffset;\n\nuniform mat4 model\n , view\n , projection;\nuniform vec3 eyePosition\n , lightPosition;\n\nvarying vec3 f_normal\n , f_lightDirection\n , f_eyeDirection\n , f_data;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n // Scale the vector magnitude to stay constant with\n // model & view changes.\n vec3 normal;\n vec4 conePosition = model * vec4(position.xyz, 1.0) + vec4(getConePosition(mat3(model) * ((vectorScale * coneScale) * vector), position.w, coneOffset, normal), 0.0);\n normal = normalize(normal * inverse(mat3(model)));\n\n // vec4 m_position = model * vec4(conePosition, 1.0);\n vec4 t_position = view * conePosition;\n gl_Position = projection * t_position;\n f_color = color; //vec4(position.w, color.r, 0, 0);\n f_normal = normal;\n f_data = conePosition.xyz;\n f_eyeDirection = eyePosition - conePosition.xyz;\n f_lightDirection = lightPosition - conePosition.xyz;\n f_uv = uv;\n}\n"]),a=n(["precision mediump float;\n#define GLSLIFY 1\n\nfloat beckmannDistribution(float x, float roughness) {\n float NdotH = max(x, 0.0001);\n float cos2Alpha = NdotH * NdotH;\n float tan2Alpha = (cos2Alpha - 1.0) / cos2Alpha;\n float roughness2 = roughness * roughness;\n float denom = 3.141592653589793 * roughness2 * cos2Alpha * cos2Alpha;\n return exp(tan2Alpha / roughness2) / denom;\n}\n\nfloat cookTorranceSpecular(\n vec3 lightDirection,\n vec3 viewDirection,\n vec3 surfaceNormal,\n float roughness,\n float fresnel) {\n\n float VdotN = max(dot(viewDirection, surfaceNormal), 0.0);\n float LdotN = max(dot(lightDirection, surfaceNormal), 0.0);\n\n //Half angle vector\n vec3 H = normalize(lightDirection + viewDirection);\n\n //Geometric term\n float NdotH = max(dot(surfaceNormal, H), 0.0);\n float VdotH = max(dot(viewDirection, H), 0.000001);\n float LdotH = max(dot(lightDirection, H), 0.000001);\n float G1 = (2.0 * NdotH * VdotN) / VdotH;\n float G2 = (2.0 * NdotH * LdotN) / LdotH;\n float G = min(1.0, min(G1, G2));\n \n //Distribution term\n float D = beckmannDistribution(NdotH, roughness);\n\n //Fresnel term\n float F = pow(1.0 - VdotN, fresnel);\n\n //Multiply terms and done\n return G * F * D / max(3.14159265 * VdotN, 0.000001);\n}\n\nuniform vec3 clipBounds[2];\nuniform float roughness\n , fresnel\n , kambient\n , kdiffuse\n , kspecular\n , opacity;\nuniform sampler2D texture;\n\nvarying vec3 f_normal\n , f_lightDirection\n , f_eyeDirection\n , f_data;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n //if(any(lessThan(f_data, clipBounds[0])) || \n // any(greaterThan(f_data, clipBounds[1]))) {\n // discard;\n //}\n\n vec3 N = normalize(f_normal);\n vec3 L = normalize(f_lightDirection);\n vec3 V = normalize(f_eyeDirection);\n \n if(!gl_FrontFacing) {\n N = -N;\n }\n\n float specular = cookTorranceSpecular(L, V, N, roughness, fresnel);\n float diffuse = min(kambient + kdiffuse * max(dot(N, L), 0.0), 1.0);\n\n vec4 surfaceColor = texture2D(texture, f_uv);\n vec4 litColor = surfaceColor.a * vec4(diffuse * surfaceColor.rgb + kspecular * vec3(1,1,1) * specular, 1.0);\n\n gl_FragColor = litColor * opacity;\n}"]),o=n(["precision mediump float;\n#define GLSLIFY 1\n\nvec3 getOrthogonalVector(vec3 v) {\n // Return up-vector for only-z vector.\n // Return ax + by + cz = 0, a point that lies on the plane that has v as a normal and that isn't (0,0,0).\n // From the above if-statement we have ||a|| > 0 U ||b|| > 0.\n // Assign z = 0, x = -b, y = a:\n // a*-b + b*a + c*0 = -ba + ba + 0 = 0\n if (v.x*v.x > v.z*v.z || v.y*v.y > v.z*v.z) {\n return normalize(vec3(-v.y, v.x, 0.0));\n } else {\n return normalize(vec3(0.0, v.z, -v.y));\n }\n}\n\n// Calculate the cone vertex and normal at the given index.\n//\n// The returned vertex is for a cone with its top at origin and height of 1.0,\n// pointing in the direction of the vector attribute.\n//\n// Each cone is made up of a top vertex, a center base vertex and base perimeter vertices.\n// These vertices are used to make up the triangles of the cone by the following:\n// segment + 0 top vertex\n// segment + 1 perimeter vertex a+1\n// segment + 2 perimeter vertex a\n// segment + 3 center base vertex\n// segment + 4 perimeter vertex a\n// segment + 5 perimeter vertex a+1\n// Where segment is the number of the radial segment * 6 and a is the angle at that radial segment.\n// To go from index to segment, floor(index / 6)\n// To go from segment to angle, 2*pi * (segment/segmentCount)\n// To go from index to segment index, index - (segment*6)\n//\nvec3 getConePosition(vec3 d, float index, float coneOffset, out vec3 normal) {\n\n const float segmentCount = 8.0;\n\n index = mod(index, segmentCount * 6.0);\n\n float segment = floor(index/6.0);\n float segmentIndex = index - (segment*6.0);\n\n normal = -normalize(d);\n\n if (segmentIndex == 3.0) {\n return mix(vec3(0.0), -d, coneOffset);\n }\n\n // angle = 2pi * ((segment + ((segmentIndex == 1.0 || segmentIndex == 5.0) ? 1.0 : 0.0)) / segmentCount)\n float nextAngle = float(segmentIndex == 1.0 || segmentIndex == 5.0);\n float angle = 2.0 * 3.14159 * ((segment + nextAngle) / segmentCount);\n\n vec3 v1 = mix(d, vec3(0.0), coneOffset);\n vec3 v2 = v1 - d;\n\n vec3 u = getOrthogonalVector(d);\n vec3 v = normalize(cross(u, d));\n\n vec3 x = u * cos(angle) * length(d)*0.25;\n vec3 y = v * sin(angle) * length(d)*0.25;\n vec3 v3 = v2 + x + y;\n if (segmentIndex <= 2.0) {\n vec3 tx = u * sin(angle);\n vec3 ty = v * -cos(angle);\n vec3 tangent = tx + ty;\n normal = normalize(cross(v3 - v1, tangent));\n }\n\n if (segmentIndex == 0.0) {\n return mix(d, vec3(0.0), coneOffset);\n }\n return v3;\n}\n\nattribute vec3 vector;\nattribute vec4 position;\nattribute vec4 id;\n\nuniform mat4 model, view, projection;\n\nuniform float vectorScale;\nuniform float coneScale;\nuniform float coneOffset;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n vec3 normal;\n vec4 conePosition = model * vec4(position.xyz, 1.0) + vec4(getConePosition(mat3(model) * ((vectorScale * coneScale) * vector), position.w, coneOffset, normal), 0.0);\n gl_Position = projection * view * conePosition;\n f_id = id;\n f_position = position.xyz;\n}\n"]),s=n(["precision mediump float;\n#define GLSLIFY 1\n\nuniform vec3 clipBounds[2];\nuniform float pickId;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n if(any(lessThan(f_position, clipBounds[0])) || \n any(greaterThan(f_position, clipBounds[1]))) {\n discard;\n }\n gl_FragColor = vec4(pickId, f_id.xyz);\n}"]);r.meshShader={vertex:i,fragment:a,attributes:[{name:"position",type:"vec4"},{name:"normal",type:"vec3"},{name:"color",type:"vec4"},{name:"uv",type:"vec2"},{name:"vector",type:"vec3"}]},r.pickShader={vertex:o,fragment:s,attributes:[{name:"position",type:"vec4"},{name:"id",type:"vec4"},{name:"vector",type:"vec3"}]}},{glslify:377}],235:[function(t,e,r){e.exports={0:"NONE",1:"ONE",2:"LINE_LOOP",3:"LINE_STRIP",4:"TRIANGLES",5:"TRIANGLE_STRIP",6:"TRIANGLE_FAN",256:"DEPTH_BUFFER_BIT",512:"NEVER",513:"LESS",514:"EQUAL",515:"LEQUAL",516:"GREATER",517:"NOTEQUAL",518:"GEQUAL",519:"ALWAYS",768:"SRC_COLOR",769:"ONE_MINUS_SRC_COLOR",770:"SRC_ALPHA",771:"ONE_MINUS_SRC_ALPHA",772:"DST_ALPHA",773:"ONE_MINUS_DST_ALPHA",774:"DST_COLOR",775:"ONE_MINUS_DST_COLOR",776:"SRC_ALPHA_SATURATE",1024:"STENCIL_BUFFER_BIT",1028:"FRONT",1029:"BACK",1032:"FRONT_AND_BACK",1280:"INVALID_ENUM",1281:"INVALID_VALUE",1282:"INVALID_OPERATION",1285:"OUT_OF_MEMORY",1286:"INVALID_FRAMEBUFFER_OPERATION",2304:"CW",2305:"CCW",2849:"LINE_WIDTH",2884:"CULL_FACE",2885:"CULL_FACE_MODE",2886:"FRONT_FACE",2928:"DEPTH_RANGE",2929:"DEPTH_TEST",2930:"DEPTH_WRITEMASK",2931:"DEPTH_CLEAR_VALUE",2932:"DEPTH_FUNC",2960:"STENCIL_TEST",2961:"STENCIL_CLEAR_VALUE",2962:"STENCIL_FUNC",2963:"STENCIL_VALUE_MASK",2964:"STENCIL_FAIL",2965:"STENCIL_PASS_DEPTH_FAIL",2966:"STENCIL_PASS_DEPTH_PASS",2967:"STENCIL_REF",2968:"STENCIL_WRITEMASK",2978:"VIEWPORT",3024:"DITHER",3042:"BLEND",3088:"SCISSOR_BOX",3089:"SCISSOR_TEST",3106:"COLOR_CLEAR_VALUE",3107:"COLOR_WRITEMASK",3317:"UNPACK_ALIGNMENT",3333:"PACK_ALIGNMENT",3379:"MAX_TEXTURE_SIZE",3386:"MAX_VIEWPORT_DIMS",3408:"SUBPIXEL_BITS",3410:"RED_BITS",3411:"GREEN_BITS",3412:"BLUE_BITS",3413:"ALPHA_BITS",3414:"DEPTH_BITS",3415:"STENCIL_BITS",3553:"TEXTURE_2D",4352:"DONT_CARE",4353:"FASTEST",4354:"NICEST",5120:"BYTE",5121:"UNSIGNED_BYTE",5122:"SHORT",5123:"UNSIGNED_SHORT",5124:"INT",5125:"UNSIGNED_INT",5126:"FLOAT",5386:"INVERT",5890:"TEXTURE",6401:"STENCIL_INDEX",6402:"DEPTH_COMPONENT",6406:"ALPHA",6407:"RGB",6408:"RGBA",6409:"LUMINANCE",6410:"LUMINANCE_ALPHA",7680:"KEEP",7681:"REPLACE",7682:"INCR",7683:"DECR",7936:"VENDOR",7937:"RENDERER",7938:"VERSION",9728:"NEAREST",9729:"LINEAR",9984:"NEAREST_MIPMAP_NEAREST",9985:"LINEAR_MIPMAP_NEAREST",9986:"NEAREST_MIPMAP_LINEAR",9987:"LINEAR_MIPMAP_LINEAR",10240:"TEXTURE_MAG_FILTER",10241:"TEXTURE_MIN_FILTER",10242:"TEXTURE_WRAP_S",10243:"TEXTURE_WRAP_T",10497:"REPEAT",10752:"POLYGON_OFFSET_UNITS",16384:"COLOR_BUFFER_BIT",32769:"CONSTANT_COLOR",32770:"ONE_MINUS_CONSTANT_COLOR",32771:"CONSTANT_ALPHA",32772:"ONE_MINUS_CONSTANT_ALPHA",32773:"BLEND_COLOR",32774:"FUNC_ADD",32777:"BLEND_EQUATION_RGB",32778:"FUNC_SUBTRACT",32779:"FUNC_REVERSE_SUBTRACT",32819:"UNSIGNED_SHORT_4_4_4_4",32820:"UNSIGNED_SHORT_5_5_5_1",32823:"POLYGON_OFFSET_FILL",32824:"POLYGON_OFFSET_FACTOR",32854:"RGBA4",32855:"RGB5_A1",32873:"TEXTURE_BINDING_2D",32926:"SAMPLE_ALPHA_TO_COVERAGE",32928:"SAMPLE_COVERAGE",32936:"SAMPLE_BUFFERS",32937:"SAMPLES",32938:"SAMPLE_COVERAGE_VALUE",32939:"SAMPLE_COVERAGE_INVERT",32968:"BLEND_DST_RGB",32969:"BLEND_SRC_RGB",32970:"BLEND_DST_ALPHA",32971:"BLEND_SRC_ALPHA",33071:"CLAMP_TO_EDGE",33170:"GENERATE_MIPMAP_HINT",33189:"DEPTH_COMPONENT16",33306:"DEPTH_STENCIL_ATTACHMENT",33635:"UNSIGNED_SHORT_5_6_5",33648:"MIRRORED_REPEAT",33901:"ALIASED_POINT_SIZE_RANGE",33902:"ALIASED_LINE_WIDTH_RANGE",33984:"TEXTURE0",33985:"TEXTURE1",33986:"TEXTURE2",33987:"TEXTURE3",33988:"TEXTURE4",33989:"TEXTURE5",33990:"TEXTURE6",33991:"TEXTURE7",33992:"TEXTURE8",33993:"TEXTURE9",33994:"TEXTURE10",33995:"TEXTURE11",33996:"TEXTURE12",33997:"TEXTURE13",33998:"TEXTURE14",33999:"TEXTURE15",34000:"TEXTURE16",34001:"TEXTURE17",34002:"TEXTURE18",34003:"TEXTURE19",34004:"TEXTURE20",34005:"TEXTURE21",34006:"TEXTURE22",34007:"TEXTURE23",34008:"TEXTURE24",34009:"TEXTURE25",34010:"TEXTURE26",34011:"TEXTURE27",34012:"TEXTURE28",34013:"TEXTURE29",34014:"TEXTURE30",34015:"TEXTURE31",34016:"ACTIVE_TEXTURE",34024:"MAX_RENDERBUFFER_SIZE",34041:"DEPTH_STENCIL",34055:"INCR_WRAP",34056:"DECR_WRAP",34067:"TEXTURE_CUBE_MAP",34068:"TEXTURE_BINDING_CUBE_MAP",34069:"TEXTURE_CUBE_MAP_POSITIVE_X",34070:"TEXTURE_CUBE_MAP_NEGATIVE_X",34071:"TEXTURE_CUBE_MAP_POSITIVE_Y",34072:"TEXTURE_CUBE_MAP_NEGATIVE_Y",34073:"TEXTURE_CUBE_MAP_POSITIVE_Z",34074:"TEXTURE_CUBE_MAP_NEGATIVE_Z",34076:"MAX_CUBE_MAP_TEXTURE_SIZE",34338:"VERTEX_ATTRIB_ARRAY_ENABLED",34339:"VERTEX_ATTRIB_ARRAY_SIZE",34340:"VERTEX_ATTRIB_ARRAY_STRIDE",34341:"VERTEX_ATTRIB_ARRAY_TYPE",34342:"CURRENT_VERTEX_ATTRIB",34373:"VERTEX_ATTRIB_ARRAY_POINTER",34466:"NUM_COMPRESSED_TEXTURE_FORMATS",34467:"COMPRESSED_TEXTURE_FORMATS",34660:"BUFFER_SIZE",34661:"BUFFER_USAGE",34816:"STENCIL_BACK_FUNC",34817:"STENCIL_BACK_FAIL",34818:"STENCIL_BACK_PASS_DEPTH_FAIL",34819:"STENCIL_BACK_PASS_DEPTH_PASS",34877:"BLEND_EQUATION_ALPHA",34921:"MAX_VERTEX_ATTRIBS",34922:"VERTEX_ATTRIB_ARRAY_NORMALIZED",34930:"MAX_TEXTURE_IMAGE_UNITS",34962:"ARRAY_BUFFER",34963:"ELEMENT_ARRAY_BUFFER",34964:"ARRAY_BUFFER_BINDING",34965:"ELEMENT_ARRAY_BUFFER_BINDING",34975:"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",35040:"STREAM_DRAW",35044:"STATIC_DRAW",35048:"DYNAMIC_DRAW",35632:"FRAGMENT_SHADER",35633:"VERTEX_SHADER",35660:"MAX_VERTEX_TEXTURE_IMAGE_UNITS",35661:"MAX_COMBINED_TEXTURE_IMAGE_UNITS",35663:"SHADER_TYPE",35664:"FLOAT_VEC2",35665:"FLOAT_VEC3",35666:"FLOAT_VEC4",35667:"INT_VEC2",35668:"INT_VEC3",35669:"INT_VEC4",35670:"BOOL",35671:"BOOL_VEC2",35672:"BOOL_VEC3",35673:"BOOL_VEC4",35674:"FLOAT_MAT2",35675:"FLOAT_MAT3",35676:"FLOAT_MAT4",35678:"SAMPLER_2D",35680:"SAMPLER_CUBE",35712:"DELETE_STATUS",35713:"COMPILE_STATUS",35714:"LINK_STATUS",35715:"VALIDATE_STATUS",35716:"INFO_LOG_LENGTH",35717:"ATTACHED_SHADERS",35718:"ACTIVE_UNIFORMS",35719:"ACTIVE_UNIFORM_MAX_LENGTH",35720:"SHADER_SOURCE_LENGTH",35721:"ACTIVE_ATTRIBUTES",35722:"ACTIVE_ATTRIBUTE_MAX_LENGTH",35724:"SHADING_LANGUAGE_VERSION",35725:"CURRENT_PROGRAM",36003:"STENCIL_BACK_REF",36004:"STENCIL_BACK_VALUE_MASK",36005:"STENCIL_BACK_WRITEMASK",36006:"FRAMEBUFFER_BINDING",36007:"RENDERBUFFER_BINDING",36048:"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",36049:"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",36050:"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",36051:"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",36053:"FRAMEBUFFER_COMPLETE",36054:"FRAMEBUFFER_INCOMPLETE_ATTACHMENT",36055:"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",36057:"FRAMEBUFFER_INCOMPLETE_DIMENSIONS",36061:"FRAMEBUFFER_UNSUPPORTED",36064:"COLOR_ATTACHMENT0",36096:"DEPTH_ATTACHMENT",36128:"STENCIL_ATTACHMENT",36160:"FRAMEBUFFER",36161:"RENDERBUFFER",36162:"RENDERBUFFER_WIDTH",36163:"RENDERBUFFER_HEIGHT",36164:"RENDERBUFFER_INTERNAL_FORMAT",36168:"STENCIL_INDEX8",36176:"RENDERBUFFER_RED_SIZE",36177:"RENDERBUFFER_GREEN_SIZE",36178:"RENDERBUFFER_BLUE_SIZE",36179:"RENDERBUFFER_ALPHA_SIZE",36180:"RENDERBUFFER_DEPTH_SIZE",36181:"RENDERBUFFER_STENCIL_SIZE",36194:"RGB565",36336:"LOW_FLOAT",36337:"MEDIUM_FLOAT",36338:"HIGH_FLOAT",36339:"LOW_INT",36340:"MEDIUM_INT",36341:"HIGH_INT",36346:"SHADER_COMPILER",36347:"MAX_VERTEX_UNIFORM_VECTORS",36348:"MAX_VARYING_VECTORS",36349:"MAX_FRAGMENT_UNIFORM_VECTORS",37440:"UNPACK_FLIP_Y_WEBGL",37441:"UNPACK_PREMULTIPLY_ALPHA_WEBGL",37442:"CONTEXT_LOST_WEBGL",37443:"UNPACK_COLORSPACE_CONVERSION_WEBGL",37444:"BROWSER_DEFAULT_WEBGL"}},{}],236:[function(t,e,r){var n=t("./1.0/numbers");e.exports=function(t){return n[t]}},{"./1.0/numbers":235}],237:[function(t,e,r){"use strict";e.exports=function(t){var e=t.gl,r=n(e),o=i(e,[{buffer:r,type:e.FLOAT,size:3,offset:0,stride:40},{buffer:r,type:e.FLOAT,size:4,offset:12,stride:40},{buffer:r,type:e.FLOAT,size:3,offset:28,stride:40}]),l=a(e);l.attributes.position.location=0,l.attributes.color.location=1,l.attributes.offset.location=2;var c=new s(e,r,o,l);return c.update(t),c};var n=t("gl-buffer"),i=t("gl-vao"),a=t("./shaders/index"),o=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];function s(t,e,r,n){this.gl=t,this.shader=n,this.buffer=e,this.vao=r,this.pixelRatio=1,this.bounds=[[1/0,1/0,1/0],[-1/0,-1/0,-1/0]],this.clipBounds=[[-1/0,-1/0,-1/0],[1/0,1/0,1/0]],this.lineWidth=[1,1,1],this.capSize=[10,10,10],this.lineCount=[0,0,0],this.lineOffset=[0,0,0],this.opacity=1}var l=s.prototype;function c(t,e){for(var r=0;r<3;++r)t[0][r]=Math.min(t[0][r],e[r]),t[1][r]=Math.max(t[1][r],e[r])}l.isOpaque=function(){return this.opacity>=1},l.isTransparent=function(){return this.opacity<1},l.drawTransparent=l.draw=function(t){var e=this.gl,r=this.shader.uniforms;this.shader.bind();var n=r.view=t.view||o,i=r.projection=t.projection||o;r.model=t.model||o,r.clipBounds=this.clipBounds,r.opacity=this.opacity;var a=n[12],s=n[13],l=n[14],c=n[15],u=this.pixelRatio*(i[3]*a+i[7]*s+i[11]*l+i[15]*c)/e.drawingBufferHeight;this.vao.bind();for(var h=0;h<3;++h)e.lineWidth(this.lineWidth[h]),r.capSize=this.capSize[h]*u,this.lineCount[h]&&e.drawArrays(e.LINES,this.lineOffset[h],this.lineCount[h]);this.vao.unbind()};var u=function(){for(var t=new Array(3),e=0;e<3;++e){for(var r=[],n=1;n<=2;++n)for(var i=-1;i<=1;i+=2){var a=[0,0,0];a[(n+e)%3]=i,r.push(a)}t[e]=r}return t}();function h(t,e,r,n){for(var i=u[n],a=0;a0)(g=u.slice())[s]+=p[1][s],i.push(u[0],u[1],u[2],d[0],d[1],d[2],d[3],0,0,0,g[0],g[1],g[2],d[0],d[1],d[2],d[3],0,0,0),c(this.bounds,g),o+=2+h(i,g,d,s)}}this.lineCount[s]=o-this.lineOffset[s]}this.buffer.update(i)}},l.dispose=function(){this.shader.dispose(),this.buffer.dispose(),this.vao.dispose()}},{"./shaders/index":238,"gl-buffer":230,"gl-vao":308}],238:[function(t,e,r){"use strict";var n=t("glslify"),i=t("gl-shader"),a=n(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec3 position, offset;\nattribute vec4 color;\nuniform mat4 model, view, projection;\nuniform float capSize;\nvarying vec4 fragColor;\nvarying vec3 fragPosition;\n\nvoid main() {\n vec4 worldPosition = model * vec4(position, 1.0);\n worldPosition = (worldPosition / worldPosition.w) + vec4(capSize * offset, 0.0);\n gl_Position = projection * view * worldPosition;\n fragColor = color;\n fragPosition = position;\n}"]),o=n(["precision mediump float;\n#define GLSLIFY 1\nuniform vec3 clipBounds[2];\nuniform float opacity;\nvarying vec3 fragPosition;\nvarying vec4 fragColor;\n\nvoid main() {\n if(any(lessThan(fragPosition, clipBounds[0])) || any(greaterThan(fragPosition, clipBounds[1]))) {\n discard;\n }\n gl_FragColor = opacity * fragColor;\n}"]);e.exports=function(t){return i(t,a,o,null,[{name:"position",type:"vec3"},{name:"color",type:"vec4"},{name:"offset",type:"vec3"}])}},{"gl-shader":287,glslify:377}],239:[function(t,e,r){"use strict";var n=t("gl-texture2d");e.exports=function(t,e,r,n){i||(i=t.FRAMEBUFFER_UNSUPPORTED,a=t.FRAMEBUFFER_INCOMPLETE_ATTACHMENT,o=t.FRAMEBUFFER_INCOMPLETE_DIMENSIONS,s=t.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);var c=t.getExtension("WEBGL_draw_buffers");!l&&c&&function(t,e){var r=t.getParameter(e.MAX_COLOR_ATTACHMENTS_WEBGL);l=new Array(r+1);for(var n=0;n<=r;++n){for(var i=new Array(r),a=0;au||r<0||r>u)throw new Error("gl-fbo: Parameters are too large for FBO");var h=1;if("color"in(n=n||{})){if((h=Math.max(0|n.color,0))<0)throw new Error("gl-fbo: Must specify a nonnegative number of colors");if(h>1){if(!c)throw new Error("gl-fbo: Multiple draw buffer extension not supported");if(h>t.getParameter(c.MAX_COLOR_ATTACHMENTS_WEBGL))throw new Error("gl-fbo: Context does not support "+h+" draw buffers")}}var f=t.UNSIGNED_BYTE,p=t.getExtension("OES_texture_float");if(n.float&&h>0){if(!p)throw new Error("gl-fbo: Context does not support floating point textures");f=t.FLOAT}else n.preferFloat&&h>0&&p&&(f=t.FLOAT);var g=!0;"depth"in n&&(g=!!n.depth);var m=!1;"stencil"in n&&(m=!!n.stencil);return new d(t,e,r,f,h,g,m,c)};var i,a,o,s,l=null;function c(t){return[t.getParameter(t.FRAMEBUFFER_BINDING),t.getParameter(t.RENDERBUFFER_BINDING),t.getParameter(t.TEXTURE_BINDING_2D)]}function u(t,e){t.bindFramebuffer(t.FRAMEBUFFER,e[0]),t.bindRenderbuffer(t.RENDERBUFFER,e[1]),t.bindTexture(t.TEXTURE_2D,e[2])}function h(t){switch(t){case i:throw new Error("gl-fbo: Framebuffer unsupported");case a:throw new Error("gl-fbo: Framebuffer incomplete attachment");case o:throw new Error("gl-fbo: Framebuffer incomplete dimensions");case s:throw new Error("gl-fbo: Framebuffer incomplete missing attachment");default:throw new Error("gl-fbo: Framebuffer failed for unspecified reason")}}function f(t,e,r,i,a,o){if(!i)return null;var s=n(t,e,r,a,i);return s.magFilter=t.NEAREST,s.minFilter=t.NEAREST,s.mipSamples=1,s.bind(),t.framebufferTexture2D(t.FRAMEBUFFER,o,t.TEXTURE_2D,s.handle,0),s}function p(t,e,r,n,i){var a=t.createRenderbuffer();return t.bindRenderbuffer(t.RENDERBUFFER,a),t.renderbufferStorage(t.RENDERBUFFER,n,e,r),t.framebufferRenderbuffer(t.FRAMEBUFFER,i,t.RENDERBUFFER,a),a}function d(t,e,r,n,i,a,o,s){this.gl=t,this._shape=[0|e,0|r],this._destroyed=!1,this._ext=s,this.color=new Array(i);for(var d=0;d1&&s.drawBuffersWEBGL(l[o]);var y=r.getExtension("WEBGL_depth_texture");y?d?t.depth=f(r,i,a,y.UNSIGNED_INT_24_8_WEBGL,r.DEPTH_STENCIL,r.DEPTH_STENCIL_ATTACHMENT):g&&(t.depth=f(r,i,a,r.UNSIGNED_SHORT,r.DEPTH_COMPONENT,r.DEPTH_ATTACHMENT)):g&&d?t._depth_rb=p(r,i,a,r.DEPTH_STENCIL,r.DEPTH_STENCIL_ATTACHMENT):g?t._depth_rb=p(r,i,a,r.DEPTH_COMPONENT16,r.DEPTH_ATTACHMENT):d&&(t._depth_rb=p(r,i,a,r.STENCIL_INDEX,r.STENCIL_ATTACHMENT));var x=r.checkFramebufferStatus(r.FRAMEBUFFER);if(x!==r.FRAMEBUFFER_COMPLETE){for(t._destroyed=!0,r.bindFramebuffer(r.FRAMEBUFFER,null),r.deleteFramebuffer(t.handle),t.handle=null,t.depth&&(t.depth.dispose(),t.depth=null),t._depth_rb&&(r.deleteRenderbuffer(t._depth_rb),t._depth_rb=null),v=0;vi||r<0||r>i)throw new Error("gl-fbo: Can't resize FBO, invalid dimensions");t._shape[0]=e,t._shape[1]=r;for(var a=c(n),o=0;o>8*p&255;this.pickOffset=r,i.bind();var d=i.uniforms;d.viewTransform=t,d.pickOffset=e,d.shape=this.shape;var g=i.attributes;return this.positionBuffer.bind(),g.position.pointer(),this.weightBuffer.bind(),g.weight.pointer(s.UNSIGNED_BYTE,!1),this.idBuffer.bind(),g.pickId.pointer(s.UNSIGNED_BYTE,!1),s.drawArrays(s.TRIANGLES,0,o),r+this.shape[0]*this.shape[1]}}}(),h.pick=function(t,e,r){var n=this.pickOffset,i=this.shape[0]*this.shape[1];if(r=n+i)return null;var a=r-n,o=this.xData,s=this.yData;return{object:this,pointId:a,dataCoord:[o[a%this.shape[0]],s[a/this.shape[0]|0]]}},h.update=function(t){var e=(t=t||{}).shape||[0,0],r=t.x||i(e[0]),o=t.y||i(e[1]),s=t.z||new Float32Array(e[0]*e[1]);this.xData=r,this.yData=o;var l=t.colorLevels||[0],c=t.colorValues||[0,0,0,1],u=l.length,h=this.bounds,p=h[0]=r[0],d=h[1]=o[0],g=1/((h[2]=r[r.length-1])-p),m=1/((h[3]=o[o.length-1])-d),v=e[0],y=e[1];this.shape=[v,y];var x=(v-1)*(y-1)*(f.length>>>1);this.numVertices=x;for(var b=a.mallocUint8(4*x),_=a.mallocFloat32(2*x),w=a.mallocUint8(2*x),k=a.mallocUint32(x),M=0,A=0;A FLOAT_MAX) {\n return vec4(127.0, 128.0, 0.0, 0.0) / 255.0;\n } else if(v < -FLOAT_MAX) {\n return vec4(255.0, 128.0, 0.0, 0.0) / 255.0;\n }\n\n highp vec4 c = vec4(0,0,0,0);\n\n //Compute exponent and mantissa\n highp float e = floor(log2(av));\n highp float m = av * pow(2.0, -e) - 1.0;\n \n //Unpack mantissa\n c[1] = floor(128.0 * m);\n m -= c[1] / 128.0;\n c[2] = floor(32768.0 * m);\n m -= c[2] / 32768.0;\n c[3] = floor(8388608.0 * m);\n \n //Unpack exponent\n highp float ebias = e + 127.0;\n c[0] = floor(ebias / 2.0);\n ebias -= c[0] * 2.0;\n c[1] += floor(ebias) * 128.0; \n\n //Unpack sign bit\n c[0] += 128.0 * step(0.0, -v);\n\n //Scale back to range\n return c / 255.0;\n}\n\nuniform float pickId;\nuniform vec3 clipBounds[2];\n\nvarying vec3 worldPosition;\nvarying float pixelArcLength;\nvarying vec4 fragColor;\n\nvoid main() {\n if(any(lessThan(worldPosition, clipBounds[0])) || any(greaterThan(worldPosition, clipBounds[1]))) {\n discard;\n }\n gl_FragColor = vec4(pickId/255.0, encode_float_1540259130(pixelArcLength).xyz);\n}"]),l=[{name:"position",type:"vec3"},{name:"nextPosition",type:"vec3"},{name:"arcLength",type:"float"},{name:"lineWidth",type:"float"},{name:"color",type:"vec4"}];r.createShader=function(t){return i(t,a,o,null,l)},r.createPickShader=function(t){return i(t,a,s,null,l)}},{"gl-shader":287,glslify:377}],245:[function(t,e,r){"use strict";e.exports=function(t){var e=t.gl||t.scene&&t.scene.gl,r=u(e);r.attributes.position.location=0,r.attributes.nextPosition.location=1,r.attributes.arcLength.location=2,r.attributes.lineWidth.location=3,r.attributes.color.location=4;var o=h(e);o.attributes.position.location=0,o.attributes.nextPosition.location=1,o.attributes.arcLength.location=2,o.attributes.lineWidth.location=3,o.attributes.color.location=4;for(var s=n(e),c=i(e,[{buffer:s,size:3,offset:0,stride:48},{buffer:s,size:3,offset:12,stride:48},{buffer:s,size:1,offset:24,stride:48},{buffer:s,size:1,offset:28,stride:48},{buffer:s,size:4,offset:32,stride:48}]),f=l(new Array(1024),[256,1,4]),p=0;p<1024;++p)f.data[p]=255;var d=a(e,f);d.wrap=e.REPEAT;var g=new m(e,r,o,s,c,d);return g.update(t),g};var n=t("gl-buffer"),i=t("gl-vao"),a=t("gl-texture2d"),o=t("glsl-read-float"),s=t("binary-search-bounds"),l=t("ndarray"),c=t("./lib/shaders"),u=c.createShader,h=c.createPickShader,f=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];function p(t,e){for(var r=0,n=0;n<3;++n){var i=t[n]-e[n];r+=i*i}return Math.sqrt(r)}function d(t){for(var e=[[-1e6,-1e6,-1e6],[1e6,1e6,1e6]],r=0;r<3;++r)e[0][r]=Math.max(t[0][r],e[0][r]),e[1][r]=Math.min(t[1][r],e[1][r]);return e}function g(t,e,r,n){this.arcLength=t,this.position=e,this.index=r,this.dataCoordinate=n}function m(t,e,r,n,i,a){this.gl=t,this.shader=e,this.pickShader=r,this.buffer=n,this.vao=i,this.clipBounds=[[-1/0,-1/0,-1/0],[1/0,1/0,1/0]],this.points=[],this.arcLength=[],this.vertexCount=0,this.bounds=[[0,0,0],[0,0,0]],this.pickId=0,this.lineWidth=1,this.texture=a,this.dashScale=1,this.opacity=1,this.dirty=!0,this.pixelRatio=1}var v=m.prototype;v.isTransparent=function(){return this.opacity<1},v.isOpaque=function(){return this.opacity>=1},v.pickSlots=1,v.setPickBase=function(t){this.pickId=t},v.drawTransparent=v.draw=function(t){var e=this.gl,r=this.shader,n=this.vao;r.bind(),r.uniforms={model:t.model||f,view:t.view||f,projection:t.projection||f,clipBounds:d(this.clipBounds),dashTexture:this.texture.bind(),dashScale:this.dashScale/this.arcLength[this.arcLength.length-1],opacity:this.opacity,screenShape:[e.drawingBufferWidth,e.drawingBufferHeight],pixelRatio:this.pixelRatio},n.bind(),n.draw(e.TRIANGLE_STRIP,this.vertexCount),n.unbind()},v.drawPick=function(t){var e=this.gl,r=this.pickShader,n=this.vao;r.bind(),r.uniforms={model:t.model||f,view:t.view||f,projection:t.projection||f,pickId:this.pickId,clipBounds:d(this.clipBounds),screenShape:[e.drawingBufferWidth,e.drawingBufferHeight],pixelRatio:this.pixelRatio},n.bind(),n.draw(e.TRIANGLE_STRIP,this.vertexCount),n.unbind()},v.update=function(t){var e,r;this.dirty=!0;var n=!!t.connectGaps;"dashScale"in t&&(this.dashScale=t.dashScale),"opacity"in t&&(this.opacity=+t.opacity);var i=t.position||t.positions;if(i){var a=t.color||t.colors||[0,0,0,1],o=t.lineWidth||1,c=[],u=[],h=[],f=0,d=0,g=[[1/0,1/0,1/0],[-1/0,-1/0,-1/0]],m=!1;t:for(e=1;e0){for(var w=0;w<24;++w)c.push(c[c.length-12]);d+=2,m=!0}continue t}g[0][r]=Math.min(g[0][r],b[r],_[r]),g[1][r]=Math.max(g[1][r],b[r],_[r])}Array.isArray(a[0])?(v=a[e-1],y=a[e]):v=y=a,3===v.length&&(v=[v[0],v[1],v[2],1]),3===y.length&&(y=[y[0],y[1],y[2],1]),x=Array.isArray(o)?o[e-1]:o;var k=f;if(f+=p(b,_),m){for(r=0;r<2;++r)c.push(b[0],b[1],b[2],_[0],_[1],_[2],k,x,v[0],v[1],v[2],v[3]);d+=2,m=!1}c.push(b[0],b[1],b[2],_[0],_[1],_[2],k,x,v[0],v[1],v[2],v[3],b[0],b[1],b[2],_[0],_[1],_[2],k,-x,v[0],v[1],v[2],v[3],_[0],_[1],_[2],b[0],b[1],b[2],f,-x,y[0],y[1],y[2],y[3],_[0],_[1],_[2],b[0],b[1],b[2],f,x,y[0],y[1],y[2],y[3]),d+=4}if(this.buffer.update(c),u.push(f),h.push(i[i.length-1].slice()),this.bounds=g,this.vertexCount=d,this.points=h,this.arcLength=u,"dashes"in t){var M=t.dashes.slice();for(M.unshift(0),e=1;e1.0001)return null;m+=g[u]}if(Math.abs(m-1)>.001)return null;return[h,function(t,e){for(var r=[0,0,0],n=0;n 0.25) {\n discard;\n }\n gl_FragColor = f_color * texture2D(texture, f_uv) * opacity;\n}"]),u=n(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec3 position;\nattribute vec4 id;\n\nuniform mat4 model, view, projection;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n gl_Position = projection * view * model * vec4(position, 1.0);\n f_id = id;\n f_position = position;\n}"]),h=n(["precision mediump float;\n#define GLSLIFY 1\n\nuniform vec3 clipBounds[2];\nuniform float pickId;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n if(any(lessThan(f_position, clipBounds[0])) || \n any(greaterThan(f_position, clipBounds[1]))) {\n discard;\n }\n gl_FragColor = vec4(pickId, f_id.xyz);\n}"]),f=n(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec3 position;\nattribute float pointSize;\nattribute vec4 id;\n\nuniform mat4 model, view, projection;\nuniform vec3 clipBounds[2];\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n if(any(lessThan(position, clipBounds[0])) || \n any(greaterThan(position, clipBounds[1]))) {\n gl_Position = vec4(0,0,0,0);\n } else {\n gl_Position = projection * view * model * vec4(position, 1.0);\n gl_PointSize = pointSize;\n }\n f_id = id;\n f_position = position;\n}"]),p=n(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec3 position;\n\nuniform mat4 model, view, projection;\n\nvoid main() {\n gl_Position = projection * view * model * vec4(position, 1.0);\n}"]),d=n(["precision mediump float;\n#define GLSLIFY 1\n\nuniform vec3 contourColor;\n\nvoid main() {\n gl_FragColor = vec4(contourColor,1);\n}\n"]);r.meshShader={vertex:i,fragment:a,attributes:[{name:"position",type:"vec3"},{name:"normal",type:"vec3"},{name:"color",type:"vec4"},{name:"uv",type:"vec2"}]},r.wireShader={vertex:o,fragment:s,attributes:[{name:"position",type:"vec3"},{name:"color",type:"vec4"},{name:"uv",type:"vec2"}]},r.pointShader={vertex:l,fragment:c,attributes:[{name:"position",type:"vec3"},{name:"color",type:"vec4"},{name:"uv",type:"vec2"},{name:"pointSize",type:"float"}]},r.pickShader={vertex:u,fragment:h,attributes:[{name:"position",type:"vec3"},{name:"id",type:"vec4"}]},r.pointPickShader={vertex:f,fragment:h,attributes:[{name:"position",type:"vec3"},{name:"pointSize",type:"float"},{name:"id",type:"vec4"}]},r.contourShader={vertex:p,fragment:d,attributes:[{name:"position",type:"vec3"}]}},{glslify:377}],268:[function(t,e,r){"use strict";var n=t("gl-shader"),i=t("gl-buffer"),a=t("gl-vao"),o=t("gl-texture2d"),s=t("normals"),l=t("gl-mat4/multiply"),c=t("gl-mat4/invert"),u=t("ndarray"),h=t("colormap"),f=t("simplicial-complex-contour"),p=t("typedarray-pool"),d=t("./lib/shaders"),g=t("./lib/closest-point"),m=d.meshShader,v=d.wireShader,y=d.pointShader,x=d.pickShader,b=d.pointPickShader,_=d.contourShader,w=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];function k(t,e,r,n,i,a,o,s,l,c,u,h,f,p,d,g,m,v,y,x,b,_,k,M,A,T,S){this.gl=t,this.cells=[],this.positions=[],this.intensity=[],this.texture=e,this.dirty=!0,this.triShader=r,this.lineShader=n,this.pointShader=i,this.pickShader=a,this.pointPickShader=o,this.contourShader=s,this.trianglePositions=l,this.triangleColors=u,this.triangleNormals=f,this.triangleUVs=h,this.triangleIds=c,this.triangleVAO=p,this.triangleCount=0,this.lineWidth=1,this.edgePositions=d,this.edgeColors=m,this.edgeUVs=v,this.edgeIds=g,this.edgeVAO=y,this.edgeCount=0,this.pointPositions=x,this.pointColors=_,this.pointUVs=k,this.pointSizes=M,this.pointIds=b,this.pointVAO=A,this.pointCount=0,this.contourLineWidth=1,this.contourPositions=T,this.contourVAO=S,this.contourCount=0,this.contourColor=[0,0,0],this.contourEnable=!0,this.pickId=1,this.bounds=[[1/0,1/0,1/0],[-1/0,-1/0,-1/0]],this.clipBounds=[[-1/0,-1/0,-1/0],[1/0,1/0,1/0]],this.lightPosition=[1e5,1e5,0],this.ambientLight=.8,this.diffuseLight=.8,this.specularLight=2,this.roughness=.5,this.fresnel=1.5,this.opacity=1,this._model=w,this._view=w,this._projection=w,this._resolution=[1,1]}var M=k.prototype;function A(t){var e=n(t,y.vertex,y.fragment);return e.attributes.position.location=0,e.attributes.color.location=2,e.attributes.uv.location=3,e.attributes.pointSize.location=4,e}function T(t){var e=n(t,x.vertex,x.fragment);return e.attributes.position.location=0,e.attributes.id.location=1,e}function S(t){var e=n(t,b.vertex,b.fragment);return e.attributes.position.location=0,e.attributes.id.location=1,e.attributes.pointSize.location=4,e}function E(t){var e=n(t,_.vertex,_.fragment);return e.attributes.position.location=0,e}M.isOpaque=function(){return this.opacity>=1},M.isTransparent=function(){return this.opacity<1},M.pickSlots=1,M.setPickBase=function(t){this.pickId=t},M.highlight=function(t){if(t&&this.contourEnable){for(var e=f(this.cells,this.intensity,t.intensity),r=e.cells,n=e.vertexIds,i=e.vertexWeights,a=r.length,o=p.mallocFloat32(6*a),s=0,l=0;l0&&((h=this.triShader).bind(),h.uniforms=s,this.triangleVAO.bind(),e.drawArrays(e.TRIANGLES,0,3*this.triangleCount),this.triangleVAO.unbind());this.edgeCount>0&&this.lineWidth>0&&((h=this.lineShader).bind(),h.uniforms=s,this.edgeVAO.bind(),e.lineWidth(this.lineWidth),e.drawArrays(e.LINES,0,2*this.edgeCount),this.edgeVAO.unbind());this.pointCount>0&&((h=this.pointShader).bind(),h.uniforms=s,this.pointVAO.bind(),e.drawArrays(e.POINTS,0,this.pointCount),this.pointVAO.unbind());this.contourEnable&&this.contourCount>0&&this.contourLineWidth>0&&((h=this.contourShader).bind(),h.uniforms=s,this.contourVAO.bind(),e.drawArrays(e.LINES,0,this.contourCount),this.contourVAO.unbind())},M.drawPick=function(t){t=t||{};for(var e=this.gl,r=t.model||w,n=t.view||w,i=t.projection||w,a=[[-1e6,-1e6,-1e6],[1e6,1e6,1e6]],o=0;o<3;++o)a[0][o]=Math.max(a[0][o],this.clipBounds[0][o]),a[1][o]=Math.min(a[1][o],this.clipBounds[1][o]);this._model=[].slice.call(r),this._view=[].slice.call(n),this._projection=[].slice.call(i),this._resolution=[e.drawingBufferWidth,e.drawingBufferHeight];var s,l={model:r,view:n,projection:i,clipBounds:a,pickId:this.pickId/255};((s=this.pickShader).bind(),s.uniforms=l,this.triangleCount>0&&(this.triangleVAO.bind(),e.drawArrays(e.TRIANGLES,0,3*this.triangleCount),this.triangleVAO.unbind()),this.edgeCount>0&&(this.edgeVAO.bind(),e.lineWidth(this.lineWidth),e.drawArrays(e.LINES,0,2*this.edgeCount),this.edgeVAO.unbind()),this.pointCount>0)&&((s=this.pointPickShader).bind(),s.uniforms=l,this.pointVAO.bind(),e.drawArrays(e.POINTS,0,this.pointCount),this.pointVAO.unbind())},M.pick=function(t){if(!t)return null;if(t.id!==this.pickId)return null;for(var e=t.value[0]+256*t.value[1]+65536*t.value[2],r=this.cells[e],n=this.positions,i=new Array(r.length),a=0;ai[M]&&(r.uniforms.dataAxis=c,r.uniforms.screenOffset=u,r.uniforms.color=m[t],r.uniforms.angle=v[t],a.drawArrays(a.TRIANGLES,i[M],i[A]-i[M]))),y[t]&&k&&(u[1^t]-=T*p*x[t],r.uniforms.dataAxis=h,r.uniforms.screenOffset=u,r.uniforms.color=b[t],r.uniforms.angle=_[t],a.drawArrays(a.TRIANGLES,w,k)),u[1^t]=T*s[2+(1^t)]-1,d[t+2]&&(u[1^t]+=T*p*g[t+2],Mi[M]&&(r.uniforms.dataAxis=c,r.uniforms.screenOffset=u,r.uniforms.color=m[t+2],r.uniforms.angle=v[t+2],a.drawArrays(a.TRIANGLES,i[M],i[A]-i[M]))),y[t+2]&&k&&(u[1^t]+=T*p*x[t+2],r.uniforms.dataAxis=h,r.uniforms.screenOffset=u,r.uniforms.color=b[t+2],r.uniforms.angle=_[t+2],a.drawArrays(a.TRIANGLES,w,k))}),g.drawTitle=function(){var t=[0,0],e=[0,0];return function(){var r=this.plot,n=this.shader,i=r.gl,a=r.screenBox,o=r.titleCenter,s=r.titleAngle,l=r.titleColor,c=r.pixelRatio;if(this.titleCount){for(var u=0;u<2;++u)e[u]=2*(o[u]*c-a[u])/(a[2+u]-a[u])-1;n.bind(),n.uniforms.dataAxis=t,n.uniforms.screenOffset=e,n.uniforms.angle=s,n.uniforms.color=l,i.drawArrays(i.TRIANGLES,this.titleOffset,this.titleCount)}}}(),g.bind=(f=[0,0],p=[0,0],d=[0,0],function(){var t=this.plot,e=this.shader,r=t._tickBounds,n=t.dataBox,i=t.screenBox,a=t.viewBox;e.bind();for(var o=0;o<2;++o){var s=r[o],l=r[o+2]-s,c=.5*(n[o+2]+n[o]),u=n[o+2]-n[o],h=a[o],g=a[o+2]-h,m=i[o],v=i[o+2]-m;p[o]=2*l/u*g/v,f[o]=2*(s-c)/u*g/v}d[1]=2*t.pixelRatio/(i[3]-i[1]),d[0]=d[1]*(i[3]-i[1])/(i[2]-i[0]),e.uniforms.dataScale=p,e.uniforms.dataShift=f,e.uniforms.textScale=d,this.vbo.bind(),e.attributes.textCoordinate.pointer()}),g.update=function(t){var e,r,n,i,o,s=[],l=t.ticks,c=t.bounds;for(o=0;o<2;++o){var u=[Math.floor(s.length/3)],h=[-1/0],f=l[o];for(e=0;e=0){var g=e[d]-n[d]*(e[d+2]-e[d])/(n[d+2]-n[d]);0===d?o.drawLine(g,e[1],g,e[3],p[d],f[d]):o.drawLine(e[0],g,e[2],g,p[d],f[d])}}for(d=0;d=0;--t)this.objects[t].dispose();this.objects.length=0;for(t=this.overlays.length-1;t>=0;--t)this.overlays[t].dispose();this.overlays.length=0,this.gl=null},c.addObject=function(t){this.objects.indexOf(t)<0&&(this.objects.push(t),this.setDirty())},c.removeObject=function(t){for(var e=this.objects,r=0;r0&&0===L[e-1];)L.pop(),z.pop().dispose()}window.addEventListener("resize",j),F.update=function(t){e||(t=t||{},P=!0,I=!0)},F.add=function(t){e||(t.axes=A,E.push(t),C.push(-1),P=!0,I=!0,V())},F.remove=function(t){if(!e){var r=E.indexOf(t);r<0||(E.splice(r,1),C.pop(),P=!0,I=!0,V())}},F.dispose=function(){if(!e&&(e=!0,window.removeEventListener("resize",j),r.removeEventListener("webglcontextlost",H),F.mouseListener.enabled=!1,!F.contextLost)){A.dispose(),S.dispose();for(var t=0;tb.distance)continue;for(var u=0;u0){r=Math.round(Math.pow(10,e));return Math.ceil(t/r)*r}return Math.ceil(t)}function m(t){return"boolean"!=typeof t||t}},{"./lib/shader":276,"3d-view-controls":42,"a-big-triangle":50,"gl-axes3d":222,"gl-axes3d/properties":229,"gl-fbo":239,"gl-mat4/perspective":257,"gl-select-static":286,"gl-spikes3d":296,"is-mobile":388,"mouse-change":402}],278:[function(t,e,r){var n=t("glslify");r.pointVertex=n(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\n\nuniform mat3 matrix;\nuniform float pointSize;\nuniform float pointCloud;\n\nhighp float rand(vec2 co) {\n highp float a = 12.9898;\n highp float b = 78.233;\n highp float c = 43758.5453;\n highp float d = dot(co.xy, vec2(a, b));\n highp float e = mod(d, 3.14);\n return fract(sin(e) * c);\n}\n\nvoid main() {\n vec3 hgPosition = matrix * vec3(position, 1);\n gl_Position = vec4(hgPosition.xy, 0, hgPosition.z);\n // if we don't jitter the point size a bit, overall point cloud\n // saturation 'jumps' on zooming, which is disturbing and confusing\n gl_PointSize = pointSize * ((19.5 + rand(position)) / 20.0);\n if(pointCloud != 0.0) { // pointCloud is truthy\n // get the same square surface as circle would be\n gl_PointSize *= 0.886;\n }\n}"]),r.pointFragment=n(["precision mediump float;\n#define GLSLIFY 1\n\nuniform vec4 color, borderColor;\nuniform float centerFraction;\nuniform float pointCloud;\n\nvoid main() {\n float radius;\n vec4 baseColor;\n if(pointCloud != 0.0) { // pointCloud is truthy\n if(centerFraction == 1.0) {\n gl_FragColor = color;\n } else {\n gl_FragColor = mix(borderColor, color, centerFraction);\n }\n } else {\n radius = length(2.0 * gl_PointCoord.xy - 1.0);\n if(radius > 1.0) {\n discard;\n }\n baseColor = mix(borderColor, color, step(radius, centerFraction));\n gl_FragColor = vec4(baseColor.rgb * baseColor.a, baseColor.a);\n }\n}\n"]),r.pickVertex=n(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\nattribute vec4 pickId;\n\nuniform mat3 matrix;\nuniform float pointSize;\nuniform vec4 pickOffset;\n\nvarying vec4 fragId;\n\nvoid main() {\n vec3 hgPosition = matrix * vec3(position, 1);\n gl_Position = vec4(hgPosition.xy, 0, hgPosition.z);\n gl_PointSize = pointSize;\n\n vec4 id = pickId + pickOffset;\n id.y += floor(id.x / 256.0);\n id.x -= floor(id.x / 256.0) * 256.0;\n\n id.z += floor(id.y / 256.0);\n id.y -= floor(id.y / 256.0) * 256.0;\n\n id.w += floor(id.z / 256.0);\n id.z -= floor(id.z / 256.0) * 256.0;\n\n fragId = id;\n}\n"]),r.pickFragment=n(["precision mediump float;\n#define GLSLIFY 1\n\nvarying vec4 fragId;\n\nvoid main() {\n float radius = length(2.0 * gl_PointCoord.xy - 1.0);\n if(radius > 1.0) {\n discard;\n }\n gl_FragColor = fragId / 255.0;\n}\n"])},{glslify:377}],279:[function(t,e,r){"use strict";var n=t("gl-shader"),i=t("gl-buffer"),a=t("typedarray-pool"),o=t("./lib/shader");function s(t,e,r,n,i){this.plot=t,this.offsetBuffer=e,this.pickBuffer=r,this.shader=n,this.pickShader=i,this.sizeMin=.5,this.sizeMinCap=2,this.sizeMax=20,this.areaRatio=1,this.pointCount=0,this.color=[1,0,0,1],this.borderColor=[0,0,0,1],this.blend=!1,this.pickOffset=0,this.points=null}e.exports=function(t,e){var r=t.gl,a=i(r),l=i(r),c=n(r,o.pointVertex,o.pointFragment),u=n(r,o.pickVertex,o.pickFragment),h=new s(t,a,l,c,u);return h.update(e),t.addObject(h),h};var l,c,u=s.prototype;u.dispose=function(){this.shader.dispose(),this.pickShader.dispose(),this.offsetBuffer.dispose(),this.pickBuffer.dispose(),this.plot.removeObject(this)},u.update=function(t){var e;function r(e,r){return e in t?t[e]:r}t=t||{},this.sizeMin=r("sizeMin",.5),this.sizeMax=r("sizeMax",20),this.color=r("color",[1,0,0,1]).slice(),this.areaRatio=r("areaRatio",1),this.borderColor=r("borderColor",[0,0,0,1]).slice(),this.blend=r("blend",!1);var n=t.positions.length>>>1,i=t.positions instanceof Float32Array,o=t.idToIndex instanceof Int32Array&&t.idToIndex.length>=n,s=t.positions,l=i?s:a.mallocFloat32(s.length),c=o?t.idToIndex:a.mallocInt32(n);if(i||l.set(s),!o)for(l.set(s),e=0;e>>1;for(r=0;r=e[0]&&a<=e[2]&&o>=e[1]&&o<=e[3]&&n++}return n}(this.points,i),u=this.plot.pickPixelRatio*Math.max(Math.min(this.sizeMinCap,this.sizeMin),Math.min(this.sizeMax,this.sizeMax/Math.pow(s,.33333)));l[0]=2/a,l[4]=2/o,l[6]=-2*i[0]/a-1,l[7]=-2*i[1]/o-1,this.offsetBuffer.bind(),r.bind(),r.attributes.position.pointer(),r.uniforms.matrix=l,r.uniforms.color=this.color,r.uniforms.borderColor=this.borderColor,r.uniforms.pointCloud=u<5,r.uniforms.pointSize=u,r.uniforms.centerFraction=Math.min(1,Math.max(0,Math.sqrt(1-this.areaRatio))),e&&(c[0]=255&t,c[1]=t>>8&255,c[2]=t>>16&255,c[3]=t>>24&255,this.pickBuffer.bind(),r.attributes.pickId.pointer(n.UNSIGNED_BYTE),r.uniforms.pickOffset=c,this.pickOffset=t);var h=n.getParameter(n.BLEND),f=n.getParameter(n.DITHER);return h&&!this.blend&&n.disable(n.BLEND),f&&n.disable(n.DITHER),n.drawArrays(n.POINTS,0,this.pointCount),h&&!this.blend&&n.enable(n.BLEND),f&&n.enable(n.DITHER),t+this.pointCount}),u.draw=u.unifiedDraw,u.drawPick=u.unifiedDraw,u.pick=function(t,e,r){var n=this.pickOffset,i=this.pointCount;if(r=n+i)return null;var a=r-n,o=this.points;return{object:this,pointId:a,dataCoord:[o[2*a],o[2*a+1]]}}},{"./lib/shader":278,"gl-buffer":230,"gl-shader":287,"typedarray-pool":507}],280:[function(t,e,r){e.exports=function(t,e,r,n){var i,a,o,s,l,c=e[0],u=e[1],h=e[2],f=e[3],p=r[0],d=r[1],g=r[2],m=r[3];(a=c*p+u*d+h*g+f*m)<0&&(a=-a,p=-p,d=-d,g=-g,m=-m);1-a>1e-6?(i=Math.acos(a),o=Math.sin(i),s=Math.sin((1-n)*i)/o,l=Math.sin(n*i)/o):(s=1-n,l=n);return t[0]=s*c+l*p,t[1]=s*u+l*d,t[2]=s*h+l*g,t[3]=s*f+l*m,t}},{}],281:[function(t,e,r){"use strict";var n=t("vectorize-text");e.exports=function(t,e){var r=i[e];r||(r=i[e]={});if(t in r)return r[t];for(var a=n(t,{textAlign:"center",textBaseline:"middle",lineHeight:1,font:e}),o=n(t,{triangles:!0,textAlign:"center",textBaseline:"middle",lineHeight:1,font:e}),s=[[1/0,1/0],[-1/0,-1/0]],l=0;l=1)return!0;for(var t=0;t<3;++t)if(this.axesProject[t]&&this.projectOpacity[t]>=1)return!0;return!1};var g=[0,0],m=[0,0,0],v=[0,0,0],y=[0,0,0,1],x=[0,0,0,1],b=c.slice(),_=[0,0,0],w=[[0,0,0],[0,0,0]];function k(t){return t[0]=t[1]=t[2]=0,t}function M(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=1,t}function A(t,e,r,n){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[r]=n,t}function T(t,e,r,n,i){var a,s=e.axesProject,l=e.gl,u=t.uniforms,f=r.model||c,p=r.view||c,d=r.projection||c,T=e.axesBounds,S=function(t){for(var e=w,r=0;r<2;++r)for(var n=0;n<3;++n)e[r][n]=Math.max(Math.min(t[r][n],1e8),-1e8);return e}(e.clipBounds);a=e.axes&&e.axes.lastCubeProps?e.axes.lastCubeProps.axis:[1,1,1],g[0]=2/l.drawingBufferWidth,g[1]=2/l.drawingBufferHeight,t.bind(),u.view=p,u.projection=d,u.screenSize=g,u.highlightId=e.highlightId,u.highlightScale=e.highlightScale,u.clipBounds=S,u.pickGroup=e.pickId/255,u.pixelRatio=e.pixelRatio;for(var E=0;E<3;++E)if(s[E]&&e.projectOpacity[E]<1===n){u.scale=e.projectScale[E],u.opacity=e.projectOpacity[E];for(var C=b,L=0;L<16;++L)C[L]=0;for(L=0;L<4;++L)C[5*L]=1;C[5*E]=0,a[E]<0?C[12+E]=T[0][E]:C[12+E]=T[1][E],o(C,f,C),u.model=C;var z=(E+1)%3,P=(E+2)%3,I=k(m),O=k(v);I[z]=1,O[P]=1;var D=h(0,0,0,M(y,I)),R=h(0,0,0,M(x,O));if(Math.abs(D[1])>Math.abs(R[1])){var B=D;D=R,R=B,B=I,I=O,O=B;var F=z;z=P,P=F}D[0]<0&&(I[z]=-1),R[1]>0&&(O[P]=-1);var N=0,j=0;for(L=0;L<4;++L)N+=Math.pow(f[4*z+L],2),j+=Math.pow(f[4*P+L],2);I[z]/=Math.sqrt(N),O[P]/=Math.sqrt(j),u.axes[0]=I,u.axes[1]=O,u.fragClipBounds[0]=A(_,S[0],E,-1e8),u.fragClipBounds[1]=A(_,S[1],E,1e8),e.vao.draw(l.TRIANGLES,e.vertexCount),e.lineWidth>0&&(l.lineWidth(e.lineWidth),e.vao.draw(l.LINES,e.lineVertexCount,e.vertexCount))}}var S=[[-1e8,-1e8,-1e8],[1e8,1e8,1e8]];function E(t,e,r,n,i,a){var o=r.gl;if(r.vao.bind(),i===r.opacity<1||a){t.bind();var s=t.uniforms;s.model=n.model||c,s.view=n.view||c,s.projection=n.projection||c,g[0]=2/o.drawingBufferWidth,g[1]=2/o.drawingBufferHeight,s.screenSize=g,s.highlightId=r.highlightId,s.highlightScale=r.highlightScale,s.fragClipBounds=S,s.clipBounds=r.axes.bounds,s.opacity=r.opacity,s.pickGroup=r.pickId/255,s.pixelRatio=r.pixelRatio,r.vao.draw(o.TRIANGLES,r.vertexCount),r.lineWidth>0&&(o.lineWidth(r.lineWidth),r.vao.draw(o.LINES,r.lineVertexCount,r.vertexCount))}T(e,r,n,i),r.vao.unbind()}d.draw=function(t){E(this.useOrtho?this.orthoShader:this.shader,this.projectShader,this,t,!1,!1)},d.drawTransparent=function(t){E(this.useOrtho?this.orthoShader:this.shader,this.projectShader,this,t,!0,!1)},d.drawPick=function(t){E(this.useOrtho?this.pickOrthoShader:this.pickPerspectiveShader,this.pickProjectShader,this,t,!1,!0)},d.pick=function(t){if(!t)return null;if(t.id!==this.pickId)return null;var e=t.value[2]+(t.value[1]<<8)+(t.value[0]<<16);if(e>=this.pointCount||e<0)return null;var r=this.points[e],n=this._selectResult;n.index=e;for(var i=0;i<3;++i)n.position[i]=n.dataCoordinate[i]=r[i];return n},d.highlight=function(t){if(t){var e=t.index,r=255&e,n=e>>8&255,i=e>>16&255;this.highlightId=[r/255,n/255,i/255,0]}else this.highlightId=[1,1,1,1]},d.update=function(t){if("perspective"in(t=t||{})&&(this.useOrtho=!t.perspective),"orthographic"in t&&(this.useOrtho=!!t.orthographic),"lineWidth"in t&&(this.lineWidth=t.lineWidth),"project"in t)if(Array.isArray(t.project))this.axesProject=t.project;else{var e=!!t.project;this.axesProject=[e,e,e]}if("projectScale"in t)if(Array.isArray(t.projectScale))this.projectScale=t.projectScale.slice();else{var r=+t.projectScale;this.projectScale=[r,r,r]}if("projectOpacity"in t)if(Array.isArray(t.projectOpacity))this.projectOpacity=t.projectOpacity.slice();else{r=+t.projectOpacity;this.projectOpacity=[r,r,r]}"opacity"in t&&(this.opacity=t.opacity),this.dirty=!0;var n=t.position;if(n){var i=t.font||"normal",o=t.alignment||[0,0],s=[1/0,1/0,1/0],c=[-1/0,-1/0,-1/0],u=t.glyph,h=t.color,f=t.size,p=t.angle,d=t.lineColor,g=0,m=0,v=0,y=n.length;t:for(var x=0;x0&&(L[0]=-o[0]*(1+M[0][0]));var q=w.cells,H=w.positions;for(_=0;_0){var v=r*u;o.drawBox(h-v,f-v,p+v,f+v,a),o.drawBox(h-v,d-v,p+v,d+v,a),o.drawBox(h-v,f-v,h+v,d+v,a),o.drawBox(p-v,f-v,p+v,d+v,a)}}}},s.update=function(t){t=t||{},this.innerFill=!!t.innerFill,this.outerFill=!!t.outerFill,this.innerColor=(t.innerColor||[0,0,0,.5]).slice(),this.outerColor=(t.outerColor||[0,0,0,.5]).slice(),this.borderColor=(t.borderColor||[0,0,0,1]).slice(),this.borderWidth=t.borderWidth||0,this.selectBox=(t.selectBox||this.selectBox).slice()},s.dispose=function(){this.boxBuffer.dispose(),this.boxShader.dispose(),this.plot.removeOverlay(this)}},{"./lib/shaders":284,"gl-buffer":230,"gl-shader":287}],286:[function(t,e,r){"use strict";e.exports=function(t,e){var r=n(t,e),a=i.mallocUint8(e[0]*e[1]*4);return new c(t,r,a)};var n=t("gl-fbo"),i=t("typedarray-pool"),a=t("ndarray"),o=t("bit-twiddle").nextPow2,s=t("cwise/lib/wrapper")({args:["array",{offset:[0,0,1],array:0},{offset:[0,0,2],array:0},{offset:[0,0,3],array:0},"scalar","scalar","index"],pre:{body:"{this_closestD2=1e8,this_closestX=-1,this_closestY=-1}",args:[],thisVars:["this_closestD2","this_closestX","this_closestY"],localVars:[]},body:{body:"{if(_inline_16_arg0_<255||_inline_16_arg1_<255||_inline_16_arg2_<255||_inline_16_arg3_<255){var _inline_16_l=_inline_16_arg4_-_inline_16_arg6_[0],_inline_16_a=_inline_16_arg5_-_inline_16_arg6_[1],_inline_16_f=_inline_16_l*_inline_16_l+_inline_16_a*_inline_16_a;_inline_16_fthis.buffer.length){i.free(this.buffer);for(var n=this.buffer=i.mallocUint8(o(r*e*4)),a=0;ar)for(t=r;te)for(t=e;t=0){for(var k=0|w.type.charAt(w.type.length-1),M=new Array(k),A=0;A=0;)T+=1;_[y]=T}var S=new Array(r.length);function E(){f.program=o.program(p,f._vref,f._fref,b,_);for(var t=0;t=0){var d=f.charCodeAt(f.length-1)-48;if(d<2||d>4)throw new n("","Invalid data type for attribute "+h+": "+f);o(t,e,p[0],i,d,a,h)}else{if(!(f.indexOf("mat")>=0))throw new n("","Unknown data type for attribute "+h+": "+f);var d=f.charCodeAt(f.length-1)-48;if(d<2||d>4)throw new n("","Invalid data type for attribute "+h+": "+f);s(t,e,p,i,d,a,h)}}}return a};var n=t("./GLError");function i(t,e,r,n,i,a){this._gl=t,this._wrapper=e,this._index=r,this._locations=n,this._dimension=i,this._constFunc=a}var a=i.prototype;function o(t,e,r,n,a,o,s){for(var l=["gl","v"],c=[],u=0;u4)throw new i("","Invalid uniform dimension type for matrix "+name+": "+r);return"gl.uniformMatrix"+a+"fv(locations["+e+"],false,obj"+t+")"}throw new i("","Unknown uniform data type for "+name+": "+r)}var a=r.charCodeAt(r.length-1)-48;if(a<2||a>4)throw new i("","Invalid data type");switch(r.charAt(0)){case"b":case"i":return"gl.uniform"+a+"iv(locations["+e+"],obj"+t+")";case"v":return"gl.uniform"+a+"fv(locations["+e+"],obj"+t+")";default:throw new i("","Unrecognized data type for vector "+name+": "+r)}}}function c(e){for(var n=["return function updateProperty(obj){"],i=function t(e,r){if("object"!=typeof r)return[[e,r]];var n=[];for(var i in r){var a=r[i],o=e;parseInt(i)+""===i?o+="["+i+"]":o+="."+i,"object"==typeof a?n.push.apply(n,t(o,a)):n.push([o,a])}return n}("",e),a=0;a4)throw new i("","Invalid data type");return"b"===t.charAt(0)?o(r,!1):o(r,0)}if(0===t.indexOf("mat")&&4===t.length){var r=t.charCodeAt(t.length-1)-48;if(r<2||r>4)throw new i("","Invalid uniform dimension type for matrix "+name+": "+t);return o(r*r,0)}throw new i("","Unknown uniform data type for "+name+": "+t)}}(r[u].type);var p}function h(t){var e;if(Array.isArray(t)){e=new Array(t.length);for(var r=0;r1){l[0]in o||(o[l[0]]=[]),o=o[l[0]];for(var c=1;c1)for(var l=0;l 0 U ||b|| > 0.\n // Assign z = 0, x = -b, y = a:\n // a*-b + b*a + c*0 = -ba + ba + 0 = 0\n if (v.x*v.x > v.z*v.z || v.y*v.y > v.z*v.z) {\n return normalize(vec3(-v.y, v.x, 0.0));\n } else {\n return normalize(vec3(0.0, v.z, -v.y));\n }\n}\n\n// Calculate the tube vertex and normal at the given index.\n//\n// The returned vertex is for a tube ring with its center at origin, radius of length(d), pointing in the direction of d.\n//\n// Each tube segment is made up of a ring of vertices.\n// These vertices are used to make up the triangles of the tube by connecting them together in the vertex array.\n// The indexes of tube segments run from 0 to 8.\n//\nvec3 getTubePosition(vec3 d, float index, out vec3 normal) {\n float segmentCount = 8.0;\n\n float angle = 2.0 * 3.14159 * (index / segmentCount);\n\n vec3 u = getOrthogonalVector(d);\n vec3 v = normalize(cross(u, d));\n\n vec3 x = u * cos(angle) * length(d);\n vec3 y = v * sin(angle) * length(d);\n vec3 v3 = x + y;\n\n normal = normalize(v3);\n\n return v3;\n}\n\nattribute vec4 vector;\nattribute vec4 color, position;\nattribute vec2 uv;\nuniform float tubeScale;\n\nuniform mat4 model\n , view\n , projection;\nuniform vec3 eyePosition\n , lightPosition;\n\nvarying vec3 f_normal\n , f_lightDirection\n , f_eyeDirection\n , f_data;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n // Scale the vector magnitude to stay constant with\n // model & view changes.\n vec3 normal;\n vec4 tubePosition = model * vec4(position.xyz, 1.0) + vec4(getTubePosition(mat3(model) * (tubeScale * vector.w * normalize(vector.xyz)), position.w, normal), 0.0);\n normal = normalize(normal * inverse(mat3(model)));\n\n vec4 t_position = view * tubePosition;\n gl_Position = projection * t_position;\n f_color = color;\n f_normal = normal;\n f_data = tubePosition.xyz;\n f_eyeDirection = eyePosition - tubePosition.xyz;\n f_lightDirection = lightPosition - tubePosition.xyz;\n f_uv = uv;\n}\n"]),a=n(["precision mediump float;\n#define GLSLIFY 1\n\nfloat beckmannDistribution(float x, float roughness) {\n float NdotH = max(x, 0.0001);\n float cos2Alpha = NdotH * NdotH;\n float tan2Alpha = (cos2Alpha - 1.0) / cos2Alpha;\n float roughness2 = roughness * roughness;\n float denom = 3.141592653589793 * roughness2 * cos2Alpha * cos2Alpha;\n return exp(tan2Alpha / roughness2) / denom;\n}\n\nfloat cookTorranceSpecular(\n vec3 lightDirection,\n vec3 viewDirection,\n vec3 surfaceNormal,\n float roughness,\n float fresnel) {\n\n float VdotN = max(dot(viewDirection, surfaceNormal), 0.0);\n float LdotN = max(dot(lightDirection, surfaceNormal), 0.0);\n\n //Half angle vector\n vec3 H = normalize(lightDirection + viewDirection);\n\n //Geometric term\n float NdotH = max(dot(surfaceNormal, H), 0.0);\n float VdotH = max(dot(viewDirection, H), 0.000001);\n float LdotH = max(dot(lightDirection, H), 0.000001);\n float G1 = (2.0 * NdotH * VdotN) / VdotH;\n float G2 = (2.0 * NdotH * LdotN) / LdotH;\n float G = min(1.0, min(G1, G2));\n \n //Distribution term\n float D = beckmannDistribution(NdotH, roughness);\n\n //Fresnel term\n float F = pow(1.0 - VdotN, fresnel);\n\n //Multiply terms and done\n return G * F * D / max(3.14159265 * VdotN, 0.000001);\n}\n\nuniform vec3 clipBounds[2];\nuniform float roughness\n , fresnel\n , kambient\n , kdiffuse\n , kspecular\n , opacity;\nuniform sampler2D texture;\n\nvarying vec3 f_normal\n , f_lightDirection\n , f_eyeDirection\n , f_data;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n vec3 N = normalize(f_normal);\n vec3 L = normalize(f_lightDirection);\n vec3 V = normalize(f_eyeDirection);\n \n if(!gl_FrontFacing) {\n N = -N;\n }\n\n float specular = cookTorranceSpecular(L, V, N, roughness, fresnel);\n float diffuse = min(kambient + kdiffuse * max(dot(N, L), 0.0), 1.0);\n\n vec4 surfaceColor = texture2D(texture, f_uv);\n vec4 litColor = surfaceColor.a * vec4(diffuse * surfaceColor.rgb + kspecular * vec3(1,1,1) * specular, 1.0);\n\n gl_FragColor = litColor * opacity;\n}"]),o=n(["precision mediump float;\n#define GLSLIFY 1\n\nvec3 getOrthogonalVector(vec3 v) {\n // Return up-vector for only-z vector.\n // Return ax + by + cz = 0, a point that lies on the plane that has v as a normal and that isn't (0,0,0).\n // From the above if-statement we have ||a|| > 0 U ||b|| > 0.\n // Assign z = 0, x = -b, y = a:\n // a*-b + b*a + c*0 = -ba + ba + 0 = 0\n if (v.x*v.x > v.z*v.z || v.y*v.y > v.z*v.z) {\n return normalize(vec3(-v.y, v.x, 0.0));\n } else {\n return normalize(vec3(0.0, v.z, -v.y));\n }\n}\n\n// Calculate the tube vertex and normal at the given index.\n//\n// The returned vertex is for a tube ring with its center at origin, radius of length(d), pointing in the direction of d.\n//\n// Each tube segment is made up of a ring of vertices.\n// These vertices are used to make up the triangles of the tube by connecting them together in the vertex array.\n// The indexes of tube segments run from 0 to 8.\n//\nvec3 getTubePosition(vec3 d, float index, out vec3 normal) {\n float segmentCount = 8.0;\n\n float angle = 2.0 * 3.14159 * (index / segmentCount);\n\n vec3 u = getOrthogonalVector(d);\n vec3 v = normalize(cross(u, d));\n\n vec3 x = u * cos(angle) * length(d);\n vec3 y = v * sin(angle) * length(d);\n vec3 v3 = x + y;\n\n normal = normalize(v3);\n\n return v3;\n}\n\nattribute vec4 vector;\nattribute vec4 position;\nattribute vec4 id;\n\nuniform mat4 model, view, projection;\nuniform float tubeScale;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n vec3 normal;\n vec4 tubePosition = model * vec4(position.xyz, 1.0) + vec4(getTubePosition(mat3(model) * (tubeScale * vector.w * normalize(vector.xyz)), position.w, normal), 0.0);\n gl_Position = projection * view * tubePosition;\n f_id = id;\n f_position = position.xyz;\n}\n"]),s=n(["precision mediump float;\n#define GLSLIFY 1\n\nuniform vec3 clipBounds[2];\nuniform float pickId;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n gl_FragColor = vec4(pickId, f_id.xyz);\n}"]);r.meshShader={vertex:i,fragment:a,attributes:[{name:"position",type:"vec4"},{name:"normal",type:"vec3"},{name:"color",type:"vec4"},{name:"uv",type:"vec2"},{name:"vector",type:"vec4"}]},r.pickShader={vertex:o,fragment:s,attributes:[{name:"position",type:"vec4"},{name:"id",type:"vec4"},{name:"vector",type:"vec4"}]}},{glslify:377}],299:[function(t,e,r){"use strict";var n=t("gl-shader"),i=t("gl-buffer"),a=t("gl-vao"),o=t("gl-texture2d"),s=t("normals"),l=t("gl-mat4/multiply"),c=t("gl-mat4/invert"),u=t("ndarray"),h=t("colormap"),f=t("simplicial-complex-contour"),p=t("typedarray-pool"),d=t("./shaders"),g=(t("./closest-point"),d.meshShader),m=d.pickShader,v=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];function y(t,e,r,n,i,a,o,s,l,c,u,h,f,p,d,g,m,y,x,b,_,w,k,M,A,T,S,E){this.gl=t,this.cells=[],this.positions=[],this.intensity=[],this.texture=e,this.dirty=!0,this.triShader=r,this.lineShader=n,this.pointShader=i,this.pickShader=a,this.pointPickShader=o,this.contourShader=s,this.trianglePositions=l,this.triangleVectors=c,this.triangleColors=h,this.triangleNormals=p,this.triangleUVs=f,this.triangleIds=u,this.triangleVAO=d,this.triangleCount=0,this.lineWidth=1,this.edgePositions=g,this.edgeColors=y,this.edgeUVs=x,this.edgeIds=m,this.edgeVAO=b,this.edgeCount=0,this.pointPositions=_,this.pointColors=k,this.pointUVs=M,this.pointSizes=A,this.pointIds=w,this.pointVAO=T,this.pointCount=0,this.contourLineWidth=1,this.contourPositions=S,this.contourVAO=E,this.contourCount=0,this.contourColor=[0,0,0],this.contourEnable=!1,this.pickId=1,this.bounds=[[1/0,1/0,1/0],[-1/0,-1/0,-1/0]],this.clipBounds=[[-1/0,-1/0,-1/0],[1/0,1/0,1/0]],this.lightPosition=[1e5,1e5,0],this.ambientLight=.8,this.diffuseLight=.8,this.specularLight=2,this.roughness=.5,this.fresnel=1.5,this.opacity=1,this.tubeScale=1,this._model=v,this._view=v,this._projection=v,this._resolution=[1,1]}var x=y.prototype;function b(t){var e=n(t,m.vertex,m.fragment,null,m.attributes);return e.attributes.position.location=0,e.attributes.id.location=1,e.attributes.vector.location=5,e}x.isOpaque=function(){return this.opacity>=1},x.isTransparent=function(){return this.opacity<1},x.pickSlots=1,x.setPickBase=function(t){this.pickId=t},x.highlight=function(t){if(t&&this.contourEnable){for(var e=f(this.cells,this.intensity,t.intensity),r=e.cells,n=e.vertexIds,i=e.vertexWeights,a=r.length,o=p.mallocFloat32(6*a),s=0,l=0;l0&&((h=this.triShader).bind(),h.uniforms=s,this.triangleVAO.bind(),e.drawArrays(e.TRIANGLES,0,3*this.triangleCount),this.triangleVAO.unbind());this.edgeCount>0&&this.lineWidth>0&&((h=this.lineShader).bind(),h.uniforms=s,this.edgeVAO.bind(),e.lineWidth(this.lineWidth),e.drawArrays(e.LINES,0,2*this.edgeCount),this.edgeVAO.unbind());this.pointCount>0&&((h=this.pointShader).bind(),h.uniforms=s,this.pointVAO.bind(),e.drawArrays(e.POINTS,0,this.pointCount),this.pointVAO.unbind());this.contourEnable&&this.contourCount>0&&this.contourLineWidth>0&&((h=this.contourShader).bind(),h.uniforms=s,this.contourVAO.bind(),e.drawArrays(e.LINES,0,this.contourCount),this.contourVAO.unbind())},x.drawPick=function(t){t=t||{};for(var e=this.gl,r=t.model||v,n=t.view||v,i=t.projection||v,a=[[-1e6,-1e6,-1e6],[1e6,1e6,1e6]],o=0;o<3;++o)a[0][o]=Math.max(a[0][o],this.clipBounds[0][o]),a[1][o]=Math.min(a[1][o],this.clipBounds[1][o]);this._model=[].slice.call(r),this._view=[].slice.call(n),this._projection=[].slice.call(i),this._resolution=[e.drawingBufferWidth,e.drawingBufferHeight];var s,l={model:r,view:n,projection:i,clipBounds:a,tubeScale:this.tubeScale,pickId:this.pickId/255};((s=this.pickShader).bind(),s.uniforms=l,this.triangleCount>0&&(this.triangleVAO.bind(),e.drawArrays(e.TRIANGLES,0,3*this.triangleCount),this.triangleVAO.unbind()),this.edgeCount>0&&(this.edgeVAO.bind(),e.lineWidth(this.lineWidth),e.drawArrays(e.LINES,0,2*this.edgeCount),this.edgeVAO.unbind()),this.pointCount>0)&&((s=this.pointPickShader).bind(),s.uniforms=l,this.pointVAO.bind(),e.drawArrays(e.POINTS,0,this.pointCount),this.pointVAO.unbind())},x.pick=function(t){if(!t)return null;if(t.id!==this.pickId)return null;var e=t.value[0]+256*t.value[1]+65536*t.value[2],r=this.cells[e],n=this.positions[r[1]].slice(0,3);return{index:e,position:n,intensity:this.intensity[r[1]],velocity:this.vectors[r[1]].slice(0,3),divergence:this.vectors[r[1]][3],dataCoordinate:n}},x.dispose=function(){this.texture.dispose(),this.triShader.dispose(),this.pickShader.dispose(),this.triangleVAO.dispose(),this.trianglePositions.dispose(),this.triangleVectors.dispose(),this.triangleColors.dispose(),this.triangleUVs.dispose(),this.triangleNormals.dispose(),this.triangleIds.dispose(),this.edgeVAO.dispose(),this.edgePositions.dispose(),this.edgeColors.dispose(),this.edgeUVs.dispose(),this.edgeIds.dispose(),this.pointVAO.dispose(),this.pointPositions.dispose(),this.pointColors.dispose(),this.pointUVs.dispose(),this.pointSizes.dispose(),this.pointIds.dispose(),this.contourVAO.dispose(),this.contourPositions.dispose()},e.exports=function(t,e){1===arguments.length&&(t=(e=t).gl);var r=e.triShader||function(t){var e=n(t,g.vertex,g.fragment,null,g.attributes);return e.attributes.position.location=0,e.attributes.color.location=2,e.attributes.uv.location=3,e.attributes.vector.location=5,e}(t),s=b(t),l=o(t,u(new Uint8Array([255,255,255,255]),[1,1,4]));l.generateMipmap(),l.minFilter=t.LINEAR_MIPMAP_LINEAR,l.magFilter=t.LINEAR;var c=i(t),h=i(t),f=i(t),p=i(t),d=i(t),m=i(t),v=a(t,[{buffer:c,type:t.FLOAT,size:4},{buffer:m,type:t.UNSIGNED_BYTE,size:4,normalized:!0},{buffer:f,type:t.FLOAT,size:4},{buffer:p,type:t.FLOAT,size:2},{buffer:d,type:t.FLOAT,size:3},{buffer:h,type:t.FLOAT,size:4}]),x=i(t),_=i(t),w=i(t),k=i(t),M=a(t,[{buffer:x,type:t.FLOAT,size:3},{buffer:k,type:t.UNSIGNED_BYTE,size:4,normalized:!0},{buffer:_,type:t.FLOAT,size:4},{buffer:w,type:t.FLOAT,size:2}]),A=i(t),T=i(t),S=i(t),E=i(t),C=i(t),L=a(t,[{buffer:A,type:t.FLOAT,size:3},{buffer:C,type:t.UNSIGNED_BYTE,size:4,normalized:!0},{buffer:T,type:t.FLOAT,size:4},{buffer:S,type:t.FLOAT,size:2},{buffer:E,type:t.FLOAT,size:1}]),z=i(t),P=new y(t,l,r,null,null,s,null,null,c,h,m,f,p,d,v,x,k,_,w,M,A,C,T,S,E,L,z,a(t,[{buffer:z,type:t.FLOAT,size:3}]));return P.update(e),P}},{"./closest-point":297,"./shaders":298,colormap:113,"gl-buffer":230,"gl-mat4/invert":254,"gl-mat4/multiply":256,"gl-shader":287,"gl-texture2d":303,"gl-vao":308,ndarray:417,normals:420,"simplicial-complex-contour":479,"typedarray-pool":507}],300:[function(t,e,r){"use strict";var n=t("gl-vec3"),i=t("gl-vec4"),a=function(t,e,r,a){for(var o=0,s=0;so&&(o=u)}var h=t.map(function(t){return function(t,e,r,a){var o,s,l,c=t.points,u=t.velocities,h=t.divergences;n.set(n.create(),0,1,0),n.create(),n.create();n.create();for(var f=[],p=[],d=[],g=[],m=[],v=[],y=0,x=0,b=i.create(),_=i.create(),w=0;w0)for(k=0;k<8;k++){var M=(k+1)%8;f.push(g[k],m[k],m[M],m[M],g[M],g[k]),d.push(_,b,b,b,_,_),v.push(y,x,x,x,y,y),p.push([f.length-6,f.length-5,f.length-4],[f.length-3,f.length-2,f.length-1])}var A=g;g=m,m=A,A=_,_=b,b=A,A=y,y=x,x=A}return{positions:f,cells:p,vectors:d,vertexIntensity:v}}(t,r,a,o)}),f=[],p=[],d=[],g=[];for(s=0;se)return r-1}return r},c=n.create(),u=n.create(),h=function(t,e,r){return tr?r:t},f=function(t,e,r,i){var a=t[0],o=t[1],s=t[2],f=r[0].length,p=r[1].length,d=r[2].length,g=l(r[0],a),m=l(r[1],o),v=l(r[2],s),y=g+1,x=m+1,b=v+1;if(r[0][g]===a&&(y=g),r[1][m]===o&&(x=m),r[2][v]===s&&(b=v),i&&(g=h(g,0,f-1),y=h(y,0,f-1),m=h(m,0,p-1),x=h(x,0,p-1),v=h(v,0,d-1),b=h(b,0,d-1)),g<0||m<0||v<0||y>=f||x>=p||b>=d)return n.create();var _=(a-r[0][g])/(r[0][y]-r[0][g]),w=(o-r[1][m])/(r[1][x]-r[1][m]),k=(s-r[2][v])/(r[2][b]-r[2][v]);(_<0||_>1||isNaN(_))&&(_=0),(w<0||w>1||isNaN(w))&&(w=0),(k<0||k>1||isNaN(k))&&(k=0);var M=v*f*p,A=b*f*p,T=m*f,S=x*f,E=g,C=y,L=e[T+M+E],z=e[T+M+C],P=e[S+M+E],I=e[S+M+C],O=e[T+A+E],D=e[T+A+C],R=e[S+A+E],B=e[S+A+C],F=n.create();return n.lerp(F,L,z,_),n.lerp(c,P,I,_),n.lerp(F,F,c,w),n.lerp(c,O,D,_),n.lerp(u,R,B,_),n.lerp(c,c,u,w),n.lerp(F,F,c,k),F},p=function(t){var e=1/0;t.sort(function(t,e){return t-e});for(var r=1;r=h&&r<=g&&n>=f&&n<=m&&i>=d&&i<=v},x=10*n.distance(e[0],e[1])/i,b=x*x,_=1,w=0;n.create();r.length>=2&&(_=function(t){for(var e=[],r=[],n=[],i={},a={},o={},s=0;sw&&!isNaN(O)&&isFinite(O)&&(w=O),C.push(O),u.push({points:A,velocities:T,divergences:C});for(var z=0;z<100*i&&A.lengthb&&n.scale(P,P,x/Math.sqrt(I)),n.add(P,P,M),S=t.getVelocity(P),n.squaredDistance(E,P)-b>-1e-4*b){A.push(P),E=P,T.push(S);L=t.getDivergence(P,S);(O=n.length(L))>w&&!isNaN(O)&&isFinite(O)&&(w=O),C.push(O)}M=P}}for(k=0;k 0.0 ||\n any(lessThan(worldCoordinate, clipBounds[0])) || any(greaterThan(worldCoordinate, clipBounds[1]))) {\n discard;\n }\n\n vec3 N = normalize(surfaceNormal);\n vec3 V = normalize(eyeDirection);\n vec3 L = normalize(lightDirection);\n\n if(gl_FrontFacing) {\n N = -N;\n }\n\n float specular = max(beckmannSpecular(L, V, N, roughness), 0.);\n float diffuse = min(kambient + kdiffuse * max(dot(N, L), 0.0), 1.0);\n\n //decide how to interpolate color \u2014 in vertex or in fragment\n vec4 surfaceColor = step(vertexColor, .5) * texture2D(colormap, vec2(value, value)) + step(.5, vertexColor) * vColor;\n\n vec4 litColor = surfaceColor.a * vec4(diffuse * surfaceColor.rgb + kspecular * vec3(1,1,1) * specular, 1.0);\n\n gl_FragColor = mix(litColor, contourColor, contourTint) * opacity;\n}\n"]),s=i(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec4 uv;\nattribute float f;\n\nuniform mat3 permutation;\nuniform mat4 model, view, projection;\nuniform float height, zOffset;\nuniform sampler2D colormap;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec2 planeCoordinate;\nvarying vec3 lightDirection, eyeDirection, surfaceNormal;\nvarying vec4 vColor;\n\nvoid main() {\n vec3 dataCoordinate = permutation * vec3(uv.xy, height);\n vec4 worldPosition = model * vec4(dataCoordinate, 1.0);\n\n vec4 clipPosition = projection * view * worldPosition;\n clipPosition.z = clipPosition.z + zOffset;\n\n gl_Position = clipPosition;\n value = f;\n kill = -1.0;\n worldCoordinate = dataCoordinate;\n planeCoordinate = uv.zw;\n\n vColor = texture2D(colormap, vec2(value, value));\n\n //Don't do lighting for contours\n surfaceNormal = vec3(1,0,0);\n eyeDirection = vec3(0,1,0);\n lightDirection = vec3(0,0,1);\n}\n"]),l=i(["precision mediump float;\n#define GLSLIFY 1\n\nuniform vec2 shape;\nuniform vec3 clipBounds[2];\nuniform float pickId;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec2 planeCoordinate;\nvarying vec3 surfaceNormal;\n\nvec2 splitFloat(float v) {\n float vh = 255.0 * v;\n float upper = floor(vh);\n float lower = fract(vh);\n return vec2(upper / 255.0, floor(lower * 16.0) / 16.0);\n}\n\nvoid main() {\n if(kill > 0.0 ||\n any(lessThan(worldCoordinate, clipBounds[0])) || any(greaterThan(worldCoordinate, clipBounds[1]))) {\n discard;\n }\n vec2 ux = splitFloat(planeCoordinate.x / shape.x);\n vec2 uy = splitFloat(planeCoordinate.y / shape.y);\n gl_FragColor = vec4(pickId, ux.x, uy.x, ux.y + (uy.y/16.0));\n}\n"]);r.createShader=function(t){var e=n(t,a,o,null,[{name:"uv",type:"vec4"},{name:"f",type:"vec3"},{name:"normal",type:"vec3"}]);return e.attributes.uv.location=0,e.attributes.f.location=1,e.attributes.normal.location=2,e},r.createPickShader=function(t){var e=n(t,a,l,null,[{name:"uv",type:"vec4"},{name:"f",type:"vec3"},{name:"normal",type:"vec3"}]);return e.attributes.uv.location=0,e.attributes.f.location=1,e.attributes.normal.location=2,e},r.createContourShader=function(t){var e=n(t,s,o,null,[{name:"uv",type:"vec4"},{name:"f",type:"float"}]);return e.attributes.uv.location=0,e.attributes.f.location=1,e},r.createPickContourShader=function(t){var e=n(t,s,l,null,[{name:"uv",type:"vec4"},{name:"f",type:"float"}]);return e.attributes.uv.location=0,e.attributes.f.location=1,e}},{"gl-shader":287,glslify:377}],302:[function(t,e,r){"use strict";e.exports=function(t){var e=t.gl,r=y(e),n=b(e),s=x(e),l=_(e),c=i(e),u=a(e,[{buffer:c,size:4,stride:w,offset:0},{buffer:c,size:3,stride:w,offset:16},{buffer:c,size:3,stride:w,offset:28}]),h=i(e),f=a(e,[{buffer:h,size:4,stride:20,offset:0},{buffer:h,size:1,stride:20,offset:16}]),p=i(e),d=a(e,[{buffer:p,size:2,type:e.FLOAT}]),g=o(e,1,S,e.RGBA,e.UNSIGNED_BYTE);g.minFilter=e.LINEAR,g.magFilter=e.LINEAR;var m=new E(e,[0,0],[[0,0,0],[0,0,0]],r,n,c,u,g,s,l,h,f,p,d),v={levels:[[],[],[]]};for(var k in t)v[k]=t[k];return v.colormap=v.colormap||"jet",m.update(v),m};var n=t("bit-twiddle"),i=t("gl-buffer"),a=t("gl-vao"),o=t("gl-texture2d"),s=t("typedarray-pool"),l=t("colormap"),c=t("ndarray-ops"),u=t("ndarray-pack"),h=t("ndarray"),f=t("surface-nets"),p=t("gl-mat4/multiply"),d=t("gl-mat4/invert"),g=t("binary-search-bounds"),m=t("ndarray-gradient"),v=t("./lib/shaders"),y=v.createShader,x=v.createContourShader,b=v.createPickShader,_=v.createPickContourShader,w=40,k=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],M=[[0,0],[0,1],[1,0],[1,1],[1,0],[0,1]],A=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];function T(t,e,r,n,i){this.position=t,this.index=e,this.uv=r,this.level=n,this.dataCoordinate=i}!function(){for(var t=0;t<3;++t){var e=A[t],r=(t+2)%3;e[(t+1)%3+0]=1,e[r+3]=1,e[t+6]=1}}();var S=256;function E(t,e,r,n,i,a,o,l,c,u,f,p,d,g){this.gl=t,this.shape=e,this.bounds=r,this.intensityBounds=[],this._shader=n,this._pickShader=i,this._coordinateBuffer=a,this._vao=o,this._colorMap=l,this._contourShader=c,this._contourPickShader=u,this._contourBuffer=f,this._contourVAO=p,this._contourOffsets=[[],[],[]],this._contourCounts=[[],[],[]],this._vertexCount=0,this._pickResult=new T([0,0,0],[0,0],[0,0],[0,0,0],[0,0,0]),this._dynamicBuffer=d,this._dynamicVAO=g,this._dynamicOffsets=[0,0,0],this._dynamicCounts=[0,0,0],this.contourWidth=[1,1,1],this.contourLevels=[[1],[1],[1]],this.contourTint=[0,0,0],this.contourColor=[[.5,.5,.5,1],[.5,.5,.5,1],[.5,.5,.5,1]],this.showContour=!0,this.showSurface=!0,this.enableHighlight=[!0,!0,!0],this.highlightColor=[[0,0,0,1],[0,0,0,1],[0,0,0,1]],this.highlightTint=[1,1,1],this.highlightLevel=[-1,-1,-1],this.enableDynamic=[!0,!0,!0],this.dynamicLevel=[NaN,NaN,NaN],this.dynamicColor=[[0,0,0,1],[0,0,0,1],[0,0,0,1]],this.dynamicTint=[1,1,1],this.dynamicWidth=[1,1,1],this.axesBounds=[[1/0,1/0,1/0],[-1/0,-1/0,-1/0]],this.surfaceProject=[!1,!1,!1],this.contourProject=[[!1,!1,!1],[!1,!1,!1],[!1,!1,!1]],this.colorBounds=[!1,!1],this._field=[h(s.mallocFloat(1024),[0,0]),h(s.mallocFloat(1024),[0,0]),h(s.mallocFloat(1024),[0,0])],this.pickId=1,this.clipBounds=[[-1/0,-1/0,-1/0],[1/0,1/0,1/0]],this.snapToData=!1,this.opacity=1,this.lightPosition=[10,1e4,0],this.ambientLight=.8,this.diffuseLight=.8,this.specularLight=2,this.roughness=.5,this.fresnel=1.5,this.vertexColor=0,this.dirty=!0}var C=E.prototype;C.isTransparent=function(){return this.opacity<1},C.isOpaque=function(){if(this.opacity>=1)return!0;for(var t=0;t<3;++t)if(this._contourCounts[t].length>0||this._dynamicCounts[t]>0)return!0;return!1},C.pickSlots=1,C.setPickBase=function(t){this.pickId=t};var L=[0,0,0],z={showSurface:!1,showContour:!1,projections:[k.slice(),k.slice(),k.slice()],clipBounds:[[[0,0,0],[0,0,0]],[[0,0,0],[0,0,0]],[[0,0,0],[0,0,0]]]};function P(t,e){var r,n,i,a=e.axes&&e.axes.lastCubeProps.axis||L,o=e.showSurface,s=e.showContour;for(r=0;r<3;++r)for(o=o||e.surfaceProject[r],n=0;n<3;++n)s=s||e.contourProject[r][n];for(r=0;r<3;++r){var l=z.projections[r];for(n=0;n<16;++n)l[n]=0;for(n=0;n<4;++n)l[5*n]=1;l[5*r]=0,l[12+r]=e.axesBounds[+(a[r]>0)][r],p(l,t.model,l);var c=z.clipBounds[r];for(i=0;i<2;++i)for(n=0;n<3;++n)c[i][n]=t.clipBounds[i][n];c[0][r]=-1e8,c[1][r]=1e8}return z.showSurface=o,z.showContour=s,z}var I={model:k,view:k,projection:k,inverseModel:k.slice(),lowerBound:[0,0,0],upperBound:[0,0,0],colorMap:0,clipBounds:[[0,0,0],[0,0,0]],height:0,contourTint:0,contourColor:[0,0,0,1],permutation:[1,0,0,0,1,0,0,0,1],zOffset:-1e-4,kambient:1,kdiffuse:1,kspecular:1,lightPosition:[1e3,1e3,1e3],eyePosition:[0,0,0],roughness:1,fresnel:1,opacity:1,vertexColor:0},O=k.slice(),D=[1,0,0,0,1,0,0,0,1];function R(t,e){t=t||{};var r=this.gl;r.disable(r.CULL_FACE),this._colorMap.bind(0);var n=I;n.model=t.model||k,n.view=t.view||k,n.projection=t.projection||k,n.lowerBound=[this.bounds[0][0],this.bounds[0][1],this.colorBounds[0]||this.bounds[0][2]],n.upperBound=[this.bounds[1][0],this.bounds[1][1],this.colorBounds[1]||this.bounds[1][2]],n.contourColor=this.contourColor[0],n.inverseModel=d(n.inverseModel,n.model);for(var i=0;i<2;++i)for(var a=n.clipBounds[i],o=0;o<3;++o)a[o]=Math.min(Math.max(this.clipBounds[i][o],-1e8),1e8);n.kambient=this.ambientLight,n.kdiffuse=this.diffuseLight,n.kspecular=this.specularLight,n.roughness=this.roughness,n.fresnel=this.fresnel,n.opacity=this.opacity,n.height=0,n.permutation=D,n.vertexColor=this.vertexColor;var s=O;for(p(s,n.view,n.model),p(s,n.projection,s),d(s,s),i=0;i<3;++i)n.eyePosition[i]=s[12+i]/s[15];var l=s[15];for(i=0;i<3;++i)l+=this.lightPosition[i]*s[4*i+3];for(i=0;i<3;++i){var c=s[12+i];for(o=0;o<3;++o)c+=s[4*o+i]*this.lightPosition[o];n.lightPosition[i]=c/l}var u=P(n,this);if(u.showSurface&&e===this.opacity<1){for(this._shader.bind(),this._shader.uniforms=n,this._vao.bind(),this.showSurface&&this._vertexCount&&this._vao.draw(r.TRIANGLES,this._vertexCount),i=0;i<3;++i)this.surfaceProject[i]&&this.vertexCount&&(this._shader.uniforms.model=u.projections[i],this._shader.uniforms.clipBounds=u.clipBounds[i],this._vao.draw(r.TRIANGLES,this._vertexCount));this._vao.unbind()}if(u.showContour&&!e){var h=this._contourShader;n.kambient=1,n.kdiffuse=0,n.kspecular=0,n.opacity=1,h.bind(),h.uniforms=n;var f=this._contourVAO;for(f.bind(),i=0;i<3;++i)for(h.uniforms.permutation=A[i],r.lineWidth(this.contourWidth[i]),o=0;o>4)/16)/255,i=Math.floor(n),a=n-i,o=e[1]*(t.value[1]+(15&t.value[2])/16)/255,s=Math.floor(o),l=o-s;i+=1,s+=1;var c=r.position;c[0]=c[1]=c[2]=0;for(var u=0;u<2;++u)for(var h=u?a:1-a,f=0;f<2;++f)for(var p=i+u,d=s+f,m=h*(f?l:1-l),v=0;v<3;++v)c[v]+=this._field[v].get(p,d)*m;for(var y=this._pickResult.level,x=0;x<3;++x)if(y[x]=g.le(this.contourLevels[x],c[x]),y[x]<0)this.contourLevels[x].length>0&&(y[x]=0);else if(y[x]Math.abs(_-c[x])&&(y[x]+=1)}for(r.index[0]=a<.5?i:i+1,r.index[1]=l<.5?s:s+1,r.uv[0]=n/e[0],r.uv[1]=o/e[1],v=0;v<3;++v)r.dataCoordinate[v]=this._field[v].get(r.index[0],r.index[1]);return r},C.update=function(t){t=t||{},this.dirty=!0,"contourWidth"in t&&(this.contourWidth=N(t.contourWidth,Number)),"showContour"in t&&(this.showContour=N(t.showContour,Boolean)),"showSurface"in t&&(this.showSurface=!!t.showSurface),"contourTint"in t&&(this.contourTint=N(t.contourTint,Boolean)),"contourColor"in t&&(this.contourColor=V(t.contourColor)),"contourProject"in t&&(this.contourProject=N(t.contourProject,function(t){return N(t,Boolean)})),"surfaceProject"in t&&(this.surfaceProject=t.surfaceProject),"dynamicColor"in t&&(this.dynamicColor=V(t.dynamicColor)),"dynamicTint"in t&&(this.dynamicTint=N(t.dynamicTint,Number)),"dynamicWidth"in t&&(this.dynamicWidth=N(t.dynamicWidth,Number)),"opacity"in t&&(this.opacity=t.opacity),"colorBounds"in t&&(this.colorBounds=t.colorBounds),"vertexColor"in t&&(this.vertexColor=t.vertexColor?1:0);var e=t.field||t.coords&&t.coords[2]||null,r=!1;if(e||(e=this._field[2].shape[0]||this._field[2].shape[2]?this._field[2].lo(1,1).hi(this._field[2].shape[0]-2,this._field[2].shape[1]-2):this._field[2].hi(0,0)),"field"in t||"coords"in t){var i=(e.shape[0]+2)*(e.shape[1]+2);i>this._field[2].data.length&&(s.freeFloat(this._field[2].data),this._field[2].data=s.mallocFloat(n.nextPow2(i))),this._field[2]=h(this._field[2].data,[e.shape[0]+2,e.shape[1]+2]),F(this._field[2],e),this.shape=e.shape.slice();for(var a=this.shape,o=0;o<2;++o)this._field[2].size>this._field[o].data.length&&(s.freeFloat(this._field[o].data),this._field[o].data=s.mallocFloat(this._field[2].size)),this._field[o]=h(this._field[o].data,[a[0]+2,a[1]+2]);if(t.coords){var p=t.coords;if(!Array.isArray(p)||3!==p.length)throw new Error("gl-surface: invalid coordinates for x/y");for(o=0;o<2;++o){var d=p[o];for(b=0;b<2;++b)if(d.shape[b]!==a[b])throw new Error("gl-surface: coords have incorrect shape");F(this._field[o],d)}}else if(t.ticks){var g=t.ticks;if(!Array.isArray(g)||2!==g.length)throw new Error("gl-surface: invalid ticks");for(o=0;o<2;++o){var v=g[o];if((Array.isArray(v)||v.length)&&(v=h(v)),v.shape[0]!==a[o])throw new Error("gl-surface: invalid tick length");var y=h(v.data,a);y.stride[o]=v.stride[0],y.stride[1^o]=0,F(this._field[o],y)}}else{for(o=0;o<2;++o){var x=[0,0];x[o]=1,this._field[o]=h(this._field[o].data,[a[0]+2,a[1]+2],x,0)}this._field[0].set(0,0,0);for(var b=0;b0){for(var kt=0;kt<5;++kt)nt.pop();W-=1}continue t}nt.push(st[0],st[1],ut[0],ut[1],st[2]),W+=1}}ot.push(W)}this._contourOffsets[it]=at,this._contourCounts[it]=ot}var Mt=s.mallocFloat(nt.length);for(o=0;os||o[1]<0||o[1]>s)throw new Error("gl-texture2d: Invalid texture size");var l=d(o,e.stride.slice()),c=0;"float32"===r?c=t.FLOAT:"float64"===r?(c=t.FLOAT,l=!1,r="float32"):"uint8"===r?c=t.UNSIGNED_BYTE:(c=t.UNSIGNED_BYTE,l=!1,r="uint8");var h,p,m=0;if(2===o.length)m=t.LUMINANCE,o=[o[0],o[1],1],e=n(e.data,o,[e.stride[0],e.stride[1],1],e.offset);else{if(3!==o.length)throw new Error("gl-texture2d: Invalid shape for texture");if(1===o[2])m=t.ALPHA;else if(2===o[2])m=t.LUMINANCE_ALPHA;else if(3===o[2])m=t.RGB;else{if(4!==o[2])throw new Error("gl-texture2d: Invalid shape for pixel coords");m=t.RGBA}}c!==t.FLOAT||t.getExtension("OES_texture_float")||(c=t.UNSIGNED_BYTE,l=!1);var v=e.size;if(l)h=0===e.offset&&e.data.length===v?e.data:e.data.subarray(e.offset,e.offset+v);else{var y=[o[2],o[2]*o[0],1];p=a.malloc(v,r);var x=n(p,o,y,0);"float32"!==r&&"float64"!==r||c!==t.UNSIGNED_BYTE?i.assign(x,e):u(x,e),h=p.subarray(0,v)}var b=g(t);t.texImage2D(t.TEXTURE_2D,0,m,o[0],o[1],0,m,c,h),l||a.free(p);return new f(t,b,o[0],o[1],m,c)}(t,e)}throw new Error("gl-texture2d: Invalid arguments for texture2d constructor")};var o=null,s=null,l=null;function c(t){return"undefined"!=typeof HTMLCanvasElement&&t instanceof HTMLCanvasElement||"undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement||"undefined"!=typeof HTMLVideoElement&&t instanceof HTMLVideoElement||"undefined"!=typeof ImageData&&t instanceof ImageData}var u=function(t,e){i.muls(t,e,255)};function h(t,e,r){var n=t.gl,i=n.getParameter(n.MAX_TEXTURE_SIZE);if(e<0||e>i||r<0||r>i)throw new Error("gl-texture2d: Invalid texture size");return t._shape=[e,r],t.bind(),n.texImage2D(n.TEXTURE_2D,0,t.format,e,r,0,t.format,t.type,null),t._mipLevels=[0],t}function f(t,e,r,n,i,a){this.gl=t,this.handle=e,this.format=i,this.type=a,this._shape=[r,n],this._mipLevels=[0],this._magFilter=t.NEAREST,this._minFilter=t.NEAREST,this._wrapS=t.CLAMP_TO_EDGE,this._wrapT=t.CLAMP_TO_EDGE,this._anisoSamples=1;var o=this,s=[this._wrapS,this._wrapT];Object.defineProperties(s,[{get:function(){return o._wrapS},set:function(t){return o.wrapS=t}},{get:function(){return o._wrapT},set:function(t){return o.wrapT=t}}]),this._wrapVector=s;var l=[this._shape[0],this._shape[1]];Object.defineProperties(l,[{get:function(){return o._shape[0]},set:function(t){return o.width=t}},{get:function(){return o._shape[1]},set:function(t){return o.height=t}}]),this._shapeVector=l}var p=f.prototype;function d(t,e){return 3===t.length?1===e[2]&&e[1]===t[0]*t[2]&&e[0]===t[2]:1===e[0]&&e[1]===t[0]}function g(t){var e=t.createTexture();return t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),e}function m(t,e,r,n,i){var a=t.getParameter(t.MAX_TEXTURE_SIZE);if(e<0||e>a||r<0||r>a)throw new Error("gl-texture2d: Invalid texture shape");if(i===t.FLOAT&&!t.getExtension("OES_texture_float"))throw new Error("gl-texture2d: Floating point textures not supported on this platform");var o=g(t);return t.texImage2D(t.TEXTURE_2D,0,n,e,r,0,n,i,null),new f(t,o,e,r,n,i)}Object.defineProperties(p,{minFilter:{get:function(){return this._minFilter},set:function(t){this.bind();var e=this.gl;if(this.type===e.FLOAT&&o.indexOf(t)>=0&&(e.getExtension("OES_texture_float_linear")||(t=e.NEAREST)),s.indexOf(t)<0)throw new Error("gl-texture2d: Unknown filter mode "+t);return e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,t),this._minFilter=t}},magFilter:{get:function(){return this._magFilter},set:function(t){this.bind();var e=this.gl;if(this.type===e.FLOAT&&o.indexOf(t)>=0&&(e.getExtension("OES_texture_float_linear")||(t=e.NEAREST)),s.indexOf(t)<0)throw new Error("gl-texture2d: Unknown filter mode "+t);return e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,t),this._magFilter=t}},mipSamples:{get:function(){return this._anisoSamples},set:function(t){var e=this._anisoSamples;if(this._anisoSamples=0|Math.max(t,1),e!==this._anisoSamples){var r=this.gl.getExtension("EXT_texture_filter_anisotropic");r&&this.gl.texParameterf(this.gl.TEXTURE_2D,r.TEXTURE_MAX_ANISOTROPY_EXT,this._anisoSamples)}return this._anisoSamples}},wrapS:{get:function(){return this._wrapS},set:function(t){if(this.bind(),l.indexOf(t)<0)throw new Error("gl-texture2d: Unknown wrap mode "+t);return this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,t),this._wrapS=t}},wrapT:{get:function(){return this._wrapT},set:function(t){if(this.bind(),l.indexOf(t)<0)throw new Error("gl-texture2d: Unknown wrap mode "+t);return this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,t),this._wrapT=t}},wrap:{get:function(){return this._wrapVector},set:function(t){if(Array.isArray(t)||(t=[t,t]),2!==t.length)throw new Error("gl-texture2d: Must specify wrap mode for rows and columns");for(var e=0;e<2;++e)if(l.indexOf(t[e])<0)throw new Error("gl-texture2d: Unknown wrap mode "+t);this._wrapS=t[0],this._wrapT=t[1];var r=this.gl;return this.bind(),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,this._wrapS),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,this._wrapT),t}},shape:{get:function(){return this._shapeVector},set:function(t){if(Array.isArray(t)){if(2!==t.length)throw new Error("gl-texture2d: Invalid texture shape")}else t=[0|t,0|t];return h(this,0|t[0],0|t[1]),[0|t[0],0|t[1]]}},width:{get:function(){return this._shape[0]},set:function(t){return h(this,t|=0,this._shape[1]),t}},height:{get:function(){return this._shape[1]},set:function(t){return t|=0,h(this,this._shape[0],t),t}}}),p.bind=function(t){var e=this.gl;return void 0!==t&&e.activeTexture(e.TEXTURE0+(0|t)),e.bindTexture(e.TEXTURE_2D,this.handle),void 0!==t?0|t:e.getParameter(e.ACTIVE_TEXTURE)-e.TEXTURE0},p.dispose=function(){this.gl.deleteTexture(this.handle)},p.generateMipmap=function(){this.bind(),this.gl.generateMipmap(this.gl.TEXTURE_2D);for(var t=Math.min(this._shape[0],this._shape[1]),e=0;t>0;++e,t>>>=1)this._mipLevels.indexOf(e)<0&&this._mipLevels.push(e)},p.setPixels=function(t,e,r,o){var s=this.gl;this.bind(),Array.isArray(e)?(o=r,r=0|e[1],e=0|e[0]):(e=e||0,r=r||0),o=o||0;var l=c(t)?t:t.raw;if(l){this._mipLevels.indexOf(o)<0?(s.texImage2D(s.TEXTURE_2D,0,this.format,this.format,this.type,l),this._mipLevels.push(o)):s.texSubImage2D(s.TEXTURE_2D,o,e,r,this.format,this.type,l)}else{if(!(t.shape&&t.stride&&t.data))throw new Error("gl-texture2d: Unsupported data type");if(t.shape.length<2||e+t.shape[1]>this._shape[1]>>>o||r+t.shape[0]>this._shape[0]>>>o||e<0||r<0)throw new Error("gl-texture2d: Texture dimensions are out of bounds");!function(t,e,r,o,s,l,c,h){var f=h.dtype,p=h.shape.slice();if(p.length<2||p.length>3)throw new Error("gl-texture2d: Invalid ndarray, must be 2d or 3d");var g=0,m=0,v=d(p,h.stride.slice());"float32"===f?g=t.FLOAT:"float64"===f?(g=t.FLOAT,v=!1,f="float32"):"uint8"===f?g=t.UNSIGNED_BYTE:(g=t.UNSIGNED_BYTE,v=!1,f="uint8");if(2===p.length)m=t.LUMINANCE,p=[p[0],p[1],1],h=n(h.data,p,[h.stride[0],h.stride[1],1],h.offset);else{if(3!==p.length)throw new Error("gl-texture2d: Invalid shape for texture");if(1===p[2])m=t.ALPHA;else if(2===p[2])m=t.LUMINANCE_ALPHA;else if(3===p[2])m=t.RGB;else{if(4!==p[2])throw new Error("gl-texture2d: Invalid shape for pixel coords");m=t.RGBA}p[2]}m!==t.LUMINANCE&&m!==t.ALPHA||s!==t.LUMINANCE&&s!==t.ALPHA||(m=s);if(m!==s)throw new Error("gl-texture2d: Incompatible texture format for setPixels");var y=h.size,x=c.indexOf(o)<0;x&&c.push(o);if(g===l&&v)0===h.offset&&h.data.length===y?x?t.texImage2D(t.TEXTURE_2D,o,s,p[0],p[1],0,s,l,h.data):t.texSubImage2D(t.TEXTURE_2D,o,e,r,p[0],p[1],s,l,h.data):x?t.texImage2D(t.TEXTURE_2D,o,s,p[0],p[1],0,s,l,h.data.subarray(h.offset,h.offset+y)):t.texSubImage2D(t.TEXTURE_2D,o,e,r,p[0],p[1],s,l,h.data.subarray(h.offset,h.offset+y));else{var b;b=l===t.FLOAT?a.mallocFloat32(y):a.mallocUint8(y);var _=n(b,p,[p[2],p[2]*p[0],1]);g===t.FLOAT&&l===t.UNSIGNED_BYTE?u(_,h):i.assign(_,h),x?t.texImage2D(t.TEXTURE_2D,o,s,p[0],p[1],0,s,l,b.subarray(0,y)):t.texSubImage2D(t.TEXTURE_2D,o,e,r,p[0],p[1],s,l,b.subarray(0,y)),l===t.FLOAT?a.freeFloat32(b):a.freeUint8(b)}}(s,e,r,o,this.format,this.type,this._mipLevels,t)}}},{ndarray:417,"ndarray-ops":411,"typedarray-pool":507}],304:[function(t,e,r){"use strict";var n=t("pick-by-alias");function i(t){if(t.container)if(t.container==document.body)document.body.style.width||(t.canvas.width=t.width||t.pixelRatio*window.innerWidth),document.body.style.height||(t.canvas.height=t.height||t.pixelRatio*window.innerHeight);else{var e=t.container.getBoundingClientRect();t.canvas.width=t.width||e.right-e.left,t.canvas.height=t.height||e.bottom-e.top}}function a(t){return"function"==typeof t.getContext&&"width"in t&&"height"in t}e.exports=function(t){var e;if(t?"string"==typeof t&&(t={container:t}):t={},a(t)?t={container:t}:t="string"==typeof(e=t).nodeName&&"function"==typeof e.appendChild&&"function"==typeof e.getBoundingClientRect?{container:t}:function(t){return"function"==typeof t.drawArrays||"function"==typeof t.drawElements}(t)?{gl:t}:n(t,{container:"container target element el canvas holder parent parentNode wrapper use ref root node",gl:"gl context webgl glContext",attrs:"attributes attrs contextAttributes",pixelRatio:"pixelRatio pxRatio px ratio pxratio pixelratio"},!0),t.pixelRatio||(t.pixelRatio=window.pixelRatio||1),t.gl)return t.gl;if(t.canvas&&(t.container=t.canvas.parentNode),t.container){if("string"==typeof t.container){var r=document.querySelector(t.container);if(!r)throw Error("Element "+t.container+" is not found");t.container=r}a(t.container)?(t.canvas=t.container,t.container=t.canvas.parentNode):t.canvas||(t.canvas=document.createElement("canvas"),t.container.appendChild(t.canvas),i(t))}else t.canvas||(t.container=document.body||document.documentElement,t.canvas=document.createElement("canvas"),t.canvas.style.position="absolute",t.canvas.style.top=0,t.canvas.style.left=0,t.container.appendChild(t.canvas),i(t));if(!t.gl)try{t.gl=t.canvas.getContext("webgl",t.attrs)}catch(e){try{t.gl=t.canvas.getContext("experimental-webgl",t.attrs)}catch(e){t.gl=t.canvas.getContext("webgl-experimental",t.attrs)}}return t.gl}},{"pick-by-alias":432}],305:[function(t,e,r){"use strict";e.exports=function(t,e,r){e?e.bind():t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null);var n=0|t.getParameter(t.MAX_VERTEX_ATTRIBS);if(r){if(r.length>n)throw new Error("gl-vao: Too many vertex attributes");for(var i=0;i1?0:Math.acos(s)};var n=t("./fromValues"),i=t("./normalize"),a=t("./dot")},{"./dot":317,"./fromValues":319,"./normalize":328}],311:[function(t,e,r){e.exports=function(t){var e=new Float32Array(3);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e}},{}],312:[function(t,e,r){e.exports=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t}},{}],313:[function(t,e,r){e.exports=function(){var t=new Float32Array(3);return t[0]=0,t[1]=0,t[2]=0,t}},{}],314:[function(t,e,r){e.exports=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],l=r[2];return t[0]=i*l-a*s,t[1]=a*o-n*l,t[2]=n*s-i*o,t}},{}],315:[function(t,e,r){e.exports=function(t,e){var r=e[0]-t[0],n=e[1]-t[1],i=e[2]-t[2];return Math.sqrt(r*r+n*n+i*i)}},{}],316:[function(t,e,r){e.exports=function(t,e,r){return t[0]=e[0]/r[0],t[1]=e[1]/r[1],t[2]=e[2]/r[2],t}},{}],317:[function(t,e,r){e.exports=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}},{}],318:[function(t,e,r){e.exports=function(t,e,r,i,a,o){var s,l;e||(e=3);r||(r=0);l=i?Math.min(i*e+r,t.length):t.length;for(s=r;s0&&(a=1/Math.sqrt(a),t[0]=e[0]*a,t[1]=e[1]*a,t[2]=e[2]*a);return t}},{}],329:[function(t,e,r){e.exports=function(t,e){e=e||1;var r=2*Math.random()*Math.PI,n=2*Math.random()-1,i=Math.sqrt(1-n*n)*e;return t[0]=Math.cos(r)*i,t[1]=Math.sin(r)*i,t[2]=n*e,t}},{}],330:[function(t,e,r){e.exports=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[0],a[1]=i[1]*Math.cos(n)-i[2]*Math.sin(n),a[2]=i[1]*Math.sin(n)+i[2]*Math.cos(n),t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t}},{}],331:[function(t,e,r){e.exports=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[2]*Math.sin(n)+i[0]*Math.cos(n),a[1]=i[1],a[2]=i[2]*Math.cos(n)-i[0]*Math.sin(n),t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t}},{}],332:[function(t,e,r){e.exports=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[0]*Math.cos(n)-i[1]*Math.sin(n),a[1]=i[0]*Math.sin(n)+i[1]*Math.cos(n),a[2]=i[2],t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t}},{}],333:[function(t,e,r){e.exports=function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t}},{}],334:[function(t,e,r){e.exports=function(t,e,r,n){return t[0]=e[0]+r[0]*n,t[1]=e[1]+r[1]*n,t[2]=e[2]+r[2]*n,t}},{}],335:[function(t,e,r){e.exports=function(t,e,r,n){return t[0]=e,t[1]=r,t[2]=n,t}},{}],336:[function(t,e,r){e.exports=function(t,e){var r=e[0]-t[0],n=e[1]-t[1],i=e[2]-t[2];return r*r+n*n+i*i}},{}],337:[function(t,e,r){e.exports=function(t){var e=t[0],r=t[1],n=t[2];return e*e+r*r+n*n}},{}],338:[function(t,e,r){e.exports=function(t,e,r){return t[0]=e[0]-r[0],t[1]=e[1]-r[1],t[2]=e[2]-r[2],t}},{}],339:[function(t,e,r){e.exports=function(t,e,r){var n=e[0],i=e[1],a=e[2];return t[0]=n*r[0]+i*r[3]+a*r[6],t[1]=n*r[1]+i*r[4]+a*r[7],t[2]=n*r[2]+i*r[5]+a*r[8],t}},{}],340:[function(t,e,r){e.exports=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[3]*n+r[7]*i+r[11]*a+r[15];return o=o||1,t[0]=(r[0]*n+r[4]*i+r[8]*a+r[12])/o,t[1]=(r[1]*n+r[5]*i+r[9]*a+r[13])/o,t[2]=(r[2]*n+r[6]*i+r[10]*a+r[14])/o,t}},{}],341:[function(t,e,r){e.exports=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],l=r[2],c=r[3],u=c*n+s*a-l*i,h=c*i+l*n-o*a,f=c*a+o*i-s*n,p=-o*n-s*i-l*a;return t[0]=u*c+p*-o+h*-l-f*-s,t[1]=h*c+p*-s+f*-o-u*-l,t[2]=f*c+p*-l+u*-s-h*-o,t}},{}],342:[function(t,e,r){e.exports=function(t,e,r){return t[0]=e[0]+r[0],t[1]=e[1]+r[1],t[2]=e[2]+r[2],t[3]=e[3]+r[3],t}},{}],343:[function(t,e,r){e.exports=function(t){var e=new Float32Array(4);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}},{}],344:[function(t,e,r){e.exports=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}},{}],345:[function(t,e,r){e.exports=function(){var t=new Float32Array(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t}},{}],346:[function(t,e,r){e.exports=function(t,e){var r=e[0]-t[0],n=e[1]-t[1],i=e[2]-t[2],a=e[3]-t[3];return Math.sqrt(r*r+n*n+i*i+a*a)}},{}],347:[function(t,e,r){e.exports=function(t,e,r){return t[0]=e[0]/r[0],t[1]=e[1]/r[1],t[2]=e[2]/r[2],t[3]=e[3]/r[3],t}},{}],348:[function(t,e,r){e.exports=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3]*e[3]}},{}],349:[function(t,e,r){e.exports=function(t,e,r,n){var i=new Float32Array(4);return i[0]=t,i[1]=e,i[2]=r,i[3]=n,i}},{}],350:[function(t,e,r){e.exports={create:t("./create"),clone:t("./clone"),fromValues:t("./fromValues"),copy:t("./copy"),set:t("./set"),add:t("./add"),subtract:t("./subtract"),multiply:t("./multiply"),divide:t("./divide"),min:t("./min"),max:t("./max"),scale:t("./scale"),scaleAndAdd:t("./scaleAndAdd"),distance:t("./distance"),squaredDistance:t("./squaredDistance"),length:t("./length"),squaredLength:t("./squaredLength"),negate:t("./negate"),inverse:t("./inverse"),normalize:t("./normalize"),dot:t("./dot"),lerp:t("./lerp"),random:t("./random"),transformMat4:t("./transformMat4"),transformQuat:t("./transformQuat")}},{"./add":342,"./clone":343,"./copy":344,"./create":345,"./distance":346,"./divide":347,"./dot":348,"./fromValues":349,"./inverse":351,"./length":352,"./lerp":353,"./max":354,"./min":355,"./multiply":356,"./negate":357,"./normalize":358,"./random":359,"./scale":360,"./scaleAndAdd":361,"./set":362,"./squaredDistance":363,"./squaredLength":364,"./subtract":365,"./transformMat4":366,"./transformQuat":367}],351:[function(t,e,r){e.exports=function(t,e){return t[0]=1/e[0],t[1]=1/e[1],t[2]=1/e[2],t[3]=1/e[3],t}},{}],352:[function(t,e,r){e.exports=function(t){var e=t[0],r=t[1],n=t[2],i=t[3];return Math.sqrt(e*e+r*r+n*n+i*i)}},{}],353:[function(t,e,r){e.exports=function(t,e,r,n){var i=e[0],a=e[1],o=e[2],s=e[3];return t[0]=i+n*(r[0]-i),t[1]=a+n*(r[1]-a),t[2]=o+n*(r[2]-o),t[3]=s+n*(r[3]-s),t}},{}],354:[function(t,e,r){e.exports=function(t,e,r){return t[0]=Math.max(e[0],r[0]),t[1]=Math.max(e[1],r[1]),t[2]=Math.max(e[2],r[2]),t[3]=Math.max(e[3],r[3]),t}},{}],355:[function(t,e,r){e.exports=function(t,e,r){return t[0]=Math.min(e[0],r[0]),t[1]=Math.min(e[1],r[1]),t[2]=Math.min(e[2],r[2]),t[3]=Math.min(e[3],r[3]),t}},{}],356:[function(t,e,r){e.exports=function(t,e,r){return t[0]=e[0]*r[0],t[1]=e[1]*r[1],t[2]=e[2]*r[2],t[3]=e[3]*r[3],t}},{}],357:[function(t,e,r){e.exports=function(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t}},{}],358:[function(t,e,r){e.exports=function(t,e){var r=e[0],n=e[1],i=e[2],a=e[3],o=r*r+n*n+i*i+a*a;o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=n*o,t[2]=i*o,t[3]=a*o);return t}},{}],359:[function(t,e,r){var n=t("./normalize"),i=t("./scale");e.exports=function(t,e){return e=e||1,t[0]=Math.random(),t[1]=Math.random(),t[2]=Math.random(),t[3]=Math.random(),n(t,t),i(t,t,e),t}},{"./normalize":358,"./scale":360}],360:[function(t,e,r){e.exports=function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t[3]=e[3]*r,t}},{}],361:[function(t,e,r){e.exports=function(t,e,r,n){return t[0]=e[0]+r[0]*n,t[1]=e[1]+r[1]*n,t[2]=e[2]+r[2]*n,t[3]=e[3]+r[3]*n,t}},{}],362:[function(t,e,r){e.exports=function(t,e,r,n,i){return t[0]=e,t[1]=r,t[2]=n,t[3]=i,t}},{}],363:[function(t,e,r){e.exports=function(t,e){var r=e[0]-t[0],n=e[1]-t[1],i=e[2]-t[2],a=e[3]-t[3];return r*r+n*n+i*i+a*a}},{}],364:[function(t,e,r){e.exports=function(t){var e=t[0],r=t[1],n=t[2],i=t[3];return e*e+r*r+n*n+i*i}},{}],365:[function(t,e,r){e.exports=function(t,e,r){return t[0]=e[0]-r[0],t[1]=e[1]-r[1],t[2]=e[2]-r[2],t[3]=e[3]-r[3],t}},{}],366:[function(t,e,r){e.exports=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3];return t[0]=r[0]*n+r[4]*i+r[8]*a+r[12]*o,t[1]=r[1]*n+r[5]*i+r[9]*a+r[13]*o,t[2]=r[2]*n+r[6]*i+r[10]*a+r[14]*o,t[3]=r[3]*n+r[7]*i+r[11]*a+r[15]*o,t}},{}],367:[function(t,e,r){e.exports=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],l=r[2],c=r[3],u=c*n+s*a-l*i,h=c*i+l*n-o*a,f=c*a+o*i-s*n,p=-o*n-s*i-l*a;return t[0]=u*c+p*-o+h*-l-f*-s,t[1]=h*c+p*-s+f*-o-u*-l,t[2]=f*c+p*-l+u*-s-h*-o,t[3]=e[3],t}},{}],368:[function(t,e,r){e.exports=function(t,e,r,a){return n[0]=a,n[1]=r,n[2]=e,n[3]=t,i[0]};var n=new Uint8Array(4),i=new Float32Array(n.buffer)},{}],369:[function(t,e,r){var n=t("glsl-tokenizer"),i=t("atob-lite");e.exports=function(t){for(var e=Array.isArray(t)?t:n(t),r=0;r0)continue;r=t.slice(0,1).join("")}return B(r),z+=r.length,(S=S.slice(r.length)).length}}function H(){return/[^a-fA-F0-9]/.test(e)?(B(S.join("")),T=l,M):(S.push(e),r=e,M+1)}function G(){return"."===e?(S.push(e),T=g,r=e,M+1):/[eE]/.test(e)?(S.push(e),T=g,r=e,M+1):"x"===e&&1===S.length&&"0"===S[0]?(T=_,S.push(e),r=e,M+1):/[^\d]/.test(e)?(B(S.join("")),T=l,M):(S.push(e),r=e,M+1)}function W(){return"f"===e&&(S.push(e),r=e,M+=1),/[eE]/.test(e)?(S.push(e),r=e,M+1):"-"===e&&/[eE]/.test(r)?(S.push(e),r=e,M+1):/[^\d]/.test(e)?(B(S.join("")),T=l,M):(S.push(e),r=e,M+1)}function Y(){if(/[^\d\w_]/.test(e)){var t=S.join("");return T=R.indexOf(t)>-1?y:D.indexOf(t)>-1?v:m,B(S.join("")),T=l,M}return S.push(e),r=e,M+1}};var n=t("./lib/literals"),i=t("./lib/operators"),a=t("./lib/builtins"),o=t("./lib/literals-300es"),s=t("./lib/builtins-300es"),l=999,c=9999,u=0,h=1,f=2,p=3,d=4,g=5,m=6,v=7,y=8,x=9,b=10,_=11,w=["block-comment","line-comment","preprocessor","operator","integer","float","ident","builtin","keyword","whitespace","eof","integer"]},{"./lib/builtins":372,"./lib/builtins-300es":371,"./lib/literals":374,"./lib/literals-300es":373,"./lib/operators":375}],371:[function(t,e,r){var n=t("./builtins");n=n.slice().filter(function(t){return!/^(gl\_|texture)/.test(t)}),e.exports=n.concat(["gl_VertexID","gl_InstanceID","gl_Position","gl_PointSize","gl_FragCoord","gl_FrontFacing","gl_FragDepth","gl_PointCoord","gl_MaxVertexAttribs","gl_MaxVertexUniformVectors","gl_MaxVertexOutputVectors","gl_MaxFragmentInputVectors","gl_MaxVertexTextureImageUnits","gl_MaxCombinedTextureImageUnits","gl_MaxTextureImageUnits","gl_MaxFragmentUniformVectors","gl_MaxDrawBuffers","gl_MinProgramTexelOffset","gl_MaxProgramTexelOffset","gl_DepthRangeParameters","gl_DepthRange","trunc","round","roundEven","isnan","isinf","floatBitsToInt","floatBitsToUint","intBitsToFloat","uintBitsToFloat","packSnorm2x16","unpackSnorm2x16","packUnorm2x16","unpackUnorm2x16","packHalf2x16","unpackHalf2x16","outerProduct","transpose","determinant","inverse","texture","textureSize","textureProj","textureLod","textureOffset","texelFetch","texelFetchOffset","textureProjOffset","textureLodOffset","textureProjLod","textureProjLodOffset","textureGrad","textureGradOffset","textureProjGrad","textureProjGradOffset"])},{"./builtins":372}],372:[function(t,e,r){e.exports=["abs","acos","all","any","asin","atan","ceil","clamp","cos","cross","dFdx","dFdy","degrees","distance","dot","equal","exp","exp2","faceforward","floor","fract","gl_BackColor","gl_BackLightModelProduct","gl_BackLightProduct","gl_BackMaterial","gl_BackSecondaryColor","gl_ClipPlane","gl_ClipVertex","gl_Color","gl_DepthRange","gl_DepthRangeParameters","gl_EyePlaneQ","gl_EyePlaneR","gl_EyePlaneS","gl_EyePlaneT","gl_Fog","gl_FogCoord","gl_FogFragCoord","gl_FogParameters","gl_FragColor","gl_FragCoord","gl_FragData","gl_FragDepth","gl_FragDepthEXT","gl_FrontColor","gl_FrontFacing","gl_FrontLightModelProduct","gl_FrontLightProduct","gl_FrontMaterial","gl_FrontSecondaryColor","gl_LightModel","gl_LightModelParameters","gl_LightModelProducts","gl_LightProducts","gl_LightSource","gl_LightSourceParameters","gl_MaterialParameters","gl_MaxClipPlanes","gl_MaxCombinedTextureImageUnits","gl_MaxDrawBuffers","gl_MaxFragmentUniformComponents","gl_MaxLights","gl_MaxTextureCoords","gl_MaxTextureImageUnits","gl_MaxTextureUnits","gl_MaxVaryingFloats","gl_MaxVertexAttribs","gl_MaxVertexTextureImageUnits","gl_MaxVertexUniformComponents","gl_ModelViewMatrix","gl_ModelViewMatrixInverse","gl_ModelViewMatrixInverseTranspose","gl_ModelViewMatrixTranspose","gl_ModelViewProjectionMatrix","gl_ModelViewProjectionMatrixInverse","gl_ModelViewProjectionMatrixInverseTranspose","gl_ModelViewProjectionMatrixTranspose","gl_MultiTexCoord0","gl_MultiTexCoord1","gl_MultiTexCoord2","gl_MultiTexCoord3","gl_MultiTexCoord4","gl_MultiTexCoord5","gl_MultiTexCoord6","gl_MultiTexCoord7","gl_Normal","gl_NormalMatrix","gl_NormalScale","gl_ObjectPlaneQ","gl_ObjectPlaneR","gl_ObjectPlaneS","gl_ObjectPlaneT","gl_Point","gl_PointCoord","gl_PointParameters","gl_PointSize","gl_Position","gl_ProjectionMatrix","gl_ProjectionMatrixInverse","gl_ProjectionMatrixInverseTranspose","gl_ProjectionMatrixTranspose","gl_SecondaryColor","gl_TexCoord","gl_TextureEnvColor","gl_TextureMatrix","gl_TextureMatrixInverse","gl_TextureMatrixInverseTranspose","gl_TextureMatrixTranspose","gl_Vertex","greaterThan","greaterThanEqual","inversesqrt","length","lessThan","lessThanEqual","log","log2","matrixCompMult","max","min","mix","mod","normalize","not","notEqual","pow","radians","reflect","refract","sign","sin","smoothstep","sqrt","step","tan","texture2D","texture2DLod","texture2DProj","texture2DProjLod","textureCube","textureCubeLod","texture2DLodEXT","texture2DProjLodEXT","textureCubeLodEXT","texture2DGradEXT","texture2DProjGradEXT","textureCubeGradEXT"]},{}],373:[function(t,e,r){var n=t("./literals");e.exports=n.slice().concat(["layout","centroid","smooth","case","mat2x2","mat2x3","mat2x4","mat3x2","mat3x3","mat3x4","mat4x2","mat4x3","mat4x4","uint","uvec2","uvec3","uvec4","samplerCubeShadow","sampler2DArray","sampler2DArrayShadow","isampler2D","isampler3D","isamplerCube","isampler2DArray","usampler2D","usampler3D","usamplerCube","usampler2DArray","coherent","restrict","readonly","writeonly","resource","atomic_uint","noperspective","patch","sample","subroutine","common","partition","active","filter","image1D","image2D","image3D","imageCube","iimage1D","iimage2D","iimage3D","iimageCube","uimage1D","uimage2D","uimage3D","uimageCube","image1DArray","image2DArray","iimage1DArray","iimage2DArray","uimage1DArray","uimage2DArray","image1DShadow","image2DShadow","image1DArrayShadow","image2DArrayShadow","imageBuffer","iimageBuffer","uimageBuffer","sampler1DArray","sampler1DArrayShadow","isampler1D","isampler1DArray","usampler1D","usampler1DArray","isampler2DRect","usampler2DRect","samplerBuffer","isamplerBuffer","usamplerBuffer","sampler2DMS","isampler2DMS","usampler2DMS","sampler2DMSArray","isampler2DMSArray","usampler2DMSArray"])},{"./literals":374}],374:[function(t,e,r){e.exports=["precision","highp","mediump","lowp","attribute","const","uniform","varying","break","continue","do","for","while","if","else","in","out","inout","float","int","void","bool","true","false","discard","return","mat2","mat3","mat4","vec2","vec3","vec4","ivec2","ivec3","ivec4","bvec2","bvec3","bvec4","sampler1D","sampler2D","sampler3D","samplerCube","sampler1DShadow","sampler2DShadow","struct","asm","class","union","enum","typedef","template","this","packed","goto","switch","default","inline","noinline","volatile","public","static","extern","external","interface","long","short","double","half","fixed","unsigned","input","output","hvec2","hvec3","hvec4","dvec2","dvec3","dvec4","fvec2","fvec3","fvec4","sampler2DRect","sampler3DRect","sampler2DRectShadow","sizeof","cast","namespace","using"]},{}],375:[function(t,e,r){e.exports=["<<=",">>=","++","--","<<",">>","<=",">=","==","!=","&&","||","+=","-=","*=","/=","%=","&=","^^","^=","|=","(",")","[","]",".","!","~","*","/","%","+","-","<",">","&","^","|","?",":","=",",",";","{","}"]},{}],376:[function(t,e,r){var n=t("./index");e.exports=function(t,e){var r=n(e),i=[];return i=(i=i.concat(r(t))).concat(r(null))}},{"./index":370}],377:[function(t,e,r){e.exports=function(t){"string"==typeof t&&(t=[t]);for(var e=[].slice.call(arguments,1),r=[],n=0;n>1,u=-7,h=r?i-1:0,f=r?-1:1,p=t[e+h];for(h+=f,a=p&(1<<-u)-1,p>>=-u,u+=s;u>0;a=256*a+t[e+h],h+=f,u-=8);for(o=a&(1<<-u)-1,a>>=-u,u+=n;u>0;o=256*o+t[e+h],h+=f,u-=8);if(0===a)a=1-c;else{if(a===l)return o?NaN:1/0*(p?-1:1);o+=Math.pow(2,n),a-=c}return(p?-1:1)*o*Math.pow(2,a-n)},r.write=function(t,e,r,n,i,a){var o,s,l,c=8*a-i-1,u=(1<>1,f=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:a-1,d=n?1:-1,g=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(s=isNaN(e)?1:0,o=u):(o=Math.floor(Math.log(e)/Math.LN2),e*(l=Math.pow(2,-o))<1&&(o--,l*=2),(e+=o+h>=1?f/l:f*Math.pow(2,1-h))*l>=2&&(o++,l/=2),o+h>=u?(s=0,o=u):o+h>=1?(s=(e*l-1)*Math.pow(2,i),o+=h):(s=e*Math.pow(2,h-1)*Math.pow(2,i),o=0));i>=8;t[r+p]=255&s,p+=d,s/=256,i-=8);for(o=o<0;t[r+p]=255&o,p+=d,o/=256,c-=8);t[r+p-d]|=128*g}},{}],381:[function(t,e,r){"use strict";e.exports=function(t,e){var r=t.length;if(0===r)throw new Error("Must have at least d+1 points");var i=t[0].length;if(r<=i)throw new Error("Must input at least d+1 points");var o=t.slice(0,i+1),s=n.apply(void 0,o);if(0===s)throw new Error("Input not in general position");for(var l=new Array(i+1),u=0;u<=i;++u)l[u]=u;s<0&&(l[0]=1,l[1]=0);for(var h=new a(l,new Array(i+1),!1),f=h.adjacent,p=new Array(i+2),u=0;u<=i;++u){for(var d=l.slice(),g=0;g<=i;++g)g===u&&(d[g]=-1);var m=d[0];d[0]=d[1],d[1]=m;var v=new a(d,new Array(i+1),!0);f[u]=v,p[u]=v}p[i+1]=h;for(var u=0;u<=i;++u)for(var d=f[u].vertices,y=f[u].adjacent,g=0;g<=i;++g){var x=d[g];if(x<0)y[g]=h;else for(var b=0;b<=i;++b)f[b].vertices.indexOf(x)<0&&(y[g]=f[b])}for(var _=new c(i,o,p),w=!!e,u=i+1;u0&&e.push(","),e.push("tuple[",r,"]");e.push(")}return orient");var i=new Function("test",e.join("")),a=n[t+1];return a||(a=n),i(a)}(t)),this.orient=a}var u=c.prototype;u.handleBoundaryDegeneracy=function(t,e){var r=this.dimension,n=this.vertices.length-1,i=this.tuple,a=this.vertices,o=[t];for(t.lastVisited=-n;o.length>0;){(t=o.pop()).vertices;for(var s=t.adjacent,l=0;l<=r;++l){var c=s[l];if(c.boundary&&!(c.lastVisited<=-n)){for(var u=c.vertices,h=0;h<=r;++h){var f=u[h];i[h]=f<0?e:a[f]}var p=this.orient();if(p>0)return c;c.lastVisited=-n,0===p&&o.push(c)}}}return null},u.walk=function(t,e){var r=this.vertices.length-1,n=this.dimension,i=this.vertices,a=this.tuple,o=e?this.interior.length*Math.random()|0:this.interior.length-1,s=this.interior[o];t:for(;!s.boundary;){for(var l=s.vertices,c=s.adjacent,u=0;u<=n;++u)a[u]=i[l[u]];s.lastVisited=r;for(u=0;u<=n;++u){var h=c[u];if(!(h.lastVisited>=r)){var f=a[u];a[u]=t;var p=this.orient();if(a[u]=f,p<0){s=h;continue t}h.boundary?h.lastVisited=-r:h.lastVisited=r}}return}return s},u.addPeaks=function(t,e){var r=this.vertices.length-1,n=this.dimension,i=this.vertices,l=this.tuple,c=this.interior,u=this.simplices,h=[e];e.lastVisited=r,e.vertices[e.vertices.indexOf(-1)]=r,e.boundary=!1,c.push(e);for(var f=[];h.length>0;){var p=(e=h.pop()).vertices,d=e.adjacent,g=p.indexOf(r);if(!(g<0))for(var m=0;m<=n;++m)if(m!==g){var v=d[m];if(v.boundary&&!(v.lastVisited>=r)){var y=v.vertices;if(v.lastVisited!==-r){for(var x=0,b=0;b<=n;++b)y[b]<0?(x=b,l[b]=t):l[b]=i[y[b]];if(this.orient()>0){y[x]=r,v.boundary=!1,c.push(v),h.push(v),v.lastVisited=r;continue}v.lastVisited=-r}var _=v.adjacent,w=p.slice(),k=d.slice(),M=new a(w,k,!0);u.push(M);var A=_.indexOf(e);if(!(A<0)){_[A]=M,k[g]=v,w[m]=-1,k[m]=e,d[m]=M,M.flip();for(b=0;b<=n;++b){var T=w[b];if(!(T<0||T===r)){for(var S=new Array(n-1),E=0,C=0;C<=n;++C){var L=w[C];L<0||C===b||(S[E++]=L)}f.push(new o(S,M,b))}}}}}}f.sort(s);for(m=0;m+1=0?o[l++]=s[u]:c=1&u;if(c===(1&t)){var h=o[0];o[0]=o[1],o[1]=h}e.push(o)}}return e}},{"robust-orientation":471,"simplicial-complex":481}],382:[function(t,e,r){"use strict";var n=t("binary-search-bounds"),i=0,a=1;function o(t,e,r,n,i){this.mid=t,this.left=e,this.right=r,this.leftPoints=n,this.rightPoints=i,this.count=(e?e.count:0)+(r?r.count:0)+n.length}e.exports=function(t){if(!t||0===t.length)return new x(null);return new x(y(t))};var s=o.prototype;function l(t,e){t.mid=e.mid,t.left=e.left,t.right=e.right,t.leftPoints=e.leftPoints,t.rightPoints=e.rightPoints,t.count=e.count}function c(t,e){var r=y(e);t.mid=r.mid,t.left=r.left,t.right=r.right,t.leftPoints=r.leftPoints,t.rightPoints=r.rightPoints,t.count=r.count}function u(t,e){var r=t.intervals([]);r.push(e),c(t,r)}function h(t,e){var r=t.intervals([]),n=r.indexOf(e);return n<0?i:(r.splice(n,1),c(t,r),a)}function f(t,e,r){for(var n=0;n=0&&t[n][1]>=e;--n){var i=r(t[n]);if(i)return i}}function d(t,e){for(var r=0;r>1],i=[],a=[],s=[];for(r=0;r3*(e+1)?u(this,t):this.left.insert(t):this.left=y([t]);else if(t[0]>this.mid)this.right?4*(this.right.count+1)>3*(e+1)?u(this,t):this.right.insert(t):this.right=y([t]);else{var r=n.ge(this.leftPoints,t,m),i=n.ge(this.rightPoints,t,v);this.leftPoints.splice(r,0,t),this.rightPoints.splice(i,0,t)}},s.remove=function(t){var e=this.count-this.leftPoints;if(t[1]3*(e-1)?h(this,t):2===(c=this.left.remove(t))?(this.left=null,this.count-=1,a):(c===a&&(this.count-=1),c):i;if(t[0]>this.mid)return this.right?4*(this.left?this.left.count:0)>3*(e-1)?h(this,t):2===(c=this.right.remove(t))?(this.right=null,this.count-=1,a):(c===a&&(this.count-=1),c):i;if(1===this.count)return this.leftPoints[0]===t?2:i;if(1===this.leftPoints.length&&this.leftPoints[0]===t){if(this.left&&this.right){for(var r=this,o=this.left;o.right;)r=o,o=o.right;if(r===this)o.right=this.right;else{var s=this.left,c=this.right;r.count-=o.count,r.right=o.left,o.left=s,o.right=c}l(this,o),this.count=(this.left?this.left.count:0)+(this.right?this.right.count:0)+this.leftPoints.length}else this.left?l(this,this.left):l(this,this.right);return a}for(s=n.ge(this.leftPoints,t,m);sthis.mid){var r;if(this.right)if(r=this.right.queryPoint(t,e))return r;return p(this.rightPoints,t,e)}return d(this.leftPoints,e)},s.queryInterval=function(t,e,r){var n;if(tthis.mid&&this.right&&(n=this.right.queryInterval(t,e,r)))return n;return ethis.mid?p(this.rightPoints,t,r):d(this.leftPoints,r)};var b=x.prototype;b.insert=function(t){this.root?this.root.insert(t):this.root=new o(t[0],null,null,[t],[t])},b.remove=function(t){if(this.root){var e=this.root.remove(t);return 2===e&&(this.root=null),e!==i}return!1},b.queryPoint=function(t,e){if(this.root)return this.root.queryPoint(t,e)},b.queryInterval=function(t,e,r){if(t<=e&&this.root)return this.root.queryInterval(t,e,r)},Object.defineProperty(b,"count",{get:function(){return this.root?this.root.count:0}}),Object.defineProperty(b,"intervals",{get:function(){return this.root?this.root.intervals([]):[]}})},{"binary-search-bounds":79}],383:[function(t,e,r){"use strict";e.exports=function(t,e){e=e||new Array(t.length);for(var r=0;r4))}},{}],392:[function(t,e,r){e.exports=function(t,e,r){return t*(1-r)+e*r}},{}],393:[function(t,e,r){(function(t){!function(t,n){"object"==typeof r&&"undefined"!=typeof e?e.exports=n():t.mapboxgl=n()}(this,function(){"use strict";var e,r,n;function i(t,i){if(e)if(r){var a="var sharedChunk = {}; ("+e+")(sharedChunk); ("+r+")(sharedChunk);",o={};e(o),(n=i(o)).workerUrl=window.URL.createObjectURL(new Blob([a],{type:"text/javascript"}))}else r=i;else e=i}return i(0,function(e){var r="undefined"!=typeof window?window:"undefined"!=typeof t?t:"undefined"!=typeof self?self:{};function n(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function i(t,e){return t(e={exports:{}},e.exports),e.exports}var a=o;function o(t,e,r,n){this.cx=3*t,this.bx=3*(r-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*e,this.by=3*(n-e)-this.cy,this.ay=1-this.cy-this.by,this.p1x=t,this.p1y=n,this.p2x=r,this.p2y=n}o.prototype.sampleCurveX=function(t){return((this.ax*t+this.bx)*t+this.cx)*t},o.prototype.sampleCurveY=function(t){return((this.ay*t+this.by)*t+this.cy)*t},o.prototype.sampleCurveDerivativeX=function(t){return(3*this.ax*t+2*this.bx)*t+this.cx},o.prototype.solveCurveX=function(t,e){var r,n,i,a,o;for(void 0===e&&(e=1e-6),i=t,o=0;o<8;o++){if(a=this.sampleCurveX(i)-t,Math.abs(a)(n=1))return n;for(;ra?r=i:n=i,i=.5*(n-r)+r}return i},o.prototype.solve=function(t,e){return this.sampleCurveY(this.solveCurveX(t,e))};var s=function(t,e,r){this.column=t,this.row=e,this.zoom=r};s.prototype.clone=function(){return new s(this.column,this.row,this.zoom)},s.prototype.zoomTo=function(t){return this.clone()._zoomTo(t)},s.prototype.sub=function(t){return this.clone()._sub(t)},s.prototype._zoomTo=function(t){var e=Math.pow(2,t-this.zoom);return this.column*=e,this.row*=e,this.zoom=t,this},s.prototype._sub=function(t){return t=t.zoomTo(this.zoom),this.column-=t.column,this.row-=t.row,this};var l=c;function c(t,e){this.x=t,this.y=e}function u(t,e,r,n){var i=new a(t,e,r,n);return function(t){return i.solve(t)}}c.prototype={clone:function(){return new c(this.x,this.y)},add:function(t){return this.clone()._add(t)},sub:function(t){return this.clone()._sub(t)},multByPoint:function(t){return this.clone()._multByPoint(t)},divByPoint:function(t){return this.clone()._divByPoint(t)},mult:function(t){return this.clone()._mult(t)},div:function(t){return this.clone()._div(t)},rotate:function(t){return this.clone()._rotate(t)},rotateAround:function(t,e){return this.clone()._rotateAround(t,e)},matMult:function(t){return this.clone()._matMult(t)},unit:function(){return this.clone()._unit()},perp:function(){return this.clone()._perp()},round:function(){return this.clone()._round()},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals:function(t){return this.x===t.x&&this.y===t.y},dist:function(t){return Math.sqrt(this.distSqr(t))},distSqr:function(t){var e=t.x-this.x,r=t.y-this.y;return e*e+r*r},angle:function(){return Math.atan2(this.y,this.x)},angleTo:function(t){return Math.atan2(this.y-t.y,this.x-t.x)},angleWith:function(t){return this.angleWithSep(t.x,t.y)},angleWithSep:function(t,e){return Math.atan2(this.x*e-this.y*t,this.x*t+this.y*e)},_matMult:function(t){var e=t[0]*this.x+t[1]*this.y,r=t[2]*this.x+t[3]*this.y;return this.x=e,this.y=r,this},_add:function(t){return this.x+=t.x,this.y+=t.y,this},_sub:function(t){return this.x-=t.x,this.y-=t.y,this},_mult:function(t){return this.x*=t,this.y*=t,this},_div:function(t){return this.x/=t,this.y/=t,this},_multByPoint:function(t){return this.x*=t.x,this.y*=t.y,this},_divByPoint:function(t){return this.x/=t.x,this.y/=t.y,this},_unit:function(){return this._div(this.mag()),this},_perp:function(){var t=this.y;return this.y=this.x,this.x=-t,this},_rotate:function(t){var e=Math.cos(t),r=Math.sin(t),n=e*this.x-r*this.y,i=r*this.x+e*this.y;return this.x=n,this.y=i,this},_rotateAround:function(t,e){var r=Math.cos(t),n=Math.sin(t),i=e.x+r*(this.x-e.x)-n*(this.y-e.y),a=e.y+n*(this.x-e.x)+r*(this.y-e.y);return this.x=i,this.y=a,this},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}},c.convert=function(t){return t instanceof c?t:Array.isArray(t)?new c(t[0],t[1]):t};var h=u(.25,.1,.25,1);function f(t,e,r){return Math.min(r,Math.max(e,t))}function p(t){for(var e=[],r=arguments.length-1;r-- >0;)e[r]=arguments[r+1];for(var n=0,i=e;n(e.y-t.y)*(r.x-t.x)}function k(t){for(var e=0,r=0,n=t.length,i=n-1,a=void 0,o=void 0;r=200&&r.status<300&&r.response?e(null,{data:n,cacheControl:r.getResponseHeader("Cache-Control"),expires:r.getResponseHeader("Expires")}):e(new A(r.statusText,r.status,t.url))},r.send(),r};function E(t,e,r){r[t]=r[t]||[],r[t].push(e)}function C(t,e,r){if(r&&r[t]){var n=r[t].indexOf(e);-1!==n&&r[t].splice(n,1)}}var L=function(t,e){void 0===e&&(e={}),p(this,e),this.type=t},z=function(t){function e(e,r){void 0===r&&(r={}),t.call(this,"error",p({error:e},r))}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(L),P=function(){};P.prototype.on=function(t,e){return this._listeners=this._listeners||{},E(t,e,this._listeners),this},P.prototype.off=function(t,e){return C(t,e,this._listeners),C(t,e,this._oneTimeListeners),this},P.prototype.once=function(t,e){return this._oneTimeListeners=this._oneTimeListeners||{},E(t,e,this._oneTimeListeners),this},P.prototype.fire=function(t){"string"==typeof t&&(t=new L(t,arguments[1]||{}));var e=t.type;if(this.listens(e)){t.target=this;for(var r=0,n=this._listeners&&this._listeners[e]?this._listeners[e].slice():[];r0||this._oneTimeListeners&&this._oneTimeListeners[t]&&this._oneTimeListeners[t].length>0||this._eventedParent&&this._eventedParent.listens(t)},P.prototype.setEventedParent=function(t,e){return this._eventedParent=t,this._eventedParentData=e,this};var I={$version:8,$root:{version:{required:!0,type:"enum",values:[8]},name:{type:"string"},metadata:{type:"*"},center:{type:"array",value:"number"},zoom:{type:"number"},bearing:{type:"number",default:0,period:360,units:"degrees"},pitch:{type:"number",default:0,units:"degrees"},light:{type:"light"},sources:{required:!0,type:"sources"},sprite:{type:"string"},glyphs:{type:"string"},transition:{type:"transition"},layers:{required:!0,type:"array",value:"layer"}},sources:{"*":{type:"source"}},source:["source_vector","source_raster","source_raster_dem","source_geojson","source_video","source_image"],source_vector:{type:{required:!0,type:"enum",values:{vector:{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.0511,180,85.0511]},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},attribution:{type:"string"},"*":{type:"*"}},source_raster:{type:{required:!0,type:"enum",values:{raster:{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.0511,180,85.0511]},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},tileSize:{type:"number",default:512,units:"pixels"},scheme:{type:"enum",values:{xyz:{},tms:{}},default:"xyz"},attribution:{type:"string"},"*":{type:"*"}},source_raster_dem:{type:{required:!0,type:"enum",values:{"raster-dem":{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.0511,180,85.0511]},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},tileSize:{type:"number",default:512,units:"pixels"},attribution:{type:"string"},encoding:{type:"enum",values:{terrarium:{},mapbox:{}},default:"mapbox"},"*":{type:"*"}},source_geojson:{type:{required:!0,type:"enum",values:{geojson:{}}},data:{type:"*"},maxzoom:{type:"number",default:18},buffer:{type:"number",default:128,maximum:512,minimum:0},tolerance:{type:"number",default:.375},cluster:{type:"boolean",default:!1},clusterRadius:{type:"number",default:50,minimum:0},clusterMaxZoom:{type:"number"},lineMetrics:{type:"boolean",default:!1}},source_video:{type:{required:!0,type:"enum",values:{video:{}}},urls:{required:!0,type:"array",value:"string"},coordinates:{required:!0,type:"array",length:4,value:{type:"array",length:2,value:"number"}}},source_image:{type:{required:!0,type:"enum",values:{image:{}}},url:{required:!0,type:"string"},coordinates:{required:!0,type:"array",length:4,value:{type:"array",length:2,value:"number"}}},layer:{id:{type:"string",required:!0},type:{type:"enum",values:{fill:{},line:{},symbol:{},circle:{},heatmap:{},"fill-extrusion":{},raster:{},hillshade:{},background:{}},required:!0},metadata:{type:"*"},source:{type:"string"},"source-layer":{type:"string"},minzoom:{type:"number",minimum:0,maximum:24},maxzoom:{type:"number",minimum:0,maximum:24},filter:{type:"filter"},layout:{type:"layout"},paint:{type:"paint"}},layout:["layout_fill","layout_line","layout_circle","layout_heatmap","layout_fill-extrusion","layout_symbol","layout_raster","layout_hillshade","layout_background"],layout_background:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},layout_fill:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},layout_circle:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},layout_heatmap:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},layout_line:{"line-cap":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{butt:{},round:{},square:{}},default:"butt"},"line-join":{type:"enum",function:"piecewise-constant","zoom-function":!0,"property-function":!0,values:{bevel:{},round:{},miter:{}},default:"miter"},"line-miter-limit":{type:"number",default:2,function:"interpolated","zoom-function":!0,requires:[{"line-join":"miter"}]},"line-round-limit":{type:"number",default:1.05,function:"interpolated","zoom-function":!0,requires:[{"line-join":"round"}]},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},layout_symbol:{"symbol-placement":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{point:{},line:{}},default:"point"},"symbol-spacing":{type:"number",default:250,minimum:1,function:"interpolated","zoom-function":!0,units:"pixels",requires:[{"symbol-placement":"line"}]},"symbol-avoid-edges":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!1},"icon-allow-overlap":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!1,requires:["icon-image"]},"icon-ignore-placement":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!1,requires:["icon-image"]},"icon-optional":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!1,requires:["icon-image","text-field"]},"icon-rotation-alignment":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{},auto:{}},default:"auto",requires:["icon-image"]},"icon-size":{type:"number",default:1,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,units:"factor of the original icon size",requires:["icon-image"]},"icon-text-fit":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{none:{},width:{},height:{},both:{}},default:"none",requires:["icon-image","text-field"]},"icon-text-fit-padding":{type:"array",value:"number",length:4,default:[0,0,0,0],units:"pixels",function:"interpolated","zoom-function":!0,requires:["icon-image","text-field",{"icon-text-fit":["both","width","height"]}]},"icon-image":{type:"string",function:"piecewise-constant","zoom-function":!0,"property-function":!0,tokens:!0},"icon-rotate":{type:"number",default:0,period:360,function:"interpolated","zoom-function":!0,"property-function":!0,units:"degrees",requires:["icon-image"]},"icon-padding":{type:"number",default:2,minimum:0,function:"interpolated","zoom-function":!0,units:"pixels",requires:["icon-image"]},"icon-keep-upright":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!1,requires:["icon-image",{"icon-rotation-alignment":"map"},{"symbol-placement":"line"}]},"icon-offset":{type:"array",value:"number",length:2,default:[0,0],function:"interpolated","zoom-function":!0,"property-function":!0,requires:["icon-image"]},"icon-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,"property-function":!0,values:{center:{},left:{},right:{},top:{},bottom:{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},default:"center",requires:["icon-image"]},"icon-pitch-alignment":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{},auto:{}},default:"auto",requires:["icon-image"]},"text-pitch-alignment":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{},auto:{}},default:"auto",requires:["text-field"]},"text-rotation-alignment":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{},auto:{}},default:"auto",requires:["text-field"]},"text-field":{type:"string",function:"piecewise-constant","zoom-function":!0,"property-function":!0,default:"",tokens:!0},"text-font":{type:"array",value:"string",function:"piecewise-constant","zoom-function":!0,"property-function":!0,default:["Open Sans Regular","Arial Unicode MS Regular"],requires:["text-field"]},"text-size":{type:"number",default:16,minimum:0,units:"pixels",function:"interpolated","zoom-function":!0,"property-function":!0,requires:["text-field"]},"text-max-width":{type:"number",default:10,minimum:0,units:"ems",function:"interpolated","zoom-function":!0,"property-function":!0,requires:["text-field"]},"text-line-height":{type:"number",default:1.2,units:"ems",function:"interpolated","zoom-function":!0,requires:["text-field"]},"text-letter-spacing":{type:"number",default:0,units:"ems",function:"interpolated","zoom-function":!0,"property-function":!0,requires:["text-field"]},"text-justify":{type:"enum",function:"piecewise-constant","zoom-function":!0,"property-function":!0,values:{left:{},center:{},right:{}},default:"center",requires:["text-field"]},"text-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,"property-function":!0,values:{center:{},left:{},right:{},top:{},bottom:{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},default:"center",requires:["text-field"]},"text-max-angle":{type:"number",default:45,units:"degrees",function:"interpolated","zoom-function":!0,requires:["text-field",{"symbol-placement":"line"}]},"text-rotate":{type:"number",default:0,period:360,units:"degrees",function:"interpolated","zoom-function":!0,"property-function":!0,requires:["text-field"]},"text-padding":{type:"number",default:2,minimum:0,units:"pixels",function:"interpolated","zoom-function":!0,requires:["text-field"]},"text-keep-upright":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!0,requires:["text-field",{"text-rotation-alignment":"map"},{"symbol-placement":"line"}]},"text-transform":{type:"enum",function:"piecewise-constant","zoom-function":!0,"property-function":!0,values:{none:{},uppercase:{},lowercase:{}},default:"none",requires:["text-field"]},"text-offset":{type:"array",value:"number",units:"ems",function:"interpolated","zoom-function":!0,"property-function":!0,length:2,default:[0,0],requires:["text-field"]},"text-allow-overlap":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!1,requires:["text-field"]},"text-ignore-placement":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!1,requires:["text-field"]},"text-optional":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!1,requires:["text-field","icon-image"]},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},layout_raster:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},layout_hillshade:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},filter:{type:"array",value:"*"},filter_operator:{type:"enum",values:{"==":{},"!=":{},">":{},">=":{},"<":{},"<=":{},in:{},"!in":{},all:{},any:{},none:{},has:{},"!has":{}}},geometry_type:{type:"enum",values:{Point:{},LineString:{},Polygon:{}}},function_stop:{type:"array",minimum:0,maximum:22,value:["number","color"],length:2},expression:{type:"array",value:"*",minimum:1},expression_name:{type:"enum",values:{let:{group:"Variable binding"},var:{group:"Variable binding"},literal:{group:"Types"},array:{group:"Types"},at:{group:"Lookup"},case:{group:"Decision"},match:{group:"Decision"},coalesce:{group:"Decision"},step:{group:"Ramps, scales, curves"},interpolate:{group:"Ramps, scales, curves"},ln2:{group:"Math"},pi:{group:"Math"},e:{group:"Math"},typeof:{group:"Types"},string:{group:"Types"},number:{group:"Types"},boolean:{group:"Types"},object:{group:"Types"},collator:{group:"Types"},"to-string":{group:"Types"},"to-number":{group:"Types"},"to-boolean":{group:"Types"},"to-rgba":{group:"Color"},"to-color":{group:"Types"},rgb:{group:"Color"},rgba:{group:"Color"},get:{group:"Lookup"},has:{group:"Lookup"},length:{group:"Lookup"},properties:{group:"Feature data"},"geometry-type":{group:"Feature data"},id:{group:"Feature data"},zoom:{group:"Zoom"},"heatmap-density":{group:"Heatmap"},"line-progress":{group:"Heatmap"},"+":{group:"Math"},"*":{group:"Math"},"-":{group:"Math"},"/":{group:"Math"},"%":{group:"Math"},"^":{group:"Math"},sqrt:{group:"Math"},log10:{group:"Math"},ln:{group:"Math"},log2:{group:"Math"},sin:{group:"Math"},cos:{group:"Math"},tan:{group:"Math"},asin:{group:"Math"},acos:{group:"Math"},atan:{group:"Math"},min:{group:"Math"},max:{group:"Math"},round:{group:"Math"},abs:{group:"Math"},ceil:{group:"Math"},floor:{group:"Math"},"==":{group:"Decision"},"!=":{group:"Decision"},">":{group:"Decision"},"<":{group:"Decision"},">=":{group:"Decision"},"<=":{group:"Decision"},all:{group:"Decision"},any:{group:"Decision"},"!":{group:"Decision"},"is-supported-script":{group:"String"},upcase:{group:"String"},downcase:{group:"String"},concat:{group:"String"},"resolved-locale":{group:"String"}}},light:{anchor:{type:"enum",default:"viewport",values:{map:{},viewport:{}},transition:!1,"zoom-function":!0,"property-function":!1,function:"piecewise-constant"},position:{type:"array",default:[1.15,210,30],length:3,value:"number",transition:!0,function:"interpolated","zoom-function":!0,"property-function":!1},color:{type:"color",default:"#ffffff",function:"interpolated","zoom-function":!0,"property-function":!1,transition:!0},intensity:{type:"number",default:.5,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,"property-function":!1,transition:!0}},paint:["paint_fill","paint_line","paint_circle","paint_heatmap","paint_fill-extrusion","paint_symbol","paint_raster","paint_hillshade","paint_background"],paint_fill:{"fill-antialias":{type:"boolean",function:"piecewise-constant","zoom-function":!0,default:!0},"fill-opacity":{type:"number",function:"interpolated","zoom-function":!0,"property-function":!0,default:1,minimum:0,maximum:1,transition:!0},"fill-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:[{"!":"fill-pattern"}]},"fill-outline-color":{type:"color",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:[{"!":"fill-pattern"},{"fill-antialias":!0}]},"fill-translate":{type:"array",value:"number",length:2,default:[0,0],function:"interpolated","zoom-function":!0,transition:!0,units:"pixels"},"fill-translate-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"map",requires:["fill-translate"]},"fill-pattern":{type:"string",function:"piecewise-constant","zoom-function":!0,transition:!0}},paint_line:{"line-opacity":{type:"number",function:"interpolated","zoom-function":!0,"property-function":!0,default:1,minimum:0,maximum:1,transition:!0},"line-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:[{"!":"line-pattern"}]},"line-translate":{type:"array",value:"number",length:2,default:[0,0],function:"interpolated","zoom-function":!0,transition:!0,units:"pixels"},"line-translate-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"map",requires:["line-translate"]},"line-width":{type:"number",default:1,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels"},"line-gap-width":{type:"number",default:0,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels"},"line-offset":{type:"number",default:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels"},"line-blur":{type:"number",default:0,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels"},"line-dasharray":{type:"array",value:"number",function:"piecewise-constant","zoom-function":!0,minimum:0,transition:!0,units:"line widths",requires:[{"!":"line-pattern"}]},"line-pattern":{type:"string",function:"piecewise-constant","zoom-function":!0,transition:!0},"line-gradient":{type:"color",function:"interpolated","zoom-function":!1,"property-function":!1,transition:!1,requires:[{"!":"line-dasharray"},{"!":"line-pattern"},{source:"geojson",has:{lineMetrics:!0}}]}},paint_circle:{"circle-radius":{type:"number",default:5,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels"},"circle-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0},"circle-blur":{type:"number",default:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0},"circle-opacity":{type:"number",default:1,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0},"circle-translate":{type:"array",value:"number",length:2,default:[0,0],function:"interpolated","zoom-function":!0,transition:!0,units:"pixels"},"circle-translate-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"map",requires:["circle-translate"]},"circle-pitch-scale":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"map"},"circle-pitch-alignment":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"viewport"},"circle-stroke-width":{type:"number",default:0,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels"},"circle-stroke-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0},"circle-stroke-opacity":{type:"number",default:1,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0}},paint_heatmap:{"heatmap-radius":{type:"number",default:30,minimum:1,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels"},"heatmap-weight":{type:"number",default:1,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!1},"heatmap-intensity":{type:"number",default:1,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!1,transition:!0},"heatmap-color":{type:"color",default:["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 255, 0)",.1,"royalblue",.3,"cyan",.5,"lime",.7,"yellow",1,"red"],function:"interpolated","zoom-function":!1,"property-function":!1,transition:!1},"heatmap-opacity":{type:"number",default:1,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,"property-function":!1,transition:!0}},paint_symbol:{"icon-opacity":{type:"number",default:1,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:["icon-image"]},"icon-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:["icon-image"]},"icon-halo-color":{type:"color",default:"rgba(0, 0, 0, 0)",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:["icon-image"]},"icon-halo-width":{type:"number",default:0,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels",requires:["icon-image"]},"icon-halo-blur":{type:"number",default:0,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels",requires:["icon-image"]},"icon-translate":{type:"array",value:"number",length:2,default:[0,0],function:"interpolated","zoom-function":!0,transition:!0,units:"pixels",requires:["icon-image"]},"icon-translate-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"map",requires:["icon-image","icon-translate"]},"text-opacity":{type:"number",default:1,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:["text-field"]},"text-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:["text-field"]},"text-halo-color":{type:"color",default:"rgba(0, 0, 0, 0)",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:["text-field"]},"text-halo-width":{type:"number",default:0,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels",requires:["text-field"]},"text-halo-blur":{type:"number",default:0,minimum:0,function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,units:"pixels",requires:["text-field"]},"text-translate":{type:"array",value:"number",length:2,default:[0,0],function:"interpolated","zoom-function":!0,transition:!0,units:"pixels",requires:["text-field"]},"text-translate-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"map",requires:["text-field","text-translate"]}},paint_raster:{"raster-opacity":{type:"number",default:1,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,transition:!0},"raster-hue-rotate":{type:"number",default:0,period:360,function:"interpolated","zoom-function":!0,transition:!0,units:"degrees"},"raster-brightness-min":{type:"number",function:"interpolated","zoom-function":!0,default:0,minimum:0,maximum:1,transition:!0},"raster-brightness-max":{type:"number",function:"interpolated","zoom-function":!0,default:1,minimum:0,maximum:1,transition:!0},"raster-saturation":{type:"number",default:0,minimum:-1,maximum:1,function:"interpolated","zoom-function":!0,transition:!0},"raster-contrast":{type:"number",default:0,minimum:-1,maximum:1,function:"interpolated","zoom-function":!0,transition:!0},"raster-fade-duration":{type:"number",default:300,minimum:0,function:"interpolated","zoom-function":!0,transition:!1,units:"milliseconds"}},paint_hillshade:{"hillshade-illumination-direction":{type:"number",default:335,minimum:0,maximum:359,function:"interpolated","zoom-function":!0,transition:!1},"hillshade-illumination-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"viewport"},"hillshade-exaggeration":{type:"number",default:.5,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,transition:!0},"hillshade-shadow-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,transition:!0},"hillshade-highlight-color":{type:"color",default:"#FFFFFF",function:"interpolated","zoom-function":!0,transition:!0},"hillshade-accent-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,transition:!0}},paint_background:{"background-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,transition:!0,requires:[{"!":"background-pattern"}]},"background-pattern":{type:"string",function:"piecewise-constant","zoom-function":!0,transition:!0},"background-opacity":{type:"number",default:1,minimum:0,maximum:1,function:"interpolated","zoom-function":!0,transition:!0}},transition:{duration:{type:"number",default:300,minimum:0,units:"milliseconds"},delay:{type:"number",default:0,minimum:0,units:"milliseconds"}},"layout_fill-extrusion":{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible"}},function:{expression:{type:"expression"},stops:{type:"array",value:"function_stop"},base:{type:"number",default:1,minimum:0},property:{type:"string",default:"$zoom"},type:{type:"enum",values:{identity:{},exponential:{},interval:{},categorical:{}},default:"exponential"},colorSpace:{type:"enum",values:{rgb:{},lab:{},hcl:{}},default:"rgb"},default:{type:"*",required:!1}},"paint_fill-extrusion":{"fill-extrusion-opacity":{type:"number",function:"interpolated","zoom-function":!0,"property-function":!1,default:1,minimum:0,maximum:1,transition:!0},"fill-extrusion-color":{type:"color",default:"#000000",function:"interpolated","zoom-function":!0,"property-function":!0,transition:!0,requires:[{"!":"fill-extrusion-pattern"}]},"fill-extrusion-translate":{type:"array",value:"number",length:2,default:[0,0],function:"interpolated","zoom-function":!0,transition:!0,units:"pixels"},"fill-extrusion-translate-anchor":{type:"enum",function:"piecewise-constant","zoom-function":!0,values:{map:{},viewport:{}},default:"map",requires:["fill-extrusion-translate"]},"fill-extrusion-pattern":{type:"string",function:"piecewise-constant","zoom-function":!0,transition:!0},"fill-extrusion-height":{type:"number",function:"interpolated","zoom-function":!0,"property-function":!0,default:0,minimum:0,units:"meters",transition:!0},"fill-extrusion-base":{type:"number",function:"interpolated","zoom-function":!0,"property-function":!0,default:0,minimum:0,units:"meters",transition:!0,requires:["fill-extrusion-height"]}}},O=function(t,e,r,n){this.message=(t?t+": ":"")+r,n&&(this.identifier=n),null!=e&&e.__line__&&(this.line=e.__line__)};function D(t){var e=t.key,r=t.value;return r?[new O(e,r,"constants have been deprecated as of v8")]:[]}function R(t){for(var e=[],r=arguments.length-1;r-- >0;)e[r]=arguments[r+1];for(var n=0,i=e;n":"value"===t.itemType.kind?"array":"array<"+e+">"}return t.kind}var J=[V,U,q,H,G,W,Z(Y)];function K(t,e){if("error"===e.kind)return null;if("array"===t.kind){if("array"===e.kind&&!K(t.itemType,e.itemType)&&("number"!=typeof t.N||t.N===e.N))return null}else{if(t.kind===e.kind)return null;if("value"===t.kind)for(var r=0,n=J;r255?255:t}function i(t){return t<0?0:t>1?1:t}function a(t){return"%"===t[t.length-1]?n(parseFloat(t)/100*255):n(parseInt(t))}function o(t){return"%"===t[t.length-1]?i(parseFloat(t)/100):i(parseFloat(t))}function s(t,e,r){return r<0?r+=1:r>1&&(r-=1),6*r<1?t+(e-t)*r*6:2*r<1?e:3*r<2?t+(e-t)*(2/3-r)*6:t}try{e.parseCSSColor=function(t){var e,i=t.replace(/ /g,"").toLowerCase();if(i in r)return r[i].slice();if("#"===i[0])return 4===i.length?(e=parseInt(i.substr(1),16))>=0&&e<=4095?[(3840&e)>>4|(3840&e)>>8,240&e|(240&e)>>4,15&e|(15&e)<<4,1]:null:7===i.length&&(e=parseInt(i.substr(1),16))>=0&&e<=16777215?[(16711680&e)>>16,(65280&e)>>8,255&e,1]:null;var l=i.indexOf("("),c=i.indexOf(")");if(-1!==l&&c+1===i.length){var u=i.substr(0,l),h=i.substr(l+1,c-(l+1)).split(","),f=1;switch(u){case"rgba":if(4!==h.length)return null;f=o(h.pop());case"rgb":return 3!==h.length?null:[a(h[0]),a(h[1]),a(h[2]),f];case"hsla":if(4!==h.length)return null;f=o(h.pop());case"hsl":if(3!==h.length)return null;var p=(parseFloat(h[0])%360+360)%360/360,d=o(h[1]),g=o(h[2]),m=g<=.5?g*(d+1):g+d-g*d,v=2*g-m;return[n(255*s(v,m,p+1/3)),n(255*s(v,m,p)),n(255*s(v,m,p-1/3)),f];default:return null}}return null}}catch(t){}}).parseCSSColor,tt=function(t,e,r,n){void 0===n&&(n=1),this.r=t,this.g=e,this.b=r,this.a=n};tt.parse=function(t){if(t){if(t instanceof tt)return t;if("string"==typeof t){var e=Q(t);if(e)return new tt(e[0]/255*e[3],e[1]/255*e[3],e[2]/255*e[3],e[3])}}},tt.prototype.toString=function(){var t=this.toArray(),e=t[0],r=t[1],n=t[2],i=t[3];return"rgba("+Math.round(e)+","+Math.round(r)+","+Math.round(n)+","+i+")"},tt.prototype.toArray=function(){var t=this.r,e=this.g,r=this.b,n=this.a;return 0===n?[0,0,0,0]:[255*t/n,255*e/n,255*r/n,n]},tt.black=new tt(0,0,0,1),tt.white=new tt(1,1,1,1),tt.transparent=new tt(0,0,0,0);var et=function(t,e,r){this.sensitivity=t?e?"variant":"case":e?"accent":"base",this.locale=r,this.collator=new Intl.Collator(this.locale?this.locale:[],{sensitivity:this.sensitivity,usage:"search"})};et.prototype.compare=function(t,e){return this.collator.compare(t,e)},et.prototype.resolvedLocale=function(){return new Intl.Collator(this.locale?this.locale:[]).resolvedOptions().locale};var rt=function(t,e,r){this.type=X,this.locale=r,this.caseSensitive=t,this.diacriticSensitive=e};function nt(t,e,r,n){return"number"==typeof t&&t>=0&&t<=255&&"number"==typeof e&&e>=0&&e<=255&&"number"==typeof r&&r>=0&&r<=255?void 0===n||"number"==typeof n&&n>=0&&n<=1?null:"Invalid rgba value ["+[t,e,r,n].join(", ")+"]: 'a' must be between 0 and 1.":"Invalid rgba value ["+("number"==typeof n?[t,e,r,n]:[t,e,r]).join(", ")+"]: 'r', 'g', and 'b' must be between 0 and 255."}function it(t){if(null===t)return V;if("string"==typeof t)return q;if("boolean"==typeof t)return H;if("number"==typeof t)return U;if(t instanceof tt)return G;if(t instanceof et)return X;if(Array.isArray(t)){for(var e,r=t.length,n=0,i=t;n4)return e.error("Expected 1, 2, or 3 arguments, but found "+(t.length-1)+" instead.");var r,n;if(t.length>2){var i=t[1];if("string"!=typeof i||!(i in ct))return e.error('The item type argument of "array" must be one of string, number, boolean',1);r=ct[i]}else r=Y;if(t.length>3){if("number"!=typeof t[2]||t[2]<0||t[2]!==Math.floor(t[2]))return e.error('The length argument to "array" must be a positive integer literal',2);n=t[2]}var a=Z(r,n),o=e.parse(t[t.length-1],t.length-1,Y);return o?new ut(a,o):null},ut.prototype.evaluate=function(t){var e=this.input.evaluate(t);if(K(this.type,it(e)))throw new ot("Expected value to be of type "+$(this.type)+", but found "+$(it(e))+" instead.");return e},ut.prototype.eachChild=function(t){t(this.input)},ut.prototype.possibleOutputs=function(){return this.input.possibleOutputs()},ut.prototype.serialize=function(){var t=["array"],e=this.type.itemType;if("string"===e.kind||"number"===e.kind||"boolean"===e.kind){t.push(e.kind);var r=this.type.N;"number"==typeof r&&t.push(r)}return t.push(this.input.serialize()),t};var ht={"to-number":U,"to-color":G},ft=function(t,e){this.type=t,this.args=e};ft.parse=function(t,e){if(t.length<2)return e.error("Expected at least one argument.");for(var r=t[0],n=ht[r],i=[],a=1;a4?"Invalid rbga value "+JSON.stringify(e)+": expected an array containing either three or four numeric values.":nt(e[0],e[1],e[2],e[3])))return new tt(e[0]/255,e[1]/255,e[2]/255,e[3]);throw new ot(r||"Could not parse color from value '"+("string"==typeof e?e:JSON.stringify(e))+"'")}for(var o=null,s=0,l=this.args;s=0)return!1;var r=!0;return t.eachChild(function(t){r&&!vt(t,e)&&(r=!1)}),r}gt.prototype.evaluate=function(t){return this._evaluate(t,this.args)},gt.prototype.eachChild=function(t){this.args.forEach(t)},gt.prototype.possibleOutputs=function(){return[void 0]},gt.prototype.serialize=function(){return[this.name].concat(this.args.map(function(t){return t.serialize()}))},gt.parse=function(t,e){var r=t[0],n=gt.definitions[r];if(!n)return e.error('Unknown expression "'+r+'". If you wanted a literal array, use ["literal", [...]].',0);for(var i=Array.isArray(n)?n[0]:n.type,a=Array.isArray(n)?[[n[1],n[2]]]:n.overloads,o=a.filter(function(e){var r=e[0];return!Array.isArray(r)||r.length===t.length-1}),s=[],l=1;lr&&ee))throw new ot("Input is not a number.");a=o-1}}return Math.max(o-1,0)}xt.prototype.parse=function(t,e,r,n,i){return void 0===i&&(i={}),e?this.concat(e,r,n)._parse(t,i):this._parse(t,i)},xt.prototype._parse=function(t,e){if(null!==t&&"string"!=typeof t&&"boolean"!=typeof t&&"number"!=typeof t||(t=["literal",t]),Array.isArray(t)){if(0===t.length)return this.error('Expected an array with at least one element. If you wanted a literal array, use ["literal", []].');var r=t[0];if("string"!=typeof r)return this.error("Expression name must be a string, but found "+typeof r+' instead. If you wanted a literal array, use ["literal", [...]].',0),null;var n=this.registry[r];if(n){var i=n.parse(t,this);if(!i)return null;if(this.expectedType){var a=this.expectedType,o=i.type;if("string"!==a.kind&&"number"!==a.kind&&"boolean"!==a.kind&&"object"!==a.kind||"value"!==o.kind)if("array"===a.kind&&"value"===o.kind)e.omitTypeAnnotations||(i=new ut(a,i));else if("color"!==a.kind||"value"!==o.kind&&"string"!==o.kind){if(this.checkSubtype(this.expectedType,i.type))return null}else e.omitTypeAnnotations||(i=new ft(a,[i]));else e.omitTypeAnnotations||(i=new lt(a,[i]))}if(!(i instanceof at)&&function t(e){if(e instanceof yt)return t(e.boundExpression);if(e instanceof gt&&"error"===e.name)return!1;if(e instanceof rt)return!1;var r=e instanceof ft||e instanceof lt||e instanceof ut,n=!0;return e.eachChild(function(e){n=r?n&&t(e):n&&e instanceof at}),!!n&&(mt(e)&&vt(e,["zoom","heatmap-density","line-progress","is-supported-script"]))}(i)){var s=new dt;try{i=new at(i.type,i.evaluate(s))}catch(t){return this.error(t.message),null}}return i}return this.error('Unknown expression "'+r+'". If you wanted a literal array, use ["literal", [...]].',0)}return void 0===t?this.error("'undefined' value invalid. Use null instead."):"object"==typeof t?this.error('Bare objects invalid. Use ["literal", {...}] instead.'):this.error("Expected an array, but found "+typeof t+" instead.")},xt.prototype.concat=function(t,e,r){var n="number"==typeof t?this.path.concat(t):this.path,i=r?this.scope.concat(r):this.scope;return new xt(this.registry,n,e||null,i,this.errors)},xt.prototype.error=function(t){for(var e=[],r=arguments.length-1;r-- >0;)e[r]=arguments[r+1];var n=""+this.key+e.map(function(t){return"["+t+"]"}).join("");this.errors.push(new N(n,t))},xt.prototype.checkSubtype=function(t,e){var r=K(t,e);return r&&this.error(r),r};var _t=function(t,e,r){this.type=t,this.input=e,this.labels=[],this.outputs=[];for(var n=0,i=r;n=s)return e.error('Input/output pairs for "step" expressions must be arranged with input values in strictly ascending order.',c);var h=e.parse(l,u,a);if(!h)return null;a=a||h.type,i.push([s,h])}return new _t(a,r,i)},_t.prototype.evaluate=function(t){var e=this.labels,r=this.outputs;if(1===e.length)return r[0].evaluate(t);var n=this.input.evaluate(t);if(n<=e[0])return r[0].evaluate(t);var i=e.length;return n>=e[i-1]?r[i-1].evaluate(t):r[bt(e,n)].evaluate(t)},_t.prototype.eachChild=function(t){t(this.input);for(var e=0,r=this.outputs;e0&&t.push(this.labels[e]),t.push(this.outputs[e].serialize());return t};var kt=Object.freeze({number:wt,color:function(t,e,r){return new tt(wt(t.r,e.r,r),wt(t.g,e.g,r),wt(t.b,e.b,r),wt(t.a,e.a,r))},array:function(t,e,r){return t.map(function(t,n){return wt(t,e[n],r)})}}),Mt=function(t,e,r,n){this.type=t,this.interpolation=e,this.input=r,this.labels=[],this.outputs=[];for(var i=0,a=n;i1}))return e.error("Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.",1);r={name:"cubic-bezier",controlPoints:o}}if(t.length-1<4)return e.error("Expected at least 4 arguments, but found only "+(t.length-1)+".");if((t.length-1)%2!=0)return e.error("Expected an even number of arguments.");if(!(n=e.parse(n,2,U)))return null;var s=[],l=null;e.expectedType&&"value"!==e.expectedType.kind&&(l=e.expectedType);for(var c=0;c=u)return e.error('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.',f);var d=e.parse(h,p,l);if(!d)return null;l=l||d.type,s.push([u,d])}return"number"===l.kind||"color"===l.kind||"array"===l.kind&&"number"===l.itemType.kind&&"number"==typeof l.N?new Mt(l,r,n,s):e.error("Type "+$(l)+" is not interpolatable.")},Mt.prototype.evaluate=function(t){var e=this.labels,r=this.outputs;if(1===e.length)return r[0].evaluate(t);var n=this.input.evaluate(t);if(n<=e[0])return r[0].evaluate(t);var i=e.length;if(n>=e[i-1])return r[i-1].evaluate(t);var a=bt(e,n),o=e[a],s=e[a+1],l=Mt.interpolationFactor(this.interpolation,n,o,s),c=r[a].evaluate(t),u=r[a+1].evaluate(t);return kt[this.type.kind.toLowerCase()](c,u,l)},Mt.prototype.eachChild=function(t){t(this.input);for(var e=0,r=this.outputs;e=r.length)throw new ot("Array index out of bounds: "+e+" > "+(r.length-1)+".");if(e!==Math.floor(e))throw new ot("Array index must be an integer, but found "+e+" instead.");return r[e]},Et.prototype.eachChild=function(t){t(this.index),t(this.input)},Et.prototype.possibleOutputs=function(){return[void 0]},Et.prototype.serialize=function(){return["at",this.index.serialize(),this.input.serialize()]};var Ct=function(t,e,r,n,i,a){this.inputType=t,this.type=e,this.input=r,this.cases=n,this.outputs=i,this.otherwise=a};Ct.parse=function(t,e){if(t.length<5)return e.error("Expected at least 4 arguments, but found only "+(t.length-1)+".");if(t.length%2!=1)return e.error("Expected an even number of arguments.");var r,n;e.expectedType&&"value"!==e.expectedType.kind&&(n=e.expectedType);for(var i={},a=[],o=2;oNumber.MAX_SAFE_INTEGER)return c.error("Branch labels must be integers no larger than "+Number.MAX_SAFE_INTEGER+".");if("number"==typeof f&&Math.floor(f)!==f)return c.error("Numeric branch labels must be integer values.");if(r){if(c.checkSubtype(r,it(f)))return null}else r=it(f);if(void 0!==i[String(f)])return c.error("Branch labels must be unique.");i[String(f)]=a.length}var p=e.parse(l,o,n);if(!p)return null;n=n||p.type,a.push(p)}var d=e.parse(t[1],1,r);if(!d)return null;var g=e.parse(t[t.length-1],t.length-1,n);return g?new Ct(r,n,d,i,a,g):null},Ct.prototype.evaluate=function(t){var e=this.input.evaluate(t);return(this.outputs[this.cases[e]]||this.otherwise).evaluate(t)},Ct.prototype.eachChild=function(t){t(this.input),this.outputs.forEach(t),t(this.otherwise)},Ct.prototype.possibleOutputs=function(){return(t=[]).concat.apply(t,this.outputs.map(function(t){return t.possibleOutputs()})).concat(this.otherwise.possibleOutputs());var t},Ct.prototype.serialize=function(){for(var t=this,e=["match",this.input.serialize()],r=[],n={},i=0,a=Object.keys(this.cases).sort();in.evaluate(t)}function Ut(t,e){var r=e[0],n=e[1];return r.evaluate(t)<=n.evaluate(t)}function qt(t,e){var r=e[0],n=e[1];return r.evaluate(t)>=n.evaluate(t)}function Ht(t){return{type:t}}function Gt(t){return{result:"success",value:t}}function Wt(t){return{result:"error",value:t}}gt.register(Rt,{error:[{kind:"error"},[q],function(t,e){var r=e[0];throw new ot(r.evaluate(t))}],typeof:[q,[Y],function(t,e){return $(it(e[0].evaluate(t)))}],"to-string":[q,[Y],function(t,e){var r=e[0],n=typeof(r=r.evaluate(t));return null===r?"":"string"===n||"number"===n||"boolean"===n?String(r):r instanceof tt?r.toString():JSON.stringify(r)}],"to-boolean":[H,[Y],function(t,e){var r=e[0];return Boolean(r.evaluate(t))}],"to-rgba":[Z(U,4),[G],function(t,e){return e[0].evaluate(t).toArray()}],rgb:[G,[U,U,U],Bt],rgba:[G,[U,U,U,U],Bt],has:{type:H,overloads:[[[q],function(t,e){return Ft(e[0].evaluate(t),t.properties())}],[[q,W],function(t,e){var r=e[0],n=e[1];return Ft(r.evaluate(t),n.evaluate(t))}]]},get:{type:Y,overloads:[[[q],function(t,e){return Nt(e[0].evaluate(t),t.properties())}],[[q,W],function(t,e){var r=e[0],n=e[1];return Nt(r.evaluate(t),n.evaluate(t))}]]},properties:[W,[],function(t){return t.properties()}],"geometry-type":[q,[],function(t){return t.geometryType()}],id:[Y,[],function(t){return t.id()}],zoom:[U,[],function(t){return t.globals.zoom}],"heatmap-density":[U,[],function(t){return t.globals.heatmapDensity||0}],"line-progress":[U,[],function(t){return t.globals.lineProgress||0}],"+":[U,Ht(U),function(t,e){for(var r=0,n=0,i=e;n":[H,[q,Y],function(t,e){var r=e[0],n=e[1],i=t.properties()[r.value],a=n.value;return typeof i==typeof a&&i>a}],"filter-id->":[H,[Y],function(t,e){var r=e[0],n=t.id(),i=r.value;return typeof n==typeof i&&n>i}],"filter-<=":[H,[q,Y],function(t,e){var r=e[0],n=e[1],i=t.properties()[r.value],a=n.value;return typeof i==typeof a&&i<=a}],"filter-id-<=":[H,[Y],function(t,e){var r=e[0],n=t.id(),i=r.value;return typeof n==typeof i&&n<=i}],"filter->=":[H,[q,Y],function(t,e){var r=e[0],n=e[1],i=t.properties()[r.value],a=n.value;return typeof i==typeof a&&i>=a}],"filter-id->=":[H,[Y],function(t,e){var r=e[0],n=t.id(),i=r.value;return typeof n==typeof i&&n>=i}],"filter-has":[H,[Y],function(t,e){return e[0].value in t.properties()}],"filter-has-id":[H,[],function(t){return null!==t.id()}],"filter-type-in":[H,[Z(q)],function(t,e){return e[0].value.indexOf(t.geometryType())>=0}],"filter-id-in":[H,[Z(Y)],function(t,e){return e[0].value.indexOf(t.id())>=0}],"filter-in-small":[H,[q,Z(Y)],function(t,e){var r=e[0];return e[1].value.indexOf(t.properties()[r.value])>=0}],"filter-in-large":[H,[q,Z(Y)],function(t,e){var r=e[0],n=e[1];return function(t,e,r,n){for(;r<=n;){var i=r+n>>1;if(e[i]===t)return!0;e[i]>t?n=i-1:r=i+1}return!1}(t.properties()[r.value],n.value,0,n.value.length-1)}],">":{type:H,overloads:[[[U,U],Vt],[[q,q],Vt],[[q,q,X],function(t,e){var r=e[0],n=e[1];return e[2].evaluate(t).compare(r.evaluate(t),n.evaluate(t))>0}]]},"<":{type:H,overloads:[[[U,U],jt],[[q,q],jt],[[q,q,X],function(t,e){var r=e[0],n=e[1];return e[2].evaluate(t).compare(r.evaluate(t),n.evaluate(t))<0}]]},">=":{type:H,overloads:[[[U,U],qt],[[q,q],qt],[[q,q,X],function(t,e){var r=e[0],n=e[1];return e[2].evaluate(t).compare(r.evaluate(t),n.evaluate(t))>=0}]]},"<=":{type:H,overloads:[[[U,U],Ut],[[q,q],Ut],[[q,q,X],function(t,e){var r=e[0],n=e[1];return e[2].evaluate(t).compare(r.evaluate(t),n.evaluate(t))<=0}]]},all:{type:H,overloads:[[[H,H],function(t,e){var r=e[0],n=e[1];return r.evaluate(t)&&n.evaluate(t)}],[Ht(H),function(t,e){for(var r=0,n=e;rQt?Math.pow(t,1/3):t/Kt+$t}function ne(t){return t>Jt?t*t*t:Kt*(t-$t)}function ie(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function ae(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function oe(t){var e=ae(t.r),r=ae(t.g),n=ae(t.b),i=re((.4124564*e+.3575761*r+.1804375*n)/Yt),a=re((.2126729*e+.7151522*r+.072175*n)/Xt);return{l:116*a-16,a:500*(i-a),b:200*(a-re((.0193339*e+.119192*r+.9503041*n)/Zt)),alpha:t.a}}function se(t){var e=(t.l+16)/116,r=isNaN(t.a)?e:e+t.a/500,n=isNaN(t.b)?e:e-t.b/200;return e=Xt*ne(e),r=Yt*ne(r),n=Zt*ne(n),new tt(ie(3.2404542*r-1.5371385*e-.4985314*n),ie(-.969266*r+1.8760108*e+.041556*n),ie(.0556434*r-.2040259*e+1.0572252*n),t.alpha)}var le={forward:oe,reverse:se,interpolate:function(t,e,r){return{l:wt(t.l,e.l,r),a:wt(t.a,e.a,r),b:wt(t.b,e.b,r),alpha:wt(t.alpha,e.alpha,r)}}},ce={forward:function(t){var e=oe(t),r=e.l,n=e.a,i=e.b,a=Math.atan2(i,n)*ee;return{h:a<0?a+360:a,c:Math.sqrt(n*n+i*i),l:r,alpha:t.a}},reverse:function(t){var e=t.h*te,r=t.c;return se({l:t.l,a:Math.cos(e)*r,b:Math.sin(e)*r,alpha:t.alpha})},interpolate:function(t,e,r){return{h:function(t,e,r){var n=e-t;return t+r*(n>180||n<-180?n-360*Math.round(n/360):n)}(t.h,e.h,r),c:wt(t.c,e.c,r),l:wt(t.l,e.l,r),alpha:wt(t.alpha,e.alpha,r)}}},ue=Object.freeze({lab:le,hcl:ce});function he(t){return t instanceof Number?"number":t instanceof String?"string":t instanceof Boolean?"boolean":Array.isArray(t)?"array":null===t?"null":typeof t}function fe(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function pe(t){return t}function de(t,e,r){return void 0!==t?t:void 0!==e?e:void 0!==r?r:void 0}function ge(t,e,r,n,i){return de(typeof r===i?n[r]:void 0,t.default,e.default)}function me(t,e,r){if("number"!==he(r))return de(t.default,e.default);var n=t.stops.length;if(1===n)return t.stops[0][1];if(r<=t.stops[0][0])return t.stops[0][1];if(r>=t.stops[n-1][0])return t.stops[n-1][1];var i=xe(t.stops,r);return t.stops[i][1]}function ve(t,e,r){var n=void 0!==t.base?t.base:1;if("number"!==he(r))return de(t.default,e.default);var i=t.stops.length;if(1===i)return t.stops[0][1];if(r<=t.stops[0][0])return t.stops[0][1];if(r>=t.stops[i-1][0])return t.stops[i-1][1];var a=xe(t.stops,r),o=function(t,e,r,n){var i=n-r,a=t-r;return 0===i?0:1===e?a/i:(Math.pow(e,a)-1)/(Math.pow(e,i)-1)}(r,n,t.stops[a][0],t.stops[a+1][0]),s=t.stops[a][1],l=t.stops[a+1][1],c=kt[e.type]||pe;if(t.colorSpace&&"rgb"!==t.colorSpace){var u=ue[t.colorSpace];c=function(t,e){return u.reverse(u.interpolate(u.forward(t),u.forward(e),o))}}return"function"==typeof s.evaluate?{evaluate:function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];var r=s.evaluate.apply(void 0,t),n=l.evaluate.apply(void 0,t);if(void 0!==r&&void 0!==n)return c(r,n,o)}}:c(s,l,o)}function ye(t,e,r){return"color"===e.type?r=tt.parse(r):he(r)===e.type||"enum"===e.type&&e.values[r]||(r=void 0),de(r,t.default,e.default)}function xe(t,e){for(var r,n,i=0,a=t.length-1,o=0;i<=a;){if(r=t[o=Math.floor((i+a)/2)][0],n=t[o+1][0],e===r||e>r&&ee&&(a=o-1)}return Math.max(o-1,0)}var be=function(t,e){var r;this.expression=t,this._warningHistory={},this._defaultValue="color"===(r=e).type&&fe(r.default)?new tt(0,0,0,0):"color"===r.type?tt.parse(r.default)||null:void 0===r.default?null:r.default,"enum"===e.type&&(this._enumValues=e.values)};function _e(t){return Array.isArray(t)&&t.length>0&&"string"==typeof t[0]&&t[0]in Rt}function we(t,e){var r=new xt(Rt,[],function(t){var e={color:G,string:q,number:U,enum:q,boolean:H};return"array"===t.type?Z(e[t.value]||Y,t.length):e[t.type]||null}(e)),n=r.parse(t);return n?Gt(new be(n,e)):Wt(r.errors)}be.prototype.evaluateWithoutErrorHandling=function(t,e){return this._evaluator||(this._evaluator=new dt),this._evaluator.globals=t,this._evaluator.feature=e,this.expression.evaluate(this._evaluator)},be.prototype.evaluate=function(t,e){this._evaluator||(this._evaluator=new dt),this._evaluator.globals=t,this._evaluator.feature=e;try{var r=this.expression.evaluate(this._evaluator);if(null==r)return this._defaultValue;if(this._enumValues&&!(r in this._enumValues))throw new ot("Expected value to be one of "+Object.keys(this._enumValues).map(function(t){return JSON.stringify(t)}).join(", ")+", but found "+JSON.stringify(r)+" instead.");return r}catch(t){return this._warningHistory[t.message]||(this._warningHistory[t.message]=!0,"undefined"!=typeof console&&console.warn(t.message)),this._defaultValue}};var ke=function(t,e){this.kind=t,this._styleExpression=e};ke.prototype.evaluateWithoutErrorHandling=function(t,e){return this._styleExpression.evaluateWithoutErrorHandling(t,e)},ke.prototype.evaluate=function(t,e){return this._styleExpression.evaluate(t,e)};var Me=function(t,e,r){this.kind=t,this.zoomStops=r.labels,this._styleExpression=e,r instanceof Mt&&(this._interpolationType=r.interpolation)};function Ae(t,e){if("error"===(t=we(t,e)).result)return t;var r=t.value.expression,n=mt(r);if(!n&&!e["property-function"])return Wt([new N("","property expressions not supported")]);var i=vt(r,["zoom"]);if(!i&&!1===e["zoom-function"])return Wt([new N("","zoom expressions not supported")]);var a=function t(e){var r=null;if(e instanceof St)r=t(e.result);else if(e instanceof Tt)for(var n=0,i=e.args;nn.maximum?[new O(e,r,r+" is greater than the maximum value "+n.maximum)]:[]}function ze(t){var e,r,n,i=t.valueSpec,a=B(t.value.type),o={},s="categorical"!==a&&void 0===t.value.property,l=!s,c="array"===he(t.value.stops)&&"array"===he(t.value.stops[0])&&"object"===he(t.value.stops[0][0]),u=Ee({key:t.key,value:t.value,valueSpec:t.styleSpec.function,style:t.style,styleSpec:t.styleSpec,objectElementValidators:{stops:function(t){if("identity"===a)return[new O(t.key,t.value,'identity function may not have a "stops" property')];var e=[],r=t.value;return e=e.concat(Ce({key:t.key,value:r,valueSpec:t.valueSpec,style:t.style,styleSpec:t.styleSpec,arrayElementValidator:h})),"array"===he(r)&&0===r.length&&e.push(new O(t.key,r,"array must have at least one stop")),e},default:function(t){return Ke({key:t.key,value:t.value,valueSpec:i,style:t.style,styleSpec:t.styleSpec})}}});return"identity"===a&&s&&u.push(new O(t.key,t.value,'missing required property "property"')),"identity"===a||t.value.stops||u.push(new O(t.key,t.value,'missing required property "stops"')),"exponential"===a&&"piecewise-constant"===t.valueSpec.function&&u.push(new O(t.key,t.value,"exponential functions not supported")),t.styleSpec.$version>=8&&(l&&!t.valueSpec["property-function"]?u.push(new O(t.key,t.value,"property functions not supported")):s&&!t.valueSpec["zoom-function"]&&"heatmap-color"!==t.objectKey&&"line-gradient"!==t.objectKey&&u.push(new O(t.key,t.value,"zoom functions not supported"))),"categorical"!==a&&!c||void 0!==t.value.property||u.push(new O(t.key,t.value,'"property" property is required')),u;function h(t){var e=[],a=t.value,s=t.key;if("array"!==he(a))return[new O(s,a,"array expected, "+he(a)+" found")];if(2!==a.length)return[new O(s,a,"array length 2 expected, length "+a.length+" found")];if(c){if("object"!==he(a[0]))return[new O(s,a,"object expected, "+he(a[0])+" found")];if(void 0===a[0].zoom)return[new O(s,a,"object stop key must have zoom")];if(void 0===a[0].value)return[new O(s,a,"object stop key must have value")];if(n&&n>B(a[0].zoom))return[new O(s,a[0].zoom,"stop zoom values must appear in ascending order")];B(a[0].zoom)!==n&&(n=B(a[0].zoom),r=void 0,o={}),e=e.concat(Ee({key:s+"[0]",value:a[0],valueSpec:{zoom:{}},style:t.style,styleSpec:t.styleSpec,objectElementValidators:{zoom:Le,value:f}}))}else e=e.concat(f({key:s+"[0]",value:a[0],valueSpec:{},style:t.style,styleSpec:t.styleSpec},a));return e.concat(Ke({key:s+"[1]",value:a[1],valueSpec:i,style:t.style,styleSpec:t.styleSpec}))}function f(t,n){var s=he(t.value),l=B(t.value),c=null!==t.value?t.value:n;if(e){if(s!==e)return[new O(t.key,c,s+" stop domain type must match previous stop domain type "+e)]}else e=s;if("number"!==s&&"string"!==s&&"boolean"!==s)return[new O(t.key,c,"stop domain value must be a number, string, or boolean")];if("number"!==s&&"categorical"!==a){var u="number expected, "+s+" found";return i["property-function"]&&void 0===a&&(u+='\nIf you intended to use a categorical function, specify `"type": "categorical"`.'),[new O(t.key,c,u)]}return"categorical"!==a||"number"!==s||isFinite(l)&&Math.floor(l)===l?"categorical"!==a&&"number"===s&&void 0!==r&&l=2&&"$id"!==t[1]&&"$type"!==t[1];case"in":case"!in":case"!has":case"none":return!1;case"==":case"!=":case">":case">=":case"<":case"<=":return 3===t.length&&(Array.isArray(t[1])||Array.isArray(t[2]));case"any":case"all":for(var e=0,r=t.slice(1);ee?1:0}function Fe(t){if(!t)return!0;var e,r=t[0];return t.length<=1?"any"!==r:"=="===r?Ne(t[1],t[2],"=="):"!="===r?Ue(Ne(t[1],t[2],"==")):"<"===r||">"===r||"<="===r||">="===r?Ne(t[1],t[2],r):"any"===r?(e=t.slice(1),["any"].concat(e.map(Fe))):"all"===r?["all"].concat(t.slice(1).map(Fe)):"none"===r?["all"].concat(t.slice(1).map(Fe).map(Ue)):"in"===r?je(t[1],t.slice(2)):"!in"===r?Ue(je(t[1],t.slice(2))):"has"===r?Ve(t[1]):"!has"!==r||Ue(Ve(t[1]))}function Ne(t,e,r){switch(t){case"$type":return["filter-type-"+r,e];case"$id":return["filter-id-"+r,e];default:return["filter-"+r,t,e]}}function je(t,e){if(0===e.length)return!1;switch(t){case"$type":return["filter-type-in",["literal",e]];case"$id":return["filter-id-in",["literal",e]];default:return e.length>200&&!e.some(function(t){return typeof t!=typeof e[0]})?["filter-in-large",t,["literal",e.sort(Be)]]:["filter-in-small",t,["literal",e]]}}function Ve(t){switch(t){case"$type":return!0;case"$id":return["filter-has-id"];default:return["filter-has",t]}}function Ue(t){return["!",t]}function qe(t){return Oe(F(t.value))?Pe(R({},t,{expressionContext:"filter",valueSpec:{value:"boolean"}})):function t(e){var r=e.value,n=e.key;if("array"!==he(r))return[new O(n,r,"array expected, "+he(r)+" found")];var i,a=e.styleSpec,o=[];if(r.length<1)return[new O(n,r,"filter array must have at least 1 element")];switch(o=o.concat(Ie({key:n+"[0]",value:r[0],valueSpec:a.filter_operator,style:e.style,styleSpec:e.styleSpec})),B(r[0])){case"<":case"<=":case">":case">=":r.length>=2&&"$type"===B(r[1])&&o.push(new O(n,r,'"$type" cannot be use with operator "'+r[0]+'"'));case"==":case"!=":3!==r.length&&o.push(new O(n,r,'filter array for operator "'+r[0]+'" must have 3 elements'));case"in":case"!in":r.length>=2&&"string"!==(i=he(r[1]))&&o.push(new O(n+"[1]",r[1],"string expected, "+i+" found"));for(var s=2;s=c[f+0]&&n>=c[f+1]?(o[h]=!0,a.push(l[h])):o[h]=!1}}},ur.prototype._forEachCell=function(t,e,r,n,i,a,o){for(var s=this._convertToCellCoord(t),l=this._convertToCellCoord(e),c=this._convertToCellCoord(r),u=this._convertToCellCoord(n),h=s;h<=c;h++)for(var f=l;f<=u;f++){var p=this.d*f+h;if(i.call(this,t,e,r,n,p,a,o))return}},ur.prototype._convertToCellCoord=function(t){return Math.max(0,Math.min(this.d-1,Math.floor(t*this.scale)+this.padding))},ur.prototype.toArrayBuffer=function(){if(this.arrayBuffer)return this.arrayBuffer;for(var t=this.cells,e=cr+this.cells.length+1+1,r=0,n=0;n=0)){var h=t[u];c[u]=fr[l].shallow.indexOf(u)>=0?h:gr(h,e)}t instanceof Error&&(c.message=t.message)}return{name:l,properties:c}}throw new Error("can't serialize object of type "+typeof t)}function mr(t){if(null==t||"boolean"==typeof t||"number"==typeof t||"string"==typeof t||t instanceof Boolean||t instanceof Number||t instanceof String||t instanceof Date||t instanceof RegExp||t instanceof ArrayBuffer||ArrayBuffer.isView(t)||t instanceof hr)return t;if(Array.isArray(t))return t.map(function(t){return mr(t)});if("object"==typeof t){var e=t,r=e.name,n=e.properties;if(!r)throw new Error("can't deserialize object of anonymous class");var i=fr[r].klass;if(!i)throw new Error("can't deserialize unregistered class "+r);if(i.deserialize)return i.deserialize(n._serialized);for(var a=Object.create(i.prototype),o=0,s=Object.keys(n);o=0?n[l]:mr(n[l])}return a}throw new Error("can't deserialize object of type "+typeof t)}var vr=function(){this.first=!0};vr.prototype.update=function(t,e){var r=Math.floor(t);return this.first?(this.first=!1,this.lastIntegerZoom=r,this.lastIntegerZoomTime=0,this.lastZoom=t,this.lastFloorZoom=r,!0):(this.lastFloorZoom>r?(this.lastIntegerZoom=r+1,this.lastIntegerZoomTime=e):this.lastFloorZoom=128&&t<=255},Arabic:function(t){return t>=1536&&t<=1791},"Arabic Supplement":function(t){return t>=1872&&t<=1919},"Arabic Extended-A":function(t){return t>=2208&&t<=2303},"Hangul Jamo":function(t){return t>=4352&&t<=4607},"Unified Canadian Aboriginal Syllabics":function(t){return t>=5120&&t<=5759},Khmer:function(t){return t>=6016&&t<=6143},"Unified Canadian Aboriginal Syllabics Extended":function(t){return t>=6320&&t<=6399},"General Punctuation":function(t){return t>=8192&&t<=8303},"Letterlike Symbols":function(t){return t>=8448&&t<=8527},"Number Forms":function(t){return t>=8528&&t<=8591},"Miscellaneous Technical":function(t){return t>=8960&&t<=9215},"Control Pictures":function(t){return t>=9216&&t<=9279},"Optical Character Recognition":function(t){return t>=9280&&t<=9311},"Enclosed Alphanumerics":function(t){return t>=9312&&t<=9471},"Geometric Shapes":function(t){return t>=9632&&t<=9727},"Miscellaneous Symbols":function(t){return t>=9728&&t<=9983},"Miscellaneous Symbols and Arrows":function(t){return t>=11008&&t<=11263},"CJK Radicals Supplement":function(t){return t>=11904&&t<=12031},"Kangxi Radicals":function(t){return t>=12032&&t<=12255},"Ideographic Description Characters":function(t){return t>=12272&&t<=12287},"CJK Symbols and Punctuation":function(t){return t>=12288&&t<=12351},Hiragana:function(t){return t>=12352&&t<=12447},Katakana:function(t){return t>=12448&&t<=12543},Bopomofo:function(t){return t>=12544&&t<=12591},"Hangul Compatibility Jamo":function(t){return t>=12592&&t<=12687},Kanbun:function(t){return t>=12688&&t<=12703},"Bopomofo Extended":function(t){return t>=12704&&t<=12735},"CJK Strokes":function(t){return t>=12736&&t<=12783},"Katakana Phonetic Extensions":function(t){return t>=12784&&t<=12799},"Enclosed CJK Letters and Months":function(t){return t>=12800&&t<=13055},"CJK Compatibility":function(t){return t>=13056&&t<=13311},"CJK Unified Ideographs Extension A":function(t){return t>=13312&&t<=19903},"Yijing Hexagram Symbols":function(t){return t>=19904&&t<=19967},"CJK Unified Ideographs":function(t){return t>=19968&&t<=40959},"Yi Syllables":function(t){return t>=40960&&t<=42127},"Yi Radicals":function(t){return t>=42128&&t<=42191},"Hangul Jamo Extended-A":function(t){return t>=43360&&t<=43391},"Hangul Syllables":function(t){return t>=44032&&t<=55215},"Hangul Jamo Extended-B":function(t){return t>=55216&&t<=55295},"Private Use Area":function(t){return t>=57344&&t<=63743},"CJK Compatibility Ideographs":function(t){return t>=63744&&t<=64255},"Arabic Presentation Forms-A":function(t){return t>=64336&&t<=65023},"Vertical Forms":function(t){return t>=65040&&t<=65055},"CJK Compatibility Forms":function(t){return t>=65072&&t<=65103},"Small Form Variants":function(t){return t>=65104&&t<=65135},"Arabic Presentation Forms-B":function(t){return t>=65136&&t<=65279},"Halfwidth and Fullwidth Forms":function(t){return t>=65280&&t<=65519}};function xr(t){for(var e=0,r=t;e=65097&&t<=65103)||yr["CJK Compatibility Ideographs"](t)||yr["CJK Compatibility"](t)||yr["CJK Radicals Supplement"](t)||yr["CJK Strokes"](t)||!(!yr["CJK Symbols and Punctuation"](t)||t>=12296&&t<=12305||t>=12308&&t<=12319||12336===t)||yr["CJK Unified Ideographs Extension A"](t)||yr["CJK Unified Ideographs"](t)||yr["Enclosed CJK Letters and Months"](t)||yr["Hangul Compatibility Jamo"](t)||yr["Hangul Jamo Extended-A"](t)||yr["Hangul Jamo Extended-B"](t)||yr["Hangul Jamo"](t)||yr["Hangul Syllables"](t)||yr.Hiragana(t)||yr["Ideographic Description Characters"](t)||yr.Kanbun(t)||yr["Kangxi Radicals"](t)||yr["Katakana Phonetic Extensions"](t)||yr.Katakana(t)&&12540!==t||!(!yr["Halfwidth and Fullwidth Forms"](t)||65288===t||65289===t||65293===t||t>=65306&&t<=65310||65339===t||65341===t||65343===t||t>=65371&&t<=65503||65507===t||t>=65512&&t<=65519)||!(!yr["Small Form Variants"](t)||t>=65112&&t<=65118||t>=65123&&t<=65126)||yr["Unified Canadian Aboriginal Syllabics"](t)||yr["Unified Canadian Aboriginal Syllabics Extended"](t)||yr["Vertical Forms"](t)||yr["Yijing Hexagram Symbols"](t)||yr["Yi Syllables"](t)||yr["Yi Radicals"](t)))}function wr(t){return!(_r(t)||function(t){return!!(yr["Latin-1 Supplement"](t)&&(167===t||169===t||174===t||177===t||188===t||189===t||190===t||215===t||247===t)||yr["General Punctuation"](t)&&(8214===t||8224===t||8225===t||8240===t||8241===t||8251===t||8252===t||8258===t||8263===t||8264===t||8265===t||8273===t)||yr["Letterlike Symbols"](t)||yr["Number Forms"](t)||yr["Miscellaneous Technical"](t)&&(t>=8960&&t<=8967||t>=8972&&t<=8991||t>=8996&&t<=9e3||9003===t||t>=9085&&t<=9114||t>=9150&&t<=9165||9167===t||t>=9169&&t<=9179||t>=9186&&t<=9215)||yr["Control Pictures"](t)&&9251!==t||yr["Optical Character Recognition"](t)||yr["Enclosed Alphanumerics"](t)||yr["Geometric Shapes"](t)||yr["Miscellaneous Symbols"](t)&&!(t>=9754&&t<=9759)||yr["Miscellaneous Symbols and Arrows"](t)&&(t>=11026&&t<=11055||t>=11088&&t<=11097||t>=11192&&t<=11243)||yr["CJK Symbols and Punctuation"](t)||yr.Katakana(t)||yr["Private Use Area"](t)||yr["CJK Compatibility Forms"](t)||yr["Small Form Variants"](t)||yr["Halfwidth and Fullwidth Forms"](t)||8734===t||8756===t||8757===t||t>=9984&&t<=10087||t>=10102&&t<=10131||65532===t||65533===t)}(t))}function kr(t,e){return!(!e&&(t>=1424&&t<=2303||yr["Arabic Presentation Forms-A"](t)||yr["Arabic Presentation Forms-B"](t))||t>=2304&&t<=3583||t>=3840&&t<=4255||yr.Khmer(t))}var Mr,Ar=!1,Tr=null,Sr=!1,Er=new P,Cr={applyArabicShaping:null,processBidirectionalText:null,isLoaded:function(){return Sr||null!=Cr.applyArabicShaping}},Lr=function(t,e){this.zoom=t,e?(this.now=e.now,this.fadeDuration=e.fadeDuration,this.zoomHistory=e.zoomHistory,this.transition=e.transition):(this.now=0,this.fadeDuration=0,this.zoomHistory=new vr,this.transition={})};Lr.prototype.isSupportedScript=function(t){return function(t,e){for(var r=0,n=t;rthis.end)return this.prior=null,r;if(this.value.isDataDriven())return this.prior=null,r;if(e=1)return 1;var e=i*i,r=e*i;return 4*(i<.5?r:3*(i-e)+r-.75)}())}return r};var Dr=function(t){this._properties=t,this._values=Object.create(t.defaultTransitioningPropertyValues)};Dr.prototype.possiblyEvaluate=function(t){for(var e=new Fr(this._properties),r=0,n=Object.keys(this._values);rn.zoomHistory.lastIntegerZoom?{from:t,to:e,fromScale:2,toScale:1,t:a+(1-a)*o}:{from:r,to:e,fromScale:.5,toScale:1,t:1-(1-o)*a}},Vr.prototype.interpolate=function(t){return t};var Ur=function(t){this.specification=t};Ur.prototype.possiblyEvaluate=function(t,e){return!!t.expression.evaluate(e)},Ur.prototype.interpolate=function(){return!1};var qr=function(t){for(var e in this.properties=t,this.defaultPropertyValues={},this.defaultTransitionablePropertyValues={},this.defaultTransitioningPropertyValues={},this.defaultPossiblyEvaluatedValues={},t){var r=t[e],n=this.defaultPropertyValues[e]=new zr(r,void 0),i=this.defaultTransitionablePropertyValues[e]=new Pr(r);this.defaultTransitioningPropertyValues[e]=i.untransitioned(),this.defaultPossiblyEvaluatedValues[e]=n.possiblyEvaluate({})}};pr("DataDrivenProperty",jr),pr("DataConstantProperty",Nr),pr("CrossFadedProperty",Vr),pr("ColorRampProperty",Ur);var Hr=function(t){function e(e,r){for(var n in t.call(this),this.id=e.id,this.metadata=e.metadata,this.type=e.type,this.minzoom=e.minzoom,this.maxzoom=e.maxzoom,this.visibility="visible","background"!==e.type&&(this.source=e.source,this.sourceLayer=e["source-layer"],this.filter=e.filter),this._featureFilter=function(){return!0},r.layout&&(this._unevaluatedLayout=new Rr(r.layout)),this._transitionablePaint=new Ir(r.paint),e.paint)this.setPaintProperty(n,e.paint[n],{validate:!1});for(var i in e.layout)this.setLayoutProperty(i,e.layout[i],{validate:!1});this._transitioningPaint=this._transitionablePaint.untransitioned()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getLayoutProperty=function(t){return"visibility"===t?this.visibility:this._unevaluatedLayout.getValue(t)},e.prototype.setLayoutProperty=function(t,e,r){if(null!=e){var n="layers."+this.id+".layout."+t;if(this._validate(or,n,t,e,r))return}"visibility"!==t?this._unevaluatedLayout.setValue(t,e):this.visibility="none"===e?e:"visible"},e.prototype.getPaintProperty=function(t){return m(t,"-transition")?this._transitionablePaint.getTransition(t.slice(0,-"-transition".length)):this._transitionablePaint.getValue(t)},e.prototype.setPaintProperty=function(t,e,r){if(null!=e){var n="layers."+this.id+".paint."+t;if(this._validate(ar,n,t,e,r))return}m(t,"-transition")?this._transitionablePaint.setTransition(t.slice(0,-"-transition".length),e||void 0):this._transitionablePaint.setValue(t,e)},e.prototype.isHidden=function(t){return!!(this.minzoom&&t=this.maxzoom)||"none"===this.visibility},e.prototype.updateTransitions=function(t){this._transitioningPaint=this._transitionablePaint.transitioned(t,this._transitioningPaint)},e.prototype.hasTransition=function(){return this._transitioningPaint.hasTransition()},e.prototype.recalculate=function(t){this._unevaluatedLayout&&(this.layout=this._unevaluatedLayout.possiblyEvaluate(t)),this.paint=this._transitioningPaint.possiblyEvaluate(t)},e.prototype.serialize=function(){var t={id:this.id,type:this.type,source:this.source,"source-layer":this.sourceLayer,metadata:this.metadata,minzoom:this.minzoom,maxzoom:this.maxzoom,filter:this.filter,layout:this._unevaluatedLayout&&this._unevaluatedLayout.serialize(),paint:this._transitionablePaint&&this._transitionablePaint.serialize()};return"none"===this.visibility&&(t.layout=t.layout||{},t.layout.visibility="none"),y(t,function(t,e){return!(void 0===t||"layout"===e&&!Object.keys(t).length||"paint"===e&&!Object.keys(t).length)})},e.prototype._validate=function(t,e,r,n,i){return(!i||!1!==i.validate)&&sr(this,t.call(nr,{key:e,layerType:this.type,objectKey:r,value:n,styleSpec:I,style:{glyphs:!0,sprite:!0}}))},e.prototype.hasOffscreenPass=function(){return!1},e.prototype.resize=function(){},e}(P),Gr={Int8:Int8Array,Uint8:Uint8Array,Int16:Int16Array,Uint16:Uint16Array,Int32:Int32Array,Uint32:Uint32Array,Float32:Float32Array},Wr=function(t,e){this._structArray=t,this._pos1=e*this.size,this._pos2=this._pos1/2,this._pos4=this._pos1/4,this._pos8=this._pos1/8},Yr=function(){this.isTransferred=!1,this.capacity=-1,this.resize(0)};function Xr(t,e){void 0===e&&(e=1);var r=0,n=0;return{members:t.map(function(t){var i,a=(i=t.type,Gr[i].BYTES_PER_ELEMENT),o=r=Zr(r,Math.max(e,a)),s=t.components||1;return n=Math.max(n,a),r+=a*s,{name:t.name,type:t.type,components:s,offset:o}}),size:Zr(r,Math.max(n,e)),alignment:e}}function Zr(t,e){return Math.ceil(t/e)*e}Yr.serialize=function(t,e){return t._trim(),e&&(t.isTransferred=!0,e.push(t.arrayBuffer)),{length:t.length,arrayBuffer:t.arrayBuffer}},Yr.deserialize=function(t){var e=Object.create(this.prototype);return e.arrayBuffer=t.arrayBuffer,e.length=t.length,e.capacity=t.arrayBuffer.byteLength/e.bytesPerElement,e._refreshViews(),e},Yr.prototype._trim=function(){this.length!==this.capacity&&(this.capacity=this.length,this.arrayBuffer=this.arrayBuffer.slice(0,this.length*this.bytesPerElement),this._refreshViews())},Yr.prototype.clear=function(){this.length=0},Yr.prototype.resize=function(t){this.reserve(t),this.length=t},Yr.prototype.reserve=function(t){if(t>this.capacity){this.capacity=Math.max(t,Math.floor(5*this.capacity),128),this.arrayBuffer=new ArrayBuffer(this.capacity*this.bytesPerElement);var e=this.uint8;this._refreshViews(),e&&this.uint8.set(e)}},Yr.prototype._refreshViews=function(){throw new Error("_refreshViews() must be implemented by each concrete StructArray layout")};var $r=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e){var r=this.length;this.resize(r+1);var n=2*r;return this.int16[n+0]=t,this.int16[n+1]=e,r},e}(Yr);$r.prototype.bytesPerElement=4,pr("StructArrayLayout2i4",$r);var Jr=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r,n){var i=this.length;this.resize(i+1);var a=4*i;return this.int16[a+0]=t,this.int16[a+1]=e,this.int16[a+2]=r,this.int16[a+3]=n,i},e}(Yr);Jr.prototype.bytesPerElement=8,pr("StructArrayLayout4i8",Jr);var Kr=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r,n,i,a){var o=this.length;this.resize(o+1);var s=6*o;return this.int16[s+0]=t,this.int16[s+1]=e,this.int16[s+2]=r,this.int16[s+3]=n,this.int16[s+4]=i,this.int16[s+5]=a,o},e}(Yr);Kr.prototype.bytesPerElement=12,pr("StructArrayLayout2i4i12",Kr);var Qr=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r,n,i,a,o,s){var l=this.length;this.resize(l+1);var c=6*l,u=12*l;return this.int16[c+0]=t,this.int16[c+1]=e,this.int16[c+2]=r,this.int16[c+3]=n,this.uint8[u+8]=i,this.uint8[u+9]=a,this.uint8[u+10]=o,this.uint8[u+11]=s,l},e}(Yr);Qr.prototype.bytesPerElement=12,pr("StructArrayLayout4i4ub12",Qr);var tn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r,n,i,a,o,s){var l=this.length;this.resize(l+1);var c=8*l;return this.int16[c+0]=t,this.int16[c+1]=e,this.int16[c+2]=r,this.int16[c+3]=n,this.uint16[c+4]=i,this.uint16[c+5]=a,this.uint16[c+6]=o,this.uint16[c+7]=s,l},e}(Yr);tn.prototype.bytesPerElement=16,pr("StructArrayLayout4i4ui16",tn);var en=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r){var n=this.length;this.resize(n+1);var i=3*n;return this.float32[i+0]=t,this.float32[i+1]=e,this.float32[i+2]=r,n},e}(Yr);en.prototype.bytesPerElement=12,pr("StructArrayLayout3f12",en);var rn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t){var e=this.length;this.resize(e+1);var r=1*e;return this.uint32[r+0]=t,e},e}(Yr);rn.prototype.bytesPerElement=4,pr("StructArrayLayout1ul4",rn);var nn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r,n,i,a,o,s,l,c,u){var h=this.length;this.resize(h+1);var f=12*h,p=6*h;return this.int16[f+0]=t,this.int16[f+1]=e,this.int16[f+2]=r,this.int16[f+3]=n,this.int16[f+4]=i,this.int16[f+5]=a,this.uint32[p+3]=o,this.uint16[f+8]=s,this.uint16[f+9]=l,this.int16[f+10]=c,this.int16[f+11]=u,h},e}(Yr);nn.prototype.bytesPerElement=24,pr("StructArrayLayout6i1ul2ui2i24",nn);var an=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r,n,i,a){var o=this.length;this.resize(o+1);var s=6*o;return this.int16[s+0]=t,this.int16[s+1]=e,this.int16[s+2]=r,this.int16[s+3]=n,this.int16[s+4]=i,this.int16[s+5]=a,o},e}(Yr);an.prototype.bytesPerElement=12,pr("StructArrayLayout2i2i2i12",an);var on=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e){var r=this.length;this.resize(r+1);var n=4*r;return this.uint8[n+0]=t,this.uint8[n+1]=e,r},e}(Yr);on.prototype.bytesPerElement=4,pr("StructArrayLayout2ub4",on);var sn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r,n,i,a,o,s,l,c,u,h,f,p){var d=this.length;this.resize(d+1);var g=20*d,m=10*d,v=40*d;return this.int16[g+0]=t,this.int16[g+1]=e,this.uint16[g+2]=r,this.uint16[g+3]=n,this.uint32[m+2]=i,this.uint32[m+3]=a,this.uint32[m+4]=o,this.uint16[g+10]=s,this.uint16[g+11]=l,this.uint16[g+12]=c,this.float32[m+7]=u,this.float32[m+8]=h,this.uint8[v+36]=f,this.uint8[v+37]=p,d},e}(Yr);sn.prototype.bytesPerElement=40,pr("StructArrayLayout2i2ui3ul3ui2f2ub40",sn);var ln=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t){var e=this.length;this.resize(e+1);var r=1*e;return this.float32[r+0]=t,e},e}(Yr);ln.prototype.bytesPerElement=4,pr("StructArrayLayout1f4",ln);var cn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r){var n=this.length;this.resize(n+1);var i=3*n;return this.int16[i+0]=t,this.int16[i+1]=e,this.int16[i+2]=r,n},e}(Yr);cn.prototype.bytesPerElement=6,pr("StructArrayLayout3i6",cn);var un=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r){var n=this.length;this.resize(n+1);var i=2*n,a=4*n;return this.uint32[i+0]=t,this.uint16[a+2]=e,this.uint16[a+3]=r,n},e}(Yr);un.prototype.bytesPerElement=8,pr("StructArrayLayout1ul2ui8",un);var hn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r){var n=this.length;this.resize(n+1);var i=3*n;return this.uint16[i+0]=t,this.uint16[i+1]=e,this.uint16[i+2]=r,n},e}(Yr);hn.prototype.bytesPerElement=6,pr("StructArrayLayout3ui6",hn);var fn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e){var r=this.length;this.resize(r+1);var n=2*r;return this.uint16[n+0]=t,this.uint16[n+1]=e,r},e}(Yr);fn.prototype.bytesPerElement=4,pr("StructArrayLayout2ui4",fn);var pn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e){var r=this.length;this.resize(r+1);var n=2*r;return this.float32[n+0]=t,this.float32[n+1]=e,r},e}(Yr);pn.prototype.bytesPerElement=8,pr("StructArrayLayout2f8",pn);var dn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},e.prototype.emplaceBack=function(t,e,r,n){var i=this.length;this.resize(i+1);var a=4*i;return this.float32[a+0]=t,this.float32[a+1]=e,this.float32[a+2]=r,this.float32[a+3]=n,i},e}(Yr);dn.prototype.bytesPerElement=16,pr("StructArrayLayout4f16",dn);var gn=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={anchorPointX:{configurable:!0},anchorPointY:{configurable:!0},x1:{configurable:!0},y1:{configurable:!0},x2:{configurable:!0},y2:{configurable:!0},featureIndex:{configurable:!0},sourceLayerIndex:{configurable:!0},bucketIndex:{configurable:!0},radius:{configurable:!0},signedDistanceFromAnchor:{configurable:!0},anchorPoint:{configurable:!0}};return r.anchorPointX.get=function(){return this._structArray.int16[this._pos2+0]},r.anchorPointX.set=function(t){this._structArray.int16[this._pos2+0]=t},r.anchorPointY.get=function(){return this._structArray.int16[this._pos2+1]},r.anchorPointY.set=function(t){this._structArray.int16[this._pos2+1]=t},r.x1.get=function(){return this._structArray.int16[this._pos2+2]},r.x1.set=function(t){this._structArray.int16[this._pos2+2]=t},r.y1.get=function(){return this._structArray.int16[this._pos2+3]},r.y1.set=function(t){this._structArray.int16[this._pos2+3]=t},r.x2.get=function(){return this._structArray.int16[this._pos2+4]},r.x2.set=function(t){this._structArray.int16[this._pos2+4]=t},r.y2.get=function(){return this._structArray.int16[this._pos2+5]},r.y2.set=function(t){this._structArray.int16[this._pos2+5]=t},r.featureIndex.get=function(){return this._structArray.uint32[this._pos4+3]},r.featureIndex.set=function(t){this._structArray.uint32[this._pos4+3]=t},r.sourceLayerIndex.get=function(){return this._structArray.uint16[this._pos2+8]},r.sourceLayerIndex.set=function(t){this._structArray.uint16[this._pos2+8]=t},r.bucketIndex.get=function(){return this._structArray.uint16[this._pos2+9]},r.bucketIndex.set=function(t){this._structArray.uint16[this._pos2+9]=t},r.radius.get=function(){return this._structArray.int16[this._pos2+10]},r.radius.set=function(t){this._structArray.int16[this._pos2+10]=t},r.signedDistanceFromAnchor.get=function(){return this._structArray.int16[this._pos2+11]},r.signedDistanceFromAnchor.set=function(t){this._structArray.int16[this._pos2+11]=t},r.anchorPoint.get=function(){return new l(this.anchorPointX,this.anchorPointY)},Object.defineProperties(e.prototype,r),e}(Wr);gn.prototype.size=24;var mn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.get=function(t){return new gn(this,t)},e}(nn);pr("CollisionBoxArray",mn);var vn=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={anchorX:{configurable:!0},anchorY:{configurable:!0},glyphStartIndex:{configurable:!0},numGlyphs:{configurable:!0},vertexStartIndex:{configurable:!0},lineStartIndex:{configurable:!0},lineLength:{configurable:!0},segment:{configurable:!0},lowerSize:{configurable:!0},upperSize:{configurable:!0},lineOffsetX:{configurable:!0},lineOffsetY:{configurable:!0},writingMode:{configurable:!0},hidden:{configurable:!0}};return r.anchorX.get=function(){return this._structArray.int16[this._pos2+0]},r.anchorX.set=function(t){this._structArray.int16[this._pos2+0]=t},r.anchorY.get=function(){return this._structArray.int16[this._pos2+1]},r.anchorY.set=function(t){this._structArray.int16[this._pos2+1]=t},r.glyphStartIndex.get=function(){return this._structArray.uint16[this._pos2+2]},r.glyphStartIndex.set=function(t){this._structArray.uint16[this._pos2+2]=t},r.numGlyphs.get=function(){return this._structArray.uint16[this._pos2+3]},r.numGlyphs.set=function(t){this._structArray.uint16[this._pos2+3]=t},r.vertexStartIndex.get=function(){return this._structArray.uint32[this._pos4+2]},r.vertexStartIndex.set=function(t){this._structArray.uint32[this._pos4+2]=t},r.lineStartIndex.get=function(){return this._structArray.uint32[this._pos4+3]},r.lineStartIndex.set=function(t){this._structArray.uint32[this._pos4+3]=t},r.lineLength.get=function(){return this._structArray.uint32[this._pos4+4]},r.lineLength.set=function(t){this._structArray.uint32[this._pos4+4]=t},r.segment.get=function(){return this._structArray.uint16[this._pos2+10]},r.segment.set=function(t){this._structArray.uint16[this._pos2+10]=t},r.lowerSize.get=function(){return this._structArray.uint16[this._pos2+11]},r.lowerSize.set=function(t){this._structArray.uint16[this._pos2+11]=t},r.upperSize.get=function(){return this._structArray.uint16[this._pos2+12]},r.upperSize.set=function(t){this._structArray.uint16[this._pos2+12]=t},r.lineOffsetX.get=function(){return this._structArray.float32[this._pos4+7]},r.lineOffsetX.set=function(t){this._structArray.float32[this._pos4+7]=t},r.lineOffsetY.get=function(){return this._structArray.float32[this._pos4+8]},r.lineOffsetY.set=function(t){this._structArray.float32[this._pos4+8]=t},r.writingMode.get=function(){return this._structArray.uint8[this._pos1+36]},r.writingMode.set=function(t){this._structArray.uint8[this._pos1+36]=t},r.hidden.get=function(){return this._structArray.uint8[this._pos1+37]},r.hidden.set=function(t){this._structArray.uint8[this._pos1+37]=t},Object.defineProperties(e.prototype,r),e}(Wr);vn.prototype.size=40;var yn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.get=function(t){return new vn(this,t)},e}(sn);pr("PlacedSymbolArray",yn);var xn=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={offsetX:{configurable:!0}};return r.offsetX.get=function(){return this._structArray.float32[this._pos4+0]},r.offsetX.set=function(t){this._structArray.float32[this._pos4+0]=t},Object.defineProperties(e.prototype,r),e}(Wr);xn.prototype.size=4;var bn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getoffsetX=function(t){return this.float32[1*t+0]},e.prototype.get=function(t){return new xn(this,t)},e}(ln);pr("GlyphOffsetArray",bn);var _n=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={x:{configurable:!0},y:{configurable:!0},tileUnitDistanceFromAnchor:{configurable:!0}};return r.x.get=function(){return this._structArray.int16[this._pos2+0]},r.x.set=function(t){this._structArray.int16[this._pos2+0]=t},r.y.get=function(){return this._structArray.int16[this._pos2+1]},r.y.set=function(t){this._structArray.int16[this._pos2+1]=t},r.tileUnitDistanceFromAnchor.get=function(){return this._structArray.int16[this._pos2+2]},r.tileUnitDistanceFromAnchor.set=function(t){this._structArray.int16[this._pos2+2]=t},Object.defineProperties(e.prototype,r),e}(Wr);_n.prototype.size=6;var wn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getx=function(t){return this.int16[3*t+0]},e.prototype.gety=function(t){return this.int16[3*t+1]},e.prototype.gettileUnitDistanceFromAnchor=function(t){return this.int16[3*t+2]},e.prototype.get=function(t){return new _n(this,t)},e}(cn);pr("SymbolLineVertexArray",wn);var kn=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={featureIndex:{configurable:!0},sourceLayerIndex:{configurable:!0},bucketIndex:{configurable:!0}};return r.featureIndex.get=function(){return this._structArray.uint32[this._pos4+0]},r.featureIndex.set=function(t){this._structArray.uint32[this._pos4+0]=t},r.sourceLayerIndex.get=function(){return this._structArray.uint16[this._pos2+2]},r.sourceLayerIndex.set=function(t){this._structArray.uint16[this._pos2+2]=t},r.bucketIndex.get=function(){return this._structArray.uint16[this._pos2+3]},r.bucketIndex.set=function(t){this._structArray.uint16[this._pos2+3]=t},Object.defineProperties(e.prototype,r),e}(Wr);kn.prototype.size=8;var Mn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.get=function(t){return new kn(this,t)},e}(un);pr("FeatureIndexArray",Mn);var An=Xr([{name:"a_pos",components:2,type:"Int16"}],4).members,Tn=function(t){void 0===t&&(t=[]),this.segments=t};Tn.prototype.prepareSegment=function(t,e,r){var n=this.segments[this.segments.length-1];return t>Tn.MAX_VERTEX_ARRAY_LENGTH&&_("Max vertices per segment is "+Tn.MAX_VERTEX_ARRAY_LENGTH+": bucket requested "+t),(!n||n.vertexLength+t>Tn.MAX_VERTEX_ARRAY_LENGTH)&&(n={vertexOffset:e.length,primitiveOffset:r.length,vertexLength:0,primitiveLength:0},this.segments.push(n)),n},Tn.prototype.get=function(){return this.segments},Tn.prototype.destroy=function(){for(var t=0,e=this.segments;tRn.max||o.yRn.max)&&_("Geometry exceeds allowed extent, reduce your vector tile buffer size")}return r}function Fn(t,e,r,n,i){t.emplaceBack(2*e+(n+1)/2,2*r+(i+1)/2)}var Nn=function(t){this.zoom=t.zoom,this.overscaling=t.overscaling,this.layers=t.layers,this.layerIds=this.layers.map(function(t){return t.id}),this.index=t.index,this.layoutVertexArray=new $r,this.indexArray=new hn,this.segments=new Tn,this.programConfigurations=new In(An,t.layers,t.zoom)};function jn(t,e,r){for(var n=0;n=3)for(var s=0;s1){if(Hn(t,e))return!0;for(var n=0;n1?t.distSqr(r):t.distSqr(r.sub(e)._mult(i)._add(e))}function Xn(t,e){for(var r,n,i,a=!1,o=0;oe.y!=i.y>e.y&&e.x<(i.x-n.x)*(e.y-n.y)/(i.y-n.y)+n.x&&(a=!a);return a}function Zn(t,e){for(var r=!1,n=0,i=t.length-1;ne.y!=o.y>e.y&&e.x<(o.x-a.x)*(e.y-a.y)/(o.y-a.y)+a.x&&(r=!r)}return r}function $n(t,e,r){var n=e.paint.get(t).value;return"constant"===n.kind?n.value:r.programConfigurations.get(e.id).binders[t].statistics.max}function Jn(t){return Math.sqrt(t[0]*t[0]+t[1]*t[1])}function Kn(t,e,r,n,i){if(!e[0]&&!e[1])return t;var a=l.convert(e);"viewport"===r&&a._rotate(-n);for(var o=[],s=0;s=Dn||l<0||l>=Dn)){var c=this.segments.prepareSegment(4,this.layoutVertexArray,this.indexArray),u=c.vertexLength;Fn(this.layoutVertexArray,s,l,-1,-1),Fn(this.layoutVertexArray,s,l,1,-1),Fn(this.layoutVertexArray,s,l,1,1),Fn(this.layoutVertexArray,s,l,-1,1),this.indexArray.emplaceBack(u,u+1,u+2),this.indexArray.emplaceBack(u,u+3,u+2),c.vertexLength+=4,c.primitiveLength+=2}}this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,t)},pr("CircleBucket",Nn,{omit:["layers"]});var Qn={paint:new qr({"circle-radius":new jr(I.paint_circle["circle-radius"]),"circle-color":new jr(I.paint_circle["circle-color"]),"circle-blur":new jr(I.paint_circle["circle-blur"]),"circle-opacity":new jr(I.paint_circle["circle-opacity"]),"circle-translate":new Nr(I.paint_circle["circle-translate"]),"circle-translate-anchor":new Nr(I.paint_circle["circle-translate-anchor"]),"circle-pitch-scale":new Nr(I.paint_circle["circle-pitch-scale"]),"circle-pitch-alignment":new Nr(I.paint_circle["circle-pitch-alignment"]),"circle-stroke-width":new jr(I.paint_circle["circle-stroke-width"]),"circle-stroke-color":new jr(I.paint_circle["circle-stroke-color"]),"circle-stroke-opacity":new jr(I.paint_circle["circle-stroke-opacity"])})},ti=i(function(t,e){var r;t.exports=((r=new Float32Array(3))[0]=0,r[1]=0,r[2]=0,function(){var t=new Float32Array(4);t[0]=0,t[1]=0,t[2]=0,t[3]=0}(),{vec3:{transformMat3:function(t,e,r){var n=e[0],i=e[1],a=e[2];return t[0]=n*r[0]+i*r[3]+a*r[6],t[1]=n*r[1]+i*r[4]+a*r[7],t[2]=n*r[2]+i*r[5]+a*r[8],t}},vec4:{transformMat4:function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3];return t[0]=r[0]*n+r[4]*i+r[8]*a+r[12]*o,t[1]=r[1]*n+r[5]*i+r[9]*a+r[13]*o,t[2]=r[2]*n+r[6]*i+r[10]*a+r[14]*o,t[3]=r[3]*n+r[7]*i+r[11]*a+r[15]*o,t}},mat2:{create:function(){var t=new Float32Array(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},rotate:function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3],s=Math.sin(r),l=Math.cos(r);return t[0]=n*l+a*s,t[1]=i*l+o*s,t[2]=n*-s+a*l,t[3]=i*-s+o*l,t},scale:function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3],s=r[0],l=r[1];return t[0]=n*s,t[1]=i*s,t[2]=a*l,t[3]=o*l,t}},mat3:{create:function(){var t=new Float32Array(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},fromRotation:function(t,e){var r=Math.sin(e),n=Math.cos(e);return t[0]=n,t[1]=r,t[2]=0,t[3]=-r,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}},mat4:{create:function(){var t=new Float32Array(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},translate:function(t,e,r){var n,i,a,o,s,l,c,u,h,f,p,d,g=r[0],m=r[1],v=r[2];return e===t?(t[12]=e[0]*g+e[4]*m+e[8]*v+e[12],t[13]=e[1]*g+e[5]*m+e[9]*v+e[13],t[14]=e[2]*g+e[6]*m+e[10]*v+e[14],t[15]=e[3]*g+e[7]*m+e[11]*v+e[15]):(n=e[0],i=e[1],a=e[2],o=e[3],s=e[4],l=e[5],c=e[6],u=e[7],h=e[8],f=e[9],p=e[10],d=e[11],t[0]=n,t[1]=i,t[2]=a,t[3]=o,t[4]=s,t[5]=l,t[6]=c,t[7]=u,t[8]=h,t[9]=f,t[10]=p,t[11]=d,t[12]=n*g+s*m+h*v+e[12],t[13]=i*g+l*m+f*v+e[13],t[14]=a*g+c*m+p*v+e[14],t[15]=o*g+u*m+d*v+e[15]),t},scale:function(t,e,r){var n=r[0],i=r[1],a=r[2];return t[0]=e[0]*n,t[1]=e[1]*n,t[2]=e[2]*n,t[3]=e[3]*n,t[4]=e[4]*i,t[5]=e[5]*i,t[6]=e[6]*i,t[7]=e[7]*i,t[8]=e[8]*a,t[9]=e[9]*a,t[10]=e[10]*a,t[11]=e[11]*a,t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t},multiply:function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3],s=e[4],l=e[5],c=e[6],u=e[7],h=e[8],f=e[9],p=e[10],d=e[11],g=e[12],m=e[13],v=e[14],y=e[15],x=r[0],b=r[1],_=r[2],w=r[3];return t[0]=x*n+b*s+_*h+w*g,t[1]=x*i+b*l+_*f+w*m,t[2]=x*a+b*c+_*p+w*v,t[3]=x*o+b*u+_*d+w*y,x=r[4],b=r[5],_=r[6],w=r[7],t[4]=x*n+b*s+_*h+w*g,t[5]=x*i+b*l+_*f+w*m,t[6]=x*a+b*c+_*p+w*v,t[7]=x*o+b*u+_*d+w*y,x=r[8],b=r[9],_=r[10],w=r[11],t[8]=x*n+b*s+_*h+w*g,t[9]=x*i+b*l+_*f+w*m,t[10]=x*a+b*c+_*p+w*v,t[11]=x*o+b*u+_*d+w*y,x=r[12],b=r[13],_=r[14],w=r[15],t[12]=x*n+b*s+_*h+w*g,t[13]=x*i+b*l+_*f+w*m,t[14]=x*a+b*c+_*p+w*v,t[15]=x*o+b*u+_*d+w*y,t},perspective:function(t,e,r,n,i){var a=1/Math.tan(e/2),o=1/(n-i);return t[0]=a/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(i+n)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*i*n*o,t[15]=0,t},rotateX:function(t,e,r){var n=Math.sin(r),i=Math.cos(r),a=e[4],o=e[5],s=e[6],l=e[7],c=e[8],u=e[9],h=e[10],f=e[11];return e!==t&&(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]),t[4]=a*i+c*n,t[5]=o*i+u*n,t[6]=s*i+h*n,t[7]=l*i+f*n,t[8]=c*i-a*n,t[9]=u*i-o*n,t[10]=h*i-s*n,t[11]=f*i-l*n,t},rotateZ:function(t,e,r){var n=Math.sin(r),i=Math.cos(r),a=e[0],o=e[1],s=e[2],l=e[3],c=e[4],u=e[5],h=e[6],f=e[7];return e!==t&&(t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]),t[0]=a*i+c*n,t[1]=o*i+u*n,t[2]=s*i+h*n,t[3]=l*i+f*n,t[4]=c*i-a*n,t[5]=u*i-o*n,t[6]=h*i-s*n,t[7]=f*i-l*n,t},invert:function(t,e){var r=e[0],n=e[1],i=e[2],a=e[3],o=e[4],s=e[5],l=e[6],c=e[7],u=e[8],h=e[9],f=e[10],p=e[11],d=e[12],g=e[13],m=e[14],v=e[15],y=r*s-n*o,x=r*l-i*o,b=r*c-a*o,_=n*l-i*s,w=n*c-a*s,k=i*c-a*l,M=u*g-h*d,A=u*m-f*d,T=u*v-p*d,S=h*m-f*g,E=h*v-p*g,C=f*v-p*m,L=y*C-x*E+b*S+_*T-w*A+k*M;return L?(L=1/L,t[0]=(s*C-l*E+c*S)*L,t[1]=(i*E-n*C-a*S)*L,t[2]=(g*k-m*w+v*_)*L,t[3]=(f*w-h*k-p*_)*L,t[4]=(l*T-o*C-c*A)*L,t[5]=(r*C-i*T+a*A)*L,t[6]=(m*b-d*k-v*x)*L,t[7]=(u*k-f*b+p*x)*L,t[8]=(o*E-s*T+c*M)*L,t[9]=(n*T-r*E-a*M)*L,t[10]=(d*w-g*b+v*y)*L,t[11]=(h*b-u*w-p*y)*L,t[12]=(s*A-o*S-l*M)*L,t[13]=(r*S-n*A+i*M)*L,t[14]=(g*x-d*_-m*y)*L,t[15]=(u*_-h*x+f*y)*L,t):null},ortho:function(t,e,r,n,i,a,o){var s=1/(e-r),l=1/(n-i),c=1/(a-o);return t[0]=-2*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*l,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*c,t[11]=0,t[12]=(e+r)*s,t[13]=(i+n)*l,t[14]=(o+a)*c,t[15]=1,t}}})}),ei=(ti.vec3,ti.vec4),ri=(ti.mat2,ti.mat3,ti.mat4),ni=function(t){function e(e){t.call(this,e,Qn)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.createBucket=function(t){return new Nn(t)},e.prototype.queryRadius=function(t){var e=t;return $n("circle-radius",this,e)+$n("circle-stroke-width",this,e)+Jn(this.paint.get("circle-translate"))},e.prototype.queryIntersectsFeature=function(t,e,r,n,i,a,o){for(var s=Kn(t,this.paint.get("circle-translate"),this.paint.get("circle-translate-anchor"),i.angle,a),l=this.paint.get("circle-radius").evaluate(e)+this.paint.get("circle-stroke-width").evaluate(e),c="map"===this.paint.get("circle-pitch-alignment"),u=c?s:function(t,e,r){return s.map(function(t){return t.map(function(t){return ii(t,e,r)})})}(0,o,i),h=c?l*a:l,f=0,p=r;ft.width||i.height>t.height||r.x>t.width-i.width||r.y>t.height-i.height)throw new RangeError("out of range source coordinates for image copy");if(i.width>e.width||i.height>e.height||n.x>e.width-i.width||n.y>e.height-i.height)throw new RangeError("out of range destination coordinates for image copy");for(var o=t.data,s=e.data,l=0;l80*r){n=a=t[0],i=o=t[1];for(var d=r;da&&(a=s),l>o&&(o=l);c=0!==(c=Math.max(a-n,o-i))?1/c:0}return wi(f,p,r,n,i,c),p}function bi(t,e,r,n,i){var a,o;if(i===Vi(t,e,r,n)>0)for(a=e;a=e;a-=n)o=Fi(a,t[a],t[a+1],o);return o&&Oi(o,o.next)&&(Ni(o),o=o.next),o}function _i(t,e){if(!t)return t;e||(e=t);var r,n=t;do{if(r=!1,n.steiner||!Oi(n,n.next)&&0!==Ii(n.prev,n,n.next))n=n.next;else{if(Ni(n),(n=e=n.prev)===n.next)break;r=!0}}while(r||n!==e);return e}function wi(t,e,r,n,i,a,o){if(t){!o&&a&&function(t,e,r,n){var i=t;do{null===i.z&&(i.z=Ci(i.x,i.y,e,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==t);i.prevZ.nextZ=null,i.prevZ=null,function(t){var e,r,n,i,a,o,s,l,c=1;do{for(r=t,t=null,a=null,o=0;r;){for(o++,n=r,s=0,e=0;e0||l>0&&n;)0!==s&&(0===l||!n||r.z<=n.z)?(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,l--),a?a.nextZ=i:t=i,i.prevZ=a,a=i;r=n}a.nextZ=null,c*=2}while(o>1)}(i)}(t,n,i,a);for(var s,l,c=t;t.prev!==t.next;)if(s=t.prev,l=t.next,a?Mi(t,n,i,a):ki(t))e.push(s.i/r),e.push(t.i/r),e.push(l.i/r),Ni(t),t=l.next,c=l.next;else if((t=l)===c){o?1===o?wi(t=Ai(t,e,r),e,r,n,i,a,2):2===o&&Ti(t,e,r,n,i,a):wi(_i(t),e,r,n,i,a,1);break}}}function ki(t){var e=t.prev,r=t,n=t.next;if(Ii(e,r,n)>=0)return!1;for(var i=t.next.next;i!==t.prev;){if(zi(e.x,e.y,r.x,r.y,n.x,n.y,i.x,i.y)&&Ii(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function Mi(t,e,r,n){var i=t.prev,a=t,o=t.next;if(Ii(i,a,o)>=0)return!1;for(var s=i.xa.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,u=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,h=Ci(s,l,e,r,n),f=Ci(c,u,e,r,n),p=t.prevZ,d=t.nextZ;p&&p.z>=h&&d&&d.z<=f;){if(p!==t.prev&&p!==t.next&&zi(i.x,i.y,a.x,a.y,o.x,o.y,p.x,p.y)&&Ii(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,d!==t.prev&&d!==t.next&&zi(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&Ii(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(;p&&p.z>=h;){if(p!==t.prev&&p!==t.next&&zi(i.x,i.y,a.x,a.y,o.x,o.y,p.x,p.y)&&Ii(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;d&&d.z<=f;){if(d!==t.prev&&d!==t.next&&zi(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&Ii(d.prev,d,d.next)>=0)return!1;d=d.nextZ}return!0}function Ai(t,e,r){var n=t;do{var i=n.prev,a=n.next.next;!Oi(i,a)&&Di(i,n,n.next,a)&&Ri(i,a)&&Ri(a,i)&&(e.push(i.i/r),e.push(n.i/r),e.push(a.i/r),Ni(n),Ni(n.next),n=t=a),n=n.next}while(n!==t);return n}function Ti(t,e,r,n,i,a){var o=t;do{for(var s=o.next.next;s!==o.prev;){if(o.i!==s.i&&Pi(o,s)){var l=Bi(o,s);return o=_i(o,o.next),l=_i(l,l.next),wi(o,e,r,n,i,a),void wi(l,e,r,n,i,a)}s=s.next}o=o.next}while(o!==t)}function Si(t,e){return t.x-e.x}function Ei(t,e){if(e=function(t,e){var r,n=e,i=t.x,a=t.y,o=-1/0;do{if(a<=n.y&&a>=n.next.y&&n.next.y!==n.y){var s=n.x+(a-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(s<=i&&s>o){if(o=s,s===i){if(a===n.y)return n;if(a===n.next.y)return n.next}r=n.x=n.x&&n.x>=u&&i!==n.x&&zi(ar.x)&&Ri(n,t)&&(r=n,f=l),n=n.next;return r}(t,e)){var r=Bi(e,t);_i(r,r.next)}}function Ci(t,e,r,n,i){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=32767*(t-r)*i)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=32767*(e-n)*i)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function Li(t){var e=t,r=t;do{e.x=0&&(t-o)*(n-s)-(r-o)*(e-s)>=0&&(r-o)*(a-s)-(i-o)*(n-s)>=0}function Pi(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var r=t;do{if(r.i!==t.i&&r.next.i!==t.i&&r.i!==e.i&&r.next.i!==e.i&&Di(r,r.next,t,e))return!0;r=r.next}while(r!==t);return!1}(t,e)&&Ri(t,e)&&Ri(e,t)&&function(t,e){var r=t,n=!1,i=(t.x+e.x)/2,a=(t.y+e.y)/2;do{r.y>a!=r.next.y>a&&r.next.y!==r.y&&i<(r.next.x-r.x)*(a-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==t);return n}(t,e)}function Ii(t,e,r){return(e.y-t.y)*(r.x-e.x)-(e.x-t.x)*(r.y-e.y)}function Oi(t,e){return t.x===e.x&&t.y===e.y}function Di(t,e,r,n){return!!(Oi(t,e)&&Oi(r,n)||Oi(t,n)&&Oi(r,e))||Ii(t,e,r)>0!=Ii(t,e,n)>0&&Ii(r,n,t)>0!=Ii(r,n,e)>0}function Ri(t,e){return Ii(t.prev,t,t.next)<0?Ii(t,e,t.next)>=0&&Ii(t,t.prev,e)>=0:Ii(t,e,t.prev)<0||Ii(t,t.next,e)<0}function Bi(t,e){var r=new ji(t.i,t.x,t.y),n=new ji(e.i,e.x,e.y),i=t.next,a=e.prev;return t.next=e,e.prev=t,r.next=i,i.prev=r,n.next=r,r.prev=n,a.next=n,n.prev=a,n}function Fi(t,e,r,n){var i=new ji(t,e,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function Ni(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function ji(t,e,r){this.i=t,this.x=e,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function Vi(t,e,r,n){for(var i=0,a=e,o=r-n;a0&&(n+=t[i-1].length,r.holes.push(n))}return r},vi.default=yi;var Ui=Hi,qi=Hi;function Hi(t,e,r,n,i){!function t(e,r,n,i,a){for(;i>n;){if(i-n>600){var o=i-n+1,s=r-n+1,l=Math.log(o),c=.5*Math.exp(2*l/3),u=.5*Math.sqrt(l*c*(o-c)/o)*(s-o/2<0?-1:1);t(e,r,Math.max(n,Math.floor(r-s*c/o+u)),Math.min(i,Math.floor(r+(o-s)*c/o+u)),a)}var h=e[r],f=n,p=i;for(Gi(e,n,r),a(e[i],h)>0&&Gi(e,n,i);f0;)p--}0===a(e[n],h)?Gi(e,n,p):Gi(e,++p,i),p<=r&&(n=p+1),r<=p&&(i=p-1)}}(t,e,r||0,n||t.length-1,i||Wi)}function Gi(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function Wi(t,e){return te?1:0}function Yi(t,e){var r=t.length;if(r<=1)return[t];for(var n,i,a=[],o=0;o1)for(var l=0;lDn)||t.y===e.y&&(t.y<0||t.y>Dn)}function na(t){return t.every(function(t){return t.x<0})||t.every(function(t){return t.x>Dn})||t.every(function(t){return t.y<0})||t.every(function(t){return t.y>Dn})}ea.prototype.populate=function(t,e){for(var r=0,n=t;r=1){var g=h[p-1];if(!ra(d,g)){l.vertexLength+4>Tn.MAX_VERTEX_ARRAY_LENGTH&&(l=this.segments.prepareSegment(4,this.layoutVertexArray,this.indexArray));var m=d.sub(g)._perp()._unit(),v=g.dist(d);f+v>32768&&(f=0),ta(this.layoutVertexArray,d.x,d.y,m.x,m.y,0,0,f),ta(this.layoutVertexArray,d.x,d.y,m.x,m.y,0,1,f),f+=v,ta(this.layoutVertexArray,g.x,g.y,m.x,m.y,0,0,f),ta(this.layoutVertexArray,g.x,g.y,m.x,m.y,0,1,f);var y=l.vertexLength;this.indexArray.emplaceBack(y,y+1,y+2),this.indexArray.emplaceBack(y+1,y+2,y+3),l.vertexLength+=4,l.primitiveLength+=2}}}}l.vertexLength+a>Tn.MAX_VERTEX_ARRAY_LENGTH&&(l=this.segments.prepareSegment(a,this.layoutVertexArray,this.indexArray));for(var x=[],b=[],_=l.vertexLength,w=0,k=i;w>3}if(i--,1===n||2===n)a+=t.readSVarint(),o+=t.readSVarint(),1===n&&(e&&s.push(e),e=[]),e.push(new l(a,o));else{if(7!==n)throw new Error("unknown command "+n);e&&e.push(e[0].clone())}}return e&&s.push(e),s},la.prototype.bbox=function(){var t=this._pbf;t.pos=this._geometry;for(var e=t.readVarint()+t.pos,r=1,n=0,i=0,a=0,o=1/0,s=-1/0,l=1/0,c=-1/0;t.pos>3}if(n--,1===r||2===r)(i+=t.readSVarint())s&&(s=i),(a+=t.readSVarint())c&&(c=a);else if(7!==r)throw new Error("unknown command "+r)}return[o,l,s,c]},la.prototype.toGeoJSON=function(t,e,r){var n,i,a=this.extent*Math.pow(2,r),o=this.extent*t,s=this.extent*e,l=this.loadGeometry(),c=la.types[this.type];function u(t){for(var e=0;e>3;e=1===n?t.readString():2===n?t.readFloat():3===n?t.readDouble():4===n?t.readVarint64():5===n?t.readVarint():6===n?t.readSVarint():7===n?t.readBoolean():null}return e}(r))}function da(t,e,r){if(3===t){var n=new ha(r,r.readVarint()+r.pos);n.length&&(e[n.name]=n)}}fa.prototype.feature=function(t){if(t<0||t>=this._features.length)throw new Error("feature index out of bounds");this._pbf.pos=this._features[t];var e=this._pbf.readVarint()+this._pbf.pos;return new sa(this._pbf,e,this.extent,this._keys,this._values)};var ga={VectorTile:function(t,e){this.layers=t.readFields(da,{},e)},VectorTileFeature:sa,VectorTileLayer:ha},ma=ga.VectorTileFeature.types,va=63,ya=Math.cos(Math.PI/180*37.5),xa=.5,ba=Math.pow(2,14)/xa;function _a(t,e,r,n,i,a,o){t.emplaceBack(e.x,e.y,n?1:0,i?1:-1,Math.round(va*r.x)+128,Math.round(va*r.y)+128,1+(0===a?0:a<0?-1:1)|(o*xa&63)<<2,o*xa>>6)}var wa=function(t){this.zoom=t.zoom,this.overscaling=t.overscaling,this.layers=t.layers,this.layerIds=this.layers.map(function(t){return t.id}),this.index=t.index,this.layoutVertexArray=new Qr,this.indexArray=new hn,this.programConfigurations=new In(oa,t.layers,t.zoom),this.segments=new Tn};function ka(t,e){return(t/e.tileTotal*(e.end-e.start)+e.start)*(ba-1)}wa.prototype.populate=function(t,e){for(var r=0,n=t;r=2&&t[l-1].equals(t[l-2]);)l--;for(var c=0;cc){var E=p.dist(x);if(E>2*u){var C=p.sub(p.sub(x)._mult(u/E)._round());this.distance+=C.dist(x),this.addCurrentVertex(C,this.distance,_.mult(1),0,0,!1,f,o),x=C}}var L=x&&b,z=L?r:b?m:v;if(L&&"round"===z&&(Ti&&(z="bevel"),"bevel"===z&&(T>2&&(z="flipbevel"),T100)M=w.clone().mult(-1);else{var P=_.x*w.y-_.y*w.x>0?-1:1,I=T*_.add(w).mag()/_.sub(w).mag();M._perp()._mult(I*P)}this.addCurrentVertex(p,this.distance,M,0,0,!1,f,o),this.addCurrentVertex(p,this.distance,M.mult(-1),0,0,!1,f,o)}else if("bevel"===z||"fakeround"===z){var O=_.x*w.y-_.y*w.x>0,D=-Math.sqrt(T*T-1);if(O?(g=0,d=D):(d=0,g=D),y||this.addCurrentVertex(p,this.distance,_,d,g,!1,f,o),"fakeround"===z){for(var R=Math.floor(8*(.5-(A-.5))),B=void 0,F=0;F=0;N--)B=_.mult((N+1)/(R+1))._add(w)._unit(),this.addPieSliceVertex(p,this.distance,B,O,f,o)}b&&this.addCurrentVertex(p,this.distance,w,-d,-g,!1,f,o)}else"butt"===z?(y||this.addCurrentVertex(p,this.distance,_,0,0,!1,f,o),b&&this.addCurrentVertex(p,this.distance,w,0,0,!1,f,o)):"square"===z?(y||(this.addCurrentVertex(p,this.distance,_,1,1,!1,f,o),this.e1=this.e2=-1),b&&this.addCurrentVertex(p,this.distance,w,-1,-1,!1,f,o)):"round"===z&&(y||(this.addCurrentVertex(p,this.distance,_,0,0,!1,f,o),this.addCurrentVertex(p,this.distance,_,1,1,!0,f,o),this.e1=this.e2=-1),b&&(this.addCurrentVertex(p,this.distance,w,-1,-1,!0,f,o),this.addCurrentVertex(p,this.distance,w,0,0,!1,f,o)));if(S&&k2*u){var V=p.add(b.sub(p)._mult(u/j)._round());this.distance+=V.dist(p),this.addCurrentVertex(V,this.distance,w.mult(1),0,0,!1,f,o),p=V}}y=!1}this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,e)}},wa.prototype.addCurrentVertex=function(t,e,r,n,i,a,o,s){var l,c=this.layoutVertexArray,u=this.indexArray;s&&(e=ka(e,s)),l=r.clone(),n&&l._sub(r.perp()._mult(n)),_a(c,t,l,a,!1,n,e),this.e3=o.vertexLength++,this.e1>=0&&this.e2>=0&&(u.emplaceBack(this.e1,this.e2,this.e3),o.primitiveLength++),this.e1=this.e2,this.e2=this.e3,l=r.mult(-1),i&&l._sub(r.perp()._mult(i)),_a(c,t,l,a,!0,-i,e),this.e3=o.vertexLength++,this.e1>=0&&this.e2>=0&&(u.emplaceBack(this.e1,this.e2,this.e3),o.primitiveLength++),this.e1=this.e2,this.e2=this.e3,e>ba/2&&!s&&(this.distance=0,this.addCurrentVertex(t,this.distance,r,n,i,a,o))},wa.prototype.addPieSliceVertex=function(t,e,r,n,i,a){r=r.mult(n?-1:1);var o=this.layoutVertexArray,s=this.indexArray;a&&(e=ka(e,a)),_a(o,t,r,!1,n,0,e),this.e3=i.vertexLength++,this.e1>=0&&this.e2>=0&&(s.emplaceBack(this.e1,this.e2,this.e3),i.primitiveLength++),n?this.e2=this.e3:this.e1=this.e3},pr("LineBucket",wa,{omit:["layers"]});var Ma=new qr({"line-cap":new Nr(I.layout_line["line-cap"]),"line-join":new jr(I.layout_line["line-join"]),"line-miter-limit":new Nr(I.layout_line["line-miter-limit"]),"line-round-limit":new Nr(I.layout_line["line-round-limit"])}),Aa={paint:new qr({"line-opacity":new jr(I.paint_line["line-opacity"]),"line-color":new jr(I.paint_line["line-color"]),"line-translate":new Nr(I.paint_line["line-translate"]),"line-translate-anchor":new Nr(I.paint_line["line-translate-anchor"]),"line-width":new jr(I.paint_line["line-width"]),"line-gap-width":new jr(I.paint_line["line-gap-width"]),"line-offset":new jr(I.paint_line["line-offset"]),"line-blur":new jr(I.paint_line["line-blur"]),"line-dasharray":new Vr(I.paint_line["line-dasharray"]),"line-pattern":new Vr(I.paint_line["line-pattern"]),"line-gradient":new Ur(I.paint_line["line-gradient"])}),layout:Ma},Ta=new(function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.possiblyEvaluate=function(e,r){return r=new Lr(Math.floor(r.zoom),{now:r.now,fadeDuration:r.fadeDuration,zoomHistory:r.zoomHistory,transition:r.transition}),t.prototype.possiblyEvaluate.call(this,e,r)},e.prototype.evaluate=function(e,r,n){return r=p({},r,{zoom:Math.floor(r.zoom)}),t.prototype.evaluate.call(this,e,r,n)},e}(jr))(Aa.paint.properties["line-width"].specification);Ta.useIntegerZoom=!0;var Sa=function(t){function e(e){t.call(this,e,Aa)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setPaintProperty=function(e,r,n){t.prototype.setPaintProperty.call(this,e,r,n),"line-gradient"===e&&this._updateGradient()},e.prototype._updateGradient=function(){var t=this._transitionablePaint._values["line-gradient"].value.expression;this.gradient=fi(t,"lineProgress"),this.gradientTexture=null},e.prototype.recalculate=function(e){t.prototype.recalculate.call(this,e),this.paint._values["line-floorwidth"]=Ta.possiblyEvaluate(this._transitioningPaint._values["line-width"].value,e)},e.prototype.createBucket=function(t){return new wa(t)},e.prototype.queryRadius=function(t){var e=t,r=Ea($n("line-width",this,e),$n("line-gap-width",this,e)),n=$n("line-offset",this,e);return r/2+Math.abs(n)+Jn(this.paint.get("line-translate"))},e.prototype.queryIntersectsFeature=function(t,e,r,n,i,a){var o=Kn(t,this.paint.get("line-translate"),this.paint.get("line-translate-anchor"),i.angle,a),s=a/2*Ea(this.paint.get("line-width").evaluate(e),this.paint.get("line-gap-width").evaluate(e)),c=this.paint.get("line-offset").evaluate(e);return c&&(r=function(t,e){for(var r=[],n=new l(0,0),i=0;i0?e+2*t:t}var Ca=Xr([{name:"a_pos_offset",components:4,type:"Int16"},{name:"a_data",components:4,type:"Uint16"}]),La=Xr([{name:"a_projected_pos",components:3,type:"Float32"}],4),za=(Xr([{name:"a_fade_opacity",components:1,type:"Uint32"}],4),Xr([{name:"a_placed",components:2,type:"Uint8"}],4)),Pa=(Xr([{type:"Int16",name:"anchorPointX"},{type:"Int16",name:"anchorPointY"},{type:"Int16",name:"x1"},{type:"Int16",name:"y1"},{type:"Int16",name:"x2"},{type:"Int16",name:"y2"},{type:"Uint32",name:"featureIndex"},{type:"Uint16",name:"sourceLayerIndex"},{type:"Uint16",name:"bucketIndex"},{type:"Int16",name:"radius"},{type:"Int16",name:"signedDistanceFromAnchor"}]),Xr([{name:"a_pos",components:2,type:"Int16"},{name:"a_anchor_pos",components:2,type:"Int16"},{name:"a_extrude",components:2,type:"Int16"}],4)),Ia=Xr([{name:"a_pos",components:2,type:"Int16"},{name:"a_anchor_pos",components:2,type:"Int16"},{name:"a_extrude",components:2,type:"Int16"}],4);function Oa(t,e,r){var n=e.layout.get("text-transform").evaluate(r);return"uppercase"===n?t=t.toLocaleUpperCase():"lowercase"===n&&(t=t.toLocaleLowerCase()),Cr.applyArabicShaping&&(t=Cr.applyArabicShaping(t)),t}Xr([{type:"Int16",name:"anchorX"},{type:"Int16",name:"anchorY"},{type:"Uint16",name:"glyphStartIndex"},{type:"Uint16",name:"numGlyphs"},{type:"Uint32",name:"vertexStartIndex"},{type:"Uint32",name:"lineStartIndex"},{type:"Uint32",name:"lineLength"},{type:"Uint16",name:"segment"},{type:"Uint16",name:"lowerSize"},{type:"Uint16",name:"upperSize"},{type:"Float32",name:"lineOffsetX"},{type:"Float32",name:"lineOffsetY"},{type:"Uint8",name:"writingMode"},{type:"Uint8",name:"hidden"}]),Xr([{type:"Float32",name:"offsetX"}]),Xr([{type:"Int16",name:"x"},{type:"Int16",name:"y"},{type:"Int16",name:"tileUnitDistanceFromAnchor"}]);var Da={"!":"\ufe15","#":"\uff03",$:"\uff04","%":"\uff05","&":"\uff06","(":"\ufe35",")":"\ufe36","*":"\uff0a","+":"\uff0b",",":"\ufe10","-":"\ufe32",".":"\u30fb","/":"\uff0f",":":"\ufe13",";":"\ufe14","<":"\ufe3f","=":"\uff1d",">":"\ufe40","?":"\ufe16","@":"\uff20","[":"\ufe47","\\":"\uff3c","]":"\ufe48","^":"\uff3e",_:"\ufe33","`":"\uff40","{":"\ufe37","|":"\u2015","}":"\ufe38","~":"\uff5e","\xa2":"\uffe0","\xa3":"\uffe1","\xa5":"\uffe5","\xa6":"\uffe4","\xac":"\uffe2","\xaf":"\uffe3","\u2013":"\ufe32","\u2014":"\ufe31","\u2018":"\ufe43","\u2019":"\ufe44","\u201c":"\ufe41","\u201d":"\ufe42","\u2026":"\ufe19","\u2027":"\u30fb","\u20a9":"\uffe6","\u3001":"\ufe11","\u3002":"\ufe12","\u3008":"\ufe3f","\u3009":"\ufe40","\u300a":"\ufe3d","\u300b":"\ufe3e","\u300c":"\ufe41","\u300d":"\ufe42","\u300e":"\ufe43","\u300f":"\ufe44","\u3010":"\ufe3b","\u3011":"\ufe3c","\u3014":"\ufe39","\u3015":"\ufe3a","\u3016":"\ufe17","\u3017":"\ufe18","\uff01":"\ufe15","\uff08":"\ufe35","\uff09":"\ufe36","\uff0c":"\ufe10","\uff0d":"\ufe32","\uff0e":"\u30fb","\uff1a":"\ufe13","\uff1b":"\ufe14","\uff1c":"\ufe3f","\uff1e":"\ufe40","\uff1f":"\ufe16","\uff3b":"\ufe47","\uff3d":"\ufe48","\uff3f":"\ufe33","\uff5b":"\ufe37","\uff5c":"\u2015","\uff5d":"\ufe38","\uff5f":"\ufe35","\uff60":"\ufe36","\uff61":"\ufe12","\uff62":"\ufe41","\uff63":"\ufe42"},Ra=function(t){function e(e,r,n,i){t.call(this,e,r),this.angle=n,void 0!==i&&(this.segment=i)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.clone=function(){return new e(this.x,this.y,this.angle,this.segment)},e}(l);function Ba(t,e){var r=e.expression;if("constant"===r.kind)return{functionType:"constant",layoutSize:r.evaluate(new Lr(t+1))};if("source"===r.kind)return{functionType:"source"};for(var n=r.zoomStops,i=0;i0)&&("constant"!==i.value.kind||i.value.value.length>0),l="constant"!==o.value.kind||o.value.value&&o.value.value.length>0;if(this.features=[],s||l){for(var c=e.iconDependencies,u=e.glyphDependencies,h=new Lr(this.zoom),f=0,p=t;f=0;s--)a[s]={x:e[s].x,y:e[s].y,tileUnitDistanceFromAnchor:i},s>0&&(i+=e[s-1].dist(e[s]));for(var l=0;l0;this.addCollisionDebugVertices(s,l,c,u,h?this.collisionCircle:this.collisionBox,o.anchorPoint,r,h)}}}},Ha.prototype.deserializeCollisionBoxes=function(t,e,r,n,i){for(var a={},o=e;o0},Ha.prototype.hasIconData=function(){return this.icon.segments.get().length>0},Ha.prototype.hasCollisionBoxData=function(){return this.collisionBox.segments.get().length>0},Ha.prototype.hasCollisionCircleData=function(){return this.collisionCircle.segments.get().length>0},Ha.prototype.sortFeatures=function(t){var e=this;if(this.sortFeaturesByY&&this.sortedAngle!==t&&(this.sortedAngle=t,!(this.text.segments.get().length>1||this.icon.segments.get().length>1))){for(var r=[],n=0;ni.maxh||t>i.maxw||r<=i.maxh&&t<=i.maxw&&(o=i.maxw*i.maxh-t*r)a.free)){if(r===a.h)return this.allocShelf(s,t,r,n);r>a.h||ru)&&(h=2*Math.max(t,u)),(ll)&&(c=2*Math.max(r,l)),this.resize(h,c),this.packOne(t,r,n)):null},t.prototype.allocFreebin=function(t,e,r,n){var i=this.freebins.splice(t,1)[0];return i.id=n,i.w=e,i.h=r,i.refcount=0,this.bins[n]=i,this.ref(i),i},t.prototype.allocShelf=function(t,e,r,n){var i=this.shelves[t].alloc(e,r,n);return this.bins[n]=i,this.ref(i),i},t.prototype.shrink=function(){if(this.shelves.length>0){for(var t=0,e=0,r=0;rthis.free||e>this.h)return null;var n=this.x;return this.x+=t,this.free-=t,new function(t,e,r,n,i,a,o){this.id=t,this.x=e,this.y=r,this.w=n,this.h=i,this.maxw=a||n,this.maxh=o||i,this.refcount=0}(r,n,this.y,t,e,t,this.h)},e.prototype.resize=function(t){return this.free+=t-this.w,this.w=t,!0},t}()}),Qa=function(t,e){var r=e.pixelRatio;this.paddedRect=t,this.pixelRatio=r},to={tl:{configurable:!0},br:{configurable:!0},displaySize:{configurable:!0}};to.tl.get=function(){return[this.paddedRect.x+1,this.paddedRect.y+1]},to.br.get=function(){return[this.paddedRect.x+this.paddedRect.w-1,this.paddedRect.y+this.paddedRect.h-1]},to.displaySize.get=function(){return[(this.paddedRect.w-2)/this.pixelRatio,(this.paddedRect.h-2)/this.pixelRatio]},Object.defineProperties(Qa.prototype,to);var eo=function(t){var e=new ui({width:0,height:0}),r={},n=new Ka(0,0,{autoResize:!0});for(var i in t){var a=t[i],o=n.packOne(a.data.width+2,a.data.height+2);e.resize({width:n.w,height:n.h}),ui.copy(a.data,e,{x:0,y:0},{x:o.x+1,y:o.y+1},a.data),r[i]=new Qa(o,a)}n.shrink(),e.resize({width:n.w,height:n.h}),this.image=e,this.positions=r};pr("ImagePosition",Qa),pr("ImageAtlas",eo);var ro=function(t,e,r,n,i){var a,o,s=8*i-n-1,l=(1<>1,u=-7,h=r?i-1:0,f=r?-1:1,p=t[e+h];for(h+=f,a=p&(1<<-u)-1,p>>=-u,u+=s;u>0;a=256*a+t[e+h],h+=f,u-=8);for(o=a&(1<<-u)-1,a>>=-u,u+=n;u>0;o=256*o+t[e+h],h+=f,u-=8);if(0===a)a=1-c;else{if(a===l)return o?NaN:1/0*(p?-1:1);o+=Math.pow(2,n),a-=c}return(p?-1:1)*o*Math.pow(2,a-n)},no=function(t,e,r,n,i,a){var o,s,l,c=8*a-i-1,u=(1<>1,f=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:a-1,d=n?1:-1,g=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(s=isNaN(e)?1:0,o=u):(o=Math.floor(Math.log(e)/Math.LN2),e*(l=Math.pow(2,-o))<1&&(o--,l*=2),(e+=o+h>=1?f/l:f*Math.pow(2,1-h))*l>=2&&(o++,l/=2),o+h>=u?(s=0,o=u):o+h>=1?(s=(e*l-1)*Math.pow(2,i),o+=h):(s=e*Math.pow(2,h-1)*Math.pow(2,i),o=0));i>=8;t[r+p]=255&s,p+=d,s/=256,i-=8);for(o=o<0;t[r+p]=255&o,p+=d,o/=256,c-=8);t[r+p-d]|=128*g},io=ao;function ao(t){this.buf=ArrayBuffer.isView&&ArrayBuffer.isView(t)?t:new Uint8Array(t||0),this.pos=0,this.type=0,this.length=this.buf.length}function oo(t){return t.type===ao.Bytes?t.readVarint()+t.pos:t.pos+1}function so(t,e,r){return r?4294967296*e+(t>>>0):4294967296*(e>>>0)+(t>>>0)}function lo(t,e,r){var n=e<=16383?1:e<=2097151?2:e<=268435455?3:Math.ceil(Math.log(e)/(7*Math.LN2));r.realloc(n);for(var i=r.pos-1;i>=t;i--)r.buf[i+n]=r.buf[i]}function co(t,e){for(var r=0;r>>8,t[r+2]=e>>>16,t[r+3]=e>>>24}function _o(t,e){return(t[e]|t[e+1]<<8|t[e+2]<<16)+(t[e+3]<<24)}ao.Varint=0,ao.Fixed64=1,ao.Bytes=2,ao.Fixed32=5,ao.prototype={destroy:function(){this.buf=null},readFields:function(t,e,r){for(r=r||this.length;this.pos>3,a=this.pos;this.type=7&n,t(i,e,this),this.pos===a&&this.skip(n)}return e},readMessage:function(t,e){return this.readFields(t,e,this.readVarint()+this.pos)},readFixed32:function(){var t=xo(this.buf,this.pos);return this.pos+=4,t},readSFixed32:function(){var t=_o(this.buf,this.pos);return this.pos+=4,t},readFixed64:function(){var t=xo(this.buf,this.pos)+4294967296*xo(this.buf,this.pos+4);return this.pos+=8,t},readSFixed64:function(){var t=xo(this.buf,this.pos)+4294967296*_o(this.buf,this.pos+4);return this.pos+=8,t},readFloat:function(){var t=ro(this.buf,this.pos,!0,23,4);return this.pos+=4,t},readDouble:function(){var t=ro(this.buf,this.pos,!0,52,8);return this.pos+=8,t},readVarint:function(t){var e,r,n=this.buf;return e=127&(r=n[this.pos++]),r<128?e:(e|=(127&(r=n[this.pos++]))<<7,r<128?e:(e|=(127&(r=n[this.pos++]))<<14,r<128?e:(e|=(127&(r=n[this.pos++]))<<21,r<128?e:function(t,e,r){var n,i,a=r.buf;if(n=(112&(i=a[r.pos++]))>>4,i<128)return so(t,n,e);if(n|=(127&(i=a[r.pos++]))<<3,i<128)return so(t,n,e);if(n|=(127&(i=a[r.pos++]))<<10,i<128)return so(t,n,e);if(n|=(127&(i=a[r.pos++]))<<17,i<128)return so(t,n,e);if(n|=(127&(i=a[r.pos++]))<<24,i<128)return so(t,n,e);if(n|=(1&(i=a[r.pos++]))<<31,i<128)return so(t,n,e);throw new Error("Expected varint not more than 10 bytes")}(e|=(15&(r=n[this.pos]))<<28,t,this))))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var t=this.readVarint();return t%2==1?(t+1)/-2:t/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var t=this.readVarint()+this.pos,e=function(t,e,r){for(var n="",i=e;i239?4:l>223?3:l>191?2:1;if(i+u>r)break;1===u?l<128&&(c=l):2===u?128==(192&(a=t[i+1]))&&(c=(31&l)<<6|63&a)<=127&&(c=null):3===u?(a=t[i+1],o=t[i+2],128==(192&a)&&128==(192&o)&&((c=(15&l)<<12|(63&a)<<6|63&o)<=2047||c>=55296&&c<=57343)&&(c=null)):4===u&&(a=t[i+1],o=t[i+2],s=t[i+3],128==(192&a)&&128==(192&o)&&128==(192&s)&&((c=(15&l)<<18|(63&a)<<12|(63&o)<<6|63&s)<=65535||c>=1114112)&&(c=null)),null===c?(c=65533,u=1):c>65535&&(c-=65536,n+=String.fromCharCode(c>>>10&1023|55296),c=56320|1023&c),n+=String.fromCharCode(c),i+=u}return n}(this.buf,this.pos,t);return this.pos=t,e},readBytes:function(){var t=this.readVarint()+this.pos,e=this.buf.subarray(this.pos,t);return this.pos=t,e},readPackedVarint:function(t,e){var r=oo(this);for(t=t||[];this.pos127;);else if(e===ao.Bytes)this.pos=this.readVarint()+this.pos;else if(e===ao.Fixed32)this.pos+=4;else{if(e!==ao.Fixed64)throw new Error("Unimplemented type: "+e);this.pos+=8}},writeTag:function(t,e){this.writeVarint(t<<3|e)},realloc:function(t){for(var e=this.length||16;e268435455||t<0?function(t,e){var r,n;if(t>=0?(r=t%4294967296|0,n=t/4294967296|0):(n=~(-t/4294967296),4294967295^(r=~(-t%4294967296))?r=r+1|0:(r=0,n=n+1|0)),t>=0x10000000000000000||t<-0x10000000000000000)throw new Error("Given varint doesn't fit into 10 bytes");e.realloc(10),function(t,e,r){r.buf[r.pos++]=127&t|128,t>>>=7,r.buf[r.pos++]=127&t|128,t>>>=7,r.buf[r.pos++]=127&t|128,t>>>=7,r.buf[r.pos++]=127&t|128,t>>>=7,r.buf[r.pos]=127&t}(r,0,e),function(t,e){var r=(7&t)<<4;e.buf[e.pos++]|=r|((t>>>=3)?128:0),t&&(e.buf[e.pos++]=127&t|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=127&t|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=127&t|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=127&t|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=127&t)))))}(n,e)}(t,this):(this.realloc(4),this.buf[this.pos++]=127&t|(t>127?128:0),t<=127||(this.buf[this.pos++]=127&(t>>>=7)|(t>127?128:0),t<=127||(this.buf[this.pos++]=127&(t>>>=7)|(t>127?128:0),t<=127||(this.buf[this.pos++]=t>>>7&127))))},writeSVarint:function(t){this.writeVarint(t<0?2*-t-1:2*t)},writeBoolean:function(t){this.writeVarint(Boolean(t))},writeString:function(t){t=String(t),this.realloc(4*t.length),this.pos++;var e=this.pos;this.pos=function(t,e,r){for(var n,i,a=0;a55295&&n<57344){if(!i){n>56319||a+1===e.length?(t[r++]=239,t[r++]=191,t[r++]=189):i=n;continue}if(n<56320){t[r++]=239,t[r++]=191,t[r++]=189,i=n;continue}n=i-55296<<10|n-56320|65536,i=null}else i&&(t[r++]=239,t[r++]=191,t[r++]=189,i=null);n<128?t[r++]=n:(n<2048?t[r++]=n>>6|192:(n<65536?t[r++]=n>>12|224:(t[r++]=n>>18|240,t[r++]=n>>12&63|128),t[r++]=n>>6&63|128),t[r++]=63&n|128)}return r}(this.buf,t,this.pos);var r=this.pos-e;r>=128&&lo(e,r,this),this.pos=e-1,this.writeVarint(r),this.pos+=r},writeFloat:function(t){this.realloc(4),no(this.buf,t,this.pos,!0,23,4),this.pos+=4},writeDouble:function(t){this.realloc(8),no(this.buf,t,this.pos,!0,52,8),this.pos+=8},writeBytes:function(t){var e=t.length;this.writeVarint(e),this.realloc(e);for(var r=0;r=128&&lo(r,n,this),this.pos=r-1,this.writeVarint(n),this.pos+=n},writeMessage:function(t,e,r){this.writeTag(t,ao.Bytes),this.writeRawMessage(e,r)},writePackedVarint:function(t,e){this.writeMessage(t,co,e)},writePackedSVarint:function(t,e){this.writeMessage(t,uo,e)},writePackedBoolean:function(t,e){this.writeMessage(t,po,e)},writePackedFloat:function(t,e){this.writeMessage(t,ho,e)},writePackedDouble:function(t,e){this.writeMessage(t,fo,e)},writePackedFixed32:function(t,e){this.writeMessage(t,go,e)},writePackedSFixed32:function(t,e){this.writeMessage(t,mo,e)},writePackedFixed64:function(t,e){this.writeMessage(t,vo,e)},writePackedSFixed64:function(t,e){this.writeMessage(t,yo,e)},writeBytesField:function(t,e){this.writeTag(t,ao.Bytes),this.writeBytes(e)},writeFixed32Field:function(t,e){this.writeTag(t,ao.Fixed32),this.writeFixed32(e)},writeSFixed32Field:function(t,e){this.writeTag(t,ao.Fixed32),this.writeSFixed32(e)},writeFixed64Field:function(t,e){this.writeTag(t,ao.Fixed64),this.writeFixed64(e)},writeSFixed64Field:function(t,e){this.writeTag(t,ao.Fixed64),this.writeSFixed64(e)},writeVarintField:function(t,e){this.writeTag(t,ao.Varint),this.writeVarint(e)},writeSVarintField:function(t,e){this.writeTag(t,ao.Varint),this.writeSVarint(e)},writeStringField:function(t,e){this.writeTag(t,ao.Bytes),this.writeString(e)},writeFloatField:function(t,e){this.writeTag(t,ao.Fixed32),this.writeFloat(e)},writeDoubleField:function(t,e){this.writeTag(t,ao.Fixed64),this.writeDouble(e)},writeBooleanField:function(t,e){this.writeVarintField(t,Boolean(e))}};var wo=3;function ko(t,e,r){1===t&&r.readMessage(Mo,e)}function Mo(t,e,r){if(3===t){var n=r.readMessage(Ao,{}),i=n.id,a=n.bitmap,o=n.width,s=n.height,l=n.left,c=n.top,u=n.advance;e.push({id:i,bitmap:new ci({width:o+2*wo,height:s+2*wo},a),metrics:{width:o,height:s,left:l,top:c,advance:u}})}}function Ao(t,e,r){1===t?e.id=r.readVarint():2===t?e.bitmap=r.readBytes():3===t?e.width=r.readVarint():4===t?e.height=r.readVarint():5===t?e.left=r.readSVarint():6===t?e.top=r.readSVarint():7===t&&(e.advance=r.readVarint())}var To=wo,So=function(t,e,r){this.target=t,this.parent=e,this.mapId=r,this.callbacks={},this.callbackID=0,g(["receive"],this),this.target.addEventListener("message",this.receive,!1)};So.prototype.send=function(t,e,r,n){var i=r?this.mapId+":"+this.callbackID++:null;r&&(this.callbacks[i]=r);var a=[];this.target.postMessage({targetMapId:n,sourceMapId:this.mapId,type:t,id:String(i),data:gr(e,a)},a)},So.prototype.receive=function(t){var e,r=this,n=t.data,i=n.id;if(!n.targetMapId||this.mapId===n.targetMapId){var a=function(t,e){var n=[];r.target.postMessage({sourceMapId:r.mapId,type:"",id:String(i),error:t?gr(t):null,data:gr(e,n)},n)};if(""===n.type)e=this.callbacks[n.id],delete this.callbacks[n.id],e&&n.error?e(mr(n.error)):e&&e(null,mr(n.data));else if(void 0!==n.id&&this.parent[n.type])this.parent[n.type](n.sourceMapId,mr(n.data),a);else if(void 0!==n.id&&this.parent.getWorkerSource){var o=n.type.split(".");this.parent.getWorkerSource(n.sourceMapId,o[0],o[1])[o[2]](mr(n.data),a)}else this.parent[n.type](mr(n.data))}},So.prototype.remove=function(){this.target.removeEventListener("message",this.receive,!1)};var Eo=n(i(function(t,e){!function(t){function e(t,e,n){var i=r(256*t,256*(e=Math.pow(2,n)-e-1),n),a=r(256*(t+1),256*(e+1),n);return i[0]+","+i[1]+","+a[0]+","+a[1]}function r(t,e,r){var n=2*Math.PI*6378137/256/Math.pow(2,r);return[t*n-2*Math.PI*6378137/2,e*n-2*Math.PI*6378137/2]}t.getURL=function(t,r,n,i,a,o){return o=o||{},t+"?"+["bbox="+e(n,i,a),"format="+(o.format||"image/png"),"service="+(o.service||"WMS"),"version="+(o.version||"1.1.1"),"request="+(o.request||"GetMap"),"srs="+(o.srs||"EPSG:3857"),"width="+(o.width||256),"height="+(o.height||256),"layers="+r].join("&")},t.getTileBBox=e,t.getMercCoords=r,Object.defineProperty(t,"__esModule",{value:!0})}(e)})),Co=function(t,e,r){this.z=t,this.x=e,this.y=r,this.key=Po(0,t,e,r)};Co.prototype.equals=function(t){return this.z===t.z&&this.x===t.x&&this.y===t.y},Co.prototype.url=function(t,e){var r=Eo.getTileBBox(this.x,this.y,this.z),n=function(t,e,r){for(var n,i="",a=t;a>0;a--)i+=(e&(n=1<this.canonical.z?new zo(t,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y):new zo(t,this.wrap,t,this.canonical.x>>e,this.canonical.y>>e)},zo.prototype.isChildOf=function(t){var e=this.canonical.z-t.canonical.z;return 0===t.overscaledZ||t.overscaledZ>e&&t.canonical.y===this.canonical.y>>e},zo.prototype.children=function(t){if(this.overscaledZ>=t)return[new zo(this.overscaledZ+1,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y)];var e=this.canonical.z+1,r=2*this.canonical.x,n=2*this.canonical.y;return[new zo(e,this.wrap,e,r,n),new zo(e,this.wrap,e,r+1,n),new zo(e,this.wrap,e,r,n+1),new zo(e,this.wrap,e,r+1,n+1)]},zo.prototype.isLessThan=function(t){return this.wrapt.wrap)&&(this.overscaledZt.overscaledZ)&&(this.canonical.xt.canonical.x)&&this.canonical.y=this.dim+this.border||e<-this.border||e>=this.dim+this.border)throw new RangeError("out of range source coordinates for DEM data");return(e+this.border)*this.stride+(t+this.border)},pr("Level",Io);var Oo=function(t,e,r){this.uid=t,this.scale=e||1,this.level=r||new Io(256,512),this.loaded=!!r};Oo.prototype.loadFromImage=function(t,e){if(t.height!==t.width)throw new RangeError("DEM tiles must be square");if(e&&"mapbox"!==e&&"terrarium"!==e)return _('"'+e+'" is not a valid encoding type. Valid types include "mapbox" and "terrarium".');var r=this.level=new Io(t.width,t.width/2),n=t.data;this._unpackData(r,n,e||"mapbox");for(var i=0;i=0&&l[3]>=0&&this.grid.insert(a,l[0],l[1],l[2],l[3])}},Fo.prototype.loadVTLayers=function(){return this.vtLayers||(this.vtLayers=new ga.VectorTile(new io(this.rawTileData)).layers,this.sourceLayerCoder=new Do(this.vtLayers?Object.keys(this.vtLayers).sort():["_geojsonTileLayer"])),this.vtLayers},Fo.prototype.query=function(t,e){var r=this;this.loadVTLayers();for(var n=t.params||{},i=Dn/t.tileSize/t.scale,a=Re(n.filter),o=t.queryGeometry,s=t.queryPadding*i,l=1/0,c=1/0,u=-1/0,h=-1/0,f=0;f=0)return!0;return!1}(a,l)){var c=this.sourceLayerCoder.decode(r),u=this.vtLayers[c].feature(n);if(i(new Lr(this.tileID.overscaledZ),u))for(var h=0;h=200&&r.status<300&&r.response){var n;try{n=JSON.parse(r.response)}catch(t){return e(t)}e(null,n)}else 401===r.status&&t.url.match(/mapbox.com/)?e(new A(r.statusText+": you may have provided an invalid Mapbox access token. See https://www.mapbox.com/api-documentation/#access-tokens",r.status,t.url)):e(new A(r.statusText,r.status,t.url))},r.send(),r},e.getImage=function(t,e){return S(t,function(t,r){if(t)e(t);else if(r){var n=new self.Image,i=self.URL||self.webkitURL;n.onload=function(){e(null,n),i.revokeObjectURL(n.src)};var a=new self.Blob([new Uint8Array(r.data)],{type:"image/png"});n.cacheControl=r.cacheControl,n.expires=r.expires,n.src=r.data.byteLength?i.createObjectURL(a):"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII="}})},e.ResourceType=M,e.RGBAImage=ui,e.default$2=Ka,e.ImagePosition=Qa,e.getArrayBuffer=S,e.default$3=function(t){return new io(t).readFields(ko,[])},e.default$4=yr,e.asyncAll=function(t,e,r){if(!t.length)return r(null,[]);var n=t.length,i=new Array(t.length),a=null;t.forEach(function(t,o){e(t,function(t,e){t&&(a=t),i[o]=e,0==--n&&r(a,i)})})},e.AlphaImage=ci,e.default$5=I,e.endsWith=m,e.extend=p,e.sphericalToCartesian=function(t){var e=t[0],r=t[1],n=t[2];return r+=90,r*=Math.PI/180,n*=Math.PI/180,{x:e*Math.cos(r)*Math.sin(n),y:e*Math.sin(r)*Math.sin(n),z:e*Math.cos(n)}},e.Evented=P,e.validateStyle=nr,e.validateLight=ir,e.emitValidationErrors=sr,e.default$6=tt,e.number=wt,e.Properties=qr,e.Transitionable=Ir,e.Transitioning=Dr,e.PossiblyEvaluated=Fr,e.DataConstantProperty=Nr,e.warnOnce=_,e.uniqueId=function(){return d++},e.default$7=So,e.pick=function(t,e){for(var r={},n=0;n@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g,function(t,r,n,i){var a=n||i;return e[r]=!a||a.toLowerCase(),""}),e["max-age"]){var r=parseInt(e["max-age"],10);isNaN(r)?delete e["max-age"]:e["max-age"]=r}return e},e.default$11=Fo,e.default$12=Ro,e.default$13=Re,e.default$14=Ha,e.CollisionBoxArray=mn,e.default$15=Tn,e.TriangleIndexArray=hn,e.default$16=Lr,e.default$17=s,e.keysDifference=function(t,e){var r=[];for(var n in t)n in e||r.push(n);return r},e.default$18=["type","source","source-layer","minzoom","maxzoom","filter","layout"],e.mat4=ri,e.vec4=ei,e.getSizeData=Ba,e.evaluateSizeForFeature=function(t,e,r){var n=e;return"source"===t.functionType?r.lowerSize/10:"composite"===t.functionType?wt(r.lowerSize/10,r.upperSize/10,n.uSizeT):n.uSize},e.evaluateSizeForZoom=function(t,e,r){if("constant"===t.functionType)return{uSizeT:0,uSize:t.layoutSize};if("source"===t.functionType)return{uSizeT:0,uSize:0};if("camera"===t.functionType){var n=t.propertyValue,i=t.zoomRange,a=t.sizeRange,o=f(Se(n,r.specification).interpolationFactor(e,i.min,i.max),0,1);return{uSizeT:0,uSize:a.min+o*(a.max-a.min)}}var s=t.propertyValue,l=t.zoomRange;return{uSizeT:f(Se(s,r.specification).interpolationFactor(e,l.min,l.max),0,1),uSize:0}},e.addDynamicAttributes=Va,e.default$19=Wa,e.WritingMode=jo,e.multiPolygonIntersectsBufferedPoint=jn,e.multiPolygonIntersectsMultiPolygon=Vn,e.multiPolygonIntersectsBufferedMultiLine=Un,e.polygonIntersectsPolygon=function(t,e){for(var r=0;r-r/2;){if(--o<0)return!1;s-=t[o].dist(a),a=t[o]}s+=t[o].dist(t[o+1]),o++;for(var l=[],c=0;sn;)c-=l.shift().angleDelta;if(c>i)return!1;o++,s+=h.dist(f)}return!0}function a(e,r,n,a,o,s,l,c,u){var h=a?.6*s*l:0,f=Math.max(a?a.right-a.left:0,o?o.right-o.left:0),p=0===e[0].x||e[0].x===u||0===e[0].y||e[0].y===u;return r-f*l=0&&M=0&&A=0&&m+f<=p){var T=new t.default$25(M,A,w,y);T._round(),o&&!i(r,T,l,o,s)||v.push(T)}}g+=_}return u||v.length||c||(v=e(r,g/2,a,o,s,l,c,!0,h)),v}(e,p?r/2*c%r:(f/2+2*s)*l*c%r,r,h,n,f*l,p,!1,u)}n.prototype.replace=function(t){this._layerConfigs={},this._layers={},this.update(t,[])},n.prototype.update=function(e,n){for(var i=this,a=0,o=e;a0&&(g=Math.max(10*s,g),this._addLineCollisionCircles(t,e,r,r.segment,m,g,n,i,a,u))}else t.emplaceBack(r.x,r.y,p,h,d,f,n,i,a,0,0);this.boxEndIndex=t.length};s.prototype._addLineCollisionCircles=function(t,e,r,n,i,a,o,s,l,c){var u=a/2,h=Math.floor(i/u),f=1+.4*Math.log(c)/Math.LN2,p=Math.floor(h*f/2),d=-a/2,g=r,m=n+1,v=d,y=-i/2,x=y-i/4;do{if(--m<0){if(v>y)return;m=0;break}v-=e[m].dist(g),g=e[m]}while(v>x);for(var b=e[m].dist(e[m+1]),_=-p;_i&&(k+=w-i),!(k=e.length)return;b=e[m].dist(e[m+1])}var M=k-v,A=e[m],T=e[m+1].sub(A)._unit()._mult(M)._add(A)._round(),S=Math.abs(k-d)0)for(var r=(this.length>>1)-1;r>=0;r--)this._down(r)}function h(t,e){return te?1:0}function f(e,r,n){void 0===r&&(r=1),void 0===n&&(n=!1);for(var i=1/0,a=1/0,o=-1/0,s=-1/0,c=e[0],u=0;uo)&&(o=h.x),(!u||h.y>s)&&(s=h.y)}var f=o-i,g=s-a,m=Math.min(f,g),v=m/2,y=new l(null,p);if(0===m)return new t.default$1(i,a);for(var x=i;x_.d||!_.d)&&(_=k,n&&console.log("found best %d after %d probes",Math.round(1e4*k.d)/1e4,w)),k.max-_.d<=r||(v=k.h/2,y.push(new d(k.p.x-v,k.p.y-v,v,e)),y.push(new d(k.p.x+v,k.p.y-v,v,e)),y.push(new d(k.p.x-v,k.p.y+v,v,e)),y.push(new d(k.p.x+v,k.p.y+v,v,e)),w+=4)}return n&&(console.log("num probes: "+w),console.log("best distance: "+_.d)),_.p}function p(t,e){return e.max-t.max}function d(e,r,n,i){this.p=new t.default$1(e,r),this.h=n,this.d=function(e,r){for(var n=!1,i=1/0,a=0;ae.y!=h.y>e.y&&e.x<(h.x-u.x)*(e.y-u.y)/(h.y-u.y)+u.x&&(n=!n),i=Math.min(i,t.distToSegmentSquared(e,u,h))}return(n?1:-1)*Math.sqrt(i)}(this.p,i),this.max=this.d+this.h*Math.SQRT2}function g(e,r,n,i,a,o){e.createArrays(),e.symbolInstances=[];var s=512*e.overscaling;e.tilePixelRatio=t.default$8/s,e.compareText={},e.iconsNeedLinear=!1;var l=e.layers[0].layout,c=e.layers[0]._unevaluatedLayout._values,u={};if("composite"===e.textSizeData.functionType){var h=e.textSizeData.zoomRange,f=h.min,p=h.max;u.compositeTextSizes=[c["text-size"].possiblyEvaluate(new t.default$16(f)),c["text-size"].possiblyEvaluate(new t.default$16(p))]}if("composite"===e.iconSizeData.functionType){var d=e.iconSizeData.zoomRange,g=d.min,v=d.max;u.compositeIconSizes=[c["icon-size"].possiblyEvaluate(new t.default$16(g)),c["icon-size"].possiblyEvaluate(new t.default$16(v))]}u.layoutTextSize=c["text-size"].possiblyEvaluate(new t.default$16(e.zoom+1)),u.layoutIconSize=c["icon-size"].possiblyEvaluate(new t.default$16(e.zoom+1)),u.textMaxSize=c["text-size"].possiblyEvaluate(new t.default$16(18));for(var y=24*l.get("text-line-height"),x="map"===l.get("text-rotation-alignment")&&"line"===l.get("symbol-placement"),b=l.get("text-keep-upright"),_=0,w=e.features;_=t.default$8||u.y<0||u.y>=t.default$8||e.symbolInstances.push(function(e,r,n,i,a,l,c,u,h,f,p,d,g,m,y,x,b,_,w,k,M){var A,T,S=e.addToLineVertexArray(r,n),E=0,C=0,L=0,z=i.horizontal?i.horizontal.text:"",P=[];i.horizontal&&(A=new s(c,n,r,u,h,f,i.horizontal,p,d,g,e.overscaling),C+=v(e,r,i.horizontal,l,g,w,m,S,i.vertical?t.WritingMode.horizontal:t.WritingMode.horizontalOnly,P,k,M),i.vertical&&(L+=v(e,r,i.vertical,l,g,w,m,S,t.WritingMode.vertical,P,k,M)));var I=A?A.boxStartIndex:e.collisionBoxArray.length,O=A?A.boxEndIndex:e.collisionBoxArray.length;if(a){var D=function(e,r,n,i,a,o){var s,l,c,u,h=r.image,f=n.layout,p=r.top-1/h.pixelRatio,d=r.left-1/h.pixelRatio,g=r.bottom+1/h.pixelRatio,m=r.right+1/h.pixelRatio;if("none"!==f.get("icon-text-fit")&&a){var v=m-d,y=g-p,x=f.get("text-size").evaluate(o)/24,b=a.left*x,_=a.right*x,w=a.top*x,k=_-b,M=a.bottom*x-w,A=f.get("icon-text-fit-padding")[0],T=f.get("icon-text-fit-padding")[1],S=f.get("icon-text-fit-padding")[2],E=f.get("icon-text-fit-padding")[3],C="width"===f.get("icon-text-fit")?.5*(M-y):0,L="height"===f.get("icon-text-fit")?.5*(k-v):0,z="width"===f.get("icon-text-fit")||"both"===f.get("icon-text-fit")?k:v,P="height"===f.get("icon-text-fit")||"both"===f.get("icon-text-fit")?M:y;s=new t.default$1(b+L-E,w+C-A),l=new t.default$1(b+L+T+z,w+C-A),c=new t.default$1(b+L+T+z,w+C+S+P),u=new t.default$1(b+L-E,w+C+S+P)}else s=new t.default$1(d,p),l=new t.default$1(m,p),c=new t.default$1(m,g),u=new t.default$1(d,g);var I=n.layout.get("icon-rotate").evaluate(o)*Math.PI/180;if(I){var O=Math.sin(I),D=Math.cos(I),R=[D,-O,O,D];s._matMult(R),l._matMult(R),u._matMult(R),c._matMult(R)}return[{tl:s,tr:l,bl:u,br:c,tex:h.paddedRect,writingMode:void 0,glyphOffset:[0,0]}]}(0,a,l,0,i.horizontal,w);T=new s(c,n,r,u,h,f,a,y,x,!1,e.overscaling),E=4*D.length;var R=e.iconSizeData,B=null;"source"===R.functionType?B=[10*l.layout.get("icon-size").evaluate(w)]:"composite"===R.functionType&&(B=[10*M.compositeIconSizes[0].evaluate(w),10*M.compositeIconSizes[1].evaluate(w)]),e.addSymbols(e.icon,D,B,_,b,w,!1,r,S.lineStartIndex,S.lineLength)}var F=T?T.boxStartIndex:e.collisionBoxArray.length,N=T?T.boxEndIndex:e.collisionBoxArray.length;return e.glyphOffsetArray.length>=t.default$14.MAX_GLYPHS&&t.warnOnce("Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907"),{key:z,textBoxStartIndex:I,textBoxEndIndex:O,iconBoxStartIndex:F,iconBoxEndIndex:N,textOffset:m,iconOffset:_,anchor:r,line:n,featureIndex:u,feature:w,numGlyphVertices:C,numVerticalGlyphVertices:L,numIconVertices:E,textOpacityState:new o,iconOpacityState:new o,isDuplicate:!1,placedTextSymbolIndices:P,crossTileID:0}}(e,u,a,n,i,e.layers[0],e.collisionBoxArray,r.index,r.sourceLayerIndex,e.index,b,M,S,g,w,A,E,m,r,l,c))};if("line"===d.get("symbol-placement"))for(var z=0,P=function(e,r,n,i,a){for(var o=[],s=0;s=i&&f.x>=i||(h.x>=i?h=new t.default$1(i,h.y+(f.y-h.y)*((i-h.x)/(f.x-h.x)))._round():f.x>=i&&(f=new t.default$1(i,h.y+(f.y-h.y)*((i-h.x)/(f.x-h.x)))._round()),h.y>=a&&f.y>=a||(h.y>=a?h=new t.default$1(h.x+(f.x-h.x)*((a-h.y)/(f.y-h.y)),a)._round():f.y>=a&&(f=new t.default$1(h.x+(f.x-h.x)*((a-h.y)/(f.y-h.y)),a)._round()),c&&h.equals(c[c.length-1])||(c=[h],o.push(c)),c.push(f)))))}return o}(r.geometry,0,0,t.default$8,t.default$8);z=0;o--)if(n.dist(a[o])0&&(this.data[0]=this.data[this.length],this._down(0)),this.data.pop(),t}},peek:function(){return this.data[0]},_up:function(t){for(var e=this.data,r=this.compare,n=e[t];t>0;){var i=t-1>>1,a=e[i];if(r(n,a)>=0)break;e[t]=a,t=i}e[t]=n},_down:function(t){for(var e=this.data,r=this.compare,n=this.length>>1,i=e[t];t=0)break;e[t]=s,t=a}e[t]=i}},l.default=c;var x=function(e){var r=new t.AlphaImage({width:0,height:0}),n={},i=new t.default$2(0,0,{autoResize:!0});for(var a in e){var o=e[a],s=n[a]={};for(var l in o){var c=o[+l];if(c&&0!==c.bitmap.width&&0!==c.bitmap.height){var u=i.packOne(c.bitmap.width+2,c.bitmap.height+2);r.resize({width:i.w,height:i.h}),t.AlphaImage.copy(c.bitmap,r,{x:0,y:0},{x:u.x+1,y:u.y+1},c.bitmap),s[l]={rect:u,metrics:c.metrics}}}}i.shrink(),r.resize({width:i.w,height:i.h}),this.image=r,this.positions=n};t.register("GlyphAtlas",x);var b=function(e){this.tileID=new t.OverscaledTileID(e.tileID.overscaledZ,e.tileID.wrap,e.tileID.canonical.z,e.tileID.canonical.x,e.tileID.canonical.y),this.uid=e.uid,this.zoom=e.zoom,this.pixelRatio=e.pixelRatio,this.tileSize=e.tileSize,this.source=e.source,this.overscaling=this.tileID.overscaleFactor(),this.showCollisionBoxes=e.showCollisionBoxes,this.collectResourceTiming=!!e.collectResourceTiming};function _(e,r){for(var n=new t.default$16(r),i=0,a=e;i=T.maxzoom||"none"!==T.visibility&&(_(A,a.zoom),(h[T.id]=T.createBucket({index:s.bucketLayerIDs.length,layers:A,zoom:a.zoom,pixelRatio:a.pixelRatio,overscaling:a.overscaling,collisionBoxArray:a.collisionBoxArray,sourceLayerIndex:v})).populate(y,f),s.bucketLayerIDs.push(A.map(function(t){return t.id})))}}}var S=t.mapObject(f.glyphDependencies,function(t){return Object.keys(t).map(Number)});Object.keys(S).length?n.send("getGlyphs",{uid:this.uid,stacks:S},function(t,e){l||(l=t,c=e,C.call(a))}):c={};var E=Object.keys(f.iconDependencies);function C(){if(l)return i(l);if(c&&u){var e=new x(c),r=new t.default$28(u);for(var n in h){var a=h[n];a instanceof t.default$14&&(_(a.layers,this.zoom),g(a,c,e.positions,u,r.positions,this.showCollisionBoxes))}this.status="done",i(null,{buckets:t.values(h).filter(function(t){return!t.isEmpty()}),featureIndex:s,collisionBoxArray:this.collisionBoxArray,glyphAtlasImage:e.image,iconAtlasImage:r.image})}}E.length?n.send("getImages",{icons:E},function(t,e){l||(l=t,u=e,C.call(a))}):u={},C.call(this)};var w=function(t){return!(!performance||!performance.getEntriesByName)&&performance.getEntriesByName(t)};function k(e,r){var n=t.getArrayBuffer(e.request,function(e,n){e?r(e):n&&r(null,{vectorTile:new t.default$29.VectorTile(new t.default$30(n.data)),rawData:n.data,cacheControl:n.cacheControl,expires:n.expires})});return function(){n.abort(),r()}}var M=function(t,e,r){this.actor=t,this.layerIndex=e,this.loadVectorData=r||k,this.loading={},this.loaded={}};M.prototype.loadTile=function(e,r){var n=this,i=e.uid;this.loading||(this.loading={});var a=this.loading[i]=new b(e);a.abort=this.loadVectorData(e,function(o,s){if(delete n.loading[i],o||!s)return r(o);var l=s.rawData,c={};s.expires&&(c.expires=s.expires),s.cacheControl&&(c.cacheControl=s.cacheControl);var u={};if(e.request&&e.request.collectResourceTiming){var h=w(e.request.url);h&&(u.resourceTiming=JSON.parse(JSON.stringify(h)))}a.vectorTile=s.vectorTile,a.parse(s.vectorTile,n.layerIndex,n.actor,function(e,n){if(e||!n)return r(e);r(null,t.extend({rawTileData:l.slice(0)},n,c,u))}),n.loaded=n.loaded||{},n.loaded[i]=a})},M.prototype.reloadTile=function(t,e){var r=this.loaded,n=t.uid,i=this;if(r&&r[n]){var a=r[n];a.showCollisionBoxes=t.showCollisionBoxes;var o=function(t,r){var n=a.reloadCallback;n&&(delete a.reloadCallback,a.parse(a.vectorTile,i.layerIndex,i.actor,n)),e(t,r)};"parsing"===a.status?a.reloadCallback=o:"done"===a.status&&a.parse(a.vectorTile,this.layerIndex,this.actor,o)}},M.prototype.abortTile=function(t,e){var r=this.loading,n=t.uid;r&&r[n]&&r[n].abort&&(r[n].abort(),delete r[n]),e()},M.prototype.removeTile=function(t,e){var r=this.loaded,n=t.uid;r&&r[n]&&delete r[n],e()};var A=function(){this.loading={},this.loaded={}};A.prototype.loadTile=function(e,r){var n=e.uid,i=e.encoding,a=new t.default$31(n);this.loading[n]=a,a.loadFromImage(e.rawImageData,i),delete this.loading[n],this.loaded=this.loaded||{},this.loaded[n]=a,r(null,a)},A.prototype.removeTile=function(t){var e=this.loaded,r=t.uid;e&&e[r]&&delete e[r]};var T={RADIUS:6378137,FLATTENING:1/298.257223563,POLAR_RADIUS:6356752.3142};function S(t){var e=0;if(t&&t.length>0){e+=Math.abs(E(t[0]));for(var r=1;r2){for(o=0;o=0}(t)===e?t:t.reverse()}var O=t.default$29.VectorTileFeature.prototype.toGeoJSON,D=function(e){this._feature=e,this.extent=t.default$8,this.type=e.type,this.properties=e.tags,"id"in e&&!isNaN(e.id)&&(this.id=parseInt(e.id,10))};D.prototype.loadGeometry=function(){if(1===this._feature.type){for(var e=[],r=0,n=this._feature.geometry;r>31}function $(t,e){for(var r=t.loadGeometry(),n=t.type,i=0,a=0,o=r.length,s=0;si;){if(a-i>600){var s=a-i+1,l=n-i+1,c=Math.log(s),u=.5*Math.exp(2*c/3),h=.5*Math.sqrt(c*u*(s-u)/s)*(l-s/2<0?-1:1);t(e,r,n,Math.max(i,Math.floor(n-l*u/s+h)),Math.min(a,Math.floor(n+(s-l)*u/s+h)),o)}var f=r[2*n+o],p=i,d=a;for(Q(e,r,i,n),r[2*a+o]>f&&Q(e,r,i,a);pf;)d--}r[2*i+o]===f?Q(e,r,i,d):Q(e,r,++d,a),d<=n&&(i=d+1),n<=d&&(a=d-1)}}(e,r,s,i,a,o%2),t(e,r,n,i,s-1,o+1),t(e,r,n,s+1,a,o+1)}};function Q(t,e,r,n){tt(t,r,n),tt(e,2*r,2*n),tt(e,2*r+1,2*n+1)}function tt(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function et(t,e,r,n){var i=t-r,a=e-n;return i*i+a*a}var rt=function(t,e,r,n,i){return new nt(t,e,r,n,i)};function nt(t,e,r,n,i){e=e||it,r=r||at,i=i||Array,this.nodeSize=n||64,this.points=t,this.ids=new i(t.length),this.coords=new i(2*t.length);for(var a=0;a=r&&s<=i&&l>=n&&l<=a&&u.push(t[d]);else{var g=Math.floor((p+f)/2);s=e[2*g],l=e[2*g+1],s>=r&&s<=i&&l>=n&&l<=a&&u.push(t[g]);var m=(h+1)%2;(0===h?r<=s:n<=l)&&(c.push(p),c.push(g-1),c.push(m)),(0===h?i>=s:a>=l)&&(c.push(g+1),c.push(f),c.push(m))}}return u}(this.ids,this.coords,t,e,r,n,this.nodeSize)},within:function(t,e,r){return function(t,e,r,n,i,a){for(var o=[0,t.length-1,0],s=[],l=i*i;o.length;){var c=o.pop(),u=o.pop(),h=o.pop();if(u-h<=a)for(var f=h;f<=u;f++)et(e[2*f],e[2*f+1],r,n)<=l&&s.push(t[f]);else{var p=Math.floor((h+u)/2),d=e[2*p],g=e[2*p+1];et(d,g,r,n)<=l&&s.push(t[p]);var m=(c+1)%2;(0===c?r-i<=d:n-i<=g)&&(o.push(h),o.push(p-1),o.push(m)),(0===c?r+i>=d:n+i>=g)&&(o.push(p+1),o.push(u),o.push(m))}}return s}(this.ids,this.coords,t,e,r,this.nodeSize)}};function ot(t){this.options=pt(Object.create(this.options),t),this.trees=new Array(this.options.maxZoom+1)}function st(t,e,r,n,i){return{x:t,y:e,zoom:1/0,id:n,properties:i,parentId:-1,numPoints:r}}function lt(t,e){var r=t.geometry.coordinates;return{x:ht(r[0]),y:ft(r[1]),zoom:1/0,id:e,parentId:-1}}function ct(t){return{type:"Feature",properties:ut(t),geometry:{type:"Point",coordinates:[(n=t.x,360*(n-.5)),(e=t.y,r=(180-360*e)*Math.PI/180,360*Math.atan(Math.exp(r))/Math.PI-90)]}};var e,r,n}function ut(t){var e=t.numPoints,r=e>=1e4?Math.round(e/1e3)+"k":e>=1e3?Math.round(e/100)/10+"k":e;return pt(pt({},t.properties),{cluster:!0,cluster_id:t.id,point_count:e,point_count_abbreviated:r})}function ht(t){return t/360+.5}function ft(t){var e=Math.sin(t*Math.PI/180),r=.5-.25*Math.log((1+e)/(1-e))/Math.PI;return r<0?0:r>1?1:r}function pt(t,e){for(var r in e)t[r]=e[r];return t}function dt(t){return t.x}function gt(t){return t.y}function mt(t,e,r,n,i,a){var o=i-r,s=a-n;if(0!==o||0!==s){var l=((t-r)*o+(e-n)*s)/(o*o+s*s);l>1?(r=i,n=a):l>0&&(r+=o*l,n+=s*l)}return(o=t-r)*o+(s=e-n)*s}function vt(t,e,r,n){var i={id:t||null,type:e,geometry:r,tags:n,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};return function(t){var e=t.geometry,r=t.type;if("Point"===r||"MultiPoint"===r||"LineString"===r)yt(t,e);else if("Polygon"===r||"MultiLineString"===r)for(var n=0;n0&&(o+=n?(i*c-l*a)/2:Math.sqrt(Math.pow(l-i,2)+Math.pow(c-a,2))),i=l,a=c}var u=e.length-3;e[2]=1,function t(e,r,n,i){for(var a,o=i,s=e[r],l=e[r+1],c=e[n],u=e[n+1],h=r+3;ho&&(a=h,o=f)}o>i&&(a-r>3&&t(e,r,a,i),e[a+2]=o,n-a>3&&t(e,a,n,i))}(e,0,u,r),e[u+2]=1,e.size=Math.abs(o),e.start=0,e.end=e.size}function wt(t,e,r,n){for(var i=0;i1?1:r}function At(t,e,r,n,i,a,o,s){if(n/=e,a>=(r/=e)&&o<=n)return t;if(a>n||o=r&&d<=n)l.push(u);else if(!(p>n||d=r&&o<=n&&(e.push(t[a]),e.push(t[a+1]),e.push(t[a+2]))}}function St(t,e,r,n,i,a,o){for(var s,l,c=Et(t),u=0===i?zt:Pt,h=t.start,f=0;f=r&&(l=u(c,p,d,m,v,r),o&&(c.start=h+s*l)):y>n?x<=n&&(l=u(c,p,d,m,v,n),o&&(c.start=h+s*l)):Lt(c,p,d,g),x=r&&(l=u(c,p,d,m,v,r),b=!0),x>n&&y<=n&&(l=u(c,p,d,m,v,n),b=!0),!a&&b&&(o&&(c.end=h+s*l),e.push(c),c=Et(t)),o&&(h+=s)}var _=t.length-3;p=t[_],d=t[_+1],g=t[_+2],(y=0===i?p:d)>=r&&y<=n&&Lt(c,p,d,g),_=c.length-3,a&&_>=3&&(c[_]!==c[0]||c[_+1]!==c[1])&&Lt(c,c[0],c[1],c[2]),c.length&&e.push(c)}function Et(t){var e=[];return e.size=t.size,e.start=t.start,e.end=t.end,e}function Ct(t,e,r,n,i,a){for(var o=0;oo.maxX&&(o.maxX=u),h>o.maxY&&(o.maxY=h)}return o}function Ft(t,e,r,n){var i=e.geometry,a=e.type,o=[];if("Point"===a||"MultiPoint"===a)for(var s=0;s0&&e.size<(i?o:n))r.numPoints+=e.length/3;else{for(var s=[],l=0;lo)&&(r.numSimplified++,s.push(e[l]),s.push(e[l+1])),r.numPoints++;i&&function(t,e){for(var r=0,n=0,i=t.length,a=i-2;n0===e)for(n=0,i=t.length;n24)throw new Error("maxZoom should be in the 0-24 range");var n=function(t,e){var r=[];if("FeatureCollection"===t.type)for(var n=0;n=this.options.minZoom;i--){var a=+Date.now();this.trees[i+1]=rt(n,dt,gt,this.options.nodeSize,Float32Array),n=this._cluster(n,i),e&&console.log("z%d: %d clusters in %dms",i,n.length,+Date.now()-a)}return this.trees[this.options.minZoom]=rt(n,dt,gt,this.options.nodeSize,Float32Array),e&&console.timeEnd("total time"),this},getClusters:function(t,e){for(var r=this.trees[this._limitZoom(e)],n=r.range(ht(t[0]),ft(t[3]),ht(t[2]),ft(t[1])),i=[],a=0;a1&&console.time("creation"),f=this.tiles[h]=Bt(t,e,r,n,l),this.tileCoords.push({z:e,x:r,y:n}),c)){c>1&&(console.log("tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",e,r,n,f.numFeatures,f.numPoints,f.numSimplified),console.timeEnd("creation"));var p="z"+e;this.stats[p]=(this.stats[p]||0)+1,this.total++}if(f.source=t,i){if(e===l.maxZoom||e===i)continue;var d=1<1&&console.time("clipping");var g,m,v,y,x,b,_=.5*l.buffer/l.extent,w=.5-_,k=.5+_,M=1+_;g=m=v=y=null,x=At(t,u,r-_,r+k,0,f.minX,f.maxX,l),b=At(t,u,r+w,r+M,0,f.minX,f.maxX,l),t=null,x&&(g=At(x,u,n-_,n+k,1,f.minY,f.maxY,l),m=At(x,u,n+w,n+M,1,f.minY,f.maxY,l),x=null),b&&(v=At(b,u,n-_,n+k,1,f.minY,f.maxY,l),y=At(b,u,n+w,n+M,1,f.minY,f.maxY,l),b=null),c>1&&console.timeEnd("clipping"),s.push(g||[],e+1,2*r,2*n),s.push(m||[],e+1,2*r,2*n+1),s.push(v||[],e+1,2*r+1,2*n),s.push(y||[],e+1,2*r+1,2*n+1)}}},jt.prototype.getTile=function(t,e,r){var n=this.options,i=n.extent,a=n.debug;if(t<0||t>24)return null;var o=1<1&&console.log("drilling down to z%d-%d-%d",t,e,r);for(var l,c=t,u=e,h=r;!l&&c>0;)c--,u=Math.floor(u/2),h=Math.floor(h/2),l=this.tiles[Vt(c,u,h)];return l&&l.source?(a>1&&console.log("found parent tile z%d-%d-%d",c,u,h),a>1&&console.time("drilling down"),this.splitTile(l.source,c,u,h,t,e,r),a>1&&console.timeEnd("drilling down"),this.tiles[s]?Dt(this.tiles[s],i):null):null};var qt=function(e){function r(t,r,n){e.call(this,t,r,Ut),n&&(this.loadGeoJSON=n)}return e&&(r.__proto__=e),r.prototype=Object.create(e&&e.prototype),r.prototype.constructor=r,r.prototype.loadData=function(t,e){this._pendingCallback&&this._pendingCallback(null,{abandoned:!0}),this._pendingCallback=e,this._pendingLoadDataParams=t,this._state&&"Idle"!==this._state?this._state="NeedsLoadData":(this._state="Coalescing",this._loadData())},r.prototype._loadData=function(){var t=this;if(this._pendingCallback&&this._pendingLoadDataParams){var e=this._pendingCallback,r=this._pendingLoadDataParams;delete this._pendingCallback,delete this._pendingLoadDataParams,this.loadGeoJSON(r,function(n,i){if(n||!i)return e(n);if("object"!=typeof i)return e(new Error("Input data is not a valid GeoJSON object."));!function t(e,r){switch(e&&e.type||null){case"FeatureCollection":return e.features=e.features.map(z(t,r)),e;case"Feature":return e.geometry=t(e.geometry,r),e;case"Polygon":case"MultiPolygon":return function(t,e){return"Polygon"===t.type?t.coordinates=P(t.coordinates,e):"MultiPolygon"===t.type&&(t.coordinates=t.coordinates.map(z(P,e))),t}(e,r);default:return e}}(i,!0);try{t._geoJSONIndex=r.cluster?function(t){return new ot(t)}(r.superclusterOptions).load(i.features):new jt(i,r.geojsonVtOptions)}catch(n){return e(n)}t.loaded={};var a={};if(r.request&&r.request.collectResourceTiming){var o=w(r.request.url);o&&(a.resourceTiming={},a.resourceTiming[r.source]=JSON.parse(JSON.stringify(o)))}e(null,a)})}},r.prototype.coalesce=function(){"Coalescing"===this._state?this._state="Idle":"NeedsLoadData"===this._state&&(this._state="Coalescing",this._loadData())},r.prototype.reloadTile=function(t,r){var n=this.loaded,i=t.uid;return n&&n[i]?e.prototype.reloadTile.call(this,t,r):this.loadTile(t,r)},r.prototype.loadGeoJSON=function(e,r){if(e.request)t.getJSON(e.request,r);else{if("string"!=typeof e.data)return r(new Error("Input data is not a valid GeoJSON object."));try{return r(null,JSON.parse(e.data))}catch(t){return r(new Error("Input data is not a valid GeoJSON object."))}}},r.prototype.removeSource=function(t,e){this._pendingCallback&&this._pendingCallback(null,{abandoned:!0}),e()},r}(M),Ht=function(e){var r=this;this.self=e,this.actor=new t.default$7(e,this),this.layerIndexes={},this.workerSourceTypes={vector:M,geojson:qt},this.workerSources={},this.demWorkerSources={},this.self.registerWorkerSource=function(t,e){if(r.workerSourceTypes[t])throw new Error('Worker source with name "'+t+'" already registered.');r.workerSourceTypes[t]=e},this.self.registerRTLTextPlugin=function(e){if(t.plugin.isLoaded())throw new Error("RTL text plugin already registered.");t.plugin.applyArabicShaping=e.applyArabicShaping,t.plugin.processBidirectionalText=e.processBidirectionalText}};return Ht.prototype.setLayers=function(t,e,r){this.getLayerIndex(t).replace(e),r()},Ht.prototype.updateLayers=function(t,e,r){this.getLayerIndex(t).update(e.layers,e.removedIds),r()},Ht.prototype.loadTile=function(t,e,r){this.getWorkerSource(t,e.type,e.source).loadTile(e,r)},Ht.prototype.loadDEMTile=function(t,e,r){this.getDEMWorkerSource(t,e.source).loadTile(e,r)},Ht.prototype.reloadTile=function(t,e,r){this.getWorkerSource(t,e.type,e.source).reloadTile(e,r)},Ht.prototype.abortTile=function(t,e,r){this.getWorkerSource(t,e.type,e.source).abortTile(e,r)},Ht.prototype.removeTile=function(t,e,r){this.getWorkerSource(t,e.type,e.source).removeTile(e,r)},Ht.prototype.removeDEMTile=function(t,e){this.getDEMWorkerSource(t,e.source).removeTile(e)},Ht.prototype.removeSource=function(t,e,r){if(this.workerSources[t]&&this.workerSources[t][e.type]&&this.workerSources[t][e.type][e.source]){var n=this.workerSources[t][e.type][e.source];delete this.workerSources[t][e.type][e.source],void 0!==n.removeSource?n.removeSource(e,r):r()}},Ht.prototype.loadWorkerSource=function(t,e,r){try{this.self.importScripts(e.url),r()}catch(t){r(t.toString())}},Ht.prototype.loadRTLTextPlugin=function(e,r,n){try{t.plugin.isLoaded()||(this.self.importScripts(r),n(t.plugin.isLoaded()?null:new Error("RTL Text Plugin failed to import scripts from "+r)))}catch(t){n(t.toString())}},Ht.prototype.getLayerIndex=function(t){var e=this.layerIndexes[t];return e||(e=this.layerIndexes[t]=new n),e},Ht.prototype.getWorkerSource=function(t,e,r){var n=this;if(this.workerSources[t]||(this.workerSources[t]={}),this.workerSources[t][e]||(this.workerSources[t][e]={}),!this.workerSources[t][e][r]){var i={send:function(e,r,i){n.actor.send(e,r,i,t)}};this.workerSources[t][e][r]=new this.workerSourceTypes[e](i,this.getLayerIndex(t))}return this.workerSources[t][e][r]},Ht.prototype.getDEMWorkerSource=function(t,e){return this.demWorkerSources[t]||(this.demWorkerSources[t]={}),this.demWorkerSources[t][e]||(this.demWorkerSources[t][e]=new A),this.demWorkerSources[t][e]},"undefined"!=typeof WorkerGlobalScope&&"undefined"!=typeof self&&self instanceof WorkerGlobalScope&&new Ht(self),Ht}),i(0,function(t){var e=t.createCommonjsModule(function(t){function e(t){return!!("undefined"!=typeof window&&"undefined"!=typeof document&&Array.prototype&&Array.prototype.every&&Array.prototype.filter&&Array.prototype.forEach&&Array.prototype.indexOf&&Array.prototype.lastIndexOf&&Array.prototype.map&&Array.prototype.some&&Array.prototype.reduce&&Array.prototype.reduceRight&&Array.isArray&&Function.prototype&&Function.prototype.bind&&Object.keys&&Object.create&&Object.getPrototypeOf&&Object.getOwnPropertyNames&&Object.isSealed&&Object.isFrozen&&Object.isExtensible&&Object.getOwnPropertyDescriptor&&Object.defineProperty&&Object.defineProperties&&Object.seal&&Object.freeze&&Object.preventExtensions&&"JSON"in window&&"parse"in JSON&&"stringify"in JSON&&function(){if(!("Worker"in window&&"Blob"in window&&"URL"in window))return!1;var t,e,r=new Blob([""],{type:"text/javascript"}),n=URL.createObjectURL(r);try{e=new Worker(n),t=!0}catch(e){t=!1}return e&&e.terminate(),URL.revokeObjectURL(n),t}()&&"Uint8ClampedArray"in window&&function(t){return void 0===r[t]&&(r[t]=function(t){var r=document.createElement("canvas"),n=Object.create(e.webGLContextAttributes);return n.failIfMajorPerformanceCaveat=t,r.probablySupportsContext?r.probablySupportsContext("webgl",n)||r.probablySupportsContext("experimental-webgl",n):r.supportsContext?r.supportsContext("webgl",n)||r.supportsContext("experimental-webgl",n):r.getContext("webgl",n)||r.getContext("experimental-webgl",n)}(t)),r[t]}(t&&t.failIfMajorPerformanceCaveat))}t.exports?t.exports=e:window&&(window.mapboxgl=window.mapboxgl||{},window.mapboxgl.supported=e);var r={};e.webGLContextAttributes={antialias:!1,alpha:!0,stencil:!0,depth:!0}}),r=t.default.performance&&t.default.performance.now?t.default.performance.now.bind(t.default.performance):Date.now.bind(Date),n=t.default.requestAnimationFrame||t.default.mozRequestAnimationFrame||t.default.webkitRequestAnimationFrame||t.default.msRequestAnimationFrame,i=t.default.cancelAnimationFrame||t.default.mozCancelAnimationFrame||t.default.webkitCancelAnimationFrame||t.default.msCancelAnimationFrame,a={now:r,frame:function(t){return n(t)},cancelFrame:function(t){return i(t)},getImageData:function(e){var r=t.default.document.createElement("canvas"),n=r.getContext("2d");if(!n)throw new Error("failed to create canvas 2d context");return r.width=e.width,r.height=e.height,n.drawImage(e,0,0,e.width,e.height),n.getImageData(0,0,e.width,e.height)},hardwareConcurrency:t.default.navigator.hardwareConcurrency||4,get devicePixelRatio(){return t.default.devicePixelRatio},supportsWebp:!1};if(t.default.document){var o=t.default.document.createElement("img");o.onload=function(){a.supportsWebp=!0},o.src="data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA="}var s={create:function(e,r,n){var i=t.default.document.createElement(e);return r&&(i.className=r),n&&n.appendChild(i),i},createNS:function(e,r){return t.default.document.createElementNS(e,r)}},l=t.default.document?t.default.document.documentElement.style:null;function c(t){if(!l)return null;for(var e=0;e=0?0:e.button},s.remove=function(t){t.parentNode&&t.parentNode.removeChild(t)};var m={API_URL:"https://api.mapbox.com",REQUIRE_ACCESS_TOKEN:!0,ACCESS_TOKEN:null},v="See https://www.mapbox.com/api-documentation/#access-tokens";function y(t,e){var r=A(m.API_URL);if(t.protocol=r.protocol,t.authority=r.authority,"/"!==r.path&&(t.path=""+r.path+t.path),!m.REQUIRE_ACCESS_TOKEN)return T(t);if(!(e=e||m.ACCESS_TOKEN))throw new Error("An API access token is required to use Mapbox GL. "+v);if("s"===e[0])throw new Error("Use a public access token (pk.*) with Mapbox GL, not a secret access token (sk.*). "+v);return t.params.push("access_token="+e),T(t)}function x(t){return 0===t.indexOf("mapbox:")}var b=function(t,e){if(!x(t))return t;var r=A(t);return r.path="/v4/"+r.authority+".json",r.params.push("secure"),y(r,e)},_=function(t,e,r,n){var i=A(t);return x(t)?(i.path="/styles/v1"+i.path+"/sprite"+e+r,y(i,n)):(i.path+=""+e+r,T(i))},w=/(\.(png|jpg)\d*)(?=$)/,k=function(t,e,r){if(!e||!x(e))return t;var n=A(t),i=a.devicePixelRatio>=2||512===r?"@2x":"",o=a.supportsWebp?".webp":"$1";return n.path=n.path.replace(w,""+i+o),function(t){for(var e=0;e=0?1.2:1))}function R(t,e,r,n,i,a,o){for(var s=0;s65535)e(new Error("glyphs > 65535 not supported"));else{var l=a.requests[s];l||(l=a.requests[s]=[],F.loadGlyphRange(r,s,n.url,n.requestTransform,function(t,e){if(e)for(var r in e)a.glyphs[+r]=e[+r];for(var n=0,i=l;nthis.height)return t.warnOnce("LineAtlas out of space"),null;for(var a=0,o=0;o90||this.lat<-90)throw new Error("Invalid LngLat latitude value: must be between -90 and 90")};G.prototype.wrap=function(){return new G(t.wrap(this.lng,-180,180),this.lat)},G.prototype.toArray=function(){return[this.lng,this.lat]},G.prototype.toString=function(){return"LngLat("+this.lng+", "+this.lat+")"},G.prototype.toBounds=function(t){var e=360*t/40075017,r=e/Math.cos(Math.PI/180*this.lat);return new W(new G(this.lng-r,this.lat-e),new G(this.lng+r,this.lat+e))},G.convert=function(t){if(t instanceof G)return t;if(Array.isArray(t)&&(2===t.length||3===t.length))return new G(Number(t[0]),Number(t[1]));if(!Array.isArray(t)&&"object"==typeof t&&null!==t)return new G(Number(t.lng),Number(t.lat));throw new Error("`LngLatLike` argument must be specified as a LngLat instance, an object {lng: , lat: }, or an array of [, ]")};var W=function(t,e){t&&(e?this.setSouthWest(t).setNorthEast(e):4===t.length?this.setSouthWest([t[0],t[1]]).setNorthEast([t[2],t[3]]):this.setSouthWest(t[0]).setNorthEast(t[1]))};W.prototype.setNorthEast=function(t){return this._ne=t instanceof G?new G(t.lng,t.lat):G.convert(t),this},W.prototype.setSouthWest=function(t){return this._sw=t instanceof G?new G(t.lng,t.lat):G.convert(t),this},W.prototype.extend=function(t){var e,r,n=this._sw,i=this._ne;if(t instanceof G)e=t,r=t;else{if(!(t instanceof W))return Array.isArray(t)?t.every(Array.isArray)?this.extend(W.convert(t)):this.extend(G.convert(t)):this;if(e=t._sw,r=t._ne,!e||!r)return this}return n||i?(n.lng=Math.min(e.lng,n.lng),n.lat=Math.min(e.lat,n.lat),i.lng=Math.max(r.lng,i.lng),i.lat=Math.max(r.lat,i.lat)):(this._sw=new G(e.lng,e.lat),this._ne=new G(r.lng,r.lat)),this},W.prototype.getCenter=function(){return new G((this._sw.lng+this._ne.lng)/2,(this._sw.lat+this._ne.lat)/2)},W.prototype.getSouthWest=function(){return this._sw},W.prototype.getNorthEast=function(){return this._ne},W.prototype.getNorthWest=function(){return new G(this.getWest(),this.getNorth())},W.prototype.getSouthEast=function(){return new G(this.getEast(),this.getSouth())},W.prototype.getWest=function(){return this._sw.lng},W.prototype.getSouth=function(){return this._sw.lat},W.prototype.getEast=function(){return this._ne.lng},W.prototype.getNorth=function(){return this._ne.lat},W.prototype.toArray=function(){return[this._sw.toArray(),this._ne.toArray()]},W.prototype.toString=function(){return"LngLatBounds("+this._sw.toString()+", "+this._ne.toString()+")"},W.prototype.isEmpty=function(){return!(this._sw&&this._ne)},W.convert=function(t){return!t||t instanceof W?t:new W(t)};var Y=function(t,e,r){this.bounds=W.convert(this.validateBounds(t)),this.minzoom=e||0,this.maxzoom=r||24};Y.prototype.validateBounds=function(t){return Array.isArray(t)&&4===t.length?[Math.max(-180,t[0]),Math.max(-90,t[1]),Math.min(180,t[2]),Math.min(90,t[3])]:[-180,-90,180,90]},Y.prototype.contains=function(t){var e=Math.floor(this.lngX(this.bounds.getWest(),t.z)),r=Math.floor(this.latY(this.bounds.getNorth(),t.z)),n=Math.ceil(this.lngX(this.bounds.getEast(),t.z)),i=Math.ceil(this.latY(this.bounds.getSouth(),t.z));return t.x>=e&&t.x=r&&t.y0&&(l[new t.OverscaledTileID(e.overscaledZ,a,r.z,i,r.y-1).key]={backfilled:!1},l[new t.OverscaledTileID(e.overscaledZ,e.wrap,r.z,r.x,r.y-1).key]={backfilled:!1},l[new t.OverscaledTileID(e.overscaledZ,s,r.z,o,r.y-1).key]={backfilled:!1}),r.y+10&&(n.resourceTiming=e._resourceTiming,e._resourceTiming=[]),e.fire(new t.Event("data",n))}})},r.prototype.onAdd=function(t){this.map=t,this.load()},r.prototype.setData=function(e){var r=this;return this._data=e,this.fire(new t.Event("dataloading",{dataType:"source"})),this._updateWorkerData(function(e){if(e)return r.fire(new t.ErrorEvent(e));var n={dataType:"source",sourceDataType:"content"};r._collectResourceTiming&&r._resourceTiming&&r._resourceTiming.length>0&&(n.resourceTiming=r._resourceTiming,r._resourceTiming=[]),r.fire(new t.Event("data",n))}),this},r.prototype._updateWorkerData=function(e){var r,n,i=this,a=t.extend({},this.workerOptions),o=this._data;"string"==typeof o?(a.request=this.map._transformRequest((r=o,(n=t.default.document.createElement("a")).href=r,n.href),t.ResourceType.Source),a.request.collectResourceTiming=this._collectResourceTiming):a.data=JSON.stringify(o),this.workerID=this.dispatcher.send(this.type+"."+a.source+".loadData",a,function(t,r){i._removed||r&&r.abandoned||(i._loaded=!0,r&&r.resourceTiming&&r.resourceTiming[i.id]&&(i._resourceTiming=r.resourceTiming[i.id].slice(0)),i.dispatcher.send(i.type+"."+a.source+".coalesce",null,null,i.workerID),e(t))},this.workerID)},r.prototype.loadTile=function(t,e){var r=this,n=void 0===t.workerID?"loadTile":"reloadTile",i={type:this.type,uid:t.uid,tileID:t.tileID,zoom:t.tileID.overscaledZ,maxZoom:this.maxzoom,tileSize:this.tileSize,source:this.id,pixelRatio:a.devicePixelRatio,showCollisionBoxes:this.map.showCollisionBoxes};t.workerID=this.dispatcher.send(n,i,function(i,a){return t.unloadVectorData(),t.aborted?e(null):i?e(i):(t.loadVectorData(a,r.map.painter,"reloadTile"===n),e(null))},this.workerID)},r.prototype.abortTile=function(t){t.aborted=!0},r.prototype.unloadTile=function(t){t.unloadVectorData(),this.dispatcher.send("removeTile",{uid:t.uid,type:this.type,source:this.id},null,t.workerID)},r.prototype.onRemove=function(){this._removed=!0,this.dispatcher.send("removeSource",{type:this.type,source:this.id},null,this.workerID)},r.prototype.serialize=function(){return t.extend({},this._options,{type:this.type,data:this._data})},r.prototype.hasTransition=function(){return!1},r}(t.Evented),K=t.createLayout([{name:"a_pos",type:"Int16",components:2},{name:"a_texture_pos",type:"Int16",components:2}]),Q=function(){this.boundProgram=null,this.boundLayoutVertexBuffer=null,this.boundPaintVertexBuffers=[],this.boundIndexBuffer=null,this.boundVertexOffset=null,this.boundDynamicVertexBuffer=null,this.vao=null};Q.prototype.bind=function(t,e,r,n,i,a,o,s){this.context=t;for(var l=this.boundPaintVertexBuffers.length!==n.length,c=0;!l&&c>s.z,c=new t.default$1(s.x*l,s.y*l),u=new t.default$1(c.x+l,c.y+l),h=this.segments.prepareSegment(4,n,i);n.emplaceBack(c.x,c.y,c.x,c.y),n.emplaceBack(u.x,c.y,u.x,c.y),n.emplaceBack(c.x,u.y,c.x,u.y),n.emplaceBack(u.x,u.y,u.x,u.y);var f=h.vertexLength;i.emplaceBack(f,f+1,f+2),i.emplaceBack(f+1,f+2,f+3),h.vertexLength+=4,h.primitiveLength+=2}this.maskedBoundsBuffer=r.createVertexBuffer(n,K.members),this.maskedIndexBuffer=r.createIndexBuffer(i)}},st.prototype.hasData=function(){return"loaded"===this.state||"reloading"===this.state||"expired"===this.state},st.prototype.setExpiryData=function(e){var r=this.expirationTime;if(e.cacheControl){var n=t.parseCacheControl(e.cacheControl);n["max-age"]&&(this.expirationTime=Date.now()+1e3*n["max-age"])}else e.expires&&(this.expirationTime=new Date(e.expires).getTime());if(this.expirationTime){var i=Date.now(),a=!1;if(this.expirationTime>i)a=!1;else if(r)if(this.expirationTimethis.max){var o=this._getAndRemoveByKey(this.order[0]);o&&this.onRemove(o)}return this},lt.prototype.has=function(t){return t.wrapped().key in this.data},lt.prototype.getAndRemove=function(t){return this.has(t)?this._getAndRemoveByKey(t.wrapped().key):null},lt.prototype._getAndRemoveByKey=function(t){var e=this.data[t].shift();return e.timeout&&clearTimeout(e.timeout),0===this.data[t].length&&delete this.data[t],this.order.splice(this.order.indexOf(t),1),e.value},lt.prototype.get=function(t){return this.has(t)?this.data[t.wrapped().key][0].value:null},lt.prototype.remove=function(t,e){if(!this.has(t))return this;var r=t.wrapped().key,n=void 0===e?0:this.data[r].indexOf(e),i=this.data[r][n];return this.data[r].splice(n,1),i.timeout&&clearTimeout(i.timeout),0===this.data[r].length&&delete this.data[r],this.onRemove(i.value),this.order.splice(this.order.indexOf(r),1),this},lt.prototype.setMaxSize=function(t){for(this.max=t;this.order.length>this.max;){var e=this._getAndRemoveByKey(this.order[0]);e&&this.onRemove(e)}return this};var ct=function(t,e,r){this.context=t;var n=t.gl;this.buffer=n.createBuffer(),this.dynamicDraw=Boolean(r),this.unbindVAO(),t.bindElementBuffer.set(this.buffer),n.bufferData(n.ELEMENT_ARRAY_BUFFER,e.arrayBuffer,this.dynamicDraw?n.DYNAMIC_DRAW:n.STATIC_DRAW),this.dynamicDraw||delete e.arrayBuffer};ct.prototype.unbindVAO=function(){this.context.extVertexArrayObject&&this.context.bindVertexArrayOES.set(null)},ct.prototype.bind=function(){this.context.bindElementBuffer.set(this.buffer)},ct.prototype.updateData=function(t){var e=this.context.gl;this.unbindVAO(),this.bind(),e.bufferSubData(e.ELEMENT_ARRAY_BUFFER,0,t.arrayBuffer)},ct.prototype.destroy=function(){var t=this.context.gl;this.buffer&&(t.deleteBuffer(this.buffer),delete this.buffer)};var ut={Int8:"BYTE",Uint8:"UNSIGNED_BYTE",Int16:"SHORT",Uint16:"UNSIGNED_SHORT",Int32:"INT",Uint32:"UNSIGNED_INT",Float32:"FLOAT"},ht=function(t,e,r,n){this.length=e.length,this.attributes=r,this.itemSize=e.bytesPerElement,this.dynamicDraw=n,this.context=t;var i=t.gl;this.buffer=i.createBuffer(),t.bindVertexBuffer.set(this.buffer),i.bufferData(i.ARRAY_BUFFER,e.arrayBuffer,this.dynamicDraw?i.DYNAMIC_DRAW:i.STATIC_DRAW),this.dynamicDraw||delete e.arrayBuffer};ht.prototype.bind=function(){this.context.bindVertexBuffer.set(this.buffer)},ht.prototype.updateData=function(t){var e=this.context.gl;this.bind(),e.bufferSubData(e.ARRAY_BUFFER,0,t.arrayBuffer)},ht.prototype.enableAttributes=function(t,e){for(var r=0;r1||(Math.abs(r)>1&&(1===Math.abs(r+i)?r+=i:1===Math.abs(r-i)&&(r-=i)),e.dem&&t.dem&&(t.dem.backfillBorder(e.dem,r,n),t.neighboringTiles&&t.neighboringTiles[a]&&(t.neighboringTiles[a].backfilled=!0)))}},r.prototype.getTile=function(t){return this.getTileByID(t.key)},r.prototype.getTileByID=function(t){return this._tiles[t]},r.prototype.getZoom=function(t){return t.zoom+t.scaleZoom(t.tileSize/this._source.tileSize)},r.prototype._findLoadedChildren=function(t,e,r){var n=!1;for(var i in this._tiles){var a=this._tiles[i];if(!(r[i]||!a.hasData()||a.tileID.overscaledZ<=t.overscaledZ||a.tileID.overscaledZ>e)){var o=Math.pow(2,a.tileID.canonical.z-t.canonical.z);if(Math.floor(a.tileID.canonical.x/o)===t.canonical.x&&Math.floor(a.tileID.canonical.y/o)===t.canonical.y)for(r[i]=a.tileID,n=!0;a&&a.tileID.overscaledZ-1>t.overscaledZ;){var s=a.tileID.scaledTo(a.tileID.overscaledZ-1);if(!s)break;(a=this._tiles[s.key])&&a.hasData()&&(delete r[i],r[s.key]=s)}}}return n},r.prototype.findLoadedParent=function(t,e,r){for(var n=t.overscaledZ-1;n>=e;n--){var i=t.scaledTo(n);if(!i)return;var a=String(i.key),o=this._tiles[a];if(o&&o.hasData())return r[a]=i,o;if(this._cache.has(i))return r[a]=i,this._cache.get(i)}},r.prototype.updateCacheSize=function(t){var e=(Math.ceil(t.width/this._source.tileSize)+1)*(Math.ceil(t.height/this._source.tileSize)+1),r=Math.floor(5*e),n="number"==typeof this._maxTileCacheSize?Math.min(this._maxTileCacheSize,r):r;this._cache.setMaxSize(n)},r.prototype.handleWrapJump=function(t){var e=(t-(void 0===this._prevLng?t:this._prevLng))/360,r=Math.round(e);if(this._prevLng=t,r){var n={};for(var i in this._tiles){var a=this._tiles[i];a.tileID=a.tileID.unwrapTo(a.tileID.wrap+r),n[a.tileID.key]=a}for(var o in this._tiles=n,this._timers)clearTimeout(this._timers[o]),delete this._timers[o];for(var s in this._tiles){var l=this._tiles[s];this._setTileReloadTimer(s,l)}}},r.prototype.update=function(e){var n=this;if(this.transform=e,this._sourceLoaded&&!this._paused){var i;this.updateCacheSize(e),this.handleWrapJump(this.transform.center.lng),this._coveredTiles={},this.used?this._source.tileID?i=e.getVisibleUnwrappedCoordinates(this._source.tileID).map(function(e){return new t.OverscaledTileID(e.canonical.z,e.wrap,e.canonical.z,e.canonical.x,e.canonical.y)}):(i=e.coveringTiles({tileSize:this._source.tileSize,minzoom:this._source.minzoom,maxzoom:this._source.maxzoom,roundZoom:this._source.roundZoom,reparseOverscaled:this._source.reparseOverscaled}),this._source.hasTile&&(i=i.filter(function(t){return n._source.hasTile(t)}))):i=[];var o,s=(this._source.roundZoom?Math.round:Math.floor)(this.getZoom(e)),l=Math.max(s-r.maxOverzooming,this._source.minzoom),c=Math.max(s+r.maxUnderzooming,this._source.minzoom),u=this._updateRetainedTiles(i,s),h={};if(Zt(this._source.type))for(var f=Object.keys(u),p=0;p=a.now())){n._findLoadedChildren(g,c,u)&&(u[d]=g);var v=n.findLoadedParent(g,l,h);v&&n._addTile(v.tileID)}}for(o in h)u[o]||(n._coveredTiles[o]=!0);for(o in h)u[o]=h[o];for(var y=t.keysDifference(this._tiles,u),x=0;xthis._source.maxzoom){var f=l.children(this._source.maxzoom)[0],p=this.getTile(f);p&&p.hasData()?n[f.key]=f:h=!1}else{this._findLoadedChildren(l,o,n);for(var d=l.children(this._source.maxzoom),g=0;g=a;--m){var v=l.scaledTo(m);if(i[v.key])break;if(i[v.key]=!0,!(c=this.getTile(v))&&u&&(c=this._addTile(v)),c&&(n[v.key]=v,u=c.wasRequested(),c.hasData()))break}}}return n},r.prototype._addTile=function(e){var r=this._tiles[e.key];if(r)return r;(r=this._cache.getAndRemove(e))&&(this._setTileReloadTimer(e.key,r),r.tileID=e);var n=Boolean(r);return n||(r=new st(e,this._source.tileSize*e.overscaleFactor()),this._loadTile(r,this._tileLoaded.bind(this,r,e.key,r.state))),r?(r.uses++,this._tiles[e.key]=r,n||this._source.fire(new t.Event("dataloading",{tile:r,coord:r.tileID,dataType:"source"})),r):null},r.prototype._setTileReloadTimer=function(t,e){var r=this;t in this._timers&&(clearTimeout(this._timers[t]),delete this._timers[t]);var n=e.getExpiryTimeout();n&&(this._timers[t]=setTimeout(function(){r._reloadTile(t,"expired"),delete r._timers[t]},n))},r.prototype._removeTile=function(t){var e=this._tiles[t];e&&(e.uses--,delete this._tiles[t],this._timers[t]&&(clearTimeout(this._timers[t]),delete this._timers[t]),e.uses>0||(e.hasData()?this._cache.add(e.tileID,e,e.getExpiryTimeout()):(e.aborted=!0,this._abortTile(e),this._unloadTile(e))))},r.prototype.clearTiles=function(){for(var t in this._shouldReloadOnResume=!1,this._paused=!1,this._tiles)this._removeTile(t);this._cache.reset()},r.prototype.tilesIn=function(e,r){for(var n=[],i=this.getIds(),a=1/0,o=1/0,s=-1/0,l=-1/0,c=e[0].zoom,u=0;u=0&&v[1].y+m>=0){for(var y=[],x=0;x=a.now())return!0}return!1},r}(t.Evented);function Xt(e,r){var n=r.zoomTo(e.canonical.z);return new t.default$1((n.column-(e.canonical.x+e.wrap*Math.pow(2,e.canonical.z)))*t.default$8,(n.row-e.canonical.y)*t.default$8)}function Zt(t){return"raster"===t||"image"===t||"video"===t}function $t(){return new t.default.Worker(En.workerUrl)}Yt.maxOverzooming=10,Yt.maxUnderzooming=3;var Jt,Kt=function(){this.active={}};function Qt(e,r){var n={};for(var i in e)"ref"!==i&&(n[i]=e[i]);return t.default$18.forEach(function(t){t in r&&(n[t]=r[t])}),n}function te(t){t=t.slice();for(var e=Object.create(null),r=0;rthis.width||n<0||e>this.height)return!i&&[];var a=[];if(t<=0&&e<=0&&this.width<=r&&this.height<=n){if(i)return!0;for(var o=0;o0:a},ce.prototype._queryCircle=function(t,e,r,n){var i=t-r,a=t+r,o=e-r,s=e+r;if(a<0||i>this.width||s<0||o>this.height)return!n&&[];var l=[],c={hitTest:n,circle:{x:t,y:e,radius:r},seenUids:{box:{},circle:{}}};return this._forEachCell(i,o,a,s,this._queryCellCircle,l,c),n?l.length>0:l},ce.prototype.query=function(t,e,r,n){return this._query(t,e,r,n,!1)},ce.prototype.hitTest=function(t,e,r,n){return this._query(t,e,r,n,!0)},ce.prototype.hitTestCircle=function(t,e,r){return this._queryCircle(t,e,r,!0)},ce.prototype._queryCell=function(t,e,r,n,i,a,o){var s=o.seenUids,l=this.boxCells[i];if(null!==l)for(var c=this.bboxes,u=0,h=l;u=c[p+0]&&n>=c[p+1]){if(o.hitTest)return a.push(!0),!0;a.push({key:this.boxKeys[f],x1:c[p],y1:c[p+1],x2:c[p+2],y2:c[p+3]})}}}var d=this.circleCells[i];if(null!==d)for(var g=this.circles,m=0,v=d;mo*o+s*s},ce.prototype._circleAndRectCollide=function(t,e,r,n,i,a,o){var s=(a-n)/2,l=Math.abs(t-(n+s));if(l>s+r)return!1;var c=(o-i)/2,u=Math.abs(e-(i+c));if(u>c+r)return!1;if(l<=s||u<=c)return!0;var h=l-s,f=u-c;return h*h+f*f<=r*r};var ue=t.default$19.layout;function he(e,r,n,i,a){var o=t.mat4.identity(new Float32Array(16));return r?(t.mat4.identity(o),t.mat4.scale(o,o,[1/a,1/a,1]),n||t.mat4.rotateZ(o,o,i.angle)):(t.mat4.scale(o,o,[i.width/2,-i.height/2,1]),t.mat4.translate(o,o,[1,-1,0]),t.mat4.multiply(o,o,e)),o}function fe(e,r,n,i,a){var o=t.mat4.identity(new Float32Array(16));return r?(t.mat4.multiply(o,o,e),t.mat4.scale(o,o,[a,a,1]),n||t.mat4.rotateZ(o,o,-i.angle)):(t.mat4.scale(o,o,[1,-1,1]),t.mat4.translate(o,o,[-1,-1,0]),t.mat4.scale(o,o,[2/i.width,2/i.height,1])),o}function pe(e,r){var n=[e.x,e.y,0,1];ke(n,n,r);var i=n[3];return{point:new t.default$1(n[0]/i,n[1]/i),signedDistanceFromCamera:i}}function de(t,e){var r=t[0]/t[3],n=t[1]/t[3];return r>=-e[0]&&r<=e[0]&&n>=-e[1]&&n<=e[1]}function ge(e,r,n,i,a,o,s,l){var c=i?e.textSizeData:e.iconSizeData,u=t.evaluateSizeForZoom(c,n.transform.zoom,ue.properties[i?"text-size":"icon-size"]),h=[256/n.width*2+1,256/n.height*2+1],f=i?e.text.dynamicLayoutVertexArray:e.icon.dynamicLayoutVertexArray;f.clear();for(var p=e.lineVertexArray,d=i?e.text.placedSymbolArray:e.icon.placedSymbolArray,g=n.transform.width/n.transform.height,m=!1,v=0;vMath.abs(n.x-r.x)*i?{useVertical:!0}:(e===t.WritingMode.vertical?r.yn.x)?{needsFlipping:!0}:null}function ye(e,r,n,i,a,o,s,l,c,u,h,f,p,d){var g,m=r/24,v=e.lineOffsetX*r,y=e.lineOffsetY*r;if(e.numGlyphs>1){var x=e.glyphStartIndex+e.numGlyphs,b=e.lineStartIndex,_=e.lineStartIndex+e.lineLength,w=me(m,l,v,y,n,h,f,e,c,o,p,!1);if(!w)return{notEnoughRoom:!0};var k=pe(w.first.point,s).point,M=pe(w.last.point,s).point;if(i&&!n){var A=ve(e.writingMode,k,M,d);if(A)return A}g=[w.first];for(var T=e.glyphStartIndex+1;T0?L.point:xe(f,C,S,1,a),P=ve(e.writingMode,S,z,d);if(P)return P}var I=be(m*l.getoffsetX(e.glyphStartIndex),v,y,n,h,f,e.segment,e.lineStartIndex,e.lineStartIndex+e.lineLength,c,o,p,!1);if(!I)return{notEnoughRoom:!0};g=[I]}for(var O=0,D=g;O0?1:-1,m=0;i&&(g*=-1,m=Math.PI),g<0&&(m+=Math.PI);for(var v=g>0?l+s:l+s+1,y=v,x=a,b=a,_=0,w=0,k=Math.abs(d);_+w<=k;){if((v+=g)=c)return null;if(b=x,void 0===(x=f[v])){var M=new t.default$1(u.getx(v),u.gety(v)),A=pe(M,h);if(A.signedDistanceFromCamera>0)x=f[v]=A.point;else{var T=v-g;x=xe(0===_?o:new t.default$1(u.getx(T),u.gety(T)),M,b,k-_+1,h)}}_+=w,w=b.dist(x)}var S=(k-_)/w,E=x.sub(b),C=E.mult(S)._add(b);return C._add(E._unit()._perp()._mult(n*g)),{point:C,angle:m+Math.atan2(x.y-b.y,x.x-b.x),tileDistance:p?{prevTileDistance:v-g===y?0:u.gettileUnitDistanceFromAnchor(v-g),lastSegmentViewportDistance:k-_}:null}}var _e=new Float32Array([-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0]);function we(t,e){for(var r=0;rT)Ae(e,S,!1);else{var P=this.projectPoint(u,E,C),I=L*k;if(d.length>0){var O=P.x-d[d.length-4],D=P.y-d[d.length-3];if(I*I*2>O*O+D*D&&S+8-A&&R=this.screenRightBoundary||n<100||e>this.screenBottomBoundary};var Se=t.default$19.layout,Ee=function(t,e,r,n){this.opacity=t?Math.max(0,Math.min(1,t.opacity+(t.placed?e:-e))):n&&r?1:0,this.placed=r};Ee.prototype.isHidden=function(){return 0===this.opacity&&!this.placed};var Ce=function(t,e,r,n,i){this.text=new Ee(t?t.text:null,e,r,i),this.icon=new Ee(t?t.icon:null,e,n,i)};Ce.prototype.isHidden=function(){return this.text.isHidden()&&this.icon.isHidden()};var Le=function(t,e,r){this.text=t,this.icon=e,this.skipFade=r},ze=function(t,e){this.transform=t.clone(),this.collisionIndex=new Me(this.transform),this.placements={},this.opacities={},this.stale=!1,this.fadeDuration=e,this.retainedQueryData={}};function Pe(t,e,r){t.emplaceBack(e?1:0,r?1:0),t.emplaceBack(e?1:0,r?1:0),t.emplaceBack(e?1:0,r?1:0),t.emplaceBack(e?1:0,r?1:0)}ze.prototype.placeLayerTile=function(e,r,n,i){var a=r.getBucket(e),o=r.latestFeatureIndex;if(a&&o&&e.id===a.layerIds[0]){var s=r.collisionBoxArray,l=a.layers[0].layout,c=Math.pow(2,this.transform.zoom-r.tileID.overscaledZ),u=r.tileSize/t.default$8,h=this.transform.calculatePosMatrix(r.tileID.toUnwrapped()),f=he(h,"map"===l.get("text-pitch-alignment"),"map"===l.get("text-rotation-alignment"),this.transform,Te(r,1,this.transform.zoom)),p=he(h,"map"===l.get("icon-pitch-alignment"),"map"===l.get("icon-rotation-alignment"),this.transform,Te(r,1,this.transform.zoom));this.retainedQueryData[a.bucketInstanceId]=new function(t,e,r,n,i){this.bucketInstanceId=t,this.featureIndex=e,this.sourceLayerIndex=r,this.bucketIndex=n,this.tileID=i}(a.bucketInstanceId,o,a.sourceLayerIndex,a.index,r.tileID),this.placeLayerBucket(a,h,f,p,c,u,n,i,s)}},ze.prototype.placeLayerBucket=function(e,r,n,i,a,o,s,l,c){for(var u=e.layers[0].layout,h=t.evaluateSizeForZoom(e.textSizeData,this.transform.zoom,Se.properties["text-size"]),f=!e.hasTextData()||u.get("text-optional"),p=!e.hasIconData()||u.get("icon-optional"),d=0,g=e.symbolInstances;d0,x=x&&b.offscreen);var A=m.collisionArrays.textCircles;if(A){var T=e.text.placedSymbolArray.get(m.placedTextSymbolIndices[0]),S=t.evaluateSizeForFeature(e.textSizeData,h,T);_=this.collisionIndex.placeCollisionCircles(A,u.get("text-allow-overlap"),a,o,m.key,T,e.lineVertexArray,e.glyphOffsetArray,S,r,n,s,"map"===u.get("text-pitch-alignment")),v=u.get("text-allow-overlap")||_.circles.length>0,x=x&&_.offscreen}m.collisionArrays.iconFeatureIndex&&(M=m.collisionArrays.iconFeatureIndex),m.collisionArrays.iconBox&&(y=(w=this.collisionIndex.placeCollisionBox(m.collisionArrays.iconBox,u.get("icon-allow-overlap"),o,r)).box.length>0,x=x&&w.offscreen),f||p?p?f||(y=y&&v):v=y&&v:y=v=y&&v,v&&b&&this.collisionIndex.insertCollisionBox(b.box,u.get("text-ignore-placement"),e.bucketInstanceId,k),y&&w&&this.collisionIndex.insertCollisionBox(w.box,u.get("icon-ignore-placement"),e.bucketInstanceId,M),v&&_&&this.collisionIndex.insertCollisionCircles(_.circles,u.get("text-ignore-placement"),e.bucketInstanceId,k),this.placements[m.crossTileID]=new Le(v,y,x||e.justReloaded),l[m.crossTileID]=!0}}e.justReloaded=!1},ze.prototype.commit=function(t,e){this.commitTime=e;var r=!1,n=t&&0!==this.fadeDuration?(this.commitTime-t.commitTime)/this.fadeDuration:1,i=t?t.opacities:{};for(var a in this.placements){var o=this.placements[a],s=i[a];s?(this.opacities[a]=new Ce(s,n,o.text,o.icon),r=r||o.text!==s.text.placed||o.icon!==s.icon.placed):(this.opacities[a]=new Ce(null,n,o.text,o.icon,o.skipFade),r=r||o.text||o.icon)}for(var l in i){var c=i[l];if(!this.opacities[l]){var u=new Ce(c,n,!1,!1);u.isHidden()||(this.opacities[l]=u,r=r||c.text.placed||c.icon.placed)}}r?this.lastPlacementChangeTime=e:"number"!=typeof this.lastPlacementChangeTime&&(this.lastPlacementChangeTime=t?t.lastPlacementChangeTime:e)},ze.prototype.updateLayerOpacities=function(t,e){for(var r={},n=0,i=e;n0||s.numVerticalGlyphVertices>0,h=s.numIconVertices>0;if(u){for(var f=je(c.text),p=(s.numGlyphVertices+s.numVerticalGlyphVertices)/4,d=0;dt},ze.prototype.setStale=function(){this.stale=!0};var Ie=Math.pow(2,25),Oe=Math.pow(2,24),De=Math.pow(2,17),Re=Math.pow(2,16),Be=Math.pow(2,9),Fe=Math.pow(2,8),Ne=Math.pow(2,1);function je(t){if(0===t.opacity&&!t.placed)return 0;if(1===t.opacity&&t.placed)return 4294967295;var e=t.placed?1:0,r=Math.floor(127*t.opacity);return r*Ie+e*Oe+r*De+e*Re+r*Be+e*Fe+r*Ne+e}var Ve=function(){this._currentTileIndex=0,this._seenCrossTileIDs={}};Ve.prototype.continuePlacement=function(t,e,r,n,i){for(;this._currentTileIndex2};this._currentPlacementIndex>=0;){var s=e[t[n._currentPlacementIndex]],l=n.placement.collisionIndex.transform.zoom;if("symbol"===s.type&&(!s.minzoom||s.minzoom<=l)&&(!s.maxzoom||s.maxzoom>l)){if(n._inProgressLayer||(n._inProgressLayer=new Ve),n._inProgressLayer.continuePlacement(r[s.source],n.placement,n._showCollisionBoxes,s,o))return;delete n._inProgressLayer}n._currentPlacementIndex--}this._done=!0},Ue.prototype.commit=function(t,e){return this.placement.commit(t,e),this.placement};var qe=512/t.default$8/2,He=function(t,e,r){this.tileID=t,this.indexedSymbolInstances={},this.bucketInstanceId=r;for(var n=0,i=e;nt.overscaledZ)for(var l in s){var c=s[l];c.tileID.isChildOf(t)&&c.findMatches(e.symbolInstances,t,a)}else{var u=s[t.scaledTo(Number(o)).key];u&&u.findMatches(e.symbolInstances,t,a)}}for(var h=0,f=e.symbolInstances;h1?"@2x":"";function c(){if(s)n(s);else if(i&&o){var e=a.getImageData(o),r={};for(var l in i){var c=i[l],u=c.width,h=c.height,f=c.x,p=c.y,d=c.sdf,g=c.pixelRatio,m=new t.RGBAImage({width:u,height:h});t.RGBAImage.copy(e,m,{x:f,y:p},{x:0,y:0},{width:u,height:h}),r[l]={data:m,pixelRatio:g,sdf:d}}n(null,r)}}t.getJSON(r(_(e,l,".json"),t.ResourceType.SpriteJSON),function(t,e){s||(s=t,i=e,c())}),t.getImage(r(_(e,l,".png"),t.ResourceType.SpriteImage),function(t,e){s||(s=t,o=e,c())})}(e.sprite,this.map._transformRequest,function(e,r){if(e)n.fire(new t.ErrorEvent(e));else if(r)for(var i in r)n.imageManager.addImage(i,r[i]);n.imageManager.setLoaded(!0),n.fire(new t.Event("data",{dataType:"style"}))}):this.imageManager.setLoaded(!0),this.glyphManager.setURL(e.glyphs);var o=te(this.stylesheet.layers);this._order=o.map(function(t){return t.id}),this._layers={};for(var s=0,l=o;s0)throw new Error("Unimplemented: "+i.map(function(t){return t.command}).join(", ")+".");return n.forEach(function(t){"setTransition"!==t.command&&r[t.command].apply(r,t.args)}),this.stylesheet=e,!0},r.prototype.addImage=function(e,r){if(this.getImage(e))return this.fire(new t.ErrorEvent(new Error("An image with this name already exists.")));this.imageManager.addImage(e,r),this.fire(new t.Event("data",{dataType:"style"}))},r.prototype.getImage=function(t){return this.imageManager.getImage(t)},r.prototype.removeImage=function(e){if(!this.getImage(e))return this.fire(new t.ErrorEvent(new Error("No image with this name exists.")));this.imageManager.removeImage(e),this.fire(new t.Event("data",{dataType:"style"}))},r.prototype.addSource=function(e,r,n){var i=this;if(this._checkLoaded(),void 0!==this.sourceCaches[e])throw new Error("There is already a source with this ID");if(!r.type)throw new Error("The type property must be defined, but the only the following properties were given: "+Object.keys(r).join(", ")+".");if(!(["vector","raster","geojson","video","image"].indexOf(r.type)>=0&&this._validate(t.validateStyle.source,"sources."+e,r,null,n))){this.map&&this.map._collectResourceTiming&&(r.collectResourceTiming=!0);var a=this.sourceCaches[e]=new Yt(e,r,this.dispatcher);a.style=this,a.setEventedParent(this,function(){return{isSourceLoaded:i.loaded(),source:a.serialize(),sourceId:e}}),a.onAdd(this.map),this._changed=!0}},r.prototype.removeSource=function(e){if(this._checkLoaded(),void 0===this.sourceCaches[e])throw new Error("There is no source with this ID");for(var r in this._layers)if(this._layers[r].source===e)return this.fire(new t.ErrorEvent(new Error('Source "'+e+'" cannot be removed while layer "'+r+'" is using it.')));var n=this.sourceCaches[e];delete this.sourceCaches[e],delete this._updatedSources[e],n.fire(new t.Event("data",{sourceDataType:"metadata",dataType:"source",sourceId:e})),n.setEventedParent(null),n.clearTiles(),n.onRemove&&n.onRemove(this.map),this._changed=!0},r.prototype.setGeoJSONSourceData=function(t,e){this._checkLoaded(),this.sourceCaches[t].getSource().setData(e),this._changed=!0},r.prototype.getSource=function(t){return this.sourceCaches[t]&&this.sourceCaches[t].getSource()},r.prototype.addLayer=function(e,r,n){this._checkLoaded();var i=e.id;if(this.getLayer(i))this.fire(new t.ErrorEvent(new Error('Layer with id "'+i+'" already exists on this map')));else if("object"==typeof e.source&&(this.addSource(i,e.source),e=t.clone(e),e=t.extend(e,{source:i})),!this._validate(t.validateStyle.layer,"layers."+i,e,{arrayIndex:-1},n)){var a=t.default$22(e);this._validateLayer(a),a.setEventedParent(this,{layer:{id:i}});var o=r?this._order.indexOf(r):this._order.length;if(r&&-1===o)this.fire(new t.ErrorEvent(new Error('Layer with id "'+r+'" does not exist on this map.')));else{if(this._order.splice(o,0,i),this._layerOrderChanged=!0,this._layers[i]=a,this._removedLayers[i]&&a.source){var s=this._removedLayers[i];delete this._removedLayers[i],s.type!==a.type?this._updatedSources[a.source]="clear":(this._updatedSources[a.source]="reload",this.sourceCaches[a.source].pause())}this._updateLayer(a)}}},r.prototype.moveLayer=function(e,r){if(this._checkLoaded(),this._changed=!0,this._layers[e]){if(e!==r){var n=this._order.indexOf(e);this._order.splice(n,1);var i=r?this._order.indexOf(r):this._order.length;r&&-1===i?this.fire(new t.ErrorEvent(new Error('Layer with id "'+r+'" does not exist on this map.'))):(this._order.splice(i,0,e),this._layerOrderChanged=!0)}}else this.fire(new t.ErrorEvent(new Error("The layer '"+e+"' does not exist in the map's style and cannot be moved.")))},r.prototype.removeLayer=function(e){this._checkLoaded();var r=this._layers[e];if(r){r.setEventedParent(null);var n=this._order.indexOf(e);this._order.splice(n,1),this._layerOrderChanged=!0,this._changed=!0,this._removedLayers[e]=r,delete this._layers[e],delete this._updatedLayers[e],delete this._updatedPaintProps[e]}else this.fire(new t.ErrorEvent(new Error("The layer '"+e+"' does not exist in the map's style and cannot be removed.")))},r.prototype.getLayer=function(t){return this._layers[t]},r.prototype.setLayerZoomRange=function(e,r,n){this._checkLoaded();var i=this.getLayer(e);i?i.minzoom===r&&i.maxzoom===n||(null!=r&&(i.minzoom=r),null!=n&&(i.maxzoom=n),this._updateLayer(i)):this.fire(new t.ErrorEvent(new Error("The layer '"+e+"' does not exist in the map's style and cannot have zoom extent.")))},r.prototype.setFilter=function(e,r){this._checkLoaded();var n=this.getLayer(e);if(n){if(!t.default$10(n.filter,r))return null==r?(n.filter=void 0,void this._updateLayer(n)):void(this._validate(t.validateStyle.filter,"layers."+n.id+".filter",r)||(n.filter=t.clone(r),this._updateLayer(n)))}else this.fire(new t.ErrorEvent(new Error("The layer '"+e+"' does not exist in the map's style and cannot be filtered.")))},r.prototype.getFilter=function(e){return t.clone(this.getLayer(e).filter)},r.prototype.setLayoutProperty=function(e,r,n){this._checkLoaded();var i=this.getLayer(e);i?t.default$10(i.getLayoutProperty(r),n)||(i.setLayoutProperty(r,n),this._updateLayer(i)):this.fire(new t.ErrorEvent(new Error("The layer '"+e+"' does not exist in the map's style and cannot be styled.")))},r.prototype.getLayoutProperty=function(t,e){return this.getLayer(t).getLayoutProperty(e)},r.prototype.setPaintProperty=function(e,r,n){this._checkLoaded();var i=this.getLayer(e);if(i){if(!t.default$10(i.getPaintProperty(r),n)){var a=i._transitionablePaint._values[r].value.isDataDriven();i.setPaintProperty(r,n),(i._transitionablePaint._values[r].value.isDataDriven()||a)&&this._updateLayer(i),this._changed=!0,this._updatedPaintProps[e]=!0}}else this.fire(new t.ErrorEvent(new Error("The layer '"+e+"' does not exist in the map's style and cannot be styled.")))},r.prototype.getPaintProperty=function(t,e){return this.getLayer(t).getPaintProperty(e)},r.prototype.getTransition=function(){return t.extend({duration:300,delay:0},this.stylesheet&&this.stylesheet.transition)},r.prototype.serialize=function(){var e=this;return t.filterObject({version:this.stylesheet.version,name:this.stylesheet.name,metadata:this.stylesheet.metadata,light:this.stylesheet.light,center:this.stylesheet.center,zoom:this.stylesheet.zoom,bearing:this.stylesheet.bearing,pitch:this.stylesheet.pitch,sprite:this.stylesheet.sprite,glyphs:this.stylesheet.glyphs,transition:this.stylesheet.transition,sources:t.mapObject(this.sourceCaches,function(t){return t.serialize()}),layers:this._order.map(function(t){return e._layers[t].serialize()})},function(t){return void 0!==t})},r.prototype._updateLayer=function(t){this._updatedLayers[t.id]=!0,t.source&&!this._updatedSources[t.source]&&(this._updatedSources[t.source]="reload",this.sourceCaches[t.source].pause()),this._changed=!0},r.prototype._flattenRenderedFeatures=function(t){for(var e=[],r=this._order.length-1;r>=0;r--)for(var n=this._order[r],i=0,a=t;i 0.5) {\n gl_FragColor = vec4(0.0, 0.0, 1.0, 0.5) * alpha;\n }\n\n if (v_notUsed > 0.5) {\n // This box not used, fade it out\n gl_FragColor *= .1;\n }\n}",vertexSource:"attribute vec2 a_pos;\nattribute vec2 a_anchor_pos;\nattribute vec2 a_extrude;\nattribute vec2 a_placed;\n\nuniform mat4 u_matrix;\nuniform vec2 u_extrude_scale;\nuniform float u_camera_to_center_distance;\n\nvarying float v_placed;\nvarying float v_notUsed;\n\nvoid main() {\n vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1);\n highp float camera_to_anchor_distance = projectedPoint.w;\n highp float collision_perspective_ratio = clamp(\n 0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance),\n 0.0, // Prevents oversized near-field boxes in pitched/overzoomed tiles\n 4.0);\n\n gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n gl_Position.xy += a_extrude * u_extrude_scale * gl_Position.w * collision_perspective_ratio;\n\n v_placed = a_placed.x;\n v_notUsed = a_placed.y;\n}\n"},collisionCircle:{fragmentSource:"uniform float u_overscale_factor;\n\nvarying float v_placed;\nvarying float v_notUsed;\nvarying float v_radius;\nvarying vec2 v_extrude;\nvarying vec2 v_extrude_scale;\n\nvoid main() {\n float alpha = 0.5;\n\n // Red = collision, hide label\n vec4 color = vec4(1.0, 0.0, 0.0, 1.0) * alpha;\n\n // Blue = no collision, label is showing\n if (v_placed > 0.5) {\n color = vec4(0.0, 0.0, 1.0, 0.5) * alpha;\n }\n\n if (v_notUsed > 0.5) {\n // This box not used, fade it out\n color *= .2;\n }\n\n float extrude_scale_length = length(v_extrude_scale);\n float extrude_length = length(v_extrude) * extrude_scale_length;\n float stroke_width = 15.0 * extrude_scale_length / u_overscale_factor;\n float radius = v_radius * extrude_scale_length;\n\n float distance_to_edge = abs(extrude_length - radius);\n float opacity_t = smoothstep(-stroke_width, 0.0, -distance_to_edge);\n\n gl_FragColor = opacity_t * color;\n}\n",vertexSource:"attribute vec2 a_pos;\nattribute vec2 a_anchor_pos;\nattribute vec2 a_extrude;\nattribute vec2 a_placed;\n\nuniform mat4 u_matrix;\nuniform vec2 u_extrude_scale;\nuniform float u_camera_to_center_distance;\n\nvarying float v_placed;\nvarying float v_notUsed;\nvarying float v_radius;\n\nvarying vec2 v_extrude;\nvarying vec2 v_extrude_scale;\n\nvoid main() {\n vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1);\n highp float camera_to_anchor_distance = projectedPoint.w;\n highp float collision_perspective_ratio = clamp(\n 0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance),\n 0.0, // Prevents oversized near-field circles in pitched/overzoomed tiles\n 4.0);\n\n gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n\n highp float padding_factor = 1.2; // Pad the vertices slightly to make room for anti-alias blur\n gl_Position.xy += a_extrude * u_extrude_scale * padding_factor * gl_Position.w * collision_perspective_ratio;\n\n v_placed = a_placed.x;\n v_notUsed = a_placed.y;\n v_radius = abs(a_extrude.y); // We don't pitch the circles, so both units of the extrusion vector are equal in magnitude to the radius\n\n v_extrude = a_extrude * padding_factor;\n v_extrude_scale = u_extrude_scale * u_camera_to_center_distance * collision_perspective_ratio;\n}\n"},debug:{fragmentSource:"uniform highp vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n",vertexSource:"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n"},fill:{fragmentSource:"#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float opacity\n\n gl_FragColor = color * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n"},fillOutline:{fragmentSource:"#pragma mapbox: define highp vec4 outline_color\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_pos;\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 outline_color\n #pragma mapbox: initialize lowp float opacity\n\n float dist = length(v_pos - gl_FragCoord.xy);\n float alpha = 1.0 - smoothstep(0.0, 1.0, dist);\n gl_FragColor = outline_color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform vec2 u_world;\n\nvarying vec2 v_pos;\n\n#pragma mapbox: define highp vec4 outline_color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 outline_color\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;\n}\n"},fillOutlinePattern:{fragmentSource:"uniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform vec2 u_texsize;\nuniform float u_mix;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec2 v_pos;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n vec2 imagecoord = mod(v_pos_a, 1.0);\n vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord_b = mod(v_pos_b, 1.0);\n vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);\n vec4 color2 = texture2D(u_image, pos2);\n\n // find distance to outline for alpha interpolation\n\n float dist = length(v_pos - gl_FragCoord.xy);\n float alpha = 1.0 - smoothstep(0.0, 1.0, dist);\n\n\n gl_FragColor = mix(color1, color2, u_mix) * alpha * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_world;\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_scale_a;\nuniform float u_scale_b;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec2 v_pos;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, a_pos);\n v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, a_pos);\n\n v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;\n}\n"},fillPattern:{fragmentSource:"uniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform vec2 u_texsize;\nuniform float u_mix;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n vec2 imagecoord = mod(v_pos_a, 1.0);\n vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord_b = mod(v_pos_b, 1.0);\n vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);\n vec4 color2 = texture2D(u_image, pos2);\n\n gl_FragColor = mix(color1, color2, u_mix) * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_scale_a;\nuniform float u_scale_b;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, a_pos);\n v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, a_pos);\n}\n"},fillExtrusion:{fragmentSource:"varying vec4 v_color;\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n#pragma mapbox: define highp vec4 color\n\nvoid main() {\n #pragma mapbox: initialize lowp float base\n #pragma mapbox: initialize lowp float height\n #pragma mapbox: initialize highp vec4 color\n\n gl_FragColor = v_color;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec3 u_lightcolor;\nuniform lowp vec3 u_lightpos;\nuniform lowp float u_lightintensity;\n\nattribute vec2 a_pos;\nattribute vec4 a_normal_ed;\n\nvarying vec4 v_color;\n\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n\n#pragma mapbox: define highp vec4 color\n\nvoid main() {\n #pragma mapbox: initialize lowp float base\n #pragma mapbox: initialize lowp float height\n #pragma mapbox: initialize highp vec4 color\n\n vec3 normal = a_normal_ed.xyz;\n\n base = max(0.0, base);\n height = max(0.0, height);\n\n float t = mod(normal.x, 2.0);\n\n gl_Position = u_matrix * vec4(a_pos, t > 0.0 ? height : base, 1);\n\n // Relative luminance (how dark/bright is the surface color?)\n float colorvalue = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;\n\n v_color = vec4(0.0, 0.0, 0.0, 1.0);\n\n // Add slight ambient lighting so no extrusions are totally black\n vec4 ambientlight = vec4(0.03, 0.03, 0.03, 1.0);\n color += ambientlight;\n\n // Calculate cos(theta), where theta is the angle between surface normal and diffuse light ray\n float directional = clamp(dot(normal / 16384.0, u_lightpos), 0.0, 1.0);\n\n // Adjust directional so that\n // the range of values for highlight/shading is narrower\n // with lower light intensity\n // and with lighter/brighter surface colors\n directional = mix((1.0 - u_lightintensity), max((1.0 - colorvalue + u_lightintensity), 1.0), directional);\n\n // Add gradient along z axis of side surfaces\n if (normal.y != 0.0) {\n directional *= clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0);\n }\n\n // Assign final color based on surface + ambient light color, diffuse light directional, and light color\n // with lower bounds adjusted to hue of light\n // so that shading is tinted with the complementary (opposite) color to the light color\n v_color.r += clamp(color.r * directional * u_lightcolor.r, mix(0.0, 0.3, 1.0 - u_lightcolor.r), 1.0);\n v_color.g += clamp(color.g * directional * u_lightcolor.g, mix(0.0, 0.3, 1.0 - u_lightcolor.g), 1.0);\n v_color.b += clamp(color.b * directional * u_lightcolor.b, mix(0.0, 0.3, 1.0 - u_lightcolor.b), 1.0);\n}\n"},fillExtrusionPattern:{fragmentSource:"uniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform vec2 u_texsize;\nuniform float u_mix;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec4 v_lighting;\n\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n\nvoid main() {\n #pragma mapbox: initialize lowp float base\n #pragma mapbox: initialize lowp float height\n\n vec2 imagecoord = mod(v_pos_a, 1.0);\n vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord_b = mod(v_pos_b, 1.0);\n vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);\n vec4 color2 = texture2D(u_image, pos2);\n\n vec4 mixedColor = mix(color1, color2, u_mix);\n\n gl_FragColor = mixedColor * v_lighting;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_scale_a;\nuniform float u_scale_b;\nuniform float u_tile_units_to_pixels;\nuniform float u_height_factor;\n\nuniform vec3 u_lightcolor;\nuniform lowp vec3 u_lightpos;\nuniform lowp float u_lightintensity;\n\nattribute vec2 a_pos;\nattribute vec4 a_normal_ed;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec4 v_lighting;\nvarying float v_directional;\n\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n\nvoid main() {\n #pragma mapbox: initialize lowp float base\n #pragma mapbox: initialize lowp float height\n\n vec3 normal = a_normal_ed.xyz;\n float edgedistance = a_normal_ed.w;\n\n base = max(0.0, base);\n height = max(0.0, height);\n\n float t = mod(normal.x, 2.0);\n float z = t > 0.0 ? height : base;\n\n gl_Position = u_matrix * vec4(a_pos, z, 1);\n\n vec2 pos = normal.x == 1.0 && normal.y == 0.0 && normal.z == 16384.0\n ? a_pos // extrusion top\n : vec2(edgedistance, z * u_height_factor); // extrusion side\n\n v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, pos);\n v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, pos);\n\n v_lighting = vec4(0.0, 0.0, 0.0, 1.0);\n float directional = clamp(dot(normal / 16383.0, u_lightpos), 0.0, 1.0);\n directional = mix((1.0 - u_lightintensity), max((0.5 + u_lightintensity), 1.0), directional);\n\n if (normal.y != 0.0) {\n directional *= clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0);\n }\n\n v_lighting.rgb += clamp(directional * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0));\n}\n"},extrusionTexture:{fragmentSource:"uniform sampler2D u_image;\nuniform float u_opacity;\nvarying vec2 v_pos;\n\nvoid main() {\n gl_FragColor = texture2D(u_image, v_pos) * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(0.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_world;\nattribute vec2 a_pos;\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos * u_world, 0, 1);\n\n v_pos.x = a_pos.x;\n v_pos.y = 1.0 - a_pos.y;\n}\n"},hillshadePrepare:{fragmentSource:"#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform sampler2D u_image;\nvarying vec2 v_pos;\nuniform vec2 u_dimension;\nuniform float u_zoom;\nuniform float u_maxzoom;\n\nfloat getElevation(vec2 coord, float bias) {\n // Convert encoded elevation value to meters\n vec4 data = texture2D(u_image, coord) * 255.0;\n return (data.r + data.g * 256.0 + data.b * 256.0 * 256.0) / 4.0;\n}\n\nvoid main() {\n vec2 epsilon = 1.0 / u_dimension;\n\n // queried pixels:\n // +-----------+\n // | | | |\n // | a | b | c |\n // | | | |\n // +-----------+\n // | | | |\n // | d | e | f |\n // | | | |\n // +-----------+\n // | | | |\n // | g | h | i |\n // | | | |\n // +-----------+\n\n float a = getElevation(v_pos + vec2(-epsilon.x, -epsilon.y), 0.0);\n float b = getElevation(v_pos + vec2(0, -epsilon.y), 0.0);\n float c = getElevation(v_pos + vec2(epsilon.x, -epsilon.y), 0.0);\n float d = getElevation(v_pos + vec2(-epsilon.x, 0), 0.0);\n float e = getElevation(v_pos, 0.0);\n float f = getElevation(v_pos + vec2(epsilon.x, 0), 0.0);\n float g = getElevation(v_pos + vec2(-epsilon.x, epsilon.y), 0.0);\n float h = getElevation(v_pos + vec2(0, epsilon.y), 0.0);\n float i = getElevation(v_pos + vec2(epsilon.x, epsilon.y), 0.0);\n\n // here we divide the x and y slopes by 8 * pixel size\n // where pixel size (aka meters/pixel) is:\n // circumference of the world / (pixels per tile * number of tiles)\n // which is equivalent to: 8 * 40075016.6855785 / (512 * pow(2, u_zoom))\n // which can be reduced to: pow(2, 19.25619978527 - u_zoom)\n // we want to vertically exaggerate the hillshading though, because otherwise\n // it is barely noticeable at low zooms. to do this, we multiply this by some\n // scale factor pow(2, (u_zoom - u_maxzoom) * a) where a is an arbitrary value\n // Here we use a=0.3 which works out to the expression below. see \n // nickidlugash's awesome breakdown for more info\n // https://github.com/mapbox/mapbox-gl-js/pull/5286#discussion_r148419556\n float exaggeration = u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;\n\n vec2 deriv = vec2(\n (c + f + f + i) - (a + d + d + g),\n (g + h + h + i) - (a + b + b + c)\n ) / pow(2.0, (u_zoom - u_maxzoom) * exaggeration + 19.2562 - u_zoom);\n\n gl_FragColor = clamp(vec4(\n deriv.x / 2.0 + 0.5,\n deriv.y / 2.0 + 0.5,\n 1.0,\n 1.0), 0.0, 1.0);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\n\nattribute vec2 a_pos;\nattribute vec2 a_texture_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = (a_texture_pos / 8192.0) / 2.0 + 0.25;\n}\n"},hillshade:{fragmentSource:"uniform sampler2D u_image;\nvarying vec2 v_pos;\n\nuniform vec2 u_latrange;\nuniform vec2 u_light;\nuniform vec4 u_shadow;\nuniform vec4 u_highlight;\nuniform vec4 u_accent;\n\n#define PI 3.141592653589793\n\nvoid main() {\n vec4 pixel = texture2D(u_image, v_pos);\n\n vec2 deriv = ((pixel.rg * 2.0) - 1.0);\n\n // We divide the slope by a scale factor based on the cosin of the pixel's approximate latitude\n // to account for mercator projection distortion. see #4807 for details\n float scaleFactor = cos(radians((u_latrange[0] - u_latrange[1]) * (1.0 - v_pos.y) + u_latrange[1]));\n // We also multiply the slope by an arbitrary z-factor of 1.25\n float slope = atan(1.25 * length(deriv) / scaleFactor);\n float aspect = deriv.x != 0.0 ? atan(deriv.y, -deriv.x) : PI / 2.0 * (deriv.y > 0.0 ? 1.0 : -1.0);\n\n float intensity = u_light.x;\n // We add PI to make this property match the global light object, which adds PI/2 to the light's azimuthal\n // position property to account for 0deg corresponding to north/the top of the viewport in the style spec\n // and the original shader was written to accept (-illuminationDirection - 90) as the azimuthal.\n float azimuth = u_light.y + PI;\n\n // We scale the slope exponentially based on intensity, using a calculation similar to\n // the exponential interpolation function in the style spec:\n // https://github.com/mapbox/mapbox-gl-js/blob/master/src/style-spec/expression/definitions/interpolate.js#L217-L228\n // so that higher intensity values create more opaque hillshading.\n float base = 1.875 - intensity * 1.75;\n float maxValue = 0.5 * PI;\n float scaledSlope = intensity != 0.5 ? ((pow(base, slope) - 1.0) / (pow(base, maxValue) - 1.0)) * maxValue : slope;\n\n // The accent color is calculated with the cosine of the slope while the shade color is calculated with the sine\n // so that the accent color's rate of change eases in while the shade color's eases out.\n float accent = cos(scaledSlope);\n // We multiply both the accent and shade color by a clamped intensity value\n // so that intensities >= 0.5 do not additionally affect the color values\n // while intensity values < 0.5 make the overall color more transparent.\n vec4 accent_color = (1.0 - accent) * u_accent * clamp(intensity * 2.0, 0.0, 1.0);\n float shade = abs(mod((aspect + azimuth) / PI + 0.5, 2.0) - 1.0);\n vec4 shade_color = mix(u_shadow, u_highlight, shade) * sin(scaledSlope) * clamp(intensity * 2.0, 0.0, 1.0);\n gl_FragColor = accent_color * (1.0 - shade_color.a) + shade_color;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\n\nattribute vec2 a_pos;\nattribute vec2 a_texture_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = a_texture_pos / 8192.0;\n}\n"},line:{fragmentSource:"#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_width2;\nvarying vec2 v_normal;\nvarying float v_gamma_scale;\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_width2.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_width2.t) or when fading out\n // (v_width2.s)\n float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;\n float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n\n gl_FragColor = color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"\n\n// the distance over which the line edge fades out.\n// Retina devices need a smaller distance to avoid aliasing.\n#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0\n\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\nattribute vec4 a_pos_normal;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform vec2 u_gl_units_to_pixels;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_gamma_scale;\nvarying highp float v_linesofar;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float width\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize mediump float gapwidth\n #pragma mapbox: initialize lowp float offset\n #pragma mapbox: initialize mediump float width\n\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n\n v_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * 2.0;\n\n vec2 pos = a_pos_normal.xy;\n\n // x is 1 if it's a round cap, 0 otherwise\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = a_pos_normal.zw;\n v_normal = normal;\n\n // these transformations used to be applied in the JS and native code bases.\n // moved them into the shader for clarity and simplicity.\n gapwidth = gapwidth / 2.0;\n float halfwidth = width / 2.0;\n offset = -1.0 * offset;\n\n float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist = outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);\n gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;\n\n // calculate how much the perspective view squishes or stretches the extrude\n float extrude_length_without_perspective = length(dist);\n float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);\n v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n\n v_width2 = vec2(outset, inset);\n}\n"},lineGradient:{fragmentSource:"\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nuniform sampler2D u_image;\n\nvarying vec2 v_width2;\nvarying vec2 v_normal;\nvarying float v_gamma_scale;\nvarying highp float v_lineprogress;\n\nvoid main() {\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_width2.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_width2.t) or when fading out\n // (v_width2.s)\n float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;\n float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n\n // For gradient lines, v_lineprogress is the ratio along the entire line,\n // scaled to [0, 2^15), and the gradient ramp is stored in a texture.\n vec4 color = texture2D(u_image, vec2(v_lineprogress, 0.5));\n\n gl_FragColor = color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"\n// the attribute conveying progress along a line is scaled to [0, 2^15)\n#define MAX_LINE_DISTANCE 32767.0\n\n// the distance over which the line edge fades out.\n// Retina devices need a smaller distance to avoid aliasing.\n#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0\n\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\nattribute vec4 a_pos_normal;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform vec2 u_gl_units_to_pixels;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_gamma_scale;\nvarying highp float v_lineprogress;\n\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float width\n\nvoid main() {\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize mediump float gapwidth\n #pragma mapbox: initialize lowp float offset\n #pragma mapbox: initialize mediump float width\n\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n\n v_lineprogress = (floor(a_data.z / 4.0) + a_data.w * 64.0) * 2.0 / MAX_LINE_DISTANCE;\n\n vec2 pos = a_pos_normal.xy;\n\n // x is 1 if it's a round cap, 0 otherwise\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = a_pos_normal.zw;\n v_normal = normal;\n\n // these transformations used to be applied in the JS and native code bases.\n // moved them into the shader for clarity and simplicity.\n gapwidth = gapwidth / 2.0;\n float halfwidth = width / 2.0;\n offset = -1.0 * offset;\n\n float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist = outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);\n gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;\n\n // calculate how much the perspective view squishes or stretches the extrude\n float extrude_length_without_perspective = length(dist);\n float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);\n v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n\n v_width2 = vec2(outset, inset);\n}\n"},linePattern:{fragmentSource:"uniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform vec2 u_texsize;\nuniform float u_fade;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_linesofar;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_width2.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_width2.t) or when fading out\n // (v_width2.s)\n float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;\n float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n\n float x_a = mod(v_linesofar / u_pattern_size_a.x, 1.0);\n float x_b = mod(v_linesofar / u_pattern_size_b.x, 1.0);\n\n // v_normal.y is 0 at the midpoint of the line, -1 at the lower edge, 1 at the upper edge\n // we clamp the line width outset to be between 0 and half the pattern height plus padding (2.0)\n // to ensure we don't sample outside the designated symbol on the sprite sheet.\n // 0.5 is added to shift the component to be bounded between 0 and 1 for interpolation of\n // the texture coordinate\n float y_a = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (u_pattern_size_a.y + 2.0) / 2.0) / u_pattern_size_a.y);\n float y_b = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (u_pattern_size_b.y + 2.0) / 2.0) / u_pattern_size_b.y);\n vec2 pos_a = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, vec2(x_a, y_a));\n vec2 pos_b = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, vec2(x_b, y_b));\n\n vec4 color = mix(texture2D(u_image, pos_a), texture2D(u_image, pos_b), u_fade);\n\n gl_FragColor = color * alpha * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\n// We scale the distance before adding it to the buffers so that we can store\n// long distances for long segments. Use this value to unscale the distance.\n#define LINE_DISTANCE_SCALE 2.0\n\n// the distance over which the line edge fades out.\n// Retina devices need a smaller distance to avoid aliasing.\n#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0\n\nattribute vec4 a_pos_normal;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform vec2 u_gl_units_to_pixels;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_linesofar;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define mediump float width\n\nvoid main() {\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize lowp float offset\n #pragma mapbox: initialize mediump float gapwidth\n #pragma mapbox: initialize mediump float width\n\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;\n\n vec2 pos = a_pos_normal.xy;\n\n // x is 1 if it's a round cap, 0 otherwise\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = a_pos_normal.zw;\n v_normal = normal;\n\n // these transformations used to be applied in the JS and native code bases.\n // moved them into the shader for clarity and simplicity.\n gapwidth = gapwidth / 2.0;\n float halfwidth = width / 2.0;\n offset = -1.0 * offset;\n\n float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist = outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);\n gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;\n\n // calculate how much the perspective view squishes or stretches the extrude\n float extrude_length_without_perspective = length(dist);\n float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);\n v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n\n v_linesofar = a_linesofar;\n v_width2 = vec2(outset, inset);\n}\n"},lineSDF:{fragmentSource:"\nuniform sampler2D u_image;\nuniform float u_sdfgamma;\nuniform float u_mix;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying vec2 v_tex_a;\nvarying vec2 v_tex_b;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float width\n#pragma mapbox: define lowp float floorwidth\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize mediump float width\n #pragma mapbox: initialize lowp float floorwidth\n\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_width2.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_width2.t) or when fading out\n // (v_width2.s)\n float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;\n float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n\n float sdfdist_a = texture2D(u_image, v_tex_a).a;\n float sdfdist_b = texture2D(u_image, v_tex_b).a;\n float sdfdist = mix(sdfdist_a, sdfdist_b, u_mix);\n alpha *= smoothstep(0.5 - u_sdfgamma / floorwidth, 0.5 + u_sdfgamma / floorwidth, sdfdist);\n\n gl_FragColor = color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\n// We scale the distance before adding it to the buffers so that we can store\n// long distances for long segments. Use this value to unscale the distance.\n#define LINE_DISTANCE_SCALE 2.0\n\n// the distance over which the line edge fades out.\n// Retina devices need a smaller distance to avoid aliasing.\n#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0\n\nattribute vec4 a_pos_normal;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform vec2 u_patternscale_a;\nuniform float u_tex_y_a;\nuniform vec2 u_patternscale_b;\nuniform float u_tex_y_b;\nuniform vec2 u_gl_units_to_pixels;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying vec2 v_tex_a;\nvarying vec2 v_tex_b;\nvarying float v_gamma_scale;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float width\n#pragma mapbox: define lowp float floorwidth\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize mediump float gapwidth\n #pragma mapbox: initialize lowp float offset\n #pragma mapbox: initialize mediump float width\n #pragma mapbox: initialize lowp float floorwidth\n\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;\n\n vec2 pos = a_pos_normal.xy;\n\n // x is 1 if it's a round cap, 0 otherwise\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = a_pos_normal.zw;\n v_normal = normal;\n\n // these transformations used to be applied in the JS and native code bases.\n // moved them into the shader for clarity and simplicity.\n gapwidth = gapwidth / 2.0;\n float halfwidth = width / 2.0;\n offset = -1.0 * offset;\n\n float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist =outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);\n gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;\n\n // calculate how much the perspective view squishes or stretches the extrude\n float extrude_length_without_perspective = length(dist);\n float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);\n v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n\n v_tex_a = vec2(a_linesofar * u_patternscale_a.x / floorwidth, normal.y * u_patternscale_a.y + u_tex_y_a);\n v_tex_b = vec2(a_linesofar * u_patternscale_b.x / floorwidth, normal.y * u_patternscale_b.y + u_tex_y_b);\n\n v_width2 = vec2(outset, inset);\n}\n"},raster:{fragmentSource:"uniform float u_fade_t;\nuniform float u_opacity;\nuniform sampler2D u_image0;\nuniform sampler2D u_image1;\nvarying vec2 v_pos0;\nvarying vec2 v_pos1;\n\nuniform float u_brightness_low;\nuniform float u_brightness_high;\n\nuniform float u_saturation_factor;\nuniform float u_contrast_factor;\nuniform vec3 u_spin_weights;\n\nvoid main() {\n\n // read and cross-fade colors from the main and parent tiles\n vec4 color0 = texture2D(u_image0, v_pos0);\n vec4 color1 = texture2D(u_image1, v_pos1);\n if (color0.a > 0.0) {\n color0.rgb = color0.rgb / color0.a;\n }\n if (color1.a > 0.0) {\n color1.rgb = color1.rgb / color1.a;\n }\n vec4 color = mix(color0, color1, u_fade_t);\n color.a *= u_opacity;\n vec3 rgb = color.rgb;\n\n // spin\n rgb = vec3(\n dot(rgb, u_spin_weights.xyz),\n dot(rgb, u_spin_weights.zxy),\n dot(rgb, u_spin_weights.yzx));\n\n // saturation\n float average = (color.r + color.g + color.b) / 3.0;\n rgb += (average - rgb) * u_saturation_factor;\n\n // contrast\n rgb = (rgb - 0.5) * u_contrast_factor + 0.5;\n\n // brightness\n vec3 u_high_vec = vec3(u_brightness_low, u_brightness_low, u_brightness_low);\n vec3 u_low_vec = vec3(u_brightness_high, u_brightness_high, u_brightness_high);\n\n gl_FragColor = vec4(mix(u_high_vec, u_low_vec, rgb) * color.a, color.a);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"uniform mat4 u_matrix;\nuniform vec2 u_tl_parent;\nuniform float u_scale_parent;\nuniform float u_buffer_scale;\n\nattribute vec2 a_pos;\nattribute vec2 a_texture_pos;\n\nvarying vec2 v_pos0;\nvarying vec2 v_pos1;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n // We are using Int16 for texture position coordinates to give us enough precision for\n // fractional coordinates. We use 8192 to scale the texture coordinates in the buffer\n // as an arbitrarily high number to preserve adequate precision when rendering.\n // This is also the same value as the EXTENT we are using for our tile buffer pos coordinates,\n // so math for modifying either is consistent.\n v_pos0 = (((a_texture_pos / 8192.0) - 0.5) / u_buffer_scale ) + 0.5;\n v_pos1 = (v_pos0 * u_scale_parent) + u_tl_parent;\n}\n"},symbolIcon:{fragmentSource:"uniform sampler2D u_texture;\n\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_tex;\nvarying float v_fade_opacity;\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n lowp float alpha = opacity * v_fade_opacity;\n gl_FragColor = texture2D(u_texture, v_tex) * alpha;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"const float PI = 3.141592653589793;\n\nattribute vec4 a_pos_offset;\nattribute vec4 a_data;\nattribute vec3 a_projected_pos;\nattribute float a_fade_opacity;\n\nuniform bool u_is_size_zoom_constant;\nuniform bool u_is_size_feature_constant;\nuniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function\nuniform highp float u_size; // used when size is both zoom and feature constant\nuniform highp float u_camera_to_center_distance;\nuniform highp float u_pitch;\nuniform bool u_rotate_symbol;\nuniform highp float u_aspect_ratio;\nuniform float u_fade_change;\n\n#pragma mapbox: define lowp float opacity\n\nuniform mat4 u_matrix;\nuniform mat4 u_label_plane_matrix;\nuniform mat4 u_gl_coord_matrix;\n\nuniform bool u_is_text;\nuniform bool u_pitch_with_map;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_tex;\nvarying float v_fade_opacity;\n\nvoid main() {\n #pragma mapbox: initialize lowp float opacity\n\n vec2 a_pos = a_pos_offset.xy;\n vec2 a_offset = a_pos_offset.zw;\n\n vec2 a_tex = a_data.xy;\n vec2 a_size = a_data.zw;\n\n highp float segment_angle = -a_projected_pos[2];\n\n float size;\n if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {\n size = mix(a_size[0], a_size[1], u_size_t) / 10.0;\n } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {\n size = a_size[0] / 10.0;\n } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {\n size = u_size;\n } else {\n size = u_size;\n }\n\n vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1);\n highp float camera_to_anchor_distance = projectedPoint.w;\n // See comments in symbol_sdf.vertex\n highp float distance_ratio = u_pitch_with_map ?\n camera_to_anchor_distance / u_camera_to_center_distance :\n u_camera_to_center_distance / camera_to_anchor_distance;\n highp float perspective_ratio = clamp(\n 0.5 + 0.5 * distance_ratio,\n 0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles\n 4.0);\n\n size *= perspective_ratio;\n\n float fontScale = u_is_text ? size / 24.0 : size;\n\n highp float symbol_rotation = 0.0;\n if (u_rotate_symbol) {\n // See comments in symbol_sdf.vertex\n vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1);\n\n vec2 a = projectedPoint.xy / projectedPoint.w;\n vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w;\n\n symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);\n }\n\n highp float angle_sin = sin(segment_angle + symbol_rotation);\n highp float angle_cos = cos(segment_angle + symbol_rotation);\n mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);\n\n vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0);\n gl_Position = u_gl_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), 0.0, 1.0);\n\n v_tex = a_tex / u_texsize;\n vec2 fade_opacity = unpack_opacity(a_fade_opacity);\n float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change;\n v_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change));\n}\n"},symbolSDF:{fragmentSource:"#define SDF_PX 8.0\n#define EDGE_GAMMA 0.105/DEVICE_PIXEL_RATIO\n\nuniform bool u_is_halo;\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\n\nuniform sampler2D u_texture;\nuniform highp float u_gamma_scale;\nuniform bool u_is_text;\n\nvarying vec2 v_data0;\nvarying vec3 v_data1;\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 fill_color\n #pragma mapbox: initialize highp vec4 halo_color\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize lowp float halo_width\n #pragma mapbox: initialize lowp float halo_blur\n\n vec2 tex = v_data0.xy;\n float gamma_scale = v_data1.x;\n float size = v_data1.y;\n float fade_opacity = v_data1[2];\n\n float fontScale = u_is_text ? size / 24.0 : size;\n\n lowp vec4 color = fill_color;\n highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale);\n lowp float buff = (256.0 - 64.0) / 256.0;\n if (u_is_halo) {\n color = halo_color;\n gamma = (halo_blur * 1.19 / SDF_PX + EDGE_GAMMA) / (fontScale * u_gamma_scale);\n buff = (6.0 - halo_width / fontScale) / SDF_PX;\n }\n\n lowp float dist = texture2D(u_texture, tex).a;\n highp float gamma_scaled = gamma * gamma_scale;\n highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);\n\n gl_FragColor = color * (alpha * opacity * fade_opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n",vertexSource:"const float PI = 3.141592653589793;\n\nattribute vec4 a_pos_offset;\nattribute vec4 a_data;\nattribute vec3 a_projected_pos;\nattribute float a_fade_opacity;\n\n// contents of a_size vary based on the type of property value\n// used for {text,icon}-size.\n// For constants, a_size is disabled.\n// For source functions, we bind only one value per vertex: the value of {text,icon}-size evaluated for the current feature.\n// For composite functions:\n// [ text-size(lowerZoomStop, feature),\n// text-size(upperZoomStop, feature) ]\nuniform bool u_is_size_zoom_constant;\nuniform bool u_is_size_feature_constant;\nuniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function\nuniform highp float u_size; // used when size is both zoom and feature constant\n\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\n\nuniform mat4 u_matrix;\nuniform mat4 u_label_plane_matrix;\nuniform mat4 u_gl_coord_matrix;\n\nuniform bool u_is_text;\nuniform bool u_pitch_with_map;\nuniform highp float u_pitch;\nuniform bool u_rotate_symbol;\nuniform highp float u_aspect_ratio;\nuniform highp float u_camera_to_center_distance;\nuniform float u_fade_change;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_data0;\nvarying vec3 v_data1;\n\nvoid main() {\n #pragma mapbox: initialize highp vec4 fill_color\n #pragma mapbox: initialize highp vec4 halo_color\n #pragma mapbox: initialize lowp float opacity\n #pragma mapbox: initialize lowp float halo_width\n #pragma mapbox: initialize lowp float halo_blur\n\n vec2 a_pos = a_pos_offset.xy;\n vec2 a_offset = a_pos_offset.zw;\n\n vec2 a_tex = a_data.xy;\n vec2 a_size = a_data.zw;\n\n highp float segment_angle = -a_projected_pos[2];\n float size;\n\n if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {\n size = mix(a_size[0], a_size[1], u_size_t) / 10.0;\n } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {\n size = a_size[0] / 10.0;\n } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {\n size = u_size;\n } else {\n size = u_size;\n }\n\n vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1);\n highp float camera_to_anchor_distance = projectedPoint.w;\n // If the label is pitched with the map, layout is done in pitched space,\n // which makes labels in the distance smaller relative to viewport space.\n // We counteract part of that effect by multiplying by the perspective ratio.\n // If the label isn't pitched with the map, we do layout in viewport space,\n // which makes labels in the distance larger relative to the features around\n // them. We counteract part of that effect by dividing by the perspective ratio.\n highp float distance_ratio = u_pitch_with_map ?\n camera_to_anchor_distance / u_camera_to_center_distance :\n u_camera_to_center_distance / camera_to_anchor_distance;\n highp float perspective_ratio = clamp(\n 0.5 + 0.5 * distance_ratio,\n 0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles\n 4.0);\n\n size *= perspective_ratio;\n\n float fontScale = u_is_text ? size / 24.0 : size;\n\n highp float symbol_rotation = 0.0;\n if (u_rotate_symbol) {\n // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units\n // To figure out that angle in projected space, we draw a short horizontal line in tile\n // space, project it, and measure its angle in projected space.\n vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1);\n\n vec2 a = projectedPoint.xy / projectedPoint.w;\n vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w;\n\n symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);\n }\n\n highp float angle_sin = sin(segment_angle + symbol_rotation);\n highp float angle_cos = cos(segment_angle + symbol_rotation);\n mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);\n\n vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0);\n gl_Position = u_gl_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), 0.0, 1.0);\n float gamma_scale = gl_Position.w;\n\n vec2 tex = a_tex / u_texsize;\n vec2 fade_opacity = unpack_opacity(a_fade_opacity);\n float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change;\n float interpolated_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change));\n\n v_data0 = vec2(tex.x, tex.y);\n v_data1 = vec3(gamma_scale, size, interpolated_fade_opacity);\n}\n"}},tr=/#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g,er=function(t){var e=Qe[t],r={};e.fragmentSource=e.fragmentSource.replace(tr,function(t,e,n,i,a){return r[a]=!0,"define"===e?"\n#ifndef HAS_UNIFORM_u_"+a+"\nvarying "+n+" "+i+" "+a+";\n#else\nuniform "+n+" "+i+" u_"+a+";\n#endif\n":"\n#ifdef HAS_UNIFORM_u_"+a+"\n "+n+" "+i+" "+a+" = u_"+a+";\n#endif\n"}),e.vertexSource=e.vertexSource.replace(tr,function(t,e,n,i,a){var o="float"===i?"vec2":"vec4";return r[a]?"define"===e?"\n#ifndef HAS_UNIFORM_u_"+a+"\nuniform lowp float a_"+a+"_t;\nattribute "+n+" "+o+" a_"+a+";\nvarying "+n+" "+i+" "+a+";\n#else\nuniform "+n+" "+i+" u_"+a+";\n#endif\n":"\n#ifndef HAS_UNIFORM_u_"+a+"\n "+a+" = unpack_mix_"+o+"(a_"+a+", a_"+a+"_t);\n#else\n "+n+" "+i+" "+a+" = u_"+a+";\n#endif\n":"define"===e?"\n#ifndef HAS_UNIFORM_u_"+a+"\nuniform lowp float a_"+a+"_t;\nattribute "+n+" "+o+" a_"+a+";\n#else\nuniform "+n+" "+i+" u_"+a+";\n#endif\n":"\n#ifndef HAS_UNIFORM_u_"+a+"\n "+n+" "+i+" "+a+" = unpack_mix_"+o+"(a_"+a+", a_"+a+"_t);\n#else\n "+n+" "+i+" "+a+" = u_"+a+";\n#endif\n"})};for(var rr in Qe)er(rr);var nr=Qe,ir=function(t,e,r,n){var i=t.gl;this.program=i.createProgram();var o=r.defines().concat("#define DEVICE_PIXEL_RATIO "+a.devicePixelRatio.toFixed(1));n&&o.push("#define OVERDRAW_INSPECTOR;");var s=o.concat(nr.prelude.fragmentSource,e.fragmentSource).join("\n"),l=o.concat(nr.prelude.vertexSource,e.vertexSource).join("\n"),c=i.createShader(i.FRAGMENT_SHADER);i.shaderSource(c,s),i.compileShader(c),i.attachShader(this.program,c);var u=i.createShader(i.VERTEX_SHADER);i.shaderSource(u,l),i.compileShader(u),i.attachShader(this.program,u);for(var h=r.layoutAttributes||[],f=0;f>16,s>>16),n.uniform2f(r.uniforms.u_pixel_coord_lower,65535&o,65535&s)};function vr(t,e,r,n,i){if(!dr(r.paint.get("fill-pattern"),t))for(var a=!0,o=0,s=n;o0){var l=a.now(),c=(l-e.timeAdded)/s,u=r?(l-r.timeAdded)/s:-1,h=n.getSource(),f=o.coveringZoomLevel({tileSize:h.tileSize,roundZoom:h.roundZoom}),p=!r||Math.abs(r.tileID.overscaledZ-f)>Math.abs(e.tileID.overscaledZ-f),d=p&&e.refreshedUponExpiration?1:t.clamp(p?c:1-u,0,1);return e.refreshedUponExpiration&&c>=1&&(e.refreshedUponExpiration=!1),r?{opacity:1,mix:1-d}:{opacity:d,mix:0}}return{opacity:1,mix:0}}function Er(e,r,n){var i=e.context,o=i.gl;i.lineWidth.set(1*a.devicePixelRatio);var s=n.posMatrix,l=e.useProgram("debug");i.setDepthMode(qt.disabled),i.setStencilMode(Ht.disabled),i.setColorMode(e.colorModeForRenderPass()),o.uniformMatrix4fv(l.uniforms.u_matrix,!1,s),o.uniform4f(l.uniforms.u_color,1,0,0,1),e.debugVAO.bind(i,l,e.debugBuffer,[]),o.drawArrays(o.LINE_STRIP,0,e.debugBuffer.length);for(var c=function(t,e,r,n){n=n||1;var i,a,o,s,l,c,u,h,f=[];for(i=0,a=t.length;i":[24,[4,18,20,9,4,0]],"?":[18,[3,16,3,17,4,19,5,20,7,21,11,21,13,20,14,19,15,17,15,15,14,13,13,12,9,10,9,7,-1,-1,9,2,8,1,9,0,10,1,9,2]],"@":[27,[18,13,17,15,15,16,12,16,10,15,9,14,8,11,8,8,9,6,11,5,14,5,16,6,17,8,-1,-1,12,16,10,14,9,11,9,8,10,6,11,5,-1,-1,18,16,17,8,17,6,19,5,21,5,23,7,24,10,24,12,23,15,22,17,20,19,18,20,15,21,12,21,9,20,7,19,5,17,4,15,3,12,3,9,4,6,5,4,7,2,9,1,12,0,15,0,18,1,20,2,21,3,-1,-1,19,16,18,8,18,6,19,5]],A:[18,[9,21,1,0,-1,-1,9,21,17,0,-1,-1,4,7,14,7]],B:[21,[4,21,4,0,-1,-1,4,21,13,21,16,20,17,19,18,17,18,15,17,13,16,12,13,11,-1,-1,4,11,13,11,16,10,17,9,18,7,18,4,17,2,16,1,13,0,4,0]],C:[21,[18,16,17,18,15,20,13,21,9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5]],D:[21,[4,21,4,0,-1,-1,4,21,11,21,14,20,16,18,17,16,18,13,18,8,17,5,16,3,14,1,11,0,4,0]],E:[19,[4,21,4,0,-1,-1,4,21,17,21,-1,-1,4,11,12,11,-1,-1,4,0,17,0]],F:[18,[4,21,4,0,-1,-1,4,21,17,21,-1,-1,4,11,12,11]],G:[21,[18,16,17,18,15,20,13,21,9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,18,8,-1,-1,13,8,18,8]],H:[22,[4,21,4,0,-1,-1,18,21,18,0,-1,-1,4,11,18,11]],I:[8,[4,21,4,0]],J:[16,[12,21,12,5,11,2,10,1,8,0,6,0,4,1,3,2,2,5,2,7]],K:[21,[4,21,4,0,-1,-1,18,21,4,7,-1,-1,9,12,18,0]],L:[17,[4,21,4,0,-1,-1,4,0,16,0]],M:[24,[4,21,4,0,-1,-1,4,21,12,0,-1,-1,20,21,12,0,-1,-1,20,21,20,0]],N:[22,[4,21,4,0,-1,-1,4,21,18,0,-1,-1,18,21,18,0]],O:[22,[9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,19,8,19,13,18,16,17,18,15,20,13,21,9,21]],P:[21,[4,21,4,0,-1,-1,4,21,13,21,16,20,17,19,18,17,18,14,17,12,16,11,13,10,4,10]],Q:[22,[9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,19,8,19,13,18,16,17,18,15,20,13,21,9,21,-1,-1,12,4,18,-2]],R:[21,[4,21,4,0,-1,-1,4,21,13,21,16,20,17,19,18,17,18,15,17,13,16,12,13,11,4,11,-1,-1,11,11,18,0]],S:[20,[17,18,15,20,12,21,8,21,5,20,3,18,3,16,4,14,5,13,7,12,13,10,15,9,16,8,17,6,17,3,15,1,12,0,8,0,5,1,3,3]],T:[16,[8,21,8,0,-1,-1,1,21,15,21]],U:[22,[4,21,4,6,5,3,7,1,10,0,12,0,15,1,17,3,18,6,18,21]],V:[18,[1,21,9,0,-1,-1,17,21,9,0]],W:[24,[2,21,7,0,-1,-1,12,21,7,0,-1,-1,12,21,17,0,-1,-1,22,21,17,0]],X:[20,[3,21,17,0,-1,-1,17,21,3,0]],Y:[18,[1,21,9,11,9,0,-1,-1,17,21,9,11]],Z:[20,[17,21,3,0,-1,-1,3,21,17,21,-1,-1,3,0,17,0]],"[":[14,[4,25,4,-7,-1,-1,5,25,5,-7,-1,-1,4,25,11,25,-1,-1,4,-7,11,-7]],"\\":[14,[0,21,14,-3]],"]":[14,[9,25,9,-7,-1,-1,10,25,10,-7,-1,-1,3,25,10,25,-1,-1,3,-7,10,-7]],"^":[16,[6,15,8,18,10,15,-1,-1,3,12,8,17,13,12,-1,-1,8,17,8,0]],_:[16,[0,-2,16,-2]],"`":[10,[6,21,5,20,4,18,4,16,5,15,6,16,5,17]],a:[19,[15,14,15,0,-1,-1,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],b:[19,[4,21,4,0,-1,-1,4,11,6,13,8,14,11,14,13,13,15,11,16,8,16,6,15,3,13,1,11,0,8,0,6,1,4,3]],c:[18,[15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],d:[19,[15,21,15,0,-1,-1,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],e:[18,[3,8,15,8,15,10,14,12,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],f:[12,[10,21,8,21,6,20,5,17,5,0,-1,-1,2,14,9,14]],g:[19,[15,14,15,-2,14,-5,13,-6,11,-7,8,-7,6,-6,-1,-1,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],h:[19,[4,21,4,0,-1,-1,4,10,7,13,9,14,12,14,14,13,15,10,15,0]],i:[8,[3,21,4,20,5,21,4,22,3,21,-1,-1,4,14,4,0]],j:[10,[5,21,6,20,7,21,6,22,5,21,-1,-1,6,14,6,-3,5,-6,3,-7,1,-7]],k:[17,[4,21,4,0,-1,-1,14,14,4,4,-1,-1,8,8,15,0]],l:[8,[4,21,4,0]],m:[30,[4,14,4,0,-1,-1,4,10,7,13,9,14,12,14,14,13,15,10,15,0,-1,-1,15,10,18,13,20,14,23,14,25,13,26,10,26,0]],n:[19,[4,14,4,0,-1,-1,4,10,7,13,9,14,12,14,14,13,15,10,15,0]],o:[19,[8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3,16,6,16,8,15,11,13,13,11,14,8,14]],p:[19,[4,14,4,-7,-1,-1,4,11,6,13,8,14,11,14,13,13,15,11,16,8,16,6,15,3,13,1,11,0,8,0,6,1,4,3]],q:[19,[15,14,15,-7,-1,-1,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3]],r:[13,[4,14,4,0,-1,-1,4,8,5,11,7,13,9,14,12,14]],s:[17,[14,11,13,13,10,14,7,14,4,13,3,11,4,9,6,8,11,7,13,6,14,4,14,3,13,1,10,0,7,0,4,1,3,3]],t:[12,[5,21,5,4,6,1,8,0,10,0,-1,-1,2,14,9,14]],u:[19,[4,14,4,4,5,1,7,0,10,0,12,1,15,4,-1,-1,15,14,15,0]],v:[16,[2,14,8,0,-1,-1,14,14,8,0]],w:[22,[3,14,7,0,-1,-1,11,14,7,0,-1,-1,11,14,15,0,-1,-1,19,14,15,0]],x:[17,[3,14,14,0,-1,-1,14,14,3,0]],y:[16,[2,14,8,0,-1,-1,14,14,8,0,6,-4,4,-6,2,-7,1,-7]],z:[17,[14,14,3,0,-1,-1,3,14,14,14,-1,-1,3,0,14,0]],"{":[14,[9,25,7,24,6,23,5,21,5,19,6,17,7,16,8,14,8,12,6,10,-1,-1,7,24,6,22,6,20,7,18,8,17,9,15,9,13,8,11,4,9,8,7,9,5,9,3,8,1,7,0,6,-2,6,-4,7,-6,-1,-1,6,8,8,6,8,4,7,2,6,1,5,-1,5,-3,6,-5,7,-6,9,-7]],"|":[8,[4,25,4,-7]],"}":[14,[5,25,7,24,8,23,9,21,9,19,8,17,7,16,6,14,6,12,8,10,-1,-1,7,24,8,22,8,20,7,18,6,17,5,15,5,13,6,11,10,9,6,7,5,5,5,3,6,1,7,0,8,-2,8,-4,7,-6,-1,-1,8,8,6,6,6,4,7,2,8,1,9,-1,9,-3,8,-5,7,-6,5,-7]],"~":[24,[3,6,3,8,4,11,6,12,8,12,10,11,14,8,16,7,18,7,20,8,21,10,-1,-1,3,8,4,10,6,11,8,11,10,10,14,7,16,6,18,6,20,7,21,10,21,12]]},Lr={symbol:function(t,e,r,n){if("translucent"===t.renderPass){var i=t.context;i.setStencilMode(Ht.disabled),i.setColorMode(t.colorModeForRenderPass()),0!==r.paint.get("icon-opacity").constantOr(1)&&cr(t,e,r,n,!1,r.paint.get("icon-translate"),r.paint.get("icon-translate-anchor"),r.layout.get("icon-rotation-alignment"),r.layout.get("icon-pitch-alignment"),r.layout.get("icon-keep-upright")),0!==r.paint.get("text-opacity").constantOr(1)&&cr(t,e,r,n,!0,r.paint.get("text-translate"),r.paint.get("text-translate-anchor"),r.layout.get("text-rotation-alignment"),r.layout.get("text-pitch-alignment"),r.layout.get("text-keep-upright")),e.map.showCollisionBoxes&&function(t,e,r,n){or(t,e,r,n,!1),or(t,e,r,n,!0)}(t,e,r,n)}},circle:function(t,e,r,n){if("translucent"===t.renderPass){var i=r.paint.get("circle-opacity"),a=r.paint.get("circle-stroke-width"),o=r.paint.get("circle-stroke-opacity");if(0!==i.constantOr(1)||0!==a.constantOr(1)&&0!==o.constantOr(1)){var s=t.context,l=s.gl;s.setDepthMode(t.depthModeForSublayer(0,qt.ReadOnly)),s.setStencilMode(Ht.disabled),s.setColorMode(t.colorModeForRenderPass());for(var c=!0,u=0;u0?1-1/(1.001-i):-i),s.uniform1f(c.uniforms.u_contrast_factor,(a=r.paint.get("raster-contrast"))>0?1/(1-a):1+a),s.uniform3fv(c.uniforms.u_spin_weights,function(t){t*=Math.PI/180;var e=Math.sin(t),r=Math.cos(t);return[(2*r+1)/3,(-Math.sqrt(3)*e-r+1)/3,(Math.sqrt(3)*e-r+1)/3]}(r.paint.get("raster-hue-rotate"))),s.uniform1f(c.uniforms.u_buffer_scale,1),s.uniform1i(c.uniforms.u_image0,0),s.uniform1i(c.uniforms.u_image1,1);for(var u=n.length&&n[0].overscaledZ,h=0,f=n;he.row){var r=t;t=e,e=r}return{x0:t.column,y0:t.row,x1:e.column,y1:e.row,dx:e.column-t.column,dy:e.row-t.row}}function Ir(t,e,r,n,i){var a=Math.max(r,Math.floor(e.y0)),o=Math.min(n,Math.ceil(e.y1));if(t.x0===e.x0&&t.y0===e.y0?t.x0+e.dy/t.dy*t.dx0,h=e.dx<0,f=a;fl.dy&&(o=s,s=l,l=o),s.dy>c.dy&&(o=s,s=c,c=o),l.dy>c.dy&&(o=l,l=c,c=o),s.dy&&Ir(c,s,n,i,a),l.dy&&Ir(c,l,n,i,a)}zr.prototype.resize=function(t,e){var r=this.context.gl;if(this.width=t*a.devicePixelRatio,this.height=e*a.devicePixelRatio,this.context.viewport.set([0,0,this.width,this.height]),this.style)for(var n=0,i=this.style._order;n=0;this.currentLayer--){var v=n.style._layers[s[n.currentLayer]];v.source!==(g&&g.id)&&(m=[],(g=n.style.sourceCaches[v.source])&&(n.clearStencil(),m=g.getVisibleCoordinates(),g.getSource().isTileClipped&&n._renderTileClippingMasks(m))),n.renderLayer(n,g,v,m)}this.renderPass="translucent";var y,x=[];for(this.currentLayer=0,this.currentLayer;this.currentLayer0?e.pop():null},zr.prototype._createProgramCached=function(t,e){this.cache=this.cache||{};var r=""+t+(e.cacheKey||"")+(this._showOverdrawInspector?"/overdraw":"");return this.cache[r]||(this.cache[r]=new ir(this.context,nr[t],e,this._showOverdrawInspector)),this.cache[r]},zr.prototype.useProgram=function(t,e){var r=this._createProgramCached(t,e||this.emptyProgramConfiguration);return this.context.program.set(r.program),r};var Dr=t.default$20.vec4,Rr=t.default$20.mat4,Br=t.default$20.mat2,Fr=function(t,e,r){this.tileSize=512,this._renderWorldCopies=void 0===r||r,this._minZoom=t||0,this._maxZoom=e||22,this.latRange=[-85.05113,85.05113],this.width=0,this.height=0,this._center=new G(0,0),this.zoom=0,this.angle=0,this._fov=.6435011087932844,this._pitch=0,this._unmodified=!0,this._posMatrixCache={},this._alignedPosMatrixCache={}},Nr={minZoom:{configurable:!0},maxZoom:{configurable:!0},renderWorldCopies:{configurable:!0},worldSize:{configurable:!0},centerPoint:{configurable:!0},size:{configurable:!0},bearing:{configurable:!0},pitch:{configurable:!0},fov:{configurable:!0},zoom:{configurable:!0},center:{configurable:!0},unmodified:{configurable:!0},x:{configurable:!0},y:{configurable:!0},point:{configurable:!0}};Fr.prototype.clone=function(){var t=new Fr(this._minZoom,this._maxZoom,this._renderWorldCopies);return t.tileSize=this.tileSize,t.latRange=this.latRange,t.width=this.width,t.height=this.height,t._center=this._center,t.zoom=this.zoom,t.angle=this.angle,t._fov=this._fov,t._pitch=this._pitch,t._unmodified=this._unmodified,t._calcMatrices(),t},Nr.minZoom.get=function(){return this._minZoom},Nr.minZoom.set=function(t){this._minZoom!==t&&(this._minZoom=t,this.zoom=Math.max(this.zoom,t))},Nr.maxZoom.get=function(){return this._maxZoom},Nr.maxZoom.set=function(t){this._maxZoom!==t&&(this._maxZoom=t,this.zoom=Math.min(this.zoom,t))},Nr.renderWorldCopies.get=function(){return this._renderWorldCopies},Nr.renderWorldCopies.set=function(t){void 0===t?t=!0:null===t&&(t=!1),this._renderWorldCopies=t},Nr.worldSize.get=function(){return this.tileSize*this.scale},Nr.centerPoint.get=function(){return this.size._div(2)},Nr.size.get=function(){return new t.default$1(this.width,this.height)},Nr.bearing.get=function(){return-this.angle/Math.PI*180},Nr.bearing.set=function(e){var r=-t.wrap(e,-180,180)*Math.PI/180;this.angle!==r&&(this._unmodified=!1,this.angle=r,this._calcMatrices(),this.rotationMatrix=Br.create(),Br.rotate(this.rotationMatrix,this.rotationMatrix,this.angle))},Nr.pitch.get=function(){return this._pitch/Math.PI*180},Nr.pitch.set=function(e){var r=t.clamp(e,0,60)/180*Math.PI;this._pitch!==r&&(this._unmodified=!1,this._pitch=r,this._calcMatrices())},Nr.fov.get=function(){return this._fov/Math.PI*180},Nr.fov.set=function(t){t=Math.max(.01,Math.min(60,t)),this._fov!==t&&(this._unmodified=!1,this._fov=t/180*Math.PI,this._calcMatrices())},Nr.zoom.get=function(){return this._zoom},Nr.zoom.set=function(t){var e=Math.min(Math.max(t,this.minZoom),this.maxZoom);this._zoom!==e&&(this._unmodified=!1,this._zoom=e,this.scale=this.zoomScale(e),this.tileZoom=Math.floor(e),this.zoomFraction=e-this.tileZoom,this._constrain(),this._calcMatrices())},Nr.center.get=function(){return this._center},Nr.center.set=function(t){t.lat===this._center.lat&&t.lng===this._center.lng||(this._unmodified=!1,this._center=t,this._constrain(),this._calcMatrices())},Fr.prototype.coveringZoomLevel=function(t){return(t.roundZoom?Math.round:Math.floor)(this.zoom+this.scaleZoom(this.tileSize/t.tileSize))},Fr.prototype.getVisibleUnwrappedCoordinates=function(e){var r=this.pointCoordinate(new t.default$1(0,0),0),n=this.pointCoordinate(new t.default$1(this.width,0),0),i=Math.floor(r.column),a=Math.floor(n.column),o=[new t.UnwrappedTileID(0,e)];if(this._renderWorldCopies)for(var s=i;s<=a;s++)0!==s&&o.push(new t.UnwrappedTileID(s,e));return o},Fr.prototype.coveringTiles=function(e){var r=this.coveringZoomLevel(e),n=r;if(void 0!==e.minzoom&&re.maxzoom&&(r=e.maxzoom);var i=this.pointCoordinate(this.centerPoint,r),a=new t.default$1(i.column-.5,i.row-.5);return function(e,r,n,i){void 0===i&&(i=!0);var a=1<=0&&l<=a)for(c=r;co&&(i=o-g)}if(this.lngRange){var m=this.x,v=c.x/2;m-vl&&(n=l-v)}void 0===n&&void 0===i||(this.center=this.unproject(new t.default$1(void 0!==n?n:this.x,void 0!==i?i:this.y))),this._unmodified=u,this._constraining=!1}},Fr.prototype._calcMatrices=function(){if(this.height){this.cameraToCenterDistance=.5/Math.tan(this._fov/2)*this.height;var t=this._fov/2,e=Math.PI/2+this._pitch,r=Math.sin(t)*this.cameraToCenterDistance/Math.sin(Math.PI-e-t),n=this.x,i=this.y,a=1.01*(Math.cos(Math.PI/2-this._pitch)*r+this.cameraToCenterDistance),o=new Float64Array(16);Rr.perspective(o,this._fov,this.width/this.height,1,a),Rr.scale(o,o,[1,-1,1]),Rr.translate(o,o,[0,0,-this.cameraToCenterDistance]),Rr.rotateX(o,o,this._pitch),Rr.rotateZ(o,o,this.angle),Rr.translate(o,o,[-n,-i,0]);var s=this.worldSize/(2*Math.PI*6378137*Math.abs(Math.cos(this.center.lat*(Math.PI/180))));Rr.scale(o,o,[1,1,s,1]),this.projMatrix=o;var l=this.width%2/2,c=this.height%2/2,u=Math.cos(this.angle),h=Math.sin(this.angle),f=n-Math.round(n)+u*l+h*c,p=i-Math.round(i)+u*c+h*l,d=new Float64Array(o);if(Rr.translate(d,d,[f>.5?f-1:f,p>.5?p-1:p,0]),this.alignedProjMatrix=d,o=Rr.create(),Rr.scale(o,o,[this.width/2,-this.height/2,1]),Rr.translate(o,o,[1,-1,0]),this.pixelMatrix=Rr.multiply(new Float64Array(16),o,this.projMatrix),!(o=Rr.invert(new Float64Array(16),this.pixelMatrix)))throw new Error("failed to invert matrix");this.pixelMatrixInverse=o,this._posMatrixCache={},this._alignedPosMatrixCache={}}},Fr.prototype.maxPitchScaleFactor=function(){if(!this.pixelMatrixInverse)return 1;var e=this.pointCoordinate(new t.default$1(0,0)).zoomTo(this.zoom),r=[e.column*this.tileSize,e.row*this.tileSize,0,1];return Dr.transformMat4(r,r,this.pixelMatrix)[3]/this.cameraToCenterDistance},Object.defineProperties(Fr.prototype,Nr);var jr=function(){var e,r,n,i;t.bindAll(["_onHashChange","_updateHash"],this),this._updateHash=(e=this._updateHashUnthrottled.bind(this),300,r=!1,n=0,i=function(){n=0,r&&(e(),n=setTimeout(i,300),r=!1)},function(){return r=!0,n||i(),n})};jr.prototype.addTo=function(e){return this._map=e,t.default.addEventListener("hashchange",this._onHashChange,!1),this._map.on("moveend",this._updateHash),this},jr.prototype.remove=function(){return t.default.removeEventListener("hashchange",this._onHashChange,!1),this._map.off("moveend",this._updateHash),clearTimeout(this._updateHash()),delete this._map,this},jr.prototype.getHashString=function(t){var e=this._map.getCenter(),r=Math.round(100*this._map.getZoom())/100,n=Math.ceil((r*Math.LN2+Math.log(512/360/.5))/Math.LN10),i=Math.pow(10,n),a=Math.round(e.lng*i)/i,o=Math.round(e.lat*i)/i,s=this._map.getBearing(),l=this._map.getPitch(),c="";return c+=t?"#/"+a+"/"+o+"/"+r:"#"+r+"/"+o+"/"+a,(s||l)&&(c+="/"+Math.round(10*s)/10),l&&(c+="/"+Math.round(l)),c},jr.prototype._onHashChange=function(){var e=t.default.location.hash.replace("#","").split("/");return e.length>=3&&(this._map.jumpTo({center:[+e[2],+e[1]],zoom:+e[0],bearing:+(e[3]||0),pitch:+(e[4]||0)}),!0)},jr.prototype._updateHashUnthrottled=function(){var e=this.getHashString();t.default.history.replaceState(t.default.history.state,"",e)};var Vr=function(e){function r(r,n,i,a){void 0===a&&(a={});var o=s.mousePos(n.getCanvasContainer(),i),l=n.unproject(o);e.call(this,r,t.extend({point:o,lngLat:l,originalEvent:i},a)),this._defaultPrevented=!1,this.target=n}e&&(r.__proto__=e),r.prototype=Object.create(e&&e.prototype),r.prototype.constructor=r;var n={defaultPrevented:{configurable:!0}};return r.prototype.preventDefault=function(){this._defaultPrevented=!0},n.defaultPrevented.get=function(){return this._defaultPrevented},Object.defineProperties(r.prototype,n),r}(t.Event),Ur=function(e){function r(r,n,i){var a=s.touchPos(n.getCanvasContainer(),i),o=a.map(function(t){return n.unproject(t)}),l=a.reduce(function(t,e,r,n){return t.add(e.div(n.length))},new t.default$1(0,0)),c=n.unproject(l);e.call(this,r,{points:a,point:l,lngLats:o,lngLat:c,originalEvent:i}),this._defaultPrevented=!1}e&&(r.__proto__=e),r.prototype=Object.create(e&&e.prototype),r.prototype.constructor=r;var n={defaultPrevented:{configurable:!0}};return r.prototype.preventDefault=function(){this._defaultPrevented=!0},n.defaultPrevented.get=function(){return this._defaultPrevented},Object.defineProperties(r.prototype,n),r}(t.Event),qr=function(t){function e(e,r,n){t.call(this,e,{originalEvent:n}),this._defaultPrevented=!1}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={defaultPrevented:{configurable:!0}};return e.prototype.preventDefault=function(){this._defaultPrevented=!0},r.defaultPrevented.get=function(){return this._defaultPrevented},Object.defineProperties(e.prototype,r),e}(t.Event),Hr=function(e){this._map=e,this._el=e.getCanvasContainer(),this._delta=0,t.bindAll(["_onWheel","_onTimeout","_onScrollFrame","_onScrollFinished"],this)};Hr.prototype.isEnabled=function(){return!!this._enabled},Hr.prototype.isActive=function(){return!!this._active},Hr.prototype.enable=function(t){this.isEnabled()||(this._enabled=!0,this._aroundCenter=t&&"center"===t.around)},Hr.prototype.disable=function(){this.isEnabled()&&(this._enabled=!1)},Hr.prototype.onWheel=function(e){if(this.isEnabled()){var r=e.deltaMode===t.default.WheelEvent.DOM_DELTA_LINE?40*e.deltaY:e.deltaY,n=a.now(),i=n-(this._lastWheelEventTime||0);this._lastWheelEventTime=n,0!==r&&r%4.000244140625==0?this._type="wheel":0!==r&&Math.abs(r)<4?this._type="trackpad":i>400?(this._type=null,this._lastValue=r,this._timeout=setTimeout(this._onTimeout,40,e)):this._type||(this._type=Math.abs(i*r)<200?"trackpad":"wheel",this._timeout&&(clearTimeout(this._timeout),this._timeout=null,r+=this._lastValue)),e.shiftKey&&r&&(r/=4),this._type&&(this._lastWheelEvent=e,this._delta-=r,this.isActive()||this._start(e)),e.preventDefault()}},Hr.prototype._onTimeout=function(t){this._type="wheel",this._delta-=this._lastValue,this.isActive()||this._start(t)},Hr.prototype._start=function(e){if(this._delta){this._frameId&&(this._map._cancelRenderFrame(this._frameId),this._frameId=null),this._active=!0,this._map.fire(new t.Event("movestart",{originalEvent:e})),this._map.fire(new t.Event("zoomstart",{originalEvent:e})),this._finishTimeout&&clearTimeout(this._finishTimeout);var r=s.mousePos(this._el,e);this._around=G.convert(this._aroundCenter?this._map.getCenter():this._map.unproject(r)),this._aroundPoint=this._map.transform.locationPoint(this._around),this._frameId||(this._frameId=this._map._requestRenderFrame(this._onScrollFrame))}},Hr.prototype._onScrollFrame=function(){var e=this;if(this._frameId=null,this.isActive()){var r=this._map.transform;if(0!==this._delta){var n="wheel"===this._type&&Math.abs(this._delta)>4.000244140625?1/450:.01,i=2/(1+Math.exp(-Math.abs(this._delta*n)));this._delta<0&&0!==i&&(i=1/i);var o="number"==typeof this._targetZoom?r.zoomScale(this._targetZoom):r.scale;this._targetZoom=Math.min(r.maxZoom,Math.max(r.minZoom,r.scaleZoom(o*i))),"wheel"===this._type&&(this._startZoom=r.zoom,this._easing=this._smoothOutEasing(200)),this._delta=0}var s=!1;if("wheel"===this._type){var l=Math.min((a.now()-this._lastWheelEventTime)/200,1),c=this._easing(l);r.zoom=t.number(this._startZoom,this._targetZoom,c),l<1?this._frameId||(this._frameId=this._map._requestRenderFrame(this._onScrollFrame)):s=!0}else r.zoom=this._targetZoom,s=!0;r.setLocationAtPoint(this._around,this._aroundPoint),this._map.fire(new t.Event("move",{originalEvent:this._lastWheelEvent})),this._map.fire(new t.Event("zoom",{originalEvent:this._lastWheelEvent})),s&&(this._active=!1,this._finishTimeout=setTimeout(function(){e._map.fire(new t.Event("zoomend",{originalEvent:e._lastWheelEvent})),e._map.fire(new t.Event("moveend",{originalEvent:e._lastWheelEvent})),delete e._targetZoom},200))}},Hr.prototype._smoothOutEasing=function(e){var r=t.ease;if(this._prevEase){var n=this._prevEase,i=(a.now()-n.start)/n.duration,o=n.easing(i+.01)-n.easing(i),s=.27/Math.sqrt(o*o+1e-4)*.01,l=Math.sqrt(.0729-s*s);r=t.bezier(s,l,.25,1)}return this._prevEase={start:a.now(),duration:e,easing:r},r};var Gr=function(e){this._map=e,this._el=e.getCanvasContainer(),this._container=e.getContainer(),t.bindAll(["_onMouseMove","_onMouseUp","_onKeyDown"],this)};Gr.prototype.isEnabled=function(){return!!this._enabled},Gr.prototype.isActive=function(){return!!this._active},Gr.prototype.enable=function(){this.isEnabled()||(this._enabled=!0)},Gr.prototype.disable=function(){this.isEnabled()&&(this._enabled=!1)},Gr.prototype.onMouseDown=function(e){this.isEnabled()&&e.shiftKey&&0===e.button&&(t.default.document.addEventListener("mousemove",this._onMouseMove,!1),t.default.document.addEventListener("keydown",this._onKeyDown,!1),t.default.document.addEventListener("mouseup",this._onMouseUp,!1),s.disableDrag(),this._startPos=s.mousePos(this._el,e),this._active=!0)},Gr.prototype._onMouseMove=function(t){var e=this._startPos,r=s.mousePos(this._el,t);this._box||(this._box=s.create("div","mapboxgl-boxzoom",this._container),this._container.classList.add("mapboxgl-crosshair"),this._fireEvent("boxzoomstart",t));var n=Math.min(e.x,r.x),i=Math.max(e.x,r.x),a=Math.min(e.y,r.y),o=Math.max(e.y,r.y);s.setTransform(this._box,"translate("+n+"px,"+a+"px)"),this._box.style.width=i-n+"px",this._box.style.height=o-a+"px"},Gr.prototype._onMouseUp=function(e){if(0===e.button){var r=this._startPos,n=s.mousePos(this._el,e),i=(new W).extend(this._map.unproject(r)).extend(this._map.unproject(n));this._finish(),s.suppressClick(),r.x===n.x&&r.y===n.y?this._fireEvent("boxzoomcancel",e):this._map.fitBounds(i,{linear:!0}).fire(new t.Event("boxzoomend",{originalEvent:e,boxZoomBounds:i}))}},Gr.prototype._onKeyDown=function(t){27===t.keyCode&&(this._finish(),this._fireEvent("boxzoomcancel",t))},Gr.prototype._finish=function(){this._active=!1,t.default.document.removeEventListener("mousemove",this._onMouseMove,!1),t.default.document.removeEventListener("keydown",this._onKeyDown,!1),t.default.document.removeEventListener("mouseup",this._onMouseUp,!1),this._container.classList.remove("mapboxgl-crosshair"),this._box&&(s.remove(this._box),this._box=null),s.enableDrag()},Gr.prototype._fireEvent=function(e,r){return this._map.fire(new t.Event(e,{originalEvent:r}))};var Wr=t.bezier(0,0,.25,1),Yr=function(e,r){this._map=e,this._el=r.element||e.getCanvasContainer(),this._state="disabled",this._button=r.button||"right",this._bearingSnap=r.bearingSnap||0,this._pitchWithRotate=!1!==r.pitchWithRotate,t.bindAll(["_onMouseMove","_onMouseUp","_onBlur","_onDragFrame"],this)};Yr.prototype.isEnabled=function(){return"disabled"!==this._state},Yr.prototype.isActive=function(){return"active"===this._state},Yr.prototype.enable=function(){this.isEnabled()||(this._state="enabled")},Yr.prototype.disable=function(){if(this.isEnabled())switch(this._state){case"active":this._state="disabled",this._unbind(),this._deactivate(),this._fireEvent("rotateend"),this._pitchWithRotate&&this._fireEvent("pitchend"),this._fireEvent("moveend");break;case"pending":this._state="disabled",this._unbind();break;default:this._state="disabled"}},Yr.prototype.onMouseDown=function(e){if("enabled"===this._state){if("right"===this._button){if(this._eventButton=s.mouseButton(e),this._eventButton!==(e.ctrlKey?0:2))return}else{if(e.ctrlKey||0!==s.mouseButton(e))return;this._eventButton=0}s.disableDrag(),t.default.document.addEventListener("mousemove",this._onMouseMove,{capture:!0}),t.default.document.addEventListener("mouseup",this._onMouseUp),t.default.addEventListener("blur",this._onBlur),this._state="pending",this._inertia=[[a.now(),this._map.getBearing()]],this._previousPos=s.mousePos(this._el,e),this._center=this._map.transform.centerPoint,e.preventDefault()}},Yr.prototype._onMouseMove=function(t){this._lastMoveEvent=t,this._pos=s.mousePos(this._el,t),"pending"===this._state&&(this._state="active",this._fireEvent("rotatestart",t),this._fireEvent("movestart",t),this._pitchWithRotate&&this._fireEvent("pitchstart",t)),this._frameId||(this._frameId=this._map._requestRenderFrame(this._onDragFrame))},Yr.prototype._onDragFrame=function(){this._frameId=null;var t=this._lastMoveEvent;if(t){var e=this._map.transform,r=this._previousPos,n=this._pos,i=.8*(r.x-n.x),o=-.5*(r.y-n.y),s=e.bearing-i,l=e.pitch-o,c=this._inertia,u=c[c.length-1];this._drainInertiaBuffer(),c.push([a.now(),this._map._normalizeBearing(s,u[1])]),e.bearing=s,this._pitchWithRotate&&(this._fireEvent("pitch",t),e.pitch=l),this._fireEvent("rotate",t),this._fireEvent("move",t),delete this._lastMoveEvent,this._previousPos=this._pos}},Yr.prototype._onMouseUp=function(t){if(s.mouseButton(t)===this._eventButton)switch(this._state){case"active":this._state="enabled",s.suppressClick(),this._unbind(),this._deactivate(),this._inertialRotate(t);break;case"pending":this._state="enabled",this._unbind()}},Yr.prototype._onBlur=function(t){switch(this._state){case"active":this._state="enabled",this._unbind(),this._deactivate(),this._fireEvent("rotateend",t),this._pitchWithRotate&&this._fireEvent("pitchend",t),this._fireEvent("moveend",t);break;case"pending":this._state="enabled",this._unbind()}},Yr.prototype._unbind=function(){t.default.document.removeEventListener("mousemove",this._onMouseMove,{capture:!0}),t.default.document.removeEventListener("mouseup",this._onMouseUp),t.default.removeEventListener("blur",this._onBlur),s.enableDrag()},Yr.prototype._deactivate=function(){this._frameId&&(this._map._cancelRenderFrame(this._frameId),this._frameId=null),delete this._lastMoveEvent,delete this._previousPos},Yr.prototype._inertialRotate=function(t){var e=this;this._fireEvent("rotateend",t),this._drainInertiaBuffer();var r=this._map,n=r.getBearing(),i=this._inertia,a=function(){Math.abs(n)180&&(p=180);var d=p/180;c+=h*p*(d/2),Math.abs(r._normalizeBearing(c,0))0&&e-t[0][0]>160;)t.shift()};var Xr=t.bezier(0,0,.3,1),Zr=function(e){this._map=e,this._el=e.getCanvasContainer(),this._state="disabled",t.bindAll(["_onMove","_onMouseUp","_onTouchEnd","_onBlur","_onDragFrame"],this)};Zr.prototype.isEnabled=function(){return"disabled"!==this._state},Zr.prototype.isActive=function(){return"active"===this._state},Zr.prototype.enable=function(){this.isEnabled()||(this._el.classList.add("mapboxgl-touch-drag-pan"),this._state="enabled")},Zr.prototype.disable=function(){if(this.isEnabled())switch(this._el.classList.remove("mapboxgl-touch-drag-pan"),this._state){case"active":this._state="disabled",this._unbind(),this._deactivate(),this._fireEvent("dragend"),this._fireEvent("moveend");break;case"pending":this._state="disabled",this._unbind();break;default:this._state="disabled"}},Zr.prototype.onMouseDown=function(e){"enabled"===this._state&&(e.ctrlKey||0!==s.mouseButton(e)||(s.addEventListener(t.default.document,"mousemove",this._onMove,{capture:!0}),s.addEventListener(t.default.document,"mouseup",this._onMouseUp),this._start(e)))},Zr.prototype.onTouchStart=function(e){"enabled"===this._state&&(e.touches.length>1||(s.addEventListener(t.default.document,"touchmove",this._onMove,{capture:!0,passive:!1}),s.addEventListener(t.default.document,"touchend",this._onTouchEnd),this._start(e)))},Zr.prototype._start=function(e){t.default.addEventListener("blur",this._onBlur),this._state="pending",this._previousPos=s.mousePos(this._el,e),this._inertia=[[a.now(),this._previousPos]]},Zr.prototype._onMove=function(t){this._lastMoveEvent=t,t.preventDefault(),this._pos=s.mousePos(this._el,t),this._drainInertiaBuffer(),this._inertia.push([a.now(),this._pos]),"pending"===this._state&&(this._state="active",this._fireEvent("dragstart",t),this._fireEvent("movestart",t)),this._frameId||(this._frameId=this._map._requestRenderFrame(this._onDragFrame))},Zr.prototype._onDragFrame=function(){this._frameId=null;var t=this._lastMoveEvent;if(t){var e=this._map.transform;e.setLocationAtPoint(e.pointLocation(this._previousPos),this._pos),this._fireEvent("drag",t),this._fireEvent("move",t),this._previousPos=this._pos,delete this._lastMoveEvent}},Zr.prototype._onMouseUp=function(t){if(0===s.mouseButton(t))switch(this._state){case"active":this._state="enabled",s.suppressClick(),this._unbind(),this._deactivate(),this._inertialPan(t);break;case"pending":this._state="enabled",this._unbind()}},Zr.prototype._onTouchEnd=function(t){switch(this._state){case"active":this._state="enabled",this._unbind(),this._deactivate(),this._inertialPan(t);break;case"pending":this._state="enabled",this._unbind()}},Zr.prototype._onBlur=function(t){switch(this._state){case"active":this._state="enabled",this._unbind(),this._deactivate(),this._fireEvent("dragend",t),this._fireEvent("moveend",t);break;case"pending":this._state="enabled",this._unbind()}},Zr.prototype._unbind=function(){s.removeEventListener(t.default.document,"touchmove",this._onMove,{capture:!0,passive:!1}),s.removeEventListener(t.default.document,"touchend",this._onTouchEnd),s.removeEventListener(t.default.document,"mousemove",this._onMove,{capture:!0}),s.removeEventListener(t.default.document,"mouseup",this._onMouseUp),s.removeEventListener(t.default,"blur",this._onBlur)},Zr.prototype._deactivate=function(){this._frameId&&(this._map._cancelRenderFrame(this._frameId),this._frameId=null),delete this._lastMoveEvent,delete this._previousPos,delete this._pos},Zr.prototype._inertialPan=function(t){this._fireEvent("dragend",t),this._drainInertiaBuffer();var e=this._inertia;if(e.length<2)this._fireEvent("moveend",t);else{var r=e[e.length-1],n=e[0],i=r[1].sub(n[1]),a=(r[0]-n[0])/1e3;if(0===a||r[1].equals(n[1]))this._fireEvent("moveend",t);else{var o=i.mult(.3/a),s=o.mag();s>1400&&(s=1400,o._unit()._mult(s));var l=s/750,c=o.mult(-l/2);this._map.panBy(c,{duration:1e3*l,easing:Xr,noMoveStart:!0},{originalEvent:t})}}},Zr.prototype._fireEvent=function(e,r){return this._map.fire(new t.Event(e,r?{originalEvent:r}:{}))},Zr.prototype._drainInertiaBuffer=function(){for(var t=this._inertia,e=a.now();t.length>0&&e-t[0][0]>160;)t.shift()};var $r=function(e){this._map=e,this._el=e.getCanvasContainer(),t.bindAll(["_onKeyDown"],this)};function Jr(t){return t*(2-t)}$r.prototype.isEnabled=function(){return!!this._enabled},$r.prototype.enable=function(){this.isEnabled()||(this._el.addEventListener("keydown",this._onKeyDown,!1),this._enabled=!0)},$r.prototype.disable=function(){this.isEnabled()&&(this._el.removeEventListener("keydown",this._onKeyDown),this._enabled=!1)},$r.prototype._onKeyDown=function(t){if(!(t.altKey||t.ctrlKey||t.metaKey)){var e=0,r=0,n=0,i=0,a=0;switch(t.keyCode){case 61:case 107:case 171:case 187:e=1;break;case 189:case 109:case 173:e=-1;break;case 37:t.shiftKey?r=-1:(t.preventDefault(),i=-1);break;case 39:t.shiftKey?r=1:(t.preventDefault(),i=1);break;case 38:t.shiftKey?n=1:(t.preventDefault(),a=-1);break;case 40:t.shiftKey?n=-1:(a=1,t.preventDefault());break;default:return}var o=this._map,s=o.getZoom(),l={duration:300,delayEndEvents:500,easing:Jr,zoom:e?Math.round(s)+e*(t.shiftKey?2:1):s,bearing:o.getBearing()+15*r,pitch:o.getPitch()+10*n,offset:[100*-i,100*-a],center:o.getCenter()};o.easeTo(l,{originalEvent:t})}};var Kr=function(e){this._map=e,t.bindAll(["_onDblClick","_onZoomEnd"],this)};Kr.prototype.isEnabled=function(){return!!this._enabled},Kr.prototype.isActive=function(){return!!this._active},Kr.prototype.enable=function(){this.isEnabled()||(this._enabled=!0)},Kr.prototype.disable=function(){this.isEnabled()&&(this._enabled=!1)},Kr.prototype.onTouchStart=function(t){var e=this;this.isEnabled()&&(t.points.length>1||(this._tapped?(clearTimeout(this._tapped),this._tapped=null,this._zoom(t)):this._tapped=setTimeout(function(){e._tapped=null},300)))},Kr.prototype.onDblClick=function(t){this.isEnabled()&&(t.originalEvent.preventDefault(),this._zoom(t))},Kr.prototype._zoom=function(t){this._active=!0,this._map.on("zoomend",this._onZoomEnd),this._map.zoomTo(this._map.getZoom()+(t.originalEvent.shiftKey?-1:1),{around:t.lngLat},t)},Kr.prototype._onZoomEnd=function(){this._active=!1,this._map.off("zoomend",this._onZoomEnd)};var Qr=t.bezier(0,0,.15,1),tn=function(e){this._map=e,this._el=e.getCanvasContainer(),t.bindAll(["_onMove","_onEnd","_onTouchFrame"],this)};tn.prototype.isEnabled=function(){return!!this._enabled},tn.prototype.enable=function(t){this.isEnabled()||(this._el.classList.add("mapboxgl-touch-zoom-rotate"),this._enabled=!0,this._aroundCenter=!!t&&"center"===t.around)},tn.prototype.disable=function(){this.isEnabled()&&(this._el.classList.remove("mapboxgl-touch-zoom-rotate"),this._enabled=!1)},tn.prototype.disableRotation=function(){this._rotationDisabled=!0},tn.prototype.enableRotation=function(){this._rotationDisabled=!1},tn.prototype.onStart=function(e){if(this.isEnabled()&&2===e.touches.length){var r=s.mousePos(this._el,e.touches[0]),n=s.mousePos(this._el,e.touches[1]);this._startVec=r.sub(n),this._gestureIntent=void 0,this._inertia=[],s.addEventListener(t.default.document,"touchmove",this._onMove,{passive:!1}),s.addEventListener(t.default.document,"touchend",this._onEnd)}},tn.prototype._getTouchEventData=function(t){var e=s.mousePos(this._el,t.touches[0]),r=s.mousePos(this._el,t.touches[1]),n=e.sub(r);return{vec:n,center:e.add(r).div(2),scale:n.mag()/this._startVec.mag(),bearing:this._rotationDisabled?0:180*n.angleWith(this._startVec)/Math.PI}},tn.prototype._onMove=function(e){if(2===e.touches.length){var r=this._getTouchEventData(e),n=r.vec,i=r.scale,a=r.bearing;if(!this._gestureIntent){var o=Math.abs(1-i)>.15;Math.abs(a)>10?this._gestureIntent="rotate":o&&(this._gestureIntent="zoom"),this._gestureIntent&&(this._map.fire(new t.Event(this._gestureIntent+"start",{originalEvent:e})),this._map.fire(new t.Event("movestart",{originalEvent:e})),this._startVec=n)}this._lastTouchEvent=e,this._frameId||(this._frameId=this._map._requestRenderFrame(this._onTouchFrame)),e.preventDefault()}},tn.prototype._onTouchFrame=function(){this._frameId=null;var e=this._gestureIntent;if(e){var r=this._map.transform;this._startScale||(this._startScale=r.scale,this._startBearing=r.bearing);var n=this._getTouchEventData(this._lastTouchEvent),i=n.center,o=n.bearing,s=n.scale,l=r.pointLocation(i),c=r.locationPoint(l);"rotate"===e&&(r.bearing=this._startBearing+o),r.zoom=r.scaleZoom(this._startScale*s),r.setLocationAtPoint(l,c),this._map.fire(new t.Event(e,{originalEvent:this._lastTouchEvent})),this._map.fire(new t.Event("move",{originalEvent:this._lastTouchEvent})),this._drainInertiaBuffer(),this._inertia.push([a.now(),s,i])}},tn.prototype._onEnd=function(e){s.removeEventListener(t.default.document,"touchmove",this._onMove,{passive:!1}),s.removeEventListener(t.default.document,"touchend",this._onEnd);var r=this._gestureIntent,n=this._startScale;if(this._frameId&&(this._map._cancelRenderFrame(this._frameId),this._frameId=null),delete this._gestureIntent,delete this._startScale,delete this._startBearing,delete this._lastTouchEvent,r){this._map.fire(new t.Event(r+"end",{originalEvent:e})),this._drainInertiaBuffer();var i=this._inertia,a=this._map;if(i.length<2)a.snapToNorth({},{originalEvent:e});else{var o=i[i.length-1],l=i[0],c=a.transform.scaleZoom(n*o[1]),u=a.transform.scaleZoom(n*l[1]),h=c-u,f=(o[0]-l[0])/1e3,p=o[2];if(0!==f&&c!==u){var d=.15*h/f;Math.abs(d)>2.5&&(d=d>0?2.5:-2.5);var g=1e3*Math.abs(d/(12*.15)),m=c+d*g/2e3;m<0&&(m=0),a.easeTo({zoom:m,duration:g,easing:Qr,around:this._aroundCenter?a.getCenter():a.unproject(p),noMoveStart:!0},{originalEvent:e})}else a.snapToNorth({},{originalEvent:e})}}},tn.prototype._drainInertiaBuffer=function(){for(var t=this._inertia,e=a.now();t.length>2&&e-t[0][0]>160;)t.shift()};var en={scrollZoom:Hr,boxZoom:Gr,dragRotate:Yr,dragPan:Zr,keyboard:$r,doubleClickZoom:Kr,touchZoomRotate:tn},rn=function(e){function r(r,n){e.call(this),this._moving=!1,this._zooming=!1,this.transform=r,this._bearingSnap=n.bearingSnap,t.bindAll(["_renderFrameCallback"],this)}return e&&(r.__proto__=e),r.prototype=Object.create(e&&e.prototype),r.prototype.constructor=r,r.prototype.getCenter=function(){return this.transform.center},r.prototype.setCenter=function(t,e){return this.jumpTo({center:t},e)},r.prototype.panBy=function(e,r,n){return e=t.default$1.convert(e).mult(-1),this.panTo(this.transform.center,t.extend({offset:e},r),n)},r.prototype.panTo=function(e,r,n){return this.easeTo(t.extend({center:e},r),n)},r.prototype.getZoom=function(){return this.transform.zoom},r.prototype.setZoom=function(t,e){return this.jumpTo({zoom:t},e),this},r.prototype.zoomTo=function(e,r,n){return this.easeTo(t.extend({zoom:e},r),n)},r.prototype.zoomIn=function(t,e){return this.zoomTo(this.getZoom()+1,t,e),this},r.prototype.zoomOut=function(t,e){return this.zoomTo(this.getZoom()-1,t,e),this},r.prototype.getBearing=function(){return this.transform.bearing},r.prototype.setBearing=function(t,e){return this.jumpTo({bearing:t},e),this},r.prototype.rotateTo=function(e,r,n){return this.easeTo(t.extend({bearing:e},r),n)},r.prototype.resetNorth=function(e,r){return this.rotateTo(0,t.extend({duration:1e3},e),r),this},r.prototype.snapToNorth=function(t,e){return Math.abs(this.getBearing())e?1:0}),["bottom","left","right","top"]))return t.warnOnce("options.padding must be a positive number, or an Object with keys 'bottom', 'left', 'right', 'top'"),this;e=W.convert(e);var a=[(r.padding.left-r.padding.right)/2,(r.padding.top-r.padding.bottom)/2],o=Math.min(r.padding.right,r.padding.left),s=Math.min(r.padding.top,r.padding.bottom);r.offset=[r.offset[0]+a[0],r.offset[1]+a[1]];var l=t.default$1.convert(r.offset),c=this.transform,u=c.project(e.getNorthWest()),h=c.project(e.getSouthEast()),f=h.sub(u),p=(c.width-2*o-2*Math.abs(l.x))/f.x,d=(c.height-2*s-2*Math.abs(l.y))/f.y;return d<0||p<0?(t.warnOnce("Map cannot fit within canvas with the given bounds, padding, and/or offset."),this):(r.center=c.unproject(u.add(h).div(2)),r.zoom=Math.min(c.scaleZoom(c.scale*Math.min(p,d)),r.maxZoom),r.bearing=0,r.linear?this.easeTo(r,n):this.flyTo(r,n))},r.prototype.jumpTo=function(e,r){this.stop();var n=this.transform,i=!1,a=!1,o=!1;return"zoom"in e&&n.zoom!==+e.zoom&&(i=!0,n.zoom=+e.zoom),void 0!==e.center&&(n.center=G.convert(e.center)),"bearing"in e&&n.bearing!==+e.bearing&&(a=!0,n.bearing=+e.bearing),"pitch"in e&&n.pitch!==+e.pitch&&(o=!0,n.pitch=+e.pitch),this.fire(new t.Event("movestart",r)).fire(new t.Event("move",r)),i&&this.fire(new t.Event("zoomstart",r)).fire(new t.Event("zoom",r)).fire(new t.Event("zoomend",r)),a&&this.fire(new t.Event("rotatestart",r)).fire(new t.Event("rotate",r)).fire(new t.Event("rotateend",r)),o&&this.fire(new t.Event("pitchstart",r)).fire(new t.Event("pitch",r)).fire(new t.Event("pitchend",r)),this.fire(new t.Event("moveend",r))},r.prototype.easeTo=function(e,r){var n=this;this.stop(),!1===(e=t.extend({offset:[0,0],duration:500,easing:t.ease},e)).animate&&(e.duration=0);var i=this.transform,a=this.getZoom(),o=this.getBearing(),s=this.getPitch(),l="zoom"in e?+e.zoom:a,c="bearing"in e?this._normalizeBearing(e.bearing,o):o,u="pitch"in e?+e.pitch:s,h=i.centerPoint.add(t.default$1.convert(e.offset)),f=i.pointLocation(h),p=G.convert(e.center||f);this._normalizeCenter(p);var d,g,m=i.project(f),v=i.project(p).sub(m),y=i.zoomScale(l-a);return e.around&&(d=G.convert(e.around),g=i.locationPoint(d)),this._zooming=l!==a,this._rotating=o!==c,this._pitching=u!==s,this._prepareEase(r,e.noMoveStart),clearTimeout(this._easeEndTimeoutID),this._ease(function(e){if(n._zooming&&(i.zoom=t.number(a,l,e)),n._rotating&&(i.bearing=t.number(o,c,e)),n._pitching&&(i.pitch=t.number(s,u,e)),d)i.setLocationAtPoint(d,g);else{var f=i.zoomScale(i.zoom-a),p=l>a?Math.min(2,y):Math.max(.5,y),x=Math.pow(p,1-e),b=i.unproject(m.add(v.mult(e*x)).mult(f));i.setLocationAtPoint(i.renderWorldCopies?b.wrap():b,h)}n._fireMoveEvents(r)},function(){e.delayEndEvents?n._easeEndTimeoutID=setTimeout(function(){return n._afterEase(r)},e.delayEndEvents):n._afterEase(r)},e),this},r.prototype._prepareEase=function(e,r){this._moving=!0,r||this.fire(new t.Event("movestart",e)),this._zooming&&this.fire(new t.Event("zoomstart",e)),this._rotating&&this.fire(new t.Event("rotatestart",e)),this._pitching&&this.fire(new t.Event("pitchstart",e))},r.prototype._fireMoveEvents=function(e){this.fire(new t.Event("move",e)),this._zooming&&this.fire(new t.Event("zoom",e)),this._rotating&&this.fire(new t.Event("rotate",e)),this._pitching&&this.fire(new t.Event("pitch",e))},r.prototype._afterEase=function(e){var r=this._zooming,n=this._rotating,i=this._pitching;this._moving=!1,this._zooming=!1,this._rotating=!1,this._pitching=!1,r&&this.fire(new t.Event("zoomend",e)),n&&this.fire(new t.Event("rotateend",e)),i&&this.fire(new t.Event("pitchend",e)),this.fire(new t.Event("moveend",e))},r.prototype.flyTo=function(e,r){var n=this;this.stop(),e=t.extend({offset:[0,0],speed:1.2,curve:1.42,easing:t.ease},e);var i=this.transform,a=this.getZoom(),o=this.getBearing(),s=this.getPitch(),l="zoom"in e?t.clamp(+e.zoom,i.minZoom,i.maxZoom):a,c="bearing"in e?this._normalizeBearing(e.bearing,o):o,u="pitch"in e?+e.pitch:s,h=i.zoomScale(l-a),f=i.centerPoint.add(t.default$1.convert(e.offset)),p=i.pointLocation(f),d=G.convert(e.center||p);this._normalizeCenter(d);var g=i.project(p),m=i.project(d).sub(g),v=e.curve,y=Math.max(i.width,i.height),x=y/h,b=m.mag();if("minZoom"in e){var _=t.clamp(Math.min(e.minZoom,a,l),i.minZoom,i.maxZoom),w=y/i.zoomScale(_-a);v=Math.sqrt(w/b*2)}var k=v*v;function M(t){var e=(x*x-y*y+(t?-1:1)*k*k*b*b)/(2*(t?x:y)*k*b);return Math.log(Math.sqrt(e*e+1)-e)}function A(t){return(Math.exp(t)-Math.exp(-t))/2}function T(t){return(Math.exp(t)+Math.exp(-t))/2}var S=M(0),E=function(t){return T(S)/T(S+v*t)},C=function(t){return y*((T(S)*(A(e=S+v*t)/T(e))-A(S))/k)/b;var e},L=(M(1)-S)/v;if(Math.abs(b)<1e-6||!isFinite(L)){if(Math.abs(y-x)<1e-6)return this.easeTo(e,r);var z=xe.maxDuration&&(e.duration=0),this._zooming=!0,this._rotating=o!==c,this._pitching=u!==s,this._prepareEase(r,!1),this._ease(function(e){var l=e*L,h=1/E(l);i.zoom=a+i.scaleZoom(h),n._rotating&&(i.bearing=t.number(o,c,e)),n._pitching&&(i.pitch=t.number(s,u,e));var p=i.unproject(g.add(m.mult(C(l))).mult(h));i.setLocationAtPoint(i.renderWorldCopies?p.wrap():p,f),n._fireMoveEvents(r)},function(){return n._afterEase(r)},e),this},r.prototype.isEasing=function(){return!!this._easeFrameId},r.prototype.stop=function(){if(this._easeFrameId&&(this._cancelRenderFrame(this._easeFrameId),delete this._easeFrameId,delete this._onEaseFrame),this._onEaseEnd){var t=this._onEaseEnd;delete this._onEaseEnd,t.call(this)}return this},r.prototype._ease=function(t,e,r){!1===r.animate||0===r.duration?(t(1),e()):(this._easeStart=a.now(),this._easeOptions=r,this._onEaseFrame=t,this._onEaseEnd=e,this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback))},r.prototype._renderFrameCallback=function(){var t=Math.min((a.now()-this._easeStart)/this._easeOptions.duration,1);this._onEaseFrame(this._easeOptions.easing(t)),t<1?this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback):this.stop()},r.prototype._normalizeBearing=function(e,r){e=t.wrap(e,-180,180);var n=Math.abs(e-r);return Math.abs(e-360-r)180?-360:r<-180?360:0}},r}(t.Evented),nn=function(e){void 0===e&&(e={}),this.options=e,t.bindAll(["_updateEditLink","_updateData","_updateCompact"],this)};nn.prototype.getDefaultPosition=function(){return"bottom-right"},nn.prototype.onAdd=function(t){var e=this.options&&this.options.compact;return this._map=t,this._container=s.create("div","mapboxgl-ctrl mapboxgl-ctrl-attrib"),e&&this._container.classList.add("mapboxgl-compact"),this._updateAttributions(),this._updateEditLink(),this._map.on("sourcedata",this._updateData),this._map.on("moveend",this._updateEditLink),void 0===e&&(this._map.on("resize",this._updateCompact),this._updateCompact()),this._container},nn.prototype.onRemove=function(){s.remove(this._container),this._map.off("sourcedata",this._updateData),this._map.off("moveend",this._updateEditLink),this._map.off("resize",this._updateCompact),this._map=void 0},nn.prototype._updateEditLink=function(){var t=this._editLink;t||(t=this._editLink=this._container.querySelector(".mapbox-improve-map"));var e=[{key:"owner",value:this.styleOwner},{key:"id",value:this.styleId},{key:"access_token",value:m.ACCESS_TOKEN}];if(t){var r=e.reduce(function(t,r,n){return r.value&&(t+=r.key+"="+r.value+(n=0)return!1;return!0})).length?(this._container.innerHTML=t.join(" | "),this._container.classList.remove("mapboxgl-attrib-empty")):this._container.classList.add("mapboxgl-attrib-empty"),this._editLink=null}},nn.prototype._updateCompact=function(){this._map.getCanvasContainer().offsetWidth<=640?this._container.classList.add("mapboxgl-compact"):this._container.classList.remove("mapboxgl-compact")};var an=function(){t.bindAll(["_updateLogo"],this)};an.prototype.onAdd=function(t){this._map=t,this._container=s.create("div","mapboxgl-ctrl");var e=s.create("a","mapboxgl-ctrl-logo");return e.target="_blank",e.href="https://www.mapbox.com/",e.setAttribute("aria-label","Mapbox logo"),this._container.appendChild(e),this._container.style.display="none",this._map.on("sourcedata",this._updateLogo),this._updateLogo(),this._container},an.prototype.onRemove=function(){s.remove(this._container),this._map.off("sourcedata",this._updateLogo)},an.prototype.getDefaultPosition=function(){return"bottom-left"},an.prototype._updateLogo=function(t){t&&"metadata"!==t.sourceDataType||(this._container.style.display=this._logoRequired()?"block":"none")},an.prototype._logoRequired=function(){if(this._map.style){var t=this._map.style.sourceCaches;for(var e in t)if(t[e].getSource().mapbox_logo)return!0;return!1}};var on=function(){this._queue=[],this._id=0,this._cleared=!1,this._currentlyRunning=!1};on.prototype.add=function(t){var e=++this._id;return this._queue.push({callback:t,id:e,cancelled:!1}),e},on.prototype.remove=function(t){for(var e=this._currentlyRunning,r=0,n=e?this._queue.concat(e):this._queue;re.maxZoom)throw new Error("maxZoom must be greater than minZoom");var n=new Fr(e.minZoom,e.maxZoom,e.renderWorldCopies);r.call(this,n,e),this._interactive=e.interactive,this._maxTileCacheSize=e.maxTileCacheSize,this._failIfMajorPerformanceCaveat=e.failIfMajorPerformanceCaveat,this._preserveDrawingBuffer=e.preserveDrawingBuffer,this._trackResize=e.trackResize,this._bearingSnap=e.bearingSnap,this._refreshExpiredTiles=e.refreshExpiredTiles,this._fadeDuration=e.fadeDuration,this._crossFadingFactor=1,this._collectResourceTiming=e.collectResourceTiming,this._renderTaskQueue=new on;var i=e.transformRequest;if(this._transformRequest=i?function(t,e){return i(t,e)||{url:t}}:function(t){return{url:t}},"string"==typeof e.container){var a=t.default.document.getElementById(e.container);if(!a)throw new Error("Container '"+e.container+"' not found.");this._container=a}else{if(!(e.container instanceof ln))throw new Error("Invalid type: 'container' must be a String or HTMLElement.");this._container=e.container}e.maxBounds&&this.setMaxBounds(e.maxBounds),t.bindAll(["_onWindowOnline","_onWindowResize","_contextLost","_contextRestored","_update","_render","_onData","_onDataLoading"],this),this._setupContainer(),this._setupPainter(),this.on("move",this._update.bind(this,!1)),this.on("zoom",this._update.bind(this,!0)),void 0!==t.default&&(t.default.addEventListener("online",this._onWindowOnline,!1),t.default.addEventListener("resize",this._onWindowResize,!1)),function(t,e){var r=t.getCanvasContainer(),n=null,i=!1;for(var a in en)t[a]=new en[a](t,e),e.interactive&&e[a]&&t[a].enable(e[a]);s.addEventListener(r,"mouseout",function(e){t.fire(new Vr("mouseout",t,e))}),s.addEventListener(r,"mousedown",function(r){i=!0;var n=new Vr("mousedown",t,r);t.fire(n),n.defaultPrevented||(e.interactive&&!t.doubleClickZoom.isActive()&&t.stop(),t.boxZoom.onMouseDown(r),t.boxZoom.isActive()||t.dragPan.isActive()||t.dragRotate.onMouseDown(r),t.boxZoom.isActive()||t.dragRotate.isActive()||t.dragPan.onMouseDown(r))}),s.addEventListener(r,"mouseup",function(e){var r=t.dragRotate.isActive();n&&!r&&t.fire(new Vr("contextmenu",t,n)),n=null,i=!1,t.fire(new Vr("mouseup",t,e))}),s.addEventListener(r,"mousemove",function(e){if(!t.dragPan.isActive()&&!t.dragRotate.isActive()){for(var n=e.toElement||e.target;n&&n!==r;)n=n.parentNode;n===r&&t.fire(new Vr("mousemove",t,e))}}),s.addEventListener(r,"mouseover",function(e){for(var n=e.toElement||e.target;n&&n!==r;)n=n.parentNode;n===r&&t.fire(new Vr("mouseover",t,e))}),s.addEventListener(r,"touchstart",function(r){var n=new Ur("touchstart",t,r);t.fire(n),n.defaultPrevented||(e.interactive&&t.stop(),t.boxZoom.isActive()||t.dragRotate.isActive()||t.dragPan.onTouchStart(r),t.touchZoomRotate.onStart(r),t.doubleClickZoom.onTouchStart(n))},{passive:!1}),s.addEventListener(r,"touchmove",function(e){t.fire(new Ur("touchmove",t,e))},{passive:!1}),s.addEventListener(r,"touchend",function(e){t.fire(new Ur("touchend",t,e))}),s.addEventListener(r,"touchcancel",function(e){t.fire(new Ur("touchcancel",t,e))}),s.addEventListener(r,"click",function(e){t.fire(new Vr("click",t,e))}),s.addEventListener(r,"dblclick",function(e){var r=new Vr("dblclick",t,e);t.fire(r),r.defaultPrevented||t.doubleClickZoom.onDblClick(r)}),s.addEventListener(r,"contextmenu",function(e){var r=t.dragRotate.isActive();i||r?i&&(n=e):t.fire(new Vr("contextmenu",t,e)),e.preventDefault()}),s.addEventListener(r,"wheel",function(e){var r=new qr("wheel",t,e);t.fire(r),r.defaultPrevented||t.scrollZoom.onWheel(e)},{passive:!1})}(this,e),this._hash=e.hash&&(new jr).addTo(this),this._hash&&this._hash._onHashChange()||this.jumpTo({center:e.center,zoom:e.zoom,bearing:e.bearing,pitch:e.pitch}),this.resize(),e.style&&this.setStyle(e.style,{localIdeographFontFamily:e.localIdeographFontFamily}),e.attributionControl&&this.addControl(new nn),this.addControl(new an,e.logoPosition),this.on("style.load",function(){this.transform.unmodified&&this.jumpTo(this.style.stylesheet)}),this.on("data",this._onData),this.on("dataloading",this._onDataLoading)}r&&(n.__proto__=r),n.prototype=Object.create(r&&r.prototype),n.prototype.constructor=n;var i={showTileBoundaries:{configurable:!0},showCollisionBoxes:{configurable:!0},showOverdrawInspector:{configurable:!0},repaint:{configurable:!0},vertices:{configurable:!0}};return n.prototype.addControl=function(t,e){void 0===e&&t.getDefaultPosition&&(e=t.getDefaultPosition()),void 0===e&&(e="top-right");var r=t.onAdd(this),n=this._controlPositions[e];return-1!==e.indexOf("bottom")?n.insertBefore(r,n.firstChild):n.appendChild(r),this},n.prototype.removeControl=function(t){return t.onRemove(this),this},n.prototype.resize=function(e){var r=this._containerDimensions(),n=r[0],i=r[1];return this._resizeCanvas(n,i),this.transform.resize(n,i),this.painter.resize(n,i),this.fire(new t.Event("movestart",e)).fire(new t.Event("move",e)).fire(new t.Event("resize",e)).fire(new t.Event("moveend",e))},n.prototype.getBounds=function(){var e=new W(this.transform.pointLocation(new t.default$1(0,this.transform.height)),this.transform.pointLocation(new t.default$1(this.transform.width,0)));return(this.transform.angle||this.transform.pitch)&&(e.extend(this.transform.pointLocation(new t.default$1(this.transform.size.x,0))),e.extend(this.transform.pointLocation(new t.default$1(0,this.transform.size.y)))),e},n.prototype.getMaxBounds=function(){return this.transform.latRange&&2===this.transform.latRange.length&&this.transform.lngRange&&2===this.transform.lngRange.length?new W([this.transform.lngRange[0],this.transform.latRange[0]],[this.transform.lngRange[1],this.transform.latRange[1]]):null},n.prototype.setMaxBounds=function(t){if(t){var e=W.convert(t);this.transform.lngRange=[e.getWest(),e.getEast()],this.transform.latRange=[e.getSouth(),e.getNorth()],this.transform._constrain(),this._update()}else null==t&&(this.transform.lngRange=null,this.transform.latRange=null,this._update());return this},n.prototype.setMinZoom=function(t){if((t=null==t?0:t)>=0&&t<=this.transform.maxZoom)return this.transform.minZoom=t,this._update(),this.getZoom()=this.transform.minZoom)return this.transform.maxZoom=t,this._update(),this.getZoom()>t&&this.setZoom(t),this;throw new Error("maxZoom must be greater than the current minZoom")},n.prototype.getRenderWorldCopies=function(){return this.transform.renderWorldCopies},n.prototype.setRenderWorldCopies=function(t){return this.transform.renderWorldCopies=t,this._update(),this},n.prototype.getMaxZoom=function(){return this.transform.maxZoom},n.prototype.project=function(t){return this.transform.locationPoint(G.convert(t))},n.prototype.unproject=function(e){return this.transform.pointLocation(t.default$1.convert(e))},n.prototype.isMoving=function(){return this._moving||this.dragPan.isActive()||this.dragRotate.isActive()||this.scrollZoom.isActive()},n.prototype.isZooming=function(){return this._zooming||this.scrollZoom.isActive()},n.prototype.isRotating=function(){return this._rotating||this.dragRotate.isActive()},n.prototype.on=function(t,e,n){var i,a=this;if(void 0===n)return r.prototype.on.call(this,t,e);var o=function(){if("mouseenter"===t||"mouseover"===t){var r=!1;return{layer:e,listener:n,delegates:{mousemove:function(i){var o=a.getLayer(e)?a.queryRenderedFeatures(i.point,{layers:[e]}):[];o.length?r||(r=!0,n.call(a,new Vr(t,a,i.originalEvent,{features:o}))):r=!1},mouseout:function(){r=!1}}}}if("mouseleave"===t||"mouseout"===t){var o=!1;return{layer:e,listener:n,delegates:{mousemove:function(r){(a.getLayer(e)?a.queryRenderedFeatures(r.point,{layers:[e]}):[]).length?o=!0:o&&(o=!1,n.call(a,new Vr(t,a,r.originalEvent)))},mouseout:function(e){o&&(o=!1,n.call(a,new Vr(t,a,e.originalEvent)))}}}}return{layer:e,listener:n,delegates:(i={},i[t]=function(t){var r=a.getLayer(e)?a.queryRenderedFeatures(t.point,{layers:[e]}):[];r.length&&(t.features=r,n.call(a,t),delete t.features)},i)}}();for(var s in this._delegatedListeners=this._delegatedListeners||{},this._delegatedListeners[t]=this._delegatedListeners[t]||[],this._delegatedListeners[t].push(o),o.delegates)a.on(s,o.delegates[s]);return this},n.prototype.off=function(t,e,n){if(void 0===n)return r.prototype.off.call(this,t,e);if(this._delegatedListeners&&this._delegatedListeners[t])for(var i=this._delegatedListeners[t],a=0;a180;){var o=r.locationPoint(t);if(o.x>=0&&o.y>=0&&o.x<=r.width&&o.y<=r.height)break;t.lng>r.center.lng?t.lng-=360:t.lng+=360}return t}pn.prototype._rotateCompassArrow=function(){var t="rotate("+this._map.transform.angle*(180/Math.PI)+"deg)";this._compassArrow.style.transform=t},pn.prototype.onAdd=function(t){return this._map=t,this.options.showCompass&&(this._map.on("rotate",this._rotateCompassArrow),this._rotateCompassArrow(),this._handler=new Yr(t,{button:"left",element:this._compass}),this._handler.enable()),this._container},pn.prototype.onRemove=function(){s.remove(this._container),this.options.showCompass&&(this._map.off("rotate",this._rotateCompassArrow),this._handler.disable(),delete this._handler),delete this._map},pn.prototype._createButton=function(t,e,r){var n=s.create("button",t,this._container);return n.type="button",n.setAttribute("aria-label",e),n.addEventListener("click",r),n};var gn={center:"translate(-50%,-50%)",top:"translate(-50%,0)","top-left":"translate(0,0)","top-right":"translate(-100%,0)",bottom:"translate(-50%,-100%)","bottom-left":"translate(0,-100%)","bottom-right":"translate(-100%,-100%)",left:"translate(0,-50%)",right:"translate(-100%,-50%)"};function mn(t,e,r){var n=t.classList;for(var i in gn)n.remove("mapboxgl-"+r+"-anchor-"+i);n.add("mapboxgl-"+r+"-anchor-"+e)}var vn=function(e){if((e instanceof t.default.HTMLElement||2===arguments.length)&&(e=t.extend({element:e},arguments[1])),t.bindAll(["_update","_onMapClick"],this),this._anchor=e&&e.anchor||"center",this._color=e&&e.color||"#3FB1CE",e&&e.element)this._element=e.element,this._offset=t.default$1.convert(e&&e.offset||[0,0]);else{this._defaultMarker=!0,this._element=s.create("div");var r=s.createNS("http://www.w3.org/2000/svg","svg");r.setAttributeNS(null,"height","41px"),r.setAttributeNS(null,"width","27px"),r.setAttributeNS(null,"viewBox","0 0 27 41");var n=s.createNS("http://www.w3.org/2000/svg","g");n.setAttributeNS(null,"stroke","none"),n.setAttributeNS(null,"stroke-width","1"),n.setAttributeNS(null,"fill","none"),n.setAttributeNS(null,"fill-rule","evenodd");var i=s.createNS("http://www.w3.org/2000/svg","g");i.setAttributeNS(null,"fill-rule","nonzero");var a=s.createNS("http://www.w3.org/2000/svg","g");a.setAttributeNS(null,"transform","translate(3.0, 29.0)"),a.setAttributeNS(null,"fill","#000000");for(var o=0,l=[{rx:"10.5",ry:"5.25002273"},{rx:"10.5",ry:"5.25002273"},{rx:"9.5",ry:"4.77275007"},{rx:"8.5",ry:"4.29549936"},{rx:"7.5",ry:"3.81822308"},{rx:"6.5",ry:"3.34094679"},{rx:"5.5",ry:"2.86367051"},{rx:"4.5",ry:"2.38636864"}];o5280?Mn(e,c,f/5280,"mi"):Mn(e,c,f,"ft")}else r&&"nautical"===r.unit?Mn(e,c,h/1852,"nm"):Mn(e,c,h,"m")}function Mn(t,e,r,n){var i,a,o,s=(i=r,(a=Math.pow(10,(""+Math.floor(i)).length-1))*(o=(o=i/a)>=10?10:o>=5?5:o>=3?3:o>=2?2:1)),l=s/r;"m"===n&&s>=1e3&&(s/=1e3,n="km"),t.style.width=e*l+"px",t.innerHTML=s+n}wn.prototype.getDefaultPosition=function(){return"bottom-left"},wn.prototype._onMove=function(){kn(this._map,this._container,this.options)},wn.prototype.onAdd=function(t){return this._map=t,this._container=s.create("div","mapboxgl-ctrl mapboxgl-ctrl-scale",t.getContainer()),this._map.on("move",this._onMove),this._onMove(),this._container},wn.prototype.onRemove=function(){s.remove(this._container),this._map.off("move",this._onMove),this._map=void 0},wn.prototype.setUnit=function(t){this.options.unit=t,kn(this._map,this._container,this.options)};var An=function(){this._fullscreen=!1,t.bindAll(["_onClickFullscreen","_changeIcon"],this),"onfullscreenchange"in t.default.document?this._fullscreenchange="fullscreenchange":"onmozfullscreenchange"in t.default.document?this._fullscreenchange="mozfullscreenchange":"onwebkitfullscreenchange"in t.default.document?this._fullscreenchange="webkitfullscreenchange":"onmsfullscreenchange"in t.default.document&&(this._fullscreenchange="MSFullscreenChange"),this._className="mapboxgl-ctrl"};An.prototype.onAdd=function(e){return this._map=e,this._mapContainer=this._map.getContainer(),this._container=s.create("div",this._className+" mapboxgl-ctrl-group"),this._checkFullscreenSupport()?this._setupUI():(this._container.style.display="none",t.warnOnce("This device does not support fullscreen mode.")),this._container},An.prototype.onRemove=function(){s.remove(this._container),this._map=null,t.default.document.removeEventListener(this._fullscreenchange,this._changeIcon)},An.prototype._checkFullscreenSupport=function(){return!!(t.default.document.fullscreenEnabled||t.default.document.mozFullScreenEnabled||t.default.document.msFullscreenEnabled||t.default.document.webkitFullscreenEnabled)},An.prototype._setupUI=function(){var e=this._fullscreenButton=s.create("button",this._className+"-icon "+this._className+"-fullscreen",this._container);e.setAttribute("aria-label","Toggle fullscreen"),e.type="button",this._fullscreenButton.addEventListener("click",this._onClickFullscreen),t.default.document.addEventListener(this._fullscreenchange,this._changeIcon)},An.prototype._isFullscreen=function(){return this._fullscreen},An.prototype._changeIcon=function(){(t.default.document.fullscreenElement||t.default.document.mozFullScreenElement||t.default.document.webkitFullscreenElement||t.default.document.msFullscreenElement)===this._mapContainer!==this._fullscreen&&(this._fullscreen=!this._fullscreen,this._fullscreenButton.classList.toggle(this._className+"-shrink"),this._fullscreenButton.classList.toggle(this._className+"-fullscreen"))},An.prototype._onClickFullscreen=function(){this._isFullscreen()?t.default.document.exitFullscreen?t.default.document.exitFullscreen():t.default.document.mozCancelFullScreen?t.default.document.mozCancelFullScreen():t.default.document.msExitFullscreen?t.default.document.msExitFullscreen():t.default.document.webkitCancelFullScreen&&t.default.document.webkitCancelFullScreen():this._mapContainer.requestFullscreen?this._mapContainer.requestFullscreen():this._mapContainer.mozRequestFullScreen?this._mapContainer.mozRequestFullScreen():this._mapContainer.msRequestFullscreen?this._mapContainer.msRequestFullscreen():this._mapContainer.webkitRequestFullscreen&&this._mapContainer.webkitRequestFullscreen()};var Tn={closeButton:!0,closeOnClick:!0},Sn=function(e){function r(r){e.call(this),this.options=t.extend(Object.create(Tn),r),t.bindAll(["_update","_onClickClose"],this)}return e&&(r.__proto__=e),r.prototype=Object.create(e&&e.prototype),r.prototype.constructor=r,r.prototype.addTo=function(e){return this._map=e,this._map.on("move",this._update),this.options.closeOnClick&&this._map.on("click",this._onClickClose),this._update(),this.fire(new t.Event("open")),this},r.prototype.isOpen=function(){return!!this._map},r.prototype.remove=function(){return this._content&&s.remove(this._content),this._container&&(s.remove(this._container),delete this._container),this._map&&(this._map.off("move",this._update),this._map.off("click",this._onClickClose),delete this._map),this.fire(new t.Event("close")),this},r.prototype.getLngLat=function(){return this._lngLat},r.prototype.setLngLat=function(t){return this._lngLat=G.convert(t),this._pos=null,this._update(),this},r.prototype.setText=function(e){return this.setDOMContent(t.default.document.createTextNode(e))},r.prototype.setHTML=function(e){var r,n=t.default.document.createDocumentFragment(),i=t.default.document.createElement("body");for(i.innerHTML=e;r=i.firstChild;)n.appendChild(r);return this.setDOMContent(n)},r.prototype.setDOMContent=function(t){return this._createContent(),this._content.appendChild(t),this._update(),this},r.prototype._createContent=function(){this._content&&s.remove(this._content),this._content=s.create("div","mapboxgl-popup-content",this._container),this.options.closeButton&&(this._closeButton=s.create("button","mapboxgl-popup-close-button",this._content),this._closeButton.type="button",this._closeButton.setAttribute("aria-label","Close popup"),this._closeButton.innerHTML="×",this._closeButton.addEventListener("click",this._onClickClose))},r.prototype._update=function(){if(this._map&&this._lngLat&&this._content){this._container||(this._container=s.create("div","mapboxgl-popup",this._map.getContainer()),this._tip=s.create("div","mapboxgl-popup-tip",this._container),this._container.appendChild(this._content)),this._map.transform.renderWorldCopies&&(this._lngLat=dn(this._lngLat,this._pos,this._map.transform));var e=this._pos=this._map.project(this._lngLat),r=this.options.anchor,n=function e(r){if(r){if("number"==typeof r){var n=Math.round(Math.sqrt(.5*Math.pow(r,2)));return{center:new t.default$1(0,0),top:new t.default$1(0,r),"top-left":new t.default$1(n,n),"top-right":new t.default$1(-n,n),bottom:new t.default$1(0,-r),"bottom-left":new t.default$1(n,-n),"bottom-right":new t.default$1(-n,-n),left:new t.default$1(r,0),right:new t.default$1(-r,0)}}if(r instanceof t.default$1||Array.isArray(r)){var i=t.default$1.convert(r);return{center:i,top:i,"top-left":i,"top-right":i,bottom:i,"bottom-left":i,"bottom-right":i,left:i,right:i}}return{center:t.default$1.convert(r.center||[0,0]),top:t.default$1.convert(r.top||[0,0]),"top-left":t.default$1.convert(r["top-left"]||[0,0]),"top-right":t.default$1.convert(r["top-right"]||[0,0]),bottom:t.default$1.convert(r.bottom||[0,0]),"bottom-left":t.default$1.convert(r["bottom-left"]||[0,0]),"bottom-right":t.default$1.convert(r["bottom-right"]||[0,0]),left:t.default$1.convert(r.left||[0,0]),right:t.default$1.convert(r.right||[0,0])}}return e(new t.default$1(0,0))}(this.options.offset);if(!r){var i,a=this._container.offsetWidth,o=this._container.offsetHeight;i=e.y+n.bottom.ythis._map.transform.height-o?["bottom"]:[],e.xthis._map.transform.width-a/2&&i.push("right"),r=0===i.length?"bottom":i.join("-")}var l=e.add(n[r]).round();s.setTransform(this._container,gn[r]+" translate("+l.x+"px,"+l.y+"px)"),mn(this._container,r,"popup")}},r.prototype._onClickClose=function(){this.remove()},r}(t.Evented),En={version:"0.45.0",supported:e,workerCount:Math.max(Math.floor(a.hardwareConcurrency/2),1),setRTLTextPlugin:t.setRTLTextPlugin,Map:un,NavigationControl:pn,GeolocateControl:bn,AttributionControl:nn,ScaleControl:wn,FullscreenControl:An,Popup:Sn,Marker:vn,Style:Je,LngLat:G,LngLatBounds:W,Point:t.default$1,Evented:t.Evented,config:m,get accessToken(){return m.ACCESS_TOKEN},set accessToken(t){m.ACCESS_TOKEN=t},workerUrl:""};return En}),n})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],394:[function(t,e,r){"use strict";e.exports=function(t){for(var e=1<p[1][2]&&(v[0]=-v[0]),p[0][2]>p[2][0]&&(v[1]=-v[1]),p[1][0]>p[0][1]&&(v[2]=-v[2]),!0}},{"./normalize":396,"gl-mat4/clone":248,"gl-mat4/create":249,"gl-mat4/determinant":250,"gl-mat4/invert":254,"gl-mat4/transpose":264,"gl-vec3/cross":314,"gl-vec3/dot":317,"gl-vec3/length":322,"gl-vec3/normalize":328}],396:[function(t,e,r){e.exports=function(t,e){var r=e[15];if(0===r)return!1;for(var n=1/r,i=0;i<16;i++)t[i]=e[i]*n;return!0}},{}],397:[function(t,e,r){var n=t("gl-vec3/lerp"),i=t("mat4-recompose"),a=t("mat4-decompose"),o=t("gl-mat4/determinant"),s=t("quat-slerp"),l=h(),c=h(),u=h();function h(){return{translate:f(),scale:f(1),skew:f(),perspective:[0,0,0,1],quaternion:[0,0,0,1]}}function f(t){return[t||0,t||0,t||0]}e.exports=function(t,e,r,h){if(0===o(e)||0===o(r))return!1;var f=a(e,l.translate,l.scale,l.skew,l.perspective,l.quaternion),p=a(r,c.translate,c.scale,c.skew,c.perspective,c.quaternion);return!(!f||!p||(n(u.translate,l.translate,c.translate,h),n(u.skew,l.skew,c.skew,h),n(u.scale,l.scale,c.scale,h),n(u.perspective,l.perspective,c.perspective,h),s(u.quaternion,l.quaternion,c.quaternion,h),i(t,u.translate,u.scale,u.skew,u.perspective,u.quaternion),0))}},{"gl-mat4/determinant":250,"gl-vec3/lerp":323,"mat4-decompose":395,"mat4-recompose":398,"quat-slerp":450}],398:[function(t,e,r){var n={identity:t("gl-mat4/identity"),translate:t("gl-mat4/translate"),multiply:t("gl-mat4/multiply"),create:t("gl-mat4/create"),scale:t("gl-mat4/scale"),fromRotationTranslation:t("gl-mat4/fromRotationTranslation")},i=(n.create(),n.create());e.exports=function(t,e,r,a,o,s){return n.identity(t),n.fromRotationTranslation(t,s,e),t[3]=o[0],t[7]=o[1],t[11]=o[2],t[15]=o[3],n.identity(i),0!==a[2]&&(i[9]=a[2],n.multiply(t,t,i)),0!==a[1]&&(i[9]=0,i[8]=a[1],n.multiply(t,t,i)),0!==a[0]&&(i[8]=0,i[4]=a[0],n.multiply(t,t,i)),n.scale(t,t,r),t}},{"gl-mat4/create":249,"gl-mat4/fromRotationTranslation":252,"gl-mat4/identity":253,"gl-mat4/multiply":256,"gl-mat4/scale":262,"gl-mat4/translate":263}],399:[function(t,e,r){"use strict";e.exports=Math.log2||function(t){return Math.log(t)*Math.LOG2E}},{}],400:[function(t,e,r){"use strict";var n=t("binary-search-bounds"),i=t("mat4-interpolate"),a=t("gl-mat4/invert"),o=t("gl-mat4/rotateX"),s=t("gl-mat4/rotateY"),l=t("gl-mat4/rotateZ"),c=t("gl-mat4/lookAt"),u=t("gl-mat4/translate"),h=(t("gl-mat4/scale"),t("gl-vec3/normalize")),f=[0,0,0];function p(t){this._components=t.slice(),this._time=[0],this.prevMatrix=t.slice(),this.nextMatrix=t.slice(),this.computedMatrix=t.slice(),this.computedInverse=t.slice(),this.computedEye=[0,0,0],this.computedUp=[0,0,0],this.computedCenter=[0,0,0],this.computedRadius=[0],this._limits=[-1/0,1/0]}e.exports=function(t){return new p((t=t||{}).matrix||[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])};var d=p.prototype;d.recalcMatrix=function(t){var e=this._time,r=n.le(e,t),o=this.computedMatrix;if(!(r<0)){var s=this._components;if(r===e.length-1)for(var l=16*r,c=0;c<16;++c)o[c]=s[l++];else{var u=e[r+1]-e[r],f=(l=16*r,this.prevMatrix),p=!0;for(c=0;c<16;++c)f[c]=s[l++];var d=this.nextMatrix;for(c=0;c<16;++c)d[c]=s[l++],p=p&&f[c]===d[c];if(u<1e-6||p)for(c=0;c<16;++c)o[c]=f[c];else i(o,f,d,(t-e[r])/u)}var g=this.computedUp;g[0]=o[1],g[1]=o[5],g[2]=o[9],h(g,g);var m=this.computedInverse;a(m,o);var v=this.computedEye,y=m[15];v[0]=m[12]/y,v[1]=m[13]/y,v[2]=m[14]/y;var x=this.computedCenter,b=Math.exp(this.computedRadius[0]);for(c=0;c<3;++c)x[c]=v[c]-o[2+4*c]*b}},d.idle=function(t){if(!(t1&&n(t[o[u-2]],t[o[u-1]],c)<=0;)u-=1,o.pop();for(o.push(l),u=s.length;u>1&&n(t[s[u-2]],t[s[u-1]],c)>=0;)u-=1,s.pop();s.push(l)}for(var r=new Array(s.length+o.length-2),h=0,i=0,f=o.length;i0;--p)r[h++]=s[p];return r};var n=t("robust-orientation")[3]},{"robust-orientation":471}],402:[function(t,e,r){"use strict";e.exports=function(t,e){e||(e=t,t=window);var r=0,i=0,a=0,o={shift:!1,alt:!1,control:!1,meta:!1},s=!1;function l(t){var e=!1;return"altKey"in t&&(e=e||t.altKey!==o.alt,o.alt=!!t.altKey),"shiftKey"in t&&(e=e||t.shiftKey!==o.shift,o.shift=!!t.shiftKey),"ctrlKey"in t&&(e=e||t.ctrlKey!==o.control,o.control=!!t.ctrlKey),"metaKey"in t&&(e=e||t.metaKey!==o.meta,o.meta=!!t.metaKey),e}function c(t,s){var c=n.x(s),u=n.y(s);"buttons"in s&&(t=0|s.buttons),(t!==r||c!==i||u!==a||l(s))&&(r=0|t,i=c||0,a=u||0,e&&e(r,i,a,o))}function u(t){c(0,t)}function h(){(r||i||a||o.shift||o.alt||o.meta||o.control)&&(i=a=0,r=0,o.shift=o.alt=o.control=o.meta=!1,e&&e(0,0,0,o))}function f(t){l(t)&&e&&e(r,i,a,o)}function p(t){0===n.buttons(t)?c(0,t):c(r,t)}function d(t){c(r|n.buttons(t),t)}function g(t){c(r&~n.buttons(t),t)}function m(){s||(s=!0,t.addEventListener("mousemove",p),t.addEventListener("mousedown",d),t.addEventListener("mouseup",g),t.addEventListener("mouseleave",u),t.addEventListener("mouseenter",u),t.addEventListener("mouseout",u),t.addEventListener("mouseover",u),t.addEventListener("blur",h),t.addEventListener("keyup",f),t.addEventListener("keydown",f),t.addEventListener("keypress",f),t!==window&&(window.addEventListener("blur",h),window.addEventListener("keyup",f),window.addEventListener("keydown",f),window.addEventListener("keypress",f)))}m();var v={element:t};return Object.defineProperties(v,{enabled:{get:function(){return s},set:function(e){e?m():s&&(s=!1,t.removeEventListener("mousemove",p),t.removeEventListener("mousedown",d),t.removeEventListener("mouseup",g),t.removeEventListener("mouseleave",u),t.removeEventListener("mouseenter",u),t.removeEventListener("mouseout",u),t.removeEventListener("mouseover",u),t.removeEventListener("blur",h),t.removeEventListener("keyup",f),t.removeEventListener("keydown",f),t.removeEventListener("keypress",f),t!==window&&(window.removeEventListener("blur",h),window.removeEventListener("keyup",f),window.removeEventListener("keydown",f),window.removeEventListener("keypress",f)))},enumerable:!0},buttons:{get:function(){return r},enumerable:!0},x:{get:function(){return i},enumerable:!0},y:{get:function(){return a},enumerable:!0},mods:{get:function(){return o},enumerable:!0}}),v};var n=t("mouse-event")},{"mouse-event":404}],403:[function(t,e,r){var n={left:0,top:0};e.exports=function(t,e,r){e=e||t.currentTarget||t.srcElement,Array.isArray(r)||(r=[0,0]);var i=t.clientX||0,a=t.clientY||0,o=(s=e,s===window||s===document||s===document.body?n:s.getBoundingClientRect());var s;return r[0]=i-o.left,r[1]=a-o.top,r}},{}],404:[function(t,e,r){"use strict";function n(t){return t.target||t.srcElement||window}r.buttons=function(t){if("object"==typeof t){if("buttons"in t)return t.buttons;if("which"in t){if(2===(e=t.which))return 4;if(3===e)return 2;if(e>0)return 1<=0)return 1< 0");"function"!=typeof t.vertex&&e("Must specify vertex creation function");"function"!=typeof t.cell&&e("Must specify cell creation function");"function"!=typeof t.phase&&e("Must specify phase function");for(var E=t.getters||[],C=new Array(T),L=0;L=0?C[L]=!0:C[L]=!1;return function(t,e,r,T,S,E){var C=E.length,L=S.length;if(L<2)throw new Error("ndarray-extract-contour: Dimension must be at least 2");for(var z="extractContour"+S.join("_"),P=[],I=[],O=[],D=0;D0&&N.push(l(D,S[R-1])+"*"+s(S[R-1])),I.push(d(D,S[R])+"=("+N.join("-")+")|0")}for(var D=0;D=0;--D)j.push(s(S[D]));I.push(w+"=("+j.join("*")+")|0",b+"=mallocUint32("+w+")",x+"=mallocUint32("+w+")",k+"=0"),I.push(g(0)+"=0");for(var R=1;R<1<0;M=M-1&d)w.push(x+"["+k+"+"+v(M)+"]");w.push(y(0));for(var M=0;M=0;--e)G(e,0);for(var r=[],e=0;e0){",p(S[e]),"=1;");t(e-1,r|1<=0?s.push("0"):e.indexOf(-(l+1))>=0?s.push("s["+l+"]-1"):(s.push("-1"),a.push("1"),o.push("s["+l+"]-2"));var c=".lo("+a.join()+").hi("+o.join()+")";if(0===a.length&&(c=""),i>0){n.push("if(1");for(var l=0;l=0||e.indexOf(-(l+1))>=0||n.push("&&s[",l,"]>2");n.push("){grad",i,"(src.pick(",s.join(),")",c);for(var l=0;l=0||e.indexOf(-(l+1))>=0||n.push(",dst.pick(",s.join(),",",l,")",c);n.push(");")}for(var l=0;l1){dst.set(",s.join(),",",u,",0.5*(src.get(",f.join(),")-src.get(",p.join(),")))}else{dst.set(",s.join(),",",u,",0)};"):n.push("if(s[",u,"]>1){diff(",h,",src.pick(",f.join(),")",c,",src.pick(",p.join(),")",c,");}else{zero(",h,");};");break;case"mirror":0===i?n.push("dst.set(",s.join(),",",u,",0);"):n.push("zero(",h,");");break;case"wrap":var d=s.slice(),g=s.slice();e[l]<0?(d[u]="s["+u+"]-2",g[u]="0"):(d[u]="s["+u+"]-1",g[u]="1"),0===i?n.push("if(s[",u,"]>2){dst.set(",s.join(),",",u,",0.5*(src.get(",d.join(),")-src.get(",g.join(),")))}else{dst.set(",s.join(),",",u,",0)};"):n.push("if(s[",u,"]>2){diff(",h,",src.pick(",d.join(),")",c,",src.pick(",g.join(),")",c,");}else{zero(",h,");};");break;default:throw new Error("ndarray-gradient: Invalid boundary condition")}}i>0&&n.push("};")}for(var s=0;s<1<>",rrshift:">>>"};!function(){for(var t in s){var e=s[t];r[t]=o({args:["array","array","array"],body:{args:["a","b","c"],body:"a=b"+e+"c"},funcName:t}),r[t+"eq"]=o({args:["array","array"],body:{args:["a","b"],body:"a"+e+"=b"},rvalue:!0,funcName:t+"eq"}),r[t+"s"]=o({args:["array","array","scalar"],body:{args:["a","b","s"],body:"a=b"+e+"s"},funcName:t+"s"}),r[t+"seq"]=o({args:["array","scalar"],body:{args:["a","s"],body:"a"+e+"=s"},rvalue:!0,funcName:t+"seq"})}}();var l={not:"!",bnot:"~",neg:"-",recip:"1.0/"};!function(){for(var t in l){var e=l[t];r[t]=o({args:["array","array"],body:{args:["a","b"],body:"a="+e+"b"},funcName:t}),r[t+"eq"]=o({args:["array"],body:{args:["a"],body:"a="+e+"a"},rvalue:!0,count:2,funcName:t+"eq"})}}();var c={and:"&&",or:"||",eq:"===",neq:"!==",lt:"<",gt:">",leq:"<=",geq:">="};!function(){for(var t in c){var e=c[t];r[t]=o({args:["array","array","array"],body:{args:["a","b","c"],body:"a=b"+e+"c"},funcName:t}),r[t+"s"]=o({args:["array","array","scalar"],body:{args:["a","b","s"],body:"a=b"+e+"s"},funcName:t+"s"}),r[t+"eq"]=o({args:["array","array"],body:{args:["a","b"],body:"a=a"+e+"b"},rvalue:!0,count:2,funcName:t+"eq"}),r[t+"seq"]=o({args:["array","scalar"],body:{args:["a","s"],body:"a=a"+e+"s"},rvalue:!0,count:2,funcName:t+"seq"})}}();var u=["abs","acos","asin","atan","ceil","cos","exp","floor","log","round","sin","sqrt","tan"];!function(){for(var t=0;tthis_s){this_s=-a}else if(a>this_s){this_s=a}",localVars:[],thisVars:["this_s"]},post:{args:[],localVars:[],thisVars:["this_s"],body:"return this_s"},funcName:"norminf"}),r.norm1=n({args:["array"],pre:{args:[],localVars:[],thisVars:["this_s"],body:"this_s=0"},body:{args:[{name:"a",lvalue:!1,rvalue:!0,count:3}],body:"this_s+=a<0?-a:a",localVars:[],thisVars:["this_s"]},post:{args:[],localVars:[],thisVars:["this_s"],body:"return this_s"},funcName:"norm1"}),r.sup=n({args:["array"],pre:{body:"this_h=-Infinity",args:[],thisVars:["this_h"],localVars:[]},body:{body:"if(_inline_1_arg0_>this_h)this_h=_inline_1_arg0_",args:[{name:"_inline_1_arg0_",lvalue:!1,rvalue:!0,count:2}],thisVars:["this_h"],localVars:[]},post:{body:"return this_h",args:[],thisVars:["this_h"],localVars:[]}}),r.inf=n({args:["array"],pre:{body:"this_h=Infinity",args:[],thisVars:["this_h"],localVars:[]},body:{body:"if(_inline_1_arg0_this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}",args:[{name:"_inline_1_arg0_",lvalue:!1,rvalue:!0,count:2},{name:"_inline_1_arg1_",lvalue:!1,rvalue:!0,count:2}],thisVars:["this_i","this_v"],localVars:["_inline_1_k"]},post:{body:"{return this_i}",args:[],thisVars:["this_i"],localVars:[]}}),r.random=o({args:["array"],pre:{args:[],body:"this_f=Math.random",thisVars:["this_f"]},body:{args:["a"],body:"a=this_f()",thisVars:["this_f"]},funcName:"random"}),r.assign=o({args:["array","array"],body:{args:["a","b"],body:"a=b"},funcName:"assign"}),r.assigns=o({args:["array","scalar"],body:{args:["a","b"],body:"a=b"},funcName:"assigns"}),r.equals=n({args:["array","array"],pre:i,body:{args:[{name:"x",lvalue:!1,rvalue:!0,count:1},{name:"y",lvalue:!1,rvalue:!0,count:1}],body:"if(x!==y){return false}",localVars:[],thisVars:[]},post:{args:[],localVars:[],thisVars:[],body:"return true"},funcName:"equals"})},{"cwise-compiler":133}],412:[function(t,e,r){"use strict";var n=t("ndarray"),i=t("./doConvert.js");e.exports=function(t,e){for(var r=[],a=t,o=1;Array.isArray(a);)r.push(a.length),o*=a.length,a=a[0];return 0===r.length?n():(e||(e=n(new Float64Array(o),r)),i(e,t),e)}},{"./doConvert.js":413,ndarray:417}],413:[function(t,e,r){e.exports=t("cwise-compiler")({args:["array","scalar","index"],pre:{body:"{}",args:[],thisVars:[],localVars:[]},body:{body:"{\nvar _inline_1_v=_inline_1_arg1_,_inline_1_i\nfor(_inline_1_i=0;_inline_1_i<_inline_1_arg2_.length-1;++_inline_1_i) {\n_inline_1_v=_inline_1_v[_inline_1_arg2_[_inline_1_i]]\n}\n_inline_1_arg0_=_inline_1_v[_inline_1_arg2_[_inline_1_arg2_.length-1]]\n}",args:[{name:"_inline_1_arg0_",lvalue:!0,rvalue:!1,count:1},{name:"_inline_1_arg1_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_1_arg2_",lvalue:!1,rvalue:!0,count:4}],thisVars:[],localVars:["_inline_1_i","_inline_1_v"]},post:{body:"{}",args:[],thisVars:[],localVars:[]},funcName:"convert",blockSize:64})},{"cwise-compiler":133}],414:[function(t,e,r){"use strict";var n=t("typedarray-pool"),i=32;function a(t){switch(t){case"uint8":return[n.mallocUint8,n.freeUint8];case"uint16":return[n.mallocUint16,n.freeUint16];case"uint32":return[n.mallocUint32,n.freeUint32];case"int8":return[n.mallocInt8,n.freeInt8];case"int16":return[n.mallocInt16,n.freeInt16];case"int32":return[n.mallocInt32,n.freeInt32];case"float32":return[n.mallocFloat,n.freeFloat];case"float64":return[n.mallocDouble,n.freeDouble];default:return null}}function o(t){for(var e=[],r=0;r0?s.push(["d",d,"=s",d,"-d",h,"*n",h].join("")):s.push(["d",d,"=s",d].join("")),h=d),0!=(p=t.length-1-l)&&(f>0?s.push(["e",p,"=s",p,"-e",f,"*n",f,",f",p,"=",c[p],"-f",f,"*n",f].join("")):s.push(["e",p,"=s",p,",f",p,"=",c[p]].join("")),f=p)}r.push("var "+s.join(","));var g=["0","n0-1","data","offset"].concat(o(t.length));r.push(["if(n0<=",i,"){","insertionSort(",g.join(","),")}else{","quickSort(",g.join(","),")}"].join("")),r.push("}return "+n);var m=new Function("insertionSort","quickSort",r.join("\n")),v=function(t,e){var r=["'use strict'"],n=["ndarrayInsertionSort",t.join("d"),e].join(""),i=["left","right","data","offset"].concat(o(t.length)),s=a(e),l=["i,j,cptr,ptr=left*s0+offset"];if(t.length>1){for(var c=[],u=1;u1){for(r.push("dptr=0;sptr=ptr"),u=t.length-1;u>=0;--u)0!==(p=t[u])&&r.push(["for(i",p,"=0;i",p,"b){break __l}"].join("")),u=t.length-1;u>=1;--u)r.push("sptr+=e"+u,"dptr+=f"+u,"}");for(r.push("dptr=cptr;sptr=cptr-s0"),u=t.length-1;u>=0;--u)0!==(p=t[u])&&r.push(["for(i",p,"=0;i",p,"=0;--u)0!==(p=t[u])&&r.push(["for(i",p,"=0;i",p,"scratch)){",f("cptr",h("cptr-s0")),"cptr-=s0","}",f("cptr","scratch"));return r.push("}"),t.length>1&&s&&r.push("free(scratch)"),r.push("} return "+n),s?new Function("malloc","free",r.join("\n"))(s[0],s[1]):new Function(r.join("\n"))()}(t,e),y=function(t,e,r){var n=["'use strict'"],s=["ndarrayQuickSort",t.join("d"),e].join(""),l=["left","right","data","offset"].concat(o(t.length)),c=a(e),u=0;n.push(["function ",s,"(",l.join(","),"){"].join(""));var h=["sixth=((right-left+1)/6)|0","index1=left+sixth","index5=right-sixth","index3=(left+right)>>1","index2=index3-sixth","index4=index3+sixth","el1=index1","el2=index2","el3=index3","el4=index4","el5=index5","less=left+1","great=right-1","pivots_are_equal=true","tmp","tmp0","x","y","z","k","ptr0","ptr1","ptr2","comp_pivot1=0","comp_pivot2=0","comp=0"];if(t.length>1){for(var f=[],p=1;p=0;--a)0!==(o=t[a])&&n.push(["for(i",o,"=0;i",o,"1)for(a=0;a1?n.push("ptr_shift+=d"+o):n.push("ptr0+=d"+o),n.push("}"))}}function y(e,r,i,a){if(1===r.length)n.push("ptr0="+d(r[0]));else{for(var o=0;o1)for(o=0;o=1;--o)i&&n.push("pivot_ptr+=f"+o),r.length>1?n.push("ptr_shift+=e"+o):n.push("ptr0+=e"+o),n.push("}")}function x(){t.length>1&&c&&n.push("free(pivot1)","free(pivot2)")}function b(e,r){var i="el"+e,a="el"+r;if(t.length>1){var o="__l"+ ++u;y(o,[i,a],!1,["comp=",g("ptr0"),"-",g("ptr1"),"\n","if(comp>0){tmp0=",i,";",i,"=",a,";",a,"=tmp0;break ",o,"}\n","if(comp<0){break ",o,"}"].join(""))}else n.push(["if(",g(d(i)),">",g(d(a)),"){tmp0=",i,";",i,"=",a,";",a,"=tmp0}"].join(""))}function _(e,r){t.length>1?v([e,r],!1,m("ptr0",g("ptr1"))):n.push(m(d(e),g(d(r))))}function w(e,r,i){if(t.length>1){var a="__l"+ ++u;y(a,[r],!0,[e,"=",g("ptr0"),"-pivot",i,"[pivot_ptr]\n","if(",e,"!==0){break ",a,"}"].join(""))}else n.push([e,"=",g(d(r)),"-pivot",i].join(""))}function k(e,r){t.length>1?v([e,r],!1,["tmp=",g("ptr0"),"\n",m("ptr0",g("ptr1")),"\n",m("ptr1","tmp")].join("")):n.push(["ptr0=",d(e),"\n","ptr1=",d(r),"\n","tmp=",g("ptr0"),"\n",m("ptr0",g("ptr1")),"\n",m("ptr1","tmp")].join(""))}function M(e,r,i){t.length>1?(v([e,r,i],!1,["tmp=",g("ptr0"),"\n",m("ptr0",g("ptr1")),"\n",m("ptr1",g("ptr2")),"\n",m("ptr2","tmp")].join("")),n.push("++"+r,"--"+i)):n.push(["ptr0=",d(e),"\n","ptr1=",d(r),"\n","ptr2=",d(i),"\n","++",r,"\n","--",i,"\n","tmp=",g("ptr0"),"\n",m("ptr0",g("ptr1")),"\n",m("ptr1",g("ptr2")),"\n",m("ptr2","tmp")].join(""))}function A(t,e){k(t,e),n.push("--"+e)}function T(e,r,i){t.length>1?v([e,r],!0,[m("ptr0",g("ptr1")),"\n",m("ptr1",["pivot",i,"[pivot_ptr]"].join(""))].join("")):n.push(m(d(e),g(d(r))),m(d(r),"pivot"+i))}function S(e,r){n.push(["if((",r,"-",e,")<=",i,"){\n","insertionSort(",e,",",r,",data,offset,",o(t.length).join(","),")\n","}else{\n",s,"(",e,",",r,",data,offset,",o(t.length).join(","),")\n","}"].join(""))}function E(e,r,i){t.length>1?(n.push(["__l",++u,":while(true){"].join("")),v([e],!0,["if(",g("ptr0"),"!==pivot",r,"[pivot_ptr]){break __l",u,"}"].join("")),n.push(i,"}")):n.push(["while(",g(d(e)),"===pivot",r,"){",i,"}"].join(""))}return n.push("var "+h.join(",")),b(1,2),b(4,5),b(1,3),b(2,3),b(1,4),b(3,4),b(2,5),b(2,3),b(4,5),t.length>1?v(["el1","el2","el3","el4","el5","index1","index3","index5"],!0,["pivot1[pivot_ptr]=",g("ptr1"),"\n","pivot2[pivot_ptr]=",g("ptr3"),"\n","pivots_are_equal=pivots_are_equal&&(pivot1[pivot_ptr]===pivot2[pivot_ptr])\n","x=",g("ptr0"),"\n","y=",g("ptr2"),"\n","z=",g("ptr4"),"\n",m("ptr5","x"),"\n",m("ptr6","y"),"\n",m("ptr7","z")].join("")):n.push(["pivot1=",g(d("el2")),"\n","pivot2=",g(d("el4")),"\n","pivots_are_equal=pivot1===pivot2\n","x=",g(d("el1")),"\n","y=",g(d("el3")),"\n","z=",g(d("el5")),"\n",m(d("index1"),"x"),"\n",m(d("index3"),"y"),"\n",m(d("index5"),"z")].join("")),_("index2","left"),_("index4","right"),n.push("if(pivots_are_equal){"),n.push("for(k=less;k<=great;++k){"),w("comp","k",1),n.push("if(comp===0){continue}"),n.push("if(comp<0){"),n.push("if(k!==less){"),k("k","less"),n.push("}"),n.push("++less"),n.push("}else{"),n.push("while(true){"),w("comp","great",1),n.push("if(comp>0){"),n.push("great--"),n.push("}else if(comp<0){"),M("k","less","great"),n.push("break"),n.push("}else{"),A("k","great"),n.push("break"),n.push("}"),n.push("}"),n.push("}"),n.push("}"),n.push("}else{"),n.push("for(k=less;k<=great;++k){"),w("comp_pivot1","k",1),n.push("if(comp_pivot1<0){"),n.push("if(k!==less){"),k("k","less"),n.push("}"),n.push("++less"),n.push("}else{"),w("comp_pivot2","k",2),n.push("if(comp_pivot2>0){"),n.push("while(true){"),w("comp","great",2),n.push("if(comp>0){"),n.push("if(--greatindex5){"),E("less",1,"++less"),E("great",2,"--great"),n.push("for(k=less;k<=great;++k){"),w("comp_pivot1","k",1),n.push("if(comp_pivot1===0){"),n.push("if(k!==less){"),k("k","less"),n.push("}"),n.push("++less"),n.push("}else{"),w("comp_pivot2","k",2),n.push("if(comp_pivot2===0){"),n.push("while(true){"),w("comp","great",2),n.push("if(comp===0){"),n.push("if(--great1&&c?new Function("insertionSort","malloc","free",n.join("\n"))(r,c[0],c[1]):new Function("insertionSort",n.join("\n"))(r)}(t,e,v);return m(v,y)}},{"typedarray-pool":507}],415:[function(t,e,r){"use strict";var n=t("./lib/compile_sort.js"),i={};e.exports=function(t){var e=t.order,r=t.dtype,a=[e,r].join(":"),o=i[a];return o||(i[a]=o=n(e,r)),o(t),t}},{"./lib/compile_sort.js":414}],416:[function(t,e,r){"use strict";var n=t("ndarray-linear-interpolate"),i=t("cwise/lib/wrapper")({args:["index","array","scalar","scalar","scalar"],pre:{body:"{this_warped=new Array(_inline_3_arg4_)}",args:[{name:"_inline_3_arg0_",lvalue:!1,rvalue:!1,count:0},{name:"_inline_3_arg1_",lvalue:!1,rvalue:!1,count:0},{name:"_inline_3_arg2_",lvalue:!1,rvalue:!1,count:0},{name:"_inline_3_arg3_",lvalue:!1,rvalue:!1,count:0},{name:"_inline_3_arg4_",lvalue:!1,rvalue:!0,count:1}],thisVars:["this_warped"],localVars:[]},body:{body:"{_inline_4_arg2_(this_warped,_inline_4_arg0_),_inline_4_arg1_=_inline_4_arg3_.apply(void 0,this_warped)}",args:[{name:"_inline_4_arg0_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_4_arg1_",lvalue:!0,rvalue:!1,count:1},{name:"_inline_4_arg2_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_4_arg3_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_4_arg4_",lvalue:!1,rvalue:!1,count:0}],thisVars:["this_warped"],localVars:[]},post:{body:"{}",args:[],thisVars:[],localVars:[]},debug:!1,funcName:"warpND",blockSize:64}),a=t("cwise/lib/wrapper")({args:["index","array","scalar","scalar","scalar"],pre:{body:"{this_warped=[0]}",args:[],thisVars:["this_warped"],localVars:[]},body:{body:"{_inline_7_arg2_(this_warped,_inline_7_arg0_),_inline_7_arg1_=_inline_7_arg3_(_inline_7_arg4_,this_warped[0])}",args:[{name:"_inline_7_arg0_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_7_arg1_",lvalue:!0,rvalue:!1,count:1},{name:"_inline_7_arg2_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_7_arg3_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_7_arg4_",lvalue:!1,rvalue:!0,count:1}],thisVars:["this_warped"],localVars:[]},post:{body:"{}",args:[],thisVars:[],localVars:[]},debug:!1,funcName:"warp1D",blockSize:64}),o=t("cwise/lib/wrapper")({args:["index","array","scalar","scalar","scalar"],pre:{body:"{this_warped=[0,0]}",args:[],thisVars:["this_warped"],localVars:[]},body:{body:"{_inline_10_arg2_(this_warped,_inline_10_arg0_),_inline_10_arg1_=_inline_10_arg3_(_inline_10_arg4_,this_warped[0],this_warped[1])}",args:[{name:"_inline_10_arg0_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_10_arg1_",lvalue:!0,rvalue:!1,count:1},{name:"_inline_10_arg2_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_10_arg3_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_10_arg4_",lvalue:!1,rvalue:!0,count:1}],thisVars:["this_warped"],localVars:[]},post:{body:"{}",args:[],thisVars:[],localVars:[]},debug:!1,funcName:"warp2D",blockSize:64}),s=t("cwise/lib/wrapper")({args:["index","array","scalar","scalar","scalar"],pre:{body:"{this_warped=[0,0,0]}",args:[],thisVars:["this_warped"],localVars:[]},body:{body:"{_inline_13_arg2_(this_warped,_inline_13_arg0_),_inline_13_arg1_=_inline_13_arg3_(_inline_13_arg4_,this_warped[0],this_warped[1],this_warped[2])}",args:[{name:"_inline_13_arg0_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_13_arg1_",lvalue:!0,rvalue:!1,count:1},{name:"_inline_13_arg2_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_13_arg3_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_13_arg4_",lvalue:!1,rvalue:!0,count:1}],thisVars:["this_warped"],localVars:[]},post:{body:"{}",args:[],thisVars:[],localVars:[]},debug:!1,funcName:"warp3D",blockSize:64});e.exports=function(t,e,r){switch(e.shape.length){case 1:a(t,r,n.d1,e);break;case 2:o(t,r,n.d2,e);break;case 3:s(t,r,n.d3,e);break;default:i(t,r,n.bind(void 0,e),e.shape.length)}return t}},{"cwise/lib/wrapper":136,"ndarray-linear-interpolate":410}],417:[function(t,e,r){var n=t("iota-array"),i=t("is-buffer"),a="undefined"!=typeof Float64Array;function o(t,e){return t[0]-e[0]}function s(){var t,e=this.stride,r=new Array(e.length);for(t=0;tMath.abs(this.stride[1]))?[1,0]:[0,1]}})"):3===e&&a.push("var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);if(s0>s1){if(s1>s2){return [2,1,0];}else if(s0>s2){return [1,2,0];}else{return [1,0,2];}}else if(s0>s2){return [2,0,1];}else if(s2>s1){return [0,1,2];}else{return [0,2,1];}}})")):a.push("ORDER})")),a.push("proto.set=function "+r+"_set("+l.join(",")+",v){"),i?a.push("return this.data.set("+u+",v)}"):a.push("return this.data["+u+"]=v}"),a.push("proto.get=function "+r+"_get("+l.join(",")+"){"),i?a.push("return this.data.get("+u+")}"):a.push("return this.data["+u+"]}"),a.push("proto.index=function "+r+"_index(",l.join(),"){return "+u+"}"),a.push("proto.hi=function "+r+"_hi("+l.join(",")+"){return new "+r+"(this.data,"+o.map(function(t){return["(typeof i",t,"!=='number'||i",t,"<0)?this.shape[",t,"]:i",t,"|0"].join("")}).join(",")+","+o.map(function(t){return"this.stride["+t+"]"}).join(",")+",this.offset)}");var p=o.map(function(t){return"a"+t+"=this.shape["+t+"]"}),d=o.map(function(t){return"c"+t+"=this.stride["+t+"]"});a.push("proto.lo=function "+r+"_lo("+l.join(",")+"){var b=this.offset,d=0,"+p.join(",")+","+d.join(","));for(var g=0;g=0){d=i"+g+"|0;b+=c"+g+"*d;a"+g+"-=d}");a.push("return new "+r+"(this.data,"+o.map(function(t){return"a"+t}).join(",")+","+o.map(function(t){return"c"+t}).join(",")+",b)}"),a.push("proto.step=function "+r+"_step("+l.join(",")+"){var "+o.map(function(t){return"a"+t+"=this.shape["+t+"]"}).join(",")+","+o.map(function(t){return"b"+t+"=this.stride["+t+"]"}).join(",")+",c=this.offset,d=0,ceil=Math.ceil");for(g=0;g=0){c=(c+this.stride["+g+"]*i"+g+")|0}else{a.push(this.shape["+g+"]);b.push(this.stride["+g+"])}");return a.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}"),a.push("return function construct_"+r+"(data,shape,stride,offset){return new "+r+"(data,"+o.map(function(t){return"shape["+t+"]"}).join(",")+","+o.map(function(t){return"stride["+t+"]"}).join(",")+",offset)}"),new Function("CTOR_LIST","ORDER",a.join("\n"))(c[t],s)}var c={float32:[],float64:[],int8:[],int16:[],int32:[],uint8:[],uint16:[],uint32:[],array:[],uint8_clamped:[],buffer:[],generic:[]};e.exports=function(t,e,r,n){if(void 0===t)return(0,c.array[0])([]);"number"==typeof t&&(t=[t]),void 0===e&&(e=[t.length]);var o=e.length;if(void 0===r){r=new Array(o);for(var s=o-1,u=1;s>=0;--s)r[s]=u,u*=e[s]}if(void 0===n)for(n=0,s=0;s>>0;e.exports=function(t,e){if(isNaN(t)||isNaN(e))return NaN;if(t===e)return t;if(0===t)return e<0?-i:i;var r=n.hi(t),o=n.lo(t);e>t==t>0?o===a?(r+=1,o=0):o+=1:0===o?(o=a,r-=1):o-=1;return n.pack(o,r)}},{"double-bits":151}],419:[function(t,e,r){var n=Math.PI,i=c(120);function a(t,e,r,n){return["C",t,e,r,n,r,n]}function o(t,e,r,n,i,a){return["C",t/3+2/3*r,e/3+2/3*n,i/3+2/3*r,a/3+2/3*n,i,a]}function s(t,e,r,a,o,c,u,h,f,p){if(p)k=p[0],M=p[1],_=p[2],w=p[3];else{var d=l(t,e,-o);t=d.x,e=d.y;var g=(t-(h=(d=l(h,f,-o)).x))/2,m=(e-(f=d.y))/2,v=g*g/(r*r)+m*m/(a*a);v>1&&(r*=v=Math.sqrt(v),a*=v);var y=r*r,x=a*a,b=(c==u?-1:1)*Math.sqrt(Math.abs((y*x-y*m*m-x*g*g)/(y*m*m+x*g*g)));b==1/0&&(b=1);var _=b*r*m/a+(t+h)/2,w=b*-a*g/r+(e+f)/2,k=Math.asin(((e-w)/a).toFixed(9)),M=Math.asin(((f-w)/a).toFixed(9));(k=t<_?n-k:k)<0&&(k=2*n+k),(M=h<_?n-M:M)<0&&(M=2*n+M),u&&k>M&&(k-=2*n),!u&&M>k&&(M-=2*n)}if(Math.abs(M-k)>i){var A=M,T=h,S=f;M=k+i*(u&&M>k?1:-1);var E=s(h=_+r*Math.cos(M),f=w+a*Math.sin(M),r,a,o,0,u,T,S,[M,A,_,w])}var C=Math.tan((M-k)/4),L=4/3*r*C,z=4/3*a*C,P=[2*t-(t+L*Math.sin(k)),2*e-(e-z*Math.cos(k)),h+L*Math.sin(M),f-z*Math.cos(M),h,f];if(p)return P;E&&(P=P.concat(E));for(var I=0;I7&&(r.push(v.splice(0,7)),v.unshift("C"));break;case"S":var x=p,b=d;"C"!=e&&"S"!=e||(x+=x-n,b+=b-i),v=["C",x,b,v[1],v[2],v[3],v[4]];break;case"T":"Q"==e||"T"==e?(h=2*p-h,f=2*d-f):(h=p,f=d),v=o(p,d,h,f,v[1],v[2]);break;case"Q":h=v[1],f=v[2],v=o(p,d,v[1],v[2],v[3],v[4]);break;case"L":v=a(p,d,v[1],v[2]);break;case"H":v=a(p,d,v[1],d);break;case"V":v=a(p,d,p,v[1]);break;case"Z":v=a(p,d,l,u)}e=y,p=v[v.length-2],d=v[v.length-1],v.length>4?(n=v[v.length-4],i=v[v.length-3]):(n=p,i=d),r.push(v)}return r}},{}],420:[function(t,e,r){r.vertexNormals=function(t,e,r){for(var n=e.length,i=new Array(n),a=void 0===r?1e-6:r,o=0;oa){var b=i[c],_=1/Math.sqrt(m*y);for(x=0;x<3;++x){var w=(x+1)%3,k=(x+2)%3;b[x]+=_*(v[w]*g[k]-v[k]*g[w])}}}for(o=0;oa)for(_=1/Math.sqrt(M),x=0;x<3;++x)b[x]*=_;else for(x=0;x<3;++x)b[x]=0}return i},r.faceNormals=function(t,e,r){for(var n=t.length,i=new Array(n),a=void 0===r?1e-6:r,o=0;oa?1/Math.sqrt(p):0;for(c=0;c<3;++c)f[c]*=p;i[o]=f}return i}},{}],421:[function(t,e,r){"use strict";var n=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var t=new String("abc");if(t[5]="de","5"===Object.getOwnPropertyNames(t)[0])return!1;for(var e={},r=0;r<10;r++)e["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(e).map(function(t){return e[t]}).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(t){n[t]=t}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(t){return!1}}()?Object.assign:function(t,e){for(var r,o,s=function(t){if(null==t)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(t)}(t),l=1;l0){var h=Math.sqrt(u+1);t[0]=.5*(o-l)/h,t[1]=.5*(s-n)/h,t[2]=.5*(r-a)/h,t[3]=.5*h}else{var f=Math.max(e,a,c),h=Math.sqrt(2*f-u+1);e>=f?(t[0]=.5*h,t[1]=.5*(i+r)/h,t[2]=.5*(s+n)/h,t[3]=.5*(o-l)/h):a>=f?(t[0]=.5*(r+i)/h,t[1]=.5*h,t[2]=.5*(l+o)/h,t[3]=.5*(s-n)/h):(t[0]=.5*(n+s)/h,t[1]=.5*(o+l)/h,t[2]=.5*h,t[3]=.5*(r-i)/h)}return t}},{}],423:[function(t,e,r){"use strict";e.exports=function(t){var e=(t=t||{}).center||[0,0,0],r=t.rotation||[0,0,0,1],n=t.radius||1;e=[].slice.call(e,0,3),u(r=[].slice.call(r,0,4),r);var i=new h(r,e,Math.log(n));i.setDistanceLimits(t.zoomMin,t.zoomMax),("eye"in t||"up"in t)&&i.lookAt(0,t.eye,t.center,t.up);return i};var n=t("filtered-vector"),i=t("gl-mat4/lookAt"),a=t("gl-mat4/fromQuat"),o=t("gl-mat4/invert"),s=t("./lib/quatFromFrame");function l(t,e,r){return Math.sqrt(Math.pow(t,2)+Math.pow(e,2)+Math.pow(r,2))}function c(t,e,r,n){return Math.sqrt(Math.pow(t,2)+Math.pow(e,2)+Math.pow(r,2)+Math.pow(n,2))}function u(t,e){var r=e[0],n=e[1],i=e[2],a=e[3],o=c(r,n,i,a);o>1e-6?(t[0]=r/o,t[1]=n/o,t[2]=i/o,t[3]=a/o):(t[0]=t[1]=t[2]=0,t[3]=1)}function h(t,e,r){this.radius=n([r]),this.center=n(e),this.rotation=n(t),this.computedRadius=this.radius.curve(0),this.computedCenter=this.center.curve(0),this.computedRotation=this.rotation.curve(0),this.computedUp=[.1,0,0],this.computedEye=[.1,0,0],this.computedMatrix=[.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.recalcMatrix(0)}var f=h.prototype;f.lastT=function(){return Math.max(this.radius.lastT(),this.center.lastT(),this.rotation.lastT())},f.recalcMatrix=function(t){this.radius.curve(t),this.center.curve(t),this.rotation.curve(t);var e=this.computedRotation;u(e,e);var r=this.computedMatrix;a(r,e);var n=this.computedCenter,i=this.computedEye,o=this.computedUp,s=Math.exp(this.computedRadius[0]);i[0]=n[0]+s*r[2],i[1]=n[1]+s*r[6],i[2]=n[2]+s*r[10],o[0]=r[1],o[1]=r[5],o[2]=r[9];for(var l=0;l<3;++l){for(var c=0,h=0;h<3;++h)c+=r[l+4*h]*i[h];r[12+l]=-c}},f.getMatrix=function(t,e){this.recalcMatrix(t);var r=this.computedMatrix;if(e){for(var n=0;n<16;++n)e[n]=r[n];return e}return r},f.idle=function(t){this.center.idle(t),this.radius.idle(t),this.rotation.idle(t)},f.flush=function(t){this.center.flush(t),this.radius.flush(t),this.rotation.flush(t)},f.pan=function(t,e,r,n){e=e||0,r=r||0,n=n||0,this.recalcMatrix(t);var i=this.computedMatrix,a=i[1],o=i[5],s=i[9],c=l(a,o,s);a/=c,o/=c,s/=c;var u=i[0],h=i[4],f=i[8],p=u*a+h*o+f*s,d=l(u-=a*p,h-=o*p,f-=s*p);u/=d,h/=d,f/=d;var g=i[2],m=i[6],v=i[10],y=g*a+m*o+v*s,x=g*u+m*h+v*f,b=l(g-=y*a+x*u,m-=y*o+x*h,v-=y*s+x*f);g/=b,m/=b,v/=b;var _=u*e+a*r,w=h*e+o*r,k=f*e+s*r;this.center.move(t,_,w,k);var M=Math.exp(this.computedRadius[0]);M=Math.max(1e-4,M+n),this.radius.set(t,Math.log(M))},f.rotate=function(t,e,r,n){this.recalcMatrix(t),e=e||0,r=r||0;var i=this.computedMatrix,a=i[0],o=i[4],s=i[8],u=i[1],h=i[5],f=i[9],p=i[2],d=i[6],g=i[10],m=e*a+r*u,v=e*o+r*h,y=e*s+r*f,x=-(d*y-g*v),b=-(g*m-p*y),_=-(p*v-d*m),w=Math.sqrt(Math.max(0,1-Math.pow(x,2)-Math.pow(b,2)-Math.pow(_,2))),k=c(x,b,_,w);k>1e-6?(x/=k,b/=k,_/=k,w/=k):(x=b=_=0,w=1);var M=this.computedRotation,A=M[0],T=M[1],S=M[2],E=M[3],C=A*w+E*x+T*_-S*b,L=T*w+E*b+S*x-A*_,z=S*w+E*_+A*b-T*x,P=E*w-A*x-T*b-S*_;if(n){x=p,b=d,_=g;var I=Math.sin(n)/l(x,b,_);x*=I,b*=I,_*=I,P=P*(w=Math.cos(e))-(C=C*w+P*x+L*_-z*b)*x-(L=L*w+P*b+z*x-C*_)*b-(z=z*w+P*_+C*b-L*x)*_}var O=c(C,L,z,P);O>1e-6?(C/=O,L/=O,z/=O,P/=O):(C=L=z=0,P=1),this.rotation.set(t,C,L,z,P)},f.lookAt=function(t,e,r,n){this.recalcMatrix(t),r=r||this.computedCenter,e=e||this.computedEye,n=n||this.computedUp;var a=this.computedMatrix;i(a,e,r,n);var o=this.computedRotation;s(o,a[0],a[1],a[2],a[4],a[5],a[6],a[8],a[9],a[10]),u(o,o),this.rotation.set(t,o[0],o[1],o[2],o[3]);for(var l=0,c=0;c<3;++c)l+=Math.pow(r[c]-e[c],2);this.radius.set(t,.5*Math.log(Math.max(l,1e-6))),this.center.set(t,r[0],r[1],r[2])},f.translate=function(t,e,r,n){this.center.move(t,e||0,r||0,n||0)},f.setMatrix=function(t,e){var r=this.computedRotation;s(r,e[0],e[1],e[2],e[4],e[5],e[6],e[8],e[9],e[10]),u(r,r),this.rotation.set(t,r[0],r[1],r[2],r[3]);var n=this.computedMatrix;o(n,e);var i=n[15];if(Math.abs(i)>1e-6){var a=n[12]/i,l=n[13]/i,c=n[14]/i;this.recalcMatrix(t);var h=Math.exp(this.computedRadius[0]);this.center.set(t,a-n[2]*h,l-n[6]*h,c-n[10]*h),this.radius.idle(t)}else this.center.idle(t),this.radius.idle(t)},f.setDistance=function(t,e){e>0&&this.radius.set(t,Math.log(e))},f.setDistanceLimits=function(t,e){t=t>0?Math.log(t):-1/0,e=e>0?Math.log(e):1/0,e=Math.max(e,t),this.radius.bounds[0][0]=t,this.radius.bounds[1][0]=e},f.getDistanceLimits=function(t){var e=this.radius.bounds;return t?(t[0]=Math.exp(e[0][0]),t[1]=Math.exp(e[1][0]),t):[Math.exp(e[0][0]),Math.exp(e[1][0])]},f.toJSON=function(){return this.recalcMatrix(this.lastT()),{center:this.computedCenter.slice(),rotation:this.computedRotation.slice(),distance:Math.log(this.computedRadius[0]),zoomMin:this.radius.bounds[0][0],zoomMax:this.radius.bounds[1][0]}},f.fromJSON=function(t){var e=this.lastT(),r=t.center;r&&this.center.set(e,r[0],r[1],r[2]);var n=t.rotation;n&&this.rotation.set(e,n[0],n[1],n[2],n[3]);var i=t.distance;i&&i>0&&this.radius.set(e,Math.log(i)),this.setDistanceLimits(t.zoomMin,t.zoomMax)}},{"./lib/quatFromFrame":422,"filtered-vector":215,"gl-mat4/fromQuat":251,"gl-mat4/invert":254,"gl-mat4/lookAt":255}],424:[function(t,e,r){"use strict";var n=t("repeat-string");e.exports=function(t,e,r){return n(r="undefined"!=typeof r?r+"":" ",e)+t}},{"repeat-string":464}],425:[function(t,e,r){"use strict";function n(t,e){if("string"!=typeof t)return[t];var r=[t];"string"==typeof e||Array.isArray(e)?e={brackets:e}:e||(e={});var n=e.brackets?Array.isArray(e.brackets)?e.brackets:[e.brackets]:["{}","[]","()"],i=e.escape||"___",a=!!e.flat;n.forEach(function(t){var e=new RegExp(["\\",t[0],"[^\\",t[0],"\\",t[1],"]*\\",t[1]].join("")),n=[];function a(e,a,o){var s=r.push(e.slice(t[0].length,-t[1].length))-1;return n.push(s),i+s}r.forEach(function(t,n){for(var i,o=0;t!=i;)if(i=t,t=t.replace(e,a),o++>1e4)throw Error("References have circular dependency. Please, check them.");r[n]=t}),n=n.reverse(),r=r.map(function(e){return n.forEach(function(r){e=e.replace(new RegExp("(\\"+i+r+"(?![0-9]))","g"),t[0]+"$1"+t[1])}),e})});var o=new RegExp("\\"+i+"([0-9]+)");return a?r:function t(e,r,n){for(var i,a=[],s=0;i=o.exec(e);){if(s++>1e4)throw Error("Circular references in parenthesis");a.push(e.slice(0,i.index)),a.push(t(r[i[1]],r)),e=e.slice(i.index+i[0].length)}return a.push(e),a}(r[0],r)}function i(t,e){if(e&&e.flat){var r,n=e&&e.escape||"___",i=t[0];if(!i)return"";for(var a=new RegExp("\\"+n+"([0-9]+)"),o=0;i!=r;){if(o++>1e4)throw Error("Circular references in "+t);r=i,i=i.replace(a,s)}return i}return t.reduce(function t(e,r){return Array.isArray(r)&&(r=r.reduce(t,"")),e+r},"");function s(e,r){if(null==t[r])throw Error("Reference "+r+"is undefined");return t[r]}}function a(t,e){return Array.isArray(t)?i(t,e):n(t,e)}a.parse=n,a.stringify=i,e.exports=a},{}],426:[function(t,e,r){"use strict";var n=t("pick-by-alias");e.exports=function(t){var e;arguments.length>1&&(t=arguments);"string"==typeof t?t=t.split(/\s/).map(parseFloat):"number"==typeof t&&(t=[t]);t.length&&"number"==typeof t[0]?e=1===t.length?{width:t[0],height:t[0],x:0,y:0}:2===t.length?{width:t[0],height:t[1],x:0,y:0}:{x:t[0],y:t[1],width:t[2]-t[0]||0,height:t[3]-t[1]||0}:t&&(t=n(t,{left:"x l left Left",top:"y t top Top",width:"w width W Width",height:"h height W Width",bottom:"b bottom Bottom",right:"r right Right"}),e={x:t.left||0,y:t.top||0},null==t.width?t.right?e.width=t.right-e.x:e.width=0:e.width=t.width,null==t.height?t.bottom?e.height=t.bottom-e.y:e.height=0:e.height=t.height);return e}},{"pick-by-alias":432}],427:[function(t,e,r){e.exports=function(t){var e=[];return t.replace(i,function(t,r,i){var o=r.toLowerCase();for(i=function(t){var e=t.match(a);return e?e.map(Number):[]}(i),"m"==o&&i.length>2&&(e.push([r].concat(i.splice(0,2))),o="l",r="m"==r?"l":"L");;){if(i.length==n[o])return i.unshift(r),e.push(i);if(i.length0;--o)a=l[o],r=s[o],s[o]=s[a],s[a]=r,l[o]=l[r],l[r]=a,c=(c+r)*o;return n.freeUint32(l),n.freeUint32(s),c},r.unrank=function(t,e,r){switch(t){case 0:return r||[];case 1:return r?(r[0]=0,r):[0];case 2:return r?(e?(r[0]=0,r[1]=1):(r[0]=1,r[1]=0),r):e?[0,1]:[1,0]}var n,i,a,o=1;for((r=r||new Array(t))[0]=0,a=1;a0;--a)e=e-(n=e/o|0)*o|0,o=o/a|0,i=0|r[a],r[a]=0|r[n],r[n]=0|i;return r}},{"invert-permutation":383,"typedarray-pool":507}],432:[function(t,e,r){"use strict";e.exports=function(t,e,r){var n,a,o={};if("string"==typeof e&&(e=i(e)),Array.isArray(e)){var s={};for(a=0;a0){o=a[u][r][0],l=u;break}s=o[1^l];for(var h=0;h<2;++h)for(var f=a[h][r],p=0;p0&&(o=d,s=g,l=h)}return i?s:(o&&c(o,l),s)}function h(t,r){var i=a[r][t][0],o=[t];c(i,r);for(var s=i[1^r];;){for(;s!==t;)o.push(s),s=u(o[o.length-2],s,!1);if(a[0][t].length+a[1][t].length===0)break;var l=o[o.length-1],h=t,f=o[1],p=u(l,h,!0);if(n(e[l],e[h],e[f],e[p])<0)break;o.push(t),s=u(l,h)}return o}function f(t,e){return e[1]===e[e.length-1]}for(var o=0;o0;){a[0][o].length;var g=h(o,p);f(d,g)?d.push.apply(d,g):(d.length>0&&l.push(d),d=g)}d.length>0&&l.push(d)}return l};var n=t("compare-angle")},{"compare-angle":114}],434:[function(t,e,r){"use strict";e.exports=function(t,e){for(var r=n(t,e.length),i=new Array(e.length),a=new Array(e.length),o=[],s=0;s0;){var c=o.pop();i[c]=!1;for(var u=r[c],s=0;s0})).length,m=new Array(g),v=new Array(g),p=0;p0;){var N=B.pop(),j=C[N];l(j,function(t,e){return t-e});var V,U=j.length,q=F[N];if(0===q){var k=d[N];V=[k]}for(var p=0;p=0)&&(F[H]=1^q,B.push(H),0===q)){var k=d[H];R(k)||(k.reverse(),V.push(k))}}0===q&&r.push(V)}return r};var n=t("edges-to-adjacency-list"),i=t("planar-dual"),a=t("point-in-big-polygon"),o=t("two-product"),s=t("robust-sum"),l=t("uniq"),c=t("./lib/trim-leaves");function u(t,e){for(var r=new Array(t),n=0;n>>1;e.dtype||(e.dtype="array"),"string"==typeof e.dtype?d=new(h(e.dtype))(m):e.dtype&&(d=e.dtype,Array.isArray(d)&&(d.length=m));for(var v=0;vr){for(var f=0;fl||A>c||T=C||o===s)){var u=y[a];void 0===s&&(s=u.length);for(var h=o;h=g&&p<=v&&d>=m&&d<=w&&z.push(f)}var b=x[a],_=b[4*o+0],k=b[4*o+1],E=b[4*o+2],L=b[4*o+3],P=function(t,e){for(var r=null,n=0;null===r;)if(r=t[4*e+n],++n>t.length)return null;return r}(b,o+1),I=.5*i,O=a+1;e(r,n,I,O,_,k||E||L||P),e(r,n+I,I,O,k,E||L||P),e(r+I,n,I,O,E,L||P),e(r+I,n+I,I,O,L,P)}}}(0,0,1,0,0,1),z},d;function E(t,e,r){for(var n=1,i=.5,a=.5,o=.5,s=0;s0&&e[i]===r[0]))return 1;a=t[i-1]}for(var s=1;a;){var l=a.key,c=n(r,l[0],l[1]);if(l[0][0]0))return 0;s=-1,a=a.right}else if(c>0)a=a.left;else{if(!(c<0))return 0;s=1,a=a.right}}return s}}(v.slabs,v.coordinates);return 0===a.length?y:function(t,e){return function(r){return t(r[0],r[1])?0:e(r)}}(l(a),y)};var n=t("robust-orientation")[3],i=t("slab-decomposition"),a=t("interval-tree-1d"),o=t("binary-search-bounds");function s(){return!0}function l(t){for(var e={},r=0;r=-t},pointBetween:function(e,r,n){var i=e[1]-r[1],a=n[0]-r[0],o=e[0]-r[0],s=n[1]-r[1],l=o*a+i*s;return!(l-t)},pointsSameX:function(e,r){return Math.abs(e[0]-r[0])t!=o-i>t&&(a-c)*(i-u)/(o-u)+c-n>t&&(s=!s),a=c,o=u}return s}};return e}},{}],443:[function(t,e,r){var n={toPolygon:function(t,e){function r(e){if(e.length<=0)return t.segments({inverted:!1,regions:[]});function r(e){var r=e.slice(0,e.length-1);return t.segments({inverted:!1,regions:[r]})}for(var n=r(e[0]),i=1;i0})}function u(t,n){var i=t.seg,a=n.seg,o=i.start,s=i.end,c=a.start,u=a.end;r&&r.checkIntersection(i,a);var h=e.linesIntersect(o,s,c,u);if(!1===h){if(!e.pointsCollinear(o,s,c))return!1;if(e.pointsSame(o,u)||e.pointsSame(s,c))return!1;var f=e.pointsSame(o,c),p=e.pointsSame(s,u);if(f&&p)return n;var d=!f&&e.pointBetween(o,c,u),g=!p&&e.pointBetween(s,c,u);if(f)return g?l(n,s):l(t,u),n;d&&(p||(g?l(n,s):l(t,u)),l(n,o))}else 0===h.alongA&&(-1===h.alongB?l(t,c):0===h.alongB?l(t,h.pt):1===h.alongB&&l(t,u)),0===h.alongB&&(-1===h.alongA?l(n,o):0===h.alongA?l(n,h.pt):1===h.alongA&&l(n,s));return!1}for(var h=[];!a.isEmpty();){var f=a.getHead();if(r&&r.vert(f.pt[0]),f.isStart){r&&r.segmentNew(f.seg,f.primary);var p=c(f),d=p.before?p.before.ev:null,g=p.after?p.after.ev:null;function m(){if(d){var t=u(f,d);if(t)return t}return!!g&&u(f,g)}r&&r.tempStatus(f.seg,!!d&&d.seg,!!g&&g.seg);var v,y,x=m();if(x)t?(y=null===f.seg.myFill.below||f.seg.myFill.above!==f.seg.myFill.below)&&(x.seg.myFill.above=!x.seg.myFill.above):x.seg.otherFill=f.seg.myFill,r&&r.segmentUpdate(x.seg),f.other.remove(),f.remove();if(a.getHead()!==f){r&&r.rewind(f.seg);continue}t?(y=null===f.seg.myFill.below||f.seg.myFill.above!==f.seg.myFill.below,f.seg.myFill.below=g?g.seg.myFill.above:i,f.seg.myFill.above=y?!f.seg.myFill.below:f.seg.myFill.below):null===f.seg.otherFill&&(v=g?f.primary===g.primary?g.seg.otherFill.above:g.seg.myFill.above:f.primary?o:i,f.seg.otherFill={above:v,below:v}),r&&r.status(f.seg,!!d&&d.seg,!!g&&g.seg),f.other.status=p.insert(n.node({ev:f}))}else{var b=f.status;if(null===b)throw new Error("PolyBool: Zero-length segment detected; your epsilon is probably too small or too large");if(s.exists(b.prev)&&s.exists(b.next)&&u(b.prev.ev,b.next.ev),r&&r.statusRemove(b.ev.seg),b.remove(),!f.primary){var _=f.seg.myFill;f.seg.myFill=f.seg.otherFill,f.seg.otherFill=_}h.push(f.seg)}a.getHead().remove()}return r&&r.done(),h}return t?{addRegion:function(t){for(var n,i,a,o=t[t.length-1],l=0;l=c?(M=1,y=c+2*f+d):y=f*(M=-f/c)+d):(M=0,p>=0?(A=0,y=d):-p>=h?(A=1,y=h+2*p+d):y=p*(A=-p/h)+d);else if(A<0)A=0,f>=0?(M=0,y=d):-f>=c?(M=1,y=c+2*f+d):y=f*(M=-f/c)+d;else{var T=1/k;y=(M*=T)*(c*M+u*(A*=T)+2*f)+A*(u*M+h*A+2*p)+d}else M<0?(b=h+p)>(x=u+f)?(_=b-x)>=(w=c-2*u+h)?(M=1,A=0,y=c+2*f+d):y=(M=_/w)*(c*M+u*(A=1-M)+2*f)+A*(u*M+h*A+2*p)+d:(M=0,b<=0?(A=1,y=h+2*p+d):p>=0?(A=0,y=d):y=p*(A=-p/h)+d):A<0?(b=c+f)>(x=u+p)?(_=b-x)>=(w=c-2*u+h)?(A=1,M=0,y=h+2*p+d):y=(M=1-(A=_/w))*(c*M+u*A+2*f)+A*(u*M+h*A+2*p)+d:(A=0,b<=0?(M=1,y=c+2*f+d):f>=0?(M=0,y=d):y=f*(M=-f/c)+d):(_=h+p-u-f)<=0?(M=0,A=1,y=h+2*p+d):_>=(w=c-2*u+h)?(M=1,A=0,y=c+2*f+d):y=(M=_/w)*(c*M+u*(A=1-M)+2*f)+A*(u*M+h*A+2*p)+d;var S=1-M-A;for(l=0;l1)for(var r=1;r0){var c=t[r-1];if(0===n(s,c)&&a(c)!==l){r-=1;continue}}t[r++]=s}}return t.length=r,t}},{"cell-orientation":99,"compare-cell":115,"compare-oriented-cell":116}],457:[function(t,e,r){"use strict";var n=t("array-bounds"),i=t("color-normalize"),a=t("update-diff"),o=t("pick-by-alias"),s=t("object-assign"),l=t("flatten-vertex-data"),c=t("to-float32"),u=c.float32,h=c.fract32;e.exports=function(t,e){"function"==typeof t?(e||(e={}),e.regl=t):e=t;e.length&&(e.positions=e);if(!(t=e.regl).hasExtension("ANGLE_instanced_arrays"))throw Error("regl-error2d: `ANGLE_instanced_arrays` extension should be enabled");var r,c,p,d,g,m,v=t._gl,y={color:"black",capSize:5,lineWidth:1,opacity:1,viewport:null,range:null,offset:0,count:0,bounds:null,positions:[],errors:[]},x=[];return d=t.buffer({usage:"dynamic",type:"uint8",data:new Uint8Array(0)}),c=t.buffer({usage:"dynamic",type:"float",data:new Uint8Array(0)}),p=t.buffer({usage:"dynamic",type:"float",data:new Uint8Array(0)}),g=t.buffer({usage:"dynamic",type:"float",data:new Uint8Array(0)}),m=t.buffer({usage:"static",type:"float",data:f}),k(e),r=t({vert:"\n\t\tprecision highp float;\n\n\t\tattribute vec2 position, positionFract;\n\t\tattribute vec4 error;\n\t\tattribute vec4 color;\n\n\t\tattribute vec2 direction, lineOffset, capOffset;\n\n\t\tuniform vec4 viewport;\n\t\tuniform float lineWidth, capSize;\n\t\tuniform vec2 scale, scaleFract, translate, translateFract;\n\n\t\tvarying vec4 fragColor;\n\n\t\tvoid main() {\n\t\t\tfragColor = color / 255.;\n\n\t\t\tvec2 pixelOffset = lineWidth * lineOffset + (capSize + lineWidth) * capOffset;\n\n\t\t\tvec2 dxy = -step(.5, direction.xy) * error.xz + step(direction.xy, vec2(-.5)) * error.yw;\n\n\t\t\tvec2 position = position + dxy;\n\n\t\t\tvec2 pos = (position + translate) * scale\n\t\t\t\t+ (positionFract + translateFract) * scale\n\t\t\t\t+ (position + translate) * scaleFract\n\t\t\t\t+ (positionFract + translateFract) * scaleFract;\n\n\t\t\tpos += pixelOffset / viewport.zw;\n\n\t\t\tgl_Position = vec4(pos * 2. - 1., 0, 1);\n\t\t}\n\t\t",frag:"\n\t\tprecision mediump float;\n\n\t\tvarying vec4 fragColor;\n\n\t\tuniform float opacity;\n\n\t\tvoid main() {\n\t\t\tgl_FragColor = fragColor;\n\t\t\tgl_FragColor.a *= opacity;\n\t\t}\n\t\t",uniforms:{range:t.prop("range"),lineWidth:t.prop("lineWidth"),capSize:t.prop("capSize"),opacity:t.prop("opacity"),scale:t.prop("scale"),translate:t.prop("translate"),scaleFract:t.prop("scaleFract"),translateFract:t.prop("translateFract"),viewport:function(t,e){return[e.viewport.x,e.viewport.y,t.viewportWidth,t.viewportHeight]}},attributes:{color:{buffer:d,offset:function(t,e){return 4*e.offset},divisor:1},position:{buffer:c,offset:function(t,e){return 8*e.offset},divisor:1},positionFract:{buffer:p,offset:function(t,e){return 8*e.offset},divisor:1},error:{buffer:g,offset:function(t,e){return 16*e.offset},divisor:1},direction:{buffer:m,stride:24,offset:0},lineOffset:{buffer:m,stride:24,offset:8},capOffset:{buffer:m,stride:24,offset:16}},primitive:"triangles",blend:{enable:!0,color:[0,0,0,0],equation:{rgb:"add",alpha:"add"},func:{srcRGB:"src alpha",dstRGB:"one minus src alpha",srcAlpha:"one minus dst alpha",dstAlpha:"one"}},depth:{enable:!1},scissor:{enable:!0,box:t.prop("viewport")},viewport:t.prop("viewport"),stencil:!1,instances:t.prop("count"),count:f.length}),s(b,{update:k,draw:_,destroy:M,regl:t,gl:v,canvas:v.canvas,groups:x}),b;function b(t){t?k(t):null===t&&M(),_()}function _(e){if("number"==typeof e)return w(e);e&&!Array.isArray(e)&&(e=[e]),t._refresh(),x.forEach(function(t,r){t&&(e&&(e[r]?t.draw=!0:t.draw=!1),t.draw?w(r):t.draw=!0)})}function w(t){"number"==typeof t&&(t=x[t]),null!=t&&t&&t.count&&t.color&&t.opacity&&t.positions&&t.positions.length>1&&(t.scaleRatio=[t.scale[0]*t.viewport.width,t.scale[1]*t.viewport.height],r(t),t.after&&t.after(t))}function k(t){if(t){null!=t.length?"number"==typeof t[0]&&(t=[{positions:t}]):Array.isArray(t)||(t=[t]);var e=0,r=0;if(b.groups=x=t.map(function(t,c){var u=x[c];return t?("function"==typeof t?t={after:t}:"number"==typeof t[0]&&(t={positions:t}),t=o(t,{color:"color colors fill",capSize:"capSize cap capsize cap-size",lineWidth:"lineWidth line-width width line thickness",opacity:"opacity alpha",range:"range dataBox",viewport:"viewport viewBox",errors:"errors error",positions:"positions position data points"}),u||(x[c]=u={id:c,scale:null,translate:null,scaleFract:null,translateFract:null,draw:!0},t=s({},y,t)),a(u,t,[{lineWidth:function(t){return.5*+t},capSize:function(t){return.5*+t},opacity:parseFloat,errors:function(t){return t=l(t),r+=t.length,t},positions:function(t,r){return t=l(t,"float64"),r.count=Math.floor(t.length/2),r.bounds=n(t,2),r.offset=e,e+=r.count,t}},{color:function(t,e){var r=e.count;if(t||(t="transparent"),!Array.isArray(t)||"number"==typeof t[0]){var n=t;t=Array(r);for(var a=0;a 0. && baClipping < length(normalWidth * endBotJoin)) {\n\t\t//handle miter clipping\n\t\tbTopCoord -= normalWidth * endTopJoin;\n\t\tbTopCoord += normalize(endTopJoin * normalWidth) * baClipping;\n\t}\n\n\tif (nextReverse) {\n\t\t//make join rectangular\n\t\tvec2 miterShift = normalWidth * endJoinDirection * miterLimit * .5;\n\t\tfloat normalAdjust = 1. - min(miterLimit / endMiterRatio, 1.);\n\t\tbBotCoord = bCoord + miterShift - normalAdjust * normalWidth * currNormal * .5;\n\t\tbTopCoord = bCoord + miterShift + normalAdjust * normalWidth * currNormal * .5;\n\t}\n\telse if (!prevReverse && abClipping > 0. && abClipping < length(normalWidth * startBotJoin)) {\n\t\t//handle miter clipping\n\t\taBotCoord -= normalWidth * startBotJoin;\n\t\taBotCoord += normalize(startBotJoin * normalWidth) * abClipping;\n\t}\n\n\tvec2 aTopPosition = (aTopCoord) * scale + translate;\n\tvec2 aBotPosition = (aBotCoord) * scale + translate;\n\n\tvec2 bTopPosition = (bTopCoord) * scale + translate;\n\tvec2 bBotPosition = (bBotCoord) * scale + translate;\n\n\t//position is normalized 0..1 coord on the screen\n\tvec2 position = (aTopPosition * lineTop + aBotPosition * lineBot) * lineStart + (bTopPosition * lineTop + bBotPosition * lineBot) * lineEnd;\n\n\tstartCoord = aCoord * scaleRatio + translate * viewport.zw + viewport.xy;\n\tendCoord = bCoord * scaleRatio + translate * viewport.zw + viewport.xy;\n\n\tgl_Position = vec4(position * 2.0 - 1.0, depth, 1);\n\n\tenableStartMiter = step(dot(currTangent, prevTangent), .5);\n\tenableEndMiter = step(dot(currTangent, nextTangent), .5);\n\n\t//bevel miter cutoffs\n\tif (miterMode == 1.) {\n\t\tif (enableStartMiter == 1.) {\n\t\t\tvec2 startMiterWidth = vec2(startJoinDirection) * thickness * miterLimit * .5;\n\t\t\tstartCutoff = vec4(aCoord, aCoord);\n\t\t\tstartCutoff.zw += vec2(-startJoinDirection.y, startJoinDirection.x) / scaleRatio;\n\t\t\tstartCutoff = startCutoff * scaleRatio.xyxy + translate.xyxy * viewport.zwzw;\n\t\t\tstartCutoff += viewport.xyxy;\n\t\t\tstartCutoff += startMiterWidth.xyxy;\n\t\t}\n\n\t\tif (enableEndMiter == 1.) {\n\t\t\tvec2 endMiterWidth = vec2(endJoinDirection) * thickness * miterLimit * .5;\n\t\t\tendCutoff = vec4(bCoord, bCoord);\n\t\t\tendCutoff.zw += vec2(-endJoinDirection.y, endJoinDirection.x) / scaleRatio;\n\t\t\tendCutoff = endCutoff * scaleRatio.xyxy + translate.xyxy * viewport.zwzw;\n\t\t\tendCutoff += viewport.xyxy;\n\t\t\tendCutoff += endMiterWidth.xyxy;\n\t\t}\n\t}\n\n\t//round miter cutoffs\n\telse if (miterMode == 2.) {\n\t\tif (enableStartMiter == 1.) {\n\t\t\tvec2 startMiterWidth = vec2(startJoinDirection) * thickness * abs(dot(startJoinDirection, currNormal)) * .5;\n\t\t\tstartCutoff = vec4(aCoord, aCoord);\n\t\t\tstartCutoff.zw += vec2(-startJoinDirection.y, startJoinDirection.x) / scaleRatio;\n\t\t\tstartCutoff = startCutoff * scaleRatio.xyxy + translate.xyxy * viewport.zwzw;\n\t\t\tstartCutoff += viewport.xyxy;\n\t\t\tstartCutoff += startMiterWidth.xyxy;\n\t\t}\n\n\t\tif (enableEndMiter == 1.) {\n\t\t\tvec2 endMiterWidth = vec2(endJoinDirection) * thickness * abs(dot(endJoinDirection, currNormal)) * .5;\n\t\t\tendCutoff = vec4(bCoord, bCoord);\n\t\t\tendCutoff.zw += vec2(-endJoinDirection.y, endJoinDirection.x) / scaleRatio;\n\t\t\tendCutoff = endCutoff * scaleRatio.xyxy + translate.xyxy * viewport.zwzw;\n\t\t\tendCutoff += viewport.xyxy;\n\t\t\tendCutoff += endMiterWidth.xyxy;\n\t\t}\n\t}\n}\n"]),frag:o(["precision highp float;\n#define GLSLIFY 1\n\nuniform sampler2D dashPattern;\nuniform float dashSize, pixelRatio, thickness, opacity, id, miterMode;\n\nvarying vec4 fragColor;\nvarying vec2 tangent;\nvarying vec4 startCutoff, endCutoff;\nvarying vec2 startCoord, endCoord;\nvarying float enableStartMiter, enableEndMiter;\n\nfloat distToLine(vec2 p, vec2 a, vec2 b) {\n\tvec2 diff = b - a;\n\tvec2 perp = normalize(vec2(-diff.y, diff.x));\n\treturn dot(p - a, perp);\n}\n\nvoid main() {\n\tfloat alpha = 1., distToStart, distToEnd;\n\tfloat cutoff = thickness * .5;\n\n\t//bevel miter\n\tif (miterMode == 1.) {\n\t\tif (enableStartMiter == 1.) {\n\t\t\tdistToStart = distToLine(gl_FragCoord.xy, startCutoff.xy, startCutoff.zw);\n\t\t\tif (distToStart < -1.) {\n\t\t\t\tdiscard;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\talpha *= min(max(distToStart + 1., 0.), 1.);\n\t\t}\n\n\t\tif (enableEndMiter == 1.) {\n\t\t\tdistToEnd = distToLine(gl_FragCoord.xy, endCutoff.xy, endCutoff.zw);\n\t\t\tif (distToEnd < -1.) {\n\t\t\t\tdiscard;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\talpha *= min(max(distToEnd + 1., 0.), 1.);\n\t\t}\n\t}\n\n\t// round miter\n\telse if (miterMode == 2.) {\n\t\tif (enableStartMiter == 1.) {\n\t\t\tdistToStart = distToLine(gl_FragCoord.xy, startCutoff.xy, startCutoff.zw);\n\t\t\tif (distToStart < 0.) {\n\t\t\t\tfloat radius = length(gl_FragCoord.xy - startCoord);\n\n\t\t\t\tif(radius > cutoff + .5) {\n\t\t\t\t\tdiscard;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\talpha -= smoothstep(cutoff - .5, cutoff + .5, radius);\n\t\t\t}\n\t\t}\n\n\t\tif (enableEndMiter == 1.) {\n\t\t\tdistToEnd = distToLine(gl_FragCoord.xy, endCutoff.xy, endCutoff.zw);\n\t\t\tif (distToEnd < 0.) {\n\t\t\t\tfloat radius = length(gl_FragCoord.xy - endCoord);\n\n\t\t\t\tif(radius > cutoff + .5) {\n\t\t\t\t\tdiscard;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\talpha -= smoothstep(cutoff - .5, cutoff + .5, radius);\n\t\t\t}\n\t\t}\n\t}\n\n\tfloat t = fract(dot(tangent, gl_FragCoord.xy) / dashSize) * .5 + .25;\n\tfloat dash = texture2D(dashPattern, vec2(t, .5)).r;\n\n\tgl_FragColor = fragColor;\n\tgl_FragColor.a *= alpha * opacity * dash;\n}\n"]),attributes:{lineEnd:{buffer:r,divisor:0,stride:8,offset:0},lineTop:{buffer:r,divisor:0,stride:8,offset:4},aColor:{buffer:t.prop("colorBuffer"),stride:4,offset:0,divisor:1},bColor:{buffer:t.prop("colorBuffer"),stride:4,offset:4,divisor:1},prevCoord:{buffer:t.prop("positionBuffer"),stride:8,offset:0,divisor:1},aCoord:{buffer:t.prop("positionBuffer"),stride:8,offset:8,divisor:1},bCoord:{buffer:t.prop("positionBuffer"),stride:8,offset:16,divisor:1},nextCoord:{buffer:t.prop("positionBuffer"),stride:8,offset:24,divisor:1}}},n))}catch(t){e=i}return{fill:t({primitive:"triangle",elements:function(t,e){return e.triangles},offset:0,vert:o(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec2 position, positionFract;\n\nuniform vec4 color;\nuniform vec2 scale, scaleFract, translate, translateFract;\nuniform float pixelRatio, id;\nuniform vec4 viewport;\nuniform float opacity;\n\nvarying vec4 fragColor;\n\nconst float MAX_LINES = 256.;\n\nvoid main() {\n\tfloat depth = (MAX_LINES - 4. - id) / (MAX_LINES);\n\n\tvec2 position = position * scale + translate\n + positionFract * scale + translateFract\n + position * scaleFract\n + positionFract * scaleFract;\n\n\tgl_Position = vec4(position * 2.0 - 1.0, depth, 1);\n\n\tfragColor = color / 255.;\n\tfragColor.a *= opacity;\n}\n"]),frag:o(["precision highp float;\n#define GLSLIFY 1\n\nvarying vec4 fragColor;\n\nvoid main() {\n\tgl_FragColor = fragColor;\n}\n"]),uniforms:{scale:t.prop("scale"),color:t.prop("fill"),scaleFract:t.prop("scaleFract"),translateFract:t.prop("translateFract"),translate:t.prop("translate"),opacity:t.prop("opacity"),pixelRatio:t.context("pixelRatio"),id:t.prop("id"),viewport:function(t,e){return[e.viewport.x,e.viewport.y,t.viewportWidth,t.viewportHeight]}},attributes:{position:{buffer:t.prop("positionBuffer"),stride:8,offset:8},positionFract:{buffer:t.prop("positionFractBuffer"),stride:8,offset:8}},blend:n.blend,depth:{enable:!1},scissor:n.scissor,stencil:n.stencil,viewport:n.viewport}),rect:i,miter:e}},m.defaults={dashes:null,join:"miter",miterLimit:1,thickness:10,cap:"square",color:"black",opacity:1,overlay:!1,viewport:null,range:null,close:!1,fill:null},m.prototype.render=function(){for(var t,e=[],r=arguments.length;r--;)e[r]=arguments[r];e.length&&(t=this).update.apply(t,e),this.draw()},m.prototype.draw=function(){for(var t=this,e=[],r=arguments.length;r--;)e[r]=arguments[r];return(e.length?e:this.passes).forEach(function(e,r){if(e&&Array.isArray(e))return(n=t).draw.apply(n,e);var n;("number"==typeof e&&(e=t.passes[e]),e&&e.count>1&&e.opacity)&&(t.regl._refresh(),e.fill&&e.triangles&&e.triangles.length>2&&t.shaders.fill(e),e.thickness&&(e.scale[0]*e.viewport.width>m.precisionThreshold||e.scale[1]*e.viewport.height>m.precisionThreshold?t.shaders.rect(e):"rect"===e.join||!e.join&&(e.thickness<=2||e.count>=m.maxPoints)?t.shaders.rect(e):t.shaders.miter(e)))}),this},m.prototype.update=function(t){var e=this;if(t){null!=t.length?"number"==typeof t[0]&&(t=[{positions:t}]):Array.isArray(t)||(t=[t]);var r=this.regl,o=this.gl;if(t.forEach(function(t,h){var d=e.passes[h];if(void 0!==t)if(null!==t){if("number"==typeof t[0]&&(t={positions:t}),t=s(t,{positions:"positions points data coords",thickness:"thickness lineWidth lineWidths line-width linewidth width stroke-width strokewidth strokeWidth",join:"lineJoin linejoin join type mode",miterLimit:"miterlimit miterLimit",dashes:"dash dashes dasharray dash-array dashArray",color:"color colour stroke colors colours stroke-color strokeColor",fill:"fill fill-color fillColor",opacity:"alpha opacity",overlay:"overlay crease overlap intersect",close:"closed close closed-path closePath",range:"range dataBox",viewport:"viewport viewBox",hole:"holes hole hollow"}),d||(e.passes[h]=d={id:h,scale:null,scaleFract:null,translate:null,translateFract:null,count:0,hole:[],depth:0,dashLength:1,dashTexture:r.texture({channels:1,data:new Uint8Array([255]),width:1,height:1,mag:"linear",min:"linear"}),colorBuffer:r.buffer({usage:"dynamic",type:"uint8",data:new Uint8Array}),positionBuffer:r.buffer({usage:"dynamic",type:"float",data:new Uint8Array}),positionFractBuffer:r.buffer({usage:"dynamic",type:"float",data:new Uint8Array})},t=a({},m.defaults,t)),null!=t.thickness&&(d.thickness=parseFloat(t.thickness)),null!=t.opacity&&(d.opacity=parseFloat(t.opacity)),null!=t.miterLimit&&(d.miterLimit=parseFloat(t.miterLimit)),null!=t.overlay&&(d.overlay=!!t.overlay,h 1.0 + delta) {\n\t\tdiscard;\n\t}\n\n\talpha -= smoothstep(1.0 - delta, 1.0 + delta, radius);\n\n\tfloat borderRadius = fragBorderRadius;\n\tfloat ratio = smoothstep(borderRadius - delta, borderRadius + delta, radius);\n\tvec4 color = mix(fragColor, fragBorderColor, ratio);\n\tcolor.a *= alpha * opacity;\n\tgl_FragColor = color;\n}\n"]),u.vert=l(["precision highp float;\n#define GLSLIFY 1\n\nattribute float x, y, xFract, yFract;\nattribute float size, borderSize;\nattribute vec4 colorId, borderColorId;\nattribute float isActive;\n\nuniform vec2 scale, scaleFract, translate, translateFract;\nuniform float pixelRatio;\nuniform sampler2D palette;\nuniform vec2 paletteSize;\n\nconst float maxSize = 100.;\n\nvarying vec4 fragColor, fragBorderColor;\nvarying float fragBorderRadius, fragWidth;\n\nvec2 paletteCoord(float id) {\n return vec2(\n (mod(id, paletteSize.x) + .5) / paletteSize.x,\n (floor(id / paletteSize.x) + .5) / paletteSize.y\n );\n}\nvec2 paletteCoord(vec2 id) {\n return vec2(\n (id.x + .5) / paletteSize.x,\n (id.y + .5) / paletteSize.y\n );\n}\n\nvec4 getColor(vec4 id) {\n // zero-palette means we deal with direct buffer\n if (paletteSize.x == 0.) return id / 255.;\n return texture2D(palette, paletteCoord(id.xy));\n}\n\nvoid main() {\n // ignore inactive points\n if (isActive == 0.) return;\n\n vec2 position = vec2(x, y);\n vec2 positionFract = vec2(xFract, yFract);\n\n vec4 color = getColor(colorId);\n vec4 borderColor = getColor(borderColorId);\n\n float size = size * maxSize / 255.;\n float borderSize = borderSize * maxSize / 255.;\n\n gl_PointSize = (size + borderSize) * pixelRatio;\n\n vec2 pos = (position + translate) * scale\n + (positionFract + translateFract) * scale\n + (position + translate) * scaleFract\n + (positionFract + translateFract) * scaleFract;\n\n gl_Position = vec4(pos * 2. - 1., 0, 1);\n\n fragBorderRadius = 1. - 2. * borderSize / (size + borderSize);\n fragColor = color;\n fragBorderColor = borderColor.a == 0. || borderSize == 0. ? vec4(color.rgb, 0.) : borderColor;\n fragWidth = 1. / gl_PointSize;\n}\n"]),f&&(u.frag=u.frag.replace("smoothstep","smoothStep")),this.drawCircle=t(u)}e.exports=v,v.defaults={color:"black",borderColor:"transparent",borderSize:0,size:12,opacity:1,marker:void 0,viewport:null,range:null,pixelSize:null,count:0,offset:0,bounds:null,positions:[],snap:1e4},v.prototype.render=function(){for(var t,e=[],r=arguments.length;r--;)e[r]=arguments[r];return e.length&&(t=this).update.apply(t,e),this.draw(),this},v.prototype.draw=function(){for(var t=this,e=[],r=arguments.length;r--;)e[r]=arguments[r];var n=this.groups;if(1===e.length&&Array.isArray(e[0])&&(null===e[0][0]||Array.isArray(e[0][0]))&&(e=e[0]),this.regl._refresh(),e.length)for(var i=0;in)?e.tree=o(t,{bounds:f}):n&&n.length&&(e.tree=n),e.tree){var p={primitive:"points",usage:"static",data:e.tree,type:"uint32"};e.elements?e.elements(p):e.elements=l.elements(p)}return a({data:d(t),usage:"dynamic"}),s({data:g(t),usage:"dynamic"}),c({data:new Uint8Array(u),type:"uint8",usage:"stream"}),t}},{marker:function(e,r,n){var i=r.activation;if(i.forEach(function(t){return t&&t.destroy&&t.destroy()}),i.length=0,e&&"number"!=typeof e[0]){for(var a=[],o=0,s=Math.min(e.length,r.count);o=0)return a;if(t instanceof Uint8Array||t instanceof Uint8ClampedArray)e=t;else{e=new Uint8Array(t.length);for(var o=0,s=t.length;oi*i*4&&(this.tooManyColors=!0),this.updatePalette(r),1===o.length?o[0]:o},v.prototype.updatePalette=function(t){if(!this.tooManyColors){var e=this.maxColors,r=this.paletteTexture,n=Math.ceil(.25*t.length/e);if(n>1)for(var i=.25*(t=t.slice()).length%e;i2?(s[0],s[2],n=s[1],i=s[3]):s.length?(n=s[0],i=s[1]):(s.x,n=s.y,s.x+s.width,i=s.y+s.height),l.length>2?(a=l[0],o=l[2],l[1],l[3]):l.length?(a=l[0],o=l[1]):(a=l.x,l.y,o=l.x+l.width,l.y+l.height),[a,n,o,i]}function p(t){if("number"==typeof t)return[t,t,t,t];if(2===t.length)return[t[0],t[1],t[0],t[1]];var e=l(t);return[e.x,e.y,e.x+e.width,e.y+e.height]}e.exports=u,u.prototype.render=function(){for(var t,e=this,r=[],n=arguments.length;n--;)r[n]=arguments[n];return r.length&&(t=this).update.apply(t,r),this.regl.attributes.preserveDrawingBuffer?this.draw():(this.dirty?null==this.planned&&(this.planned=o(function(){e.draw(),e.dirty=!0,e.planned=null})):(this.draw(),this.dirty=!0,o(function(){e.dirty=!1})),this)},u.prototype.update=function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];if(t.length){for(var r=0;rM))&&(s.lower||!(k>>=e))<<3,(e|=r=(15<(t>>>=r))<<2)|(r=(3<(t>>>=r))<<1)|t>>>r>>1}function s(){function t(t){t:{for(var e=16;268435456>=e;e*=16)if(t<=e){t=e;break t}t=0}return 0<(e=r[o(t)>>2]).length?e.pop():new ArrayBuffer(t)}function e(t){r[o(t.byteLength)>>2].push(t)}var r=a(8,function(){return[]});return{alloc:t,free:e,allocType:function(e,r){var n=null;switch(e){case 5120:n=new Int8Array(t(r),0,r);break;case 5121:n=new Uint8Array(t(r),0,r);break;case 5122:n=new Int16Array(t(2*r),0,r);break;case 5123:n=new Uint16Array(t(2*r),0,r);break;case 5124:n=new Int32Array(t(4*r),0,r);break;case 5125:n=new Uint32Array(t(4*r),0,r);break;case 5126:n=new Float32Array(t(4*r),0,r);break;default:return null}return n.length!==r?n.subarray(0,r):n},freeType:function(t){e(t.buffer)}}}function l(t){return!!t&&"object"==typeof t&&Array.isArray(t.shape)&&Array.isArray(t.stride)&&"number"==typeof t.offset&&t.shape.length===t.stride.length&&(Array.isArray(t.data)||Y(t.data))}function c(t,e,r,n,i,a){for(var o=0;o(i=s)&&(i=n.buffer.byteLength,5123===h?i>>=1:5125===h&&(i>>=2)),n.vertCount=i,i=o,0>o&&(i=4,1===(o=n.buffer.dimension)&&(i=0),2===o&&(i=1),3===o&&(i=4)),n.primType=i}function o(t){n.elementsCount--,delete s[t.id],t.buffer.destroy(),t.buffer=null}var s={},c=0,u={uint8:5121,uint16:5123};e.oes_element_index_uint&&(u.uint32=5125),i.prototype.bind=function(){this.buffer.bind()};var h=[];return{create:function(t,e){function s(t){if(t)if("number"==typeof t)c(t),h.primType=4,h.vertCount=0|t,h.type=5121;else{var e=null,r=35044,n=-1,i=-1,o=0,f=0;Array.isArray(t)||Y(t)||l(t)?e=t:("data"in t&&(e=t.data),"usage"in t&&(r=K[t.usage]),"primitive"in t&&(n=rt[t.primitive]),"count"in t&&(i=0|t.count),"type"in t&&(f=u[t.type]),"length"in t?o=0|t.length:(o=i,5123===f||5122===f?o*=2:5125!==f&&5124!==f||(o*=4))),a(h,e,r,n,i,o,f)}else c(),h.primType=4,h.vertCount=0,h.type=5121;return s}var c=r.create(null,34963,!0),h=new i(c._buffer);return n.elementsCount++,s(t),s._reglType="elements",s._elements=h,s.subdata=function(t,e){return c.subdata(t,e),s},s.destroy=function(){o(h)},s},createStream:function(t){var e=h.pop();return e||(e=new i(r.create(null,34963,!0,!1)._buffer)),a(e,t,35040,-1,-1,0,0),e},destroyStream:function(t){h.push(t)},getElements:function(t){return"function"==typeof t&&t._elements instanceof i?t._elements:null},clear:function(){X(s).forEach(o)}}}function g(t){for(var e=G.allocType(5123,t.length),r=0;r>>31<<15,i=(a<<1>>>24)-127,a=a>>13&1023;e[r]=-24>i?n:-14>i?n+(a+1024>>-14-i):15>=i,r.height>>=i,p(r,n[i]),t.mipmask|=1<e;++e)t.images[e]=null;return t}function L(t){for(var e=t.images,r=0;re){for(var r=0;r=--this.refCount&&B(this)}}),o.profile&&(a.getTotalTextureSize=function(){var t=0;return Object.keys(vt).forEach(function(e){t+=vt[e].stats.size}),t}),{create2D:function(e,r){function n(t,e){var r=i.texInfo;z.call(r);var a=C();return"number"==typeof t?T(a,0|t,"number"==typeof e?0|e:0|t):t?(P(r,t),S(a,t)):T(a,1,1),r.genMipmaps&&(a.mipmask=(a.width<<1)-1),i.mipmask=a.mipmask,c(i,a),i.internalformat=a.internalformat,n.width=a.width,n.height=a.height,D(i),E(a,3553),I(r,3553),R(),L(a),o.profile&&(i.stats.size=k(i.internalformat,i.type,a.width,a.height,r.genMipmaps,!1)),n.format=tt[i.internalformat],n.type=et[i.type],n.mag=rt[r.magFilter],n.min=nt[r.minFilter],n.wrapS=it[r.wrapS],n.wrapT=it[r.wrapT],n}var i=new O(3553);return vt[i.id]=i,a.textureCount++,n(e,r),n.subimage=function(t,e,r,a){e|=0,r|=0,a|=0;var o=v();return c(o,i),o.width=0,o.height=0,p(o,t),o.width=o.width||(i.width>>a)-e,o.height=o.height||(i.height>>a)-r,D(i),d(o,3553,e,r,a),R(),M(o),n},n.resize=function(e,r){var a=0|e,s=0|r||a;if(a===i.width&&s===i.height)return n;n.width=i.width=a,n.height=i.height=s,D(i);for(var l,c=i.channels,u=i.type,h=0;i.mipmask>>h;++h){var f=a>>h,p=s>>h;if(!f||!p)break;l=G.zero.allocType(u,f*p*c),t.texImage2D(3553,h,i.format,f,p,0,i.format,i.type,l),l&&G.zero.freeType(l)}return R(),o.profile&&(i.stats.size=k(i.internalformat,i.type,a,s,!1,!1)),n},n._reglType="texture2d",n._texture=i,o.profile&&(n.stats=i.stats),n.destroy=function(){i.decRef()},n},createCube:function(e,r,n,i,s,l){function h(t,e,r,n,i,a){var s,l=f.texInfo;for(z.call(l),s=0;6>s;++s)g[s]=C();if("number"!=typeof t&&t){if("object"==typeof t)if(e)S(g[0],t),S(g[1],e),S(g[2],r),S(g[3],n),S(g[4],i),S(g[5],a);else if(P(l,t),u(f,t),"faces"in t)for(t=t.faces,s=0;6>s;++s)c(g[s],f),S(g[s],t[s]);else for(s=0;6>s;++s)S(g[s],t)}else for(t=0|t||1,s=0;6>s;++s)T(g[s],t,t);for(c(f,g[0]),f.mipmask=l.genMipmaps?(g[0].width<<1)-1:g[0].mipmask,f.internalformat=g[0].internalformat,h.width=g[0].width,h.height=g[0].height,D(f),s=0;6>s;++s)E(g[s],34069+s);for(I(l,34067),R(),o.profile&&(f.stats.size=k(f.internalformat,f.type,h.width,h.height,l.genMipmaps,!0)),h.format=tt[f.internalformat],h.type=et[f.type],h.mag=rt[l.magFilter],h.min=nt[l.minFilter],h.wrapS=it[l.wrapS],h.wrapT=it[l.wrapT],s=0;6>s;++s)L(g[s]);return h}var f=new O(34067);vt[f.id]=f,a.cubeCount++;var g=Array(6);return h(e,r,n,i,s,l),h.subimage=function(t,e,r,n,i){r|=0,n|=0,i|=0;var a=v();return c(a,f),a.width=0,a.height=0,p(a,e),a.width=a.width||(f.width>>i)-r,a.height=a.height||(f.height>>i)-n,D(f),d(a,34069+t,r,n,i),R(),M(a),h},h.resize=function(e){if((e|=0)!==f.width){h.width=f.width=e,h.height=f.height=e,D(f);for(var r=0;6>r;++r)for(var n=0;f.mipmask>>n;++n)t.texImage2D(34069+r,n,f.format,e>>n,e>>n,0,f.format,f.type,null);return R(),o.profile&&(f.stats.size=k(f.internalformat,f.type,h.width,h.height,!1,!0)),h}},h._reglType="textureCube",h._texture=f,o.profile&&(h.stats=f.stats),h.destroy=function(){f.decRef()},h},clear:function(){for(var e=0;er;++r)if(0!=(e.mipmask&1<>r,e.height>>r,0,e.internalformat,e.type,null);else for(var n=0;6>n;++n)t.texImage2D(34069+n,r,e.internalformat,e.width>>r,e.height>>r,0,e.internalformat,e.type,null);I(e.texInfo,e.target)})}}}function A(t,e,r,n,i,a){function o(t,e,r){this.target=t,this.texture=e,this.renderbuffer=r;var n=t=0;e?(t=e.width,n=e.height):r&&(t=r.width,n=r.height),this.width=t,this.height=n}function s(t){t&&(t.texture&&t.texture._texture.decRef(),t.renderbuffer&&t.renderbuffer._renderbuffer.decRef())}function l(t,e,r){t&&(t.texture?t.texture._texture.refCount+=1:t.renderbuffer._renderbuffer.refCount+=1)}function c(e,r){r&&(r.texture?t.framebufferTexture2D(36160,e,r.target,r.texture._texture.texture,0):t.framebufferRenderbuffer(36160,e,36161,r.renderbuffer._renderbuffer.renderbuffer))}function u(t){var e=3553,r=null,n=null,i=t;return"object"==typeof t&&(i=t.data,"target"in t&&(e=0|t.target)),"texture2d"===(t=i._reglType)?r=i:"textureCube"===t?r=i:"renderbuffer"===t&&(n=i,e=36161),new o(e,r,n)}function h(t,e,r,a,s){return r?((t=n.create2D({width:t,height:e,format:a,type:s}))._texture.refCount=0,new o(3553,t,null)):((t=i.create({width:t,height:e,format:a}))._renderbuffer.refCount=0,new o(36161,null,t))}function f(t){return t&&(t.texture||t.renderbuffer)}function p(t,e,r){t&&(t.texture?t.texture.resize(e,r):t.renderbuffer&&t.renderbuffer.resize(e,r))}function d(){this.id=k++,M[this.id]=this,this.framebuffer=t.createFramebuffer(),this.height=this.width=0,this.colorAttachments=[],this.depthStencilAttachment=this.stencilAttachment=this.depthAttachment=null}function g(t){t.colorAttachments.forEach(s),s(t.depthAttachment),s(t.stencilAttachment),s(t.depthStencilAttachment)}function m(e){t.deleteFramebuffer(e.framebuffer),e.framebuffer=null,a.framebufferCount--,delete M[e.id]}function v(e){var n;t.bindFramebuffer(36160,e.framebuffer);var i=e.colorAttachments;for(n=0;ni;++i){for(c=0;ct;++t)r[t].resize(n);return e.width=e.height=n,e},_reglType:"framebufferCube",destroy:function(){r.forEach(function(t){t.destroy()})}})},clear:function(){X(M).forEach(m)},restore:function(){X(M).forEach(function(e){e.framebuffer=t.createFramebuffer(),v(e)})}})}function T(){this.w=this.z=this.y=this.x=this.state=0,this.buffer=null,this.size=0,this.normalized=!1,this.type=5126,this.divisor=this.stride=this.offset=0}function S(t,e,r,n){function i(t,e,r,n){this.name=t,this.id=e,this.location=r,this.info=n}function a(t,e){for(var r=0;rt&&(t=e.stats.uniformsCount)}),t},r.getMaxAttributesCount=function(){var t=0;return f.forEach(function(e){e.stats.attributesCount>t&&(t=e.stats.attributesCount)}),t}),{clear:function(){var e=t.deleteShader.bind(t);X(c).forEach(e),c={},X(u).forEach(e),u={},f.forEach(function(e){t.deleteProgram(e.program)}),f.length=0,h={},r.shaderCount=0},program:function(t,e,n){var i=h[e];i||(i=h[e]={});var a=i[t];return a||(a=new s(e,t),r.shaderCount++,l(a),i[t]=a,f.push(a)),a},restore:function(){c={},u={};for(var t=0;t"+e+"?"+i+".constant["+e+"]:0;"}).join(""),"}}else{","if(",o,"(",i,".buffer)){",u,"=",s,".createStream(",34962,",",i,".buffer);","}else{",u,"=",s,".getBuffer(",i,".buffer);","}",h,'="type" in ',i,"?",a.glTypes,"[",i,".type]:",u,".dtype;",l.normalized,"=!!",i,".normalized;"),n("size"),n("offset"),n("stride"),n("divisor"),r("}}"),r.exit("if(",l.isStream,"){",s,".destroyStream(",u,");","}"),l})}),o}function A(t,e,r,n,i){var o=_(t),s=function(t,e,r){function n(t){if(t in i){var r=i[t];t=!0;var n,o,s=0|r.x,l=0|r.y;return"width"in r?n=0|r.width:t=!1,"height"in r?o=0|r.height:t=!1,new O(!t&&e&&e.thisDep,!t&&e&&e.contextDep,!t&&e&&e.propDep,function(t,e){var i=t.shared.context,a=n;"width"in r||(a=e.def(i,".","framebufferWidth","-",s));var c=o;return"height"in r||(c=e.def(i,".","framebufferHeight","-",l)),[s,l,a,c]})}if(t in a){var c=a[t];return t=B(c,function(t,e){var r=t.invoke(e,c),n=t.shared.context,i=e.def(r,".x|0"),a=e.def(r,".y|0");return[i,a,e.def('"width" in ',r,"?",r,".width|0:","(",n,".","framebufferWidth","-",i,")"),r=e.def('"height" in ',r,"?",r,".height|0:","(",n,".","framebufferHeight","-",a,")")]}),e&&(t.thisDep=t.thisDep||e.thisDep,t.contextDep=t.contextDep||e.contextDep,t.propDep=t.propDep||e.propDep),t}return e?new O(e.thisDep,e.contextDep,e.propDep,function(t,e){var r=t.shared.context;return[0,0,e.def(r,".","framebufferWidth"),e.def(r,".","framebufferHeight")]}):null}var i=t.static,a=t.dynamic;if(t=n("viewport")){var o=t;t=new O(t.thisDep,t.contextDep,t.propDep,function(t,e){var r=o.append(t,e),n=t.shared.context;return e.set(n,".viewportWidth",r[2]),e.set(n,".viewportHeight",r[3]),r})}return{viewport:t,scissor_box:n("scissor.box")}}(t,o),l=k(t),c=function(t,e){var r=t.static,n=t.dynamic,i={};return nt.forEach(function(t){function e(e,a){if(t in r){var s=e(r[t]);i[o]=R(function(){return s})}else if(t in n){var l=n[t];i[o]=B(l,function(t,e){return a(t,e,t.invoke(e,l))})}}var o=v(t);switch(t){case"cull.enable":case"blend.enable":case"dither":case"stencil.enable":case"depth.enable":case"scissor.enable":case"polygonOffset.enable":case"sample.alpha":case"sample.enable":case"depth.mask":return e(function(t){return t},function(t,e,r){return r});case"depth.func":return e(function(t){return kt[t]},function(t,e,r){return e.def(t.constants.compareFuncs,"[",r,"]")});case"depth.range":return e(function(t){return t},function(t,e,r){return[e.def("+",r,"[0]"),e=e.def("+",r,"[1]")]});case"blend.func":return e(function(t){return[wt["srcRGB"in t?t.srcRGB:t.src],wt["dstRGB"in t?t.dstRGB:t.dst],wt["srcAlpha"in t?t.srcAlpha:t.src],wt["dstAlpha"in t?t.dstAlpha:t.dst]]},function(t,e,r){function n(t,n){return e.def('"',t,n,'" in ',r,"?",r,".",t,n,":",r,".",t)}t=t.constants.blendFuncs;var i=n("src","RGB"),a=n("dst","RGB"),o=(i=e.def(t,"[",i,"]"),e.def(t,"[",n("src","Alpha"),"]"));return[i,a=e.def(t,"[",a,"]"),o,t=e.def(t,"[",n("dst","Alpha"),"]")]});case"blend.equation":return e(function(t){return"string"==typeof t?[$[t],$[t]]:"object"==typeof t?[$[t.rgb],$[t.alpha]]:void 0},function(t,e,r){var n=t.constants.blendEquations,i=e.def(),a=e.def();return(t=t.cond("typeof ",r,'==="string"')).then(i,"=",a,"=",n,"[",r,"];"),t.else(i,"=",n,"[",r,".rgb];",a,"=",n,"[",r,".alpha];"),e(t),[i,a]});case"blend.color":return e(function(t){return a(4,function(e){return+t[e]})},function(t,e,r){return a(4,function(t){return e.def("+",r,"[",t,"]")})});case"stencil.mask":return e(function(t){return 0|t},function(t,e,r){return e.def(r,"|0")});case"stencil.func":return e(function(t){return[kt[t.cmp||"keep"],t.ref||0,"mask"in t?t.mask:-1]},function(t,e,r){return[t=e.def('"cmp" in ',r,"?",t.constants.compareFuncs,"[",r,".cmp]",":",7680),e.def(r,".ref|0"),e=e.def('"mask" in ',r,"?",r,".mask|0:-1")]});case"stencil.opFront":case"stencil.opBack":return e(function(e){return["stencil.opBack"===t?1029:1028,Mt[e.fail||"keep"],Mt[e.zfail||"keep"],Mt[e.zpass||"keep"]]},function(e,r,n){function i(t){return r.def('"',t,'" in ',n,"?",a,"[",n,".",t,"]:",7680)}var a=e.constants.stencilOps;return["stencil.opBack"===t?1029:1028,i("fail"),i("zfail"),i("zpass")]});case"polygonOffset.offset":return e(function(t){return[0|t.factor,0|t.units]},function(t,e,r){return[e.def(r,".factor|0"),e=e.def(r,".units|0")]});case"cull.face":return e(function(t){var e=0;return"front"===t?e=1028:"back"===t&&(e=1029),e},function(t,e,r){return e.def(r,'==="front"?',1028,":",1029)});case"lineWidth":return e(function(t){return t},function(t,e,r){return r});case"frontFace":return e(function(t){return At[t]},function(t,e,r){return e.def(r+'==="cw"?2304:2305')});case"colorMask":return e(function(t){return t.map(function(t){return!!t})},function(t,e,r){return a(4,function(t){return"!!"+r+"["+t+"]"})});case"sample.coverage":return e(function(t){return["value"in t?t.value:1,!!t.invert]},function(t,e,r){return[e.def('"value" in ',r,"?+",r,".value:1"),e=e.def("!!",r,".invert")]})}}),i}(t),u=w(t),h=s.viewport;return h&&(c.viewport=h),(s=s[h=v("scissor.box")])&&(c[h]=s),(o={framebuffer:o,draw:l,shader:u,state:c,dirty:s=0>1)",s],");")}function e(){r(l,".drawArraysInstancedANGLE(",[d,g,m,s],");")}p?y?t():(r("if(",p,"){"),t(),r("}else{"),e(),r("}")):e()}function o(){function t(){r(u+".drawElements("+[d,m,v,g+"<<(("+v+"-5121)>>1)"]+");")}function e(){r(u+".drawArrays("+[d,g,m]+");")}p?y?t():(r("if(",p,"){"),t(),r("}else{"),e(),r("}")):e()}var s,l,c=t.shared,u=c.gl,h=c.draw,f=n.draw,p=function(){var i=f.elements,a=e;return i?((i.contextDep&&n.contextDynamic||i.propDep)&&(a=r),i=i.append(t,a)):i=a.def(h,".","elements"),i&&a("if("+i+")"+u+".bindBuffer(34963,"+i+".buffer.buffer);"),i}(),d=i("primitive"),g=i("offset"),m=function(){var i=f.count,a=e;return i?((i.contextDep&&n.contextDynamic||i.propDep)&&(a=r),i=i.append(t,a)):i=a.def(h,".","count"),i}();if("number"==typeof m){if(0===m)return}else r("if(",m,"){"),r.exit("}");K&&(s=i("instances"),l=t.instancing);var v=p+".type",y=f.elements&&D(f.elements);K&&("number"!=typeof s||0<=s)?"string"==typeof s?(r("if(",s,">0){"),a(),r("}else if(",s,"<0){"),o(),r("}")):a():o()}function q(t,e,r,n,i){return i=(e=b()).proc("body",i),K&&(e.instancing=i.def(e.shared.extensions,".angle_instanced_arrays")),t(e,i,r,n),e.compile().body}function H(t,e,r,n){L(t,e),N(t,e,r,n.attributes,function(){return!0}),j(t,e,r,n.uniforms,function(){return!0}),V(t,e,e,r)}function G(t,e,r,n){function i(){return!0}t.batchId="a1",L(t,e),N(t,e,r,n.attributes,i),j(t,e,r,n.uniforms,i),V(t,e,e,r)}function W(t,e,r,n){function i(t){return t.contextDep&&o||t.propDep}function a(t){return!i(t)}L(t,e);var o=r.contextDep,s=e.def(),l=e.def();t.shared.props=l,t.batchId=s;var c=t.scope(),u=t.scope();e(c.entry,"for(",s,"=0;",s,"<","a1",";++",s,"){",l,"=","a0","[",s,"];",u,"}",c.exit),r.needsContext&&T(t,u,r.context),r.needsFramebuffer&&S(t,u,r.framebuffer),C(t,u,r.state,i),r.profile&&i(r.profile)&&F(t,u,r,!1,!0),n?(N(t,c,r,n.attributes,a),N(t,u,r,n.attributes,i),j(t,c,r,n.uniforms,a),j(t,u,r,n.uniforms,i),V(t,c,u,r)):(e=t.global.def("{}"),n=r.shader.progVar.append(t,u),l=u.def(n,".id"),c=u.def(e,"[",l,"]"),u(t.shared.gl,".useProgram(",n,".program);","if(!",c,"){",c,"=",e,"[",l,"]=",t.link(function(e){return q(G,t,r,e,2)}),"(",n,");}",c,".call(this,a0[",s,"],",s,");"))}function Y(t,r){function n(e){var n=r.shader[e];n&&i.set(a.shader,"."+e,n.append(t,i))}var i=t.proc("scope",3);t.batchId="a2";var a=t.shared,o=a.current;T(t,i,r.context),r.framebuffer&&r.framebuffer.append(t,i),I(Object.keys(r.state)).forEach(function(e){var n=r.state[e].append(t,i);m(n)?n.forEach(function(r,n){i.set(t.next[e],"["+n+"]",r)}):i.set(a.next,"."+e,n)}),F(t,i,r,!0,!0),["elements","offset","count","instances","primitive"].forEach(function(e){var n=r.draw[e];n&&i.set(a.draw,"."+e,""+n.append(t,i))}),Object.keys(r.uniforms).forEach(function(n){i.set(a.uniforms,"["+e.id(n)+"]",r.uniforms[n].append(t,i))}),Object.keys(r.attributes).forEach(function(e){var n=r.attributes[e].append(t,i),a=t.scopeAttrib(e);Object.keys(new Z).forEach(function(t){i.set(a,"."+t,n[t])})}),n("vert"),n("frag"),0=--this.refCount&&o(this)},i.profile&&(n.getTotalRenderbufferSize=function(){var t=0;return Object.keys(u).forEach(function(e){t+=u[e].stats.size}),t}),{create:function(e,r){function o(e,r){var n=0,a=0,u=32854;if("object"==typeof e&&e?("shape"in e?(n=0|(a=e.shape)[0],a=0|a[1]):("radius"in e&&(n=a=0|e.radius),"width"in e&&(n=0|e.width),"height"in e&&(a=0|e.height)),"format"in e&&(u=s[e.format])):"number"==typeof e?(n=0|e,a="number"==typeof r?0|r:n):e||(n=a=1),n!==c.width||a!==c.height||u!==c.format)return o.width=c.width=n,o.height=c.height=a,c.format=u,t.bindRenderbuffer(36161,c.renderbuffer),t.renderbufferStorage(36161,u,n,a),i.profile&&(c.stats.size=mt[c.format]*c.width*c.height),o.format=l[c.format],o}var c=new a(t.createRenderbuffer());return u[c.id]=c,n.renderbufferCount++,o(e,r),o.resize=function(e,r){var n=0|e,a=0|r||n;return n===c.width&&a===c.height?o:(o.width=c.width=n,o.height=c.height=a,t.bindRenderbuffer(36161,c.renderbuffer),t.renderbufferStorage(36161,c.format,n,a),i.profile&&(c.stats.size=mt[c.format]*c.width*c.height),o)},o._reglType="renderbuffer",o._renderbuffer=c,i.profile&&(o.stats=c.stats),o.destroy=function(){c.decRef()},o},clear:function(){X(u).forEach(o)},restore:function(){X(u).forEach(function(e){e.renderbuffer=t.createRenderbuffer(),t.bindRenderbuffer(36161,e.renderbuffer),t.renderbufferStorage(36161,e.format,e.width,e.height)}),t.bindRenderbuffer(36161,null)}}},yt=[];yt[6408]=4,yt[6407]=3;var xt=[];xt[5121]=1,xt[5126]=4,xt[36193]=2;var bt=["x","y","z","w"],_t="blend.func blend.equation stencil.func stencil.opFront stencil.opBack sample.coverage viewport scissor.box polygonOffset.offset".split(" "),wt={0:0,1:1,zero:0,one:1,"src color":768,"one minus src color":769,"src alpha":770,"one minus src alpha":771,"dst color":774,"one minus dst color":775,"dst alpha":772,"one minus dst alpha":773,"constant color":32769,"one minus constant color":32770,"constant alpha":32771,"one minus constant alpha":32772,"src alpha saturate":776},kt={never:512,less:513,"<":513,equal:514,"=":514,"==":514,"===":514,lequal:515,"<=":515,greater:516,">":516,notequal:517,"!=":517,"!==":517,gequal:518,">=":518,always:519},Mt={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683,"increment wrap":34055,"decrement wrap":34056,invert:5386},At={cw:2304,ccw:2305},Tt=new O(!1,!1,!1,function(){});return function(t){function e(){if(0===Z.length)w&&w.update(),Q=null;else{Q=q.next(e),h();for(var t=Z.length-1;0<=t;--t){var r=Z[t];r&&r(z,null,0)}m.flush(),w&&w.update()}}function r(){!Q&&0=Z.length&&n()}}}}function u(){var t=Y.viewport,e=Y.scissor_box;t[0]=t[1]=e[0]=e[1]=0,z.viewportWidth=z.framebufferWidth=z.drawingBufferWidth=t[2]=e[2]=m.drawingBufferWidth,z.viewportHeight=z.framebufferHeight=z.drawingBufferHeight=t[3]=e[3]=m.drawingBufferHeight}function h(){z.tick+=1,z.time=g(),u(),G.procs.poll()}function f(){u(),G.procs.refresh(),w&&w.update()}function g(){return(H()-k)/1e3}if(!(t=i(t)))return null;var m=t.gl,v=m.getContextAttributes();m.isContextLost();var y=function(t,e){function r(e){var r;e=e.toLowerCase();try{r=n[e]=t.getExtension(e)}catch(t){}return!!r}for(var n={},i=0;ie;++e)tt(j({framebuffer:t.framebuffer.faces[e]},t),l);else tt(t,l);else l(0,t)},prop:U.define.bind(null,1),context:U.define.bind(null,2),this:U.define.bind(null,3),draw:s({}),buffer:function(t){return I.create(t,34962,!1,!1)},elements:function(t){return O.create(t,!1)},texture:R.create2D,cube:R.createCube,renderbuffer:B.create,framebuffer:V.create,framebufferCube:V.createCube,attributes:v,frame:c,on:function(t,e){var r;switch(t){case"frame":return c(e);case"lost":r=$;break;case"restore":r=J;break;case"destroy":r=K}return r.push(e),{cancel:function(){for(var t=0;t=r)return i.substr(0,r);for(;r>i.length&&e>1;)1&e&&(i+=t),e>>=1,t+=t;return i=(i+=t).substr(0,r)}},{}],465:[function(t,e,r){(function(t){e.exports=t.performance&&t.performance.now?function(){return performance.now()}:Date.now||function(){return+new Date}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],466:[function(t,e,r){"use strict";e.exports=function(t){for(var e=t.length,r=t[t.length-1],n=e,i=e-2;i>=0;--i){var a=r,o=t[i],s=(r=a+o)-a,l=o-s;l&&(t[--n]=r,r=l)}for(var c=0,i=n;i>1;return["sum(",t(e.slice(0,r)),",",t(e.slice(r)),")"].join("")}(e);var n}function u(t){return new Function("sum","scale","prod","compress",["function robustDeterminant",t,"(m){return compress(",c(function(t){for(var e=new Array(t),r=0;r>1;return["sum(",c(t.slice(0,e)),",",c(t.slice(e)),")"].join("")}function u(t,e){if("m"===t.charAt(0)){if("w"===e.charAt(0)){var r=t.split("[");return["w",e.substr(1),"m",r[0].substr(1)].join("")}return["prod(",t,",",e,")"].join("")}return u(e,t)}function h(t){if(2===t.length)return[["diff(",u(t[0][0],t[1][1]),",",u(t[1][0],t[0][1]),")"].join("")];for(var e=[],r=0;r0&&r.push(","),r.push("[");for(var o=0;o0&&r.push(","),o===i?r.push("+b[",a,"]"):r.push("+A[",a,"][",o,"]");r.push("]")}r.push("]),")}r.push("det(A)]}return ",e);var s=new Function("det",r.join(""));return s(t<6?n[t]:n)}var o=[function(){return[0]},function(t,e){return[[e[0]],[t[0][0]]]}];!function(){for(;o.length>1;return["sum(",c(t.slice(0,e)),",",c(t.slice(e)),")"].join("")}function u(t){if(2===t.length)return[["sum(prod(",t[0][0],",",t[1][1],"),prod(-",t[0][1],",",t[1][0],"))"].join("")];for(var e=[],r=0;r0){if(a<=0)return o;n=i+a}else{if(!(i<0))return o;if(a>=0)return o;n=-(i+a)}var s=3.3306690738754716e-16*n;return o>=s||o<=-s?o:f(t,e,r)},function(t,e,r,n){var i=t[0]-n[0],a=e[0]-n[0],o=r[0]-n[0],s=t[1]-n[1],l=e[1]-n[1],c=r[1]-n[1],u=t[2]-n[2],h=e[2]-n[2],f=r[2]-n[2],d=a*c,g=o*l,m=o*s,v=i*c,y=i*l,x=a*s,b=u*(d-g)+h*(m-v)+f*(y-x),_=7.771561172376103e-16*((Math.abs(d)+Math.abs(g))*Math.abs(u)+(Math.abs(m)+Math.abs(v))*Math.abs(h)+(Math.abs(y)+Math.abs(x))*Math.abs(f));return b>_||-b>_?b:p(t,e,r,n)}];!function(){for(;d.length<=s;)d.push(h(d.length));for(var t=[],r=["slow"],n=0;n<=s;++n)t.push("a"+n),r.push("o"+n);var i=["function getOrientation(",t.join(),"){switch(arguments.length){case 0:case 1:return 0;"];for(n=2;n<=s;++n)i.push("case ",n,":return o",n,"(",t.slice(0,n).join(),");");i.push("}var s=new Array(arguments.length);for(var i=0;i0&&o>0||a<0&&o<0)return!1;var s=n(r,t,e),l=n(i,t,e);if(s>0&&l>0||s<0&&l<0)return!1;if(0===a&&0===o&&0===s&&0===l)return function(t,e,r,n){for(var i=0;i<2;++i){var a=t[i],o=e[i],s=Math.min(a,o),l=Math.max(a,o),c=r[i],u=n[i],h=Math.min(c,u),f=Math.max(c,u);if(f=n?(i=h,(l+=1)=n?(i=h,(l+=1)0?1:0}},{}],478:[function(t,e,r){"use strict";e.exports=function(t){return i(n(t))};var n=t("boundary-cells"),i=t("reduce-simplicial-complex")},{"boundary-cells":83,"reduce-simplicial-complex":456}],479:[function(t,e,r){"use strict";e.exports=function(t,e,r,s){r=r||0,"undefined"==typeof s&&(s=function(t){for(var e=t.length,r=0,n=0;n>1,v=E[2*m+1];","if(v===b){return m}","if(b0&&l.push(","),l.push("[");for(var n=0;n0&&l.push(","),l.push("B(C,E,c[",i[0],"],c[",i[1],"])")}l.push("]")}l.push(");")}}for(var a=t+1;a>1;--a){a>1,s=a(t[o],e);s<=0?(0===s&&(i=o),r=o+1):s>0&&(n=o-1)}return i}function u(t,e){for(var r=new Array(t.length),i=0,o=r.length;i=t.length||0!==a(t[m],s)););}return r}function h(t,e){if(e<0)return[];for(var r=[],i=(1<>>u&1&&c.push(i[u]);e.push(c)}return s(e)},r.skeleton=h,r.boundary=function(t){for(var e=[],r=0,n=t.length;r>1:(t>>1)-1}function x(t){for(var e=v(t);;){var r=e,n=2*t+1,i=2*(t+1),a=t;if(n0;){var r=y(t);if(r>=0){var n=v(r);if(e0){var t=M[0];return m(0,S-1),S-=1,x(0),t}return-1}function w(t,e){var r=M[t];return c[r]===e?t:(c[r]=-1/0,b(t),_(),c[r]=e,b((S+=1)-1))}function k(t){if(!u[t]){u[t]=!0;var e=s[t],r=l[t];s[r]>=0&&(s[r]=e),l[e]>=0&&(l[e]=r),A[e]>=0&&w(A[e],g(e)),A[r]>=0&&w(A[r],g(r))}}for(var M=[],A=new Array(a),h=0;h>1;h>=0;--h)x(h);for(;;){var E=_();if(E<0||c[E]>r)break;k(E)}for(var C=[],h=0;h=0&&r>=0&&e!==r){var n=A[e],i=A[r];n!==i&&z.push([n,i])}}),i.unique(i.normalize(z)),{positions:C,edges:z}};var n=t("robust-orientation"),i=t("simplicial-complex")},{"robust-orientation":471,"simplicial-complex":483}],486:[function(t,e,r){"use strict";e.exports=function(t,e){var r,a,o,s;if(e[0][0]e[1][0]))return i(e,t);r=e[1],a=e[0]}if(t[0][0]t[1][0]))return-i(t,e);o=t[1],s=t[0]}var l=n(r,a,s),c=n(r,a,o);if(l<0){if(c<=0)return l}else if(l>0){if(c>=0)return l}else if(c)return c;if(l=n(s,o,a),c=n(s,o,r),l<0){if(c<=0)return l}else if(l>0){if(c>=0)return l}else if(c)return c;return a[0]-s[0]};var n=t("robust-orientation");function i(t,e){var r,i,a,o;if(e[0][0]e[1][0])){var s=Math.min(t[0][1],t[1][1]),l=Math.max(t[0][1],t[1][1]),c=Math.min(e[0][1],e[1][1]),u=Math.max(e[0][1],e[1][1]);return lu?s-u:l-u}r=e[1],i=e[0]}t[0][1]0)if(e[0]!==o[1][0])r=t,t=t.right;else{if(l=c(t.right,e))return l;t=t.left}else{if(e[0]!==o[1][0])return t;var l;if(l=c(t.right,e))return l;t=t.left}}return r}function u(t,e,r,n){this.y=t,this.index=e,this.start=r,this.closed=n}function h(t,e,r,n){this.x=t,this.segment=e,this.create=r,this.index=n}s.prototype.castUp=function(t){var e=n.le(this.coordinates,t[0]);if(e<0)return-1;this.slabs[e];var r=c(this.slabs[e],t),i=-1;if(r&&(i=r.value),this.coordinates[e]===t[0]){var s=null;if(r&&(s=r.key),e>0){var u=c(this.slabs[e-1],t);u&&(s?o(u.key,s)>0&&(s=u.key,i=u.value):(i=u.value,s=u.key))}var h=this.horizontal[e];if(h.length>0){var f=n.ge(h,t[1],l);if(f=h.length)return i;p=h[f]}}if(p.start)if(s){var d=a(s[0],s[1],[t[0],p.y]);s[0][0]>s[1][0]&&(d=-d),d>0&&(i=p.index)}else i=p.index;else p.y!==t[1]&&(i=p.index)}}}return i}},{"./lib/order-segments":486,"binary-search-bounds":79,"functional-red-black-tree":219,"robust-orientation":471}],488:[function(t,e,r){"use strict";var n=t("robust-dot-product"),i=t("robust-sum");function a(t,e){var r=i(n(t,e),[e[e.length-1]]);return r[r.length-1]}function o(t,e,r,n){var i=-e/(n-e);i<0?i=0:i>1&&(i=1);for(var a=1-i,o=t.length,s=new Array(o),l=0;l0||i>0&&u<0){var h=o(s,u,l,i);r.push(h),n.push(h.slice())}u<0?n.push(l.slice()):u>0?r.push(l.slice()):(r.push(l.slice()),n.push(l.slice())),i=u}return{positive:r,negative:n}},e.exports.positive=function(t,e){for(var r=[],n=a(t[t.length-1],e),i=t[t.length-1],s=t[0],l=0;l0||n>0&&c<0)&&r.push(o(i,c,s,n)),c>=0&&r.push(s.slice()),n=c}return r},e.exports.negative=function(t,e){for(var r=[],n=a(t[t.length-1],e),i=t[t.length-1],s=t[0],l=0;l0||n>0&&c<0)&&r.push(o(i,c,s,n)),c<=0&&r.push(s.slice()),n=c}return r}},{"robust-dot-product":468,"robust-sum":476}],489:[function(t,e,r){!function(){"use strict";var t={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[\+\-]/};function e(r){return function(r,n){var i,a,o,s,l,c,u,h,f,p=1,d=r.length,g="";for(a=0;a=0),s[8]){case"b":i=parseInt(i,10).toString(2);break;case"c":i=String.fromCharCode(parseInt(i,10));break;case"d":case"i":i=parseInt(i,10);break;case"j":i=JSON.stringify(i,null,s[6]?parseInt(s[6]):0);break;case"e":i=s[7]?parseFloat(i).toExponential(s[7]):parseFloat(i).toExponential();break;case"f":i=s[7]?parseFloat(i).toFixed(s[7]):parseFloat(i);break;case"g":i=s[7]?String(Number(i.toPrecision(s[7]))):parseFloat(i);break;case"o":i=(parseInt(i,10)>>>0).toString(8);break;case"s":i=String(i),i=s[7]?i.substring(0,s[7]):i;break;case"t":i=String(!!i),i=s[7]?i.substring(0,s[7]):i;break;case"T":i=Object.prototype.toString.call(i).slice(8,-1).toLowerCase(),i=s[7]?i.substring(0,s[7]):i;break;case"u":i=parseInt(i,10)>>>0;break;case"v":i=i.valueOf(),i=s[7]?i.substring(0,s[7]):i;break;case"x":i=(parseInt(i,10)>>>0).toString(16);break;case"X":i=(parseInt(i,10)>>>0).toString(16).toUpperCase()}t.json.test(s[8])?g+=i:(!t.number.test(s[8])||h&&!s[3]?f="":(f=h?"+":"-",i=i.toString().replace(t.sign,"")),c=s[4]?"0"===s[4]?"0":s[4].charAt(1):" ",u=s[6]-(f+i).length,l=s[6]&&u>0?c.repeat(u):"",g+=s[5]?f+i+l:"0"===c?f+l+i:l+f+i)}return g}(function(e){if(i[e])return i[e];var r,n=e,a=[],o=0;for(;n;){if(null!==(r=t.text.exec(n)))a.push(r[0]);else if(null!==(r=t.modulo.exec(n)))a.push("%");else{if(null===(r=t.placeholder.exec(n)))throw new SyntaxError("[sprintf] unexpected placeholder");if(r[2]){o|=1;var s=[],l=r[2],c=[];if(null===(c=t.key.exec(l)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(s.push(c[1]);""!==(l=l.substring(c[0].length));)if(null!==(c=t.key_access.exec(l)))s.push(c[1]);else{if(null===(c=t.index_access.exec(l)))throw new SyntaxError("[sprintf] failed to parse named argument key");s.push(c[1])}r[2]=s}else o|=2;if(3===o)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");a.push(r)}n=n.substring(r[0].length)}return i[e]=a}(r),arguments)}function n(t,r){return e.apply(null,[t].concat(r||[]))}var i=Object.create(null);"undefined"!=typeof r&&(r.sprintf=e,r.vsprintf=n),"undefined"!=typeof window&&(window.sprintf=e,window.vsprintf=n)}()},{}],490:[function(t,e,r){"use strict";var n=t("parenthesis");e.exports=function(t,e,r){if(null==t)throw Error("First argument should be a string");if(null==e)throw Error("Separator should be a string or a RegExp");r?("string"==typeof r||Array.isArray(r))&&(r={ignore:r}):r={},null==r.escape&&(r.escape=!0),null==r.ignore?r.ignore=["[]","()","{}","<>",'""',"''","``","\u201c\u201d","\xab\xbb"]:("string"==typeof r.ignore&&(r.ignore=[r.ignore]),r.ignore=r.ignore.map(function(t){return 1===t.length&&(t+=t),t}));var i=n.parse(t,{flat:!0,brackets:r.ignore}),a=i[0].split(e);if(r.escape){for(var o=[],s=0;s0;){e=c[c.length-1];var p=t[e];if(a[e]=0&&s[e].push(o[g])}a[e]=d}else{if(n[e]===r[e]){for(var m=[],v=[],y=0,d=l.length-1;d>=0;--d){var x=l[d];if(i[x]=!1,m.push(x),v.push(s[x]),y+=s[x].length,o[x]=h.length,x===e){l.length=d;break}}h.push(m);for(var b=new Array(y),d=0;d c)|0 },"),"generic"===e&&a.push("getters:[0],");for(var s=[],l=[],c=0;c>>7){");for(var c=0;c<1<<(1<128&&c%128==0){h.length>0&&f.push("}}");var p="vExtra"+h.length;a.push("case ",c>>>7,":",p,"(m&0x7f,",l.join(),");break;"),f=["function ",p,"(m,",l.join(),"){switch(m){"],h.push(f)}f.push("case ",127&c,":");for(var d=new Array(r),g=new Array(r),m=new Array(r),v=new Array(r),y=0,x=0;xx)&&!(c&1<<_)!=!(c&1<0&&(A="+"+m[b]+"*c");var T=d[b].length/y*.5,S=.5+v[b]/y*.5;M.push("d"+b+"-"+S+"-"+T+"*("+d[b].join("+")+A+")/("+g[b].join("+")+")")}f.push("a.push([",M.join(),"]);","break;")}a.push("}},"),h.length>0&&f.push("}}");for(var E=[],c=0;c<1<1&&(a=1),a<-1&&(a=-1),i*Math.acos(a)};r.default=function(t){var e=t.px,r=t.py,l=t.cx,c=t.cy,u=t.rx,h=t.ry,f=t.xAxisRotation,p=void 0===f?0:f,d=t.largeArcFlag,g=void 0===d?0:d,m=t.sweepFlag,v=void 0===m?0:m,y=[];if(0===u||0===h)return[];var x=Math.sin(p*i/360),b=Math.cos(p*i/360),_=b*(e-l)/2+x*(r-c)/2,w=-x*(e-l)/2+b*(r-c)/2;if(0===_&&0===w)return[];u=Math.abs(u),h=Math.abs(h);var k=Math.pow(_,2)/Math.pow(u,2)+Math.pow(w,2)/Math.pow(h,2);k>1&&(u*=Math.sqrt(k),h*=Math.sqrt(k));var M=function(t,e,r,n,a,o,l,c,u,h,f,p){var d=Math.pow(a,2),g=Math.pow(o,2),m=Math.pow(f,2),v=Math.pow(p,2),y=d*g-d*v-g*m;y<0&&(y=0),y/=d*v+g*m;var x=(y=Math.sqrt(y)*(l===c?-1:1))*a/o*p,b=y*-o/a*f,_=h*x-u*b+(t+r)/2,w=u*x+h*b+(e+n)/2,k=(f-x)/a,M=(p-b)/o,A=(-f-x)/a,T=(-p-b)/o,S=s(1,0,k,M),E=s(k,M,A,T);return 0===c&&E>0&&(E-=i),1===c&&E<0&&(E+=i),[_,w,S,E]}(e,r,l,c,u,h,g,v,x,b,_,w),A=n(M,4),T=A[0],S=A[1],E=A[2],C=A[3],L=Math.max(Math.ceil(Math.abs(C)/(i/4)),1);C/=L;for(var z=0;ze[2]&&(e[2]=c[u+0]),c[u+1]>e[3]&&(e[3]=c[u+1]);return e}},{"abs-svg-path":51,assert:59,"is-svg-path":391,"normalize-svg-path":496,"parse-svg-path":427}],496:[function(t,e,r){"use strict";e.exports=function(t){for(var e,r=[],o=0,s=0,l=0,c=0,u=null,h=null,f=0,p=0,d=0,g=t.length;d4?(o=m[m.length-4],s=m[m.length-3]):(o=f,s=p),r.push(m)}return r};var n=t("svg-arc-to-cubic-bezier");function i(t,e,r,n){return["C",t,e,r,n,r,n]}function a(t,e,r,n,i,a){return["C",t/3+2/3*r,e/3+2/3*n,i/3+2/3*r,a/3+2/3*n,i,a]}},{"svg-arc-to-cubic-bezier":494}],497:[function(t,e,r){(function(r){"use strict";var n=t("svg-path-bounds"),i=t("parse-svg-path"),a=t("draw-svg-path"),o=t("is-svg-path"),s=t("bitmap-sdf"),l=document.createElement("canvas"),c=l.getContext("2d");e.exports=function(t,e){if(!o(t))throw Error("Argument should be valid svg path string");e||(e={});var u,h;e.shape?(u=e.shape[0],h=e.shape[1]):(u=l.width=e.w||e.width||200,h=l.height=e.h||e.height||200);var f=Math.min(u,h),p=e.stroke||0,d=e.viewbox||e.viewBox||n(t),g=[u/(d[2]-d[0]),h/(d[3]-d[1])],m=Math.min(g[0]||0,g[1]||0)/2;c.fillStyle="black",c.fillRect(0,0,u,h),c.fillStyle="white",p&&("number"!=typeof p&&(p=1),c.strokeStyle=p>0?"white":"black",c.lineWidth=Math.abs(p));if(c.translate(.5*u,.5*h),c.scale(m,m),r.Path2D){var v=new Path2D(t);c.fill(v),p&&c.stroke(v)}else{var y=i(t);a(c,y),c.fill(),p&&c.stroke()}return c.setTransform(1,0,0,1,0,0),s(c,{cutoff:null!=e.cutoff?e.cutoff:.5,radius:null!=e.radius?e.radius:.5*f})}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"bitmap-sdf":81,"draw-svg-path":152,"is-svg-path":391,"parse-svg-path":427,"svg-path-bounds":495}],498:[function(t,e,r){(function(r){"use strict";e.exports=function t(e,r,i){var i=i||{};var o=a[e];o||(o=a[e]={" ":{data:new Float32Array(0),shape:.2}});var s=o[r];if(!s)if(r.length<=1||!/\d/.test(r))s=o[r]=function(t){for(var e=t.cells,r=t.positions,n=new Float32Array(6*e.length),i=0,a=0,o=0;o0&&(h+=.02);for(var p=new Float32Array(u),d=0,g=-.5*h,f=0;f1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}if(t=L(t,360),e=L(e,100),r=L(r,100),0===e)n=i=a=r;else{var s=r<.5?r*(1+e):r+e-r*e,l=2*r-s;n=o(l,s,t+1/3),i=o(l,s,t),a=o(l,s,t-1/3)}return{r:255*n,g:255*i,b:255*a}}(e.h,l,u),h=!0,f="hsl"),e.hasOwnProperty("a")&&(a=e.a));var p,d,g;return a=C(a),{ok:h,format:e.format||f,r:o(255,s(i.r,0)),g:o(255,s(i.g,0)),b:o(255,s(i.b,0)),a:a}}(e);this._originalInput=e,this._r=u.r,this._g=u.g,this._b=u.b,this._a=u.a,this._roundA=a(100*this._a)/100,this._format=l.format||u.format,this._gradientType=l.gradientType,this._r<1&&(this._r=a(this._r)),this._g<1&&(this._g=a(this._g)),this._b<1&&(this._b=a(this._b)),this._ok=u.ok,this._tc_id=i++}function u(t,e,r){t=L(t,255),e=L(e,255),r=L(r,255);var n,i,a=s(t,e,r),l=o(t,e,r),c=(a+l)/2;if(a==l)n=i=0;else{var u=a-l;switch(i=c>.5?u/(2-a-l):u/(a+l),a){case t:n=(e-r)/u+(e>1)+720)%360;--e;)n.h=(n.h+i)%360,a.push(c(n));return a}function T(t,e){e=e||6;for(var r=c(t).toHsv(),n=r.h,i=r.s,a=r.v,o=[],s=1/e;e--;)o.push(c({h:n,s:i,v:a})),a=(a+s)%1;return o}c.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var t=this.toRgb();return(299*t.r+587*t.g+114*t.b)/1e3},getLuminance:function(){var e,r,n,i=this.toRgb();return e=i.r/255,r=i.g/255,n=i.b/255,.2126*(e<=.03928?e/12.92:t.pow((e+.055)/1.055,2.4))+.7152*(r<=.03928?r/12.92:t.pow((r+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:t.pow((n+.055)/1.055,2.4))},setAlpha:function(t){return this._a=C(t),this._roundA=a(100*this._a)/100,this},toHsv:function(){var t=h(this._r,this._g,this._b);return{h:360*t.h,s:t.s,v:t.v,a:this._a}},toHsvString:function(){var t=h(this._r,this._g,this._b),e=a(360*t.h),r=a(100*t.s),n=a(100*t.v);return 1==this._a?"hsv("+e+", "+r+"%, "+n+"%)":"hsva("+e+", "+r+"%, "+n+"%, "+this._roundA+")"},toHsl:function(){var t=u(this._r,this._g,this._b);return{h:360*t.h,s:t.s,l:t.l,a:this._a}},toHslString:function(){var t=u(this._r,this._g,this._b),e=a(360*t.h),r=a(100*t.s),n=a(100*t.l);return 1==this._a?"hsl("+e+", "+r+"%, "+n+"%)":"hsla("+e+", "+r+"%, "+n+"%, "+this._roundA+")"},toHex:function(t){return f(this._r,this._g,this._b,t)},toHexString:function(t){return"#"+this.toHex(t)},toHex8:function(t){return function(t,e,r,n,i){var o=[I(a(t).toString(16)),I(a(e).toString(16)),I(a(r).toString(16)),I(D(n))];if(i&&o[0].charAt(0)==o[0].charAt(1)&&o[1].charAt(0)==o[1].charAt(1)&&o[2].charAt(0)==o[2].charAt(1)&&o[3].charAt(0)==o[3].charAt(1))return o[0].charAt(0)+o[1].charAt(0)+o[2].charAt(0)+o[3].charAt(0);return o.join("")}(this._r,this._g,this._b,this._a,t)},toHex8String:function(t){return"#"+this.toHex8(t)},toRgb:function(){return{r:a(this._r),g:a(this._g),b:a(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+a(this._r)+", "+a(this._g)+", "+a(this._b)+")":"rgba("+a(this._r)+", "+a(this._g)+", "+a(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:a(100*L(this._r,255))+"%",g:a(100*L(this._g,255))+"%",b:a(100*L(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+a(100*L(this._r,255))+"%, "+a(100*L(this._g,255))+"%, "+a(100*L(this._b,255))+"%)":"rgba("+a(100*L(this._r,255))+"%, "+a(100*L(this._g,255))+"%, "+a(100*L(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(E[f(this._r,this._g,this._b,!0)]||!1)},toFilter:function(t){var e="#"+p(this._r,this._g,this._b,this._a),r=e,n=this._gradientType?"GradientType = 1, ":"";if(t){var i=c(t);r="#"+p(i._r,i._g,i._b,i._a)}return"progid:DXImageTransform.Microsoft.gradient("+n+"startColorstr="+e+",endColorstr="+r+")"},toString:function(t){var e=!!t;t=t||this._format;var r=!1,n=this._a<1&&this._a>=0;return e||!n||"hex"!==t&&"hex6"!==t&&"hex3"!==t&&"hex4"!==t&&"hex8"!==t&&"name"!==t?("rgb"===t&&(r=this.toRgbString()),"prgb"===t&&(r=this.toPercentageRgbString()),"hex"!==t&&"hex6"!==t||(r=this.toHexString()),"hex3"===t&&(r=this.toHexString(!0)),"hex4"===t&&(r=this.toHex8String(!0)),"hex8"===t&&(r=this.toHex8String()),"name"===t&&(r=this.toName()),"hsl"===t&&(r=this.toHslString()),"hsv"===t&&(r=this.toHsvString()),r||this.toHexString()):"name"===t&&0===this._a?this.toName():this.toRgbString()},clone:function(){return c(this.toString())},_applyModification:function(t,e){var r=t.apply(null,[this].concat([].slice.call(e)));return this._r=r._r,this._g=r._g,this._b=r._b,this.setAlpha(r._a),this},lighten:function(){return this._applyModification(v,arguments)},brighten:function(){return this._applyModification(y,arguments)},darken:function(){return this._applyModification(x,arguments)},desaturate:function(){return this._applyModification(d,arguments)},saturate:function(){return this._applyModification(g,arguments)},greyscale:function(){return this._applyModification(m,arguments)},spin:function(){return this._applyModification(b,arguments)},_applyCombination:function(t,e){return t.apply(null,[this].concat([].slice.call(e)))},analogous:function(){return this._applyCombination(A,arguments)},complement:function(){return this._applyCombination(_,arguments)},monochromatic:function(){return this._applyCombination(T,arguments)},splitcomplement:function(){return this._applyCombination(M,arguments)},triad:function(){return this._applyCombination(w,arguments)},tetrad:function(){return this._applyCombination(k,arguments)}},c.fromRatio=function(t,e){if("object"==typeof t){var r={};for(var n in t)t.hasOwnProperty(n)&&(r[n]="a"===n?t[n]:O(t[n]));t=r}return c(t,e)},c.equals=function(t,e){return!(!t||!e)&&c(t).toRgbString()==c(e).toRgbString()},c.random=function(){return c.fromRatio({r:l(),g:l(),b:l()})},c.mix=function(t,e,r){r=0===r?0:r||50;var n=c(t).toRgb(),i=c(e).toRgb(),a=r/100;return c({r:(i.r-n.r)*a+n.r,g:(i.g-n.g)*a+n.g,b:(i.b-n.b)*a+n.b,a:(i.a-n.a)*a+n.a})},c.readability=function(e,r){var n=c(e),i=c(r);return(t.max(n.getLuminance(),i.getLuminance())+.05)/(t.min(n.getLuminance(),i.getLuminance())+.05)},c.isReadable=function(t,e,r){var n,i,a=c.readability(t,e);switch(i=!1,(n=function(t){var e,r;e=((t=t||{level:"AA",size:"small"}).level||"AA").toUpperCase(),r=(t.size||"small").toLowerCase(),"AA"!==e&&"AAA"!==e&&(e="AA");"small"!==r&&"large"!==r&&(r="small");return{level:e,size:r}}(r)).level+n.size){case"AAsmall":case"AAAlarge":i=a>=4.5;break;case"AAlarge":i=a>=3;break;case"AAAsmall":i=a>=7}return i},c.mostReadable=function(t,e,r){var n,i,a,o,s=null,l=0;i=(r=r||{}).includeFallbackColors,a=r.level,o=r.size;for(var u=0;ul&&(l=n,s=c(e[u]));return c.isReadable(t,s,{level:a,size:o})||!i?s:(r.includeFallbackColors=!1,c.mostReadable(t,["#fff","#000"],r))};var S=c.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},E=c.hexNames=function(t){var e={};for(var r in t)t.hasOwnProperty(r)&&(e[t[r]]=r);return e}(S);function C(t){return t=parseFloat(t),(isNaN(t)||t<0||t>1)&&(t=1),t}function L(e,r){(function(t){return"string"==typeof t&&-1!=t.indexOf(".")&&1===parseFloat(t)})(e)&&(e="100%");var n=function(t){return"string"==typeof t&&-1!=t.indexOf("%")}(e);return e=o(r,s(0,parseFloat(e))),n&&(e=parseInt(e*r,10)/100),t.abs(e-r)<1e-6?1:e%r/parseFloat(r)}function z(t){return o(1,s(0,t))}function P(t){return parseInt(t,16)}function I(t){return 1==t.length?"0"+t:""+t}function O(t){return t<=1&&(t=100*t+"%"),t}function D(e){return t.round(255*parseFloat(e)).toString(16)}function R(t){return P(t)/255}var B,F,N,j=(F="[\\s|\\(]+("+(B="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+B+")[,|\\s]+("+B+")\\s*\\)?",N="[\\s|\\(]+("+B+")[,|\\s]+("+B+")[,|\\s]+("+B+")[,|\\s]+("+B+")\\s*\\)?",{CSS_UNIT:new RegExp(B),rgb:new RegExp("rgb"+F),rgba:new RegExp("rgba"+N),hsl:new RegExp("hsl"+F),hsla:new RegExp("hsla"+N),hsv:new RegExp("hsv"+F),hsva:new RegExp("hsva"+N),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});function V(t){return!!j.CSS_UNIT.exec(t)}"undefined"!=typeof e&&e.exports?e.exports=c:window.tinycolor=c}(Math)},{}],500:[function(t,e,r){"use strict";function n(t){if(t instanceof Float32Array)return t;if("number"==typeof t)return new Float32Array([t])[0];var e=new Float32Array(t);return e.set(t),e}e.exports=n,e.exports.float32=e.exports.float=n,e.exports.fract32=e.exports.fract=function(t){if("number"==typeof t)return n(t-n(t));for(var e=n(t),r=0,i=e.length;rh&&(h=l[0]),l[1]f&&(f=l[1])}function i(t){switch(t.type){case"GeometryCollection":t.geometries.forEach(i);break;case"Point":n(t.coordinates);break;case"MultiPoint":t.coordinates.forEach(n)}}if(!e){var a,o,s=r(t),l=new Array(2),c=1/0,u=c,h=-c,f=-c;for(o in t.arcs.forEach(function(t){for(var e=-1,r=t.length;++eh&&(h=l[0]),l[1]f&&(f=l[1])}),t.objects)i(t.objects[o]);e=t.bbox=[c,u,h,f]}return e},i=function(t,e){for(var r,n=t.length,i=n-e;i<--n;)r=t[i],t[i++]=t[n],t[n]=r};function a(t,e){var r=e.id,n=e.bbox,i=null==e.properties?{}:e.properties,a=o(t,e);return null==r&&null==n?{type:"Feature",properties:i,geometry:a}:null==n?{type:"Feature",id:r,properties:i,geometry:a}:{type:"Feature",id:r,bbox:n,properties:i,geometry:a}}function o(t,e){var n=r(t),a=t.arcs;function o(t,e){e.length&&e.pop();for(var r=a[t<0?~t:t],o=0,s=r.length;o1)n=function(t,e,r){var n,i=[],a=[];function o(t){var e=t<0?~t:t;(a[e]||(a[e]=[])).push({i:t,g:n})}function s(t){t.forEach(o)}function l(t){t.forEach(s)}return function t(e){switch(n=e,e.type){case"GeometryCollection":e.geometries.forEach(t);break;case"LineString":s(e.arcs);break;case"MultiLineString":case"Polygon":l(e.arcs);break;case"MultiPolygon":e.arcs.forEach(l)}}(e),a.forEach(null==r?function(t){i.push(t[0].i)}:function(t){r(t[0].g,t[t.length-1].g)&&i.push(t[0].i)}),i}(0,e,r);else for(i=0,n=new Array(a=t.arcs.length);i1)for(var a,o,c=1,u=l(i[0]);cu&&(o=i[0],i[0]=i[c],i[c]=o,u=a);return i})}}var u=function(t,e){for(var r=0,n=t.length;r>>1;t[i]=2))throw new Error("n must be \u22652");if(t.transform)throw new Error("already quantized");var r,i=n(t),a=i[0],o=(i[2]-a)/(e-1)||1,s=i[1],l=(i[3]-s)/(e-1)||1;function c(t){t[0]=Math.round((t[0]-a)/o),t[1]=Math.round((t[1]-s)/l)}function u(t){switch(t.type){case"GeometryCollection":t.geometries.forEach(u);break;case"Point":c(t.coordinates);break;case"MultiPoint":t.coordinates.forEach(c)}}for(r in t.arcs.forEach(function(t){for(var e,r,n,i=1,c=1,u=t.length,h=t[0],f=h[0]=Math.round((h[0]-a)/o),p=h[1]=Math.round((h[1]-s)/l);iMath.max(r,n)?i[2]=1:r>Math.max(e,n)?i[0]=1:i[1]=1;for(var a=0,o=0,l=0;l<3;++l)a+=t[l]*t[l],o+=i[l]*t[l];for(l=0;l<3;++l)i[l]-=o/a*t[l];return s(i,i),i}function f(t,e,r,i,a,o,s,l){this.center=n(r),this.up=n(i),this.right=n(a),this.radius=n([o]),this.angle=n([s,l]),this.angle.bounds=[[-1/0,-Math.PI/2],[1/0,Math.PI/2]],this.setDistanceLimits(t,e),this.computedCenter=this.center.curve(0),this.computedUp=this.up.curve(0),this.computedRight=this.right.curve(0),this.computedRadius=this.radius.curve(0),this.computedAngle=this.angle.curve(0),this.computedToward=[0,0,0],this.computedEye=[0,0,0],this.computedMatrix=new Array(16);for(var c=0;c<16;++c)this.computedMatrix[c]=.5;this.recalcMatrix(0)}var p=f.prototype;p.setDistanceLimits=function(t,e){t=t>0?Math.log(t):-1/0,e=e>0?Math.log(e):1/0,e=Math.max(e,t),this.radius.bounds[0][0]=t,this.radius.bounds[1][0]=e},p.getDistanceLimits=function(t){var e=this.radius.bounds[0];return t?(t[0]=Math.exp(e[0][0]),t[1]=Math.exp(e[1][0]),t):[Math.exp(e[0][0]),Math.exp(e[1][0])]},p.recalcMatrix=function(t){this.center.curve(t),this.up.curve(t),this.right.curve(t),this.radius.curve(t),this.angle.curve(t);for(var e=this.computedUp,r=this.computedRight,n=0,i=0,a=0;a<3;++a)i+=e[a]*r[a],n+=e[a]*e[a];var l=Math.sqrt(n),u=0;for(a=0;a<3;++a)r[a]-=e[a]*i/n,u+=r[a]*r[a],e[a]/=l;var h=Math.sqrt(u);for(a=0;a<3;++a)r[a]/=h;var f=this.computedToward;o(f,e,r),s(f,f);var p=Math.exp(this.computedRadius[0]),d=this.computedAngle[0],g=this.computedAngle[1],m=Math.cos(d),v=Math.sin(d),y=Math.cos(g),x=Math.sin(g),b=this.computedCenter,_=m*y,w=v*y,k=x,M=-m*x,A=-v*x,T=y,S=this.computedEye,E=this.computedMatrix;for(a=0;a<3;++a){var C=_*r[a]+w*f[a]+k*e[a];E[4*a+1]=M*r[a]+A*f[a]+T*e[a],E[4*a+2]=C,E[4*a+3]=0}var L=E[1],z=E[5],P=E[9],I=E[2],O=E[6],D=E[10],R=z*D-P*O,B=P*I-L*D,F=L*O-z*I,N=c(R,B,F);R/=N,B/=N,F/=N,E[0]=R,E[4]=B,E[8]=F;for(a=0;a<3;++a)S[a]=b[a]+E[2+4*a]*p;for(a=0;a<3;++a){u=0;for(var j=0;j<3;++j)u+=E[a+4*j]*S[j];E[12+a]=-u}E[15]=1},p.getMatrix=function(t,e){this.recalcMatrix(t);var r=this.computedMatrix;if(e){for(var n=0;n<16;++n)e[n]=r[n];return e}return r};var d=[0,0,0];p.rotate=function(t,e,r,n){if(this.angle.move(t,e,r),n){this.recalcMatrix(t);var i=this.computedMatrix;d[0]=i[2],d[1]=i[6],d[2]=i[10];for(var o=this.computedUp,s=this.computedRight,l=this.computedToward,c=0;c<3;++c)i[4*c]=o[c],i[4*c+1]=s[c],i[4*c+2]=l[c];a(i,i,n,d);for(c=0;c<3;++c)o[c]=i[4*c],s[c]=i[4*c+1];this.up.set(t,o[0],o[1],o[2]),this.right.set(t,s[0],s[1],s[2])}},p.pan=function(t,e,r,n){e=e||0,r=r||0,n=n||0,this.recalcMatrix(t);var i=this.computedMatrix,a=(Math.exp(this.computedRadius[0]),i[1]),o=i[5],s=i[9],l=c(a,o,s);a/=l,o/=l,s/=l;var u=i[0],h=i[4],f=i[8],p=u*a+h*o+f*s,d=c(u-=a*p,h-=o*p,f-=s*p),g=(u/=d)*e+a*r,m=(h/=d)*e+o*r,v=(f/=d)*e+s*r;this.center.move(t,g,m,v);var y=Math.exp(this.computedRadius[0]);y=Math.max(1e-4,y+n),this.radius.set(t,Math.log(y))},p.translate=function(t,e,r,n){this.center.move(t,e||0,r||0,n||0)},p.setMatrix=function(t,e,r,n){var a=1;"number"==typeof r&&(a=0|r),(a<0||a>3)&&(a=1);var o=(a+2)%3;e||(this.recalcMatrix(t),e=this.computedMatrix);var s=e[a],l=e[a+4],h=e[a+8];if(n){var f=Math.abs(s),p=Math.abs(l),d=Math.abs(h),g=Math.max(f,p,d);f===g?(s=s<0?-1:1,l=h=0):d===g?(h=h<0?-1:1,s=l=0):(l=l<0?-1:1,s=h=0)}else{var m=c(s,l,h);s/=m,l/=m,h/=m}var v,y,x=e[o],b=e[o+4],_=e[o+8],w=x*s+b*l+_*h,k=c(x-=s*w,b-=l*w,_-=h*w),M=l*(_/=k)-h*(b/=k),A=h*(x/=k)-s*_,T=s*b-l*x,S=c(M,A,T);if(M/=S,A/=S,T/=S,this.center.jump(t,H,G,W),this.radius.idle(t),this.up.jump(t,s,l,h),this.right.jump(t,x,b,_),2===a){var E=e[1],C=e[5],L=e[9],z=E*x+C*b+L*_,P=E*M+C*A+L*T;v=R<0?-Math.PI/2:Math.PI/2,y=Math.atan2(P,z)}else{var I=e[2],O=e[6],D=e[10],R=I*s+O*l+D*h,B=I*x+O*b+D*_,F=I*M+O*A+D*T;v=Math.asin(u(R)),y=Math.atan2(F,B)}this.angle.jump(t,y,v),this.recalcMatrix(t);var N=e[2],j=e[6],V=e[10],U=this.computedMatrix;i(U,e);var q=U[15],H=U[12]/q,G=U[13]/q,W=U[14]/q,Y=Math.exp(this.computedRadius[0]);this.center.jump(t,H-N*Y,G-j*Y,W-V*Y)},p.lastT=function(){return Math.max(this.center.lastT(),this.up.lastT(),this.right.lastT(),this.radius.lastT(),this.angle.lastT())},p.idle=function(t){this.center.idle(t),this.up.idle(t),this.right.idle(t),this.radius.idle(t),this.angle.idle(t)},p.flush=function(t){this.center.flush(t),this.up.flush(t),this.right.flush(t),this.radius.flush(t),this.angle.flush(t)},p.setDistance=function(t,e){e>0&&this.radius.set(t,Math.log(e))},p.lookAt=function(t,e,r,n){this.recalcMatrix(t),e=e||this.computedEye,r=r||this.computedCenter;var i=(n=n||this.computedUp)[0],a=n[1],o=n[2],s=c(i,a,o);if(!(s<1e-6)){i/=s,a/=s,o/=s;var l=e[0]-r[0],h=e[1]-r[1],f=e[2]-r[2],p=c(l,h,f);if(!(p<1e-6)){l/=p,h/=p,f/=p;var d=this.computedRight,g=d[0],m=d[1],v=d[2],y=i*g+a*m+o*v,x=c(g-=y*i,m-=y*a,v-=y*o);if(!(x<.01&&(x=c(g=a*f-o*h,m=o*l-i*f,v=i*h-a*l))<1e-6)){g/=x,m/=x,v/=x,this.up.set(t,i,a,o),this.right.set(t,g,m,v),this.center.set(t,r[0],r[1],r[2]),this.radius.set(t,Math.log(p));var b=a*v-o*m,_=o*g-i*v,w=i*m-a*g,k=c(b,_,w),M=i*l+a*h+o*f,A=g*l+m*h+v*f,T=(b/=k)*l+(_/=k)*h+(w/=k)*f,S=Math.asin(u(M)),E=Math.atan2(T,A),C=this.angle._state,L=C[C.length-1],z=C[C.length-2];L%=2*Math.PI;var P=Math.abs(L+2*Math.PI-E),I=Math.abs(L-E),O=Math.abs(L-2*Math.PI-E);P0?r.pop():new ArrayBuffer(t)}function f(t){return new Uint8Array(h(t),0,t)}function p(t){return new Uint16Array(h(2*t),0,t)}function d(t){return new Uint32Array(h(4*t),0,t)}function g(t){return new Int8Array(h(t),0,t)}function m(t){return new Int16Array(h(2*t),0,t)}function v(t){return new Int32Array(h(4*t),0,t)}function y(t){return new Float32Array(h(4*t),0,t)}function x(t){return new Float64Array(h(8*t),0,t)}function b(t){return o?new Uint8ClampedArray(h(t),0,t):f(t)}function _(t){return new DataView(h(t),0,t)}function w(t){t=i.nextPow2(t);var e=i.log2(t),r=c[e];return r.length>0?r.pop():new n(t)}r.free=function(t){if(n.isBuffer(t))c[i.log2(t.length)].push(t);else{if("[object ArrayBuffer]"!==Object.prototype.toString.call(t)&&(t=t.buffer),!t)return;var e=t.length||t.byteLength,r=0|i.log2(e);l[r].push(t)}},r.freeUint8=r.freeUint16=r.freeUint32=r.freeInt8=r.freeInt16=r.freeInt32=r.freeFloat32=r.freeFloat=r.freeFloat64=r.freeDouble=r.freeUint8Clamped=r.freeDataView=function(t){u(t.buffer)},r.freeArrayBuffer=u,r.freeBuffer=function(t){c[i.log2(t.length)].push(t)},r.malloc=function(t,e){if(void 0===e||"arraybuffer"===e)return h(t);switch(e){case"uint8":return f(t);case"uint16":return p(t);case"uint32":return d(t);case"int8":return g(t);case"int16":return m(t);case"int32":return v(t);case"float":case"float32":return y(t);case"double":case"float64":return x(t);case"uint8_clamped":return b(t);case"buffer":return w(t);case"data":case"dataview":return _(t);default:return null}return null},r.mallocArrayBuffer=h,r.mallocUint8=f,r.mallocUint16=p,r.mallocUint32=d,r.mallocInt8=g,r.mallocInt16=m,r.mallocInt32=v,r.mallocFloat32=r.mallocFloat=y,r.mallocFloat64=r.mallocDouble=x,r.mallocUint8Clamped=b,r.mallocDataView=_,r.mallocBuffer=w,r.clearCache=function(){for(var t=0;t<32;++t)s.UINT8[t].length=0,s.UINT16[t].length=0,s.UINT32[t].length=0,s.INT8[t].length=0,s.INT16[t].length=0,s.INT32[t].length=0,s.FLOAT[t].length=0,s.DOUBLE[t].length=0,s.UINT8C[t].length=0,l[t].length=0,c[t].length=0}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},t("buffer").Buffer)},{"bit-twiddle":80,buffer:92,dup:154}],508:[function(t,e,r){"use strict";"use restrict";function n(t){this.roots=new Array(t),this.ranks=new Array(t);for(var e=0;e=a)return t;switch(t){case"%s":return String(n[r++]);case"%d":return Number(n[r++]);case"%j":try{return JSON.stringify(n[r++])}catch(t){return"[Circular]"}default:return t}}),l=n[r];r=3&&(n.depth=arguments[2]),arguments.length>=4&&(n.colors=arguments[3]),d(e)?n.showHidden=e:e&&r._extend(n,e),y(n.showHidden)&&(n.showHidden=!1),y(n.depth)&&(n.depth=2),y(n.colors)&&(n.colors=!1),y(n.customInspect)&&(n.customInspect=!0),n.colors&&(n.stylize=l),u(n,t,n.depth)}function l(t,e){var r=s.styles[e];return r?"\x1b["+s.colors[r][0]+"m"+t+"\x1b["+s.colors[r][1]+"m":t}function c(t,e){return t}function u(t,e,n){if(t.customInspect&&e&&k(e.inspect)&&e.inspect!==r.inspect&&(!e.constructor||e.constructor.prototype!==e)){var i=e.inspect(n,t);return v(i)||(i=u(t,i,n)),i}var a=function(t,e){if(y(e))return t.stylize("undefined","undefined");if(v(e)){var r="'"+JSON.stringify(e).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return t.stylize(r,"string")}if(m(e))return t.stylize(""+e,"number");if(d(e))return t.stylize(""+e,"boolean");if(g(e))return t.stylize("null","null")}(t,e);if(a)return a;var o=Object.keys(e),s=function(t){var e={};return t.forEach(function(t,r){e[t]=!0}),e}(o);if(t.showHidden&&(o=Object.getOwnPropertyNames(e)),w(e)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return h(e);if(0===o.length){if(k(e)){var l=e.name?": "+e.name:"";return t.stylize("[Function"+l+"]","special")}if(x(e))return t.stylize(RegExp.prototype.toString.call(e),"regexp");if(_(e))return t.stylize(Date.prototype.toString.call(e),"date");if(w(e))return h(e)}var c,b="",M=!1,A=["{","}"];(p(e)&&(M=!0,A=["[","]"]),k(e))&&(b=" [Function"+(e.name?": "+e.name:"")+"]");return x(e)&&(b=" "+RegExp.prototype.toString.call(e)),_(e)&&(b=" "+Date.prototype.toUTCString.call(e)),w(e)&&(b=" "+h(e)),0!==o.length||M&&0!=e.length?n<0?x(e)?t.stylize(RegExp.prototype.toString.call(e),"regexp"):t.stylize("[Object]","special"):(t.seen.push(e),c=M?function(t,e,r,n,i){for(var a=[],o=0,s=e.length;o=0&&0,t+e.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return r[0]+(""===e?"":e+"\n ")+" "+t.join(",\n ")+" "+r[1];return r[0]+e+" "+t.join(", ")+" "+r[1]}(c,b,A)):A[0]+b+A[1]}function h(t){return"["+Error.prototype.toString.call(t)+"]"}function f(t,e,r,n,i,a){var o,s,l;if((l=Object.getOwnPropertyDescriptor(e,i)||{value:e[i]}).get?s=l.set?t.stylize("[Getter/Setter]","special"):t.stylize("[Getter]","special"):l.set&&(s=t.stylize("[Setter]","special")),S(n,i)||(o="["+i+"]"),s||(t.seen.indexOf(l.value)<0?(s=g(r)?u(t,l.value,null):u(t,l.value,r-1)).indexOf("\n")>-1&&(s=a?s.split("\n").map(function(t){return" "+t}).join("\n").substr(2):"\n"+s.split("\n").map(function(t){return" "+t}).join("\n")):s=t.stylize("[Circular]","special")),y(o)){if(a&&i.match(/^\d+$/))return s;(o=JSON.stringify(""+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=t.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=t.stylize(o,"string"))}return o+": "+s}function p(t){return Array.isArray(t)}function d(t){return"boolean"==typeof t}function g(t){return null===t}function m(t){return"number"==typeof t}function v(t){return"string"==typeof t}function y(t){return void 0===t}function x(t){return b(t)&&"[object RegExp]"===M(t)}function b(t){return"object"==typeof t&&null!==t}function _(t){return b(t)&&"[object Date]"===M(t)}function w(t){return b(t)&&("[object Error]"===M(t)||t instanceof Error)}function k(t){return"function"==typeof t}function M(t){return Object.prototype.toString.call(t)}function A(t){return t<10?"0"+t.toString(10):t.toString(10)}r.debuglog=function(t){if(y(a)&&(a=e.env.NODE_DEBUG||""),t=t.toUpperCase(),!o[t])if(new RegExp("\\b"+t+"\\b","i").test(a)){var n=e.pid;o[t]=function(){var e=r.format.apply(r,arguments);console.error("%s %d: %s",t,n,e)}}else o[t]=function(){};return o[t]},r.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},r.isArray=p,r.isBoolean=d,r.isNull=g,r.isNullOrUndefined=function(t){return null==t},r.isNumber=m,r.isString=v,r.isSymbol=function(t){return"symbol"==typeof t},r.isUndefined=y,r.isRegExp=x,r.isObject=b,r.isDate=_,r.isError=w,r.isFunction=k,r.isPrimitive=function(t){return null===t||"boolean"==typeof t||"number"==typeof t||"string"==typeof t||"symbol"==typeof t||"undefined"==typeof t},r.isBuffer=t("./support/isBuffer");var T=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function S(t,e){return Object.prototype.hasOwnProperty.call(t,e)}r.log=function(){var t,e;console.log("%s - %s",(t=new Date,e=[A(t.getHours()),A(t.getMinutes()),A(t.getSeconds())].join(":"),[t.getDate(),T[t.getMonth()],e].join(" ")),r.format.apply(r,arguments))},r.inherits=t("inherits"),r._extend=function(t,e){if(!e||!b(e))return t;for(var r=Object.keys(e),n=r.length;n--;)t[r[n]]=e[r[n]];return t}}).call(this,t("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./support/isBuffer":513,_process:449,inherits:512}],515:[function(t,e,r){"use strict";e.exports=function(t,e){"object"==typeof e&&null!==e||(e={});return n(t,e.canvas||i,e.context||a,e)};var n=t("./lib/vtext"),i=null,a=null;"undefined"!=typeof document&&((i=document.createElement("canvas")).width=8192,i.height=1024,a=i.getContext("2d"))},{"./lib/vtext":516}],516:[function(t,e,r){"use strict";e.exports=function(t,e,r,n){var a=n.size||64,o=n.font||"normal";return r.font=a+"px "+o,r.textAlign="start",r.textBaseline="alphabetic",r.direction="ltr",h(function(t,e,r,n){var a=0|Math.ceil(e.measureText(r).width+2*n);if(a>8192)throw new Error("vectorize-text: String too long (sorry, this will get fixed later)");var o=3*n;t.height=0?e[a]:i})},has___:{value:x(function(e){var n=y(e);return n?r in n:t.indexOf(e)>=0})},set___:{value:x(function(n,i){var a,o=y(n);return o?o[r]=i:(a=t.indexOf(n))>=0?e[a]=i:(a=t.length,e[a]=i,t[a]=n),this})},delete___:{value:x(function(n){var i,a,o=y(n);return o?r in o&&delete o[r]:!((i=t.indexOf(n))<0||(a=t.length-1,t[i]=void 0,e[i]=e[a],t[i]=t[a],t.length=a,e.length=a,0))})}})};g.prototype=Object.create(Object.prototype,{get:{value:function(t,e){return this.get___(t,e)},writable:!0,configurable:!0},has:{value:function(t){return this.has___(t)},writable:!0,configurable:!0},set:{value:function(t,e){return this.set___(t,e)},writable:!0,configurable:!0},delete:{value:function(t){return this.delete___(t)},writable:!0,configurable:!0}}),"function"==typeof r?function(){function n(){this instanceof g||b();var e,n=new r,i=void 0,a=!1;return e=t?function(t,e){return n.set(t,e),n.has(t)||(i||(i=new g),i.set(t,e)),this}:function(t,e){if(a)try{n.set(t,e)}catch(r){i||(i=new g),i.set___(t,e)}else n.set(t,e);return this},Object.create(g.prototype,{get___:{value:x(function(t,e){return i?n.has(t)?n.get(t):i.get___(t,e):n.get(t,e)})},has___:{value:x(function(t){return n.has(t)||!!i&&i.has___(t)})},set___:{value:x(e)},delete___:{value:x(function(t){var e=!!n.delete(t);return i&&i.delete___(t)||e})},permitHostObjects___:{value:x(function(t){if(t!==m)throw new Error("bogus call to permitHostObjects___");a=!0})}})}t&&"undefined"!=typeof Proxy&&(Proxy=void 0),n.prototype=g.prototype,e.exports=n,Object.defineProperty(WeakMap.prototype,"constructor",{value:WeakMap,enumerable:!1,configurable:!0,writable:!0})}():("undefined"!=typeof Proxy&&(Proxy=void 0),e.exports=g)}function m(t){t.permitHostObjects___&&t.permitHostObjects___(m)}function v(t){return!(t.substr(0,l.length)==l&&"___"===t.substr(t.length-3))}function y(t){if(t!==Object(t))throw new TypeError("Not an object: "+t);var e=t[c];if(e&&e.key===t)return e;if(s(t)){e={key:t};try{return o(t,c,{value:e,writable:!1,enumerable:!1,configurable:!1}),e}catch(t){return}}}function x(t){return t.prototype=null,Object.freeze(t)}function b(){p||"undefined"==typeof console||(p=!0,console.warn("WeakMap should be invoked as new WeakMap(), not WeakMap(). This will be an error in the future."))}}()},{}],518:[function(t,e,r){var n=t("./hidden-store.js");e.exports=function(){var t={};return function(e){if(("object"!=typeof e||null===e)&&"function"!=typeof e)throw new Error("Weakmap-shim: Key must be object");var r=e.valueOf(t);return r&&r.identity===t?r:n(e,t)}}},{"./hidden-store.js":519}],519:[function(t,e,r){e.exports=function(t,e){var r={identity:e},n=t.valueOf;return Object.defineProperty(t,"valueOf",{value:function(t){return t!==e?n.apply(this,arguments):r},writable:!0}),r}},{}],520:[function(t,e,r){var n=t("./create-store.js");e.exports=function(){var t=n();return{get:function(e,r){var n=t(e);return n.hasOwnProperty("value")?n.value:r},set:function(e,r){return t(e).value=r,this},has:function(e){return"value"in t(e)},delete:function(e){return delete t(e).value}}}},{"./create-store.js":518}],521:[function(t,e,r){var n=t("get-canvas-context");e.exports=function(t){return n("webgl",t)}},{"get-canvas-context":221}],522:[function(t,e,r){var n=t("../main"),i=t("object-assign"),a=n.instance();function o(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}o.prototype=new n.baseCalendar,i(o.prototype,{name:"Chinese",jdEpoch:1721425.5,hasYearZero:!1,minMonth:0,firstMonth:0,minDay:1,regionalOptions:{"":{name:"Chinese",epochs:["BEC","EC"],monthNumbers:function(t,e){if("string"==typeof t){var r=t.match(l);return r?r[0]:""}var n=this._validateYear(t),i=t.month(),a=""+this.toChineseMonth(n,i);return e&&a.length<2&&(a="0"+a),this.isIntercalaryMonth(n,i)&&(a+="i"),a},monthNames:function(t){if("string"==typeof t){var e=t.match(c);return e?e[0]:""}var r=this._validateYear(t),n=t.month(),i=["\u4e00\u6708","\u4e8c\u6708","\u4e09\u6708","\u56db\u6708","\u4e94\u6708","\u516d\u6708","\u4e03\u6708","\u516b\u6708","\u4e5d\u6708","\u5341\u6708","\u5341\u4e00\u6708","\u5341\u4e8c\u6708"][this.toChineseMonth(r,n)-1];return this.isIntercalaryMonth(r,n)&&(i="\u95f0"+i),i},monthNamesShort:function(t){if("string"==typeof t){var e=t.match(u);return e?e[0]:""}var r=this._validateYear(t),n=t.month(),i=["\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u5341\u4e00","\u5341\u4e8c"][this.toChineseMonth(r,n)-1];return this.isIntercalaryMonth(r,n)&&(i="\u95f0"+i),i},parseMonth:function(t,e){t=this._validateYear(t);var r,n=parseInt(e);if(isNaN(n))"\u95f0"===e[0]&&(r=!0,e=e.substring(1)),"\u6708"===e[e.length-1]&&(e=e.substring(0,e.length-1)),n=1+["\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u5341\u4e00","\u5341\u4e8c"].indexOf(e);else{var i=e[e.length-1];r="i"===i||"I"===i}return this.toMonthIndex(t,n,r)},dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],digits:null,dateFormat:"yyyy/mm/dd",firstDay:1,isRTL:!1}},_validateYear:function(t,e){if(t.year&&(t=t.year()),"number"!=typeof t||t<1888||t>2111)throw e.replace(/\{0\}/,this.local.name);return t},toMonthIndex:function(t,e,r){var i=this.intercalaryMonth(t);if(r&&e!==i||e<1||e>12)throw n.local.invalidMonth.replace(/\{0\}/,this.local.name);return i?!r&&e<=i?e-1:e:e-1},toChineseMonth:function(t,e){t.year&&(e=(t=t.year()).month());var r=this.intercalaryMonth(t);if(e<0||e>(r?12:11))throw n.local.invalidMonth.replace(/\{0\}/,this.local.name);return r?e>13},isIntercalaryMonth:function(t,e){t.year&&(e=(t=t.year()).month());var r=this.intercalaryMonth(t);return!!r&&r===e},leapYear:function(t){return 0!==this.intercalaryMonth(t)},weekOfYear:function(t,e,r){var i,o=this._validateYear(t,n.local.invalidyear),s=f[o-f[0]],l=s>>9&4095,c=s>>5&15,u=31&s;(i=a.newDate(l,c,u)).add(4-(i.dayOfWeek()||7),"d");var h=this.toJD(t,e,r)-i.toJD();return 1+Math.floor(h/7)},monthsInYear:function(t){return this.leapYear(t)?13:12},daysInMonth:function(t,e){t.year&&(e=t.month(),t=t.year()),t=this._validateYear(t);var r=h[t-h[0]];if(e>(r>>13?12:11))throw n.local.invalidMonth.replace(/\{0\}/,this.local.name);return r&1<<12-e?30:29},weekDay:function(t,e,r){return(this.dayOfWeek(t,e,r)||7)<6},toJD:function(t,e,r){var i=this._validate(t,s,r,n.local.invalidDate);t=this._validateYear(i.year()),e=i.month(),r=i.day();var o=this.isIntercalaryMonth(t,e),s=this.toChineseMonth(t,e),l=function(t,e,r,n,i){var a,o,s;if("object"==typeof t)o=t,a=e||{};else{var l="number"==typeof t&&t>=1888&&t<=2111;if(!l)throw new Error("Lunar year outside range 1888-2111");var c="number"==typeof e&&e>=1&&e<=12;if(!c)throw new Error("Lunar month outside range 1 - 12");var u,p="number"==typeof r&&r>=1&&r<=30;if(!p)throw new Error("Lunar day outside range 1 - 30");"object"==typeof n?(u=!1,a=n):(u=!!n,a=i||{}),o={year:t,month:e,day:r,isIntercalary:u}}s=o.day-1;var d,g=h[o.year-h[0]],m=g>>13;d=m?o.month>m?o.month:o.isIntercalary?o.month:o.month-1:o.month-1;for(var v=0;v>9&4095,(x>>5&15)-1,(31&x)+s);return a.year=b.getFullYear(),a.month=1+b.getMonth(),a.day=b.getDate(),a}(t,s,r,o);return a.toJD(l.year,l.month,l.day)},fromJD:function(t){var e=a.fromJD(t),r=function(t,e,r,n){var i,a;if("object"==typeof t)i=t,a=e||{};else{var o="number"==typeof t&&t>=1888&&t<=2111;if(!o)throw new Error("Solar year outside range 1888-2111");var s="number"==typeof e&&e>=1&&e<=12;if(!s)throw new Error("Solar month outside range 1 - 12");var l="number"==typeof r&&r>=1&&r<=31;if(!l)throw new Error("Solar day outside range 1 - 31");i={year:t,month:e,day:r},a=n||{}}var c=f[i.year-f[0]],u=i.year<<9|i.month<<5|i.day;a.year=u>=c?i.year:i.year-1,c=f[a.year-f[0]];var p,d=new Date(c>>9&4095,(c>>5&15)-1,31&c),g=new Date(i.year,i.month-1,i.day);p=Math.round((g-d)/864e5);var m,v=h[a.year-h[0]];for(m=0;m<13;m++){var y=v&1<<12-m?30:29;if(p>13;!x||m=2&&n<=6},extraInfo:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);return{century:o[Math.floor((i.year()-1)/100)+1]||""}},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);return t=i.year()+(i.year()<0?1:0),e=i.month(),(r=i.day())+(e>1?16:0)+(e>2?32*(e-2):0)+400*(t-1)+this.jdEpoch-1},fromJD:function(t){t=Math.floor(t+.5)-Math.floor(this.jdEpoch)-1;var e=Math.floor(t/400)+1;t-=400*(e-1),t+=t>15?16:0;var r=Math.floor(t/32)+1,n=t-32*(r-1)+1;return this.newDate(e<=0?e-1:e,r,n)}});var o={20:"Fruitbat",21:"Anchovy"};n.calendars.discworld=a},{"../main":536,"object-assign":421}],525:[function(t,e,r){var n=t("../main"),i=t("object-assign");function a(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}a.prototype=new n.baseCalendar,i(a.prototype,{name:"Ethiopian",jdEpoch:1724220.5,daysPerMonth:[30,30,30,30,30,30,30,30,30,30,30,30,5],hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,regionalOptions:{"":{name:"Ethiopian",epochs:["BEE","EE"],monthNames:["Meskerem","Tikemet","Hidar","Tahesas","Tir","Yekatit","Megabit","Miazia","Genbot","Sene","Hamle","Nehase","Pagume"],monthNamesShort:["Mes","Tik","Hid","Tah","Tir","Yek","Meg","Mia","Gen","Sen","Ham","Neh","Pag"],dayNames:["Ehud","Segno","Maksegno","Irob","Hamus","Arb","Kidame"],dayNamesShort:["Ehu","Seg","Mak","Iro","Ham","Arb","Kid"],dayNamesMin:["Eh","Se","Ma","Ir","Ha","Ar","Ki"],digits:null,dateFormat:"dd/mm/yyyy",firstDay:0,isRTL:!1}},leapYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear);return(t=e.year()+(e.year()<0?1:0))%4==3||t%4==-1},monthsInYear:function(t){return this._validate(t,this.minMonth,this.minDay,n.local.invalidYear||n.regionalOptions[""].invalidYear),13},weekOfYear:function(t,e,r){var n=this.newDate(t,e,r);return n.add(-n.dayOfWeek(),"d"),Math.floor((n.dayOfYear()-1)/7)+1},daysInMonth:function(t,e){var r=this._validate(t,e,this.minDay,n.local.invalidMonth);return this.daysPerMonth[r.month()-1]+(13===r.month()&&this.leapYear(r.year())?1:0)},weekDay:function(t,e,r){return(this.dayOfWeek(t,e,r)||7)<6},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);return(t=i.year())<0&&t++,i.day()+30*(i.month()-1)+365*(t-1)+Math.floor(t/4)+this.jdEpoch-1},fromJD:function(t){var e=Math.floor(t)+.5-this.jdEpoch,r=Math.floor((e-Math.floor((e+366)/1461))/365)+1;r<=0&&r--,e=Math.floor(t)+.5-this.newDate(r,1,1).toJD();var n=Math.floor(e/30)+1,i=e-30*(n-1)+1;return this.newDate(r,n,i)}}),n.calendars.ethiopian=a},{"../main":536,"object-assign":421}],526:[function(t,e,r){var n=t("../main"),i=t("object-assign");function a(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}function o(t,e){return t-e*Math.floor(t/e)}a.prototype=new n.baseCalendar,i(a.prototype,{name:"Hebrew",jdEpoch:347995.5,daysPerMonth:[30,29,30,29,30,29,30,29,30,29,30,29,29],hasYearZero:!1,minMonth:1,firstMonth:7,minDay:1,regionalOptions:{"":{name:"Hebrew",epochs:["BAM","AM"],monthNames:["Nisan","Iyar","Sivan","Tammuz","Av","Elul","Tishrei","Cheshvan","Kislev","Tevet","Shevat","Adar","Adar II"],monthNamesShort:["Nis","Iya","Siv","Tam","Av","Elu","Tis","Che","Kis","Tev","She","Ada","Ad2"],dayNames:["Yom Rishon","Yom Sheni","Yom Shlishi","Yom Revi'i","Yom Chamishi","Yom Shishi","Yom Shabbat"],dayNamesShort:["Ris","She","Shl","Rev","Cha","Shi","Sha"],dayNamesMin:["Ri","She","Shl","Re","Ch","Shi","Sha"],digits:null,dateFormat:"dd/mm/yyyy",firstDay:0,isRTL:!1}},leapYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear);return this._leapYear(e.year())},_leapYear:function(t){return o(7*(t=t<0?t+1:t)+1,19)<7},monthsInYear:function(t){return this._validate(t,this.minMonth,this.minDay,n.local.invalidYear),this._leapYear(t.year?t.year():t)?13:12},weekOfYear:function(t,e,r){var n=this.newDate(t,e,r);return n.add(-n.dayOfWeek(),"d"),Math.floor((n.dayOfYear()-1)/7)+1},daysInYear:function(t){return t=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear).year(),this.toJD(-1===t?1:t+1,7,1)-this.toJD(t,7,1)},daysInMonth:function(t,e){return t.year&&(e=t.month(),t=t.year()),this._validate(t,e,this.minDay,n.local.invalidMonth),12===e&&this.leapYear(t)?30:8===e&&5===o(this.daysInYear(t),10)?30:9===e&&3===o(this.daysInYear(t),10)?29:this.daysPerMonth[e-1]},weekDay:function(t,e,r){return 6!==this.dayOfWeek(t,e,r)},extraInfo:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);return{yearType:(this.leapYear(i)?"embolismic":"common")+" "+["deficient","regular","complete"][this.daysInYear(i)%10-3]}},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);t=i.year(),e=i.month(),r=i.day();var a=t<=0?t+1:t,o=this.jdEpoch+this._delay1(a)+this._delay2(a)+r+1;if(e<7){for(var s=7;s<=this.monthsInYear(t);s++)o+=this.daysInMonth(t,s);for(s=1;s=this.toJD(-1===e?1:e+1,7,1);)e++;for(var r=tthis.toJD(e,r,this.daysInMonth(e,r));)r++;var n=t-this.toJD(e,r,1)+1;return this.newDate(e,r,n)}}),n.calendars.hebrew=a},{"../main":536,"object-assign":421}],527:[function(t,e,r){var n=t("../main"),i=t("object-assign");function a(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}a.prototype=new n.baseCalendar,i(a.prototype,{name:"Islamic",jdEpoch:1948439.5,daysPerMonth:[30,29,30,29,30,29,30,29,30,29,30,29],hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,regionalOptions:{"":{name:"Islamic",epochs:["BH","AH"],monthNames:["Muharram","Safar","Rabi' al-awwal","Rabi' al-thani","Jumada al-awwal","Jumada al-thani","Rajab","Sha'aban","Ramadan","Shawwal","Dhu al-Qi'dah","Dhu al-Hijjah"],monthNamesShort:["Muh","Saf","Rab1","Rab2","Jum1","Jum2","Raj","Sha'","Ram","Shaw","DhuQ","DhuH"],dayNames:["Yawm al-ahad","Yawm al-ithnayn","Yawm ath-thulaathaa'","Yawm al-arbi'aa'","Yawm al-kham\u012bs","Yawm al-jum'a","Yawm as-sabt"],dayNamesShort:["Aha","Ith","Thu","Arb","Kha","Jum","Sab"],dayNamesMin:["Ah","It","Th","Ar","Kh","Ju","Sa"],digits:null,dateFormat:"yyyy/mm/dd",firstDay:6,isRTL:!1}},leapYear:function(t){return(11*this._validate(t,this.minMonth,this.minDay,n.local.invalidYear).year()+14)%30<11},weekOfYear:function(t,e,r){var n=this.newDate(t,e,r);return n.add(-n.dayOfWeek(),"d"),Math.floor((n.dayOfYear()-1)/7)+1},daysInYear:function(t){return this.leapYear(t)?355:354},daysInMonth:function(t,e){var r=this._validate(t,e,this.minDay,n.local.invalidMonth);return this.daysPerMonth[r.month()-1]+(12===r.month()&&this.leapYear(r.year())?1:0)},weekDay:function(t,e,r){return 5!==this.dayOfWeek(t,e,r)},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);return t=i.year(),e=i.month(),t=t<=0?t+1:t,(r=i.day())+Math.ceil(29.5*(e-1))+354*(t-1)+Math.floor((3+11*t)/30)+this.jdEpoch-1},fromJD:function(t){t=Math.floor(t)+.5;var e=Math.floor((30*(t-this.jdEpoch)+10646)/10631);e=e<=0?e-1:e;var r=Math.min(12,Math.ceil((t-29-this.toJD(e,1,1))/29.5)+1),n=t-this.toJD(e,r,1)+1;return this.newDate(e,r,n)}}),n.calendars.islamic=a},{"../main":536,"object-assign":421}],528:[function(t,e,r){var n=t("../main"),i=t("object-assign");function a(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}a.prototype=new n.baseCalendar,i(a.prototype,{name:"Julian",jdEpoch:1721423.5,daysPerMonth:[31,28,31,30,31,30,31,31,30,31,30,31],hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,regionalOptions:{"":{name:"Julian",epochs:["BC","AD"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],digits:null,dateFormat:"mm/dd/yyyy",firstDay:0,isRTL:!1}},leapYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear);return(t=e.year()<0?e.year()+1:e.year())%4==0},weekOfYear:function(t,e,r){var n=this.newDate(t,e,r);return n.add(4-(n.dayOfWeek()||7),"d"),Math.floor((n.dayOfYear()-1)/7)+1},daysInMonth:function(t,e){var r=this._validate(t,e,this.minDay,n.local.invalidMonth);return this.daysPerMonth[r.month()-1]+(2===r.month()&&this.leapYear(r.year())?1:0)},weekDay:function(t,e,r){return(this.dayOfWeek(t,e,r)||7)<6},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);return t=i.year(),e=i.month(),r=i.day(),t<0&&t++,e<=2&&(t--,e+=12),Math.floor(365.25*(t+4716))+Math.floor(30.6001*(e+1))+r-1524.5},fromJD:function(t){var e=Math.floor(t+.5)+1524,r=Math.floor((e-122.1)/365.25),n=Math.floor(365.25*r),i=Math.floor((e-n)/30.6001),a=i-Math.floor(i<14?1:13),o=r-Math.floor(a>2?4716:4715),s=e-n-Math.floor(30.6001*i);return o<=0&&o--,this.newDate(o,a,s)}}),n.calendars.julian=a},{"../main":536,"object-assign":421}],529:[function(t,e,r){var n=t("../main"),i=t("object-assign");function a(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}function o(t,e){return t-e*Math.floor(t/e)}function s(t,e){return o(t-1,e)+1}a.prototype=new n.baseCalendar,i(a.prototype,{name:"Mayan",jdEpoch:584282.5,hasYearZero:!0,minMonth:0,firstMonth:0,minDay:0,regionalOptions:{"":{name:"Mayan",epochs:["",""],monthNames:["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"],monthNamesShort:["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"],dayNames:["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19"],dayNamesShort:["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19"],dayNamesMin:["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19"],digits:null,dateFormat:"YYYY.m.d",firstDay:0,isRTL:!1,haabMonths:["Pop","Uo","Zip","Zotz","Tzec","Xul","Yaxkin","Mol","Chen","Yax","Zac","Ceh","Mac","Kankin","Muan","Pax","Kayab","Cumku","Uayeb"],tzolkinMonths:["Imix","Ik","Akbal","Kan","Chicchan","Cimi","Manik","Lamat","Muluc","Oc","Chuen","Eb","Ben","Ix","Men","Cib","Caban","Etznab","Cauac","Ahau"]}},leapYear:function(t){return this._validate(t,this.minMonth,this.minDay,n.local.invalidYear),!1},formatYear:function(t){t=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear).year();var e=Math.floor(t/400);return t%=400,t+=t<0?400:0,e+"."+Math.floor(t/20)+"."+t%20},forYear:function(t){if((t=t.split(".")).length<3)throw"Invalid Mayan year";for(var e=0,r=0;r19||r>0&&n<0)throw"Invalid Mayan year";e=20*e+n}return e},monthsInYear:function(t){return this._validate(t,this.minMonth,this.minDay,n.local.invalidYear),18},weekOfYear:function(t,e,r){return this._validate(t,e,r,n.local.invalidDate),0},daysInYear:function(t){return this._validate(t,this.minMonth,this.minDay,n.local.invalidYear),360},daysInMonth:function(t,e){return this._validate(t,e,this.minDay,n.local.invalidMonth),20},daysInWeek:function(){return 5},dayOfWeek:function(t,e,r){return this._validate(t,e,r,n.local.invalidDate).day()},weekDay:function(t,e,r){return this._validate(t,e,r,n.local.invalidDate),!0},extraInfo:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate).toJD(),a=this._toHaab(i),o=this._toTzolkin(i);return{haabMonthName:this.local.haabMonths[a[0]-1],haabMonth:a[0],haabDay:a[1],tzolkinDayName:this.local.tzolkinMonths[o[0]-1],tzolkinDay:o[0],tzolkinTrecena:o[1]}},_toHaab:function(t){var e=o((t-=this.jdEpoch)+8+340,365);return[Math.floor(e/20)+1,o(e,20)]},_toTzolkin:function(t){return[s((t-=this.jdEpoch)+20,20),s(t+4,13)]},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);return i.day()+20*i.month()+360*i.year()+this.jdEpoch},fromJD:function(t){t=Math.floor(t)+.5-this.jdEpoch;var e=Math.floor(t/360);t%=360,t+=t<0?360:0;var r=Math.floor(t/20),n=t%20;return this.newDate(e,r,n)}}),n.calendars.mayan=a},{"../main":536,"object-assign":421}],530:[function(t,e,r){var n=t("../main"),i=t("object-assign");function a(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}a.prototype=new n.baseCalendar;var o=n.instance("gregorian");i(a.prototype,{name:"Nanakshahi",jdEpoch:2257673.5,daysPerMonth:[31,31,31,31,31,30,30,30,30,30,30,30],hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,regionalOptions:{"":{name:"Nanakshahi",epochs:["BN","AN"],monthNames:["Chet","Vaisakh","Jeth","Harh","Sawan","Bhadon","Assu","Katak","Maghar","Poh","Magh","Phagun"],monthNamesShort:["Che","Vai","Jet","Har","Saw","Bha","Ass","Kat","Mgr","Poh","Mgh","Pha"],dayNames:["Somvaar","Mangalvar","Budhvaar","Veervaar","Shukarvaar","Sanicharvaar","Etvaar"],dayNamesShort:["Som","Mangal","Budh","Veer","Shukar","Sanichar","Et"],dayNamesMin:["So","Ma","Bu","Ve","Sh","Sa","Et"],digits:null,dateFormat:"dd-mm-yyyy",firstDay:0,isRTL:!1}},leapYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear||n.regionalOptions[""].invalidYear);return o.leapYear(e.year()+(e.year()<1?1:0)+1469)},weekOfYear:function(t,e,r){var n=this.newDate(t,e,r);return n.add(1-(n.dayOfWeek()||7),"d"),Math.floor((n.dayOfYear()-1)/7)+1},daysInMonth:function(t,e){var r=this._validate(t,e,this.minDay,n.local.invalidMonth);return this.daysPerMonth[r.month()-1]+(12===r.month()&&this.leapYear(r.year())?1:0)},weekDay:function(t,e,r){return(this.dayOfWeek(t,e,r)||7)<6},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidMonth);(t=i.year())<0&&t++;for(var a=i.day(),s=1;s=this.toJD(e+1,1,1);)e++;for(var r=t-Math.floor(this.toJD(e,1,1)+.5)+1,n=1;r>this.daysInMonth(e,n);)r-=this.daysInMonth(e,n),n++;return this.newDate(e,n,r)}}),n.calendars.nanakshahi=a},{"../main":536,"object-assign":421}],531:[function(t,e,r){var n=t("../main"),i=t("object-assign");function a(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}a.prototype=new n.baseCalendar,i(a.prototype,{name:"Nepali",jdEpoch:1700709.5,daysPerMonth:[31,31,32,32,31,30,30,29,30,29,30,30],hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,daysPerYear:365,regionalOptions:{"":{name:"Nepali",epochs:["BBS","ABS"],monthNames:["Baisakh","Jestha","Ashadh","Shrawan","Bhadra","Ashwin","Kartik","Mangsir","Paush","Mangh","Falgun","Chaitra"],monthNamesShort:["Bai","Je","As","Shra","Bha","Ash","Kar","Mang","Pau","Ma","Fal","Chai"],dayNames:["Aaitabaar","Sombaar","Manglbaar","Budhabaar","Bihibaar","Shukrabaar","Shanibaar"],dayNamesShort:["Aaita","Som","Mangl","Budha","Bihi","Shukra","Shani"],dayNamesMin:["Aai","So","Man","Bu","Bi","Shu","Sha"],digits:null,dateFormat:"dd/mm/yyyy",firstDay:1,isRTL:!1}},leapYear:function(t){return this.daysInYear(t)!==this.daysPerYear},weekOfYear:function(t,e,r){var n=this.newDate(t,e,r);return n.add(-n.dayOfWeek(),"d"),Math.floor((n.dayOfYear()-1)/7)+1},daysInYear:function(t){if(t=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear).year(),"undefined"==typeof this.NEPALI_CALENDAR_DATA[t])return this.daysPerYear;for(var e=0,r=this.minMonth;r<=12;r++)e+=this.NEPALI_CALENDAR_DATA[t][r];return e},daysInMonth:function(t,e){return t.year&&(e=t.month(),t=t.year()),this._validate(t,e,this.minDay,n.local.invalidMonth),"undefined"==typeof this.NEPALI_CALENDAR_DATA[t]?this.daysPerMonth[e-1]:this.NEPALI_CALENDAR_DATA[t][e]},weekDay:function(t,e,r){return 6!==this.dayOfWeek(t,e,r)},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);t=i.year(),e=i.month(),r=i.day();var a=n.instance(),o=0,s=e,l=t;this._createMissingCalendarData(t);var c=t-(s>9||9===s&&r>=this.NEPALI_CALENDAR_DATA[l][0]?56:57);for(9!==e&&(o=r,s--);9!==s;)s<=0&&(s=12,l--),o+=this.NEPALI_CALENDAR_DATA[l][s],s--;return 9===e?(o+=r-this.NEPALI_CALENDAR_DATA[l][0])<0&&(o+=a.daysInYear(c)):o+=this.NEPALI_CALENDAR_DATA[l][9]-this.NEPALI_CALENDAR_DATA[l][0],a.newDate(c,1,1).add(o,"d").toJD()},fromJD:function(t){var e=n.instance().fromJD(t),r=e.year(),i=e.dayOfYear(),a=r+56;this._createMissingCalendarData(a);for(var o=9,s=this.NEPALI_CALENDAR_DATA[a][0],l=this.NEPALI_CALENDAR_DATA[a][o]-s+1;i>l;)++o>12&&(o=1,a++),l+=this.NEPALI_CALENDAR_DATA[a][o];var c=this.NEPALI_CALENDAR_DATA[a][o]-(l-i);return this.newDate(a,o,c)},_createMissingCalendarData:function(t){var e=this.daysPerMonth.slice(0);e.unshift(17);for(var r=t-1;r0?474:473))%2820+474+38)%2816<682},weekOfYear:function(t,e,r){var n=this.newDate(t,e,r);return n.add(-(n.dayOfWeek()+1)%7,"d"),Math.floor((n.dayOfYear()-1)/7)+1},daysInMonth:function(t,e){var r=this._validate(t,e,this.minDay,n.local.invalidMonth);return this.daysPerMonth[r.month()-1]+(12===r.month()&&this.leapYear(r.year())?1:0)},weekDay:function(t,e,r){return 5!==this.dayOfWeek(t,e,r)},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);t=i.year(),e=i.month(),r=i.day();var a=t-(t>=0?474:473),s=474+o(a,2820);return r+(e<=7?31*(e-1):30*(e-1)+6)+Math.floor((682*s-110)/2816)+365*(s-1)+1029983*Math.floor(a/2820)+this.jdEpoch-1},fromJD:function(t){var e=(t=Math.floor(t)+.5)-this.toJD(475,1,1),r=Math.floor(e/1029983),n=o(e,1029983),i=2820;if(1029982!==n){var a=Math.floor(n/366),s=o(n,366);i=Math.floor((2134*a+2816*s+2815)/1028522)+a+1}var l=i+2820*r+474;l=l<=0?l-1:l;var c=t-this.toJD(l,1,1)+1,u=c<=186?Math.ceil(c/31):Math.ceil((c-6)/30),h=t-this.toJD(l,u,1)+1;return this.newDate(l,u,h)}}),n.calendars.persian=a,n.calendars.jalali=a},{"../main":536,"object-assign":421}],533:[function(t,e,r){var n=t("../main"),i=t("object-assign"),a=n.instance();function o(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}o.prototype=new n.baseCalendar,i(o.prototype,{name:"Taiwan",jdEpoch:2419402.5,yearsOffset:1911,daysPerMonth:[31,28,31,30,31,30,31,31,30,31,30,31],hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,regionalOptions:{"":{name:"Taiwan",epochs:["BROC","ROC"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],digits:null,dateFormat:"yyyy/mm/dd",firstDay:1,isRTL:!1}},leapYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear);t=this._t2gYear(e.year());return a.leapYear(t)},weekOfYear:function(t,e,r){var i=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear);t=this._t2gYear(i.year());return a.weekOfYear(t,i.month(),i.day())},daysInMonth:function(t,e){var r=this._validate(t,e,this.minDay,n.local.invalidMonth);return this.daysPerMonth[r.month()-1]+(2===r.month()&&this.leapYear(r.year())?1:0)},weekDay:function(t,e,r){return(this.dayOfWeek(t,e,r)||7)<6},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);t=this._t2gYear(i.year());return a.toJD(t,i.month(),i.day())},fromJD:function(t){var e=a.fromJD(t),r=this._g2tYear(e.year());return this.newDate(r,e.month(),e.day())},_t2gYear:function(t){return t+this.yearsOffset+(t>=-this.yearsOffset&&t<=-1?1:0)},_g2tYear:function(t){return t-this.yearsOffset-(t>=1&&t<=this.yearsOffset?1:0)}}),n.calendars.taiwan=o},{"../main":536,"object-assign":421}],534:[function(t,e,r){var n=t("../main"),i=t("object-assign"),a=n.instance();function o(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}o.prototype=new n.baseCalendar,i(o.prototype,{name:"Thai",jdEpoch:1523098.5,yearsOffset:543,daysPerMonth:[31,28,31,30,31,30,31,31,30,31,30,31],hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,regionalOptions:{"":{name:"Thai",epochs:["BBE","BE"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],digits:null,dateFormat:"dd/mm/yyyy",firstDay:0,isRTL:!1}},leapYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear);t=this._t2gYear(e.year());return a.leapYear(t)},weekOfYear:function(t,e,r){var i=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear);t=this._t2gYear(i.year());return a.weekOfYear(t,i.month(),i.day())},daysInMonth:function(t,e){var r=this._validate(t,e,this.minDay,n.local.invalidMonth);return this.daysPerMonth[r.month()-1]+(2===r.month()&&this.leapYear(r.year())?1:0)},weekDay:function(t,e,r){return(this.dayOfWeek(t,e,r)||7)<6},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate);t=this._t2gYear(i.year());return a.toJD(t,i.month(),i.day())},fromJD:function(t){var e=a.fromJD(t),r=this._g2tYear(e.year());return this.newDate(r,e.month(),e.day())},_t2gYear:function(t){return t-this.yearsOffset-(t>=1&&t<=this.yearsOffset?1:0)},_g2tYear:function(t){return t+this.yearsOffset+(t>=-this.yearsOffset&&t<=-1?1:0)}}),n.calendars.thai=o},{"../main":536,"object-assign":421}],535:[function(t,e,r){var n=t("../main"),i=t("object-assign");function a(t){this.local=this.regionalOptions[t||""]||this.regionalOptions[""]}a.prototype=new n.baseCalendar,i(a.prototype,{name:"UmmAlQura",hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,regionalOptions:{"":{name:"Umm al-Qura",epochs:["BH","AH"],monthNames:["Al-Muharram","Safar","Rabi' al-awwal","Rabi' Al-Thani","Jumada Al-Awwal","Jumada Al-Thani","Rajab","Sha'aban","Ramadan","Shawwal","Dhu al-Qi'dah","Dhu al-Hijjah"],monthNamesShort:["Muh","Saf","Rab1","Rab2","Jum1","Jum2","Raj","Sha'","Ram","Shaw","DhuQ","DhuH"],dayNames:["Yawm al-Ahad","Yawm al-Ithnain","Yawm al-Thal\u0101th\u0101\u2019","Yawm al-Arba\u2018\u0101\u2019","Yawm al-Kham\u012bs","Yawm al-Jum\u2018a","Yawm al-Sabt"],dayNamesMin:["Ah","Ith","Th","Ar","Kh","Ju","Sa"],digits:null,dateFormat:"yyyy/mm/dd",firstDay:6,isRTL:!0}},leapYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,n.local.invalidYear);return 355===this.daysInYear(e.year())},weekOfYear:function(t,e,r){var n=this.newDate(t,e,r);return n.add(-n.dayOfWeek(),"d"),Math.floor((n.dayOfYear()-1)/7)+1},daysInYear:function(t){for(var e=0,r=1;r<=12;r++)e+=this.daysInMonth(t,r);return e},daysInMonth:function(t,e){for(var r=this._validate(t,e,this.minDay,n.local.invalidMonth).toJD()-24e5+.5,i=0,a=0;ar)return o[i]-o[i-1];i++}return 30},weekDay:function(t,e,r){return 5!==this.dayOfWeek(t,e,r)},toJD:function(t,e,r){var i=this._validate(t,e,r,n.local.invalidDate),a=12*(i.year()-1)+i.month()-15292;return i.day()+o[a-1]-1+24e5-.5},fromJD:function(t){for(var e=t-24e5+.5,r=0,n=0;ne);n++)r++;var i=r+15292,a=Math.floor((i-1)/12),s=a+1,l=i-12*a,c=e-o[r-1]+1;return this.newDate(s,l,c)},isValid:function(t,e,r){var i=n.baseCalendar.prototype.isValid.apply(this,arguments);return i&&(i=(t=null!=t.year?t.year:t)>=1276&&t<=1500),i},_validate:function(t,e,r,i){var a=n.baseCalendar.prototype._validate.apply(this,arguments);if(a.year<1276||a.year>1500)throw i.replace(/\{0\}/,this.local.name);return a}}),n.calendars.ummalqura=a;var o=[20,50,79,109,138,168,197,227,256,286,315,345,374,404,433,463,492,522,551,581,611,641,670,700,729,759,788,818,847,877,906,936,965,995,1024,1054,1083,1113,1142,1172,1201,1231,1260,1290,1320,1350,1379,1409,1438,1468,1497,1527,1556,1586,1615,1645,1674,1704,1733,1763,1792,1822,1851,1881,1910,1940,1969,1999,2028,2058,2087,2117,2146,2176,2205,2235,2264,2294,2323,2353,2383,2413,2442,2472,2501,2531,2560,2590,2619,2649,2678,2708,2737,2767,2796,2826,2855,2885,2914,2944,2973,3003,3032,3062,3091,3121,3150,3180,3209,3239,3268,3298,3327,3357,3386,3416,3446,3476,3505,3535,3564,3594,3623,3653,3682,3712,3741,3771,3800,3830,3859,3889,3918,3948,3977,4007,4036,4066,4095,4125,4155,4185,4214,4244,4273,4303,4332,4362,4391,4421,4450,4480,4509,4539,4568,4598,4627,4657,4686,4716,4745,4775,4804,4834,4863,4893,4922,4952,4981,5011,5040,5070,5099,5129,5158,5188,5218,5248,5277,5307,5336,5366,5395,5425,5454,5484,5513,5543,5572,5602,5631,5661,5690,5720,5749,5779,5808,5838,5867,5897,5926,5956,5985,6015,6044,6074,6103,6133,6162,6192,6221,6251,6281,6311,6340,6370,6399,6429,6458,6488,6517,6547,6576,6606,6635,6665,6694,6724,6753,6783,6812,6842,6871,6901,6930,6960,6989,7019,7048,7078,7107,7137,7166,7196,7225,7255,7284,7314,7344,7374,7403,7433,7462,7492,7521,7551,7580,7610,7639,7669,7698,7728,7757,7787,7816,7846,7875,7905,7934,7964,7993,8023,8053,8083,8112,8142,8171,8201,8230,8260,8289,8319,8348,8378,8407,8437,8466,8496,8525,8555,8584,8614,8643,8673,8702,8732,8761,8791,8821,8850,8880,8909,8938,8968,8997,9027,9056,9086,9115,9145,9175,9205,9234,9264,9293,9322,9352,9381,9410,9440,9470,9499,9529,9559,9589,9618,9648,9677,9706,9736,9765,9794,9824,9853,9883,9913,9943,9972,10002,10032,10061,10090,10120,10149,10178,10208,10237,10267,10297,10326,10356,10386,10415,10445,10474,10504,10533,10562,10592,10621,10651,10680,10710,10740,10770,10799,10829,10858,10888,10917,10947,10976,11005,11035,11064,11094,11124,11153,11183,11213,11242,11272,11301,11331,11360,11389,11419,11448,11478,11507,11537,11567,11596,11626,11655,11685,11715,11744,11774,11803,11832,11862,11891,11921,11950,11980,12010,12039,12069,12099,12128,12158,12187,12216,12246,12275,12304,12334,12364,12393,12423,12453,12483,12512,12542,12571,12600,12630,12659,12688,12718,12747,12777,12807,12837,12866,12896,12926,12955,12984,13014,13043,13072,13102,13131,13161,13191,13220,13250,13280,13310,13339,13368,13398,13427,13456,13486,13515,13545,13574,13604,13634,13664,13693,13723,13752,13782,13811,13840,13870,13899,13929,13958,13988,14018,14047,14077,14107,14136,14166,14195,14224,14254,14283,14313,14342,14372,14401,14431,14461,14490,14520,14550,14579,14609,14638,14667,14697,14726,14756,14785,14815,14844,14874,14904,14933,14963,14993,15021,15051,15081,15110,15140,15169,15199,15228,15258,15287,15317,15347,15377,15406,15436,15465,15494,15524,15553,15582,15612,15641,15671,15701,15731,15760,15790,15820,15849,15878,15908,15937,15966,15996,16025,16055,16085,16114,16144,16174,16204,16233,16262,16292,16321,16350,16380,16409,16439,16468,16498,16528,16558,16587,16617,16646,16676,16705,16734,16764,16793,16823,16852,16882,16912,16941,16971,17001,17030,17060,17089,17118,17148,17177,17207,17236,17266,17295,17325,17355,17384,17414,17444,17473,17502,17532,17561,17591,17620,17650,17679,17709,17738,17768,17798,17827,17857,17886,17916,17945,17975,18004,18034,18063,18093,18122,18152,18181,18211,18241,18270,18300,18330,18359,18388,18418,18447,18476,18506,18535,18565,18595,18625,18654,18684,18714,18743,18772,18802,18831,18860,18890,18919,18949,18979,19008,19038,19068,19098,19127,19156,19186,19215,19244,19274,19303,19333,19362,19392,19422,19452,19481,19511,19540,19570,19599,19628,19658,19687,19717,19746,19776,19806,19836,19865,19895,19924,19954,19983,20012,20042,20071,20101,20130,20160,20190,20219,20249,20279,20308,20338,20367,20396,20426,20455,20485,20514,20544,20573,20603,20633,20662,20692,20721,20751,20780,20810,20839,20869,20898,20928,20957,20987,21016,21046,21076,21105,21135,21164,21194,21223,21253,21282,21312,21341,21371,21400,21430,21459,21489,21519,21548,21578,21607,21637,21666,21696,21725,21754,21784,21813,21843,21873,21902,21932,21962,21991,22021,22050,22080,22109,22138,22168,22197,22227,22256,22286,22316,22346,22375,22405,22434,22464,22493,22522,22552,22581,22611,22640,22670,22700,22730,22759,22789,22818,22848,22877,22906,22936,22965,22994,23024,23054,23083,23113,23143,23173,23202,23232,23261,23290,23320,23349,23379,23408,23438,23467,23497,23527,23556,23586,23616,23645,23674,23704,23733,23763,23792,23822,23851,23881,23910,23940,23970,23999,24029,24058,24088,24117,24147,24176,24206,24235,24265,24294,24324,24353,24383,24413,24442,24472,24501,24531,24560,24590,24619,24648,24678,24707,24737,24767,24796,24826,24856,24885,24915,24944,24974,25003,25032,25062,25091,25121,25150,25180,25210,25240,25269,25299,25328,25358,25387,25416,25446,25475,25505,25534,25564,25594,25624,25653,25683,25712,25742,25771,25800,25830,25859,25888,25918,25948,25977,26007,26037,26067,26096,26126,26155,26184,26214,26243,26272,26302,26332,26361,26391,26421,26451,26480,26510,26539,26568,26598,26627,26656,26686,26715,26745,26775,26805,26834,26864,26893,26923,26952,26982,27011,27041,27070,27099,27129,27159,27188,27218,27248,27277,27307,27336,27366,27395,27425,27454,27484,27513,27542,27572,27602,27631,27661,27691,27720,27750,27779,27809,27838,27868,27897,27926,27956,27985,28015,28045,28074,28104,28134,28163,28193,28222,28252,28281,28310,28340,28369,28399,28428,28458,28488,28517,28547,28577,28607,28636,28665,28695,28724,28754,28783,28813,28843,28872,28901,28931,28960,28990,29019,29049,29078,29108,29137,29167,29196,29226,29255,29285,29315,29345,29375,29404,29434,29463,29492,29522,29551,29580,29610,29640,29669,29699,29729,29759,29788,29818,29847,29876,29906,29935,29964,29994,30023,30053,30082,30112,30141,30171,30200,30230,30259,30289,30318,30348,30378,30408,30437,30467,30496,30526,30555,30585,30614,30644,30673,30703,30732,30762,30791,30821,30850,30880,30909,30939,30968,30998,31027,31057,31086,31116,31145,31175,31204,31234,31263,31293,31322,31352,31381,31411,31441,31471,31500,31530,31559,31589,31618,31648,31676,31706,31736,31766,31795,31825,31854,31884,31913,31943,31972,32002,32031,32061,32090,32120,32150,32180,32209,32239,32268,32298,32327,32357,32386,32416,32445,32475,32504,32534,32563,32593,32622,32652,32681,32711,32740,32770,32799,32829,32858,32888,32917,32947,32976,33006,33035,33065,33094,33124,33153,33183,33213,33243,33272,33302,33331,33361,33390,33420,33450,33479,33509,33539,33568,33598,33627,33657,33686,33716,33745,33775,33804,33834,33863,33893,33922,33952,33981,34011,34040,34069,34099,34128,34158,34187,34217,34247,34277,34306,34336,34365,34395,34424,34454,34483,34512,34542,34571,34601,34631,34660,34690,34719,34749,34778,34808,34837,34867,34896,34926,34955,34985,35015,35044,35074,35103,35133,35162,35192,35222,35251,35280,35310,35340,35370,35399,35429,35458,35488,35517,35547,35576,35605,35635,35665,35694,35723,35753,35782,35811,35841,35871,35901,35930,35960,35989,36019,36048,36078,36107,36136,36166,36195,36225,36254,36284,36314,36343,36373,36403,36433,36462,36492,36521,36551,36580,36610,36639,36669,36698,36728,36757,36786,36816,36845,36875,36904,36934,36963,36993,37022,37052,37081,37111,37141,37170,37200,37229,37259,37288,37318,37347,37377,37406,37436,37465,37495,37524,37554,37584,37613,37643,37672,37701,37731,37760,37790,37819,37849,37878,37908,37938,37967,37997,38027,38056,38085,38115,38144,38174,38203,38233,38262,38292,38322,38351,38381,38410,38440,38469,38499,38528,38558,38587,38617,38646,38676,38705,38735,38764,38794,38823,38853,38882,38912,38941,38971,39001,39030,39059,39089,39118,39148,39178,39208,39237,39267,39297,39326,39355,39385,39414,39444,39473,39503,39532,39562,39592,39621,39650,39680,39709,39739,39768,39798,39827,39857,39886,39916,39946,39975,40005,40035,40064,40094,40123,40153,40182,40212,40241,40271,40300,40330,40359,40389,40418,40448,40477,40507,40536,40566,40595,40625,40655,40685,40714,40744,40773,40803,40832,40862,40892,40921,40951,40980,41009,41039,41068,41098,41127,41157,41186,41216,41245,41275,41304,41334,41364,41393,41422,41452,41481,41511,41540,41570,41599,41629,41658,41688,41718,41748,41777,41807,41836,41865,41894,41924,41953,41983,42012,42042,42072,42102,42131,42161,42190,42220,42249,42279,42308,42337,42367,42397,42426,42456,42485,42515,42545,42574,42604,42633,42662,42692,42721,42751,42780,42810,42839,42869,42899,42929,42958,42988,43017,43046,43076,43105,43135,43164,43194,43223,43253,43283,43312,43342,43371,43401,43430,43460,43489,43519,43548,43578,43607,43637,43666,43696,43726,43755,43785,43814,43844,43873,43903,43932,43962,43991,44021,44050,44080,44109,44139,44169,44198,44228,44258,44287,44317,44346,44375,44405,44434,44464,44493,44523,44553,44582,44612,44641,44671,44700,44730,44759,44788,44818,44847,44877,44906,44936,44966,44996,45025,45055,45084,45114,45143,45172,45202,45231,45261,45290,45320,45350,45380,45409,45439,45468,45498,45527,45556,45586,45615,45644,45674,45704,45733,45763,45793,45823,45852,45882,45911,45940,45970,45999,46028,46058,46088,46117,46147,46177,46206,46236,46265,46295,46324,46354,46383,46413,46442,46472,46501,46531,46560,46590,46620,46649,46679,46708,46738,46767,46797,46826,46856,46885,46915,46944,46974,47003,47033,47063,47092,47122,47151,47181,47210,47240,47269,47298,47328,47357,47387,47417,47446,47476,47506,47535,47565,47594,47624,47653,47682,47712,47741,47771,47800,47830,47860,47890,47919,47949,47978,48008,48037,48066,48096,48125,48155,48184,48214,48244,48273,48303,48333,48362,48392,48421,48450,48480,48509,48538,48568,48598,48627,48657,48687,48717,48746,48776,48805,48834,48864,48893,48922,48952,48982,49011,49041,49071,49100,49130,49160,49189,49218,49248,49277,49306,49336,49365,49395,49425,49455,49484,49514,49543,49573,49602,49632,49661,49690,49720,49749,49779,49809,49838,49868,49898,49927,49957,49986,50016,50045,50075,50104,50133,50163,50192,50222,50252,50281,50311,50340,50370,50400,50429,50459,50488,50518,50547,50576,50606,50635,50665,50694,50724,50754,50784,50813,50843,50872,50902,50931,50960,50990,51019,51049,51078,51108,51138,51167,51197,51227,51256,51286,51315,51345,51374,51403,51433,51462,51492,51522,51552,51582,51611,51641,51670,51699,51729,51758,51787,51816,51846,51876,51906,51936,51965,51995,52025,52054,52083,52113,52142,52171,52200,52230,52260,52290,52319,52349,52379,52408,52438,52467,52497,52526,52555,52585,52614,52644,52673,52703,52733,52762,52792,52822,52851,52881,52910,52939,52969,52998,53028,53057,53087,53116,53146,53176,53205,53235,53264,53294,53324,53353,53383,53412,53441,53471,53500,53530,53559,53589,53619,53648,53678,53708,53737,53767,53796,53825,53855,53884,53913,53943,53973,54003,54032,54062,54092,54121,54151,54180,54209,54239,54268,54297,54327,54357,54387,54416,54446,54476,54505,54535,54564,54593,54623,54652,54681,54711,54741,54770,54800,54830,54859,54889,54919,54948,54977,55007,55036,55066,55095,55125,55154,55184,55213,55243,55273,55302,55332,55361,55391,55420,55450,55479,55508,55538,55567,55597,55627,55657,55686,55716,55745,55775,55804,55834,55863,55892,55922,55951,55981,56011,56040,56070,56100,56129,56159,56188,56218,56247,56276,56306,56335,56365,56394,56424,56454,56483,56513,56543,56572,56601,56631,56660,56690,56719,56749,56778,56808,56837,56867,56897,56926,56956,56985,57015,57044,57074,57103,57133,57162,57192,57221,57251,57280,57310,57340,57369,57399,57429,57458,57487,57517,57546,57576,57605,57634,57664,57694,57723,57753,57783,57813,57842,57871,57901,57930,57959,57989,58018,58048,58077,58107,58137,58167,58196,58226,58255,58285,58314,58343,58373,58402,58432,58461,58491,58521,58551,58580,58610,58639,58669,58698,58727,58757,58786,58816,58845,58875,58905,58934,58964,58994,59023,59053,59082,59111,59141,59170,59200,59229,59259,59288,59318,59348,59377,59407,59436,59466,59495,59525,59554,59584,59613,59643,59672,59702,59731,59761,59791,59820,59850,59879,59909,59939,59968,59997,60027,60056,60086,60115,60145,60174,60204,60234,60264,60293,60323,60352,60381,60411,60440,60469,60499,60528,60558,60588,60618,60648,60677,60707,60736,60765,60795,60824,60853,60883,60912,60942,60972,61002,61031,61061,61090,61120,61149,61179,61208,61237,61267,61296,61326,61356,61385,61415,61445,61474,61504,61533,61563,61592,61621,61651,61680,61710,61739,61769,61799,61828,61858,61888,61917,61947,61976,62006,62035,62064,62094,62123,62153,62182,62212,62242,62271,62301,62331,62360,62390,62419,62448,62478,62507,62537,62566,62596,62625,62655,62685,62715,62744,62774,62803,62832,62862,62891,62921,62950,62980,63009,63039,63069,63099,63128,63157,63187,63216,63246,63275,63305,63334,63363,63393,63423,63453,63482,63512,63541,63571,63600,63630,63659,63689,63718,63747,63777,63807,63836,63866,63895,63925,63955,63984,64014,64043,64073,64102,64131,64161,64190,64220,64249,64279,64309,64339,64368,64398,64427,64457,64486,64515,64545,64574,64603,64633,64663,64692,64722,64752,64782,64811,64841,64870,64899,64929,64958,64987,65017,65047,65076,65106,65136,65166,65195,65225,65254,65283,65313,65342,65371,65401,65431,65460,65490,65520,65549,65579,65608,65638,65667,65697,65726,65755,65785,65815,65844,65874,65903,65933,65963,65992,66022,66051,66081,66110,66140,66169,66199,66228,66258,66287,66317,66346,66376,66405,66435,66465,66494,66524,66553,66583,66612,66641,66671,66700,66730,66760,66789,66819,66849,66878,66908,66937,66967,66996,67025,67055,67084,67114,67143,67173,67203,67233,67262,67292,67321,67351,67380,67409,67439,67468,67497,67527,67557,67587,67617,67646,67676,67705,67735,67764,67793,67823,67852,67882,67911,67941,67971,68e3,68030,68060,68089,68119,68148,68177,68207,68236,68266,68295,68325,68354,68384,68414,68443,68473,68502,68532,68561,68591,68620,68650,68679,68708,68738,68768,68797,68827,68857,68886,68916,68946,68975,69004,69034,69063,69092,69122,69152,69181,69211,69240,69270,69300,69330,69359,69388,69418,69447,69476,69506,69535,69565,69595,69624,69654,69684,69713,69743,69772,69802,69831,69861,69890,69919,69949,69978,70008,70038,70067,70097,70126,70156,70186,70215,70245,70274,70303,70333,70362,70392,70421,70451,70481,70510,70540,70570,70599,70629,70658,70687,70717,70746,70776,70805,70835,70864,70894,70924,70954,70983,71013,71042,71071,71101,71130,71159,71189,71218,71248,71278,71308,71337,71367,71397,71426,71455,71485,71514,71543,71573,71602,71632,71662,71691,71721,71751,71781,71810,71839,71869,71898,71927,71957,71986,72016,72046,72075,72105,72135,72164,72194,72223,72253,72282,72311,72341,72370,72400,72429,72459,72489,72518,72548,72577,72607,72637,72666,72695,72725,72754,72784,72813,72843,72872,72902,72931,72961,72991,73020,73050,73080,73109,73139,73168,73197,73227,73256,73286,73315,73345,73375,73404,73434,73464,73493,73523,73552,73581,73611,73640,73669,73699,73729,73758,73788,73818,73848,73877,73907,73936,73965,73995,74024,74053,74083,74113,74142,74172,74202,74231,74261,74291,74320,74349,74379,74408,74437,74467,74497,74526,74556,74586,74615,74645,74675,74704,74733,74763,74792,74822,74851,74881,74910,74940,74969,74999,75029,75058,75088,75117,75147,75176,75206,75235,75264,75294,75323,75353,75383,75412,75442,75472,75501,75531,75560,75590,75619,75648,75678,75707,75737,75766,75796,75826,75856,75885,75915,75944,75974,76003,76032,76062,76091,76121,76150,76180,76210,76239,76269,76299,76328,76358,76387,76416,76446,76475,76505,76534,76564,76593,76623,76653,76682,76712,76741,76771,76801,76830,76859,76889,76918,76948,76977,77007,77036,77066,77096,77125,77155,77185,77214,77243,77273,77302,77332,77361,77390,77420,77450,77479,77509,77539,77569,77598,77627,77657,77686,77715,77745,77774,77804,77833,77863,77893,77923,77952,77982,78011,78041,78070,78099,78129,78158,78188,78217,78247,78277,78307,78336,78366,78395,78425,78454,78483,78513,78542,78572,78601,78631,78661,78690,78720,78750,78779,78808,78838,78867,78897,78926,78956,78985,79015,79044,79074,79104,79133,79163,79192,79222,79251,79281,79310,79340,79369,79399,79428,79458,79487,79517,79546,79576,79606,79635,79665,79695,79724,79753,79783,79812,79841,79871,79900,79930,79960,79990]},{"../main":536,"object-assign":421}],536:[function(t,e,r){var n=t("object-assign");function i(){this.regionalOptions=[],this.regionalOptions[""]={invalidCalendar:"Calendar {0} not found",invalidDate:"Invalid {0} date",invalidMonth:"Invalid {0} month",invalidYear:"Invalid {0} year",differentCalendars:"Cannot mix {0} and {1} dates"},this.local=this.regionalOptions[""],this.calendars={},this._localCals={}}function a(t,e,r,n){if(this._calendar=t,this._year=e,this._month=r,this._day=n,0===this._calendar._validateLevel&&!this._calendar.isValid(this._year,this._month,this._day))throw(c.local.invalidDate||c.regionalOptions[""].invalidDate).replace(/\{0\}/,this._calendar.local.name)}function o(t,e){return"000000".substring(0,e-(t=""+t).length)+t}function s(){this.shortYearCutoff="+10"}function l(t){this.local=this.regionalOptions[t]||this.regionalOptions[""]}n(i.prototype,{instance:function(t,e){t=(t||"gregorian").toLowerCase(),e=e||"";var r=this._localCals[t+"-"+e];if(!r&&this.calendars[t]&&(r=new this.calendars[t](e),this._localCals[t+"-"+e]=r),!r)throw(this.local.invalidCalendar||this.regionalOptions[""].invalidCalendar).replace(/\{0\}/,t);return r},newDate:function(t,e,r,n,i){return(n=(null!=t&&t.year?t.calendar():"string"==typeof n?this.instance(n,i):n)||this.instance()).newDate(t,e,r)},substituteDigits:function(t){return function(e){return(e+"").replace(/[0-9]/g,function(e){return t[e]})}},substituteChineseDigits:function(t,e){return function(r){for(var n="",i=0;r>0;){var a=r%10;n=(0===a?"":t[a]+e[i])+n,i++,r=Math.floor(r/10)}return 0===n.indexOf(t[1]+e[1])&&(n=n.substr(1)),n||t[0]}}}),n(a.prototype,{newDate:function(t,e,r){return this._calendar.newDate(null==t?this:t,e,r)},year:function(t){return 0===arguments.length?this._year:this.set(t,"y")},month:function(t){return 0===arguments.length?this._month:this.set(t,"m")},day:function(t){return 0===arguments.length?this._day:this.set(t,"d")},date:function(t,e,r){if(!this._calendar.isValid(t,e,r))throw(c.local.invalidDate||c.regionalOptions[""].invalidDate).replace(/\{0\}/,this._calendar.local.name);return this._year=t,this._month=e,this._day=r,this},leapYear:function(){return this._calendar.leapYear(this)},epoch:function(){return this._calendar.epoch(this)},formatYear:function(){return this._calendar.formatYear(this)},monthOfYear:function(){return this._calendar.monthOfYear(this)},weekOfYear:function(){return this._calendar.weekOfYear(this)},daysInYear:function(){return this._calendar.daysInYear(this)},dayOfYear:function(){return this._calendar.dayOfYear(this)},daysInMonth:function(){return this._calendar.daysInMonth(this)},dayOfWeek:function(){return this._calendar.dayOfWeek(this)},weekDay:function(){return this._calendar.weekDay(this)},extraInfo:function(){return this._calendar.extraInfo(this)},add:function(t,e){return this._calendar.add(this,t,e)},set:function(t,e){return this._calendar.set(this,t,e)},compareTo:function(t){if(this._calendar.name!==t._calendar.name)throw(c.local.differentCalendars||c.regionalOptions[""].differentCalendars).replace(/\{0\}/,this._calendar.local.name).replace(/\{1\}/,t._calendar.local.name);var e=this._year!==t._year?this._year-t._year:this._month!==t._month?this.monthOfYear()-t.monthOfYear():this._day-t._day;return 0===e?0:e<0?-1:1},calendar:function(){return this._calendar},toJD:function(){return this._calendar.toJD(this)},fromJD:function(t){return this._calendar.fromJD(t)},toJSDate:function(){return this._calendar.toJSDate(this)},fromJSDate:function(t){return this._calendar.fromJSDate(t)},toString:function(){return(this.year()<0?"-":"")+o(Math.abs(this.year()),4)+"-"+o(this.month(),2)+"-"+o(this.day(),2)}}),n(s.prototype,{_validateLevel:0,newDate:function(t,e,r){return null==t?this.today():(t.year&&(this._validate(t,e,r,c.local.invalidDate||c.regionalOptions[""].invalidDate),r=t.day(),e=t.month(),t=t.year()),new a(this,t,e,r))},today:function(){return this.fromJSDate(new Date)},epoch:function(t){return this._validate(t,this.minMonth,this.minDay,c.local.invalidYear||c.regionalOptions[""].invalidYear).year()<0?this.local.epochs[0]:this.local.epochs[1]},formatYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,c.local.invalidYear||c.regionalOptions[""].invalidYear);return(e.year()<0?"-":"")+o(Math.abs(e.year()),4)},monthsInYear:function(t){return this._validate(t,this.minMonth,this.minDay,c.local.invalidYear||c.regionalOptions[""].invalidYear),12},monthOfYear:function(t,e){var r=this._validate(t,e,this.minDay,c.local.invalidMonth||c.regionalOptions[""].invalidMonth);return(r.month()+this.monthsInYear(r)-this.firstMonth)%this.monthsInYear(r)+this.minMonth},fromMonthOfYear:function(t,e){var r=(e+this.firstMonth-2*this.minMonth)%this.monthsInYear(t)+this.minMonth;return this._validate(t,r,this.minDay,c.local.invalidMonth||c.regionalOptions[""].invalidMonth),r},daysInYear:function(t){var e=this._validate(t,this.minMonth,this.minDay,c.local.invalidYear||c.regionalOptions[""].invalidYear);return this.leapYear(e)?366:365},dayOfYear:function(t,e,r){var n=this._validate(t,e,r,c.local.invalidDate||c.regionalOptions[""].invalidDate);return n.toJD()-this.newDate(n.year(),this.fromMonthOfYear(n.year(),this.minMonth),this.minDay).toJD()+1},daysInWeek:function(){return 7},dayOfWeek:function(t,e,r){var n=this._validate(t,e,r,c.local.invalidDate||c.regionalOptions[""].invalidDate);return(Math.floor(this.toJD(n))+2)%this.daysInWeek()},extraInfo:function(t,e,r){return this._validate(t,e,r,c.local.invalidDate||c.regionalOptions[""].invalidDate),{}},add:function(t,e,r){return this._validate(t,this.minMonth,this.minDay,c.local.invalidDate||c.regionalOptions[""].invalidDate),this._correctAdd(t,this._add(t,e,r),e,r)},_add:function(t,e,r){if(this._validateLevel++,"d"===r||"w"===r){var n=t.toJD()+e*("w"===r?this.daysInWeek():1),i=t.calendar().fromJD(n);return this._validateLevel--,[i.year(),i.month(),i.day()]}try{var a=t.year()+("y"===r?e:0),o=t.monthOfYear()+("m"===r?e:0);i=t.day();"y"===r?(t.month()!==this.fromMonthOfYear(a,o)&&(o=this.newDate(a,t.month(),this.minDay).monthOfYear()),o=Math.min(o,this.monthsInYear(a)),i=Math.min(i,this.daysInMonth(a,this.fromMonthOfYear(a,o)))):"m"===r&&(!function(t){for(;oe-1+t.minMonth;)a++,o-=e,e=t.monthsInYear(a)}(this),i=Math.min(i,this.daysInMonth(a,this.fromMonthOfYear(a,o))));var s=[a,this.fromMonthOfYear(a,o),i];return this._validateLevel--,s}catch(t){throw this._validateLevel--,t}},_correctAdd:function(t,e,r,n){if(!(this.hasYearZero||"y"!==n&&"m"!==n||0!==e[0]&&t.year()>0==e[0]>0)){var i={y:[1,1,"y"],m:[1,this.monthsInYear(-1),"m"],w:[this.daysInWeek(),this.daysInYear(-1),"d"],d:[1,this.daysInYear(-1),"d"]}[n],a=r<0?-1:1;e=this._add(t,r*i[0]+a*i[1],i[2])}return t.date(e[0],e[1],e[2])},set:function(t,e,r){this._validate(t,this.minMonth,this.minDay,c.local.invalidDate||c.regionalOptions[""].invalidDate);var n="y"===r?e:t.year(),i="m"===r?e:t.month(),a="d"===r?e:t.day();return"y"!==r&&"m"!==r||(a=Math.min(a,this.daysInMonth(n,i))),t.date(n,i,a)},isValid:function(t,e,r){this._validateLevel++;var n=this.hasYearZero||0!==t;if(n){var i=this.newDate(t,e,this.minDay);n=e>=this.minMonth&&e-this.minMonth=this.minDay&&r-this.minDay13.5?13:1),c=i-(l>2.5?4716:4715);return c<=0&&c--,this.newDate(c,l,s)},toJSDate:function(t,e,r){var n=this._validate(t,e,r,c.local.invalidDate||c.regionalOptions[""].invalidDate),i=new Date(n.year(),n.month()-1,n.day());return i.setHours(0),i.setMinutes(0),i.setSeconds(0),i.setMilliseconds(0),i.setHours(i.getHours()>12?i.getHours()+2:0),i},fromJSDate:function(t){return this.newDate(t.getFullYear(),t.getMonth()+1,t.getDate())}});var c=e.exports=new i;c.cdate=a,c.baseCalendar=s,c.calendars.gregorian=l},{"object-assign":421}],537:[function(t,e,r){var n=t("object-assign"),i=t("./main");n(i.regionalOptions[""],{invalidArguments:"Invalid arguments",invalidFormat:"Cannot format a date from another calendar",missingNumberAt:"Missing number at position {0}",unknownNameAt:"Unknown name at position {0}",unexpectedLiteralAt:"Unexpected literal at position {0}",unexpectedText:"Additional text found at end"}),i.local=i.regionalOptions[""],n(i.cdate.prototype,{formatDate:function(t,e){return"string"!=typeof t&&(e=t,t=""),this._calendar.formatDate(t||"",this,e)}}),n(i.baseCalendar.prototype,{UNIX_EPOCH:i.instance().newDate(1970,1,1).toJD(),SECS_PER_DAY:86400,TICKS_EPOCH:i.instance().jdEpoch,TICKS_PER_DAY:864e9,ATOM:"yyyy-mm-dd",COOKIE:"D, dd M yyyy",FULL:"DD, MM d, yyyy",ISO_8601:"yyyy-mm-dd",JULIAN:"J",RFC_822:"D, d M yy",RFC_850:"DD, dd-M-yy",RFC_1036:"D, d M yy",RFC_1123:"D, d M yyyy",RFC_2822:"D, d M yyyy",RSS:"D, d M yy",TICKS:"!",TIMESTAMP:"@",W3C:"yyyy-mm-dd",formatDate:function(t,e,r){if("string"!=typeof t&&(r=e,e=t,t=""),!e)return"";if(e.calendar()!==this)throw i.local.invalidFormat||i.regionalOptions[""].invalidFormat;t=t||this.local.dateFormat;for(var n,a,o,s,l=(r=r||{}).dayNamesShort||this.local.dayNamesShort,c=r.dayNames||this.local.dayNames,u=r.monthNumbers||this.local.monthNumbers,h=r.monthNamesShort||this.local.monthNamesShort,f=r.monthNames||this.local.monthNames,p=(r.calculateWeek||this.local.calculateWeek,function(e,r){for(var n=1;w+n1}),d=function(t,e,r,n){var i=""+e;if(p(t,n))for(;i.length1},x=function(t,r){var n=y(t,r),a=[2,3,n?4:2,n?4:2,10,11,20]["oyYJ@!".indexOf(t)+1],o=new RegExp("^-?\\d{1,"+a+"}"),s=e.substring(A).match(o);if(!s)throw(i.local.missingNumberAt||i.regionalOptions[""].missingNumberAt).replace(/\{0\}/,A);return A+=s[0].length,parseInt(s[0],10)},b=this,_=function(){if("function"==typeof l){y("m");var t=l.call(b,e.substring(A));return A+=t.length,t}return x("m")},w=function(t,r,n,a){for(var o=y(t,a)?n:r,s=0;s-1){p=1,d=g;for(var E=this.daysInMonth(f,p);d>E;E=this.daysInMonth(f,p))p++,d-=E}return h>-1?this.fromJD(h):this.newDate(f,p,d)},determineDate:function(t,e,r,n,i){r&&"object"!=typeof r&&(i=n,n=r,r=null),"string"!=typeof n&&(i=n,n="");var a=this;return e=e?e.newDate():null,t=null==t?e:"string"==typeof t?function(t){try{return a.parseDate(n,t,i)}catch(t){}for(var e=((t=t.toLowerCase()).match(/^c/)&&r?r.newDate():null)||a.today(),o=/([+-]?[0-9]+)\s*(d|w|m|y)?/g,s=o.exec(t);s;)e.add(parseInt(s[1],10),s[2]||"d"),s=o.exec(t);return e}(t):"number"==typeof t?isNaN(t)||t===1/0||t===-1/0?e:a.today().add(t,"d"):a.newDate(t)}})},{"./main":536,"object-assign":421}],538:[function(t,e,r){e.exports=t("cwise-compiler")({args:["array",{offset:[1],array:0},"scalar","scalar","index"],pre:{body:"{}",args:[],thisVars:[],localVars:[]},post:{body:"{}",args:[],thisVars:[],localVars:[]},body:{body:"{\n var _inline_1_da = _inline_1_arg0_ - _inline_1_arg3_\n var _inline_1_db = _inline_1_arg1_ - _inline_1_arg3_\n if((_inline_1_da >= 0) !== (_inline_1_db >= 0)) {\n _inline_1_arg2_.push(_inline_1_arg4_[0] + 0.5 + 0.5 * (_inline_1_da + _inline_1_db) / (_inline_1_da - _inline_1_db))\n }\n }",args:[{name:"_inline_1_arg0_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_1_arg1_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_1_arg2_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_1_arg3_",lvalue:!1,rvalue:!0,count:2},{name:"_inline_1_arg4_",lvalue:!1,rvalue:!0,count:1}],thisVars:[],localVars:["_inline_1_da","_inline_1_db"]},funcName:"zeroCrossings"})},{"cwise-compiler":133}],539:[function(t,e,r){"use strict";e.exports=function(t,e){var r=[];return e=+e||0,n(t.hi(t.shape[0]-1),r,e),r};var n=t("./lib/zc-core")},{"./lib/zc-core":538}],540:[function(t,e,r){"use strict";e.exports=[{path:"",backoff:0},{path:"M-2.4,-3V3L0.6,0Z",backoff:.6},{path:"M-3.7,-2.5V2.5L1.3,0Z",backoff:1.3},{path:"M-4.45,-3L-1.65,-0.2V0.2L-4.45,3L1.55,0Z",backoff:1.55},{path:"M-2.2,-2.2L-0.2,-0.2V0.2L-2.2,2.2L-1.4,3L1.6,0L-1.4,-3Z",backoff:1.6},{path:"M-4.4,-2.1L-0.6,-0.2V0.2L-4.4,2.1L-4,3L2,0L-4,-3Z",backoff:2},{path:"M2,0A2,2 0 1,1 0,-2A2,2 0 0,1 2,0Z",backoff:0,noRotate:!0},{path:"M2,2V-2H-2V2Z",backoff:0,noRotate:!0}]},{}],541:[function(t,e,r){"use strict";var n=t("./arrow_paths"),i=t("../../plots/font_attributes"),a=t("../../plots/cartesian/constants"),o=t("../../plot_api/plot_template").templatedArray;e.exports=o("annotation",{visible:{valType:"boolean",dflt:!0,editType:"calcIfAutorange+arraydraw"},text:{valType:"string",editType:"calcIfAutorange+arraydraw"},textangle:{valType:"angle",dflt:0,editType:"calcIfAutorange+arraydraw"},font:i({editType:"calcIfAutorange+arraydraw",colorEditType:"arraydraw"}),width:{valType:"number",min:1,dflt:null,editType:"calcIfAutorange+arraydraw"},height:{valType:"number",min:1,dflt:null,editType:"calcIfAutorange+arraydraw"},opacity:{valType:"number",min:0,max:1,dflt:1,editType:"arraydraw"},align:{valType:"enumerated",values:["left","center","right"],dflt:"center",editType:"arraydraw"},valign:{valType:"enumerated",values:["top","middle","bottom"],dflt:"middle",editType:"arraydraw"},bgcolor:{valType:"color",dflt:"rgba(0,0,0,0)",editType:"arraydraw"},bordercolor:{valType:"color",dflt:"rgba(0,0,0,0)",editType:"arraydraw"},borderpad:{valType:"number",min:0,dflt:1,editType:"calcIfAutorange+arraydraw"},borderwidth:{valType:"number",min:0,dflt:1,editType:"calcIfAutorange+arraydraw"},showarrow:{valType:"boolean",dflt:!0,editType:"calcIfAutorange+arraydraw"},arrowcolor:{valType:"color",editType:"arraydraw"},arrowhead:{valType:"integer",min:0,max:n.length,dflt:1,editType:"arraydraw"},startarrowhead:{valType:"integer",min:0,max:n.length,dflt:1,editType:"arraydraw"},arrowside:{valType:"flaglist",flags:["end","start"],extras:["none"],dflt:"end",editType:"arraydraw"},arrowsize:{valType:"number",min:.3,dflt:1,editType:"calcIfAutorange+arraydraw"},startarrowsize:{valType:"number",min:.3,dflt:1,editType:"calcIfAutorange+arraydraw"},arrowwidth:{valType:"number",min:.1,editType:"calcIfAutorange+arraydraw"},standoff:{valType:"number",min:0,dflt:0,editType:"calcIfAutorange+arraydraw"},startstandoff:{valType:"number",min:0,dflt:0,editType:"calcIfAutorange+arraydraw"},ax:{valType:"any",editType:"calcIfAutorange+arraydraw"},ay:{valType:"any",editType:"calcIfAutorange+arraydraw"},axref:{valType:"enumerated",dflt:"pixel",values:["pixel",a.idRegex.x.toString()],editType:"calc"},ayref:{valType:"enumerated",dflt:"pixel",values:["pixel",a.idRegex.y.toString()],editType:"calc"},xref:{valType:"enumerated",values:["paper",a.idRegex.x.toString()],editType:"calc"},x:{valType:"any",editType:"calcIfAutorange+arraydraw"},xanchor:{valType:"enumerated",values:["auto","left","center","right"],dflt:"auto",editType:"calcIfAutorange+arraydraw"},xshift:{valType:"number",dflt:0,editType:"calcIfAutorange+arraydraw"},yref:{valType:"enumerated",values:["paper",a.idRegex.y.toString()],editType:"calc"},y:{valType:"any",editType:"calcIfAutorange+arraydraw"},yanchor:{valType:"enumerated",values:["auto","top","middle","bottom"],dflt:"auto",editType:"calcIfAutorange+arraydraw"},yshift:{valType:"number",dflt:0,editType:"calcIfAutorange+arraydraw"},clicktoshow:{valType:"enumerated",values:[!1,"onoff","onout"],dflt:!1,editType:"arraydraw"},xclick:{valType:"any",editType:"arraydraw"},yclick:{valType:"any",editType:"arraydraw"},hovertext:{valType:"string",editType:"arraydraw"},hoverlabel:{bgcolor:{valType:"color",editType:"arraydraw"},bordercolor:{valType:"color",editType:"arraydraw"},font:i({editType:"arraydraw"}),editType:"arraydraw"},captureevents:{valType:"boolean",editType:"arraydraw"},editType:"calc",_deprecated:{ref:{valType:"string",editType:"calc"}}})},{"../../plot_api/plot_template":722,"../../plots/cartesian/constants":737,"../../plots/font_attributes":758,"./arrow_paths":540}],542:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../plots/cartesian/axes"),a=t("./draw").draw;function o(t){var e=t._fullLayout;n.filterVisible(e.annotations).forEach(function(e){var r,n,a,o,s=i.getFromId(t,e.xref),l=i.getFromId(t,e.yref),c=3*e.arrowsize*e.arrowwidth||0,u=3*e.startarrowsize*e.arrowwidth||0;s&&s.autorange&&(r=c+e.xshift,n=c-e.xshift,a=u+e.xshift,o=u-e.xshift,e.axref===e.xref?(i.expand(s,[s.r2c(e.x)],{ppadplus:r,ppadminus:n}),i.expand(s,[s.r2c(e.ax)],{ppadplus:Math.max(e._xpadplus,a),ppadminus:Math.max(e._xpadminus,o)})):(a=e.ax?a+e.ax:a,o=e.ax?o-e.ax:o,i.expand(s,[s.r2c(e.x)],{ppadplus:Math.max(e._xpadplus,r,a),ppadminus:Math.max(e._xpadminus,n,o)}))),l&&l.autorange&&(r=c-e.yshift,n=c+e.yshift,a=u-e.yshift,o=u+e.yshift,e.ayref===e.yref?(i.expand(l,[l.r2c(e.y)],{ppadplus:r,ppadminus:n}),i.expand(l,[l.r2c(e.ay)],{ppadplus:Math.max(e._ypadplus,a),ppadminus:Math.max(e._ypadminus,o)})):(a=e.ay?a+e.ay:a,o=e.ay?o-e.ay:o,i.expand(l,[l.r2c(e.y)],{ppadplus:Math.max(e._ypadplus,r,a),ppadminus:Math.max(e._ypadminus,n,o)})))})}e.exports=function(t){var e=t._fullLayout,r=n.filterVisible(e.annotations);if(r.length&&t._fullData.length){var s={};for(var l in r.forEach(function(t){s[t.xref]=1,s[t.yref]=1}),s){var c=i.getFromId(t,l);if(c&&c.autorange)return n.syncOrAsync([a,o],t)}}}},{"../../lib":684,"../../plots/cartesian/axes":732,"./draw":547}],543:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../registry"),a=t("../../plot_api/plot_template").arrayEditor;function o(t,e){var r,n,i,a,o,l,c,u=t._fullLayout.annotations,h=[],f=[],p=[],d=(e||[]).length;for(r=0;r0||r.explicitOff.length>0},onClick:function(t,e){var r,s,l=o(t,e),c=l.on,u=l.off.concat(l.explicitOff),h={},f=t._fullLayout.annotations;if(!c.length&&!u.length)return;for(r=0;r2/3?"right":"center"),{center:0,middle:0,left:.5,bottom:-.5,right:-.5,top:.5}[e]}e._w=w,e._h=P;for(var q=!1,H=["x","y"],G=0;G1)&&(Q===K?((lt=tt.r2fraction(e["a"+J]))<0||lt>1)&&(q=!0):q=!0,q))continue;W=tt._offset+tt.r2p(e[J]),Z=.5}else"x"===J?(X=e[J],W=b.l+b.w*X):(X=1-e[J],W=b.t+b.h*X),Z=e.showarrow?.5:X;if(e.showarrow){st.head=W;var ct=e["a"+J];$=rt*U(.5,e.xanchor)-nt*U(.5,e.yanchor),Q===K?(st.tail=tt._offset+tt.r2p(ct),Y=$):(st.tail=W+ct,Y=$+ct),st.text=st.tail+$;var ut=x["x"===J?"width":"height"];if("paper"===K&&(st.head=o.constrain(st.head,1,ut-1)),"pixel"===Q){var ht=-Math.max(st.tail-3,st.text),ft=Math.min(st.tail+3,st.text)-ut;ht>0?(st.tail+=ht,st.text+=ht):ft>0&&(st.tail-=ft,st.text-=ft)}st.tail+=ot,st.head+=ot}else Y=$=it*U(Z,at),st.text=W+$;st.text+=ot,$+=ot,Y+=ot,e["_"+J+"padplus"]=it/2+Y,e["_"+J+"padminus"]=it/2-Y,e["_"+J+"size"]=it,e["_"+J+"shift"]=$}if(q)I.remove();else{var pt=0,dt=0;if("left"!==e.align&&(pt=(w-v)*("center"===e.align?.5:1)),"top"!==e.valign&&(dt=(P-y)*("middle"===e.valign?.5:1)),u)n.select("svg").attr({x:R+pt-1,y:R+dt}).call(c.setClipUrl,F?T:null);else{var gt=R+dt-d.top,mt=R+pt-d.left;V.call(h.positionText,mt,gt).call(c.setClipUrl,F?T:null)}N.select("rect").call(c.setRect,R,R,w,P),B.call(c.setRect,O/2,O/2,D-O,j-O),I.call(c.setTranslate,Math.round(S.x.text-D/2),Math.round(S.y.text-j/2)),L.attr({transform:"rotate("+E+","+S.x.text+","+S.y.text+")"});var vt,yt=function(r,n){C.selectAll(".annotation-arrow-g").remove();var u=S.x.head,h=S.y.head,f=S.x.tail+r,d=S.y.tail+n,v=S.x.text+r,y=S.y.text+n,x=o.rotationXYMatrix(E,v,y),w=o.apply2DTransform(x),T=o.apply2DTransform2(x),z=+B.attr("width"),P=+B.attr("height"),O=v-.5*z,D=O+z,R=y-.5*P,F=R+P,N=[[O,R,O,F],[O,F,D,F],[D,F,D,R],[D,R,O,R]].map(T);if(!N.reduce(function(t,e){return t^!!o.segmentsIntersect(u,h,u+1e6,h+1e6,e[0],e[1],e[2],e[3])},!1)){N.forEach(function(t){var e=o.segmentsIntersect(f,d,u,h,t[0],t[1],t[2],t[3]);e&&(f=e.x,d=e.y)});var j=e.arrowwidth,V=e.arrowcolor,U=e.arrowside,q=C.append("g").style({opacity:l.opacity(V)}).classed("annotation-arrow-g",!0),H=q.append("path").attr("d","M"+f+","+d+"L"+u+","+h).style("stroke-width",j+"px").call(l.stroke,l.rgb(V));if(g(H,U,e),_.annotationPosition&&H.node().parentNode&&!a){var G=u,W=h;if(e.standoff){var Y=Math.sqrt(Math.pow(u-f,2)+Math.pow(h-d,2));G+=e.standoff*(f-u)/Y,W+=e.standoff*(d-h)/Y}var X,Z,$=q.append("path").classed("annotation-arrow",!0).classed("anndrag",!0).classed("cursor-move",!0).attr({d:"M3,3H-3V-3H3ZM0,0L"+(f-G)+","+(d-W),transform:"translate("+G+","+W+")"}).style("stroke-width",j+6+"px").call(l.stroke,"rgba(0,0,0,0)").call(l.fill,"rgba(0,0,0,0)");p.init({element:$.node(),gd:t,prepFn:function(){var t=c.getTranslate(I);X=t.x,Z=t.y,s&&s.autorange&&k(s._name+".autorange",!0),m&&m.autorange&&k(m._name+".autorange",!0)},moveFn:function(t,r){var n=w(X,Z),i=n[0]+t,a=n[1]+r;I.call(c.setTranslate,i,a),M("x",s?s.p2r(s.r2p(e.x)+t):e.x+t/b.w),M("y",m?m.p2r(m.r2p(e.y)+r):e.y-r/b.h),e.axref===e.xref&&M("ax",s.p2r(s.r2p(e.ax)+t)),e.ayref===e.yref&&M("ay",m.p2r(m.r2p(e.ay)+r)),q.attr("transform","translate("+t+","+r+")"),L.attr({transform:"rotate("+E+","+i+","+a+")"})},doneFn:function(){i.call("relayout",t,A());var e=document.querySelector(".js-notes-box-panel");e&&e.redraw(e.selectedObj)}})}}};if(e.showarrow&&yt(0,0),z)p.init({element:I.node(),gd:t,prepFn:function(){vt=L.attr("transform")},moveFn:function(t,r){var n="pointer";if(e.showarrow)e.axref===e.xref?M("ax",s.p2r(s.r2p(e.ax)+t)):M("ax",e.ax+t),e.ayref===e.yref?M("ay",m.p2r(m.r2p(e.ay)+r)):M("ay",e.ay+r),yt(t,r);else{if(a)return;var i,o;if(s)i=s.p2r(s.r2p(e.x)+t);else{var l=e._xsize/b.w,c=e.x+(e._xshift-e.xshift)/b.w-l/2;i=p.align(c+t/b.w,l,0,1,e.xanchor)}if(m)o=m.p2r(m.r2p(e.y)+r);else{var u=e._ysize/b.h,h=e.y-(e._yshift+e.yshift)/b.h-u/2;o=p.align(h-r/b.h,u,0,1,e.yanchor)}M("x",i),M("y",o),s&&m||(n=p.getCursor(s?.5:i,m?.5:o,e.xanchor,e.yanchor))}L.attr({transform:"translate("+t+","+r+")"+vt}),f(I,n)},doneFn:function(){f(I),i.call("relayout",t,A());var e=document.querySelector(".js-notes-box-panel");e&&e.redraw(e.selectedObj)}})}}}e.exports={draw:function(t){var e=t._fullLayout;e._infolayer.selectAll(".annotation").remove();for(var r=0;r=0,m=e.indexOf("end")>=0,v=h.backoff*p+r.standoff,y=f.backoff*d+r.startstandoff;if("line"===u.nodeName){o={x:+t.attr("x1"),y:+t.attr("y1")},s={x:+t.attr("x2"),y:+t.attr("y2")};var x=o.x-s.x,b=o.y-s.y;if(c=(l=Math.atan2(b,x))+Math.PI,v&&y&&v+y>Math.sqrt(x*x+b*b))return void z();if(v){if(v*v>x*x+b*b)return void z();var _=v*Math.cos(l),w=v*Math.sin(l);s.x+=_,s.y+=w,t.attr({x2:s.x,y2:s.y})}if(y){if(y*y>x*x+b*b)return void z();var k=y*Math.cos(l),M=y*Math.sin(l);o.x-=k,o.y-=M,t.attr({x1:o.x,y1:o.y})}}else if("path"===u.nodeName){var A=u.getTotalLength(),T="";if(A1){c=!0;break}}c?t.fullLayout._infolayer.select(".annotation-"+t.id+'[data-index="'+s+'"]').remove():(l._pdata=i(t.glplot.cameraParams,[e.xaxis.r2l(l.x)*r[0],e.yaxis.r2l(l.y)*r[1],e.zaxis.r2l(l.z)*r[2]]),n(t.graphDiv,l,s,t.id,l._xa,l._ya))}}},{"../../plots/gl3d/project":783,"../annotations/draw":547}],554:[function(t,e,r){"use strict";var n=t("../../registry"),i=t("../../lib");e.exports={moduleType:"component",name:"annotations3d",schema:{subplots:{scene:{annotations:t("./attributes")}}},layoutAttributes:t("./attributes"),handleDefaults:t("./defaults"),includeBasePlot:function(t,e){var r=n.subplotsRegistry.gl3d;if(!r)return;for(var a=r.attrRegex,o=Object.keys(t),s=0;s=0))return t;if(3===o)n[o]>1&&(n[o]=1);else if(n[o]>=1)return t}var s=Math.round(255*n[0])+", "+Math.round(255*n[1])+", "+Math.round(255*n[2]);return a?"rgba("+s+", "+n[3]+")":"rgb("+s+")"}a.tinyRGB=function(t){var e=t.toRgb();return"rgb("+Math.round(e.r)+", "+Math.round(e.g)+", "+Math.round(e.b)+")"},a.rgb=function(t){return a.tinyRGB(n(t))},a.opacity=function(t){return t?n(t).getAlpha():0},a.addOpacity=function(t,e){var r=n(t).toRgb();return"rgba("+Math.round(r.r)+", "+Math.round(r.g)+", "+Math.round(r.b)+", "+e+")"},a.combine=function(t,e){var r=n(t).toRgb();if(1===r.a)return n(t).toRgbString();var i=n(e||l).toRgb(),a=1===i.a?i:{r:255*(1-i.a)+i.r*i.a,g:255*(1-i.a)+i.g*i.a,b:255*(1-i.a)+i.b*i.a},o={r:a.r*(1-r.a)+r.r*r.a,g:a.g*(1-r.a)+r.g*r.a,b:a.b*(1-r.a)+r.b*r.a};return n(o).toRgbString()},a.contrast=function(t,e,r){var i=n(t);return 1!==i.getAlpha()&&(i=n(a.combine(t,l))),(i.isDark()?e?i.lighten(e):l:r?i.darken(r):s).toString()},a.stroke=function(t,e){var r=n(e);t.style({stroke:a.tinyRGB(r),"stroke-opacity":r.getAlpha()})},a.fill=function(t,e){var r=n(e);t.style({fill:a.tinyRGB(r),"fill-opacity":r.getAlpha()})},a.clean=function(t){if(t&&"object"==typeof t){var e,r,n,i,o=Object.keys(t);for(e=0;e0?S>=O:S<=O));E++)S>R&&S0?S>=O:S<=O));E++)S>C[0]&&S1){var at=Math.pow(10,Math.floor(Math.log(it)/Math.LN10));rt*=at*c.roundUp(it/at,[2,5,10]),(Math.abs(r.levels.start)/r.levels.size+1e-6)%1<2e-6&&(tt.tick0=0)}tt.dtick=rt}tt.domain=[$+Y,$+H-Y],tt.setScale();var ot=c.ensureSingle(k._infolayer,"g",e,function(t){t.classed(M.colorbar,!0).each(function(){var t=n.select(this);t.append("rect").classed(M.cbbg,!0),t.append("g").classed(M.cbfills,!0),t.append("g").classed(M.cblines,!0),t.append("g").classed(M.cbaxis,!0).classed(M.crisp,!0),t.append("g").classed(M.cbtitleunshift,!0).append("g").classed(M.cbtitle,!0),t.append("rect").classed(M.cboutline,!0),t.select(".cbtitle").datum(0)})});ot.attr("transform","translate("+Math.round(T.l)+","+Math.round(T.t)+")");var st=ot.select(".cbtitleunshift").attr("transform","translate(-"+Math.round(T.l)+",-"+Math.round(T.t)+")");tt._axislayer=ot.select(".cbaxis");var lt=0;if(-1!==["top","bottom"].indexOf(r.titleside)){var ct,ut=T.l+(r.x+G)*T.w,ht=tt.titlefont.size;ct="top"===r.titleside?(1-($+H-Y))*T.h+T.t+3+.75*ht:(1-($+Y))*T.h+T.t-3-.25*ht,vt(tt._id+"title",{attributes:{x:ut,y:ct,"text-anchor":"start"}})}var ft,pt,dt,gt=c.syncOrAsync([a.previousPromises,function(){if(-1!==["top","bottom"].indexOf(r.titleside)){var e=ot.select(".cbtitle"),a=e.select("text"),o=[-r.outlinewidth/2,r.outlinewidth/2],l=e.select(".h"+tt._id+"title-math-group").node(),u=15.6;if(a.node()&&(u=parseInt(a.node().style.fontSize,10)*v),l?(lt=f.bBox(l).height)>u&&(o[1]-=(lt-u)/2):a.node()&&!a.classed(M.jsPlaceholder)&&(lt=f.bBox(a.node()).height),lt){if(lt+=5,"top"===r.titleside)tt.domain[1]-=lt/T.h,o[1]*=-1;else{tt.domain[0]+=lt/T.h;var h=g.lineCount(a);o[1]+=(1-h)*u}e.attr("transform","translate("+o+")"),tt.setScale()}}ot.selectAll(".cbfills,.cblines").attr("transform","translate(0,"+Math.round(T.h*(1-tt.domain[1]))+")"),tt._axislayer.attr("transform","translate(0,"+Math.round(-T.t)+")");var p=ot.select(".cbfills").selectAll("rect.cbfill").data(z);p.enter().append("rect").classed(M.cbfill,!0).style("stroke","none"),p.exit().remove(),p.each(function(t,e){var r=[0===e?C[0]:(z[e]+z[e-1])/2,e===z.length-1?C[1]:(z[e]+z[e+1])/2].map(tt.c2p).map(Math.round);e!==z.length-1&&(r[1]+=r[1]>r[0]?1:-1);var a=I(t).replace("e-",""),o=i(a).toHexString();n.select(this).attr({x:X,width:Math.max(V,2),y:n.min(r),height:Math.max(n.max(r)-n.min(r),2),fill:o})});var d=ot.select(".cblines").selectAll("path.cbline").data(r.line.color&&r.line.width?L:[]);return d.enter().append("path").classed(M.cbline,!0),d.exit().remove(),d.each(function(t){n.select(this).attr("d","M"+X+","+(Math.round(tt.c2p(t))+r.line.width/2%1)+"h"+V).call(f.lineGroupStyle,r.line.width,P(t),r.line.dash)}),tt._axislayer.selectAll("g."+tt._id+"tick,path").remove(),tt._pos=X+V+(r.outlinewidth||0)/2-("outside"===r.ticks?1:0),tt.side="right",c.syncOrAsync([function(){return s.doTicksSingle(t,tt,!0)},function(){if(-1===["top","bottom"].indexOf(r.titleside)){var e=tt.titlefont.size,i=tt._offset+tt._length/2,a=T.l+(tt.position||0)*T.w+("right"===tt.side?10+e*(tt.showticklabels?1:.5):-10-e*(tt.showticklabels?.5:0));vt("h"+tt._id+"title",{avoid:{selection:n.select(t).selectAll("g."+tt._id+"tick"),side:r.titleside,offsetLeft:T.l,offsetTop:0,maxShift:k.width},attributes:{x:a,y:i,"text-anchor":"middle"},transform:{rotate:"-90",offset:0}})}}])},a.previousPromises,function(){var n=V+r.outlinewidth/2+f.bBox(tt._axislayer.node()).width;if((F=st.select("text")).node()&&!F.classed(M.jsPlaceholder)){var i,o=st.select(".h"+tt._id+"title-math-group").node();i=o&&-1!==["top","bottom"].indexOf(r.titleside)?f.bBox(o).width:f.bBox(st.node()).right-X-T.l,n=Math.max(n,i)}var s=2*r.xpad+n+r.borderwidth+r.outlinewidth/2,l=J-K;ot.select(".cbbg").attr({x:X-r.xpad-(r.borderwidth+r.outlinewidth)/2,y:K-W,width:Math.max(s,2),height:Math.max(l+2*W,2)}).call(p.fill,r.bgcolor).call(p.stroke,r.bordercolor).style({"stroke-width":r.borderwidth}),ot.selectAll(".cboutline").attr({x:X,y:K+r.ypad+("top"===r.titleside?lt:0),width:Math.max(V,2),height:Math.max(l-2*r.ypad-lt,2)}).call(p.stroke,r.outlinecolor).style({fill:"None","stroke-width":r.outlinewidth});var c=({center:.5,right:1}[r.xanchor]||0)*s;ot.attr("transform","translate("+(T.l-c)+","+T.t+")");var u={},h=y[r.yanchor],d=x[r.yanchor];"pixels"===r.lenmode?(u.y=r.y,u.t=l*h,u.b=l*d):(u.t=u.b=0,u.yt=r.y+r.len*h,u.yb=r.y-r.len*d);var g=y[r.xanchor],m=x[r.xanchor];if("pixels"===r.thicknessmode)u.x=r.x,u.l=s*g,u.r=s*m;else{var v=s-V;u.l=v*g,u.r=v*m,u.xl=r.x-r.thickness*g,u.xr=r.x+r.thickness*m}a.autoMargin(t,e,u)}],t);if(gt&>.then&&(t._promises||[]).push(gt),t._context.edits.colorbarPosition)l.init({element:ot.node(),gd:t,prepFn:function(){ft=ot.attr("transform"),h(ot)},moveFn:function(t,e){ot.attr("transform",ft+" translate("+t+","+e+")"),pt=l.align(Z+t/T.w,U,0,1,r.xanchor),dt=l.align($-e/T.h,H,0,1,r.yanchor);var n=l.getCursor(pt,dt,r.xanchor,r.yanchor);h(ot,n)},doneFn:function(){h(ot),void 0!==pt&&void 0!==dt&&o.call("restyle",t,{"colorbar.x":pt,"colorbar.y":dt},A().index)}});return gt}function mt(t,e){return c.coerce(Q,tt,w,t,e)}function vt(e,r){var n=A(),i="colorbar.title",a=n._module.colorbar.container;a&&(i=a+"."+i);var o={propContainer:tt,propName:i,traceIndex:n.index,placeholder:k._dfltTitle.colorbar,containerGroup:ot.select(".cbtitle")},s="h"===e.charAt(0)?e.substr(1):"h"+e;ot.selectAll("."+s+",."+s+"-math-group").remove(),d.draw(t,e,u(o,r||{}))}k._infolayer.selectAll("g."+e).remove()}function A(){var r,n,i=e.substr(2);for(r=0;r=0?i.Reds:i.Blues,s.reversescale?a(y):y),l.autocolorscale||h("autocolorscale",!1))}},{"../../lib":684,"./flip_scale":570,"./scales":577}],567:[function(t,e,r){"use strict";var n=t("./scales");e.exports=n.RdBu},{"./scales":577}],568:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../../lib"),a=t("../colorbar/has_colorbar"),o=t("../colorbar/defaults"),s=t("./is_valid_scale"),l=t("./flip_scale");e.exports=function(t,e,r,c,u){var h,f=u.prefix,p=u.cLetter,d=f.slice(0,f.length-1),g=f?i.nestedProperty(t,d).get()||{}:t,m=f?i.nestedProperty(e,d).get()||{}:e,v=g[p+"min"],y=g[p+"max"],x=g.colorscale;c(f+p+"auto",!(n(v)&&n(y)&&v=0;i--,a++)e=t[i],n[a]=[1-e[0],e[1]];return n}},{}],571:[function(t,e,r){"use strict";var n=t("./scales"),i=t("./default_scale"),a=t("./is_valid_scale_array");e.exports=function(t,e){if(e||(e=i),!t)return e;function r(){try{t=n[t]||JSON.parse(t)}catch(r){t=e}}return"string"==typeof t&&(r(),"string"==typeof t&&r()),a(t)?t:e}},{"./default_scale":567,"./is_valid_scale_array":575,"./scales":577}],572:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../../lib"),a=t("./is_valid_scale");e.exports=function(t,e){var r=e?i.nestedProperty(t,e).get()||{}:t,o=r.color,s=!1;if(i.isArrayOrTypedArray(o))for(var l=0;l4/3-s?o:s}},{}],579:[function(t,e,r){"use strict";var n=t("../../lib"),i=[["sw-resize","s-resize","se-resize"],["w-resize","move","e-resize"],["nw-resize","n-resize","ne-resize"]];e.exports=function(t,e,r,a){return t="left"===r?0:"center"===r?1:"right"===r?2:n.constrain(Math.floor(3*t),0,2),e="bottom"===a?0:"middle"===a?1:"top"===a?2:n.constrain(Math.floor(3*e),0,2),i[e][t]}},{"../../lib":684}],580:[function(t,e,r){"use strict";var n=t("mouse-event-offset"),i=t("has-hover"),a=t("has-passive-events"),o=t("../../registry"),s=t("../../lib"),l=t("../../plots/cartesian/constants"),c=t("../../constants/interactions"),u=e.exports={};u.align=t("./align"),u.getCursor=t("./cursor");var h=t("./unhover");function f(){var t=document.createElement("div");t.className="dragcover";var e=t.style;return e.position="fixed",e.left=0,e.right=0,e.top=0,e.bottom=0,e.zIndex=999999999,e.background="none",document.body.appendChild(t),t}function p(t){return n(t.changedTouches?t.changedTouches[0]:t,document.body)}u.unhover=h.wrapped,u.unhoverRaw=h.raw,u.init=function(t){var e,r,n,h,d,g,m,v,y=t.gd,x=1,b=c.DBLCLICKDELAY,_=t.element;y._mouseDownTime||(y._mouseDownTime=0),_.style.pointerEvents="all",_.onmousedown=k,a?(_._ontouchstart&&_.removeEventListener("touchstart",_._ontouchstart),_._ontouchstart=k,_.addEventListener("touchstart",k,{passive:!1})):_.ontouchstart=k;var w=t.clampFn||function(t,e,r){return Math.abs(t)b&&(x=Math.max(x-1,1)),y._dragged)t.doneFn&&t.doneFn();else if(t.clickFn&&t.clickFn(x,g),!v){var r;try{r=new MouseEvent("click",e)}catch(t){var n=p(e);(r=document.createEvent("MouseEvents")).initMouseEvent("click",e.bubbles,e.cancelable,e.view,e.detail,e.screenX,e.screenY,n[0],n[1],e.ctrlKey,e.altKey,e.shiftKey,e.metaKey,e.button,e.relatedTarget)}m.dispatchEvent(r)}!function(t){t._dragging=!1,t._replotPending&&o.call("plot",t)}(y),y._dragged=!1}else y._dragged=!1}},u.coverSlip=f},{"../../constants/interactions":660,"../../lib":684,"../../plots/cartesian/constants":737,"../../registry":817,"./align":578,"./cursor":579,"./unhover":581,"has-hover":378,"has-passive-events":379,"mouse-event-offset":403}],581:[function(t,e,r){"use strict";var n=t("../../lib/events"),i=t("../../lib/throttle"),a=t("../../lib/get_graph_div"),o=t("../fx/constants"),s=e.exports={};s.wrapped=function(t,e,r){(t=a(t))._fullLayout&&i.clear(t._fullLayout._uid+o.HOVERID),s.raw(t,e,r)},s.raw=function(t,e){var r=t._fullLayout,i=t._hoverdata;e||(e={}),e.target&&!1===n.triggerHandler(t,"plotly_beforehover",e)||(r._hoverlayer.selectAll("g").remove(),r._hoverlayer.selectAll("line").remove(),r._hoverlayer.selectAll("circle").remove(),t._hoverdata=void 0,e.target&&i&&t.emit("plotly_unhover",{event:e,points:i}))}},{"../../lib/events":672,"../../lib/get_graph_div":679,"../../lib/throttle":709,"../fx/constants":595}],582:[function(t,e,r){"use strict";r.dash={valType:"string",values:["solid","dot","dash","longdash","dashdot","longdashdot"],dflt:"solid",editType:"style"}},{}],583:[function(t,e,r){"use strict";var n=t("d3"),i=t("fast-isnumeric"),a=t("tinycolor2"),o=t("../../registry"),s=t("../color"),l=t("../colorscale"),c=t("../../lib"),u=t("../../lib/svg_text_utils"),h=t("../../constants/xmlns_namespaces"),f=t("../../constants/alignment").LINE_SPACING,p=t("../../constants/interactions").DESELECTDIM,d=t("../../traces/scatter/subtypes"),g=t("../../traces/scatter/make_bubble_size_func"),m=e.exports={};m.font=function(t,e,r,n){c.isPlainObject(e)&&(n=e.color,r=e.size,e=e.family),e&&t.style("font-family",e),r+1&&t.style("font-size",r+"px"),n&&t.call(s.fill,n)},m.setPosition=function(t,e,r){t.attr("x",e).attr("y",r)},m.setSize=function(t,e,r){t.attr("width",e).attr("height",r)},m.setRect=function(t,e,r,n,i){t.call(m.setPosition,e,r).call(m.setSize,n,i)},m.translatePoint=function(t,e,r,n){var a=r.c2p(t.x),o=n.c2p(t.y);return!!(i(a)&&i(o)&&e.node())&&("text"===e.node().nodeName?e.attr("x",a).attr("y",o):e.attr("transform","translate("+a+","+o+")"),!0)},m.translatePoints=function(t,e,r){t.each(function(t){var i=n.select(this);m.translatePoint(t,i,e,r)})},m.hideOutsideRangePoint=function(t,e,r,n,i,a){e.attr("display",r.isPtWithinRange(t,i)&&n.isPtWithinRange(t,a)?null:"none")},m.hideOutsideRangePoints=function(t,e){if(e._hasClipOnAxisFalse){var r=e.xaxis,i=e.yaxis;t.each(function(e){var a=e[0].trace,o=a.xcalendar,s=a.ycalendar,l="bar"===a.type?".bartext":".point,.textpoint";t.selectAll(l).each(function(t){m.hideOutsideRangePoint(t,n.select(this),r,i,o,s)})})}},m.crispRound=function(t,e,r){return e&&i(e)?t._context.staticPlot?e:e<1?1:Math.round(e):r||0},m.singleLineStyle=function(t,e,r,n,i){e.style("fill","none");var a=(((t||[])[0]||{}).trace||{}).line||{},o=r||a.width||0,l=i||a.dash||"";s.stroke(e,n||a.color),m.dashLine(e,l,o)},m.lineGroupStyle=function(t,e,r,i){t.style("fill","none").each(function(t){var a=(((t||[])[0]||{}).trace||{}).line||{},o=e||a.width||0,l=i||a.dash||"";n.select(this).call(s.stroke,r||a.color).call(m.dashLine,l,o)})},m.dashLine=function(t,e,r){r=+r||0,e=m.dashStyle(e,r),t.style({"stroke-dasharray":e,"stroke-width":r+"px"})},m.dashStyle=function(t,e){e=+e||1;var r=Math.max(e,3);return"solid"===t?t="":"dot"===t?t=r+"px,"+r+"px":"dash"===t?t=3*r+"px,"+3*r+"px":"longdash"===t?t=5*r+"px,"+5*r+"px":"dashdot"===t?t=3*r+"px,"+r+"px,"+r+"px,"+r+"px":"longdashdot"===t&&(t=5*r+"px,"+2*r+"px,"+r+"px,"+2*r+"px"),t},m.singleFillStyle=function(t){var e=(((n.select(t.node()).data()[0]||[])[0]||{}).trace||{}).fillcolor;e&&t.call(s.fill,e)},m.fillGroupStyle=function(t){t.style("stroke-width",0).each(function(e){var r=n.select(this);try{r.call(s.fill,e[0].trace.fillcolor)}catch(e){c.error(e,t),r.remove()}})};var v=t("./symbol_defs");m.symbolNames=[],m.symbolFuncs=[],m.symbolNeedLines={},m.symbolNoDot={},m.symbolNoFill={},m.symbolList=[],Object.keys(v).forEach(function(t){var e=v[t];m.symbolList=m.symbolList.concat([e.n,t,e.n+100,t+"-open"]),m.symbolNames[e.n]=t,m.symbolFuncs[e.n]=e.f,e.needLine&&(m.symbolNeedLines[e.n]=!0),e.noDot?m.symbolNoDot[e.n]=!0:m.symbolList=m.symbolList.concat([e.n+200,t+"-dot",e.n+300,t+"-open-dot"]),e.noFill&&(m.symbolNoFill[e.n]=!0)});var y=m.symbolNames.length,x="M0,0.5L0.5,0L0,-0.5L-0.5,0Z";function b(t,e){var r=t%100;return m.symbolFuncs[r](e)+(t>=200?x:"")}m.symbolNumber=function(t){if("string"==typeof t){var e=0;t.indexOf("-open")>0&&(e=100,t=t.replace("-open","")),t.indexOf("-dot")>0&&(e+=200,t=t.replace("-dot","")),(t=m.symbolNames.indexOf(t))>=0&&(t+=e)}return t%100>=y||t>=400?0:Math.floor(Math.max(t,0))};var _={x1:1,x2:0,y1:0,y2:0},w={x1:0,x2:0,y1:1,y2:0};m.gradient=function(t,e,r,i,o,l){var u=e._fullLayout._defs.select(".gradients").selectAll("#"+r).data([i+o+l],c.identity);u.exit().remove(),u.enter().append("radial"===i?"radialGradient":"linearGradient").each(function(){var t=n.select(this);"horizontal"===i?t.attr(_):"vertical"===i&&t.attr(w),t.attr("id",r);var e=a(o),c=a(l);t.append("stop").attr({offset:"0%","stop-color":s.tinyRGB(c),"stop-opacity":c.getAlpha()}),t.append("stop").attr({offset:"100%","stop-color":s.tinyRGB(e),"stop-opacity":e.getAlpha()})}),t.style({fill:"url(#"+r+")","fill-opacity":null})},m.initGradients=function(t){c.ensureSingle(t._fullLayout._defs,"g","gradients").selectAll("linearGradient,radialGradient").remove()},m.pointStyle=function(t,e,r){if(t.size()){var i=m.makePointStyleFns(e);t.each(function(t){m.singlePointStyle(t,n.select(this),e,i,r)})}},m.singlePointStyle=function(t,e,r,n,i){var a=r.marker,o=a.line;if(e.style("opacity",n.selectedOpacityFn?n.selectedOpacityFn(t):void 0===t.mo?a.opacity:t.mo),n.ms2mrc){var l;l="various"===t.ms||"various"===a.size?3:n.ms2mrc(t.ms),t.mrc=l,n.selectedSizeFn&&(l=t.mrc=n.selectedSizeFn(t));var u=m.symbolNumber(t.mx||a.symbol)||0;t.om=u%200>=100,e.attr("d",b(u,l))}var h,f,p,d=!1;if(t.so)p=o.outlierwidth,f=o.outliercolor,h=a.outliercolor;else{var g=(o||{}).width;p=(t.mlw+1||g+1||(t.trace?(t.trace.marker.line||{}).width:0)+1)-1||0,f="mlc"in t?t.mlcc=n.lineScale(t.mlc):c.isArrayOrTypedArray(o.color)?s.defaultLine:o.color,c.isArrayOrTypedArray(a.color)&&(h=s.defaultLine,d=!0),h="mc"in t?t.mcc=n.markerScale(t.mc):a.color||"rgba(0,0,0,0)",n.selectedColorFn&&(h=n.selectedColorFn(t))}if(t.om)e.call(s.stroke,h).style({"stroke-width":(p||1)+"px",fill:"none"});else{e.style("stroke-width",p+"px");var v=a.gradient,y=t.mgt;if(y?d=!0:y=v&&v.type,y&&"none"!==y){var x=t.mgc;x?d=!0:x=v.color;var _="g"+i._fullLayout._uid+"-"+r.uid;d&&(_+="-"+t.i),e.call(m.gradient,i,_,y,h,x)}else e.call(s.fill,h);p&&e.call(s.stroke,f)}},m.makePointStyleFns=function(t){var e={},r=t.marker;return e.markerScale=m.tryColorscale(r,""),e.lineScale=m.tryColorscale(r,"line"),o.traceIs(t,"symbols")&&(e.ms2mrc=d.isBubble(t)?g(t):function(){return(r.size||6)/2}),t.selectedpoints&&c.extendFlat(e,m.makeSelectedPointStyleFns(t)),e},m.makeSelectedPointStyleFns=function(t){var e={},r=t.selected||{},n=t.unselected||{},i=t.marker||{},a=r.marker||{},s=n.marker||{},l=i.opacity,u=a.opacity,h=s.opacity,f=void 0!==u,d=void 0!==h;(c.isArrayOrTypedArray(l)||f||d)&&(e.selectedOpacityFn=function(t){var e=void 0===t.mo?i.opacity:t.mo;return t.selected?f?u:e:d?h:p*e});var g=i.color,m=a.color,v=s.color;(m||v)&&(e.selectedColorFn=function(t){var e=t.mcc||g;return t.selected?m||e:v||e});var y=i.size,x=a.size,b=s.size,_=void 0!==x,w=void 0!==b;return o.traceIs(t,"symbols")&&(_||w)&&(e.selectedSizeFn=function(t){var e=t.mrc||y/2;return t.selected?_?x/2:e:w?b/2:e}),e},m.makeSelectedTextStyleFns=function(t){var e={},r=t.selected||{},n=t.unselected||{},i=t.textfont||{},a=r.textfont||{},o=n.textfont||{},l=i.color,c=a.color,u=o.color;return e.selectedTextColorFn=function(t){var e=t.tc||l;return t.selected?c||e:u||(c?e:s.addOpacity(e,p))},e},m.selectedPointStyle=function(t,e){if(t.size()&&e.selectedpoints){var r=m.makeSelectedPointStyleFns(e),i=e.marker||{},a=[];r.selectedOpacityFn&&a.push(function(t,e){t.style("opacity",r.selectedOpacityFn(e))}),r.selectedColorFn&&a.push(function(t,e){s.fill(t,r.selectedColorFn(e))}),r.selectedSizeFn&&a.push(function(t,e){var n=e.mx||i.symbol||0,a=r.selectedSizeFn(e);t.attr("d",b(m.symbolNumber(n),a)),e.mrc2=a}),a.length&&t.each(function(t){for(var e=n.select(this),r=0;r0?r:0}m.textPointStyle=function(t,e,r){if(t.size()){var i;if(e.selectedpoints){var a=m.makeSelectedTextStyleFns(e);i=a.selectedTextColorFn}t.each(function(t){var a=n.select(this),o=c.extractOption(t,e,"tx","text");if(o||0===o){var s=t.tp||e.textposition,l=A(t,e),h=i?i(t):t.tc||e.textfont.color;a.call(m.font,t.tf||e.textfont.family,l,h).text(o).call(u.convertToTspans,r).call(M,s,l,t.mrc)}else a.remove()})}},m.selectedTextStyle=function(t,e){if(t.size()&&e.selectedpoints){var r=m.makeSelectedTextStyleFns(e);t.each(function(t){var i=n.select(this),a=r.selectedTextColorFn(t),o=t.tp||e.textposition,l=A(t,e);s.fill(i,a),M(i,o,l,t.mrc2||t.mrc)})}};var T=.5;function S(t,e,r,i){var a=t[0]-e[0],o=t[1]-e[1],s=r[0]-e[0],l=r[1]-e[1],c=Math.pow(a*a+o*o,T/2),u=Math.pow(s*s+l*l,T/2),h=(u*u*a-c*c*s)*i,f=(u*u*o-c*c*l)*i,p=3*u*(c+u),d=3*c*(c+u);return[[n.round(e[0]+(p&&h/p),2),n.round(e[1]+(p&&f/p),2)],[n.round(e[0]-(d&&h/d),2),n.round(e[1]-(d&&f/d),2)]]}m.smoothopen=function(t,e){if(t.length<3)return"M"+t.join("L");var r,n="M"+t[0],i=[];for(r=1;r=1e4&&(m.savedBBoxes={},L=0),r&&(m.savedBBoxes[r]=v),L++,c.extendFlat({},v)},m.setClipUrl=function(t,e){if(e){if(void 0===m.baseUrl){var r=n.select("base");r.size()&&r.attr("href")?m.baseUrl=window.location.href.split("#")[0]:m.baseUrl=""}t.attr("clip-path","url("+m.baseUrl+"#"+e+")")}else t.attr("clip-path",null)},m.getTranslate=function(t){var e=(t[t.attr?"attr":"getAttribute"]("transform")||"").replace(/.*\btranslate\((-?\d*\.?\d*)[^-\d]*(-?\d*\.?\d*)[^\d].*/,function(t,e,r){return[e,r].join(" ")}).split(" ");return{x:+e[0]||0,y:+e[1]||0}},m.setTranslate=function(t,e,r){var n=t.attr?"attr":"getAttribute",i=t.attr?"attr":"setAttribute",a=t[n]("transform")||"";return e=e||0,r=r||0,a=a.replace(/(\btranslate\(.*?\);?)/,"").trim(),a=(a+=" translate("+e+", "+r+")").trim(),t[i]("transform",a),a},m.getScale=function(t){var e=(t[t.attr?"attr":"getAttribute"]("transform")||"").replace(/.*\bscale\((\d*\.?\d*)[^\d]*(\d*\.?\d*)[^\d].*/,function(t,e,r){return[e,r].join(" ")}).split(" ");return{x:+e[0]||1,y:+e[1]||1}},m.setScale=function(t,e,r){var n=t.attr?"attr":"getAttribute",i=t.attr?"attr":"setAttribute",a=t[n]("transform")||"";return e=e||1,r=r||1,a=a.replace(/(\bscale\(.*?\);?)/,"").trim(),a=(a+=" scale("+e+", "+r+")").trim(),t[i]("transform",a),a};var P=/\s*sc.*/;m.setPointGroupScale=function(t,e,r){if(e=e||1,r=r||1,t){var n=1===e&&1===r?"":" scale("+e+","+r+")";t.each(function(){var t=(this.getAttribute("transform")||"").replace(P,"");t=(t+=n).trim(),this.setAttribute("transform",t)})}};var I=/translate\([^)]*\)\s*$/;m.setTextPointsScale=function(t,e,r){t&&t.each(function(){var t,i=n.select(this),a=i.select("text");if(a.node()){var o=parseFloat(a.attr("x")||0),s=parseFloat(a.attr("y")||0),l=(i.attr("transform")||"").match(I);t=1===e&&1===r?[]:["translate("+o+","+s+")","scale("+e+","+r+")","translate("+-o+","+-s+")"],l&&t.push(l),i.attr("transform",t.join(" "))}})}},{"../../constants/alignment":656,"../../constants/interactions":660,"../../constants/xmlns_namespaces":663,"../../lib":684,"../../lib/svg_text_utils":708,"../../registry":817,"../../traces/scatter/make_bubble_size_func":1031,"../../traces/scatter/subtypes":1037,"../color":558,"../colorscale":573,"./symbol_defs":584,d3:147,"fast-isnumeric":214,tinycolor2:499}],584:[function(t,e,r){"use strict";var n=t("d3");e.exports={circle:{n:0,f:function(t){var e=n.round(t,2);return"M"+e+",0A"+e+","+e+" 0 1,1 0,-"+e+"A"+e+","+e+" 0 0,1 "+e+",0Z"}},square:{n:1,f:function(t){var e=n.round(t,2);return"M"+e+","+e+"H-"+e+"V-"+e+"H"+e+"Z"}},diamond:{n:2,f:function(t){var e=n.round(1.3*t,2);return"M"+e+",0L0,"+e+"L-"+e+",0L0,-"+e+"Z"}},cross:{n:3,f:function(t){var e=n.round(.4*t,2),r=n.round(1.2*t,2);return"M"+r+","+e+"H"+e+"V"+r+"H-"+e+"V"+e+"H-"+r+"V-"+e+"H-"+e+"V-"+r+"H"+e+"V-"+e+"H"+r+"Z"}},x:{n:4,f:function(t){var e=n.round(.8*t/Math.sqrt(2),2),r="l"+e+","+e,i="l"+e+",-"+e,a="l-"+e+",-"+e,o="l-"+e+","+e;return"M0,"+e+r+i+a+i+a+o+a+o+r+o+r+"Z"}},"triangle-up":{n:5,f:function(t){var e=n.round(2*t/Math.sqrt(3),2);return"M-"+e+","+n.round(t/2,2)+"H"+e+"L0,-"+n.round(t,2)+"Z"}},"triangle-down":{n:6,f:function(t){var e=n.round(2*t/Math.sqrt(3),2);return"M-"+e+",-"+n.round(t/2,2)+"H"+e+"L0,"+n.round(t,2)+"Z"}},"triangle-left":{n:7,f:function(t){var e=n.round(2*t/Math.sqrt(3),2);return"M"+n.round(t/2,2)+",-"+e+"V"+e+"L-"+n.round(t,2)+",0Z"}},"triangle-right":{n:8,f:function(t){var e=n.round(2*t/Math.sqrt(3),2);return"M-"+n.round(t/2,2)+",-"+e+"V"+e+"L"+n.round(t,2)+",0Z"}},"triangle-ne":{n:9,f:function(t){var e=n.round(.6*t,2),r=n.round(1.2*t,2);return"M-"+r+",-"+e+"H"+e+"V"+r+"Z"}},"triangle-se":{n:10,f:function(t){var e=n.round(.6*t,2),r=n.round(1.2*t,2);return"M"+e+",-"+r+"V"+e+"H-"+r+"Z"}},"triangle-sw":{n:11,f:function(t){var e=n.round(.6*t,2),r=n.round(1.2*t,2);return"M"+r+","+e+"H-"+e+"V-"+r+"Z"}},"triangle-nw":{n:12,f:function(t){var e=n.round(.6*t,2),r=n.round(1.2*t,2);return"M-"+e+","+r+"V-"+e+"H"+r+"Z"}},pentagon:{n:13,f:function(t){var e=n.round(.951*t,2),r=n.round(.588*t,2),i=n.round(-t,2),a=n.round(-.309*t,2);return"M"+e+","+a+"L"+r+","+n.round(.809*t,2)+"H-"+r+"L-"+e+","+a+"L0,"+i+"Z"}},hexagon:{n:14,f:function(t){var e=n.round(t,2),r=n.round(t/2,2),i=n.round(t*Math.sqrt(3)/2,2);return"M"+i+",-"+r+"V"+r+"L0,"+e+"L-"+i+","+r+"V-"+r+"L0,-"+e+"Z"}},hexagon2:{n:15,f:function(t){var e=n.round(t,2),r=n.round(t/2,2),i=n.round(t*Math.sqrt(3)/2,2);return"M-"+r+","+i+"H"+r+"L"+e+",0L"+r+",-"+i+"H-"+r+"L-"+e+",0Z"}},octagon:{n:16,f:function(t){var e=n.round(.924*t,2),r=n.round(.383*t,2);return"M-"+r+",-"+e+"H"+r+"L"+e+",-"+r+"V"+r+"L"+r+","+e+"H-"+r+"L-"+e+","+r+"V-"+r+"Z"}},star:{n:17,f:function(t){var e=1.4*t,r=n.round(.225*e,2),i=n.round(.951*e,2),a=n.round(.363*e,2),o=n.round(.588*e,2),s=n.round(-e,2),l=n.round(-.309*e,2),c=n.round(.118*e,2),u=n.round(.809*e,2);return"M"+r+","+l+"H"+i+"L"+a+","+c+"L"+o+","+u+"L0,"+n.round(.382*e,2)+"L-"+o+","+u+"L-"+a+","+c+"L-"+i+","+l+"H-"+r+"L0,"+s+"Z"}},hexagram:{n:18,f:function(t){var e=n.round(.66*t,2),r=n.round(.38*t,2),i=n.round(.76*t,2);return"M-"+i+",0l-"+r+",-"+e+"h"+i+"l"+r+",-"+e+"l"+r+","+e+"h"+i+"l-"+r+","+e+"l"+r+","+e+"h-"+i+"l-"+r+","+e+"l-"+r+",-"+e+"h-"+i+"Z"}},"star-triangle-up":{n:19,f:function(t){var e=n.round(t*Math.sqrt(3)*.8,2),r=n.round(.8*t,2),i=n.round(1.6*t,2),a=n.round(4*t,2),o="A "+a+","+a+" 0 0 1 ";return"M-"+e+","+r+o+e+","+r+o+"0,-"+i+o+"-"+e+","+r+"Z"}},"star-triangle-down":{n:20,f:function(t){var e=n.round(t*Math.sqrt(3)*.8,2),r=n.round(.8*t,2),i=n.round(1.6*t,2),a=n.round(4*t,2),o="A "+a+","+a+" 0 0 1 ";return"M"+e+",-"+r+o+"-"+e+",-"+r+o+"0,"+i+o+e+",-"+r+"Z"}},"star-square":{n:21,f:function(t){var e=n.round(1.1*t,2),r=n.round(2*t,2),i="A "+r+","+r+" 0 0 1 ";return"M-"+e+",-"+e+i+"-"+e+","+e+i+e+","+e+i+e+",-"+e+i+"-"+e+",-"+e+"Z"}},"star-diamond":{n:22,f:function(t){var e=n.round(1.4*t,2),r=n.round(1.9*t,2),i="A "+r+","+r+" 0 0 1 ";return"M-"+e+",0"+i+"0,"+e+i+e+",0"+i+"0,-"+e+i+"-"+e+",0Z"}},"diamond-tall":{n:23,f:function(t){var e=n.round(.7*t,2),r=n.round(1.4*t,2);return"M0,"+r+"L"+e+",0L0,-"+r+"L-"+e+",0Z"}},"diamond-wide":{n:24,f:function(t){var e=n.round(1.4*t,2),r=n.round(.7*t,2);return"M0,"+r+"L"+e+",0L0,-"+r+"L-"+e+",0Z"}},hourglass:{n:25,f:function(t){var e=n.round(t,2);return"M"+e+","+e+"H-"+e+"L"+e+",-"+e+"H-"+e+"Z"},noDot:!0},bowtie:{n:26,f:function(t){var e=n.round(t,2);return"M"+e+","+e+"V-"+e+"L-"+e+","+e+"V-"+e+"Z"},noDot:!0},"circle-cross":{n:27,f:function(t){var e=n.round(t,2);return"M0,"+e+"V-"+e+"M"+e+",0H-"+e+"M"+e+",0A"+e+","+e+" 0 1,1 0,-"+e+"A"+e+","+e+" 0 0,1 "+e+",0Z"},needLine:!0,noDot:!0},"circle-x":{n:28,f:function(t){var e=n.round(t,2),r=n.round(t/Math.sqrt(2),2);return"M"+r+","+r+"L-"+r+",-"+r+"M"+r+",-"+r+"L-"+r+","+r+"M"+e+",0A"+e+","+e+" 0 1,1 0,-"+e+"A"+e+","+e+" 0 0,1 "+e+",0Z"},needLine:!0,noDot:!0},"square-cross":{n:29,f:function(t){var e=n.round(t,2);return"M0,"+e+"V-"+e+"M"+e+",0H-"+e+"M"+e+","+e+"H-"+e+"V-"+e+"H"+e+"Z"},needLine:!0,noDot:!0},"square-x":{n:30,f:function(t){var e=n.round(t,2);return"M"+e+","+e+"L-"+e+",-"+e+"M"+e+",-"+e+"L-"+e+","+e+"M"+e+","+e+"H-"+e+"V-"+e+"H"+e+"Z"},needLine:!0,noDot:!0},"diamond-cross":{n:31,f:function(t){var e=n.round(1.3*t,2);return"M"+e+",0L0,"+e+"L-"+e+",0L0,-"+e+"ZM0,-"+e+"V"+e+"M-"+e+",0H"+e},needLine:!0,noDot:!0},"diamond-x":{n:32,f:function(t){var e=n.round(1.3*t,2),r=n.round(.65*t,2);return"M"+e+",0L0,"+e+"L-"+e+",0L0,-"+e+"ZM-"+r+",-"+r+"L"+r+","+r+"M-"+r+","+r+"L"+r+",-"+r},needLine:!0,noDot:!0},"cross-thin":{n:33,f:function(t){var e=n.round(1.4*t,2);return"M0,"+e+"V-"+e+"M"+e+",0H-"+e},needLine:!0,noDot:!0,noFill:!0},"x-thin":{n:34,f:function(t){var e=n.round(t,2);return"M"+e+","+e+"L-"+e+",-"+e+"M"+e+",-"+e+"L-"+e+","+e},needLine:!0,noDot:!0,noFill:!0},asterisk:{n:35,f:function(t){var e=n.round(1.2*t,2),r=n.round(.85*t,2);return"M0,"+e+"V-"+e+"M"+e+",0H-"+e+"M"+r+","+r+"L-"+r+",-"+r+"M"+r+",-"+r+"L-"+r+","+r},needLine:!0,noDot:!0,noFill:!0},hash:{n:36,f:function(t){var e=n.round(t/2,2),r=n.round(t,2);return"M"+e+","+r+"V-"+r+"m-"+r+",0V"+r+"M"+r+","+e+"H-"+r+"m0,-"+r+"H"+r},needLine:!0,noFill:!0},"y-up":{n:37,f:function(t){var e=n.round(1.2*t,2),r=n.round(1.6*t,2),i=n.round(.8*t,2);return"M-"+e+","+i+"L0,0M"+e+","+i+"L0,0M0,-"+r+"L0,0"},needLine:!0,noDot:!0,noFill:!0},"y-down":{n:38,f:function(t){var e=n.round(1.2*t,2),r=n.round(1.6*t,2),i=n.round(.8*t,2);return"M-"+e+",-"+i+"L0,0M"+e+",-"+i+"L0,0M0,"+r+"L0,0"},needLine:!0,noDot:!0,noFill:!0},"y-left":{n:39,f:function(t){var e=n.round(1.2*t,2),r=n.round(1.6*t,2),i=n.round(.8*t,2);return"M"+i+","+e+"L0,0M"+i+",-"+e+"L0,0M-"+r+",0L0,0"},needLine:!0,noDot:!0,noFill:!0},"y-right":{n:40,f:function(t){var e=n.round(1.2*t,2),r=n.round(1.6*t,2),i=n.round(.8*t,2);return"M-"+i+","+e+"L0,0M-"+i+",-"+e+"L0,0M"+r+",0L0,0"},needLine:!0,noDot:!0,noFill:!0},"line-ew":{n:41,f:function(t){var e=n.round(1.4*t,2);return"M"+e+",0H-"+e},needLine:!0,noDot:!0,noFill:!0},"line-ns":{n:42,f:function(t){var e=n.round(1.4*t,2);return"M0,"+e+"V-"+e},needLine:!0,noDot:!0,noFill:!0},"line-ne":{n:43,f:function(t){var e=n.round(t,2);return"M"+e+",-"+e+"L-"+e+","+e},needLine:!0,noDot:!0,noFill:!0},"line-nw":{n:44,f:function(t){var e=n.round(t,2);return"M"+e+","+e+"L-"+e+",-"+e},needLine:!0,noDot:!0,noFill:!0}}},{d3:147}],585:[function(t,e,r){"use strict";e.exports={visible:{valType:"boolean",editType:"calc"},type:{valType:"enumerated",values:["percent","constant","sqrt","data"],editType:"calc"},symmetric:{valType:"boolean",editType:"calc"},array:{valType:"data_array",editType:"calc"},arrayminus:{valType:"data_array",editType:"calc"},value:{valType:"number",min:0,dflt:10,editType:"calc"},valueminus:{valType:"number",min:0,dflt:10,editType:"calc"},traceref:{valType:"integer",min:0,dflt:0,editType:"style"},tracerefminus:{valType:"integer",min:0,dflt:0,editType:"style"},copy_ystyle:{valType:"boolean",editType:"plot"},copy_zstyle:{valType:"boolean",editType:"style"},color:{valType:"color",editType:"style"},thickness:{valType:"number",min:0,dflt:2,editType:"style"},width:{valType:"number",min:0,editType:"plot"},editType:"calc",_deprecated:{opacity:{valType:"number",editType:"style"}}}},{}],586:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../../registry"),a=t("../../plots/cartesian/axes"),o=t("./compute_error");function s(t,e,r,i){var s=e["error_"+i]||{},l=[];if(s.visible&&-1!==["linear","log"].indexOf(r.type)){for(var c=o(s),u=0;u0;t.each(function(t){var u,h=t[0].trace,f=h.error_x||{},p=h.error_y||{};h.ids&&(u=function(t){return t.id});var d=o.hasMarkers(h)&&h.marker.maxdisplayed>0;p.visible||f.visible||(t=[]);var g=n.select(this).selectAll("g.errorbar").data(t,u);if(g.exit().remove(),t.length){f.visible||g.selectAll("path.xerror").remove(),p.visible||g.selectAll("path.yerror").remove(),g.style("opacity",1);var m=g.enter().append("g").classed("errorbar",!0);c&&m.style("opacity",0).transition().duration(r.duration).style("opacity",1),a.setClipUrl(g,e.layerClipId),g.each(function(t){var e=n.select(this),a=function(t,e,r){var n={x:e.c2p(t.x),y:r.c2p(t.y)};void 0!==t.yh&&(n.yh=r.c2p(t.yh),n.ys=r.c2p(t.ys),i(n.ys)||(n.noYS=!0,n.ys=r.c2p(t.ys,!0)));void 0!==t.xh&&(n.xh=e.c2p(t.xh),n.xs=e.c2p(t.xs),i(n.xs)||(n.noXS=!0,n.xs=e.c2p(t.xs,!0)));return n}(t,s,l);if(!d||t.vis){var o,u=e.select("path.yerror");if(p.visible&&i(a.x)&&i(a.yh)&&i(a.ys)){var h=p.width;o="M"+(a.x-h)+","+a.yh+"h"+2*h+"m-"+h+",0V"+a.ys,a.noYS||(o+="m-"+h+",0h"+2*h),!u.size()?u=e.append("path").style("vector-effect","non-scaling-stroke").classed("yerror",!0):c&&(u=u.transition().duration(r.duration).ease(r.easing)),u.attr("d",o)}else u.remove();var g=e.select("path.xerror");if(f.visible&&i(a.y)&&i(a.xh)&&i(a.xs)){var m=(f.copy_ystyle?p:f).width;o="M"+a.xh+","+(a.y-m)+"v"+2*m+"m0,-"+m+"H"+a.xs,a.noXS||(o+="m0,-"+m+"v"+2*m),!g.size()?g=e.append("path").style("vector-effect","non-scaling-stroke").classed("xerror",!0):c&&(g=g.transition().duration(r.duration).ease(r.easing)),g.attr("d",o)}else g.remove()}})}})}},{"../../traces/scatter/subtypes":1037,"../drawing":583,d3:147,"fast-isnumeric":214}],591:[function(t,e,r){"use strict";var n=t("d3"),i=t("../color");e.exports=function(t){t.each(function(t){var e=t[0].trace,r=e.error_y||{},a=e.error_x||{},o=n.select(this);o.selectAll("path.yerror").style("stroke-width",r.thickness+"px").call(i.stroke,r.color),a.copy_ystyle&&(a=r),o.selectAll("path.xerror").style("stroke-width",a.thickness+"px").call(i.stroke,a.color)})}},{"../color":558,d3:147}],592:[function(t,e,r){"use strict";var n=t("../../plots/font_attributes");e.exports={hoverlabel:{bgcolor:{valType:"color",arrayOk:!0,editType:"none"},bordercolor:{valType:"color",arrayOk:!0,editType:"none"},font:n({arrayOk:!0,editType:"none"}),namelength:{valType:"integer",min:-1,arrayOk:!0,editType:"none"},editType:"calc"}}},{"../../plots/font_attributes":758}],593:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../registry");function a(t,e,r,i){i=i||n.identity,Array.isArray(t)&&(e[0][r]=i(t))}e.exports=function(t){var e=t.calcdata,r=t._fullLayout;function o(t){return function(e){return n.coerceHoverinfo({hoverinfo:e},{_module:t._module},r)}}for(var s=0;s=0&&r.index-1&&o.length>y&&(o=y>3?o.substr(0,y-3)+"...":o.substr(0,y))}void 0!==t.zLabel?(void 0!==t.xLabel&&(c+="x: "+t.xLabel+"
"),void 0!==t.yLabel&&(c+="y: "+t.yLabel+"
"),c+=(c?"z: ":"")+t.zLabel):L&&t[i+"Label"]===M?c=t[("x"===i?"y":"x")+"Label"]||"":void 0===t.xLabel?void 0!==t.yLabel&&(c=t.yLabel):c=void 0===t.yLabel?t.xLabel:"("+t.xLabel+", "+t.yLabel+")",!t.text&&0!==t.text||Array.isArray(t.text)||(c+=(c?"
":"")+t.text),void 0!==t.extraText&&(c+=(c?"
":"")+t.extraText),""===c&&(""===o&&e.remove(),c=o);var x=e.select("text.nums").call(u.font,t.fontFamily||d,t.fontSize||g,t.fontColor||m).text(c).attr("data-notex",1).call(l.positionText,0,0).call(l.convertToTspans,r),b=e.select("text.name"),_=0;o&&o!==c?(b.call(u.font,t.fontFamily||d,t.fontSize||g,p).text(o).attr("data-notex",1).call(l.positionText,0,0).call(l.convertToTspans,r),_=b.node().getBoundingClientRect().width+2*k):(b.remove(),e.select("rect").remove()),e.select("path").style({fill:p,stroke:m});var A,T,z=x.node().getBoundingClientRect(),P=t.xa._offset+(t.x0+t.x1)/2,I=t.ya._offset+(t.y0+t.y1)/2,O=Math.abs(t.x1-t.x0),D=Math.abs(t.y1-t.y0),R=z.width+w+k+_;t.ty0=S-z.top,t.bx=z.width+2*k,t.by=z.height+2*k,t.anchor="start",t.txwidth=z.width,t.tx2width=_,t.offset=0,a?(t.pos=P,A=I+D/2+R<=C,T=I-D/2-R>=0,"top"!==t.idealAlign&&A||!T?A?(I+=D/2,t.anchor="start"):t.anchor="middle":(I-=D/2,t.anchor="end")):(t.pos=I,A=P+O/2+R<=E,T=P-O/2-R>=0,"left"!==t.idealAlign&&A||!T?A?(P+=O/2,t.anchor="start"):t.anchor="middle":(P-=O/2,t.anchor="end")),x.attr("text-anchor",t.anchor),_&&b.attr("text-anchor",t.anchor),e.attr("transform","translate("+P+","+I+")"+(a?"rotate("+v+")":""))}),R}function A(t,e){t.each(function(t){var r=n.select(this);if(t.del)r.remove();else{var i="end"===t.anchor?-1:1,a=r.select("text.nums"),o={start:1,end:-1,middle:0}[t.anchor],s=o*(w+k),c=s+o*(t.txwidth+k),h=0,f=t.offset;"middle"===t.anchor&&(s-=t.tx2width/2,c+=t.txwidth/2+k),e&&(f*=-_,h=t.offset*b),r.select("path").attr("d","middle"===t.anchor?"M-"+(t.bx/2+t.tx2width/2)+","+(f-t.by/2)+"h"+t.bx+"v"+t.by+"h-"+t.bx+"Z":"M0,0L"+(i*w+h)+","+(w+f)+"v"+(t.by/2-w)+"h"+i*t.bx+"v-"+t.by+"H"+(i*w+h)+"V"+(f-w)+"Z"),a.call(l.positionText,s+h,f+t.ty0-t.by/2+k),t.tx2width&&(r.select("text.name").call(l.positionText,c+o*k+h,f+t.ty0-t.by/2+k),r.select("rect").call(u.setRect,c+(o-1)*t.tx2width/2+h,f-t.by/2-1,t.tx2width,t.by+2))}})}function T(t,e){var r=t.index,n=t.trace||{},i=t.cd[0],a=t.cd[r]||{},s=Array.isArray(r)?function(t,e){return o.castOption(i,r,t)||o.extractOption({},n,"",e)}:function(t,e){return o.extractOption(a,n,t,e)};function l(e,r,n){var i=s(r,n);i&&(t[e]=i)}if(l("hoverinfo","hi","hoverinfo"),l("color","hbg","hoverlabel.bgcolor"),l("borderColor","hbc","hoverlabel.bordercolor"),l("fontFamily","htf","hoverlabel.font.family"),l("fontSize","hts","hoverlabel.font.size"),l("fontColor","htc","hoverlabel.font.color"),l("nameLength","hnl","hoverlabel.namelength"),t.posref="y"===e?t.xa._offset+(t.x0+t.x1)/2:t.ya._offset+(t.y0+t.y1)/2,t.x0=o.constrain(t.x0,0,t.xa._length),t.x1=o.constrain(t.x1,0,t.xa._length),t.y0=o.constrain(t.y0,0,t.ya._length),t.y1=o.constrain(t.y1,0,t.ya._length),void 0!==t.xLabelVal&&(t.xLabel="xLabel"in t?t.xLabel:p.hoverLabelText(t.xa,t.xLabelVal),t.xVal=t.xa.c2d(t.xLabelVal)),void 0!==t.yLabelVal&&(t.yLabel="yLabel"in t?t.yLabel:p.hoverLabelText(t.ya,t.yLabelVal),t.yVal=t.ya.c2d(t.yLabelVal)),void 0!==t.zLabelVal&&void 0===t.zLabel&&(t.zLabel=String(t.zLabelVal)),!(isNaN(t.xerr)||"log"===t.xa.type&&t.xerr<=0)){var c=p.tickText(t.xa,t.xa.c2l(t.xerr),"hover").text;void 0!==t.xerrneg?t.xLabel+=" +"+c+" / -"+p.tickText(t.xa,t.xa.c2l(t.xerrneg),"hover").text:t.xLabel+=" \xb1 "+c,"x"===e&&(t.distance+=1)}if(!(isNaN(t.yerr)||"log"===t.ya.type&&t.yerr<=0)){var u=p.tickText(t.ya,t.ya.c2l(t.yerr),"hover").text;void 0!==t.yerrneg?t.yLabel+=" +"+u+" / -"+p.tickText(t.ya,t.ya.c2l(t.yerrneg),"hover").text:t.yLabel+=" \xb1 "+u,"y"===e&&(t.distance+=1)}var h=t.hoverinfo||t.trace.hoverinfo;return"all"!==h&&(-1===(h=Array.isArray(h)?h:h.split("+")).indexOf("x")&&(t.xLabel=void 0),-1===h.indexOf("y")&&(t.yLabel=void 0),-1===h.indexOf("z")&&(t.zLabel=void 0),-1===h.indexOf("text")&&(t.text=void 0),-1===h.indexOf("name")&&(t.name=void 0)),t}function S(t,e){var r,n,i=e.container,o=e.fullLayout,s=e.event,l=!!t.hLinePoint,c=!!t.vLinePoint;if(i.selectAll(".spikeline").remove(),c||l){var f=h.combine(o.plot_bgcolor,o.paper_bgcolor);if(l){var p,d,g=t.hLinePoint;r=g&&g.xa,"cursor"===(n=g&&g.ya).spikesnap?(p=s.pointerX,d=s.pointerY):(p=r._offset+g.x,d=n._offset+g.y);var m,v,y=a.readability(g.color,f)<1.5?h.contrast(f):g.color,x=n.spikemode,b=n.spikethickness,_=n.spikecolor||y,w=n._boundingBox,k=(w.left+w.right)/2w[0]._length||tt<0||tt>k[0]._length)return f.unhoverRaw(t,e)}if(e.pointerX=Q+w[0]._offset,e.pointerY=tt+k[0]._offset,D="xval"in e?g.flat(l,e.xval):g.p2c(w,Q),R="yval"in e?g.flat(l,e.yval):g.p2c(k,tt),!i(D[0])||!i(R[0]))return o.warn("Fx.hover failed",e,t),f.unhoverRaw(t,e)}var nt=1/0;for(F=0;FY&&($.splice(0,Y),nt=$[0].distance),y&&0!==Z&&0===$.length){W.distance=Z,W.index=!1;var lt=j._module.hoverPoints(W,H,G,"closest",u._hoverlayer);if(lt&&(lt=lt.filter(function(t){return t.spikeDistance<=Z})),lt&<.length){var ct,ut=lt.filter(function(t){return t.xa.showspikes});if(ut.length){var ht=ut[0];i(ht.x0)&&i(ht.y0)&&(ct=gt(ht),(!K.vLinePoint||K.vLinePoint.spikeDistance>ct.spikeDistance)&&(K.vLinePoint=ct))}var ft=lt.filter(function(t){return t.ya.showspikes});if(ft.length){var pt=ft[0];i(pt.x0)&&i(pt.y0)&&(ct=gt(pt),(!K.hLinePoint||K.hLinePoint.spikeDistance>ct.spikeDistance)&&(K.hLinePoint=ct))}}}}function dt(t,e){for(var r,n=null,i=1/0,a=0;a1,Et=h.combine(u.plot_bgcolor||h.background,u.paper_bgcolor),Ct={hovermode:O,rotateLabels:St,bgColor:Et,container:u._hoverlayer,outerContainer:u._paperdiv,commonLabelOpts:u.hoverlabel,hoverdistance:u.hoverdistance},Lt=M($,Ct,t);if(function(t,e,r){var n,i,a,o,s,l,c,u=0,h=t.map(function(t,n){var i=t[e];return[{i:n,dp:0,pos:t.pos,posref:t.posref,size:t.by*("x"===i._id.charAt(0)?x:1)/2,pmin:0,pmax:"x"===i._id.charAt(0)?r.width:r.height}]}).sort(function(t,e){return t[0].posref-e[0].posref});function f(t){var e=t[0],r=t[t.length-1];if(i=e.pmin-e.pos-e.dp+e.size,a=r.pos+r.dp+r.size-e.pmax,i>.01){for(s=t.length-1;s>=0;s--)t[s].dp+=i;n=!1}if(!(a<.01)){if(i<-.01){for(s=t.length-1;s>=0;s--)t[s].dp-=a;n=!1}if(n){var c=0;for(o=0;oe.pmax&&c++;for(o=t.length-1;o>=0&&!(c<=0);o--)(l=t[o]).pos>e.pmax-1&&(l.del=!0,c--);for(o=0;o=0;s--)t[s].dp-=a;for(o=t.length-1;o>=0&&!(c<=0);o--)(l=t[o]).pos+l.dp+l.size>e.pmax&&(l.del=!0,c--)}}}for(;!n&&u<=t.length;){for(u++,n=!0,o=0;o.01&&g.pmin===m.pmin&&g.pmax===m.pmax){for(s=d.length-1;s>=0;s--)d[s].dp+=i;for(p.push.apply(p,d),h.splice(o+1,1),c=0,s=p.length-1;s>=0;s--)c+=p[s].dp;for(a=c/p.length,s=p.length-1;s>=0;s--)p[s].dp-=a;n=!1}else o++}h.forEach(f)}for(o=h.length-1;o>=0;o--){var v=h[o];for(s=v.length-1;s>=0;s--){var y=v[s],b=t[y.i];b.offset=y.dp,b.del=y.del}}}($,St?"xa":"ya",u),A(Lt,St),e.target&&e.target.tagName){var zt=d.getComponentMethod("annotations","hasClickToShow")(t,At);c(n.select(e.target),zt?"pointer":"")}if(!e.target||a||!function(t,e,r){if(!r||r.length!==t._hoverdata.length)return!0;for(var n=r.length-1;n>=0;n--){var i=r[n],a=t._hoverdata[n];if(i.curveNumber!==a.curveNumber||String(i.pointNumber)!==String(a.pointNumber))return!0}return!1}(t,0,Mt))return;Mt&&t.emit("plotly_unhover",{event:e,points:Mt});t.emit("plotly_hover",{event:e,points:t._hoverdata,xaxes:w,yaxes:k,xvals:D,yvals:R})}(t,e,r,a)})},r.loneHover=function(t,e){var r={color:t.color||h.defaultLine,x0:t.x0||t.x||0,x1:t.x1||t.x||0,y0:t.y0||t.y||0,y1:t.y1||t.y||0,xLabel:t.xLabel,yLabel:t.yLabel,zLabel:t.zLabel,text:t.text,name:t.name,idealAlign:t.idealAlign,borderColor:t.borderColor,fontFamily:t.fontFamily,fontSize:t.fontSize,fontColor:t.fontColor,trace:{index:0,hoverinfo:""},xa:{_offset:0},ya:{_offset:0},index:0},i=n.select(e.container),a=e.outerContainer?n.select(e.outerContainer):i,o={hovermode:"closest",rotateLabels:!1,bgColor:e.bgColor||h.background,container:i,outerContainer:a},s=M([r],o,e.gd);return A(s,o.rotateLabels),s.node()}},{"../../lib":684,"../../lib/events":672,"../../lib/override_cursor":695,"../../lib/svg_text_utils":708,"../../plots/cartesian/axes":732,"../../registry":817,"../color":558,"../dragelement":580,"../drawing":583,"./constants":595,"./helpers":597,d3:147,"fast-isnumeric":214,tinycolor2:499}],599:[function(t,e,r){"use strict";var n=t("../../lib");e.exports=function(t,e,r,i){r("hoverlabel.bgcolor",(i=i||{}).bgcolor),r("hoverlabel.bordercolor",i.bordercolor),r("hoverlabel.namelength",i.namelength),n.coerceFont(r,"hoverlabel.font",i.font)}},{"../../lib":684}],600:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../lib"),a=t("../dragelement"),o=t("./helpers"),s=t("./layout_attributes");e.exports={moduleType:"component",name:"fx",constants:t("./constants"),schema:{layout:s},attributes:t("./attributes"),layoutAttributes:s,supplyLayoutGlobalDefaults:t("./layout_global_defaults"),supplyDefaults:t("./defaults"),supplyLayoutDefaults:t("./layout_defaults"),calc:t("./calc"),getDistanceFunction:o.getDistanceFunction,getClosest:o.getClosest,inbox:o.inbox,quadrature:o.quadrature,appendArrayPointValue:o.appendArrayPointValue,castHoverOption:function(t,e,r){return i.castOption(t,e,"hoverlabel."+r)},castHoverinfo:function(t,e,r){return i.castOption(t,r,"hoverinfo",function(r){return i.coerceHoverinfo({hoverinfo:r},{_module:t._module},e)})},hover:t("./hover").hover,unhover:a.unhover,loneHover:t("./hover").loneHover,loneUnhover:function(t){var e=i.isD3Selection(t)?t:n.select(t);e.selectAll("g.hovertext").remove(),e.selectAll(".spikeline").remove()},click:t("./click")}},{"../../lib":684,"../dragelement":580,"./attributes":592,"./calc":593,"./click":594,"./constants":595,"./defaults":596,"./helpers":597,"./hover":598,"./layout_attributes":601,"./layout_defaults":602,"./layout_global_defaults":603,d3:147}],601:[function(t,e,r){"use strict";var n=t("./constants"),i=t("../../plots/font_attributes")({editType:"none"});i.family.dflt=n.HOVERFONT,i.size.dflt=n.HOVERFONTSIZE,e.exports={dragmode:{valType:"enumerated",values:["zoom","pan","select","lasso","orbit","turntable"],dflt:"zoom",editType:"modebar"},hovermode:{valType:"enumerated",values:["x","y","closest",!1],editType:"modebar"},hoverdistance:{valType:"integer",min:-1,dflt:20,editType:"none"},spikedistance:{valType:"integer",min:-1,dflt:20,editType:"none"},hoverlabel:{bgcolor:{valType:"color",editType:"none"},bordercolor:{valType:"color",editType:"none"},font:i,namelength:{valType:"integer",min:-1,dflt:15,editType:"none"},editType:"none"},selectdirection:{valType:"enumerated",values:["h","v","d","any"],dflt:"any",editType:"none"}}},{"../../plots/font_attributes":758,"./constants":595}],602:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("./layout_attributes");e.exports=function(t,e,r){function a(r,a){return n.coerce(t,e,i,r,a)}var o;"select"===a("dragmode")&&a("selectdirection"),e._has("cartesian")?(e._isHoriz=function(t){for(var e=!0,r=0;r1){f||p||d||"independent"===M("pattern")&&(f=!0),m._hasSubplotGrid=f;var x,b,_="top to bottom"===M("roworder"),w=f?.2:.1,k=f?.3:.1;g&&e._splomGridDflt&&(x=e._splomGridDflt.xside,b=e._splomGridDflt.yside),m._domains={x:u("x",M,w,x,y),y:u("y",M,k,b,v,_)}}else delete e.grid}function M(t,e){return n.coerce(r,m,l,t,e)}},contentDefaults:function(t,e){var r=e.grid;if(r&&r._domains){var n,i,a,o,s,l,u,f=t.grid||{},p=e._subplots,d=r._hasSubplotGrid,g=r.rows,m=r.columns,v="independent"===r.pattern,y=r._axisMap={};if(d){var x=f.subplots||[];l=r.subplots=new Array(g);var b=1;for(n=0;n=2/3},r.isCenterAnchor=function(t){return"center"===t.xanchor||"auto"===t.xanchor&&t.x>1/3&&t.x<2/3},r.isBottomAnchor=function(t){return"bottom"===t.yanchor||"auto"===t.yanchor&&t.y<=1/3},r.isMiddleAnchor=function(t){return"middle"===t.yanchor||"auto"===t.yanchor&&t.y>1/3&&t.y<2/3}},{}],611:[function(t,e,r){"use strict";var n=t("../../plots/font_attributes"),i=t("../color/attributes");e.exports={bgcolor:{valType:"color",editType:"legend"},bordercolor:{valType:"color",dflt:i.defaultLine,editType:"legend"},borderwidth:{valType:"number",min:0,dflt:0,editType:"legend"},font:n({editType:"legend"}),orientation:{valType:"enumerated",values:["v","h"],dflt:"v",editType:"legend"},traceorder:{valType:"flaglist",flags:["reversed","grouped"],extras:["normal"],editType:"legend"},tracegroupgap:{valType:"number",min:0,dflt:10,editType:"legend"},x:{valType:"number",min:-2,max:3,dflt:1.02,editType:"legend"},xanchor:{valType:"enumerated",values:["auto","left","center","right"],dflt:"left",editType:"legend"},y:{valType:"number",min:-2,max:3,dflt:1,editType:"legend"},yanchor:{valType:"enumerated",values:["auto","top","middle","bottom"],dflt:"auto",editType:"legend"},editType:"legend"}},{"../../plots/font_attributes":758,"../color/attributes":557}],612:[function(t,e,r){"use strict";e.exports={scrollBarWidth:6,scrollBarMinHeight:20,scrollBarColor:"#808BA4",scrollBarMargin:4}},{}],613:[function(t,e,r){"use strict";var n=t("../../registry"),i=t("../../lib"),a=t("../../plot_api/plot_template"),o=t("./attributes"),s=t("../../plots/layout_attributes"),l=t("./helpers");e.exports=function(t,e,r){for(var c,u,h,f,p=t.legend||{},d=0,g="normal",m=0;m1)){var y=a.newContainer(e,"legend");if(b("bgcolor",e.paper_bgcolor),b("bordercolor"),b("borderwidth"),i.coerceFont(b,"font",e.font),b("orientation"),"h"===y.orientation){var x=t.xaxis;x&&x.rangeslider&&x.rangeslider.visible?(c=0,h="left",u=1.1,f="bottom"):(c=0,h="left",u=-.1,f="top")}b("traceorder",g),l.isGrouped(e.legend)&&b("tracegroupgap"),b("x",c),b("xanchor",h),b("y",u),b("yanchor",f),i.noneOrAll(p,y,["x","y"])}function b(t,e){return i.coerce(p,y,o,t,e)}}},{"../../lib":684,"../../plot_api/plot_template":722,"../../plots/layout_attributes":786,"../../registry":817,"./attributes":611,"./helpers":617}],614:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../lib"),a=t("../../plots/plots"),o=t("../../registry"),s=t("../../lib/events"),l=t("../dragelement"),c=t("../drawing"),u=t("../color"),h=t("../../lib/svg_text_utils"),f=t("./handle_click"),p=t("./constants"),d=t("../../constants/interactions"),g=t("../../constants/alignment"),m=g.LINE_SPACING,v=g.FROM_TL,y=g.FROM_BR,x=t("./get_legend_data"),b=t("./style"),_=t("./helpers"),w=t("./anchor_utils"),k=d.DBLCLICKDELAY;function M(t,e,r,n,i){var a=r.data()[0][0].trace,o={event:i,node:r.node(),curveNumber:a.index,expandedIndex:a._expandedIndex,data:t.data,layout:t.layout,frames:t._transitionData._frames,config:t._context,fullData:t._fullData,fullLayout:t._fullLayout};if(a._group&&(o.group=a._group),"pie"===a.type&&(o.label=r.datum()[0].label),!1!==s.triggerHandler(t,"plotly_legendclick",o))if(1===n)e._clickTimeout=setTimeout(function(){f(r,t,n)},k);else if(2===n){e._clickTimeout&&clearTimeout(e._clickTimeout),t._legendMouseDownTime=0,!1!==s.triggerHandler(t,"plotly_legenddoubleclick",o)&&f(r,t,n)}}function A(t,e,r){var n=t.data()[0][0],a=e._fullLayout,s=n.trace,l=o.traceIs(s,"pie"),u=s.index,f=l?n.label:s.name,p=e._context.edits.legendText&&!l,d=i.ensureSingle(t,"text","legendtext");function g(r){h.convertToTspans(r,e,function(){!function(t,e){var r=t.data()[0][0];if(!r.trace.showlegend)return void t.remove();var n,i,a=t.select("g[class*=math-group]"),o=a.node(),s=e._fullLayout.legend.font.size*m;if(o){var l=c.bBox(o);n=l.height,i=l.width,c.setTranslate(a,0,n/4)}else{var u=t.select(".legendtext"),f=h.lineCount(u),p=u.node();n=s*f,i=p?c.bBox(p).width:0;var d=s*(.3+(1-f)/2);h.positionText(u,40,d)}n=Math.max(n,16)+3,r.height=n,r.width=i}(t,e)})}d.attr("text-anchor","start").classed("user-select-none",!0).call(c.font,a.legend.font).text(p?T(f,r):f),p?d.call(h.makeEditable,{gd:e,text:f}).call(g).on("edit",function(t){this.text(T(t,r)).call(g);var a=n.trace._fullInput||{},s={};if(o.hasTransform(a,"groupby")){var l=o.getTransformIndices(a,"groupby"),c=l[l.length-1],h=i.keyedContainer(a,"transforms["+c+"].styles","target","value.name");h.set(n.trace._group,t),s=h.constructUpdate()}else s.name=t;return o.call("restyle",e,s,u)}):g(d)}function T(t,e){var r=Math.max(4,e);if(t&&t.trim().length>=r/2)return t;for(var n=r-(t=t||"").length;n>0;n--)t+=" ";return t}function S(t,e){var r,a=1,o=i.ensureSingle(t,"rect","legendtoggle",function(t){t.style("cursor","pointer").attr("pointer-events","all").call(u.fill,"rgba(0,0,0,0)")});o.on("mousedown",function(){(r=(new Date).getTime())-e._legendMouseDownTimek&&(a=Math.max(a-1,1)),M(e,r,t,a,n.event)}})}function E(t,e,r){var i=t._fullLayout,a=i.legend,o=a.borderwidth,s=_.isGrouped(a),l=0;if(a._width=0,a._height=0,_.isVertical(a))s&&e.each(function(t,e){c.setTranslate(this,0,e*a.tracegroupgap)}),r.each(function(t){var e=t[0],r=e.height,n=e.width;c.setTranslate(this,o,5+o+a._height+r/2),a._height+=r,a._width=Math.max(a._width,n)}),a._width+=45+2*o,a._height+=10+2*o,s&&(a._height+=(a._lgroupsLength-1)*a.tracegroupgap),l=40;else if(s){for(var u=[a._width],h=e.data(),f=0,p=h.length;fo+w-k,r.each(function(t){var e=t[0],r=m?40+t[0].width:x;o+b+k+r>i.width-(i.margin.r+i.margin.l)&&(b=0,v+=y,a._height=a._height+y,y=0),c.setTranslate(this,o+b,5+o+e.height/2+v),a._width+=k+r,a._height=Math.max(a._height,e.height),b+=k+r,y=Math.max(e.height,y)}),a._width+=2*o,a._height+=10+2*o}a._width=Math.ceil(a._width),a._height=Math.ceil(a._height);var M=t._context.edits.legendText||t._context.edits.legendPosition;r.each(function(t){var e=t[0],r=n.select(this).select(".legendtoggle");c.setRect(r,0,-e.height/2,(M?0:a._width)+l,e.height)})}function C(t){var e=t._fullLayout.legend,r="left";w.isRightAnchor(e)?r="right":w.isCenterAnchor(e)&&(r="center");var n="top";w.isBottomAnchor(e)?n="bottom":w.isMiddleAnchor(e)&&(n="middle"),a.autoMargin(t,"legend",{x:e.x,y:e.y,l:e._width*v[r],r:e._width*y[r],b:e._height*y[n],t:e._height*v[n]})}e.exports=function(t){var e=t._fullLayout,r="legend"+e._uid;if(e._infolayer&&t.calcdata){t._legendMouseDownTime||(t._legendMouseDownTime=0);var s=e.legend,h=e.showlegend&&x(t.calcdata,s),f=e.hiddenlabels||[];if(!e.showlegend||!h.length)return e._infolayer.selectAll(".legend").remove(),e._topdefs.select("#"+r).remove(),void a.autoMargin(t,"legend");for(var d=0,g=0;gN?function(t){var e=t._fullLayout.legend,r="left";w.isRightAnchor(e)?r="right":w.isCenterAnchor(e)&&(r="center");a.autoMargin(t,"legend",{x:e.x,y:.5,l:e._width*v[r],r:e._width*y[r],b:0,t:0})}(t):C(t);var j=e._size,V=j.l+j.w*s.x,U=j.t+j.h*(1-s.y);w.isRightAnchor(s)?V-=s._width:w.isCenterAnchor(s)&&(V-=s._width/2),w.isBottomAnchor(s)?U-=s._height:w.isMiddleAnchor(s)&&(U-=s._height/2);var q=s._width,H=j.w;q>H?(V=j.l,q=H):(V+q>F&&(V=F-q),V<0&&(V=0),q=Math.min(F-V,s._width));var G,W,Y,X,Z=s._height,$=j.h;if(Z>$?(U=j.t,Z=$):(U+Z>N&&(U=N-Z),U<0&&(U=0),Z=Math.min(N-U,s._height)),c.setTranslate(z,V,U),D.on(".drag",null),z.on("wheel",null),s._height<=Z||t._context.staticPlot)I.attr({width:q-s.borderwidth,height:Z-s.borderwidth,x:s.borderwidth/2,y:s.borderwidth/2}),c.setTranslate(O,0,0),P.select("rect").attr({width:q-2*s.borderwidth,height:Z-2*s.borderwidth,x:s.borderwidth,y:s.borderwidth}),c.setClipUrl(O,r),c.setRect(D,0,0,0,0),delete s._scrollY;else{var J,K,Q=Math.max(p.scrollBarMinHeight,Z*Z/s._height),tt=Z-Q-2*p.scrollBarMargin,et=s._height-Z,rt=tt/et,nt=Math.min(s._scrollY||0,et);I.attr({width:q-2*s.borderwidth+p.scrollBarWidth+p.scrollBarMargin,height:Z-s.borderwidth,x:s.borderwidth/2,y:s.borderwidth/2}),P.select("rect").attr({width:q-2*s.borderwidth+p.scrollBarWidth+p.scrollBarMargin,height:Z-2*s.borderwidth,x:s.borderwidth,y:s.borderwidth+nt}),c.setClipUrl(O,r),at(nt,Q,rt),z.on("wheel",function(){at(nt=i.constrain(s._scrollY+n.event.deltaY/tt*et,0,et),Q,rt),0!==nt&&nt!==et&&n.event.preventDefault()});var it=n.behavior.drag().on("dragstart",function(){J=n.event.sourceEvent.clientY,K=nt}).on("drag",function(){var t=n.event.sourceEvent;2===t.buttons||t.ctrlKey||at(nt=i.constrain((t.clientY-J)/rt+K,0,et),Q,rt)});D.call(it)}if(t._context.edits.legendPosition)z.classed("cursor-move",!0),l.init({element:z.node(),gd:t,prepFn:function(){var t=c.getTranslate(z);Y=t.x,X=t.y},moveFn:function(t,e){var r=Y+t,n=X+e;c.setTranslate(z,r,n),G=l.align(r,0,j.l,j.l+j.w,s.xanchor),W=l.align(n,0,j.t+j.h,j.t,s.yanchor)},doneFn:function(){void 0!==G&&void 0!==W&&o.call("relayout",t,{"legend.x":G,"legend.y":W})},clickFn:function(r,n){var i=e._infolayer.selectAll("g.traces").filter(function(){var t=this.getBoundingClientRect();return n.clientX>=t.left&&n.clientX<=t.right&&n.clientY>=t.top&&n.clientY<=t.bottom});i.size()>0&&M(t,z,i,r,n)}})}function at(e,r,n){s._scrollY=t._fullLayout.legend._scrollY=e,c.setTranslate(O,0,-e),c.setRect(D,q,p.scrollBarMargin+e*n,p.scrollBarWidth,r),P.select("rect").attr({y:s.borderwidth+e})}}},{"../../constants/alignment":656,"../../constants/interactions":660,"../../lib":684,"../../lib/events":672,"../../lib/svg_text_utils":708,"../../plots/plots":795,"../../registry":817,"../color":558,"../dragelement":580,"../drawing":583,"./anchor_utils":610,"./constants":612,"./get_legend_data":615,"./handle_click":616,"./helpers":617,"./style":619,d3:147}],615:[function(t,e,r){"use strict";var n=t("../../registry"),i=t("./helpers");e.exports=function(t,e){var r,a,o={},s=[],l=!1,c={},u=0;function h(t,r){if(""!==t&&i.isGrouped(e))-1===s.indexOf(t)?(s.push(t),l=!0,o[t]=[[r]]):o[t].push([r]);else{var n="~~i"+u;s.push(n),o[n]=[[r]],u++}}for(r=0;rr[1])return r[1]}return i}function d(t){return t[0]}if(u||h||f){var g={},m={};u&&(g.mc=p("marker.color",d),g.mx=p("marker.symbol",d),g.mo=p("marker.opacity",a.mean,[.2,1]),g.ms=p("marker.size",a.mean,[2,16]),g.mlc=p("marker.line.color",d),g.mlw=p("marker.line.width",a.mean,[0,5]),m.marker={sizeref:1,sizemin:1,sizemode:"diameter"}),f&&(m.line={width:p("line.width",d,[0,10])}),h&&(g.tx="Aa",g.tp=p("textposition",d),g.ts=10,g.tc=p("textfont.color",d),g.tf=p("textfont.family",d)),r=[a.minExtend(s,g)],(i=a.minExtend(c,m)).selectedpoints=null}var v=n.select(this).select("g.legendpoints"),y=v.selectAll("path.scatterpts").data(u?r:[]);y.enter().append("path").classed("scatterpts",!0).attr("transform","translate(20,0)"),y.exit().remove(),y.call(o.pointStyle,i,e),u&&(r[0].mrc=3);var x=v.selectAll("g.pointtext").data(h?r:[]);x.enter().append("g").classed("pointtext",!0).append("text").attr("transform","translate(20,0)"),x.exit().remove(),x.selectAll("text").call(o.textPointStyle,i,e)}).each(function(t){var e=t[0].trace,r=n.select(this).select("g.legendpoints").selectAll("path.legendcandle").data("candlestick"===e.type&&e.visible?[t,t]:[]);r.enter().append("path").classed("legendcandle",!0).attr("d",function(t,e){return e?"M-15,0H-8M-8,6V-6H8Z":"M15,0H8M8,-6V6H-8Z"}).attr("transform","translate(20,0)").style("stroke-miterlimit",1),r.exit().remove(),r.each(function(t,r){var i=e[r?"increasing":"decreasing"],a=i.line.width,o=n.select(this);o.style("stroke-width",a+"px").call(s.fill,i.fillcolor),a&&s.stroke(o,i.line.color)})}).each(function(t){var e=t[0].trace,r=n.select(this).select("g.legendpoints").selectAll("path.legendohlc").data("ohlc"===e.type&&e.visible?[t,t]:[]);r.enter().append("path").classed("legendohlc",!0).attr("d",function(t,e){return e?"M-15,0H0M-8,-6V0":"M15,0H0M8,6V0"}).attr("transform","translate(20,0)").style("stroke-miterlimit",1),r.exit().remove(),r.each(function(t,r){var i=e[r?"increasing":"decreasing"],a=i.line.width,l=n.select(this);l.style("fill","none").call(o.dashLine,i.line.dash,a),a&&s.stroke(l,i.line.color)})})}},{"../../lib":684,"../../registry":817,"../../traces/pie/style_one":1001,"../../traces/scatter/subtypes":1037,"../color":558,"../drawing":583,d3:147}],620:[function(t,e,r){"use strict";var n=t("../../registry"),i=t("../../plots/plots"),a=t("../../plots/cartesian/axis_ids"),o=t("../../lib"),s=t("../../../build/ploticon"),l=o._,c=e.exports={};function u(t,e){var r,i,o=e.currentTarget,s=o.getAttribute("data-attr"),l=o.getAttribute("data-val")||!0,c=t._fullLayout,u={},h=a.list(t,null,!0),f="on";if("zoom"===s){var p,d="in"===l?.5:2,g=(1+d)/2,m=(1-d)/2;for(i=0;i1?(_=["toggleHover"],w=["resetViews"]):h?(b=["zoomInGeo","zoomOutGeo"],_=["hoverClosestGeo"],w=["resetGeo"]):u?(_=["hoverClosest3d"],w=["resetCameraDefault3d","resetCameraLastSave3d"]):g?(_=["toggleHover"],w=["resetViewMapbox"]):_=p?["hoverClosestGl2d"]:f?["hoverClosestPie"]:["toggleHover"];c&&(_=["toggleSpikelines","hoverClosestCartesian","hoverCompareCartesian"]);!c&&!p||v||(b=["zoomIn2d","zoomOut2d","autoScale2d"],"resetViews"!==w[0]&&(w=["resetScale2d"]));u?k=["zoom3d","pan3d","orbitRotation","tableRotation"]:(c||p)&&!v||d?k=["zoom2d","pan2d"]:g||h?k=["pan2d"]:m&&(k=["zoom2d"]);(function(t){for(var e=!1,r=0;r0)){var g=function(t,e,r){for(var n=r.filter(function(r){return e[r].anchor===t._id}),i=0,a=0;a0?f+c:c;return{ppad:c,ppadplus:u?d:g,ppadminus:u?g:d}}return{ppad:c}}function u(t,e,r,n,i){var s="category"===t.type?t.r2c:t.d2c;if(void 0!==e)return[s(e),s(r)];if(n){var l,c,u,h,f=1/0,p=-1/0,d=n.match(a.segmentRE);for("date"===t.type&&(s=o.decodeDate(s)),l=0;lp&&(p=h)));return p>=f?[f,p]:void 0}}e.exports=function(t){var e=t._fullLayout,r=n.filterVisible(e.shapes);if(r.length&&t._fullData.length)for(var o=0;o10?t/2:10;return n.append("circle").attr({"data-line-point":"start-point",cx:D?q(r.xanchor)+r.x0:q(r.x0),cy:R?H(r.yanchor)-r.y0:H(r.y0),r:a}).style(i).classed("cursor-grab",!0),n.append("circle").attr({"data-line-point":"end-point",cx:D?q(r.xanchor)+r.x1:q(r.x1),cy:R?H(r.yanchor)-r.y1:H(r.y1),r:a}).style(i).classed("cursor-grab",!0),n}():e,X={element:Y.node(),gd:t,prepFn:function(n){D&&(_=q(r.xanchor));R&&(w=H(r.yanchor));"path"===r.type?z=r.path:(v=D?r.x0:q(r.x0),y=R?r.y0:H(r.y0),x=D?r.x1:q(r.x1),b=R?r.y1:H(r.y1));vb?(k=y,S="y0",M=b,E="y1"):(k=b,S="y1",M=y,E="y0");Z(n),K(p,r),function(t,e,r){var n=e.xref,i=e.yref,o=a.getFromId(r,n),l=a.getFromId(r,i),c="";"paper"===n||o.autorange||(c+=n);"paper"===i||l.autorange||(c+=i);t.call(s.setClipUrl,c?"clip"+r._fullLayout._uid+c:null)}(e,r,t),X.moveFn="move"===P?$:J},doneFn:function(){u(e),Q(p),d(e,t,r),n.call("relayout",t,N.getUpdateObj())},clickFn:function(){Q(p)}};function Z(t){if(B)P="path"===t.target.tagName?"move":"start-point"===t.target.attributes["data-line-point"].value?"resize-over-start-point":"resize-over-end-point";else{var r=X.element.getBoundingClientRect(),n=r.right-r.left,i=r.bottom-r.top,a=t.clientX-r.left,o=t.clientY-r.top,s=!F&&n>I&&i>O&&!t.shiftKey?c.getCursor(a/n,1-o/i):"move";u(e,s),P=s.split("-")[0]}}function $(n,i){if("path"===r.type){var a=function(t){return t},o=a,s=a;D?j("xanchor",r.xanchor=G(_+n)):(o=function(t){return G(q(t)+n)},V&&"date"===V.type&&(o=f.encodeDate(o))),R?j("yanchor",r.yanchor=W(w+i)):(s=function(t){return W(H(t)+i)},U&&"date"===U.type&&(s=f.encodeDate(s))),j("path",r.path=m(z,o,s))}else D?j("xanchor",r.xanchor=G(_+n)):(j("x0",r.x0=G(v+n)),j("x1",r.x1=G(x+n))),R?j("yanchor",r.yanchor=W(w+i)):(j("y0",r.y0=W(y+i)),j("y1",r.y1=W(b+i)));e.attr("d",g(t,r)),K(p,r)}function J(n,i){if(F){var a=function(t){return t},o=a,s=a;D?j("xanchor",r.xanchor=G(_+n)):(o=function(t){return G(q(t)+n)},V&&"date"===V.type&&(o=f.encodeDate(o))),R?j("yanchor",r.yanchor=W(w+i)):(s=function(t){return W(H(t)+i)},U&&"date"===U.type&&(s=f.encodeDate(s))),j("path",r.path=m(z,o,s))}else if(B){if("resize-over-start-point"===P){var l=v+n,c=R?y-i:y+i;j("x0",r.x0=D?l:G(l)),j("y0",r.y0=R?c:W(c))}else if("resize-over-end-point"===P){var u=x+n,h=R?b-i:b+i;j("x1",r.x1=D?u:G(u)),j("y1",r.y1=R?h:W(h))}}else{var d=~P.indexOf("n")?k+i:k,N=~P.indexOf("s")?M+i:M,Y=~P.indexOf("w")?A+n:A,X=~P.indexOf("e")?T+n:T;~P.indexOf("n")&&R&&(d=k-i),~P.indexOf("s")&&R&&(N=M-i),(!R&&N-d>O||R&&d-N>O)&&(j(S,r[S]=R?d:W(d)),j(E,r[E]=R?N:W(N))),X-Y>I&&(j(C,r[C]=D?Y:G(Y)),j(L,r[L]=D?X:G(X)))}e.attr("d",g(t,r)),K(p,r)}function K(t,e){(D||R)&&function(){var r="path"!==e.type,n=t.selectAll(".visual-cue").data([0]);n.enter().append("path").attr({fill:"#fff","fill-rule":"evenodd",stroke:"#000","stroke-width":1}).classed("visual-cue",!0);var a=q(D?e.xanchor:i.midRange(r?[e.x0,e.x1]:f.extractPathCoords(e.path,h.paramIsX))),o=H(R?e.yanchor:i.midRange(r?[e.y0,e.y1]:f.extractPathCoords(e.path,h.paramIsY)));if(a=f.roundPositionForSharpStrokeRendering(a,1),o=f.roundPositionForSharpStrokeRendering(o,1),D&&R){var s="M"+(a-1-1)+","+(o-1-1)+"h-8v2h8 v8h2v-8 h8v-2h-8 v-8h-2 Z";n.attr("d",s)}else if(D){var l="M"+(a-1-1)+","+(o-9-1)+"v18 h2 v-18 Z";n.attr("d",l)}else{var c="M"+(a-9-1)+","+(o-1-1)+"h18 v2 h-18 Z";n.attr("d",c)}}()}function Q(t){t.selectAll(".visual-cue").remove()}c.init(X),Y.node().onmousemove=Z}(t,x,r,e,p)}}function d(t,e,r){var n=(r.xref+r.yref).replace(/paper/g,"");t.call(s.setClipUrl,n?"clip"+e._fullLayout._uid+n:null)}function g(t,e){var r,n,o,s,l,c,u,p,d=e.type,g=a.getFromId(t,e.xref),m=a.getFromId(t,e.yref),v=t._fullLayout._size;if(g?(r=f.shapePositionToRange(g),n=function(t){return g._offset+g.r2p(r(t,!0))}):n=function(t){return v.l+v.w*t},m?(o=f.shapePositionToRange(m),s=function(t){return m._offset+m.r2p(o(t,!0))}):s=function(t){return v.t+v.h*(1-t)},"path"===d)return g&&"date"===g.type&&(n=f.decodeDate(n)),m&&"date"===m.type&&(s=f.decodeDate(s)),function(t,e,r){var n=t.path,a=t.xsizemode,o=t.ysizemode,s=t.xanchor,l=t.yanchor;return n.replace(h.segmentRE,function(t){var n=0,c=t.charAt(0),u=h.paramIsX[c],f=h.paramIsY[c],p=h.numParams[c],d=t.substr(1).replace(h.paramRE,function(t){return u[n]?t="pixel"===a?e(s)+Number(t):e(t):f[n]&&(t="pixel"===o?r(l)-Number(t):r(t)),++n>p&&(t="X"),t});return n>p&&(d=d.replace(/[\s,]*X.*/,""),i.log("Ignoring extra params in segment "+t)),c+d})}(e,n,s);if("pixel"===e.xsizemode){var y=n(e.xanchor);l=y+e.x0,c=y+e.x1}else l=n(e.x0),c=n(e.x1);if("pixel"===e.ysizemode){var x=s(e.yanchor);u=x-e.y0,p=x-e.y1}else u=s(e.y0),p=s(e.y1);if("line"===d)return"M"+l+","+u+"L"+c+","+p;if("rect"===d)return"M"+l+","+u+"H"+c+"V"+p+"H"+l+"Z";var b=(l+c)/2,_=(u+p)/2,w=Math.abs(b-l),k=Math.abs(_-u),M="A"+w+","+k,A=b+w+","+_;return"M"+A+M+" 0 1,1 "+(b+","+(_-k))+M+" 0 0,1 "+A+"Z"}function m(t,e,r){return t.replace(h.segmentRE,function(t){var n=0,i=t.charAt(0),a=h.paramIsX[i],o=h.paramIsY[i],s=h.numParams[i];return i+t.substr(1).replace(h.paramRE,function(t){return n>=s?t:(a[n]?t=e(t):o[n]&&(t=r(t)),n++,t)})})}e.exports={draw:function(t){var e=t._fullLayout;for(var r in e._shapeUpperLayer.selectAll("path").remove(),e._shapeLowerLayer.selectAll("path").remove(),e._plots){var n=e._plots[r].shapelayer;n&&n.selectAll("path").remove()}for(var i=0;i0&&(s=s.transition().duration(e.transition.duration).ease(e.transition.easing)),s.attr("transform","translate("+(o-.5*h.gripWidth)+","+e._dims.currentValueTotalHeight+")")}}function E(t,e){var r=t._dims;return r.inputAreaStart+h.stepInset+(r.inputAreaLength-2*h.stepInset)*Math.min(1,Math.max(0,e))}function C(t,e){var r=t._dims;return Math.min(1,Math.max(0,(e-h.stepInset-r.inputAreaStart)/(r.inputAreaLength-2*h.stepInset-2*r.inputAreaStart)))}function L(t,e,r){var n=r._dims,i=s.ensureSingle(t,"rect",h.railTouchRectClass,function(n){n.call(A,e,t,r).style("pointer-events","all")});i.attr({width:n.inputAreaLength,height:Math.max(n.inputAreaWidth,h.tickOffset+r.ticklen+n.labelHeight)}).call(a.fill,r.bgcolor).attr("opacity",0),o.setTranslate(i,0,n.currentValueTotalHeight)}function z(t,e){var r=e._dims,n=r.inputAreaLength-2*h.railInset,i=s.ensureSingle(t,"rect",h.railRectClass);i.attr({width:n,height:h.railWidth,rx:h.railRadius,ry:h.railRadius,"shape-rendering":"crispEdges"}).call(a.stroke,e.bordercolor).call(a.fill,e.bgcolor).style("stroke-width",e.borderwidth+"px"),o.setTranslate(i,h.railInset,.5*(r.inputAreaWidth-h.railWidth)+r.currentValueTotalHeight)}e.exports=function(t){var e=t._fullLayout,r=function(t,e){for(var r=t[h.name],n=[],i=0;i0?[0]:[]);function s(e){e._commandObserver&&(e._commandObserver.remove(),delete e._commandObserver),i.autoMargin(t,m(e))}if(a.enter().append("g").classed(h.containerClassName,!0).style("cursor","ew-resize"),a.exit().each(function(){n.select(this).selectAll("g."+h.groupClassName).each(s)}).remove(),0!==r.length){var l=a.selectAll("g."+h.groupClassName).data(r,v);l.enter().append("g").classed(h.groupClassName,!0),l.exit().each(s).remove();for(var c=0;c0||f<0){var g={left:[-r,0],right:[r,0],top:[0,-r],bottom:[0,r]}[y.side];e.attr("transform","translate("+g+")")}}}P.call(I),L&&(C?P.on(".opacity",null):(S=0,E=!0,P.text(m).on("mouseover.opacity",function(){n.select(this).transition().duration(h.SHOW_PLACEHOLDER).style("opacity",1)}).on("mouseout.opacity",function(){n.select(this).transition().duration(h.HIDE_PLACEHOLDER).style("opacity",0)})),P.call(u.makeEditable,{gd:t}).on("edit",function(e){void 0!==v?o.call("restyle",t,g,e,v):o.call("relayout",t,g,e)}).on("cancel",function(){this.text(this.attr("data-unformatted")).call(I)}).on("input",function(t){this.text(t||" ").call(u.positionText,x.x,x.y)}));return P.classed("js-placeholder",E),_}};var f=/ [XY][0-9]* /},{"../../constants/interactions":660,"../../lib":684,"../../lib/svg_text_utils":708,"../../plots/plots":795,"../../registry":817,"../color":558,"../drawing":583,d3:147,"fast-isnumeric":214}],650:[function(t,e,r){"use strict";var n=t("../../plots/font_attributes"),i=t("../color/attributes"),a=t("../../lib/extend").extendFlat,o=t("../../plot_api/edit_types").overrideAll,s=t("../../plots/pad_attributes"),l=t("../../plot_api/plot_template").templatedArray,c=l("button",{visible:{valType:"boolean"},method:{valType:"enumerated",values:["restyle","relayout","animate","update","skip"],dflt:"restyle"},args:{valType:"info_array",freeLength:!0,items:[{valType:"any"},{valType:"any"},{valType:"any"}]},label:{valType:"string",dflt:""},execute:{valType:"boolean",dflt:!0}});e.exports=o(l("updatemenu",{_arrayAttrRegexps:[/^updatemenus\[(0|[1-9][0-9]+)\]\.buttons/],visible:{valType:"boolean"},type:{valType:"enumerated",values:["dropdown","buttons"],dflt:"dropdown"},direction:{valType:"enumerated",values:["left","right","up","down"],dflt:"down"},active:{valType:"integer",min:-1,dflt:0},showactive:{valType:"boolean",dflt:!0},buttons:c,x:{valType:"number",min:-2,max:3,dflt:-.05},xanchor:{valType:"enumerated",values:["auto","left","center","right"],dflt:"right"},y:{valType:"number",min:-2,max:3,dflt:1},yanchor:{valType:"enumerated",values:["auto","top","middle","bottom"],dflt:"top"},pad:a({},s,{}),font:n({}),bgcolor:{valType:"color"},bordercolor:{valType:"color",dflt:i.borderLine},borderwidth:{valType:"number",min:0,dflt:1,editType:"arraydraw"}}),"arraydraw","from-root")},{"../../lib/extend":673,"../../plot_api/edit_types":715,"../../plot_api/plot_template":722,"../../plots/font_attributes":758,"../../plots/pad_attributes":794,"../color/attributes":557}],651:[function(t,e,r){"use strict";e.exports={name:"updatemenus",containerClassName:"updatemenu-container",headerGroupClassName:"updatemenu-header-group",headerClassName:"updatemenu-header",headerArrowClassName:"updatemenu-header-arrow",dropdownButtonGroupClassName:"updatemenu-dropdown-button-group",dropdownButtonClassName:"updatemenu-dropdown-button",buttonClassName:"updatemenu-button",itemRectClassName:"updatemenu-item-rect",itemTextClassName:"updatemenu-item-text",menuIndexAttrName:"updatemenu-active-index",autoMarginIdRoot:"updatemenu-",blankHeaderOpts:{label:" "},minWidth:30,minHeight:30,textPadX:24,arrowPadX:16,rx:2,ry:2,textOffsetX:12,textOffsetY:3,arrowOffsetX:4,gapButtonHeader:5,gapButton:2,activeColor:"#F4FAFF",hoverColor:"#F4FAFF",arrowSymbol:{left:"\u25c4",right:"\u25ba",up:"\u25b2",down:"\u25bc"}}},{}],652:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../plots/array_container_defaults"),a=t("./attributes"),o=t("./constants").name,s=a.buttons;function l(t,e,r){function o(r,i){return n.coerce(t,e,a,r,i)}o("visible",i(t,e,{name:"buttons",handleItemDefaults:c}).length>0)&&(o("active"),o("direction"),o("type"),o("showactive"),o("x"),o("y"),n.noneOrAll(t,e,["x","y"]),o("xanchor"),o("yanchor"),o("pad.t"),o("pad.r"),o("pad.b"),o("pad.l"),n.coerceFont(o,"font",r.font),o("bgcolor",r.paper_bgcolor),o("bordercolor"),o("borderwidth"))}function c(t,e){function r(r,i){return n.coerce(t,e,s,r,i)}r("visible","skip"===t.method||Array.isArray(t.args))&&(r("method"),r("args"),r("label"),r("execute"))}e.exports=function(t,e){i(t,e,{name:o,handleItemDefaults:l})}},{"../../lib":684,"../../plots/array_container_defaults":728,"./attributes":650,"./constants":651}],653:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../plots/plots"),a=t("../color"),o=t("../drawing"),s=t("../../lib"),l=t("../../lib/svg_text_utils"),c=t("../legend/anchor_utils"),u=t("../../plot_api/plot_template").arrayEditor,h=t("../../constants/alignment").LINE_SPACING,f=t("./constants"),p=t("./scrollbox");function d(t){return t._index}function g(t,e){return+t.attr(f.menuIndexAttrName)===e._index}function m(t,e,r,n,i,a,o,s){e.active=o,u(t.layout,f.name,e).applyUpdate("active",o),"buttons"===e.type?y(t,n,null,null,e):"dropdown"===e.type&&(i.attr(f.menuIndexAttrName,"-1"),v(t,n,i,a,e),s||y(t,n,i,a,e))}function v(t,e,r,n,i){var a=s.ensureSingle(e,"g",f.headerClassName,function(t){t.style("pointer-events","all")}),l=i._dims,c=i.active,u=i.buttons[c]||f.blankHeaderOpts,h={y:i.pad.t,yPad:0,x:i.pad.l,xPad:0,index:0},p={width:l.headerWidth,height:l.headerHeight};a.call(x,i,u,t).call(S,i,h,p),s.ensureSingle(e,"text",f.headerArrowClassName,function(t){t.classed("user-select-none",!0).attr("text-anchor","end").call(o.font,i.font).text(f.arrowSymbol[i.direction])}).attr({x:l.headerWidth-f.arrowOffsetX+i.pad.l,y:l.headerHeight/2+f.textOffsetY+i.pad.t}),a.on("click",function(){r.call(E,String(g(r,i)?-1:i._index)),y(t,e,r,n,i)}),a.on("mouseover",function(){a.call(k)}),a.on("mouseout",function(){a.call(M,i)}),o.setTranslate(e,l.lx,l.ly)}function y(t,e,r,a,o){r||(r=e).attr("pointer-events","all");var l=function(t){return-1==+t.attr(f.menuIndexAttrName)}(r)&&"buttons"!==o.type?[]:o.buttons,c="dropdown"===o.type?f.dropdownButtonClassName:f.buttonClassName,u=r.selectAll("g."+c).data(s.filterVisible(l)),h=u.enter().append("g").classed(c,!0),p=u.exit();"dropdown"===o.type?(h.attr("opacity","0").transition().attr("opacity","1"),p.transition().attr("opacity","0").remove()):p.remove();var d=0,g=0,v=o._dims,y=-1!==["up","down"].indexOf(o.direction);"dropdown"===o.type&&(y?g=v.headerHeight+f.gapButtonHeader:d=v.headerWidth+f.gapButtonHeader),"dropdown"===o.type&&"up"===o.direction&&(g=-f.gapButtonHeader+f.gapButton-v.openHeight),"dropdown"===o.type&&"left"===o.direction&&(d=-f.gapButtonHeader+f.gapButton-v.openWidth);var b={x:v.lx+d+o.pad.l,y:v.ly+g+o.pad.t,yPad:f.gapButton,xPad:f.gapButton,index:0},_={l:b.x+o.borderwidth,t:b.y+o.borderwidth};u.each(function(s,l){var c=n.select(this);c.call(x,o,s,t).call(S,o,b),c.on("click",function(){n.event.defaultPrevented||(m(t,o,0,e,r,a,l),s.execute&&i.executeAPICommand(t,s.method,s.args),t.emit("plotly_buttonclicked",{menu:o,button:s,active:o.active}))}),c.on("mouseover",function(){c.call(k)}),c.on("mouseout",function(){c.call(M,o),u.call(w,o)})}),u.call(w,o),y?(_.w=Math.max(v.openWidth,v.headerWidth),_.h=b.y-_.t):(_.w=b.x-_.l,_.h=Math.max(v.openHeight,v.headerHeight)),_.direction=o.direction,a&&(u.size()?function(t,e,r,n,i,a){var o,s,l,c=i.direction,u="up"===c||"down"===c,h=i._dims,p=i.active;if(u)for(s=0,l=0;l0?[0]:[]);if(o.enter().append("g").classed(f.containerClassName,!0).style("cursor","pointer"),o.exit().each(function(){n.select(this).selectAll("g."+f.headerGroupClassName).each(a)}).remove(),0!==r.length){var l=o.selectAll("g."+f.headerGroupClassName).data(r,d);l.enter().append("g").classed(f.headerGroupClassName,!0);for(var c=s.ensureSingle(o,"g",f.dropdownButtonGroupClassName,function(t){t.style("pointer-events","all")}),u=0;uw,A=s.barLength+2*s.barPad,T=s.barWidth+2*s.barPad,S=d,E=m+v;E+T>c&&(E=c-T);var C=this.container.selectAll("rect.scrollbar-horizontal").data(M?[0]:[]);C.exit().on(".drag",null).remove(),C.enter().append("rect").classed("scrollbar-horizontal",!0).call(i.fill,s.barColor),M?(this.hbar=C.attr({rx:s.barRadius,ry:s.barRadius,x:S,y:E,width:A,height:T}),this._hbarXMin=S+A/2,this._hbarTranslateMax=w-A):(delete this.hbar,delete this._hbarXMin,delete this._hbarTranslateMax);var L=v>k,z=s.barWidth+2*s.barPad,P=s.barLength+2*s.barPad,I=d+g,O=m;I+z>l&&(I=l-z);var D=this.container.selectAll("rect.scrollbar-vertical").data(L?[0]:[]);D.exit().on(".drag",null).remove(),D.enter().append("rect").classed("scrollbar-vertical",!0).call(i.fill,s.barColor),L?(this.vbar=D.attr({rx:s.barRadius,ry:s.barRadius,x:I,y:O,width:z,height:P}),this._vbarYMin=O+P/2,this._vbarTranslateMax=k-P):(delete this.vbar,delete this._vbarYMin,delete this._vbarTranslateMax);var R=this.id,B=u-.5,F=L?h+z+.5:h+.5,N=f-.5,j=M?p+T+.5:p+.5,V=o._topdefs.selectAll("#"+R).data(M||L?[0]:[]);if(V.exit().remove(),V.enter().append("clipPath").attr("id",R).append("rect"),M||L?(this._clipRect=V.select("rect").attr({x:Math.floor(B),y:Math.floor(N),width:Math.ceil(F)-Math.floor(B),height:Math.ceil(j)-Math.floor(N)}),this.container.call(a.setClipUrl,R),this.bg.attr({x:d,y:m,width:g,height:v})):(this.bg.attr({width:0,height:0}),this.container.on("wheel",null).on(".drag",null).call(a.setClipUrl,null),delete this._clipRect),M||L){var U=n.behavior.drag().on("dragstart",function(){n.event.sourceEvent.preventDefault()}).on("drag",this._onBoxDrag.bind(this));this.container.on("wheel",null).on("wheel",this._onBoxWheel.bind(this)).on(".drag",null).call(U);var q=n.behavior.drag().on("dragstart",function(){n.event.sourceEvent.preventDefault(),n.event.sourceEvent.stopPropagation()}).on("drag",this._onBarDrag.bind(this));M&&this.hbar.on(".drag",null).call(q),L&&this.vbar.on(".drag",null).call(q)}this.setTranslate(e,r)},s.prototype.disable=function(){(this.hbar||this.vbar)&&(this.bg.attr({width:0,height:0}),this.container.on("wheel",null).on(".drag",null).call(a.setClipUrl,null),delete this._clipRect),this.hbar&&(this.hbar.on(".drag",null),this.hbar.remove(),delete this.hbar,delete this._hbarXMin,delete this._hbarTranslateMax),this.vbar&&(this.vbar.on(".drag",null),this.vbar.remove(),delete this.vbar,delete this._vbarYMin,delete this._vbarTranslateMax)},s.prototype._onBoxDrag=function(){var t=this.translateX,e=this.translateY;this.hbar&&(t-=n.event.dx),this.vbar&&(e-=n.event.dy),this.setTranslate(t,e)},s.prototype._onBoxWheel=function(){var t=this.translateX,e=this.translateY;this.hbar&&(t+=n.event.deltaY),this.vbar&&(e+=n.event.deltaY),this.setTranslate(t,e)},s.prototype._onBarDrag=function(){var t=this.translateX,e=this.translateY;if(this.hbar){var r=t+this._hbarXMin,i=r+this._hbarTranslateMax;t=(o.constrain(n.event.x,r,i)-r)/(i-r)*(this.position.w-this._box.w)}if(this.vbar){var a=e+this._vbarYMin,s=a+this._vbarTranslateMax;e=(o.constrain(n.event.y,a,s)-a)/(s-a)*(this.position.h-this._box.h)}this.setTranslate(t,e)},s.prototype.setTranslate=function(t,e){var r=this.position.w-this._box.w,n=this.position.h-this._box.h;if(t=o.constrain(t||0,0,r),e=o.constrain(e||0,0,n),this.translateX=t,this.translateY=e,this.container.call(a.setTranslate,this._box.l-this.position.l-t,this._box.t-this.position.t-e),this._clipRect&&this._clipRect.attr({x:Math.floor(this.position.l+t-.5),y:Math.floor(this.position.t+e-.5)}),this.hbar){var i=t/r;this.hbar.call(a.setTranslate,t+i*this._hbarTranslateMax,e)}if(this.vbar){var s=e/n;this.vbar.call(a.setTranslate,t,e+s*this._vbarTranslateMax)}}},{"../../lib":684,"../color":558,"../drawing":583,d3:147}],656:[function(t,e,r){"use strict";e.exports={FROM_BL:{left:0,center:.5,right:1,bottom:0,middle:.5,top:1},FROM_TL:{left:0,center:.5,right:1,bottom:1,middle:.5,top:0},FROM_BR:{left:1,center:.5,right:0,bottom:0,middle:.5,top:1},LINE_SPACING:1.3,MID_SHIFT:.35,OPPOSITE_SIDE:{left:"right",right:"left",top:"bottom",bottom:"top"}}},{}],657:[function(t,e,r){"use strict";e.exports={COMPARISON_OPS:["=","!=","<",">=",">","<="],COMPARISON_OPS2:["=","<",">=",">","<="],INTERVAL_OPS:["[]","()","[)","(]","][",")(","](",")["],SET_OPS:["{}","}{"],CONSTRAINT_REDUCTION:{"=":"=","<":"<","<=":"<",">":">",">=":">","[]":"[]","()":"[]","[)":"[]","(]":"[]","][":"][",")(":"][","](":"][",")[":"]["}}},{}],658:[function(t,e,r){"use strict";e.exports={solid:[[],0],dot:[[.5,1],200],dash:[[.5,1],50],longdash:[[.5,1],10],dashdot:[[.5,.625,.875,1],50],longdashdot:[[.5,.7,.8,1],10]}},{}],659:[function(t,e,r){"use strict";e.exports={circle:"\u25cf","circle-open":"\u25cb",square:"\u25a0","square-open":"\u25a1",diamond:"\u25c6","diamond-open":"\u25c7",cross:"+",x:"\u274c"}},{}],660:[function(t,e,r){"use strict";e.exports={SHOW_PLACEHOLDER:100,HIDE_PLACEHOLDER:1e3,DBLCLICKDELAY:300,DESELECTDIM:.2}},{}],661:[function(t,e,r){"use strict";e.exports={BADNUM:void 0,FP_SAFE:Number.MAX_VALUE/1e4,ONEAVGYEAR:315576e5,ONEAVGMONTH:26298e5,ONEDAY:864e5,ONEHOUR:36e5,ONEMIN:6e4,ONESEC:1e3,EPOCHJD:2440587.5,ALMOST_EQUAL:1-1e-6,MINUS_SIGN:"\u2212"}},{}],662:[function(t,e,r){"use strict";e.exports={entityToUnicode:{mu:"\u03bc","#956":"\u03bc",amp:"&","#28":"&",lt:"<","#60":"<",gt:">","#62":">",nbsp:"\xa0","#160":"\xa0",times:"\xd7","#215":"\xd7",plusmn:"\xb1","#177":"\xb1",deg:"\xb0","#176":"\xb0"}}},{}],663:[function(t,e,r){"use strict";r.xmlns="http://www.w3.org/2000/xmlns/",r.svg="http://www.w3.org/2000/svg",r.xlink="http://www.w3.org/1999/xlink",r.svgAttrs={xmlns:r.svg,"xmlns:xlink":r.xlink}},{}],664:[function(t,e,r){"use strict";r.version="1.39.3",t("es6-promise").polyfill(),t("../build/plotcss"),t("./fonts/mathjax_config");for(var n=t("./registry"),i=r.register=n.register,a=t("./plot_api"),o=Object.keys(a),s=0;s180&&(t-=360*Math.round(t/360)),t}},{}],667:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../constants/numerical").BADNUM,a=/^['"%,$#\s']+|[, ]|['"%,$#\s']+$/g;e.exports=function(t){return"string"==typeof t&&(t=t.replace(a,"")),n(t)?Number(t):i}},{"../constants/numerical":661,"fast-isnumeric":214}],668:[function(t,e,r){"use strict";e.exports=function(t){var e=t._fullLayout;e._glcanvas&&e._glcanvas.size()&&e._glcanvas.each(function(t){t.regl&&t.regl.clear({color:!0,depth:!0})})}},{}],669:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("tinycolor2"),a=t("../plots/attributes"),o=t("../components/colorscale/get_scale"),s=(Object.keys(t("../components/colorscale/scales")),t("./nested_property")),l=t("./regex").counter,c=t("../constants/interactions").DESELECTDIM,u=t("./angles").wrap180,h=t("./is_array").isArrayOrTypedArray;function f(t,e){var n=r.valObjectMeta[e.valType];if(e.arrayOk&&h(t))return!0;if(n.validateFunction)return n.validateFunction(t,e);var i={},a=i,o={set:function(t){a=t}};return n.coerceFunction(t,o,i,e),a!==i}r.valObjectMeta={data_array:{coerceFunction:function(t,e,r){h(t)?e.set(t):void 0!==r&&e.set(r)}},enumerated:{coerceFunction:function(t,e,r,n){n.coerceNumber&&(t=+t),-1===n.values.indexOf(t)?e.set(r):e.set(t)},validateFunction:function(t,e){e.coerceNumber&&(t=+t);for(var r=e.values,n=0;ni.max?e.set(r):e.set(+t)}},integer:{coerceFunction:function(t,e,r,i){t%1||!n(t)||void 0!==i.min&&ti.max?e.set(r):e.set(+t)}},string:{coerceFunction:function(t,e,r,n){if("string"!=typeof t){var i="number"==typeof t;!0!==n.strict&&i?e.set(String(t)):e.set(r)}else n.noBlank&&!t?e.set(r):e.set(t)}},color:{coerceFunction:function(t,e,r){i(t).isValid()?e.set(t):e.set(r)}},colorlist:{coerceFunction:function(t,e,r){Array.isArray(t)&&t.length&&t.every(function(t){return i(t).isValid()})?e.set(t):e.set(r)}},colorscale:{coerceFunction:function(t,e,r){e.set(o(t,r))}},angle:{coerceFunction:function(t,e,r){"auto"===t?e.set("auto"):n(t)?e.set(u(+t)):e.set(r)}},subplotid:{coerceFunction:function(t,e,r,n){var i=n.regex||l(r);"string"==typeof t&&i.test(t)?e.set(t):e.set(r)},validateFunction:function(t,e){var r=e.dflt;return t===r||"string"==typeof t&&!!l(r).test(t)}},flaglist:{coerceFunction:function(t,e,r,n){if("string"==typeof t)if(-1===(n.extras||[]).indexOf(t)){for(var i=t.split("+"),a=0;a=n&&t<=i?t:u}if("string"!=typeof t&&"number"!=typeof t)return u;t=String(t);var c=_(e),v=t.charAt(0);!c||"G"!==v&&"g"!==v||(t=t.substr(1),e="");var w=c&&"chinese"===e.substr(0,7),k=t.match(w?x:y);if(!k)return u;var M=k[1],A=k[3]||"1",T=Number(k[5]||1),S=Number(k[7]||0),E=Number(k[9]||0),C=Number(k[11]||0);if(c){if(2===M.length)return u;var L;M=Number(M);try{var z=m.getComponentMethod("calendars","getCal")(e);if(w){var P="i"===A.charAt(A.length-1);A=parseInt(A,10),L=z.newDate(M,z.toMonthIndex(M,A,P),T)}else L=z.newDate(M,Number(A),T)}catch(t){return u}return L?(L.toJD()-g)*h+S*f+E*p+C*d:u}M=2===M.length?(Number(M)+2e3-b)%100+b:Number(M),A-=1;var I=new Date(Date.UTC(2e3,A,T,S,E));return I.setUTCFullYear(M),I.getUTCMonth()!==A?u:I.getUTCDate()!==T?u:I.getTime()+C*d},n=r.MIN_MS=r.dateTime2ms("-9999"),i=r.MAX_MS=r.dateTime2ms("9999-12-31 23:59:59.9999"),r.isDateTime=function(t,e){return r.dateTime2ms(t,e)!==u};var k=90*h,M=3*f,A=5*p;function T(t,e,r,n,i){if((e||r||n||i)&&(t+=" "+w(e,2)+":"+w(r,2),(n||i)&&(t+=":"+w(n,2),i))){for(var a=4;i%10==0;)a-=1,i/=10;t+="."+w(i,a)}return t}r.ms2DateTime=function(t,e,r){if("number"!=typeof t||!(t>=n&&t<=i))return u;e||(e=0);var a,o,s,c,y,x,b=Math.floor(10*l(t+.05,1)),w=Math.round(t-b/10);if(_(r)){var S=Math.floor(w/h)+g,E=Math.floor(l(t,h));try{a=m.getComponentMethod("calendars","getCal")(r).fromJD(S).formatDate("yyyy-mm-dd")}catch(t){a=v("G%Y-%m-%d")(new Date(w))}if("-"===a.charAt(0))for(;a.length<11;)a="-0"+a.substr(1);else for(;a.length<10;)a="0"+a;o=e=n+h&&t<=i-h))return u;var e=Math.floor(10*l(t+.05,1)),r=new Date(Math.round(t-e/10));return T(a.time.format("%Y-%m-%d")(r),r.getHours(),r.getMinutes(),r.getSeconds(),10*r.getUTCMilliseconds()+e)},r.cleanDate=function(t,e,n){if(r.isJSDate(t)||"number"==typeof t){if(_(n))return s.error("JS Dates and milliseconds are incompatible with world calendars",t),e;if(!(t=r.ms2DateTimeLocal(+t))&&void 0!==e)return e}else if(!r.isDateTime(t,n))return s.error("unrecognized date",t),e;return t};var S=/%\d?f/g;function E(t,e,r,n){t=t.replace(S,function(t){var r=Math.min(+t.charAt(1)||6,6);return(e/1e3%1+2).toFixed(r).substr(2).replace(/0+$/,"")||"0"});var i=new Date(Math.floor(e+.05));if(_(n))try{t=m.getComponentMethod("calendars","worldCalFmt")(t,e,n)}catch(t){return"Invalid"}return r(t)(i)}var C=[59,59.9,59.99,59.999,59.9999];r.formatDate=function(t,e,r,n,i,a){if(i=_(i)&&i,!e)if("y"===r)e=a.year;else if("m"===r)e=a.month;else{if("d"!==r)return function(t,e){var r=l(t+.05,h),n=w(Math.floor(r/f),2)+":"+w(l(Math.floor(r/p),60),2);if("M"!==e){o(e)||(e=0);var i=(100+Math.min(l(t/d,60),C[e])).toFixed(e).substr(1);e>0&&(i=i.replace(/0+$/,"").replace(/[\.]$/,"")),n+=":"+i}return n}(t,r)+"\n"+E(a.dayMonthYear,t,n,i);e=a.dayMonth+"\n"+a.year}return E(e,t,n,i)};var L=3*h;r.incrementMonth=function(t,e,r){r=_(r)&&r;var n=l(t,h);if(t=Math.round(t-n),r)try{var i=Math.round(t/h)+g,a=m.getComponentMethod("calendars","getCal")(r),o=a.fromJD(i);return e%12?a.add(o,e,"m"):a.add(o,e/12,"y"),(o.toJD()-g)*h+n}catch(e){s.error("invalid ms "+t+" in calendar "+r)}var c=new Date(t+L);return c.setUTCMonth(c.getUTCMonth()+e)+n-L},r.findExactDates=function(t,e){for(var r,n,i=0,a=0,s=0,l=0,c=_(e)&&m.getComponentMethod("calendars","getCal")(e),u=0;u0&&(r.push(i),i=[])}return i.length>0&&r.push(i),r},r.makeLine=function(t){return 1===t.length?{type:"LineString",coordinates:t[0]}:{type:"MultiLineString",coordinates:t}},r.makePolygon=function(t){if(1===t.length)return{type:"Polygon",coordinates:t};for(var e=new Array(t.length),r=0;r1||g<0||g>1?null:{x:t+l*g,y:e+h*g}}function l(t,e,r,n,i){var a=n*t+i*e;if(a<0)return n*n+i*i;if(a>r){var o=n-t,s=i-e;return o*o+s*s}var l=n*e-i*t;return l*l/r}r.segmentsIntersect=s,r.segmentDistance=function(t,e,r,n,i,a,o,c){if(s(t,e,r,n,i,a,o,c))return 0;var u=r-t,h=n-e,f=o-i,p=c-a,d=u*u+h*h,g=f*f+p*p,m=Math.min(l(u,h,d,i-t,a-e),l(u,h,d,o-t,c-e),l(f,p,g,t-i,e-a),l(f,p,g,r-i,n-a));return Math.sqrt(m)},r.getTextLocation=function(t,e,r,s){if(t===i&&s===a||(n={},i=t,a=s),n[r])return n[r];var l=t.getPointAtLength(o(r-s/2,e)),c=t.getPointAtLength(o(r+s/2,e)),u=Math.atan((c.y-l.y)/(c.x-l.x)),h=t.getPointAtLength(o(r,e)),f={x:(4*h.x+l.x+c.x)/6,y:(4*h.y+l.y+c.y)/6,theta:u};return n[r]=f,f},r.clearLocationCache=function(){i=null},r.getVisibleSegment=function(t,e,r){var n,i,a=e.left,o=e.right,s=e.top,l=e.bottom,c=0,u=t.getTotalLength(),h=u;function f(e){var r=t.getPointAtLength(e);0===e?n=r:e===u&&(i=r);var c=r.xo?r.x-o:0,h=r.yl?r.y-l:0;return Math.sqrt(c*c+h*h)}for(var p=f(c);p;){if((c+=p+r)>h)return;p=f(c)}for(p=f(h);p;){if(c>(h-=p+r))return;p=f(h)}return{min:c,max:h,len:h-c,total:u,isClosed:0===c&&h===u&&Math.abs(n.x-i.x)<.1&&Math.abs(n.y-i.y)<.1}},r.findPointOnPath=function(t,e,r,n){for(var i,a,o,s=(n=n||{}).pathLength||t.getTotalLength(),l=n.tolerance||.001,c=n.iterationLimit||30,u=t.getPointAtLength(0)[r]>t.getPointAtLength(s)[r]?-1:1,h=0,f=0,p=s;h0?p=i:f=i,h++}return a}},{"./mod":691}],679:[function(t,e,r){"use strict";e.exports=function(t){var e;if("string"==typeof t){if(null===(e=document.getElementById(t)))throw new Error("No DOM element with id '"+t+"' exists on the page.");return e}if(null==t)throw new Error("DOM element provided is null or undefined");return t}},{}],680:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("tinycolor2"),a=t("color-normalize"),o=t("../components/colorscale"),s=t("../components/color/attributes").defaultLine,l=t("./is_array").isArrayOrTypedArray,c=a(s),u=1;function h(t,e){var r=t;return r[3]*=e,r}function f(t){if(n(t))return c;var e=a(t);return e.length?e:c}function p(t){return n(t)?t:u}e.exports={formatColor:function(t,e,r){var n,i,s,d,g,m=t.color,v=l(m),y=l(e),x=[];if(n=void 0!==t.colorscale?o.makeColorScaleFunc(o.extractScale(t.colorscale,t.cmin,t.cmax)):f,i=v?function(t,e){return void 0===t[e]?c:a(n(t[e]))}:f,s=y?function(t,e){return void 0===t[e]?u:p(t[e])}:p,v||y)for(var b=0;b=0;){var n=t.indexOf(";",r);if(n/g,"")}(function(t){for(var e=0;(e=t.indexOf("",e))>=0;){var r=t.indexOf("",e);if(r/g,"\n"))))}},{"../constants/string_mappings":662,"superscript-text":492}],683:[function(t,e,r){"use strict";e.exports=function(t){return t}},{}],684:[function(t,e,r){"use strict";var n=t("d3"),i=t("fast-isnumeric"),a=t("../constants/numerical"),o=a.FP_SAFE,s=a.BADNUM,l=e.exports={};l.nestedProperty=t("./nested_property"),l.keyedContainer=t("./keyed_container"),l.relativeAttr=t("./relative_attr"),l.isPlainObject=t("./is_plain_object"),l.mod=t("./mod"),l.toLogRange=t("./to_log_range"),l.relinkPrivateKeys=t("./relink_private"),l.ensureArray=t("./ensure_array");var c=t("./is_array");l.isTypedArray=c.isTypedArray,l.isArrayOrTypedArray=c.isArrayOrTypedArray,l.isArray1D=c.isArray1D;var u=t("./coerce");l.valObjectMeta=u.valObjectMeta,l.coerce=u.coerce,l.coerce2=u.coerce2,l.coerceFont=u.coerceFont,l.coerceHoverinfo=u.coerceHoverinfo,l.coerceSelectionMarkerOpacity=u.coerceSelectionMarkerOpacity,l.validate=u.validate;var h=t("./dates");l.dateTime2ms=h.dateTime2ms,l.isDateTime=h.isDateTime,l.ms2DateTime=h.ms2DateTime,l.ms2DateTimeLocal=h.ms2DateTimeLocal,l.cleanDate=h.cleanDate,l.isJSDate=h.isJSDate,l.formatDate=h.formatDate,l.incrementMonth=h.incrementMonth,l.dateTick0=h.dateTick0,l.dfltRange=h.dfltRange,l.findExactDates=h.findExactDates,l.MIN_MS=h.MIN_MS,l.MAX_MS=h.MAX_MS;var f=t("./search");l.findBin=f.findBin,l.sorterAsc=f.sorterAsc,l.sorterDes=f.sorterDes,l.distinctVals=f.distinctVals,l.roundUp=f.roundUp;var p=t("./stats");l.aggNums=p.aggNums,l.len=p.len,l.mean=p.mean,l.midRange=p.midRange,l.variance=p.variance,l.stdev=p.stdev,l.interp=p.interp;var d=t("./matrix");l.init2dArray=d.init2dArray,l.transposeRagged=d.transposeRagged,l.dot=d.dot,l.translationMatrix=d.translationMatrix,l.rotationMatrix=d.rotationMatrix,l.rotationXYMatrix=d.rotationXYMatrix,l.apply2DTransform=d.apply2DTransform,l.apply2DTransform2=d.apply2DTransform2;var g=t("./angles");l.deg2rad=g.deg2rad,l.rad2deg=g.rad2deg,l.wrap360=g.wrap360,l.wrap180=g.wrap180;var m=t("./geometry2d");l.segmentsIntersect=m.segmentsIntersect,l.segmentDistance=m.segmentDistance,l.getTextLocation=m.getTextLocation,l.clearLocationCache=m.clearLocationCache,l.getVisibleSegment=m.getVisibleSegment,l.findPointOnPath=m.findPointOnPath;var v=t("./extend");l.extendFlat=v.extendFlat,l.extendDeep=v.extendDeep,l.extendDeepAll=v.extendDeepAll,l.extendDeepNoArrays=v.extendDeepNoArrays;var y=t("./loggers");l.log=y.log,l.warn=y.warn,l.error=y.error;var x=t("./regex");l.counterRegex=x.counter;var b=t("./throttle");function _(t){var e={};for(var r in t)for(var n=t[r],i=0;io?s:i(t)?Number(t):s:s},l.isIndex=function(t,e){return!(void 0!==e&&t>=e)&&(i(t)&&t>=0&&t%1==0)},l.noop=t("./noop"),l.identity=t("./identity"),l.swapAttrs=function(t,e,r,n){r||(r="x"),n||(n="y");for(var i=0;ir?Math.max(r,Math.min(e,t)):Math.max(e,Math.min(r,t))},l.bBoxIntersect=function(t,e,r){return r=r||0,t.left<=e.right+r&&e.left<=t.right+r&&t.top<=e.bottom+r&&e.top<=t.bottom+r},l.simpleMap=function(t,e,r,n){for(var i=t.length,a=new Array(i),o=0;o=Math.pow(2,r)?i>10?(l.warn("randstr failed uniqueness"),c):t(e,r,n,(i||0)+1):c},l.OptionControl=function(t,e){t||(t={}),e||(e="opt");var r={optionList:[],_newoption:function(n){n[e]=t,r[n.name]=n,r.optionList.push(n)}};return r["_"+e]=t,r},l.smooth=function(t,e){if((e=Math.round(e)||0)<2)return t;var r,n,i,a,o=t.length,s=2*o,l=2*e-1,c=new Array(l),u=new Array(o);for(r=0;r=s&&(i-=s*Math.floor(i/s)),i<0?i=-1-i:i>=o&&(i=s-1-i),a+=t[i]*c[n];u[r]=a}return u},l.syncOrAsync=function(t,e,r){var n;function i(){return l.syncOrAsync(t,e,r)}for(;t.length;)if((n=(0,t.splice(0,1)[0])(e))&&n.then)return n.then(i).then(void 0,l.promiseError);return r&&r(e)},l.stripTrailingSlash=function(t){return"/"===t.substr(-1)?t.substr(0,t.length-1):t},l.noneOrAll=function(t,e,r){if(t){var n,i=!1,a=!0;for(n=0;n1?i+o[1]:"";if(a&&(o.length>1||s.length>4||r))for(;n.test(s);)s=s.replace(n,"$1"+a+"$2");return s+l};var M=/%{([^\s%{}]*)}/g,A=/^\w*$/;l.templateString=function(t,e){var r={};return t.replace(M,function(t,n){return A.test(n)?e[n]||"":(r[n]=r[n]||l.nestedProperty(e,n).get,r[n]()||"")})};l.subplotSort=function(t,e){for(var r=Math.min(t.length,e.length)+1,n=0,i=0,a=0;a=48&&o<=57,c=s>=48&&s<=57;if(l&&(n=10*n+o-48),c&&(i=10*i+s-48),!l||!c){if(n!==i)return n-i;if(o!==s)return o-s}}return i-n};var T=2e9;l.seedPseudoRandom=function(){T=2e9},l.pseudoRandom=function(){var t=T;return T=(69069*T+1)%4294967296,Math.abs(T-t)<429496729?l.pseudoRandom():T/4294967296}},{"../constants/numerical":661,"./angles":666,"./clean_number":667,"./coerce":669,"./dates":670,"./ensure_array":671,"./extend":673,"./filter_unique":674,"./filter_visible":675,"./geometry2d":678,"./get_graph_div":679,"./identity":683,"./is_array":685,"./is_plain_object":686,"./keyed_container":687,"./localize":688,"./loggers":689,"./matrix":690,"./mod":691,"./nested_property":692,"./noop":693,"./notifier":694,"./push_unique":698,"./regex":700,"./relative_attr":701,"./relink_private":702,"./search":703,"./stats":706,"./throttle":709,"./to_log_range":710,d3:147,"fast-isnumeric":214}],685:[function(t,e,r){"use strict";var n="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer:{isView:function(){return!1}},i="undefined"==typeof DataView?function(){}:DataView;function a(t){return n.isView(t)&&!(t instanceof i)}function o(t){return Array.isArray(t)||a(t)}e.exports={isTypedArray:a,isArrayOrTypedArray:o,isArray1D:function(t){return!o(t[0])}}},{}],686:[function(t,e,r){"use strict";e.exports=function(t){return window&&window.process&&window.process.versions?"[object Object]"===Object.prototype.toString.call(t):"[object Object]"===Object.prototype.toString.call(t)&&Object.getPrototypeOf(t)===Object.prototype}},{}],687:[function(t,e,r){"use strict";var n=t("./nested_property"),i=/^\w*$/;e.exports=function(t,e,r,a){var o,s,l;r=r||"name",a=a||"value";var c={};e&&e.length?(l=n(t,e),s=l.get()):s=t,e=e||"";var u={};if(s)for(o=0;o2)return c[e]=2|c[e],f.set(t,null);if(h){for(o=e;o1){for(var t=["LOG:"],e=0;e0){for(var t=["WARN:"],e=0;e0){for(var t=["ERROR:"],e=0;e/g),o=0;oo||a===i||al||e&&c(t))}:function(t,e){var a=t[0],c=t[1];if(a===i||ao||c===i||cl)return!1;var u,h,f,p,d,g=r.length,m=r[0][0],v=r[0][1],y=0;for(u=1;uMath.max(h,m)||c>Math.max(f,v)))if(cu||Math.abs(n(o,f))>i)return!0;return!1};a.filter=function(t,e){var r=[t[0]],n=0,i=0;function a(a){t.push(a);var s=r.length,l=n;r.splice(i+1);for(var c=l+1;c1&&a(t.pop());return{addPt:a,raw:t,filtered:r}}},{"../constants/numerical":661,"./matrix":690}],697:[function(t,e,r){(function(r){"use strict";var n=t("./show_no_webgl_msg"),i=t("regl");e.exports=function(t,e){var a=t._fullLayout,o=!0;return a._glcanvas.each(function(n){if(!n.regl&&(!n.pick||a._has("parcoords")))try{n.regl=i({canvas:this,attributes:{antialias:!n.pick,preserveDrawingBuffer:!0},pixelRatio:t._context.plotGlPixelRatio||r.devicePixelRatio,extensions:e||[]})}catch(t){o=!1}}),o||n({container:a._glcontainer.node()}),o}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./show_no_webgl_msg":705,regl:463}],698:[function(t,e,r){"use strict";e.exports=function(t,e){if(e instanceof RegExp){var r,n=e.toString();for(r=0;ri.queueLength&&(t.undoQueue.queue.shift(),t.undoQueue.index--))},startSequence:function(t){t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},t.undoQueue.sequence=!0,t.undoQueue.beginSequence=!0},stopSequence:function(t){t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},t.undoQueue.sequence=!1,t.undoQueue.beginSequence=!1},undo:function(t){var e,r;if(t.framework&&t.framework.isPolar)t.framework.undo();else if(!(void 0===t.undoQueue||isNaN(t.undoQueue.index)||t.undoQueue.index<=0)){for(t.undoQueue.index--,e=t.undoQueue.queue[t.undoQueue.index],t.undoQueue.inSequence=!0,r=0;r=t.undoQueue.queue.length)){for(e=t.undoQueue.queue[t.undoQueue.index],t.undoQueue.inSequence=!0,r=0;re}function l(t,e){return t>=e}r.findBin=function(t,e,r){if(n(e.start))return r?Math.ceil((t-e.start)/e.size-1e-9)-1:Math.floor((t-e.start)/e.size+1e-9);var c,u,h=0,f=e.length,p=0,d=f>1?(e[f-1]-e[0])/(f-1):1;for(u=d>=0?r?a:o:r?l:s,t+=1e-9*d*(r?-1:1)*(d>=0?1:-1);h90&&i.log("Long binary search..."),h-1},r.sorterAsc=function(t,e){return t-e},r.sorterDes=function(t,e){return e-t},r.distinctVals=function(t){var e=t.slice();e.sort(r.sorterAsc);for(var n=e.length-1,i=e[n]-e[0]||1,a=i/(n||1)/1e4,o=[e[0]],s=0;se[s]+a&&(i=Math.min(i,e[s+1]-e[s]),o.push(e[s+1]));return{vals:o,minDiff:i}},r.roundUp=function(t,e,r){for(var n,i=0,a=e.length-1,o=0,s=r?0:1,l=r?1:0,c=r?Math.ceil:Math.floor;ia.length)&&(o=a.length),n(e)||(e=!1),i(a[0])){for(l=new Array(o),s=0;st.length-1)return t[t.length-1];var r=e%1;return r*t[Math.ceil(e)]+(1-r)*t[Math.floor(e)]}},{"./is_array":685,"fast-isnumeric":214}],707:[function(t,e,r){"use strict";var n=t("color-normalize");e.exports=function(t){return t?n(t):[0,0,0,1]}},{"color-normalize":107}],708:[function(t,e,r){"use strict";var n=t("d3"),i=t("../lib"),a=t("../constants/xmlns_namespaces"),o=t("../constants/string_mappings"),s=t("../constants/alignment").LINE_SPACING;function l(t,e){return t.node().getBoundingClientRect()[e]}var c=/([^$]*)([$]+[^$]*[$]+)([^$]*)/;r.convertToTspans=function(t,e,o){var v=t.text(),C=!t.attr("data-notex")&&"undefined"!=typeof MathJax&&v.match(c),L=n.select(t.node().parentNode);if(!L.empty()){var z=t.attr("class")?t.attr("class").split(" ")[0]:"text";return z+="-math",L.selectAll("svg."+z).remove(),L.selectAll("g."+z+"-group").remove(),t.style("display",null).attr({"data-unformatted":v,"data-math":"N"}),C?(e&&e._promises||[]).push(new Promise(function(e){t.style("display","none");var r=parseInt(t.node().style.fontSize,10),a={fontSize:r};!function(t,e,r){var a="math-output-"+i.randstr({},64),o=n.select("body").append("div").attr({id:a}).style({visibility:"hidden",position:"absolute"}).style({"font-size":e.fontSize+"px"}).text((s=t,s.replace(u,"\\lt ").replace(h,"\\gt ")));var s;MathJax.Hub.Queue(["Typeset",MathJax.Hub,o.node()],function(){var e=n.select("body").select("#MathJax_SVG_glyphs");if(o.select(".MathJax_SVG").empty()||!o.select("svg").node())i.log("There was an error in the tex syntax.",t),r();else{var a=o.select("svg").node().getBoundingClientRect();r(o.select(".MathJax_SVG"),e,a)}o.remove()})}(C[2],a,function(n,i,a){L.selectAll("svg."+z).remove(),L.selectAll("g."+z+"-group").remove();var s=n&&n.select("svg");if(!s||!s.node())return P(),void e();var c=L.append("g").classed(z+"-group",!0).attr({"pointer-events":"none","data-unformatted":v,"data-math":"Y"});c.node().appendChild(s.node()),i&&i.node()&&s.node().insertBefore(i.node().cloneNode(!0),s.node().firstChild),s.attr({class:z,height:a.height,preserveAspectRatio:"xMinYMin meet"}).style({overflow:"visible","pointer-events":"none"});var u=t.node().style.fill||"black";s.select("g").attr({fill:u,stroke:u});var h=l(s,"width"),f=l(s,"height"),p=+t.attr("x")-h*{start:0,middle:.5,end:1}[t.attr("text-anchor")||"start"],d=-(r||l(t,"height"))/4;"y"===z[0]?(c.attr({transform:"rotate("+[-90,+t.attr("x"),+t.attr("y")]+") translate("+[-h/2,d-f/2]+")"}),s.attr({x:+t.attr("x"),y:+t.attr("y")})):"l"===z[0]?s.attr({x:t.attr("x"),y:d-f/2}):"a"===z[0]?s.attr({x:0,y:d}):s.attr({x:p,y:+t.attr("y")+d-f/2}),o&&o.call(t,c),e(c)})})):P(),t}function P(){L.empty()||(z=t.attr("class")+"-math",L.select("svg."+z).remove()),t.text("").style("white-space","pre"),function(t,e){e=(r=e,function(t,e){if(!t)return"";for(var r=0;r1)for(var i=1;i doesnt match end tag <"+t+">. Pretending it did match.",e),o=c[c.length-1].node}else i.log("Ignoring unexpected end tag .",e)}w.test(e)?h():(o=t,c=[{node:t}]);for(var z=e.split(b),P=0;P|>|>)/g;var f={sup:"font-size:70%",sub:"font-size:70%",b:"font-weight:bold",i:"font-style:italic",a:"cursor:pointer",span:"",em:"font-style:italic;font-weight:bold"},p={sub:"0.3em",sup:"-0.6em"},d={sub:"-0.21em",sup:"0.42em"},g="\u200b",m=["http:","https:","mailto:","",void 0,":"],v=new RegExp("]*)?/?>","g"),y=Object.keys(o.entityToUnicode).map(function(t){return{regExp:new RegExp("&"+t+";","g"),sub:o.entityToUnicode[t]}}),x=/(\r\n?|\n)/g,b=/(<[^<>]*>)/,_=/<(\/?)([^ >]*)(\s+(.*))?>/i,w=//i,k=/(^|[\s"'])style\s*=\s*("([^"]*);?"|'([^']*);?')/i,M=/(^|[\s"'])href\s*=\s*("([^"]*)"|'([^']*)')/i,A=/(^|[\s"'])target\s*=\s*("([^"\s]*)"|'([^'\s]*)')/i,T=/(^|[\s"'])popup\s*=\s*("([\w=,]*)"|'([\w=,]*)')/i;function S(t,e){if(!t)return null;var r=t.match(e);return r&&(r[3]||r[4])}var E=/(^|;)\s*color:/;function C(t,e,r){var n,i,a,o=r.horizontalAlign,s=r.verticalAlign||"top",l=t.node().getBoundingClientRect(),c=e.node().getBoundingClientRect();return i="bottom"===s?function(){return l.bottom-n.height}:"middle"===s?function(){return l.top+(l.height-n.height)/2}:function(){return l.top},a="right"===o?function(){return l.right-n.width}:"center"===o?function(){return l.left+(l.width-n.width)/2}:function(){return l.left},function(){return n=this.node().getBoundingClientRect(),this.style({top:i()-c.top+"px",left:a()-c.left+"px","z-index":1e3}),this}}r.plainText=function(t){return(t||"").replace(v," ")},r.lineCount=function(t){return t.selectAll("tspan.line").size()||1},r.positionText=function(t,e,r){return t.each(function(){var t=n.select(this);function i(e,r){return void 0===r?null===(r=t.attr(e))&&(t.attr(e,0),r=0):t.attr(e,r),r}var a=i("x",e),o=i("y",r);"text"===this.nodeName&&t.selectAll("tspan.line").attr({x:a,y:o})})},r.makeEditable=function(t,e){var r=e.gd,i=e.delegate,a=n.dispatch("edit","input","cancel"),o=i||t;if(t.style({"pointer-events":i?"none":"all"}),1!==t.size())throw new Error("boo");function s(){!function(){var i=n.select(r).select(".svg-container"),o=i.append("div"),s=t.node().style,c=parseFloat(s.fontSize||12),u=e.text;void 0===u&&(u=t.attr("data-unformatted"));o.classed("plugin-editable editable",!0).style({position:"absolute","font-family":s.fontFamily||"Arial","font-size":c,color:e.fill||s.fill||"black",opacity:1,"background-color":e.background||"transparent",outline:"#ffffff33 1px solid",margin:[-c/8+1,0,0,-1].join("px ")+"px",padding:"0","box-sizing":"border-box"}).attr({contenteditable:!0}).text(u).call(C(t,i,e)).on("blur",function(){r._editing=!1,t.text(this.textContent).style({opacity:1});var e,i=n.select(this).attr("class");(e=i?"."+i.split(" ")[0]+"-math-group":"[class*=-math-group]")&&n.select(t.node().parentNode).select(e).style({opacity:0});var o=this.textContent;n.select(this).transition().duration(0).remove(),n.select(document).on("mouseup",null),a.edit.call(t,o)}).on("focus",function(){var t=this;r._editing=!0,n.select(document).on("mouseup",function(){if(n.event.target===t)return!1;document.activeElement===o.node()&&o.node().blur()})}).on("keyup",function(){27===n.event.which?(r._editing=!1,t.style({opacity:1}),n.select(this).style({opacity:0}).on("blur",function(){return!1}).transition().remove(),a.cancel.call(t,this.textContent)):(a.input.call(t,this.textContent),n.select(this).call(C(t,i,e)))}).on("keydown",function(){13===n.event.which&&this.blur()}).call(l)}(),t.style({opacity:0});var i,s=o.attr("class");(i=s?"."+s.split(" ")[0]+"-math-group":"[class*=-math-group]")&&n.select(t.node().parentNode).select(i).style({opacity:0})}function l(t){var e=t.node(),r=document.createRange();r.selectNodeContents(e);var n=window.getSelection();n.removeAllRanges(),n.addRange(r),e.focus()}return e.immediate?s():o.on("click",s),n.rebind(t,a,"on")}},{"../constants/alignment":656,"../constants/string_mappings":662,"../constants/xmlns_namespaces":663,"../lib":684,d3:147}],709:[function(t,e,r){"use strict";var n={};function i(t){t&&null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}r.throttle=function(t,e,r){var a=n[t],o=Date.now();if(!a){for(var s in n)n[s].tsa.ts+e?l():a.timer=setTimeout(function(){l(),a.timer=null},e)},r.done=function(t){var e=n[t];return e&&e.timer?new Promise(function(t){var r=e.onDone;e.onDone=function(){r&&r(),t(),e.onDone=null}}):Promise.resolve()},r.clear=function(t){if(t)i(n[t]),delete n[t];else for(var e in n)r.clear(e)}},{}],710:[function(t,e,r){"use strict";var n=t("fast-isnumeric");e.exports=function(t,e){if(t>0)return Math.log(t)/Math.LN10;var r=Math.log(Math.min(e[0],e[1]))/Math.LN10;return n(r)||(r=Math.log(Math.max(e[0],e[1]))/Math.LN10-6),r}},{"fast-isnumeric":214}],711:[function(t,e,r){"use strict";var n=e.exports={},i=t("../plots/geo/constants").locationmodeToLayer,a=t("topojson-client").feature;n.getTopojsonName=function(t){return[t.scope.replace(/ /g,"-"),"_",t.resolution.toString(),"m"].join("")},n.getTopojsonPath=function(t,e){return t+e+".json"},n.getTopojsonFeatures=function(t,e){var r=i[t.locationmode],n=e.objects[r];return a(e,n).features}},{"../plots/geo/constants":760,"topojson-client":502}],712:[function(t,e,r){"use strict";e.exports={moduleType:"locale",name:"en-US",dictionary:{"Click to enter Colorscale title":"Click to enter Colorscale title"},format:{date:"%m/%d/%Y"}}},{}],713:[function(t,e,r){"use strict";e.exports={moduleType:"locale",name:"en",dictionary:{"Click to enter Colorscale title":"Click to enter Colourscale title"},format:{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"],periods:["AM","PM"],dateTime:"%a %b %e %X %Y",date:"%d/%m/%Y",time:"%H:%M:%S",decimal:".",thousands:",",grouping:[3],currency:["$",""],year:"%Y",month:"%b %Y",dayMonth:"%b %-d",dayMonthYear:"%b %-d, %Y"}}},{}],714:[function(t,e,r){"use strict";var n=t("../registry");e.exports=function(t){for(var e,r,i=n.layoutArrayContainers,a=n.layoutArrayRegexes,o=t.split("[")[0],s=0;s0&&o.log("Clearing previous rejected promises from queue."),t._promises=[]},r.cleanLayout=function(t){var e,r;t||(t={}),t.xaxis1&&(t.xaxis||(t.xaxis=t.xaxis1),delete t.xaxis1),t.yaxis1&&(t.yaxis||(t.yaxis=t.yaxis1),delete t.yaxis1),t.scene1&&(t.scene||(t.scene=t.scene1),delete t.scene1);var n=(s.subplotsRegistry.cartesian||{}).attrRegex,a=(s.subplotsRegistry.gl3d||{}).attrRegex,l=Object.keys(t);for(e=0;e3?(T.x=1.02,T.xanchor="left"):T.x<-2&&(T.x=-.02,T.xanchor="right"),T.y>3?(T.y=1.02,T.yanchor="bottom"):T.y<-2&&(T.y=-.02,T.yanchor="top")),"rotate"===t.dragmode&&(t.dragmode="orbit"),h.clean(t),t},r.cleanData=function(t){for(var e=0;e0)return t.substr(0,e)}r.hasParent=function(t,e){for(var r=y(e);r;){if(r in t)return!0;r=y(r)}return!1};var x=["x","y","z"];r.clearAxisTypes=function(t,e,r){for(var n=0;n1&&o.warn("Full array edits are incompatible with other edits",h);var y=r[""][""];if(u(y))e.set(null);else{if(!Array.isArray(y))return o.warn("Unrecognized full array edit value",h,y),!0;e.set(y)}return!g&&(f(m,v),p(t),!0)}var x,b,_,w,k,M,A,T=Object.keys(r).map(Number).sort(s),S=e.get(),E=S||[],C=n(v,h).get(),L=[],z=-1,P=E.length;for(x=0;xE.length-(A?0:1))o.warn("index out of range",h,_);else if(void 0!==M)k.length>1&&o.warn("Insertion & removal are incompatible with edits to the same index.",h,_),u(M)?L.push(_):A?("add"===M&&(M={}),E.splice(_,0,M),C&&C.splice(_,0,{})):o.warn("Unrecognized full object edit value",h,_,M),-1===z&&(z=_);else for(b=0;b=0;x--)E.splice(L[x],1),C&&C.splice(L[x],1);if(E.length?S||e.set(E):e.set(null),g)return!1;if(f(m,v),d!==a){var I;if(-1===z)I=T;else{for(P=Math.max(E.length,P),I=[],x=0;x=z);x++)I.push(_);for(x=z;x=t.data.length||i<-t.data.length)throw new Error(r+" must be valid indices for gd.data.");if(e.indexOf(i,n+1)>-1||i>=0&&e.indexOf(-t.data.length+i)>-1||i<0&&e.indexOf(t.data.length+i)>-1)throw new Error("each index in "+r+" must be unique.")}}function I(t,e,r){if(!Array.isArray(t.data))throw new Error("gd.data must be an array.");if("undefined"==typeof e)throw new Error("currentIndices is a required argument.");if(Array.isArray(e)||(e=[e]),P(t,e,"currentIndices"),"undefined"==typeof r||Array.isArray(r)||(r=[r]),"undefined"!=typeof r&&P(t,r,"newIndices"),"undefined"!=typeof r&&e.length!==r.length)throw new Error("current and new indices must be of equal length.")}function O(t,e,r,n,a){!function(t,e,r,n){var i=o.isPlainObject(n);if(!Array.isArray(t.data))throw new Error("gd.data must be an array");if(!o.isPlainObject(e))throw new Error("update must be a key:value object");if("undefined"==typeof r)throw new Error("indices must be an integer or array of integers");for(var a in P(t,r,"indices"),e){if(!Array.isArray(e[a])||e[a].length!==r.length)throw new Error("attribute "+a+" must be an array of length equal to indices array length");if(i&&(!(a in n)||!Array.isArray(n[a])||n[a].length!==e[a].length))throw new Error("when maxPoints is set as a key:value object it must contain a 1:1 corrispondence with the keys and number of traces in the update object")}}(t,e,r,n);for(var s=function(t,e,r,n){var a,s,l,c,u,h=o.isPlainObject(n),f=[];for(var p in Array.isArray(r)||(r=[r]),r=z(r,t.data.length-1),e)for(var d=0;d=0&&r=0&&r0&&"string"!=typeof C.parts[z];)z--;var P=C.parts[z],I=C.parts[z-1]+"."+P,O=C.parts.slice(0,z).join("."),D=o.nestedProperty(t.layout,O).get(),B=o.nestedProperty(s,O).get(),F=C.get();if(void 0!==L){y[E]=L,x[E]="reverse"===P?L:R(F);var U=u.getLayoutValObject(s,C.parts);if(U&&U.impliedEdits&&null!==L)for(var G in U.impliedEdits)b(o.relativeAttr(E,G),U.impliedEdits[G]);if(-1!==["width","height"].indexOf(E)&&null===L)s[E]=t._initialAutoSize[E];else if(I.match(N))S(I),o.nestedProperty(s,O+"._inputRange").set(null);else if(I.match(j)){S(I),o.nestedProperty(s,O+"._inputRange").set(null);var W=o.nestedProperty(s,O).get();W._inputDomain&&(W._input.domain=W._inputDomain.slice())}else I.match(V)&&o.nestedProperty(s,O+"._inputDomain").set(null);if("type"===P){var Y=D,X="linear"===B.type&&"log"===L,Z="log"===B.type&&"linear"===L;if(X||Z){if(Y&&Y.range)if(B.autorange)X&&(Y.range=Y.range[1]>Y.range[0]?[1,2]:[2,1]);else{var $=Y.range[0],J=Y.range[1];X?($<=0&&J<=0&&b(O+".autorange",!0),$<=0?$=J/1e6:J<=0&&(J=$/1e6),b(O+".range[0]",Math.log($)/Math.LN10),b(O+".range[1]",Math.log(J)/Math.LN10)):(b(O+".range[0]",Math.pow(10,$)),b(O+".range[1]",Math.pow(10,J)))}else b(O+".autorange",!0);Array.isArray(s._subplots.polar)&&s._subplots.polar.length&&s[C.parts[0]]&&"radialaxis"===C.parts[1]&&delete s[C.parts[0]]._subplot.viewInitial["radialaxis.range"],c.getComponentMethod("annotations","convertCoords")(t,B,L,b),c.getComponentMethod("images","convertCoords")(t,B,L,b)}else b(O+".autorange",!0),b(O+".range",null);o.nestedProperty(s,O+"._inputRange").set(null)}else if(P.match(A)){var K=o.nestedProperty(s,E).get(),Q=(L||{}).type;Q&&"-"!==Q||(Q="linear"),c.getComponentMethod("annotations","convertCoords")(t,K,Q,b),c.getComponentMethod("images","convertCoords")(t,K,Q,b)}var tt=_.containerArrayMatch(E);if(tt){r=tt.array,n=tt.index;var et=tt.property,rt=(o.nestedProperty(a,r)||[])[n]||{},nt=rt,it=U||{editType:"calc"},at=-1!==it.editType.indexOf("calcIfAutorange");""===n?(at?v.calc=!0:M.update(v,it),at=!1):""===et&&(nt=L,_.isAddVal(L)?x[E]=null:_.isRemoveVal(L)?(x[E]=rt,nt=rt):o.warn("unrecognized full object value",e)),at&&(H(t,nt,"x")||H(t,nt,"y"))?v.calc=!0:M.update(v,it),f[r]||(f[r]={});var ot=f[r][n];ot||(ot=f[r][n]={}),ot[et]=L,delete e[E]}else"reverse"===P?(D.range?D.range.reverse():(b(O+".autorange",!0),D.range=[1,0]),B.autorange?v.calc=!0:v.plot=!0):(s._has("scatter-like")&&s._has("regl")&&"dragmode"===E&&("lasso"===L||"select"===L)&&"lasso"!==F&&"select"!==F?v.plot=!0:U?M.update(v,U):v.calc=!0,C.set(L))}}for(r in f){_.applyContainerArrayChanges(t,o.nestedProperty(a,r),f[r],v)||(v.plot=!0)}var st=s._axisConstraintGroups||[];for(k in T)for(n=0;n=i.length?i[0]:i[t]:i}function l(t){return Array.isArray(a)?t>=a.length?a[0]:a[t]:a}function c(t,e){var r=0;return function(){if(t&&++r===e)return t()}}return void 0===n._frameWaitingCnt&&(n._frameWaitingCnt=0),new Promise(function(a,u){function f(){n._currentFrame&&n._currentFrame.onComplete&&n._currentFrame.onComplete();var e=n._currentFrame=n._frameQueue.shift();if(e){var r=e.name?e.name.toString():null;t._fullLayout._currentFrame=r,n._lastFrameAt=Date.now(),n._timeToNext=e.frameOpts.duration,h.transition(t,e.frame.data,e.frame.layout,w.coerceTraceIndices(t,e.frame.traces),e.frameOpts,e.transitionOpts).then(function(){e.onComplete&&e.onComplete()}),t.emit("plotly_animatingframe",{name:r,frame:e.frame,animation:{frame:e.frameOpts,transition:e.transitionOpts}})}else t.emit("plotly_animated"),window.cancelAnimationFrame(n._animationRaf),n._animationRaf=null}function p(){t.emit("plotly_animating"),n._lastFrameAt=-1/0,n._timeToNext=0,n._runningTransitions=0,n._currentFrame=null;var e=function(){n._animationRaf=window.requestAnimationFrame(e),Date.now()-n._lastFrameAt>n._timeToNext&&f()};e()}var d,g,m=0;function v(t){return Array.isArray(i)?m>=i.length?t.transitionOpts=i[m]:t.transitionOpts=i[0]:t.transitionOpts=i,m++,t}var y=[],x=null==e,b=Array.isArray(e);if(!x&&!b&&o.isPlainObject(e))y.push({type:"object",data:v(o.extendFlat({},e))});else if(x||-1!==["string","number"].indexOf(typeof e))for(d=0;d0&&MM)&&A.push(g);y=A}}y.length>0?function(e){if(0!==e.length){for(var i=0;i=0;n--)if(o.isPlainObject(e[n])){var g=e[n].name,m=(u[g]||d[g]||{}).name,v=e[n].name,y=u[m]||d[m];m&&v&&"number"==typeof v&&y&&T<5&&(T++,o.warn('addFrames: overwriting frame "'+(u[m]||d[m]).name+'" with a frame whose name of type "number" also equates to "'+m+'". This is valid but may potentially lead to unexpected behavior since all plotly.js frame names are stored internally as strings.'),5===T&&o.warn("addFrames: This API call has yielded too many of these warnings. For the rest of this call, further warnings about numeric frame names will be suppressed.")),d[g]={name:g},p.push({frame:h.supplyFrameDefaults(e[n]),index:r&&void 0!==r[n]&&null!==r[n]?r[n]:f+n})}p.sort(function(t,e){return t.index>e.index?-1:t.index=0;n--){if("number"==typeof(i=p[n].frame).name&&o.warn("Warning: addFrames accepts frames with numeric names, but the numbers areimplicitly cast to strings"),!i.name)for(;u[i.name="frame "+t._transitionData._counter++];);if(u[i.name]){for(a=0;a=0;r--)n=e[r],a.push({type:"delete",index:n}),s.unshift({type:"insert",index:n,value:i[n]});var c=h.modifyFrames,u=h.modifyFrames,f=[t,s],p=[t,a];return l&&l.add(t,c,f,u,p),h.modifyFrames(t,a)},r.purge=function(t){var e=(t=o.getGraphDiv(t))._fullLayout||{},r=t._fullData||[],n=t.calcdata||[];return h.cleanPlot([],{},r,e,n),h.purge(t),s.purge(t),e._container&&e._container.remove(),delete t._context,t}},{"../components/color":558,"../components/colorbar/connect":560,"../components/drawing":583,"../constants/xmlns_namespaces":663,"../lib":684,"../lib/events":672,"../lib/queue":699,"../lib/svg_text_utils":708,"../plots/cartesian/axes":732,"../plots/cartesian/constants":737,"../plots/cartesian/graph_interact":741,"../plots/plots":795,"../plots/polar/legacy":803,"../registry":817,"./edit_types":715,"./helpers":716,"./manage_arrays":718,"./plot_config":720,"./plot_schema":721,"./subroutines":723,d3:147,"fast-isnumeric":214,"has-hover":378}],720:[function(t,e,r){"use strict";e.exports={staticPlot:!1,plotlyServerURL:"https://plot.ly",editable:!1,edits:{annotationPosition:!1,annotationTail:!1,annotationText:!1,axisTitleText:!1,colorbarPosition:!1,colorbarTitleText:!1,legendPosition:!1,legendText:!1,shapePosition:!1,titleText:!1},autosizable:!1,queueLength:0,fillFrame:!1,frameMargins:0,scrollZoom:!1,doubleClick:"reset+autosize",showTips:!0,showAxisDragHandles:!0,showAxisRangeEntryBoxes:!0,showLink:!1,sendData:!0,linkText:"Edit chart",showSources:!1,displayModeBar:"hover",modeBarButtonsToRemove:[],modeBarButtonsToAdd:[],modeBarButtons:!1,toImageButtonOptions:{},displaylogo:!0,plotGlPixelRatio:2,setBackground:"transparent",topojsonURL:"https://cdn.plot.ly/",mapboxAccessToken:null,logging:1,globalTransforms:[],locale:"en-US",locales:{}}},{}],721:[function(t,e,r){"use strict";var n=t("../registry"),i=t("../lib"),a=t("../plots/attributes"),o=t("../plots/layout_attributes"),s=t("../plots/frame_attributes"),l=t("../plots/animation_attributes"),c=t("../plots/polar/legacy/area_attributes"),u=t("../plots/polar/legacy/axis_attributes"),h=t("./edit_types"),f=i.extendFlat,p=i.extendDeepAll,d=i.isPlainObject,g="_isSubplotObj",m="_isLinkedToArray",v=[g,m,"_arrayAttrRegexps","_deprecated"];function y(t,e,r){if(!t)return!1;if(t._isLinkedToArray)if(x(e[r]))r++;else if(r=a.length)return!1;if(2===t.dimensions){if(r++,e.length===r)return t;var o=e[r];if(!x(o))return!1;t=a[i][o]}else t=a[i]}else t=a}}return t}function x(t){return t===Math.round(t)&&t>=0}function b(t){return function(t){r.crawl(t,function(t,e,n){r.isValObject(t)?"data_array"===t.valType?(t.role="data",n[e+"src"]={valType:"string",editType:"none"}):!0===t.arrayOk&&(n[e+"src"]={valType:"string",editType:"none"}):d(t)&&(t.role="object")})}(t),function(t){r.crawl(t,function(t,e,r){if(!t)return;var n=t[m];if(!n)return;delete t[m],r[e]={items:{}},r[e].items[n]=t,r[e].role="object"})}(t),function(t){!function t(e){for(var r in e)if(d(e[r]))t(e[r]);else if(Array.isArray(e[r]))for(var n=0;n=l.length)return!1;i=(r=(n.transformsRegistry[l[u].type]||{}).attributes)&&r[e[2]],s=3}else if("area"===t.type)i=c[o];else{var h=t._module;if(h||(h=(n.modules[t.type||a.type.dflt]||{})._module),!h)return!1;if(!(i=(r=h.attributes)&&r[o])){var f=h.basePlotModule;f&&f.attributes&&(i=f.attributes[o])}i||(i=a[o])}return y(i,e,s)},r.getLayoutValObject=function(t,e){return y(function(t,e){var r,i,a,s,l=t._basePlotModules;if(l){var c;for(r=0;r=i&&(r._input||{})._templateitemname;s&&(o=i);var l,c=e+"["+o+"]";function u(){l={},s&&(l[c]={},l[c][a]=s)}function h(t,e){s?n.nestedProperty(l[c],t).set(e):l[c+"."+t]=e}function f(){var t=l;return u(),t}return u(),{modifyBase:function(t,e){l[t]=e},modifyItem:h,getUpdateObj:f,applyUpdate:function(e,r){e&&h(e,r);var i=f();for(var a in i)n.nestedProperty(t,a).set(i[a])}}}},{"../lib":684,"../plots/attributes":729}],723:[function(t,e,r){"use strict";var n=t("d3"),i=t("../registry"),a=t("../plots/plots"),o=t("../lib"),s=t("../lib/clear_gl_canvases"),l=t("../components/color"),c=t("../components/drawing"),u=t("../components/titles"),h=t("../components/modebar"),f=t("../plots/cartesian/axes"),p=t("../constants/alignment"),d=t("../plots/cartesian/constraints"),g=d.enforce,m=d.clean,v=t("../plots/cartesian/autorange").doAutoRange;function y(t){var e,i=t._fullLayout,a=i._size,s=a.p,u=f.list(t,"",!0),d=i._has("cartesian");function g(t,e,r){var n=t._lw/2;return"x"===t._id.charAt(0)?e?"top"===r?e._offset-s-n:e._offset+e._length+s+n:a.t+a.h*(1-(t.position||0))+n%1:e?"right"===r?e._offset+e._length+s+n:e._offset-s-n:a.l+a.w*(t.position||0)+n%1}for(e=0;e=t[1]||i[1]<=t[0])&&a[0]e[0])return!0}return!1}(n,a,k)){var l=s.node(),c=r.bg=o.ensureSingle(s,"rect","bg");l.insertBefore(c.node(),l.childNodes[0])}else s.select("rect.bg").remove(),_.push(e),k.push([n,a])});var M=i._bgLayer.selectAll(".bg").data(_);return M.enter().append("rect").classed("bg",!0),M.exit().remove(),M.each(function(t){i._plots[t].bg=n.select(this)}),y.each(function(t){var e=t[0],r=i._plots[e],n=r.xaxis,a=r.yaxis;r.bg&&d&&r.bg.call(c.setRect,n._offset-s,a._offset-s,n._length+2*s,a._length+2*s).call(l.fill,i.plot_bgcolor).style("stroke-width",0);var h,f,p=r.clipId="clip"+i._uid+e+"plot",m=o.ensureSingleById(i._clips,"clipPath",p,function(t){t.classed("plotclip",!0).append("rect")});if(r.clipRect=m.select("rect").attr({width:n._length,height:a._length}),c.setTranslate(r.plot,n._offset,a._offset),r._hasClipOnAxisFalse?(h=null,f=p):(h=p,f=null),c.setClipUrl(r.plot,h),r.layerClipId=f,d){var v,y,x,_,k,M,A,T,S,E,C,L,z,P="M0,0";b(n,e)&&(k=w(n,"left",a,u),v=n._offset-(k?s+k:0),M=w(n,"right",a,u),y=n._offset+n._length+(M?s+M:0),x=g(n,a,"bottom"),_=g(n,a,"top"),(z=!n._anchorAxis||e!==n._mainSubplot)&&n.ticks&&"allticks"===n.mirror&&(n._linepositions[e]=[x,_]),P=R(n,O,function(t){return"M"+n._offset+","+t+"h"+n._length}),z&&n.showline&&("all"===n.mirror||"allticks"===n.mirror)&&(P+=O(x)+O(_)),r.xlines.style("stroke-width",n._lw+"px").call(l.stroke,n.showline?n.linecolor:"rgba(0,0,0,0)")),r.xlines.attr("d",P);var I="M0,0";b(a,e)&&(C=w(a,"bottom",n,u),A=a._offset+a._length+(C?s:0),L=w(a,"top",n,u),T=a._offset-(L?s:0),S=g(a,n,"left"),E=g(a,n,"right"),(z=!a._anchorAxis||e!==n._mainSubplot)&&a.ticks&&"allticks"===a.mirror&&(a._linepositions[e]=[S,E]),I=R(a,D,function(t){return"M"+t+","+a._offset+"v"+a._length}),z&&a.showline&&("all"===a.mirror||"allticks"===a.mirror)&&(I+=D(S)+D(E)),r.ylines.style("stroke-width",a._lw+"px").call(l.stroke,a.showline?a.linecolor:"rgba(0,0,0,0)")),r.ylines.attr("d",I)}function O(t){return"M"+v+","+t+"H"+y}function D(t){return"M"+t+","+T+"V"+A}function R(t,r,n){if(!t.showline||e!==t._mainSubplot)return"";if(!t._anchorAxis)return n(t._mainLinePosition);var i=r(t._mainLinePosition);return t.mirror&&(i+=r(t._mainMirrorPosition)),i}}),f.makeClipPaths(t),r.drawMainTitle(t),h.manage(t),t._promises.length&&Promise.all(t._promises)}function x(t,e){var r=e._subplots,n=r.cartesian.concat(r.gl2d||[]),i={_fullLayout:e},a="x"===t._id.charAt(0),o=t._mainAxis._anchorAxis,s="",l="",c="";if(o&&(c=o._mainAxis._id,s=a?t._id+c:c+t._id),!s||!e._plots[s]){s="";for(var u=0;uk?u.push({code:"unused",traceType:y,templateCount:w,dataCount:k}):k>w&&u.push({code:"reused",traceType:y,templateCount:w,dataCount:k})}}else u.push({code:"data"});if(function t(e,r){for(var n in e)if("_"!==n.charAt(0)){var a=e[n],o=p(e,n,r);i(a)?(Array.isArray(e)&&!1===a._template&&a.templateitemname&&u.push({code:"missing",path:o,templateitemname:a.templateitemname}),t(a,o)):Array.isArray(a)&&d(a)&&t(a,o)}}({data:m,layout:f},""),u.length)return u.map(g)}},{"../lib":684,"../plots/attributes":729,"../plots/plots":795,"./plot_config":720,"./plot_schema":721,"./plot_template":722}],725:[function(t,e,r){"use strict";var n=t("./plot_api"),i=t("../lib"),a=t("../snapshot/helpers"),o=t("../snapshot/tosvg"),s=t("../snapshot/svgtoimg"),l={format:{valType:"enumerated",values:["png","jpeg","webp","svg"],dflt:"png"},width:{valType:"number",min:1},height:{valType:"number",min:1},scale:{valType:"number",min:0,dflt:1},setBackground:{valType:"any",dflt:!1},imageDataOnly:{valType:"boolean",dflt:!1}},c=/^data:image\/\w+;base64,/;e.exports=function(t,e){var r,u,h;function f(t){return!(t in e)||i.validate(e[t],l[t])}if(e=e||{},i.isPlainObject(t)?(r=t.data||[],u=t.layout||{},h=t.config||{}):(t=i.getGraphDiv(t),r=i.extendDeep([],t.data),u=i.extendDeep({},t.layout),h=t._context),!f("width")||!f("height"))throw new Error("Height and width should be pixel values.");if(!f("format"))throw new Error("Image format is not jpeg, png, svg or webp.");var p={};function d(t,r){return i.coerce(e,p,l,t,r)}var g=d("format"),m=d("width"),v=d("height"),y=d("scale"),x=d("setBackground"),b=d("imageDataOnly"),_=document.createElement("div");_.style.position="absolute",_.style.left="-5000px",document.body.appendChild(_);var w=i.extendFlat({},u);m&&(w.width=m),v&&(w.height=v);var k=i.extendFlat({},h,{staticPlot:!0,setBackground:x}),M=a.getRedrawFunc(_);function A(){return new Promise(function(t){setTimeout(t,a.getDelay(_._fullLayout))})}function T(){return new Promise(function(t,e){var r=o(_,g,y),a=_._fullLayout.width,l=_._fullLayout.height;if(n.purge(_),document.body.removeChild(_),"svg"===g)return t(b?r:"data:image/svg+xml,"+encodeURIComponent(r));var c=document.createElement("canvas");c.id=i.randstr(),s({format:g,width:a,height:l,scale:y,canvas:c,svg:r,promise:!0}).then(t).catch(e)})}return new Promise(function(t,e){n.plot(_,r,w,k).then(M).then(A).then(T).then(function(e){t(function(t){return b?t.replace(c,""):t}(e))}).catch(function(t){e(t)})})}},{"../lib":684,"../snapshot/helpers":821,"../snapshot/svgtoimg":823,"../snapshot/tosvg":825,"./plot_api":719}],726:[function(t,e,r){"use strict";var n=t("../lib"),i=t("../plots/plots"),a=t("./plot_schema"),o=t("./plot_config"),s=n.isPlainObject,l=Array.isArray,c=n.isArrayOrTypedArray;function u(t,e,r,i,a,o){o=o||[];for(var h=Object.keys(t),f=0;fx.length&&i.push(p("unused",a,v.concat(x.length)));var M,A,T,S,E,C=x.length,L=Array.isArray(k);if(L&&(C=Math.min(C,k.length)),2===b.dimensions)for(A=0;Ax[A].length&&i.push(p("unused",a,v.concat(A,x[A].length)));var z=x[A].length;for(M=0;M<(L?Math.min(z,k[A].length):z);M++)T=L?k[A][M]:k,S=y[A][M],E=x[A][M],n.validate(S,T)?E!==S&&E!==+S&&i.push(p("dynamic",a,v.concat(A,M),S,E)):i.push(p("value",a,v.concat(A,M),S))}else i.push(p("array",a,v.concat(A),y[A]));else for(A=0;A1&&f.push(p("object","layout"))),i.supplyDefaults(d);for(var g=d._fullData,m=r.length,v=0;v0&&c>0&&u/c>d&&(o=n,l=a,d=u/c);if(f===p){var y=f-1,x=f+1;h="tozero"===t.rangemode?f<0?[y,0]:[0,x]:"nonnegative"===t.rangemode?[Math.max(0,y),Math.max(0,x)]:[y,x]}else d&&("linear"!==t.type&&"-"!==t.type||("tozero"===t.rangemode?(o.val>=0&&(o={val:0,pad:0}),l.val<=0&&(l={val:0,pad:0})):"nonnegative"===t.rangemode&&(o.val-d*m(o)<0&&(o={val:0,pad:0}),l.val<0&&(l={val:1,pad:0})),d=(l.val-o.val)/(t._length-m(o)-m(l))),h=[o.val-d*m(o),l.val+d*m(l)]);return h[0]===h[1]&&("tozero"===t.rangemode?h=h[0]<0?[h[0],0]:h[0]>0?[0,h[0]]:[0,1]:(h=[h[0]-1,h[0]+1],"nonnegative"===t.rangemode&&(h[0]=Math.max(0,h[0])))),g&&h.reverse(),i.simpleMap(h,t.l2r||Number)}function s(t){var e=t._length/20;return"domain"===t.constrain&&t._inputDomain&&(e*=(t._inputDomain[1]-t._inputDomain[0])/(t.domain[1]-t.domain[0])),function(t){return t.pad+(t.extrapad?e:0)}}function l(t){return n(t)&&Math.abs(t)=e}e.exports={getAutoRange:o,makePadFn:s,doAutoRange:function(t){t._length||t.setScale();var e,r=t._min&&t._max&&t._min.length&&t._max.length;t.autorange&&r&&(t.range=o(t),t._r=t.range.slice(),t._rl=i.simpleMap(t._r,t.r2l),(e=t._input).range=t.range.slice(),e.autorange=t.autorange);if(t._anchorAxis&&t._anchorAxis.rangeslider){var n=t._anchorAxis.rangeslider[t._name];n&&"auto"===n.rangemode&&(n.range=r?o(t):t._rangeInitial?t._rangeInitial.slice():t.range.slice()),(e=t._anchorAxis._input).rangeslider[t._name]=i.extendFlat({},n)}},expand:function(t,e,r){if(!function(t){return t.autorange||t._rangesliderAutorange}(t)||!e)return;t._min||(t._min=[]);t._max||(t._max=[]);r||(r={});t._m||t.setScale();var i,o,s,h,f,p,d,g,m,v,y,x,b=e.length,_=r.padded||!1,w=r.tozero&&("linear"===t.type||"-"===t.type),k="log"===t.type,M=!1;function A(t){if(Array.isArray(t))return M=!0,function(e){return Math.max(Number(t[e]||0),0)};var e=Math.max(Number(t||0),0);return function(){return e}}var T=A((t._m>0?r.ppadplus:r.ppadminus)||r.ppad||0),S=A((t._m>0?r.ppadminus:r.ppadplus)||r.ppad||0),E=A(r.vpadplus||r.vpad),C=A(r.vpadminus||r.vpad);if(!M){if(y=1/0,x=-1/0,k)for(i=0;i0&&(y=h),h>x&&h-a&&(y=h),h>x&&h=b&&(h.extrapad||!_)){v=!1;break}M(i,h.val)&&h.pad<=b&&(_||!h.extrapad)&&(a.splice(o,1),o--)}if(v){var A=w&&0===i;a.push({val:i,pad:A?0:b,extrapad:!A&&_})}}}}var z=Math.min(6,b);for(i=0;i=z;i--)L(i)}}},{"../../constants/numerical":661,"../../lib":684,"fast-isnumeric":214}],732:[function(t,e,r){"use strict";var n=t("d3"),i=t("fast-isnumeric"),a=t("../../plots/plots"),o=t("../../registry"),s=t("../../lib"),l=t("../../lib/svg_text_utils"),c=t("../../components/titles"),u=t("../../components/color"),h=t("../../components/drawing"),f=t("../../constants/numerical"),p=f.ONEAVGYEAR,d=f.ONEAVGMONTH,g=f.ONEDAY,m=f.ONEHOUR,v=f.ONEMIN,y=f.ONESEC,x=f.MINUS_SIGN,b=f.BADNUM,_=t("../../constants/alignment").MID_SHIFT,w=t("../../constants/alignment").LINE_SPACING,k=e.exports={};k.setConvert=t("./set_convert");var M=t("./axis_autotype"),A=t("./axis_ids");k.id2name=A.id2name,k.name2id=A.name2id,k.cleanId=A.cleanId,k.list=A.list,k.listIds=A.listIds,k.getFromId=A.getFromId,k.getFromTrace=A.getFromTrace;var T=t("./autorange");k.expand=T.expand,k.getAutoRange=T.getAutoRange,k.coerceRef=function(t,e,r,n,i,a){var o=n.charAt(n.length-1),l=r._fullLayout._subplots[o+"axis"],c=n+"ref",u={};return i||(i=l[0]||a),a||(a=i),u[c]={valType:"enumerated",values:l.concat(a?[a]:[]),dflt:i},s.coerce(t,e,u,c)},k.coercePosition=function(t,e,r,n,i,a){var o,l;if("paper"===n||"pixel"===n)o=s.ensureNumber,l=r(i,a);else{var c=k.getFromId(e,n);l=r(i,a=c.fraction2r(a)),o=c.cleanPos}t[i]=o(l)},k.cleanPosition=function(t,e,r){return("paper"===r||"pixel"===r?s.ensureNumber:k.getFromId(e,r).cleanPos)(t)};var S=k.getDataConversions=function(t,e,r,n){var i,a="x"===r||"y"===r||"z"===r?r:n;if(Array.isArray(a)){if(i={type:M(n),_categories:[]},k.setConvert(i),"category"===i.type)for(var o=0;o2e-6||((r-t._forceTick0)/t._minDtick%1+1.000001)%1>2e-6)&&(t._minDtick=0)):t._minDtick=0},k.saveRangeInitial=function(t,e){for(var r=k.list(t,"",!0),n=!1,i=0;i.3*f||u(n)||u(a))){var p=r.dtick/2;t+=t+p.8){var o=Number(r.substr(1));a.exactYears>.8&&o%12==0?t=k.tickIncrement(t,"M6","reverse")+1.5*g:a.exactMonths>.8?t=k.tickIncrement(t,"M1","reverse")+15.5*g:t-=g/2;var l=k.tickIncrement(t,r);if(l<=n)return l}return t}(m,t,l.dtick,c,a)),d=m,0;d<=u;)d=k.tickIncrement(d,l.dtick,!1,a),0;return{start:e.c2r(m,0,a),end:e.c2r(d,0,a),size:l.dtick,_dataSpan:u-c}},k.prepTicks=function(t){var e=s.simpleMap(t.range,t.r2l);if("auto"===t.tickmode||!t.dtick){var r,n=t.nticks;n||("category"===t.type?(r=t.tickfont?1.2*(t.tickfont.size||12):15,n=t._length/r):(r="y"===t._id.charAt(0)?40:80,n=s.constrain(t._length/r,4,9)+1),"radialaxis"===t._name&&(n*=2)),"array"===t.tickmode&&(n*=100),k.autoTicks(t,Math.abs(e[1]-e[0])/n),t._minDtick>0&&t.dtick<2*t._minDtick&&(t.dtick=t._minDtick,t.tick0=t.l2r(t._forceTick0))}t.tick0||(t.tick0="date"===t.type?"2000-01-01":0),F(t)},k.calcTicks=function(t){k.prepTicks(t);var e=s.simpleMap(t.range,t.r2l);if("array"===t.tickmode)return function(t){var e,r,n=t.tickvals,i=t.ticktext,a=new Array(n.length),o=s.simpleMap(t.range,t.r2l),l=1.0001*o[0]-1e-4*o[1],c=1.0001*o[1]-1e-4*o[0],u=Math.min(l,c),h=Math.max(l,c),f=0;Array.isArray(i)||(i=[]);var p="category"===t.type?t.d2l_noadd:t.d2l;"log"===t.type&&"L"!==String(t.dtick).charAt(0)&&(t.dtick="L"+Math.pow(10,Math.floor(Math.min(t.range[0],t.range[1]))-1));for(r=0;ru&&e=n:c<=n)&&!(a.length>l||c===o);c=k.tickIncrement(c,t.dtick,i,t.calendar))o=c,a.push(c);"angular"===t._id&&360===Math.abs(e[1]-e[0])&&a.pop(),t._tmax=a[a.length-1],t._prevDateHead="",t._inCalcTicks=!0;for(var u=new Array(a.length),h=0;h10||"01-01"!==n.substr(5)?t._tickround="d":t._tickround=+e.substr(1)%12==0?"y":"m";else if(e>=g&&a<=10||e>=15*g)t._tickround="d";else if(e>=v&&a<=16||e>=m)t._tickround="M";else if(e>=y&&a<=19||e>=v)t._tickround="S";else{var o=t.l2r(r+e).replace(/^-/,"").length;t._tickround=Math.max(a,o)-20}}else if(i(e)||"L"===e.charAt(0)){var s=t.range.map(t.r2d||Number);i(e)||(e=Number(e.substr(1))),t._tickround=2-Math.floor(Math.log(e)/Math.LN10+.01);var l=Math.max(Math.abs(s[0]),Math.abs(s[1])),c=Math.floor(Math.log(l)/Math.LN10+.01);Math.abs(c)>3&&(V(t.exponentformat)&&!U(c)?t._tickexponent=3*Math.round((c-1)/3):t._tickexponent=c)}else t._tickround=null}function N(t,e,r){var n=t.tickfont||{};return{x:e,dx:0,dy:0,text:r||"",fontSize:n.size,font:n.family,fontColor:n.color}}k.autoTicks=function(t,e){var r;function n(t){return Math.pow(t,Math.floor(Math.log(e)/Math.LN10))}if("date"===t.type){t.tick0=s.dateTick0(t.calendar);var a=2*e;a>p?(e/=p,r=n(10),t.dtick="M"+12*B(e,r,L)):a>d?(e/=d,t.dtick="M"+B(e,1,z)):a>g?(t.dtick=B(e,g,I),t.tick0=s.dateTick0(t.calendar,!0)):a>m?t.dtick=B(e,m,z):a>v?t.dtick=B(e,v,P):a>y?t.dtick=B(e,y,P):(r=n(10),t.dtick=B(e,r,L))}else if("log"===t.type){t.tick0=0;var o=s.simpleMap(t.range,t.r2l);if(e>.7)t.dtick=Math.ceil(e);else if(Math.abs(o[1]-o[0])<1){var l=1.5*Math.abs((o[1]-o[0])/e);e=Math.abs(Math.pow(10,o[1])-Math.pow(10,o[0]))/l,r=n(10),t.dtick="L"+B(e,r,L)}else t.dtick=e>.3?"D2":"D1"}else"category"===t.type?(t.tick0=0,t.dtick=Math.ceil(Math.max(e,1))):"angular"===t._id?(t.tick0=0,r=1,t.dtick=B(e,r,R)):(t.tick0=0,r=n(10),t.dtick=B(e,r,L));if(0===t.dtick&&(t.dtick=1),!i(t.dtick)&&"string"!=typeof t.dtick){var c=t.dtick;throw t.dtick=1,"ax.dtick error: "+String(c)}},k.tickIncrement=function(t,e,r,a){var o=r?-1:1;if(i(e))return t+o*e;var l=e.charAt(0),c=o*Number(e.substr(1));if("M"===l)return s.incrementMonth(t,c,a);if("L"===l)return Math.log(Math.pow(10,t)+c)/Math.LN10;if("D"===l){var u="D2"===e?D:O,h=t+.01*o,f=s.roundUp(s.mod(h,1),u,r);return Math.floor(h)+Math.log(n.round(Math.pow(10,f),1))/Math.LN10}throw"unrecognized dtick "+String(e)},k.tickFirst=function(t){var e=t.r2l||Number,r=s.simpleMap(t.range,e),a=r[1]"+l,t._prevDateHead=l));e.text=c}(t,o,r,c):"log"===t.type?function(t,e,r,n,a){var o=t.dtick,l=e.x,c=t.tickformat;"never"===a&&(a="");!n||"string"==typeof o&&"L"===o.charAt(0)||(o="L3");if(c||"string"==typeof o&&"L"===o.charAt(0))e.text=q(Math.pow(10,l),t,a,n);else if(i(o)||"D"===o.charAt(0)&&s.mod(l+.01,1)<.1){var u=Math.round(l);-1!==["e","E","power"].indexOf(t.exponentformat)||V(t.exponentformat)&&U(u)?(e.text=0===u?1:1===u?"10":u>1?"10"+u+"":"10"+x+-u+"",e.fontSize*=1.25):(e.text=q(Math.pow(10,l),t,"","fakehover"),"D1"===o&&"y"===t._id.charAt(0)&&(e.dy-=e.fontSize/6))}else{if("D"!==o.charAt(0))throw"unrecognized dtick "+String(o);e.text=String(Math.round(Math.pow(10,s.mod(l,1)))),e.fontSize*=.75}if("D1"===t.dtick){var h=String(e.text).charAt(0);"0"!==h&&"1"!==h||("y"===t._id.charAt(0)?e.dx-=e.fontSize/4:(e.dy+=e.fontSize/2,e.dx+=(t.range[1]>t.range[0]?1:-1)*e.fontSize*(l<0?.5:.25)))}}(t,o,0,c,n):"category"===t.type?function(t,e){var r=t._categories[Math.round(e.x)];void 0===r&&(r="");e.text=String(r)}(t,o):"angular"===t._id?function(t,e,r,n,i){if("radians"!==t.thetaunit||r)e.text=q(e.x,t,i,n);else{var a=e.x/180;if(0===a)e.text="0";else{var o=function(t){function e(t,e){return Math.abs(t-e)<=1e-6}var r=function(t){var r=1;for(;!e(Math.round(t*r)/r,t);)r*=10;return r}(t),n=t*r,i=Math.abs(function t(r,n){return e(n,0)?r:t(n,r%n)}(n,r));return[Math.round(n/i),Math.round(r/i)]}(a);if(o[1]>=100)e.text=q(s.deg2rad(e.x),t,i,n);else{var l=e.x<0;1===o[1]?1===o[0]?e.text="\u03c0":e.text=o[0]+"\u03c0":e.text=["",o[0],"","\u2044","",o[1],"","\u03c0"].join(""),l&&(e.text=x+e.text)}}}}(t,o,r,c,n):function(t,e,r,n,i){"never"===i?i="":"all"===t.showexponent&&Math.abs(e.x/t.dtick)<1e-6&&(i="hide");e.text=q(e.x,t,i,n)}(t,o,0,c,n),t.tickprefix&&!p(t.showtickprefix)&&(o.text=t.tickprefix+o.text),t.ticksuffix&&!p(t.showticksuffix)&&(o.text+=t.ticksuffix),o},k.hoverLabelText=function(t,e,r){if(r!==b&&r!==e)return k.hoverLabelText(t,e)+" - "+k.hoverLabelText(t,r);var n="log"===t.type&&e<=0,i=k.tickText(t,t.c2l(n?-e:e),"hover").text;return n?0===e?"0":x+i:i};var j=["f","p","n","\u03bc","m","","k","M","G","T"];function V(t){return"SI"===t||"B"===t}function U(t){return t>14||t<-15}function q(t,e,r,n){var a=t<0,o=e._tickround,l=r||e.exponentformat||"B",c=e._tickexponent,u=k.getTickFormat(e),h=e.separatethousands;if(n){var f={exponentformat:l,dtick:"none"===e.showexponent?e.dtick:i(t)&&Math.abs(t)||1,range:"none"===e.showexponent?e.range.map(e.r2d):[0,t||1]};F(f),o=(Number(f._tickround)||0)+4,c=f._tickexponent,e.hoverformat&&(u=e.hoverformat)}if(u)return e._numFormat(u)(t).replace(/-/g,x);var p,d=Math.pow(10,-o)/2;if("none"===l&&(c=0),(t=Math.abs(t))"+p+"":"B"===l&&9===c?t+="B":V(l)&&(t+=j[c/3+5]));return a?x+t:t}function H(t,e){for(var r=0;r=0,a=u(t,e[1])<=0;return(r||i)&&(n||a)}if(t.tickformatstops&&t.tickformatstops.length>0)switch(t.type){case"date":case"linear":for(e=0;e=o(i)))){r=n;break}break;case"log":for(e=0;e1&&e1)for(n=1;n2*o}(t,e)?"date":function(t){for(var e,r=Math.max(1,(t.length-1)/1e3),n=0,o=0,s=0;s2*n}(t)?"category":function(t){if(!t)return!1;for(var e=0;en?1:-1:+(t.substr(1)||1)-+(e.substr(1)||1)}},{"../../registry":817,"./constants":737}],736:[function(t,e,r){"use strict";e.exports=function(t,e,r,n){if("category"===e.type){var i,a=t.categoryarray,o=Array.isArray(a)&&a.length>0;o&&(i="array");var s,l=r("categoryorder",i);"array"===l&&(s=r("categoryarray")),o||"array"!==l||(l=e.categoryorder="trace"),"trace"===l?e._initialCategories=[]:"array"===l?e._initialCategories=s.slice():(s=function(t,e){var r,n,i,a=e.dataAttr||t._id.charAt(0),o={};if(e.axData)r=e.axData;else for(r=[],n=0;no*y)||w)for(r=0;rP&&DL&&(L=D);f/=(L-C)/(2*z),C=c.l2r(C),L=c.l2r(L),c.range=c._input.range=T=0?Math.min(t,.9):1/(1/Math.max(t,-.3)+3.222))}function P(t,e,r,n,i){return t.append("path").attr("class","zoombox").style({fill:e>.2?"rgba(0,0,0,0)":"rgba(255,255,255,0)","stroke-width":0}).attr("transform","translate("+r+", "+n+")").attr("d",i+"Z")}function I(t,e,r){return t.append("path").attr("class","zoombox-corners").style({fill:u.background,stroke:u.defaultLine,"stroke-width":1,opacity:0}).attr("transform","translate("+e+", "+r+")").attr("d","M0,0Z")}function O(t,e,r,n,i,a){t.attr("d",n+"M"+r.l+","+r.t+"v"+r.h+"h"+r.w+"v-"+r.h+"h-"+r.w+"Z"),D(t,e,i,a)}function D(t,e,r,n){r||(t.transition().style("fill",n>.2?"rgba(0,0,0,0.4)":"rgba(255,255,255,0.3)").duration(200),e.transition().style("opacity",1).duration(200))}function R(t){n.select(t).selectAll(".zoombox,.js-zoombox-backdrop,.js-zoombox-menu,.zoombox-corners").remove()}function B(t){A&&t.data&&t._context.showTips&&(s.notifier(s._(t,"Double-click to zoom back out"),"long"),A=!1)}function F(t){return"lasso"===t||"select"===t}function N(t){var e=Math.floor(Math.min(t.b-t.t,t.r-t.l,M)/2);return"M"+(t.l-3.5)+","+(t.t-.5+e)+"h3v"+-e+"h"+e+"v-3h-"+(e+3)+"ZM"+(t.r+3.5)+","+(t.t-.5+e)+"h-3v"+-e+"h"+-e+"v-3h"+(e+3)+"ZM"+(t.r+3.5)+","+(t.b+.5-e)+"h-3v"+e+"h"+-e+"v3h"+(e+3)+"ZM"+(t.l-3.5)+","+(t.b+.5-e)+"h3v"+e+"h"+e+"v3h-"+(e+3)+"Z"}function j(t,e){if(a){var r=void 0!==t.onwheel?"wheel":"mousewheel";t._onwheel&&t.removeEventListener(r,t._onwheel),t._onwheel=e,t.addEventListener(r,e,{passive:!1})}else void 0!==t.onwheel?t.onwheel=e:void 0!==t.onmousewheel&&(t.onmousewheel=e)}function V(t){var e=[];for(var r in t)e.push(t[r]);return e}e.exports={makeDragBox:function(t,e,r,a,u,p,A,T){var D,U,q,H,G,W,Y,X,Z,$,J,K,Q,tt,et,rt,nt,it,at,ot,st,lt=t._fullLayout._zoomlayer,ct=A+T==="nsew",ut=1===(A+T).length;function ht(){if(D=e.xaxis,U=e.yaxis,Z=D._length,$=U._length,Y=D._offset,X=U._offset,(q={})[D._id]=D,(H={})[U._id]=U,A&&T)for(var r=e.overlays,n=0;nM||o>M?(bt="xy",a/Z>o/$?(o=a*$/Z,gt>i?mt.t=gt-o:mt.b=gt+o):(a=o*Z/$,dt>n?mt.l=dt-a:mt.r=dt+a),wt.attr("d",N(mt))):s():!Q||o10||r.scrollWidth-r.clientWidth>10)){clearTimeout(It);var n=-e.deltaY;if(isFinite(n)||(n=e.wheelDelta/10),isFinite(n)){var i,a=Math.exp(-Math.min(Math.max(n,-20),20)/200),o=Dt.draglayer.select(".nsewdrag").node().getBoundingClientRect(),l=(e.clientX-o.left)/o.width,c=(o.bottom-e.clientY)/o.height;if(rt){for(T||(l=.5),i=0;ig[1]-.01&&(e.domain=s),i.noneOrAll(t.domain,e.domain,s)}return r("layer"),e}},{"../../lib":684,"fast-isnumeric":214}],748:[function(t,e,r){"use strict";var n=t("../../constants/alignment").FROM_BL;e.exports=function(t,e,r){void 0===r&&(r=n[t.constraintoward||"center"]);var i=[t.r2l(t.range[0]),t.r2l(t.range[1])],a=i[0]+(i[1]-i[0])*r;t.range=t._input.range=[t.l2r(a+(i[0]-a)*e),t.l2r(a+(i[1]-a)*e)]}},{"../../constants/alignment":656}],749:[function(t,e,r){"use strict";var n=t("polybooljs"),i=t("../../registry"),a=t("../../components/color"),o=t("../../components/fx"),s=t("../../lib/polygon"),l=t("../../lib/throttle"),c=t("../../components/fx/helpers").makeEventData,u=t("./axis_ids").getFromId,h=t("../sort_modules").sortModules,f=t("./constants"),p=f.MINSELECT,d=s.filter,g=s.tester,m=s.multitester;function v(t){return t._id}function y(t,e,r){var n,a,o,s;if(r){var l=r.points||[];for(n=0;n0)return Math.log(e)/Math.LN10;if(e<=0&&r&&t.range&&2===t.range.length){var n=t.range[0],i=t.range[1];return.5*(n+i-3*u*Math.abs(n-i))}return f}function v(e,r,n){var a=l(e,n||t.calendar);if(a===f){if(!i(e))return f;a=l(new Date(+e))}return a}function y(e,r,n){return s(e,r,n||t.calendar)}function x(e){return t._categories[Math.round(e)]}function b(e){if(t._categoriesMap){var r=t._categoriesMap[e];if(void 0!==r)return r}if(i(e))return+e}function _(e){return i(e)?n.round(t._b+t._m*e,2):f}function w(e){return(e-t._b)/t._m}t.c2l="log"===t.type?m:c,t.l2c="log"===t.type?g:c,t.l2p=_,t.p2l=w,t.c2p="log"===t.type?function(t,e){return _(m(t,e))}:_,t.p2c="log"===t.type?function(t){return g(w(t))}:w,-1!==["linear","-"].indexOf(t.type)?(t.d2r=t.r2d=t.d2c=t.r2c=t.d2l=t.r2l=o,t.c2d=t.c2r=t.l2d=t.l2r=c,t.d2p=t.r2p=function(e){return t.l2p(o(e))},t.p2d=t.p2r=w,t.cleanPos=c):"log"===t.type?(t.d2r=t.d2l=function(t,e){return m(o(t),e)},t.r2d=t.r2c=function(t){return g(o(t))},t.d2c=t.r2l=o,t.c2d=t.l2r=c,t.c2r=m,t.l2d=g,t.d2p=function(e,r){return t.l2p(t.d2r(e,r))},t.p2d=function(t){return g(w(t))},t.r2p=function(e){return t.l2p(o(e))},t.p2r=w,t.cleanPos=c):"date"===t.type?(t.d2r=t.r2d=a.identity,t.d2c=t.r2c=t.d2l=t.r2l=v,t.c2d=t.c2r=t.l2d=t.l2r=y,t.d2p=t.r2p=function(e,r,n){return t.l2p(v(e,0,n))},t.p2d=t.p2r=function(t,e,r){return y(w(t),e,r)},t.cleanPos=function(e){return a.cleanDate(e,f,t.calendar)}):"category"===t.type&&(t.d2c=t.d2l=function(e){if(null!=e){if(void 0===t._categoriesMap&&(t._categoriesMap={}),void 0!==t._categoriesMap[e])return t._categoriesMap[e];t._categories.push(e);var r=t._categories.length-1;return t._categoriesMap[e]=r,r}return f},t.r2d=t.c2d=t.l2d=x,t.d2r=t.d2l_noadd=b,t.r2c=function(e){var r=b(e);return void 0!==r?r:t.fraction2r(.5)},t.l2r=t.c2r=c,t.r2l=b,t.d2p=function(e){return t.l2p(t.r2c(e))},t.p2d=function(t){return x(w(t))},t.r2p=t.d2p,t.p2r=w,t.cleanPos=function(t){return"string"==typeof t&&""!==t?t:c(t)}),t.fraction2r=function(e){var r=t.r2l(t.range[0]),n=t.r2l(t.range[1]);return t.l2r(r+e*(n-r))},t.r2fraction=function(e){var r=t.r2l(t.range[0]),n=t.r2l(t.range[1]);return(t.r2l(e)-r)/(n-r)},t.cleanRange=function(e,n){n||(n={}),e||(e="range");var o,s,l=a.nestedProperty(t,e).get();if(s=(s="date"===t.type?a.dfltRange(t.calendar):"y"===r?p.DFLTRANGEY:n.dfltRange||p.DFLTRANGEX).slice(),l&&2===l.length)for("date"===t.type&&(l[0]=a.cleanDate(l[0],f,t.calendar),l[1]=a.cleanDate(l[1],f,t.calendar)),o=0;o<2;o++)if("date"===t.type){if(!a.isDateTime(l[o],t.calendar)){t[e]=s;break}if(t.r2l(l[0])===t.r2l(l[1])){var c=a.constrain(t.r2l(l[0]),a.MIN_MS+1e3,a.MAX_MS-1e3);l[0]=t.l2r(c-1e3),l[1]=t.l2r(c+1e3);break}}else{if(!i(l[o])){if(!i(l[1-o])){t[e]=s;break}l[o]=l[1-o]*(o?10:.1)}if(l[o]<-h?l[o]=-h:l[o]>h&&(l[o]=h),l[0]===l[1]){var u=Math.max(1,Math.abs(1e-6*l[0]));l[0]-=u,l[1]+=u}}else a.nestedProperty(t,e).set(s)},t.setScale=function(n){var i=e._size;if(t._categories||(t._categories=[]),t._categoriesMap||(t._categoriesMap={}),t.overlaying){var a=d.getFromId({_fullLayout:e},t.overlaying);t.domain=a.domain}var o=n&&t._r?"_r":"range",s=t.calendar;t.cleanRange(o);var l=t.r2l(t[o][0],s),c=t.r2l(t[o][1],s);if("y"===r?(t._offset=i.t+(1-t.domain[1])*i.h,t._length=i.h*(t.domain[1]-t.domain[0]),t._m=t._length/(l-c),t._b=-t._m*c):(t._offset=i.l+t.domain[0]*i.w,t._length=i.w*(t.domain[1]-t.domain[0]),t._m=t._length/(c-l),t._b=-t._m*l),!isFinite(t._m)||!isFinite(t._b))throw e._replotting=!1,new Error("Something went wrong with axis scaling")},t.makeCalcdata=function(e,r){var n,i,o,s,l=t.type,c="date"===l&&e[r+"calendar"];if(r in e){if(n=e[r],s=e._length||n.length,a.isTypedArray(n)&&("linear"===l||"log"===l)){if(s===n.length)return n;if(n.subarray)return n.subarray(0,s)}for(i=new Array(s),o=0;o0?Number(c):l;else if("string"!=typeof c)e.dtick=l;else{var u=c.charAt(0),h=c.substr(1);((h=n(h)?Number(h):0)<=0||!("date"===o&&"M"===u&&h===Math.round(h)||"log"===o&&"L"===u||"log"===o&&"D"===u&&(1===h||2===h)))&&(e.dtick=l)}var f="date"===o?i.dateTick0(e.calendar):0,p=r("tick0",f);"date"===o?e.tick0=i.cleanDate(p,f):n(p)&&"D1"!==c&&"D2"!==c?e.tick0=Number(p):e.tick0=f}else{void 0===r("tickvals")?e.tickmode="auto":r("ticktext")}}},{"../../constants/numerical":661,"../../lib":684,"fast-isnumeric":214}],754:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../registry"),a=t("../../components/drawing"),o=t("./axes"),s=t("./constants").attrRegex;e.exports=function(t,e,r,l){var c=t._fullLayout,u=[];var h,f,p,d,g=function(t){var e,r,n,i,a={};for(e in t)if((r=e.split("."))[0].match(s)){var o=e.charAt(0),l=r[0];if(n=c[l],i={},Array.isArray(t[e])?i.to=t[e].slice(0):Array.isArray(t[e].range)&&(i.to=t[e].range.slice(0)),!i.to)continue;i.axisName=l,i.length=n._length,u.push(o),a[o]=i}return a}(e),m=Object.keys(g),v=function(t,e,r){var n,i,a,o=t._plots,s=[];for(n in o){var l=o[n];if(-1===s.indexOf(l)){var c=l.xaxis._id,u=l.yaxis._id,h=l.xaxis.range,f=l.yaxis.range;l.xaxis._r=l.xaxis.range.slice(),l.yaxis._r=l.yaxis.range.slice(),i=r[c]?r[c].to:h,a=r[u]?r[u].to:f,h[0]===i[0]&&h[1]===i[1]&&f[0]===a[0]&&f[1]===a[1]||-1===e.indexOf(c)&&-1===e.indexOf(u)||s.push(l)}}return s}(c,m,g);if(!v.length)return function(){function e(e,r,n){for(var i=0;i rect").call(a.setTranslate,0,0).call(a.setScale,1,1),t.plot.call(a.setTranslate,e._offset,r._offset).call(a.setScale,1,1);var n=t.plot.selectAll(".scatterlayer .trace");n.selectAll(".point").call(a.setPointGroupScale,1,1),n.selectAll(".textpoint").call(a.setTextPointsScale,1,1),n.call(a.hideOutsideRangePoints,t)}function x(e,r){var n,s,l,u=g[e.xaxis._id],h=g[e.yaxis._id],f=[];if(u){s=(n=t._fullLayout[u.axisName])._r,l=u.to,f[0]=(s[0]*(1-r)+r*l[0]-s[0])/(s[1]-s[0])*e.xaxis._length;var p=s[1]-s[0],d=l[1]-l[0];n.range[0]=s[0]*(1-r)+r*l[0],n.range[1]=s[1]*(1-r)+r*l[1],f[2]=e.xaxis._length*(1-r+r*d/p)}else f[0]=0,f[2]=e.xaxis._length;if(h){s=(n=t._fullLayout[h.axisName])._r,l=h.to,f[1]=(s[1]*(1-r)+r*l[1]-s[1])/(s[0]-s[1])*e.yaxis._length;var m=s[1]-s[0],v=l[1]-l[0];n.range[0]=s[0]*(1-r)+r*l[0],n.range[1]=s[1]*(1-r)+r*l[1],f[3]=e.yaxis._length*(1-r+r*v/m)}else f[1]=0,f[3]=e.yaxis._length;!function(e,r){var n,a=[];for(a=[e._id,r._id],n=0;nr.duration?(function(){for(var e={},r=0;r0&&i["_"+r+"axes"][e])return i;if((i[r+"axis"]||r)===e){if(s(i,r))return i;if((i[r]||[]).length||i[r+"0"])return i}}}(e,r,a);if(!l)return;if("histogram"===l.type&&a==={v:"y",h:"x"}[l.orientation||"v"])return void(t.type="linear");var c,u=a+"calendar",h=l[u];if(s(l,a)){var f=o(l),p=[];for(c=0;c0?".":"")+a;i.isPlainObject(o)?l(o,e,s,n+1):e(s,a,o)}})}r.manageCommandObserver=function(t,e,n,o){var s={},l=!0;e&&e._commandObserver&&(s=e._commandObserver),s.cache||(s.cache={}),s.lookupTable={};var c=r.hasSimpleAPICommandBindings(t,n,s.lookupTable);if(e&&e._commandObserver){if(c)return s;if(e._commandObserver.remove)return e._commandObserver.remove(),e._commandObserver=null,s}if(c){a(t,c,s.cache),s.check=function(){if(l){var e=a(t,c,s.cache);return e.changed&&o&&void 0!==s.lookupTable[e.value]&&(s.disable(),Promise.resolve(o({value:e.value,type:c.type,prop:c.prop,traces:c.traces,index:s.lookupTable[e.value]})).then(s.enable,s.enable)),e.changed}};for(var u=["plotly_relayout","plotly_redraw","plotly_restyle","plotly_update","plotly_animatingframe","plotly_afterplot"],h=0;hi*Math.PI/180}return!1},r.getPath=function(){return n.geo.path().projection(r)},r.getBounds=function(t){return r.getPath().bounds(t)},r.fitExtent=function(t,e){var n=t[1][0]-t[0][0],i=t[1][1]-t[0][1],a=r.clipExtent&&r.clipExtent();r.scale(150).translate([0,0]),a&&r.clipExtent(null);var o=r.getBounds(e),s=Math.min(n/(o[1][0]-o[0][0]),i/(o[1][1]-o[0][1])),l=+t[0][0]+(n-s*(o[1][0]+o[0][0]))/2,c=+t[0][1]+(i-s*(o[1][1]+o[0][1]))/2;return a&&r.clipExtent(a),r.scale(150*s).translate([l,c])},r.precision(d.precision),i&&r.clipAngle(i-d.clipPad);return r}(e);u.center([c.lon-l.lon,c.lat-l.lat]).rotate([-l.lon,-l.lat,l.roll]).parallels(s.parallels);var h=[[r.l+r.w*o.x[0],r.t+r.h*(1-o.y[1])],[r.l+r.w*o.x[1],r.t+r.h*(1-o.y[0])]],f=e.lonaxis,p=e.lataxis,g=function(t,e){var r=d.clipPad,n=t[0]+r,i=t[1]-r,a=e[0]+r,o=e[1]-r;n>0&&i<0&&(i+=360);var s=(i-n)/4;return{type:"Polygon",coordinates:[[[n,a],[n,o],[n+s,o],[n+2*s,o],[n+3*s,o],[i,o],[i,a],[i-s,a],[i-2*s,a],[i-3*s,a],[n,a]]]}}(f.range,p.range);u.fitExtent(h,g);var m=this.bounds=u.getBounds(g),v=this.fitScale=u.scale(),y=u.translate();if(!isFinite(m[0][0])||!isFinite(m[0][1])||!isFinite(m[1][0])||!isFinite(m[1][1])||isNaN(y[0])||isNaN(y[0])){for(var x=this.graphDiv,b=["projection.rotation","center","lonaxis.range","lataxis.range"],_="Invalid geo settings, relayout'ing to default view.",w={},k=0;k0&&k<0&&(k+=360);var M,A,T,S=(w+k)/2;if(!c){var E=u?s.projRotate:[S,0,0];M=r("projection.rotation.lon",E[0]),r("projection.rotation.lat",E[1]),r("projection.rotation.roll",E[2]),r("showcoastlines",!u)&&(r("coastlinecolor"),r("coastlinewidth")),r("showocean")&&r("oceancolor")}(c?(A=-96.6,T=38.7):(A=u?S:M,T=(_[0]+_[1])/2),r("center.lon",A),r("center.lat",T),h)&&r("projection.parallels",s.projParallels||[0,60]);r("projection.scale"),r("showland")&&r("landcolor"),r("showlakes")&&r("lakecolor"),r("showrivers")&&(r("rivercolor"),r("riverwidth")),r("showcountries",u&&"usa"!==a)&&(r("countrycolor"),r("countrywidth")),("usa"===a||"north america"===a&&50===n)&&(r("showsubunits",!0),r("subunitcolor"),r("subunitwidth")),u||r("showframe",!0)&&(r("framecolor"),r("framewidth")),r("bgcolor")}e.exports=function(t,e,r){n(t,e,r,{type:"geo",attributes:a,handleDefaults:s,partition:"y"})}},{"../../subplot_defaults":809,"../constants":760,"./layout_attributes":765}],765:[function(t,e,r){"use strict";var n=t("../../../components/color/attributes"),i=t("../../domain").attributes,a=t("../constants"),o=t("../../../plot_api/edit_types").overrideAll,s={range:{valType:"info_array",items:[{valType:"number"},{valType:"number"}]},showgrid:{valType:"boolean",dflt:!1},tick0:{valType:"number"},dtick:{valType:"number"},gridcolor:{valType:"color",dflt:n.lightLine},gridwidth:{valType:"number",min:0,dflt:1}};e.exports=o({domain:i({name:"geo"},{}),resolution:{valType:"enumerated",values:[110,50],dflt:110,coerceNumber:!0},scope:{valType:"enumerated",values:Object.keys(a.scopeDefaults),dflt:"world"},projection:{type:{valType:"enumerated",values:Object.keys(a.projNames)},rotation:{lon:{valType:"number"},lat:{valType:"number"},roll:{valType:"number"}},parallels:{valType:"info_array",items:[{valType:"number"},{valType:"number"}]},scale:{valType:"number",min:0,dflt:1}},center:{lon:{valType:"number"},lat:{valType:"number"}},showcoastlines:{valType:"boolean"},coastlinecolor:{valType:"color",dflt:n.defaultLine},coastlinewidth:{valType:"number",min:0,dflt:1},showland:{valType:"boolean",dflt:!1},landcolor:{valType:"color",dflt:a.landColor},showocean:{valType:"boolean",dflt:!1},oceancolor:{valType:"color",dflt:a.waterColor},showlakes:{valType:"boolean",dflt:!1},lakecolor:{valType:"color",dflt:a.waterColor},showrivers:{valType:"boolean",dflt:!1},rivercolor:{valType:"color",dflt:a.waterColor},riverwidth:{valType:"number",min:0,dflt:1},showcountries:{valType:"boolean"},countrycolor:{valType:"color",dflt:n.defaultLine},countrywidth:{valType:"number",min:0,dflt:1},showsubunits:{valType:"boolean"},subunitcolor:{valType:"color",dflt:n.defaultLine},subunitwidth:{valType:"number",min:0,dflt:1},showframe:{valType:"boolean"},framecolor:{valType:"color",dflt:n.defaultLine},framewidth:{valType:"number",min:0,dflt:1},bgcolor:{valType:"color",dflt:n.background},lonaxis:s,lataxis:s},"plot","from-root")},{"../../../components/color/attributes":557,"../../../plot_api/edit_types":715,"../../domain":757,"../constants":760}],766:[function(t,e,r){"use strict";e.exports=function(t){function e(t,e){return{type:"Feature",id:t.id,properties:t.properties,geometry:r(t.geometry,e)}}function r(e,n){if(!e)return null;if("GeometryCollection"===e.type)return{type:"GeometryCollection",geometries:object.geometries.map(function(t){return r(t,n)})};if(!c.hasOwnProperty(e.type))return null;var i=c[e.type];return t.geo.stream(e,n(i)),i.result()}t.geo.project=function(t,e){var i=e.stream;if(!i)throw new Error("not yet supported");return(t&&n.hasOwnProperty(t.type)?n[t.type]:r)(t,i)};var n={Feature:e,FeatureCollection:function(t,r){return{type:"FeatureCollection",features:t.features.map(function(t){return e(t,r)})}}},i=[],a=[],o={point:function(t,e){i.push([t,e])},result:function(){var t=i.length?i.length<2?{type:"Point",coordinates:i[0]}:{type:"MultiPoint",coordinates:i}:null;return i=[],t}},s={lineStart:u,point:function(t,e){i.push([t,e])},lineEnd:function(){i.length&&(a.push(i),i=[])},result:function(){var t=a.length?a.length<2?{type:"LineString",coordinates:a[0]}:{type:"MultiLineString",coordinates:a}:null;return a=[],t}},l={polygonStart:u,lineStart:u,point:function(t,e){i.push([t,e])},lineEnd:function(){var t=i.length;if(t){do{i.push(i[0].slice())}while(++t<4);a.push(i),i=[]}},polygonEnd:u,result:function(){if(!a.length)return null;var t=[],e=[];return a.forEach(function(r){!function(t){if((e=t.length)<4)return!1;for(var e,r=0,n=t[e-1][1]*t[0][0]-t[e-1][0]*t[0][1];++rn^p>n&&r<(f-c)*(n-u)/(p-u)+c&&(i=!i)}return i}(t[0],r))return t.push(e),!0})||t.push([e])}),a=[],t.length?t.length>1?{type:"MultiPolygon",coordinates:t}:{type:"Polygon",coordinates:t[0]}:null}},c={Point:o,MultiPoint:o,LineString:s,MultiLineString:s,Polygon:l,MultiPolygon:l,Sphere:l};function u(){}var h=1e-6,f=h*h,p=Math.PI,d=p/2,g=(Math.sqrt(p),p/180),m=180/p;function v(t){return t>1?d:t<-1?-d:Math.asin(t)}function y(t){return t>1?0:t<-1?p:Math.acos(t)}var x=t.geo.projection,b=t.geo.projectionMutator;function _(t,e){var r=(2+d)*Math.sin(e);e/=2;for(var n=0,i=1/0;n<10&&Math.abs(i)>h;n++){var a=Math.cos(e);e-=i=(e+Math.sin(e)*(a+2)-r)/(2*a*(1+a))}return[2/Math.sqrt(p*(4+p))*t*(1+Math.cos(e)),2*Math.sqrt(p/(4+p))*Math.sin(e)]}t.geo.interrupt=function(e){var r,n=[[[[-p,0],[0,d],[p,0]]],[[[-p,0],[0,-d],[p,0]]]];function i(t,r){for(var i=r<0?-1:1,a=n[+(r<0)],o=0,s=a.length-1;oa[o][2][0];++o);var l=e(t-a[o][1][0],r);return l[0]+=e(a[o][1][0],i*r>i*a[o][0][1]?a[o][0][1]:r)[0],l}e.invert&&(i.invert=function(t,a){for(var o=r[+(a<0)],s=n[+(a<0)],c=0,u=o.length;c=0;--i){var o=n[1][i],l=180*o[0][0]/p,c=180*o[0][1]/p,u=180*o[1][1]/p,h=180*o[2][0]/p,f=180*o[2][1]/p;r.push(s([[h-e,f-e],[h-e,u+e],[l+e,u+e],[l+e,c-e]],30))}return{type:"Polygon",coordinates:[t.merge(r)]}}(),l)},i},a.lobes=function(t){return arguments.length?(n=t.map(function(t){return t.map(function(t){return[[t[0][0]*p/180,t[0][1]*p/180],[t[1][0]*p/180,t[1][1]*p/180],[t[2][0]*p/180,t[2][1]*p/180]]})}),r=n.map(function(t){return t.map(function(t){var r,n=e(t[0][0],t[0][1])[0],i=e(t[2][0],t[2][1])[0],a=e(t[1][0],t[0][1])[1],o=e(t[1][0],t[1][1])[1];return a>o&&(r=a,a=o,o=r),[[n,a],[i,o]]})}),a):n.map(function(t){return t.map(function(t){return[[180*t[0][0]/p,180*t[0][1]/p],[180*t[1][0]/p,180*t[1][1]/p],[180*t[2][0]/p,180*t[2][1]/p]]})})},a},_.invert=function(t,e){var r=.5*e*Math.sqrt((4+p)/p),n=v(r),i=Math.cos(n);return[t/(2/Math.sqrt(p*(4+p))*(1+i)),v((n+r*(i+2))/(2+d))]},(t.geo.eckert4=function(){return x(_)}).raw=_;var w=t.geo.azimuthalEqualArea.raw;function k(t,e){if(arguments.length<2&&(e=t),1===e)return w;if(e===1/0)return M;function r(r,n){var i=w(r/e,n);return i[0]*=t,i}return r.invert=function(r,n){var i=w.invert(r/t,n);return i[0]*=e,i},r}function M(t,e){return[t*Math.cos(e)/Math.cos(e/=2),2*Math.sin(e)]}function A(t,e){return[3*t/(2*p)*Math.sqrt(p*p/3-e*e),e]}function T(t,e){return[t,1.25*Math.log(Math.tan(p/4+.4*e))]}function S(t){return function(e){var r,n=t*Math.sin(e),i=30;do{e-=r=(e+Math.sin(e)-n)/(1+Math.cos(e))}while(Math.abs(r)>h&&--i>0);return e/2}}M.invert=function(t,e){var r=2*v(e/2);return[t*Math.cos(r/2)/Math.cos(r),r]},(t.geo.hammer=function(){var t=2,e=b(k),r=e(t);return r.coefficient=function(r){return arguments.length?e(t=+r):t},r}).raw=k,A.invert=function(t,e){return[2/3*p*t/Math.sqrt(p*p/3-e*e),e]},(t.geo.kavrayskiy7=function(){return x(A)}).raw=A,T.invert=function(t,e){return[t,2.5*Math.atan(Math.exp(.8*e))-.625*p]},(t.geo.miller=function(){return x(T)}).raw=T,S(p);var E=function(t,e,r){var n=S(r);function i(r,i){return[t*r*Math.cos(i=n(i)),e*Math.sin(i)]}return i.invert=function(n,i){var a=v(i/e);return[n/(t*Math.cos(a)),v((2*a+Math.sin(2*a))/r)]},i}(Math.SQRT2/d,Math.SQRT2,p);function C(t,e){var r=e*e,n=r*r;return[t*(.8707-.131979*r+n*(n*(.003971*r-.001529*n)-.013791)),e*(1.007226+r*(.015085+n*(.028874*r-.044475-.005916*n)))]}(t.geo.mollweide=function(){return x(E)}).raw=E,C.invert=function(t,e){var r,n=e,i=25;do{var a=n*n,o=a*a;n-=r=(n*(1.007226+a*(.015085+o*(.028874*a-.044475-.005916*o)))-e)/(1.007226+a*(.045255+o*(.259866*a-.311325-.005916*11*o)))}while(Math.abs(r)>h&&--i>0);return[t/(.8707+(a=n*n)*(a*(a*a*a*(.003971-.001529*a)-.013791)-.131979)),n]},(t.geo.naturalEarth=function(){return x(C)}).raw=C;var L=[[.9986,-.062],[1,0],[.9986,.062],[.9954,.124],[.99,.186],[.9822,.248],[.973,.31],[.96,.372],[.9427,.434],[.9216,.4958],[.8962,.5571],[.8679,.6176],[.835,.6769],[.7986,.7346],[.7597,.7903],[.7186,.8435],[.6732,.8936],[.6213,.9394],[.5722,.9761],[.5322,1]];function z(t,e){var r,n=Math.min(18,36*Math.abs(e)/p),i=Math.floor(n),a=n-i,o=(r=L[i])[0],s=r[1],l=(r=L[++i])[0],c=r[1],u=(r=L[Math.min(19,++i)])[0],h=r[1];return[t*(l+a*(u-o)/2+a*a*(u-2*l+o)/2),(e>0?d:-d)*(c+a*(h-s)/2+a*a*(h-2*c+s)/2)]}function P(t,e){return[t*Math.cos(e),e]}function I(t,e){var r,n=Math.cos(e),i=(r=y(n*Math.cos(t/=2)))?r/Math.sin(r):1;return[2*n*Math.sin(t)*i,Math.sin(e)*i]}function O(t,e){var r=I(t,e);return[(r[0]+t/d)/2,(r[1]+e)/2]}L.forEach(function(t){t[1]*=1.0144}),z.invert=function(t,e){var r=e/d,n=90*r,i=Math.min(18,Math.abs(n/5)),a=Math.max(0,Math.floor(i));do{var o=L[a][1],s=L[a+1][1],l=L[Math.min(19,a+2)][1],c=l-o,u=l-2*s+o,h=2*(Math.abs(r)-s)/c,p=u/c,v=h*(1-p*h*(1-2*p*h));if(v>=0||1===a){n=(e>=0?5:-5)*(v+i);var y,x=50;do{v=(i=Math.min(18,Math.abs(n)/5))-(a=Math.floor(i)),o=L[a][1],s=L[a+1][1],l=L[Math.min(19,a+2)][1],n-=(y=(e>=0?d:-d)*(s+v*(l-o)/2+v*v*(l-2*s+o)/2)-e)*m}while(Math.abs(y)>f&&--x>0);break}}while(--a>=0);var b=L[a][0],_=L[a+1][0],w=L[Math.min(19,a+2)][0];return[t/(_+v*(w-b)/2+v*v*(w-2*_+b)/2),n*g]},(t.geo.robinson=function(){return x(z)}).raw=z,P.invert=function(t,e){return[t/Math.cos(e),e]},(t.geo.sinusoidal=function(){return x(P)}).raw=P,I.invert=function(t,e){if(!(t*t+4*e*e>p*p+h)){var r=t,n=e,i=25;do{var a,o=Math.sin(r),s=Math.sin(r/2),l=Math.cos(r/2),c=Math.sin(n),u=Math.cos(n),f=Math.sin(2*n),d=c*c,g=u*u,m=s*s,v=1-g*l*l,x=v?y(u*l)*Math.sqrt(a=1/v):a=0,b=2*x*u*s-t,_=x*c-e,w=a*(g*m+x*u*l*d),k=a*(.5*o*f-2*x*c*s),M=.25*a*(f*s-x*c*g*o),A=a*(d*l+x*m*u),T=k*M-A*w;if(!T)break;var S=(_*k-b*A)/T,E=(b*M-_*w)/T;r-=S,n-=E}while((Math.abs(S)>h||Math.abs(E)>h)&&--i>0);return[r,n]}},(t.geo.aitoff=function(){return x(I)}).raw=I,O.invert=function(t,e){var r=t,n=e,i=25;do{var a,o=Math.cos(n),s=Math.sin(n),l=Math.sin(2*n),c=s*s,u=o*o,f=Math.sin(r),p=Math.cos(r/2),g=Math.sin(r/2),m=g*g,v=1-u*p*p,x=v?y(o*p)*Math.sqrt(a=1/v):a=0,b=.5*(2*x*o*g+r/d)-t,_=.5*(x*s+n)-e,w=.5*a*(u*m+x*o*p*c)+.5/d,k=a*(f*l/4-x*s*g),M=.125*a*(l*g-x*s*u*f),A=.5*a*(c*p+x*m*o)+.5,T=k*M-A*w,S=(_*k-b*A)/T,E=(b*M-_*w)/T;r-=S,n-=E}while((Math.abs(S)>h||Math.abs(E)>h)&&--i>0);return[r,n]},(t.geo.winkel3=function(){return x(O)}).raw=O}},{}],767:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../lib"),a=Math.PI/180,o=180/Math.PI,s={cursor:"pointer"},l={cursor:"auto"};function c(t,e){return n.behavior.zoom().translate(e.translate()).scale(e.scale())}function u(t,e,r){var n=t.id,a=t.graphDiv,o=a.layout[n],s=a._fullLayout[n],l={};function c(t,e){var r=i.nestedProperty(s,t);r.get()!==e&&(r.set(e),i.nestedProperty(o,t).set(e),l[n+"."+t]=e)}r(c),c("projection.scale",e.scale()/t.fitScale),a.emit("plotly_relayout",l)}function h(t,e){var r=c(0,e);function i(r){var n=e.invert(t.midPt);r("center.lon",n[0]),r("center.lat",n[1])}return r.on("zoomstart",function(){n.select(this).style(s)}).on("zoom",function(){e.scale(n.event.scale).translate(n.event.translate),t.render()}).on("zoomend",function(){n.select(this).style(l),u(t,e,i)}),r}function f(t,e){var r,i,a,o,h,f,p,d,g,m=c(0,e),v=2;function y(t){return e.invert(t)}function x(r){var n=e.rotate(),i=e.invert(t.midPt);r("projection.rotation.lon",-n[0]),r("center.lon",i[0]),r("center.lat",i[1])}return m.on("zoomstart",function(){n.select(this).style(s),r=n.mouse(this),i=e.rotate(),a=e.translate(),o=i,h=y(r)}).on("zoom",function(){if(f=n.mouse(this),function(t){var r=y(t);if(!r)return!0;var n=e(r);return Math.abs(n[0]-t[0])>v||Math.abs(n[1]-t[1])>v}(r))return m.scale(e.scale()),void m.translate(e.translate());e.scale(n.event.scale),e.translate([a[0],n.event.translate[1]]),h?y(f)&&(d=y(f),p=[o[0]+(d[0]-h[0]),i[1],i[2]],e.rotate(p),o=p):h=y(r=f),g=!0,t.render()}).on("zoomend",function(){n.select(this).style(l),g&&u(t,e,x)}),m}function p(t,e){var r,i={r:e.rotate(),k:e.scale()},h=c(0,e),f=function(t){var e=0,r=arguments.length,i=[];for(;++ed?(a=(h>0?90:-90)-p,i=0):(a=Math.asin(h/d)*o-p,i=Math.sqrt(d*d-h*h));var m=180-a-2*p,y=(Math.atan2(f,u)-Math.atan2(c,i))*o,x=(Math.atan2(f,u)-Math.atan2(c,-i))*o,b=g(r[0],r[1],a,y),_=g(r[0],r[1],m,x);return b<=_?[a,y,r[2]]:[m,x,r[2]]}(k,r,E);isFinite(M[0])&&isFinite(M[1])&&isFinite(M[2])||(M=E),e.rotate(M),E=M}}else r=d(e,T=b);f.of(this,arguments)({type:"zoom"})}),A=f.of(this,arguments),p++||A({type:"zoomstart"})}).on("zoomend",function(){var r;n.select(this).style(l),m.call(h,"zoom",null),r=f.of(this,arguments),--p||r({type:"zoomend"}),u(t,e,x)}).on("zoom.redraw",function(){t.render()}),n.rebind(h,f,"on")}function d(t,e){var r=t.invert(e);return r&&isFinite(r[0])&&isFinite(r[1])&&function(t){var e=t[0]*a,r=t[1]*a,n=Math.cos(r);return[n*Math.cos(e),n*Math.sin(e),Math.sin(r)]}(r)}function g(t,e,r,n){var i=m(r-t),a=m(n-e);return Math.sqrt(i*i+a*a)}function m(t){return(t%360+540)%360-180}function v(t,e,r){var n=r*a,i=t.slice(),o=0===e?1:0,s=2===e?1:2,l=Math.cos(n),c=Math.sin(n);return i[o]=t[o]*l-t[s]*c,i[s]=t[s]*l+t[o]*c,i}function y(t,e){for(var r=0,n=0,i=t.length;nMath.abs(s)?(c.boxEnd[1]=c.boxStart[1]+Math.abs(a)*_*(s>=0?1:-1),c.boxEnd[1]l[3]&&(c.boxEnd[1]=l[3],c.boxEnd[0]=c.boxStart[0]+(l[3]-c.boxStart[1])/Math.abs(_))):(c.boxEnd[0]=c.boxStart[0]+Math.abs(s)/_*(a>=0?1:-1),c.boxEnd[0]l[2]&&(c.boxEnd[0]=l[2],c.boxEnd[1]=c.boxStart[1]+(l[2]-c.boxStart[0])*Math.abs(_)))}}else c.boxEnabled?(a=c.boxStart[0]!==c.boxEnd[0],s=c.boxStart[1]!==c.boxEnd[1],a||s?(a&&(m(0,c.boxStart[0],c.boxEnd[0]),t.xaxis.autorange=!1),s&&(m(1,c.boxStart[1],c.boxEnd[1]),t.yaxis.autorange=!1),t.relayoutCallback()):t.glplot.setDirty(),c.boxEnabled=!1,c.boxInited=!1):c.boxInited&&(c.boxInited=!1);break;case"pan":c.boxEnabled=!1,c.boxInited=!1,e?(c.panning||(c.dragStart[0]=n,c.dragStart[1]=i),Math.abs(c.dragStart[0]-n)Math.abs(e))c.rotate(a,0,0,-t*r*Math.PI*d.rotateSpeed/window.innerWidth);else{var o=-d.zoomSpeed*i*e/window.innerHeight*(a-c.lastT())/20;c.pan(a,0,0,h*(Math.exp(o)-1))}}},!0),d};var n=t("right-now"),i=t("3d-view"),a=t("mouse-change"),o=t("mouse-wheel"),s=t("mouse-event-offset"),l=t("has-passive-events")},{"3d-view":43,"has-passive-events":379,"mouse-change":402,"mouse-event-offset":403,"mouse-wheel":405,"right-now":465}],774:[function(t,e,r){"use strict";var n=t("../../plot_api/edit_types").overrideAll,i=t("../../components/fx/layout_attributes"),a=t("./scene"),o=t("../get_data").getSubplotData,s=t("../../lib"),l=t("../../constants/xmlns_namespaces");r.name="gl3d",r.attr="scene",r.idRoot="scene",r.idRegex=r.attrRegex=s.counterRegex("scene"),r.attributes=t("./layout/attributes"),r.layoutAttributes=t("./layout/layout_attributes"),r.baseLayoutAttrOverrides=n({hoverlabel:i.hoverlabel},"plot","nested"),r.supplyLayoutDefaults=t("./layout/defaults"),r.plot=function(t){for(var e=t._fullLayout,r=t._fullData,n=e._subplots.gl3d,i=0;i1;o(t,e,r,{type:"gl3d",attributes:l,handleDefaults:c,fullLayout:e,font:e.font,fullData:r,getDfltFromLayout:function(e){if(!i)return n.validate(t[e],l[e])?t[e]:void 0},paper_bgcolor:e.paper_bgcolor,calendar:e.calendar})}},{"../../../components/color":558,"../../../lib":684,"../../../registry":817,"../../subplot_defaults":809,"./axis_defaults":777,"./layout_attributes":780}],780:[function(t,e,r){"use strict";var n=t("./axis_attributes"),i=t("../../domain").attributes,a=t("../../../lib/extend").extendFlat,o=t("../../../lib").counterRegex;function s(t,e,r){return{x:{valType:"number",dflt:t,editType:"camera"},y:{valType:"number",dflt:e,editType:"camera"},z:{valType:"number",dflt:r,editType:"camera"},editType:"camera"}}e.exports={_arrayAttrRegexps:[o("scene",".annotations",!0)],bgcolor:{valType:"color",dflt:"rgba(0,0,0,0)",editType:"plot"},camera:{up:a(s(0,0,1),{}),center:a(s(0,0,0),{}),eye:a(s(1.25,1.25,1.25),{}),editType:"camera"},domain:i({name:"scene",editType:"plot"}),aspectmode:{valType:"enumerated",values:["auto","cube","data","manual"],dflt:"auto",editType:"plot",impliedEdits:{"aspectratio.x":void 0,"aspectratio.y":void 0,"aspectratio.z":void 0}},aspectratio:{x:{valType:"number",min:0,editType:"plot",impliedEdits:{"^aspectmode":"manual"}},y:{valType:"number",min:0,editType:"plot",impliedEdits:{"^aspectmode":"manual"}},z:{valType:"number",min:0,editType:"plot",impliedEdits:{"^aspectmode":"manual"}},editType:"plot",impliedEdits:{aspectmode:"manual"}},xaxis:n,yaxis:n,zaxis:n,dragmode:{valType:"enumerated",values:["orbit","turntable","zoom","pan",!1],dflt:"turntable",editType:"plot"},hovermode:{valType:"enumerated",values:["closest",!1],dflt:"closest",editType:"modebar"},editType:"plot",_deprecated:{cameraposition:{valType:"info_array",editType:"camera"}}}},{"../../../lib":684,"../../../lib/extend":673,"../../domain":757,"./axis_attributes":776}],781:[function(t,e,r){"use strict";var n=t("../../../lib/str2rgbarray"),i=["xaxis","yaxis","zaxis"];function a(){this.enabled=[!0,!0,!0],this.colors=[[0,0,0,1],[0,0,0,1],[0,0,0,1]],this.drawSides=[!0,!0,!0],this.lineWidth=[1,1,1]}a.prototype.merge=function(t){for(var e=0;e<3;++e){var r=t[i[e]];r.visible?(this.enabled[e]=r.showspikes,this.colors[e]=n(r.spikecolor),this.drawSides[e]=r.spikesides,this.lineWidth[e]=r.spikethickness):(this.enabled[e]=!1,this.drawSides[e]=!1)}},e.exports=function(t){var e=new a;return e.merge(t),e}},{"../../../lib/str2rgbarray":707}],782:[function(t,e,r){"use strict";e.exports=function(t){for(var e=t.axesOptions,r=t.glplot.axesPixels,l=t.fullSceneLayout,c=[[],[],[]],u=0;u<3;++u){var h=l[o[u]];if(h._length=(r[u].hi-r[u].lo)*r[u].pixelsPerDataUnit/t.dataScale[u],Math.abs(h._length)===1/0)c[u]=[];else{h._input_range=h.range.slice(),h.range[0]=r[u].lo/t.dataScale[u],h.range[1]=r[u].hi/t.dataScale[u],h._m=1/(t.dataScale[u]*r[u].pixelsPerDataUnit),h.range[0]===h.range[1]&&(h.range[0]-=1,h.range[1]+=1);var f=h.tickmode;if("auto"===h.tickmode){h.tickmode="linear";var p=h.nticks||i.constrain(h._length/40,4,9);n.autoTicks(h,Math.abs(h.range[1]-h.range[0])/p)}for(var d=n.calcTicks(h),g=0;g")}else m=c.textLabel;t.fullSceneLayout.hovermode&&h.loneHover({x:(.5+.5*d[0]/d[3])*i,y:(.5-.5*d[1]/d[3])*a,xLabel:w,yLabel:k,zLabel:M,text:m,name:l.name,color:h.castHoverOption(e,v,"bgcolor")||l.color,borderColor:h.castHoverOption(e,v,"bordercolor"),fontFamily:h.castHoverOption(e,v,"font.family"),fontSize:h.castHoverOption(e,v,"font.size"),fontColor:h.castHoverOption(e,v,"font.color")},{container:r,gd:t.graphDiv});var T={x:c.traceCoordinate[0],y:c.traceCoordinate[1],z:c.traceCoordinate[2],data:e._input,fullData:e,curveNumber:e.index,pointNumber:v};e._module.eventData&&(T=e._module.eventData(T,c,e,{},v)),h.appendArrayPointValue(T,e,v);var S={points:[T]};c.buttons&&c.distance<5?t.graphDiv.emit("plotly_click",S):t.graphDiv.emit("plotly_hover",S),o=S}else h.loneUnhover(r),t.graphDiv.emit("plotly_unhover",o);t.drawAnnotations(t)}.bind(null,t),t.traces={},!0}function b(t,e){var r=document.createElement("div"),n=t.container;this.graphDiv=t.graphDiv;var i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.style.position="absolute",i.style.top=i.style.left="0px",i.style.width=i.style.height="100%",i.style["z-index"]=20,i.style["pointer-events"]="none",r.appendChild(i),this.svgContainer=i,r.id=t.id,r.style.position="absolute",r.style.top=r.style.left="0px",r.style.width=r.style.height="100%",n.appendChild(r),this.fullLayout=e,this.id=t.id||"scene",this.fullSceneLayout=e[this.id],this.plotArgs=[[],{},{}],this.axesOptions=m(e[this.id]),this.spikeOptions=v(e[this.id]),this.container=r,this.staticMode=!!t.staticPlot,this.pixelRatio=t.plotGlPixelRatio||2,this.dataScale=[1,1,1],this.contourLevels=[[],[],[]],this.convertAnnotations=l.getComponentMethod("annotations3d","convert"),this.drawAnnotations=l.getComponentMethod("annotations3d","draw"),x(this)}var _=b.prototype;_.recoverContext=function(){var t=this,e=this.glplot.gl,r=this.glplot.canvas;this.glplot.dispose(),requestAnimationFrame(function n(){e.isContextLost()?requestAnimationFrame(n):x(t,t.fullLayout,r,e)?t.plot.apply(t,t.plotArgs):c.error("Catastrophic and unrecoverable WebGL error. Context lost.")})};var w=["xaxis","yaxis","zaxis"];function k(t,e,r){for(var n=t.fullSceneLayout,i=0;i<3;i++){var a=w[i],o=a.charAt(0),s=n[a],l=e[o],u=e[o+"calendar"],h=e["_"+o+"length"];if(c.isArrayOrTypedArray(l))for(var f,p=0;p<(h||l.length);p++)if(c.isArrayOrTypedArray(l[p]))for(var d=0;dh[1][o]?p[o]=1:h[1][o]===h[0][o]?p[o]=1:p[o]=1/(h[1][o]-h[0][o]);for(this.dataScale=p,this.convertAnnotations(this),a=0;ag[1][a])g[0][a]=-1,g[1][a]=1;else{var E=g[1][a]-g[0][a];g[0][a]-=E/32,g[1][a]+=E/32}}else{var C=s.range;g[0][a]=s.r2l(C[0]),g[1][a]=s.r2l(C[1])}g[0][a]===g[1][a]&&(g[0][a]-=1,g[1][a]+=1),m[a]=g[1][a]-g[0][a],this.glplot.bounds[0][a]=g[0][a]*p[a],this.glplot.bounds[1][a]=g[1][a]*p[a]}var L=[1,1,1];for(a=0;a<3;++a){var z=v[l=(s=c[w[a]]).type];L[a]=Math.pow(z.acc,1/z.count)/p[a]}var P;if("auto"===c.aspectmode)P=Math.max.apply(null,L)/Math.min.apply(null,L)<=4?L:[1,1,1];else if("cube"===c.aspectmode)P=[1,1,1];else if("data"===c.aspectmode)P=L;else{if("manual"!==c.aspectmode)throw new Error("scene.js aspectRatio was not one of the enumerated types");var I=c.aspectratio;P=[I.x,I.y,I.z]}c.aspectratio.x=u.aspectratio.x=P[0],c.aspectratio.y=u.aspectratio.y=P[1],c.aspectratio.z=u.aspectratio.z=P[2],this.glplot.aspect=P;var O=c.domain||null,D=e._size||null;if(O&&D){var R=this.container.style;R.position="absolute",R.left=D.l+O.x[0]*D.w+"px",R.top=D.t+(1-O.y[1])*D.h+"px",R.width=D.w*(O.x[1]-O.x[0])+"px",R.height=D.h*(O.y[1]-O.y[0])+"px"}this.glplot.redraw()}},_.destroy=function(){this.glplot&&(this.camera.mouseListener.enabled=!1,this.container.removeEventListener("wheel",this.camera.wheelListener),this.camera=this.glplot.camera=null,this.glplot.dispose(),this.container.parentNode.removeChild(this.container),this.glplot=null)},_.getCamera=function(){return this.glplot.camera.view.recalcMatrix(this.camera.view.lastT()),M(this.glplot.camera)},_.setCamera=function(t){var e;this.glplot.camera.lookAt.apply(this,[[(e=t).eye.x,e.eye.y,e.eye.z],[e.center.x,e.center.y,e.center.z],[e.up.x,e.up.y,e.up.z]])},_.saveCamera=function(t){var e=this.getCamera(),r=c.nestedProperty(t,this.id+".camera"),n=r.get(),i=!1;function a(t,e,r,n){var i=["up","center","eye"],a=["x","y","z"];return e[i[r]]&&t[i[r]][a[n]]===e[i[r]][a[n]]}if(void 0===n)i=!0;else for(var o=0;o<3;o++)for(var s=0;s<3;s++)if(!a(e,n,o,s)){i=!0;break}return i&&r.set(e),i},_.updateFx=function(t,e){var r=this.camera;r&&("orbit"===t?(r.mode="orbit",r.keyBindingMode="rotate"):"turntable"===t?(r.up=[0,0,1],r.mode="turntable",r.keyBindingMode="rotate"):r.keyBindingMode=t),this.fullSceneLayout.hovermode=e},_.toImage=function(t){t||(t="png"),this.staticMode&&this.container.appendChild(n),this.glplot.redraw();var e=this.glplot.gl,r=e.drawingBufferWidth,i=e.drawingBufferHeight;e.bindFramebuffer(e.FRAMEBUFFER,null);var a=new Uint8Array(r*i*4);e.readPixels(0,0,r,i,e.RGBA,e.UNSIGNED_BYTE,a);for(var o=0,s=i-1;o0)}function l(t){var e={},r={};switch(t.type){case"circle":n.extendFlat(r,{"circle-radius":t.circle.radius,"circle-color":t.color,"circle-opacity":t.opacity});break;case"line":n.extendFlat(r,{"line-width":t.line.width,"line-color":t.color,"line-opacity":t.opacity});break;case"fill":n.extendFlat(r,{"fill-color":t.color,"fill-outline-color":t.fill.outlinecolor,"fill-opacity":t.opacity});break;case"symbol":var a=t.symbol,o=i(a.textposition,a.iconsize);n.extendFlat(e,{"icon-image":a.icon+"-15","icon-size":a.iconsize/10,"text-field":a.text,"text-size":a.textfont.size,"text-anchor":o.anchor,"text-offset":o.offset}),n.extendFlat(r,{"icon-color":t.color,"text-color":a.textfont.color,"text-opacity":t.opacity})}return{layout:e,paint:r}}o.update=function(t){this.visible?this.needsNewSource(t)?(this.removeLayer(),this.updateSource(t),this.updateLayer(t)):this.needsNewLayer(t)?this.updateLayer(t):this.updateStyle(t):(this.updateSource(t),this.updateLayer(t)),this.visible=s(t)},o.needsNewSource=function(t){return this.sourceType!==t.sourcetype||this.source!==t.source||this.layerType!==t.type},o.needsNewLayer=function(t){return this.layerType!==t.type||this.below!==t.below},o.updateSource=function(t){var e=this.map;if(e.getSource(this.idSource)&&e.removeSource(this.idSource),this.sourceType=t.sourcetype,this.source=t.source,s(t)){var r=function(t){var e,r=t.sourcetype,n=t.source,i={type:r};"geojson"===r?e="data":"vector"===r&&(e="string"==typeof n?"url":"tiles");return i[e]=n,i}(t);e.addSource(this.idSource,r)}},o.updateLayer=function(t){var e=this.map,r=l(t);this.removeLayer(),this.layerType=t.type,s(t)&&e.addLayer({id:this.idLayer,source:this.idSource,"source-layer":t.sourcelayer||"",type:t.type,layout:r.layout,paint:r.paint},t.below)},o.updateStyle=function(t){if(s(t)){var e=l(t);this.mapbox.setOptions(this.idLayer,"setLayoutProperty",e.layout),this.mapbox.setOptions(this.idLayer,"setPaintProperty",e.paint)}},o.removeLayer=function(){var t=this.map;t.getLayer(this.idLayer)&&t.removeLayer(this.idLayer)},o.dispose=function(){var t=this.map;t.removeLayer(this.idLayer),t.removeSource(this.idSource)},e.exports=function(t,e,r){var n=new a(t,e);return n.update(r),n}},{"../../lib":684,"./convert_text_opts":788}],791:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../components/color").defaultLine,a=t("../domain").attributes,o=t("../font_attributes"),s=t("../../traces/scatter/attributes").textposition,l=t("../../plot_api/edit_types").overrideAll,c=t("../../plot_api/plot_template").templatedArray,u=o({});u.family.dflt="Open Sans Regular, Arial Unicode MS Regular",e.exports=l({_arrayAttrRegexps:[n.counterRegex("mapbox",".layers",!0)],domain:a({name:"mapbox"}),accesstoken:{valType:"string",noBlank:!0,strict:!0},style:{valType:"any",values:["basic","streets","outdoors","light","dark","satellite","satellite-streets"],dflt:"basic"},center:{lon:{valType:"number",dflt:0},lat:{valType:"number",dflt:0}},zoom:{valType:"number",dflt:1},bearing:{valType:"number",dflt:0},pitch:{valType:"number",dflt:0},layers:c("layer",{visible:{valType:"boolean",dflt:!0},sourcetype:{valType:"enumerated",values:["geojson","vector"],dflt:"geojson"},source:{valType:"any"},sourcelayer:{valType:"string",dflt:""},type:{valType:"enumerated",values:["circle","line","fill","symbol"],dflt:"circle"},below:{valType:"string",dflt:""},color:{valType:"color",dflt:i},opacity:{valType:"number",min:0,max:1,dflt:1},circle:{radius:{valType:"number",dflt:15}},line:{width:{valType:"number",dflt:2}},fill:{outlinecolor:{valType:"color",dflt:i}},symbol:{icon:{valType:"string",dflt:"marker"},iconsize:{valType:"number",dflt:10},text:{valType:"string",dflt:""},textfont:u,textposition:n.extendFlat({},s,{arrayOk:!1})}})},"plot","from-root")},{"../../components/color":558,"../../lib":684,"../../plot_api/edit_types":715,"../../plot_api/plot_template":722,"../../traces/scatter/attributes":1015,"../domain":757,"../font_attributes":758}],792:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../subplot_defaults"),a=t("../array_container_defaults"),o=t("./layout_attributes");function s(t,e,r,n){r("accesstoken",n.accessToken),r("style"),r("center.lon"),r("center.lat"),r("zoom"),r("bearing"),r("pitch"),a(t,e,{name:"layers",handleItemDefaults:l}),e._input=t}function l(t,e){function r(r,i){return n.coerce(t,e,o.layers,r,i)}if(r("visible")){var i=r("sourcetype");r("source"),"vector"===i&&r("sourcelayer");var a=r("type");r("below"),r("color"),r("opacity"),"circle"===a&&r("circle.radius"),"line"===a&&r("line.width"),"fill"===a&&r("fill.outlinecolor"),"symbol"===a&&(r("symbol.icon"),r("symbol.iconsize"),r("symbol.text"),n.coerceFont(r,"symbol.textfont"),r("symbol.textposition"))}}e.exports=function(t,e,r){i(t,e,r,{type:"mapbox",attributes:o,handleDefaults:s,partition:"y",accessToken:e._mapboxAccessToken})}},{"../../lib":684,"../array_container_defaults":728,"../subplot_defaults":809,"./layout_attributes":791}],793:[function(t,e,r){"use strict";var n=t("mapbox-gl"),i=t("../../components/fx"),a=t("../../lib"),o=t("../../components/dragelement"),s=t("../cartesian/select").prepSelect,l=t("./constants"),c=t("./layout_attributes"),u=t("./layers");function h(t){this.id=t.id,this.gd=t.gd,this.container=t.container,this.isStatic=t.staticPlot;var e=t.fullLayout;this.uid=e._uid+"-"+this.id,this.opts=e[this.id],this.div=null,this.xaxis=null,this.yaxis=null,this.createFramework(e),this.map=null,this.accessToken=null,this.styleObj=null,this.traceHash={},this.layerList=[]}var f=h.prototype;function p(t){var e=c.style.values,r=c.style.dflt,n={};return a.isPlainObject(t)?(n.id=t.id,n.style=t):"string"==typeof t?(n.id=t,n.style=-1!==e.indexOf(t)?d(t):t):(n.id=r,n.style=d(r)),n.transition={duration:0,delay:0},n}function d(t){return l.styleUrlPrefix+t+"-"+l.styleUrlSuffix}function g(t){return[t.lon,t.lat]}e.exports=function(t){return new h(t)},f.plot=function(t,e,r){var n,i=this,a=i.opts=e[this.id];i.map&&a.accesstoken!==i.accessToken&&(i.map.remove(),i.map=null,i.styleObj=null,i.traceHash=[],i.layerList={}),n=i.map?new Promise(function(r,n){i.updateMap(t,e,r,n)}):new Promise(function(r,n){i.createMap(t,e,r,n)}),r.push(n)},f.createMap=function(t,e,r,a){var o=this,s=o.gd,c=o.opts,u=o.styleObj=p(c.style);o.accessToken=c.accesstoken;var h=o.map=new n.Map({container:o.div,style:u.style,center:g(c.center),zoom:c.zoom,bearing:c.bearing,pitch:c.pitch,interactive:!o.isStatic,preserveDrawingBuffer:o.isStatic,doubleClickZoom:!1,boxZoom:!1}),f=l.controlContainerClassName,d=o.div.getElementsByClassName(f)[0];if(o.div.removeChild(d),h._canvas.style.left="0px",h._canvas.style.top="0px",o.rejectOnError(a),h.once("load",function(){o.updateData(t),o.updateLayout(e),o.resolveOnRender(r)}),!o.isStatic){var m=!1;h.on("moveend",function(t){if(o.map){var e=o.getView();c._input.center=c.center=e.center,c._input.zoom=c.zoom=e.zoom,c._input.bearing=c.bearing=e.bearing,c._input.pitch=c.pitch=e.pitch,(t.originalEvent||m)&&y(e),m=!1}}),h.on("wheel",function(){m=!0}),h.on("mousemove",function(t){var e=o.div.getBoundingClientRect();t.clientX=t.point.x+e.left,t.clientY=t.point.y+e.top,t.target.getBoundingClientRect=function(){return e},o.xaxis.p2c=function(){return t.lngLat.lng},o.yaxis.p2c=function(){return t.lngLat.lat},i.hover(s,t,o.id)}),h.on("click",function(t){i.click(s,t.originalEvent)}),h.on("dragstart",v),h.on("zoomstart",v),h.on("dblclick",function(){s.emit("plotly_doubleclick",null);var t=o.viewInitial;h.setCenter(g(t.center)),h.setZoom(t.zoom),h.setBearing(t.bearing),h.setPitch(t.pitch);var e=o.getView();c._input.center=c.center=e.center,c._input.zoom=c.zoom=e.zoom,c._input.bearing=c.bearing=e.bearing,c._input.pitch=c.pitch=e.pitch,y(e)}),o.clearSelect=function(){s._fullLayout._zoomlayer.selectAll(".select-outline").remove()}}function v(){i.loneUnhover(e._toppaper)}function y(t){var e=o.id,r={};for(var n in t)r[e+"."+n]=t[n];s.emit("plotly_relayout",r)}},f.updateMap=function(t,e,r,n){var i=this,a=i.map;i.rejectOnError(n);var o=p(i.opts.style);i.styleObj.id!==o.id?(i.styleObj=o,a.setStyle(o.style),a.once("styledata",function(){i.traceHash={},i.updateData(t),i.updateLayout(e),i.resolveOnRender(r)})):(i.updateData(t),i.updateLayout(e),i.resolveOnRender(r))},f.updateData=function(t){var e,r,n,i,a=this.traceHash;for(n=0;n=e.width-20?(a["text-anchor"]="start",a.x=5):(a["text-anchor"]="end",a.x=e._paper.attr("width")-7),r.attr(a);var o=r.select(".js-link-to-tool"),s=r.select(".js-link-spacer"),u=r.select(".js-sourcelinks");t._context.showSources&&t._context.showSources(t),t._context.showLink&&function(t,e){e.text("");var r=e.append("a").attr({"xlink:xlink:href":"#",class:"link--impt link--embedview","font-weight":"bold"}).text(t._context.linkText+" "+String.fromCharCode(187));if(t._context.sendData)r.on("click",function(){v.sendDataToCloud(t)});else{var n=window.location.pathname.split("/"),i=window.location.search;r.attr({"xlink:xlink:show":"new","xlink:xlink:href":"/"+n[2].split(".")[0]+"/"+n[1]+i})}}(t,o),s.text(o.text()&&u.text()?" - ":"")}},v.sendDataToCloud=function(t){t.emit("plotly_beforeexport");var e=(window.PLOTLYENV||{}).BASE_URL||t._context.plotlyServerURL,r=n.select(t).append("div").attr("id","hiddenform").style("display","none"),i=r.append("form").attr({action:e+"/external",method:"post",target:"_blank"});return i.append("input").attr({type:"text",name:"data"}).node().value=v.graphJson(t,!1,"keepdata"),i.node().submit(),r.remove(),t.emit("plotly_afterexport"),!1};var b,_=["days","shortDays","months","shortMonths","periods","dateTime","date","time","decimal","thousands","grouping","currency"],w=["year","month","dayMonth","dayMonthYear"];function k(t,e){var r=t._context.locale,n=!1,i={};function o(t){for(var r=!0,a=0;a1&&O.length>1){for(a.getComponentMethod("grid","sizeDefaults")(c,s),o=0;o15&&O.length>15&&0===s.shapes.length&&0===s.images.length,s._hasCartesian=s._has("cartesian"),s._hasGeo=s._has("geo"),s._hasGL3D=s._has("gl3d"),s._hasGL2D=s._has("gl2d"),s._hasTernary=s._has("ternary"),s._hasPie=s._has("pie"),v.linkSubplots(p,s,u,i),v.cleanPlot(p,s,u,i,y),g(s,i),v.doAutoMargin(t);var F=h.list(t);for(o=0;o0){var u=function(t){var e,r={left:0,right:0,bottom:0,top:0};if(t)for(e in t)t.hasOwnProperty(e)&&(r.left+=t[e].left||0,r.right+=t[e].right||0,r.bottom+=t[e].bottom||0,r.top+=t[e].top||0);return r}(t._boundingBoxMargins),h=u.left+u.right,f=u.bottom+u.top,p=1-2*s,d=r._container&&r._container.node?r._container.node().getBoundingClientRect():{width:r.width,height:r.height};n=Math.round(p*(d.width-h)),a=Math.round(p*(d.height-f))}else{var g=c?window.getComputedStyle(t):{};n=parseFloat(g.width)||r.width,a=parseFloat(g.height)||r.height}var m=v.layoutAttributes.width.min,y=v.layoutAttributes.height.min;n1,b=!e.height&&Math.abs(r.height-a)>1;(b||x)&&(x&&(r.width=n),b&&(r.height=a)),t._initialAutoSize||(t._initialAutoSize={width:n,height:a}),v.sanitizeMargins(r)},v.supplyLayoutModuleDefaults=function(t,e,r,n){var i,o,s,c=a.componentsRegistry,u=e._basePlotModules,h=a.subplotsRegistry.cartesian;for(i in c)(s=c[i]).includeBasePlot&&s.includeBasePlot(t,e);for(var f in u.length||u.push(h),e._has("cartesian")&&(a.getComponentMethod("grid","contentDefaults")(t,e),h.finalizeSubplots(t,e)),e._subplots)e._subplots[f].sort(l.subplotSort);for(o=0;o.5*n.width&&(r.l=r.r=0),r.b+r.t>.5*n.height&&(r.b=r.t=0);var l=void 0!==r.xl?r.xl:r.x,c=void 0!==r.xr?r.xr:r.x,u=void 0!==r.yt?r.yt:r.y,h=void 0!==r.yb?r.yb:r.y;i[e]={l:{val:l,size:r.l+o},r:{val:c,size:r.r+o},b:{val:h,size:r.b+o},t:{val:u,size:r.t+o}},a[e]=1}else delete i[e],delete a[e];n._replotting||v.doAutoMargin(t)}},v.doAutoMargin=function(t){var e=t._fullLayout;e._size||(e._size={}),A(e);var r=e._size,n=JSON.stringify(r),o=Math.max(e.margin.l||0,0),s=Math.max(e.margin.r||0,0),l=Math.max(e.margin.t||0,0),c=Math.max(e.margin.b||0,0),u=e._pushmargin,h=e._pushmarginIds;if(!1!==e.margin.autoexpand){for(var f in u)h[f]||delete u[f];for(var p in u.base={l:{val:0,size:o},r:{val:1,size:s},t:{val:1,size:l},b:{val:0,size:c}},u){var d=u[p].l||{},g=u[p].b||{},m=d.val,v=d.size,y=g.val,x=g.size;for(var b in u){if(i(v)&&u[b].r){var _=u[b].r.val,w=u[b].r.size;if(_>m){var k=(v*_+(w-e.width)*m)/(_-m),M=(w*(1-m)+(v-e.width)*(1-_))/(_-m);k>=0&&M>=0&&k+M>o+s&&(o=k,s=M)}}if(i(x)&&u[b].t){var T=u[b].t.val,S=u[b].t.size;if(T>y){var E=(x*T+(S-e.height)*y)/(T-y),C=(S*(1-y)+(x-e.height)*(1-T))/(T-y);E>=0&&C>=0&&E+C>c+l&&(c=E,l=C)}}}}}if(r.l=Math.round(o),r.r=Math.round(s),r.t=Math.round(l),r.b=Math.round(c),r.p=Math.round(e.margin.pad),r.w=Math.round(e.width)-r.l-r.r,r.h=Math.round(e.height)-r.t-r.b,!e._replotting&&"{}"!==n&&n!==JSON.stringify(e._size))return"_redrawFromAutoMarginCount"in e?e._redrawFromAutoMarginCount++:e._redrawFromAutoMarginCount=1,a.call("plot",t)},v.graphJson=function(t,e,r,n,i){(i&&e&&!t._fullData||i&&!e&&!t._fullLayout)&&v.supplyDefaults(t);var a=i?t._fullData:t.data,o=i?t._fullLayout:t.layout,s=(t._transitionData||{})._frames;function c(t){if("function"==typeof t)return null;if(l.isPlainObject(t)){var e,n,i={};for(e in t)if("function"!=typeof t[e]&&-1===["_","["].indexOf(e.charAt(0))){if("keepdata"===r){if("src"===e.substr(e.length-3))continue}else if("keepstream"===r){if("string"==typeof(n=t[e+"src"])&&n.indexOf(":")>0&&!l.isPlainObject(t.stream))continue}else if("keepall"!==r&&"string"==typeof(n=t[e+"src"])&&n.indexOf(":")>0)continue;i[e]=c(t[e])}return i}return Array.isArray(t)?t.map(c):l.isJSDate(t)?l.ms2DateTimeLocal(+t):t}var u={data:(a||[]).map(function(t){var r=c(t);return e&&delete r.fit,r})};return e||(u.layout=c(o)),t.framework&&t.framework.isPolar&&(u=t.framework.getConfig()),s&&(u.frames=c(s)),"object"===n?u:JSON.stringify(u)},v.modifyFrames=function(t,e){var r,n,i,a=t._transitionData._frames,o=t._transitionData._frameHash;for(r=0;r0&&(t._transitioningWithDuration=!0),t._transitionData._interruptCallbacks.push(function(){p=!0}),i.redraw&&t._transitionData._interruptCallbacks.push(function(){return a.call("redraw",t)}),t._transitionData._interruptCallbacks.push(function(){t.emit("plotly_transitioninterrupted",[])});var n,s,c=0,u=0;function h(){return c++,function(){var r;u++,p||u!==c||(r=e,t._transitionData&&(function(t){if(t)for(;t.length;)t.shift()}(t._transitionData._interruptCallbacks),Promise.resolve().then(function(){if(i.redraw)return a.call("redraw",t)}).then(function(){t._transitioning=!1,t._transitioningWithDuration=!1,t.emit("plotly_transitioned",[])}).then(r)))}}var d=t._fullLayout._basePlotModules,g=!1;if(r)for(s=0;s=0;s--)if(o[s].enabled){r._indexToPoints=o[s]._indexToPoints;break}n&&n.calc&&(a=n.calc(t,r))}Array.isArray(a)&&a[0]||(a=[{x:u,y:u}]),a[0].t||(a[0].t={}),a[0].trace=r,p[e]=a}}for(m&&T(l),i=0;i=0?f.angularAxis.domain:n.extent(k),E=Math.abs(k[1]-k[0]);A&&!M&&(E=0);var C=S.slice();T&&M&&(C[1]+=E);var L=f.angularAxis.ticksCount||4;L>8&&(L=L/(L/8)+L%8),f.angularAxis.ticksStep&&(L=(C[1]-C[0])/L);var z=f.angularAxis.ticksStep||(C[1]-C[0])/(L*(f.minorTicks+1));w&&(z=Math.max(Math.round(z),1)),C[2]||(C[2]=z);var P=n.range.apply(this,C);if(P=P.map(function(t,e){return parseFloat(t.toPrecision(12))}),s=n.scale.linear().domain(C.slice(0,2)).range("clockwise"===f.direction?[0,360]:[360,0]),u.layout.angularAxis.domain=s.domain(),u.layout.angularAxis.endPadding=T?E:0,"undefined"==typeof(t=n.select(this).select("svg.chart-root"))||t.empty()){var I=(new DOMParser).parseFromString("' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '","application/xml"),O=this.appendChild(this.ownerDocument.importNode(I.documentElement,!0));t=n.select(O)}t.select(".guides-group").style({"pointer-events":"none"}),t.select(".angular.axis-group").style({"pointer-events":"none"}),t.select(".radial.axis-group").style({"pointer-events":"none"});var D,R=t.select(".chart-group"),B={fill:"none",stroke:f.tickColor},F={"font-size":f.font.size,"font-family":f.font.family,fill:f.font.color,"text-shadow":["-1px 0px","1px -1px","-1px 1px","1px 1px"].map(function(t,e){return" "+t+" 0 "+f.font.outlineColor}).join(",")};if(f.showLegend){D=t.select(".legend-group").attr({transform:"translate("+[x,f.margin.top]+")"}).style({display:"block"});var N=p.map(function(t,e){var r=o.util.cloneJson(t);return r.symbol="DotPlot"===t.geometry?t.dotType||"circle":"LinePlot"!=t.geometry?"square":"line",r.visibleInLegend="undefined"==typeof t.visibleInLegend||t.visibleInLegend,r.color="LinePlot"===t.geometry?t.strokeColor:t.color,r});o.Legend().config({data:p.map(function(t,e){return t.name||"Element"+e}),legendConfig:i({},o.Legend.defaultConfig().legendConfig,{container:D,elements:N,reverseOrder:f.legend.reverseOrder})})();var j=D.node().getBBox();x=Math.min(f.width-j.width-f.margin.left-f.margin.right,f.height-f.margin.top-f.margin.bottom)/2,x=Math.max(10,x),_=[f.margin.left+x,f.margin.top+x],r.range([0,x]),u.layout.radialAxis.domain=r.domain(),D.attr("transform","translate("+[_[0]+x,_[1]-x]+")")}else D=t.select(".legend-group").style({display:"none"});t.attr({width:f.width,height:f.height}).style({opacity:f.opacity}),R.attr("transform","translate("+_+")").style({cursor:"crosshair"});var V=[(f.width-(f.margin.left+f.margin.right+2*x+(j?j.width:0)))/2,(f.height-(f.margin.top+f.margin.bottom+2*x))/2];if(V[0]=Math.max(0,V[0]),V[1]=Math.max(0,V[1]),t.select(".outer-group").attr("transform","translate("+V+")"),f.title){var U=t.select("g.title-group text").style(F).text(f.title),q=U.node().getBBox();U.attr({x:_[0]-q.width/2,y:_[1]-x-20})}var H=t.select(".radial.axis-group");if(f.radialAxis.gridLinesVisible){var G=H.selectAll("circle.grid-circle").data(r.ticks(5));G.enter().append("circle").attr({class:"grid-circle"}).style(B),G.attr("r",r),G.exit().remove()}H.select("circle.outside-circle").attr({r:x}).style(B);var W=t.select("circle.background-circle").attr({r:x}).style({fill:f.backgroundColor,stroke:f.stroke});function Y(t,e){return s(t)%360+f.orientation}if(f.radialAxis.visible){var X=n.svg.axis().scale(r).ticks(5).tickSize(5);H.call(X).attr({transform:"rotate("+f.radialAxis.orientation+")"}),H.selectAll(".domain").style(B),H.selectAll("g>text").text(function(t,e){return this.textContent+f.radialAxis.ticksSuffix}).style(F).style({"text-anchor":"start"}).attr({x:0,y:0,dx:0,dy:0,transform:function(t,e){return"horizontal"===f.radialAxis.tickOrientation?"rotate("+-f.radialAxis.orientation+") translate("+[0,F["font-size"]]+")":"translate("+[0,F["font-size"]]+")"}}),H.selectAll("g>line").style({stroke:"black"})}var Z=t.select(".angular.axis-group").selectAll("g.angular-tick").data(P),$=Z.enter().append("g").classed("angular-tick",!0);Z.attr({transform:function(t,e){return"rotate("+Y(t)+")"}}).style({display:f.angularAxis.visible?"block":"none"}),Z.exit().remove(),$.append("line").classed("grid-line",!0).classed("major",function(t,e){return e%(f.minorTicks+1)==0}).classed("minor",function(t,e){return!(e%(f.minorTicks+1)==0)}).style(B),$.selectAll(".minor").style({stroke:f.minorTickColor}),Z.select("line.grid-line").attr({x1:f.tickLength?x-f.tickLength:0,x2:x}).style({display:f.angularAxis.gridLinesVisible?"block":"none"}),$.append("text").classed("axis-text",!0).style(F);var J=Z.select("text.axis-text").attr({x:x+f.labelOffset,dy:a+"em",transform:function(t,e){var r=Y(t),n=x+f.labelOffset,i=f.angularAxis.tickOrientation;return"horizontal"==i?"rotate("+-r+" "+n+" 0)":"radial"==i?r<270&&r>90?"rotate(180 "+n+" 0)":null:"rotate("+(r<=180&&r>0?-90:90)+" "+n+" 0)"}}).style({"text-anchor":"middle",display:f.angularAxis.labelsVisible?"block":"none"}).text(function(t,e){return e%(f.minorTicks+1)!=0?"":w?w[t]+f.angularAxis.ticksSuffix:t+f.angularAxis.ticksSuffix}).style(F);f.angularAxis.rewriteTicks&&J.text(function(t,e){return e%(f.minorTicks+1)!=0?"":f.angularAxis.rewriteTicks(this.textContent,e)});var K=n.max(R.selectAll(".angular-tick text")[0].map(function(t,e){return t.getCTM().e+t.getBBox().width}));D.attr({transform:"translate("+[x+K,f.margin.top]+")"});var Q=t.select("g.geometry-group").selectAll("g").size()>0,tt=t.select("g.geometry-group").selectAll("g.geometry").data(p);if(tt.enter().append("g").attr({class:function(t,e){return"geometry geometry"+e}}),tt.exit().remove(),p[0]||Q){var et=[];p.forEach(function(t,e){var n={};n.radialScale=r,n.angularScale=s,n.container=tt.filter(function(t,r){return r==e}),n.geometry=t.geometry,n.orientation=f.orientation,n.direction=f.direction,n.index=e,et.push({data:t,geometryConfig:n})});var rt=n.nest().key(function(t,e){return"undefined"!=typeof t.data.groupId||"unstacked"}).entries(et),nt=[];rt.forEach(function(t,e){"unstacked"===t.key?nt=nt.concat(t.values.map(function(t,e){return[t]})):nt.push(t.values)}),nt.forEach(function(t,e){var r;r=Array.isArray(t)?t[0].geometryConfig.geometry:t.geometryConfig.geometry;var n=t.map(function(t,e){return i(o[r].defaultConfig(),t)});o[r]().config(n)()})}var it,at,ot=t.select(".guides-group"),st=t.select(".tooltips-group"),lt=o.tooltipPanel().config({container:st,fontSize:8})(),ct=o.tooltipPanel().config({container:st,fontSize:8})(),ut=o.tooltipPanel().config({container:st,hasTick:!0})();if(!M){var ht=ot.select("line").attr({x1:0,y1:0,y2:0}).style({stroke:"grey","pointer-events":"none"});R.on("mousemove.angular-guide",function(t,e){var r=o.util.getMousePos(W).angle;ht.attr({x2:-x,transform:"rotate("+r+")"}).style({opacity:.5});var n=(r+180+360-f.orientation)%360;it=s.invert(n);var i=o.util.convertToCartesian(x+12,r+180);lt.text(o.util.round(it)).move([i[0]+_[0],i[1]+_[1]])}).on("mouseout.angular-guide",function(t,e){ot.select("line").style({opacity:0})})}var ft=ot.select("circle").style({stroke:"grey",fill:"none"});R.on("mousemove.radial-guide",function(t,e){var n=o.util.getMousePos(W).radius;ft.attr({r:n}).style({opacity:.5}),at=r.invert(o.util.getMousePos(W).radius);var i=o.util.convertToCartesian(n,f.radialAxis.orientation);ct.text(o.util.round(at)).move([i[0]+_[0],i[1]+_[1]])}).on("mouseout.radial-guide",function(t,e){ft.style({opacity:0}),ut.hide(),lt.hide(),ct.hide()}),t.selectAll(".geometry-group .mark").on("mouseover.tooltip",function(e,r){var i=n.select(this),a=this.style.fill,s="black",l=this.style.opacity||1;if(i.attr({"data-opacity":l}),a&&"none"!==a){i.attr({"data-fill":a}),s=n.hsl(a).darker().toString(),i.style({fill:s,opacity:1});var c={t:o.util.round(e[0]),r:o.util.round(e[1])};M&&(c.t=w[e[0]]);var u="t: "+c.t+", r: "+c.r,h=this.getBoundingClientRect(),f=t.node().getBoundingClientRect(),p=[h.left+h.width/2-V[0]-f.left,h.top+h.height/2-V[1]-f.top];ut.config({color:s}).text(u),ut.move(p)}else a=this.style.stroke||"black",i.attr({"data-stroke":a}),s=n.hsl(a).darker().toString(),i.style({stroke:s,opacity:1})}).on("mousemove.tooltip",function(t,e){if(0!=n.event.which)return!1;n.select(this).attr("data-fill")&&ut.show()}).on("mouseout.tooltip",function(t,e){ut.hide();var r=n.select(this),i=r.attr("data-fill");i?r.style({fill:i,opacity:r.attr("data-opacity")}):r.style({stroke:r.attr("data-stroke"),opacity:r.attr("data-opacity")})})})}(c),this},f.config=function(t){if(!arguments.length)return l;var e=o.util.cloneJson(t);return e.data.forEach(function(t,e){l.data[e]||(l.data[e]={}),i(l.data[e],o.Axis.defaultConfig().data[0]),i(l.data[e],t)}),i(l.layout,o.Axis.defaultConfig().layout),i(l.layout,e.layout),this},f.getLiveConfig=function(){return u},f.getinputConfig=function(){return c},f.radialScale=function(t){return r},f.angularScale=function(t){return s},f.svg=function(){return t},n.rebind(f,h,"on"),f},o.Axis.defaultConfig=function(t,e){return{data:[{t:[1,2,3,4],r:[10,11,12,13],name:"Line1",geometry:"LinePlot",color:null,strokeDash:"solid",strokeColor:null,strokeSize:"1",visibleInLegend:!0,opacity:1}],layout:{defaultColorRange:n.scale.category10().range(),title:null,height:450,width:500,margin:{top:40,right:40,bottom:40,left:40},font:{size:12,color:"gray",outlineColor:"white",family:"Tahoma, sans-serif"},direction:"clockwise",orientation:0,labelOffset:10,radialAxis:{domain:null,orientation:-45,ticksSuffix:"",visible:!0,gridLinesVisible:!0,tickOrientation:"horizontal",rewriteTicks:null},angularAxis:{domain:[0,360],ticksSuffix:"",visible:!0,gridLinesVisible:!0,labelsVisible:!0,tickOrientation:"horizontal",rewriteTicks:null,ticksCount:null,ticksStep:null},minorTicks:0,tickLength:null,tickColor:"silver",minorTickColor:"#eee",backgroundColor:"none",needsEndSpacing:null,showLegend:!0,legend:{reverseOrder:!1},opacity:1}}},o.util={},o.DATAEXTENT="dataExtent",o.AREA="AreaChart",o.LINE="LinePlot",o.DOT="DotPlot",o.BAR="BarChart",o.util._override=function(t,e){for(var r in t)r in e&&(e[r]=t[r])},o.util._extend=function(t,e){for(var r in t)e[r]=t[r]},o.util._rndSnd=function(){return 2*Math.random()-1+(2*Math.random()-1)+(2*Math.random()-1)},o.util.dataFromEquation2=function(t,e){var r=e||6;return n.range(0,360+r,r).map(function(e,r){var n=e*Math.PI/180;return[e,t(n)]})},o.util.dataFromEquation=function(t,e,r){var i=e||6,a=[],o=[];n.range(0,360+i,i).forEach(function(e,r){var n=e*Math.PI/180,i=t(n);a.push(e),o.push(i)});var s={t:a,r:o};return r&&(s.name=r),s},o.util.ensureArray=function(t,e){if("undefined"==typeof t)return null;var r=[].concat(t);return n.range(e).map(function(t,e){return r[e]||r[0]})},o.util.fillArrays=function(t,e,r){return e.forEach(function(e,n){t[e]=o.util.ensureArray(t[e],r)}),t},o.util.cloneJson=function(t){return JSON.parse(JSON.stringify(t))},o.util.validateKeys=function(t,e){"string"==typeof e&&(e=e.split("."));var r=e.shift();return t[r]&&(!e.length||objHasKeys(t[r],e))},o.util.sumArrays=function(t,e){return n.zip(t,e).map(function(t,e){return n.sum(t)})},o.util.arrayLast=function(t){return t[t.length-1]},o.util.arrayEqual=function(t,e){for(var r=Math.max(t.length,e.length,1);r-- >=0&&t[r]===e[r];);return-2===r},o.util.flattenArray=function(t){for(var e=[];!o.util.arrayEqual(e,t);)e=t,t=[].concat.apply([],t);return t},o.util.deduplicate=function(t){return t.filter(function(t,e,r){return r.indexOf(t)==e})},o.util.convertToCartesian=function(t,e){var r=e*Math.PI/180;return[t*Math.cos(r),t*Math.sin(r)]},o.util.round=function(t,e){var r=e||2,n=Math.pow(10,r);return Math.round(t*n)/n},o.util.getMousePos=function(t){var e=n.mouse(t.node()),r=e[0],i=e[1],a={};return a.x=r,a.y=i,a.pos=e,a.angle=180*(Math.atan2(i,r)+Math.PI)/Math.PI,a.radius=Math.sqrt(r*r+i*i),a},o.util.duplicatesCount=function(t){for(var e,r={},n={},i=0,a=t.length;i0)){var l=n.select(this.parentNode).selectAll("path.line").data([0]);l.enter().insert("path"),l.attr({class:"line",d:u(s),transform:function(t,r){return"rotate("+(e.orientation+90)+")"},"pointer-events":"none"}).style({fill:function(t,e){return d.fill(r,i,a)},"fill-opacity":0,stroke:function(t,e){return d.stroke(r,i,a)},"stroke-width":function(t,e){return d["stroke-width"](r,i,a)},"stroke-dasharray":function(t,e){return d["stroke-dasharray"](r,i,a)},opacity:function(t,e){return d.opacity(r,i,a)},display:function(t,e){return d.display(r,i,a)}})}};var h=e.angularScale.range(),f=Math.abs(h[1]-h[0])/o[0].length*Math.PI/180,p=n.svg.arc().startAngle(function(t){return-f/2}).endAngle(function(t){return f/2}).innerRadius(function(t){return e.radialScale(l+(t[2]||0))}).outerRadius(function(t){return e.radialScale(l+(t[2]||0))+e.radialScale(t[1])});c.arc=function(t,r,i){n.select(this).attr({class:"mark arc",d:p,transform:function(t,r){return"rotate("+(e.orientation+s(t[0])+90)+")"}})};var d={fill:function(e,r,n){return t[n].data.color},stroke:function(e,r,n){return t[n].data.strokeColor},"stroke-width":function(e,r,n){return t[n].data.strokeSize+"px"},"stroke-dasharray":function(e,n,i){return r[t[i].data.strokeDash]},opacity:function(e,r,n){return t[n].data.opacity},display:function(e,r,n){return"undefined"==typeof t[n].data.visible||t[n].data.visible?"block":"none"}},g=n.select(this).selectAll("g.layer").data(o);g.enter().append("g").attr({class:"layer"});var m=g.selectAll("path.mark").data(function(t,e){return t});m.enter().append("path").attr({class:"mark"}),m.style(d).each(c[e.geometryType]),m.exit().remove(),g.exit().remove()})}return a.config=function(e){return arguments.length?(e.forEach(function(e,r){t[r]||(t[r]={}),i(t[r],o.PolyChart.defaultConfig()),i(t[r],e)}),this):t},a.getColorScale=function(){},n.rebind(a,e,"on"),a},o.PolyChart.defaultConfig=function(){return{data:{name:"geom1",t:[[1,2,3,4]],r:[[1,2,3,4]],dotType:"circle",dotSize:64,dotVisible:!1,barWidth:20,color:"#ffa500",strokeSize:1,strokeColor:"silver",strokeDash:"solid",opacity:1,index:0,visible:!0,visibleInLegend:!0},geometryConfig:{geometry:"LinePlot",geometryType:"arc",direction:"clockwise",orientation:0,container:"body",radialScale:null,angularScale:null,colorScale:n.scale.category20()}}},o.BarChart=function(){return o.PolyChart()},o.BarChart.defaultConfig=function(){return{geometryConfig:{geometryType:"bar"}}},o.AreaChart=function(){return o.PolyChart()},o.AreaChart.defaultConfig=function(){return{geometryConfig:{geometryType:"arc"}}},o.DotPlot=function(){return o.PolyChart()},o.DotPlot.defaultConfig=function(){return{geometryConfig:{geometryType:"dot",dotType:"circle"}}},o.LinePlot=function(){return o.PolyChart()},o.LinePlot.defaultConfig=function(){return{geometryConfig:{geometryType:"line"}}},o.Legend=function(){var t=o.Legend.defaultConfig(),e=n.dispatch("hover");function r(){var e=t.legendConfig,a=t.data.map(function(t,r){return[].concat(t).map(function(t,n){var a=i({},e.elements[r]);return a.name=t,a.color=[].concat(e.elements[r].color)[n],a})}),o=n.merge(a);o=o.filter(function(t,r){return e.elements[r]&&(e.elements[r].visibleInLegend||"undefined"==typeof e.elements[r].visibleInLegend)}),e.reverseOrder&&(o=o.reverse());var s=e.container;("string"==typeof s||s.nodeName)&&(s=n.select(s));var l=o.map(function(t,e){return t.color}),c=e.fontSize,u=null==e.isContinuous?"number"==typeof o[0]:e.isContinuous,h=u?e.height:c*o.length,f=s.classed("legend-group",!0).selectAll("svg").data([0]),p=f.enter().append("svg").attr({width:300,height:h+c,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1"});p.append("g").classed("legend-axis",!0),p.append("g").classed("legend-marks",!0);var d=n.range(o.length),g=n.scale[u?"linear":"ordinal"]().domain(d).range(l),m=n.scale[u?"linear":"ordinal"]().domain(d)[u?"range":"rangePoints"]([0,h]);if(u){var v=f.select(".legend-marks").append("defs").append("linearGradient").attr({id:"grad1",x1:"0%",y1:"0%",x2:"0%",y2:"100%"}).selectAll("stop").data(l);v.enter().append("stop"),v.attr({offset:function(t,e){return e/(l.length-1)*100+"%"}}).style({"stop-color":function(t,e){return t}}),f.append("rect").classed("legend-mark",!0).attr({height:e.height,width:e.colorBandWidth,fill:"url(#grad1)"})}else{var y=f.select(".legend-marks").selectAll("path.legend-mark").data(o);y.enter().append("path").classed("legend-mark",!0),y.attr({transform:function(t,e){return"translate("+[c/2,m(e)+c/2]+")"},d:function(t,e){var r,i,a,o=t.symbol;return a=3*(i=c),"line"===(r=o)?"M"+[[-i/2,-i/12],[i/2,-i/12],[i/2,i/12],[-i/2,i/12]]+"Z":-1!=n.svg.symbolTypes.indexOf(r)?n.svg.symbol().type(r).size(a)():n.svg.symbol().type("square").size(a)()},fill:function(t,e){return g(e)}}),y.exit().remove()}var x=n.svg.axis().scale(m).orient("right"),b=f.select("g.legend-axis").attr({transform:"translate("+[u?e.colorBandWidth:c,c/2]+")"}).call(x);return b.selectAll(".domain").style({fill:"none",stroke:"none"}),b.selectAll("line").style({fill:"none",stroke:u?e.textColor:"none"}),b.selectAll("text").style({fill:e.textColor,"font-size":e.fontSize}).text(function(t,e){return o[e].name}),r}return r.config=function(e){return arguments.length?(i(t,e),this):t},n.rebind(r,e,"on"),r},o.Legend.defaultConfig=function(t,e){return{data:["a","b","c"],legendConfig:{elements:[{symbol:"line",color:"red"},{symbol:"square",color:"yellow"},{symbol:"diamond",color:"limegreen"}],height:150,colorBandWidth:30,fontSize:12,container:"body",isContinuous:null,textColor:"grey",reverseOrder:!1}}},o.tooltipPanel=function(){var t,e,r,a={container:null,hasTick:!1,fontSize:12,color:"white",padding:5},s="tooltip-"+o.tooltipPanel.uid++,l=10,c=function(){var n=(t=a.container.selectAll("g."+s).data([0])).enter().append("g").classed(s,!0).style({"pointer-events":"none",display:"none"});return r=n.append("path").style({fill:"white","fill-opacity":.9}).attr({d:"M0 0"}),e=n.append("text").attr({dx:a.padding+l,dy:.3*+a.fontSize}),c};return c.text=function(i){var o=n.hsl(a.color).l,s=o>=.5?"#aaa":"white",u=o>=.5?"black":"white",h=i||"";e.style({fill:u,"font-size":a.fontSize+"px"}).text(h);var f=a.padding,p=e.node().getBBox(),d={fill:a.color,stroke:s,"stroke-width":"2px"},g=p.width+2*f+l,m=p.height+2*f;return r.attr({d:"M"+[[l,-m/2],[l,-m/4],[a.hasTick?0:l,0],[l,m/4],[l,m/2],[g,m/2],[g,-m/2]].join("L")+"Z"}).style(d),t.attr({transform:"translate("+[l,-m/2+2*f]+")"}),t.style({display:"block"}),c},c.move=function(e){if(t)return t.attr({transform:"translate("+[e[0],e[1]]+")"}).style({display:"block"}),c},c.hide=function(){if(t)return t.style({display:"none"}),c},c.show=function(){if(t)return t.style({display:"block"}),c},c.config=function(t){return i(a,t),c},c},o.tooltipPanel.uid=1,o.adapter={},o.adapter.plotly=function(){var t={convert:function(t,e){var r={};if(t.data&&(r.data=t.data.map(function(t,r){var n=i({},t);return[[n,["marker","color"],["color"]],[n,["marker","opacity"],["opacity"]],[n,["marker","line","color"],["strokeColor"]],[n,["marker","line","dash"],["strokeDash"]],[n,["marker","line","width"],["strokeSize"]],[n,["marker","symbol"],["dotType"]],[n,["marker","size"],["dotSize"]],[n,["marker","barWidth"],["barWidth"]],[n,["line","interpolation"],["lineInterpolation"]],[n,["showlegend"],["visibleInLegend"]]].forEach(function(t,r){o.util.translator.apply(null,t.concat(e))}),e||delete n.marker,e&&delete n.groupId,e?("LinePlot"===n.geometry?(n.type="scatter",!0===n.dotVisible?(delete n.dotVisible,n.mode="lines+markers"):n.mode="lines"):"DotPlot"===n.geometry?(n.type="scatter",n.mode="markers"):"AreaChart"===n.geometry?n.type="area":"BarChart"===n.geometry&&(n.type="bar"),delete n.geometry):("scatter"===n.type?"lines"===n.mode?n.geometry="LinePlot":"markers"===n.mode?n.geometry="DotPlot":"lines+markers"===n.mode&&(n.geometry="LinePlot",n.dotVisible=!0):"area"===n.type?n.geometry="AreaChart":"bar"===n.type&&(n.geometry="BarChart"),delete n.mode,delete n.type),n}),!e&&t.layout&&"stack"===t.layout.barmode)){var a=o.util.duplicates(r.data.map(function(t,e){return t.geometry}));r.data.forEach(function(t,e){var n=a.indexOf(t.geometry);-1!=n&&(r.data[e].groupId=n)})}if(t.layout){var s=i({},t.layout);if([[s,["plot_bgcolor"],["backgroundColor"]],[s,["showlegend"],["showLegend"]],[s,["radialaxis"],["radialAxis"]],[s,["angularaxis"],["angularAxis"]],[s.angularaxis,["showline"],["gridLinesVisible"]],[s.angularaxis,["showticklabels"],["labelsVisible"]],[s.angularaxis,["nticks"],["ticksCount"]],[s.angularaxis,["tickorientation"],["tickOrientation"]],[s.angularaxis,["ticksuffix"],["ticksSuffix"]],[s.angularaxis,["range"],["domain"]],[s.angularaxis,["endpadding"],["endPadding"]],[s.radialaxis,["showline"],["gridLinesVisible"]],[s.radialaxis,["tickorientation"],["tickOrientation"]],[s.radialaxis,["ticksuffix"],["ticksSuffix"]],[s.radialaxis,["range"],["domain"]],[s.angularAxis,["showline"],["gridLinesVisible"]],[s.angularAxis,["showticklabels"],["labelsVisible"]],[s.angularAxis,["nticks"],["ticksCount"]],[s.angularAxis,["tickorientation"],["tickOrientation"]],[s.angularAxis,["ticksuffix"],["ticksSuffix"]],[s.angularAxis,["range"],["domain"]],[s.angularAxis,["endpadding"],["endPadding"]],[s.radialAxis,["showline"],["gridLinesVisible"]],[s.radialAxis,["tickorientation"],["tickOrientation"]],[s.radialAxis,["ticksuffix"],["ticksSuffix"]],[s.radialAxis,["range"],["domain"]],[s.font,["outlinecolor"],["outlineColor"]],[s.legend,["traceorder"],["reverseOrder"]],[s,["labeloffset"],["labelOffset"]],[s,["defaultcolorrange"],["defaultColorRange"]]].forEach(function(t,r){o.util.translator.apply(null,t.concat(e))}),e?("undefined"!=typeof s.tickLength&&(s.angularaxis.ticklen=s.tickLength,delete s.tickLength),s.tickColor&&(s.angularaxis.tickcolor=s.tickColor,delete s.tickColor)):(s.angularAxis&&"undefined"!=typeof s.angularAxis.ticklen&&(s.tickLength=s.angularAxis.ticklen),s.angularAxis&&"undefined"!=typeof s.angularAxis.tickcolor&&(s.tickColor=s.angularAxis.tickcolor)),s.legend&&"boolean"!=typeof s.legend.reverseOrder&&(s.legend.reverseOrder="normal"!=s.legend.reverseOrder),s.legend&&"boolean"==typeof s.legend.traceorder&&(s.legend.traceorder=s.legend.traceorder?"reversed":"normal",delete s.legend.reverseOrder),s.margin&&"undefined"!=typeof s.margin.t){var l=["t","r","b","l","pad"],c=["top","right","bottom","left","pad"],u={};n.entries(s.margin).forEach(function(t,e){u[c[l.indexOf(t.key)]]=t.value}),s.margin=u}e&&(delete s.needsEndSpacing,delete s.minorTickColor,delete s.minorTicks,delete s.angularaxis.ticksCount,delete s.angularaxis.ticksCount,delete s.angularaxis.ticksStep,delete s.angularaxis.rewriteTicks,delete s.angularaxis.nticks,delete s.radialaxis.ticksCount,delete s.radialaxis.ticksCount,delete s.radialaxis.ticksStep,delete s.radialaxis.rewriteTicks,delete s.radialaxis.nticks),r.layout=s}return r}};return t}},{"../../../constants/alignment":656,"../../../lib":684,d3:147}],805:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../../lib"),a=t("../../../components/color"),o=t("./micropolar"),s=t("./undo_manager"),l=i.extendDeepAll,c=e.exports={};c.framework=function(t){var e,r,i,a,u,h=new s;function f(r,s){return s&&(u=s),n.select(n.select(u).node().parentNode).selectAll(".svg-container>*:not(.chart-root)").remove(),e=e?l(e,r):r,i||(i=o.Axis()),a=o.adapter.plotly().convert(e),i.config(a).render(u),t.data=e.data,t.layout=e.layout,c.fillLayout(t),e}return f.isPolar=!0,f.svg=function(){return i.svg()},f.getConfig=function(){return e},f.getLiveConfig=function(){return o.adapter.plotly().convert(i.getLiveConfig(),!0)},f.getLiveScales=function(){return{t:i.angularScale(),r:i.radialScale()}},f.setUndoPoint=function(){var t,n,i=this,a=o.util.cloneJson(e);t=a,n=r,h.add({undo:function(){n&&i(n)},redo:function(){i(t)}}),r=o.util.cloneJson(a)},f.undo=function(){h.undo()},f.redo=function(){h.redo()},f},c.fillLayout=function(t){var e=n.select(t).selectAll(".plot-container"),r=e.selectAll(".svg-container"),i=t.framework&&t.framework.svg&&t.framework.svg(),o={width:800,height:600,paper_bgcolor:a.background,_container:e,_paperdiv:r,_paper:i};t._fullLayout=l(o,t.layout)}},{"../../../components/color":558,"../../../lib":684,"./micropolar":804,"./undo_manager":806,d3:147}],806:[function(t,e,r){"use strict";e.exports=function(){var t,e=[],r=-1,n=!1;function i(t,e){return t?(n=!0,t[e](),n=!1,this):this}return{add:function(t){return n?this:(e.splice(r+1,e.length-r),e.push(t),r=e.length-1,this)},setCallback:function(e){t=e},undo:function(){var n=e[r];return n?(i(n,"undo"),r-=1,t&&t(n.undo),this):this},redo:function(){var n=e[r+1];return n?(i(n,"redo"),r+=1,t&&t(n.redo),this):this},clear:function(){e=[],r=-1},hasUndo:function(){return-1!==r},hasRedo:function(){return rn&&(n+=360);var i=M(k(t)),a=i+360;return i>=r&&i<=n||a>=r&&a<=n}function I(t,e){return e[D(e,function(e){return Math.abs(O(t,e))})]}function O(t,e){var r=e-t;return Math.atan2(Math.sin(r),Math.cos(r))}function D(t,e){e=e||o.identity;for(var r,n=1/0,i=0;i1e-10?t:0}function Y(t){return Math.abs(t)<1e-10?0:t>0?1:-1}function X(t){return Y(Math.cos(t))}function Z(t){return Y(Math.sin(t))}e.exports=function(t,e){return new E(t,e)},C.plot=function(t,e){var r=e[this.id];this._hasClipOnAxisFalse=!1;for(var n=0;n=90||s>90&&l>=450?1:u<=0&&f<=0?0:Math.max(u,f);e=s<=180&&l>=180||s>180&&l>=540?-1:c>=0&&h>=0?0:Math.min(c,h);r=s<=270&&l>=270||s>270&&l>=630?-1:u>=0&&f>=0?0:Math.min(u,f);n=l>=360?1:c<=0&&h<=0?0:Math.max(c,h);return[e,r,n,i]}(y),b=x[2]-x[0],_=x[3]-x[1],k=v/m,A=Math.abs(_/b);k>A?(h=m,g=(v-(f=m*A))/i.h/2,p=[a[0],a[1]],d=[c[0]+g,c[1]-g]):(f=v,g=(m-(h=v/A))/i.w/2,p=[a[0]+g,a[1]-g],d=[c[0],c[1]]),r.xLength2=h,r.yLength2=f,r.xDomain2=p,r.yDomain2=d;var T=r.xOffset2=i.l+i.w*p[0],S=r.yOffset2=i.t+i.h*(1-d[1]),E=r.radius=h/b,C=r.cx=T-E*x[0],L=r.cy=S+E*x[3],z=r.cxx=C-T,P=r.cyy=L-S,I={anchor:"free",position:0,_counteraxis:!0,automargin:!1};r.radialAxis=o.extendFlat({},e.radialaxis,I,{_axislayer:n["radial-axis"],_gridlayer:n["radial-grid"],_id:"x",_pos:0,side:{counterclockwise:"top",clockwise:"bottom"}[e.radialaxis.side],domain:[0,E/i.w]}),r.angularAxis=o.extendFlat({},e.angularaxis,I,{_axislayer:n["angular-axis"],_gridlayer:n["angular-grid"],_id:"angular",_pos:0,side:"right",domain:[0,Math.PI],autorange:!1}),r.doAutoRange(t,e),r.updateAngularAxis(t,e),r.updateRadialAxis(t,e),r.updateRadialAxisTitle(t,e);var O=r.radialAxis.range,D=O[1]-O[0],R=r.xaxis={type:"linear",_id:"x",range:[x[0]*D,x[2]*D],domain:p};u.setConvert(R,t),R.setScale();var B=r.yaxis={type:"linear",_id:"y",range:[x[1]*D,x[3]*D],domain:d};u.setConvert(B,t),B.setScale(),R.isPtWithinRange=function(t){return r.isPtWithinSector(t)},B.isPtWithinRange=function(){return!0},r.clipPaths.forTraces.select("path").attr("d",V(E,y,r.vangles)).attr("transform",H(z,P)),n.frontplot.attr("transform",H(T,S)).call(l.setClipUrl,r._hasClipOnAxisFalse?null:r.clipIds.forTraces),n.bg.attr("d",V(E,y,r.vangles)).attr("transform",H(C,L)).call(s.fill,e.bgcolor),r.framework.selectAll(".crisp").classed("crisp",0)},C.doAutoRange=function(t,e){var r=e.radialaxis,n=this.radialAxis;L(n,r,t),h(n),r.range=n.range.slice(),r._input.range=n.range.slice()},C.updateRadialAxis=function(t,e){var r=this,n=r.gd,i=r.layers,a=r.radius,o=r.cx,l=r.cy,c=e.radialaxis,h=e.sector,f=M(h[0]),p=r.radialAxis;r.fillViewInitialKey("radialaxis.angle",c.angle),r.fillViewInitialKey("radialaxis.range",p.range.slice()),"auto"===p.tickangle&&f>90&&f<=270&&(p.tickangle=180),p._transfn=function(t){return"translate("+p.l2p(t.x)+",0)"},p._gridpath=function(t){return j(p.r2p(t.x),h,r.vangles)};var d=z(c);r.radialTickLayout!==d&&(i["radial-axis"].selectAll(".xtick").remove(),r.radialTickLayout=d),u.doTicksSingle(n,p,!0);var g=r.radialAxisAngle=r.vangles?k(I(w(c.angle),r.vangles)):c.angle,m=H(o,l)+G(-g);q(i["radial-axis"],c.showticklabels||c.ticks,{transform:m}),q(i["radial-grid"],c.showgrid,{transform:H(o,l)}).selectAll("path").attr("transform",null),q(i["radial-line"].select("line"),c.showline,{x1:0,y1:0,x2:a,y2:0,transform:m}).attr("stroke-width",c.linewidth).call(s.stroke,c.linecolor)},C.updateRadialAxisTitle=function(t,e,r){var n=this.gd,i=this.radius,a=this.cx,o=this.cy,s=e.radialaxis,c=this.id+"title",u=void 0!==r?r:this.radialAxisAngle,h=w(u),f=Math.cos(h),p=Math.sin(h),d=0;if(s.title){var m=l.bBox(this.layers["radial-axis"].node()).height,v=s.titlefont.size;d="counterclockwise"===s.side?-m-.4*v:m+.8*v}this.layers["radial-axis-title"]=g.draw(n,c,{propContainer:s,propName:this.id+".radialaxis.title",placeholder:_(n,"Click to enter radial axis title"),attributes:{x:a+i/2*f+d*p,y:o-i/2*p+d*f,"text-anchor":"middle"},transform:{rotate:-u}})},C.updateAngularAxis=function(t,e){var r=this.gd,i=this.layers,a=this.radius,o=this.cx,l=this.cy,c=e.angularaxis,h=e.sector,f=h.map(w),p=this.angularAxis;function d(t){return p.c2rad(t.x,"degrees")}function g(t){return[a*Math.cos(t),a*Math.sin(t)]}if(this.fillViewInitialKey("angularaxis.rotation",c.rotation),"linear"===p.type)U(h)?p.range=h.slice():p.range=f.map(p.unTransformRad).map(k),"radians"===p.thetaunit&&(p.tick0=k(p.tick0),p.dtick=k(p.dtick));else if("category"===p.type){var m=c.period?Math.max(c.period,c._categories.length):c._categories.length;p.range=[0,m],p._tickFilter=function(t){return P(d(t),h)}}L(p,c,t),p._transfn=function(t){var e=d(t),r=g(e),i=H(o+r[0],l-r[1]),a=n.select(this);return a&&a.node()&&a.classed("ticks")&&(i+=G(-k(e))),i},p._gridpath=function(t){var e=g(d(t));return"M0,0L"+-e[0]+","+e[1]};var v="outside"!==c.ticks?.7:.5;p._labelx=function(t){var e=d(t),r=p._labelStandoff,n=p._pad;return(0===Z(e)?0:Math.cos(e)*(r+n+v*t.fontSize))+X(e)*(t.dx+r+n)},p._labely=function(t){var e=d(t),r=p._labelStandoff,n=p._labelShift,i=p._pad;return t.dy+t.fontSize*b-n+-Math.sin(e)*(r+i+v*t.fontSize)},p._labelanchor=function(t,e){var r=d(e);return 0===Z(r)?X(r)>0?"start":"end":"middle"};var y,x=z(c);this.angularTickLayout!==x&&(i["angular-axis"].selectAll(".angulartick").remove(),this.angularTickLayout=x),u.doTicksSingle(r,p,!0),"linear"===e.gridshape?O((y=p._vals.map(d))[0],y[1])<0&&(y=y.slice().reverse()):y=null,this.vangles=y,q(i["angular-line"].select("path"),c.showline,{d:V(a,h,y),transform:H(o,l)}).attr("stroke-width",c.linewidth).call(s.stroke,c.linecolor)},C.updateFx=function(t,e){this.gd._context.staticPlot||(this.updateAngularDrag(t,e),this.updateRadialDrag(t,e),this.updateMainDrag(t,e))},C.updateMainDrag=function(t,e){var r=this,s=r.gd,l=r.layers,c=t._zoomlayer,u=S.MINZOOM,h=S.OFFEDGE,g=r.radius,y=r.cx,x=r.cy,b=r.cxx,_=r.cyy,w=e.sector,k=r.vangles,M=S.cornerHalfWidth,A=S.cornerLen/2,T=p.makeDragger(l,"path","maindrag","crosshair");n.select(T).attr("d",V(g,w,k)).attr("transform",H(y,x));var E,C,L,z,P,I,N,j,U,q={element:T,gd:s,subplot:r.id,plotinfo:{xaxis:r.xaxis,yaxis:r.yaxis},xaxes:[r.xaxis],yaxes:[r.yaxis]};function G(t,e){return Math.sqrt(t*t+e*e)}function Y(t,e){return G(t-b,e-_)}function X(t,e){return Math.atan2(_-e,t-b)}function Z(t,e){return[t*Math.cos(e),t*Math.sin(-e)]}function $(t){return V(t,w,k)}function J(t,e){if(0===t)return $(2*M);var r=A/t,n=e-r,i=e+r,a=Math.max(0,Math.min(t,g)),o=a-M,s=a+M;return"M"+Z(o,n)+"A"+[o,o]+" 0,0,0 "+Z(o,i)+"L"+Z(s,i)+"A"+[s,s]+" 0,0,1 "+Z(s,n)+"Z"}function K(t,e,r){if(0===t)return $(2*M);var n,i,a=Z(t,e),o=Z(t,r),s=W((a[0]+o[0])/2),l=W((a[1]+o[1])/2);if(s&&l){var c=l/s,u=-1/c,h=B(M,c,s,l);n=B(A,u,h[0][0],h[0][1]),i=B(A,u,h[1][0],h[1][1])}else{var f,p;l?(f=A,p=M):(f=M,p=A),n=[[s-f,l-p],[s+f,l-p]],i=[[s-f,l+p],[s+f,l+p]]}return"M"+n.join("L")+"L"+i.reverse().join("L")+"Z"}function Q(t,e){return e=Math.min(e,g),tu?(t0?r:1/0}),r=o.mod(e+1,k.length);return[k[e],k[r]]}function nt(t,e,r,n){var i=R(r,n,r,[t-b,_-e]);return G(i[0],i[1])}function it(t,e){var r,n,i=E+t,a=C+e,o=X(E,C),s=X(i,a),l=rt(o),c=rt(s);Q(nt(E,C,l[0],l[1]),Math.min(nt(i,a,c[0],c[1]),g))&&(r=P+$(z)+$(L),n=[K(L,l[0],l[1]),K(z,l[0],l[1])].join(" ")),tt(r,n)}function at(){if(p.removeZoombox(s),null!==L&&null!==z){p.showDoubleClickNotifier(s);var t=r.radialAxis.range,e=t[1]-t[0],n={};n[r.id+".radialaxis.range"]=[t[0]+L*e/g,t[0]+z*e/g],a.call("relayout",s,n)}}q.prepFn=function(t,e,n){var a=s._fullLayout.dragmode,o=T.getBoundingClientRect();if(E=e-o.left,C=n-o.top,k){var l=function(t,e,r){for(var n=1/0,i=1/0,a=F(t,e,r),o=0;o0==f>y[0]){T=d.range[1]=f,u.doTicksSingle(i,r.radialAxis,!0),s["radial-grid"].attr("transform",H(c,h)).selectAll("path").attr("transform",null);var p=T-y[0],g=r.sectorBBox;for(var v in r.xaxis.range=[g[0]*p,g[2]*p],r.yaxis.range=[g[1]*p,g[3]*p],r.xaxis.setScale(),r.yaxis.setScale(),r.traceHash){var b=r.traceHash[v],_=o.filterVisible(b),w=b[0][0].trace._module,k=i._fullLayout[r.id];if(w.plot(i,r,_,k),!a.traceIs(v,"gl"))for(var M=0;M<_.length;M++)w.style(i,_[M])}}}},C.updateAngularDrag=function(t,e){var r,i=this,s=i.gd,c=i.layers,h=i.radius,d=i.cx,g=i.cy,m=i.cxx,x=i.cyy,b=e.sector,_=S.angularDragBoxSize,M=p.makeDragger(c,"path","angulardrag","move"),E={element:M,gd:s};if(i.vangles){var C=N(F(h+_,b,i.vangles)),L=N(F(h,b,i.vangles));r="M"+C.reverse().join("L")+"M"+L.join("L")}else r=function(t,e,r){var n,i,a,o=Math.abs(r[1]-r[0])<=180?0:1;function s(t,e){return[t*Math.cos(e),-t*Math.sin(e)]}function l(t,e,r){return"A"+[t,t]+" "+[0,o,r]+" "+s(t,e)}return U(r)?(n=0,a=2*Math.PI,i=Math.PI,"M"+s(t,n)+l(t,i,0)+l(t,a,0)+"ZM"+s(e,n)+l(e,i,1)+l(e,a,1)+"Z"):(n=w(r[0]),a=w(r[1]),"M"+s(t,n)+"L"+s(e,n)+l(e,a,0)+"L"+s(t,a)+l(t,n,1)+"Z")}(h,h+_,b);function z(t,e){return Math.atan2(x+_-e,t-m-_)}n.select(M).attr("d",r).attr("transform",H(d,g)).call(y,"move");var P,I,O,D,R,B,j,V=c.frontplot.select(".scatterlayer").selectAll(".trace"),q=V.selectAll(".point"),W=V.selectAll(".textpoint");function Y(t,e){var r=i.gd._fullLayout,h=r[i.id],f=z(P+t,I+e),p=k(f-j);if(D=O+p,c.frontplot.attr("transform",H(i.xOffset2,i.yOffset2)+G([-p,m,x])),i.vangles){R=i.radialAxisAngle+p;var v=H(d,g)+G(-p),y=H(d,g)+G(-R);c.bg.attr("transform",v),c["radial-grid"].attr("transform",v),c["angular-line"].select("path").attr("transform",v),c["radial-axis"].attr("transform",y),c["radial-line"].select("line").attr("transform",y),i.updateRadialAxisTitle(r,h,R)}else i.clipPaths.forTraces.select("path").attr("transform",H(m,x)+G(p));q.each(function(){var t=n.select(this),e=l.getTranslate(t);t.attr("transform",H(e.x,e.y)+G([p]))}),W.each(function(){var t=n.select(this),e=t.select("text"),r=l.getTranslate(t);t.attr("transform",G([p,e.attr("x"),e.attr("y")])+H(r.x,r.y))});var _=i.angularAxis;for(var M in _.rotation=A(D),"linear"!==_.type||U(b)||(_.range=B.map(w).map(_.unTransformRad).map(k)),T(_),u.doTicksSingle(s,_,!0),i._hasClipOnAxisFalse&&!U(b)&&(i.sector=[B[0]-p,B[1]-p],V.call(l.hideOutsideRangePoints,i)),i.traceHash)if(a.traceIs(M,"gl")){var S=i.traceHash[M],E=o.filterVisible(S);S[0][0].trace._module.plot(s,i,E,h)}}function X(){W.select("text").attr("transform",null);var t={};t[i.id+".angularaxis.rotation"]=D,i.vangles&&(t[i.id+".radialaxis.angle"]=R),a.call("relayout",s,t)}E.prepFn=function(e,r,n){var a=t[i.id];B=a.sector.slice(),O=a.angularaxis.rotation;var o=M.getBoundingClientRect();P=r-o.left,I=n-o.top,j=z(P,I),E.moveFn=Y,E.doneFn=X,v(t._zoomlayer)},i.vangles&&!U(b)&&(E.prepFn=o.noop,y(n.select(M),null)),f.init(E)},C.isPtWithinSector=function(t){var e=this.sector;if(!P(t.rad,e))return!1;var r,n,i=this.vangles,a=this.radialAxis,o=a.range,s=a.c2r(t.r);if(o[1]>=o[0]?(r=o[0],n=o[1]):(r=o[1],n=o[0]),i){var l=x(F(r,e,i)),c=x(F(n,e,i)),u=[s*Math.cos(t.rad),s*Math.sin(t.rad)];return c.contains(u)&&!l.contains(u)}return s>=r&&s<=n},C.fillViewInitialKey=function(t,e){t in this.viewInitial||(this.viewInitial[t]=e)}},{"../../components/color":558,"../../components/dragelement":580,"../../components/drawing":583,"../../components/fx":600,"../../components/titles":649,"../../constants/alignment":656,"../../lib":684,"../../lib/polygon":696,"../../lib/setcursor":704,"../../registry":817,"../cartesian/autorange":731,"../cartesian/axes":732,"../cartesian/dragbox":740,"../cartesian/select":749,"../plots":795,"./constants":796,"./helpers":797,d3:147,tinycolor2:499}],808:[function(t,e,r){"use strict";function n(t,e){return"splom"===t?-1:"splom"===e?1:0}e.exports={sortBasePlotModules:function(t,e){return n(t.name,e.name)},sortModules:n}},{}],809:[function(t,e,r){"use strict";var n=t("../lib"),i=t("../plot_api/plot_template"),a=t("./domain").defaults;e.exports=function(t,e,r,o){var s,l,c=o.type,u=o.attributes,h=o.handleDefaults,f=o.partition||"x",p=e._subplots[c],d=p.length,g=d&&p[0].replace(/\d+$/,"");function m(t,e){return n.coerce(s,l,u,t,e)}for(var v=0;v=f&&(d.min=0,g.min=0,m.min=0,t.aaxis&&delete t.aaxis.min,t.baxis&&delete t.baxis.min,t.caxis&&delete t.caxis.min)}e.exports=function(t,e,r){a(t,e,r,{type:"ternary",attributes:o,handleDefaults:c,font:e.font,paper_bgcolor:e.paper_bgcolor})}},{"../../../components/color":558,"../../../plot_api/plot_template":722,"../../subplot_defaults":809,"./axis_defaults":813,"./layout_attributes":815}],815:[function(t,e,r){"use strict";var n=t("../../../components/color/attributes"),i=t("../../domain").attributes,a=t("./axis_attributes"),o=t("../../../plot_api/edit_types").overrideAll;e.exports=o({domain:i({name:"ternary"}),bgcolor:{valType:"color",dflt:n.background},sum:{valType:"number",dflt:1,min:0},aaxis:a,baxis:a,caxis:a},"plot","from-root")},{"../../../components/color/attributes":557,"../../../plot_api/edit_types":715,"../../domain":757,"./axis_attributes":812}],816:[function(t,e,r){"use strict";var n=t("d3"),i=t("tinycolor2"),a=t("../../registry"),o=t("../../lib"),s=o._,l=t("../../components/color"),c=t("../../components/drawing"),u=t("../cartesian/set_convert"),h=t("../../lib/extend").extendFlat,f=t("../plots"),p=t("../cartesian/axes"),d=t("../../components/dragelement"),g=t("../../components/fx"),m=t("../../components/titles"),v=t("../cartesian/select").prepSelect,y=t("../cartesian/select").clearSelect,x=t("../cartesian/constants");function b(t,e){this.id=t.id,this.graphDiv=t.graphDiv,this.init(e),this.makeFramework(e)}e.exports=b;var _=b.prototype;_.init=function(t){this.container=t._ternarylayer,this.defs=t._defs,this.layoutId=t._uid,this.traceHash={},this.layers={}},_.plot=function(t,e){var r=e[this.id],n=e._size;this._hasClipOnAxisFalse=!1;for(var i=0;iw*x?i=(a=x)*w:a=(i=y)/w,o=m*i/y,s=v*a/x,r=e.l+e.w*d-i/2,n=e.t+e.h*(1-g)-a/2,f.x0=r,f.y0=n,f.w=i,f.h=a,f.sum=b,f.xaxis={type:"linear",range:[_+2*M-b,b-_-2*k],domain:[d-o/2,d+o/2],_id:"x"},u(f.xaxis,f.graphDiv._fullLayout),f.xaxis.setScale(),f.xaxis.isPtWithinRange=function(t){return t.a>=f.aaxis.range[0]&&t.a<=f.aaxis.range[1]&&t.b>=f.baxis.range[1]&&t.b<=f.baxis.range[0]&&t.c>=f.caxis.range[1]&&t.c<=f.caxis.range[0]},f.yaxis={type:"linear",range:[_,b-k-M],domain:[g-s/2,g+s/2],_id:"y"},u(f.yaxis,f.graphDiv._fullLayout),f.yaxis.setScale(),f.yaxis.isPtWithinRange=function(){return!0};var A=f.yaxis.domain[0],T=f.aaxis=h({},t.aaxis,{visible:!0,range:[_,b-k-M],side:"left",_counterangle:30,tickangle:(+t.aaxis.tickangle||0)-30,domain:[A,A+s*w],_axislayer:f.layers.aaxis,_gridlayer:f.layers.agrid,_pos:0,_id:"y",_length:i,_gridpath:"M0,0l"+a+",-"+i/2,automargin:!1});u(T,f.graphDiv._fullLayout),T.setScale();var S=f.baxis=h({},t.baxis,{visible:!0,range:[b-_-M,k],side:"bottom",_counterangle:30,domain:f.xaxis.domain,_axislayer:f.layers.baxis,_gridlayer:f.layers.bgrid,_counteraxis:f.aaxis,_pos:0,_id:"x",_length:i,_gridpath:"M0,0l-"+i/2+",-"+a,automargin:!1});u(S,f.graphDiv._fullLayout),S.setScale(),T._counteraxis=S;var E=f.caxis=h({},t.caxis,{visible:!0,range:[b-_-k,M],side:"right",_counterangle:30,tickangle:(+t.caxis.tickangle||0)+30,domain:[A,A+s*w],_axislayer:f.layers.caxis,_gridlayer:f.layers.cgrid,_counteraxis:f.baxis,_pos:0,_id:"y",_length:i,_gridpath:"M0,0l-"+a+","+i/2,automargin:!1});u(E,f.graphDiv._fullLayout),E.setScale();var C="M"+r+","+(n+a)+"h"+i+"l-"+i/2+",-"+a+"Z";f.clipDef.select("path").attr("d",C),f.layers.plotbg.select("path").attr("d",C);var L="M0,"+a+"h"+i+"l-"+i/2+",-"+a+"Z";f.clipDefRelative.select("path").attr("d",L);var z="translate("+r+","+n+")";f.plotContainer.selectAll(".scatterlayer,.maplayer").attr("transform",z),f.clipDefRelative.select("path").attr("transform",null);var P="translate("+(r-S._offset)+","+(n+a)+")";f.layers.baxis.attr("transform",P),f.layers.bgrid.attr("transform",P);var I="translate("+(r+i/2)+","+n+")rotate(30)translate(0,"+-T._offset+")";f.layers.aaxis.attr("transform",I),f.layers.agrid.attr("transform",I);var O="translate("+(r+i/2)+","+n+")rotate(-30)translate(0,"+-E._offset+")";f.layers.caxis.attr("transform",O),f.layers.cgrid.attr("transform",O),f.drawAxes(!0),f.plotContainer.selectAll(".crisp").classed("crisp",!1),f.layers.aline.select("path").attr("d",T.showline?"M"+r+","+(n+a)+"l"+i/2+",-"+a:"M0,0").call(l.stroke,T.linecolor||"#000").style("stroke-width",(T.linewidth||0)+"px"),f.layers.bline.select("path").attr("d",S.showline?"M"+r+","+(n+a)+"h"+i:"M0,0").call(l.stroke,S.linecolor||"#000").style("stroke-width",(S.linewidth||0)+"px"),f.layers.cline.select("path").attr("d",E.showline?"M"+(r+i/2)+","+n+"l"+i/2+","+a:"M0,0").call(l.stroke,E.linecolor||"#000").style("stroke-width",(E.linewidth||0)+"px"),f.graphDiv._context.staticPlot||f.initInteractions(),c.setClipUrl(f.layers.frontplot,f._hasClipOnAxisFalse?null:f.clipId)},_.drawAxes=function(t){var e=this.graphDiv,r=this.id.substr(7)+"title",n=this.aaxis,i=this.baxis,a=this.caxis;if(p.doTicksSingle(e,n,!0),p.doTicksSingle(e,i,!0),p.doTicksSingle(e,a,!0),t){var o=Math.max(n.showticklabels?n.tickfont.size/2:0,(a.showticklabels?.75*a.tickfont.size:0)+("outside"===a.ticks?.87*a.ticklen:0));this.layers["a-title"]=m.draw(e,"a"+r,{propContainer:n,propName:this.id+".aaxis.title",placeholder:s(e,"Click to enter Component A title"),attributes:{x:this.x0+this.w/2,y:this.y0-n.titlefont.size/3-o,"text-anchor":"middle"}});var l=(i.showticklabels?i.tickfont.size:0)+("outside"===i.ticks?i.ticklen:0)+3;this.layers["b-title"]=m.draw(e,"b"+r,{propContainer:i,propName:this.id+".baxis.title",placeholder:s(e,"Click to enter Component B title"),attributes:{x:this.x0-l,y:this.y0+this.h+.83*i.titlefont.size+l,"text-anchor":"middle"}}),this.layers["c-title"]=m.draw(e,"c"+r,{propContainer:a,propName:this.id+".caxis.title",placeholder:s(e,"Click to enter Component C title"),attributes:{x:this.x0+this.w+l,y:this.y0+this.h+.83*a.titlefont.size+l,"text-anchor":"middle"}})}};var k=x.MINZOOM/2+.87,M="m-0.87,.5h"+k+"v3h-"+(k+5.2)+"l"+(k/2+2.6)+",-"+(.87*k+4.5)+"l2.6,1.5l-"+k/2+","+.87*k+"Z",A="m0.87,.5h-"+k+"v3h"+(k+5.2)+"l-"+(k/2+2.6)+",-"+(.87*k+4.5)+"l-2.6,1.5l"+k/2+","+.87*k+"Z",T="m0,1l"+k/2+","+.87*k+"l2.6,-1.5l-"+(k/2+2.6)+",-"+(.87*k+4.5)+"l-"+(k/2+2.6)+","+(.87*k+4.5)+"l2.6,1.5l"+k/2+",-"+.87*k+"Z",S="m0.5,0.5h5v-2h-5v-5h-2v5h-5v2h5v5h2Z",E=!0;function C(t){n.select(t).selectAll(".zoombox,.js-zoombox-backdrop,.js-zoombox-menu,.zoombox-corners").remove()}_.initInteractions=function(){var t,e,r,n,u,h,f,p,m,b,_=this,k=_.layers.plotbg.select("path").node(),L=_.graphDiv,z=L._fullLayout._zoomlayer,P={element:k,gd:L,plotinfo:{xaxis:_.xaxis,yaxis:_.yaxis},subplot:_.id,prepFn:function(a,o,s){P.xaxes=[_.xaxis],P.yaxes=[_.yaxis];var c=L._fullLayout.dragmode;a.shiftKey&&(c="pan"===c?"zoom":"pan"),P.minDrag="lasso"===c?1:void 0,"zoom"===c?(P.moveFn=R,P.doneFn=B,function(a,o,s){var c=k.getBoundingClientRect();t=o-c.left,e=s-c.top,r={a:_.aaxis.range[0],b:_.baxis.range[1],c:_.caxis.range[1]},u=r,n=_.aaxis.range[1]-r.a,h=i(_.graphDiv._fullLayout[_.id].bgcolor).getLuminance(),f="M0,"+_.h+"L"+_.w/2+", 0L"+_.w+","+_.h+"Z",p=!1,m=z.append("path").attr("class","zoombox").attr("transform","translate("+_.x0+", "+_.y0+")").style({fill:h>.2?"rgba(0,0,0,0)":"rgba(255,255,255,0)","stroke-width":0}).attr("d",f),b=z.append("path").attr("class","zoombox-corners").attr("transform","translate("+_.x0+", "+_.y0+")").style({fill:l.background,stroke:l.defaultLine,"stroke-width":1,opacity:0}).attr("d","M0,0Z"),y(z)}(0,o,s)):"pan"===c?(P.moveFn=F,P.doneFn=N,r={a:_.aaxis.range[0],b:_.baxis.range[1],c:_.caxis.range[1]},u=r,y(z)):"select"!==c&&"lasso"!==c||v(a,o,s,P,c)},clickFn:function(t,e){if(C(L),2===t){var r={};r[_.id+".aaxis.min"]=0,r[_.id+".baxis.min"]=0,r[_.id+".caxis.min"]=0,L.emit("plotly_doubleclick",null),a.call("relayout",L,r)}g.click(L,e,_.id)}};function I(t,e){return 1-e/_.h}function O(t,e){return 1-(t+(_.h-e)/Math.sqrt(3))/_.w}function D(t,e){return(t-(_.h-e)/Math.sqrt(3))/_.w}function R(i,a){var o=t+i,s=e+a,l=Math.max(0,Math.min(1,I(0,e),I(0,s))),c=Math.max(0,Math.min(1,O(t,e),O(o,s))),d=Math.max(0,Math.min(1,D(t,e),D(o,s))),g=(l/2+d)*_.w,v=(1-l/2-c)*_.w,y=(g+v)/2,k=v-g,E=(1-l)*_.h,C=E-k/w;k.2?"rgba(0,0,0,0.4)":"rgba(255,255,255,0.3)").duration(200),b.transition().style("opacity",1).duration(200),p=!0)}function B(){if(C(L),u!==r){var t={};t[_.id+".aaxis.min"]=u.a,t[_.id+".baxis.min"]=u.b,t[_.id+".caxis.min"]=u.c,a.call("relayout",L,t),E&&L.data&&L._context.showTips&&(o.notifier(s(L,"Double-click to zoom back out"),"long"),E=!1)}}function F(t,e){var n=t/_.xaxis._m,i=e/_.yaxis._m,a=[(u={a:r.a-i,b:r.b+(n+i)/2,c:r.c-(n-i)/2}).a,u.b,u.c].sort(),o=a.indexOf(u.a),s=a.indexOf(u.b),l=a.indexOf(u.c);a[0]<0&&(a[1]+a[0]/2<0?(a[2]+=a[0]+a[1],a[0]=a[1]=0):(a[2]+=a[0]/2,a[1]+=a[0]/2,a[0]=0),u={a:a[o],b:a[s],c:a[l]},e=(r.a-u.a)*_.yaxis._m,t=(r.c-u.c-r.b+u.b)*_.xaxis._m);var h="translate("+(_.x0+t)+","+(_.y0+e)+")";_.plotContainer.selectAll(".scatterlayer,.maplayer").attr("transform",h);var f="translate("+-t+","+-e+")";_.clipDefRelative.select("path").attr("transform",f),_.aaxis.range=[u.a,_.sum-u.b-u.c],_.baxis.range=[_.sum-u.a-u.c,u.b],_.caxis.range=[_.sum-u.a-u.b,u.c],_.drawAxes(!1),_.plotContainer.selectAll(".crisp").classed("crisp",!1),_._hasClipOnAxisFalse&&_.plotContainer.select(".scatterlayer").selectAll(".trace").call(c.hideOutsideRangePoints,_)}function N(){var t={};t[_.id+".aaxis.min"]=u.a,t[_.id+".baxis.min"]=u.b,t[_.id+".caxis.min"]=u.c,a.call("relayout",L,t)}k.onmousemove=function(t){g.hover(L,t,_.id),L._fullLayout._lasthover=k,L._fullLayout._hoversubplot=_.id},k.onmouseout=function(t){L._dragging||d.unhover(L,t)},d.init(P)}},{"../../components/color":558,"../../components/dragelement":580,"../../components/drawing":583,"../../components/fx":600,"../../components/titles":649,"../../lib":684,"../../lib/extend":673,"../../registry":817,"../cartesian/axes":732,"../cartesian/constants":737,"../cartesian/select":749,"../cartesian/set_convert":750,"../plots":795,d3:147,tinycolor2:499}],817:[function(t,e,r){"use strict";var n=t("./lib/loggers"),i=t("./lib/noop"),a=t("./lib/push_unique"),o=t("./lib/is_plain_object"),s=t("./lib/extend"),l=t("./plots/attributes"),c=t("./plots/layout_attributes"),u=s.extendFlat,h=s.extendDeepAll;function f(t){var e=t.name,i=t.categories,a=t.meta;if(r.modules[e])n.log("Type "+e+" already registered");else{r.subplotsRegistry[t.basePlotModule.name]||function(t){var e=t.name;if(r.subplotsRegistry[e])return void n.log("Plot type "+e+" already registered.");for(var i in m(t),r.subplotsRegistry[e]=t,r.componentsRegistry)x(i,t.name)}(t.basePlotModule);for(var o={},s=0;s-1&&(u[f[r]].title="");for(r=0;r")?"":e.html(t).text()});return e.remove(),r}(_),_=(_=_.replace(/&(?!\w+;|\#[0-9]+;| \#x[0-9A-F]+;)/g,"&")).replace(c,"'"),i.isIE()&&(_=(_=(_=_.replace(/"/gi,"'")).replace(/(\('#)([^']*)('\))/gi,'("#$2")')).replace(/(\\')/gi,'"')),_}},{"../components/color":558,"../components/drawing":583,"../constants/xmlns_namespaces":663,"../lib":684,d3:147}],826:[function(t,e,r){"use strict";var n=t("../../lib").mergeArray;e.exports=function(t,e){for(var r=0;ra;if(!o)return e}return void 0!==r?r:t.dflt}(t.size,s,n.size),color:function(t,e,r){return a(e).isValid()?e:void 0!==r?r:t.dflt}(t.color,l,n.color)}}function b(t,e){var r;return Array.isArray(t)?e.01?N:function(t,e){return Math.abs(t-e)>=2?N(t):t>e?Math.ceil(t):Math.floor(t)};A=F(A,E),E=F(E,A),C=F(C,L),L=F(L,C)}o.ensureSingle(z,"path").style("vector-effect","non-scaling-stroke").attr("d","M"+A+","+C+"V"+L+"H"+E+"V"+C+"Z").call(c.setClipUrl,e.layerClipId),function(t,e,r,n,i,a,l,u){var h;function w(e,r,n){var i=o.ensureSingle(e,"text").text(r).attr({class:"bartext bartext-"+h,transform:"","text-anchor":"middle","data-notex":1}).call(c.font,n).call(s.convertToTspans,t);return i}var k=r[0].trace,M=k.orientation,A=function(t,e){var r=b(t.text,e);return _(f,r)}(k,n);if(h=function(t,e){var r=b(t.textposition,e);return function(t,e,r){return t.coerceNumber&&(e=+e),-1!==t.values.indexOf(e)?e:void 0!==r?r:t.dflt}(p,r)}(k,n),!A||"none"===h)return void e.select("text").remove();var T,S,E,C,L,z,P=function(t,e,r){return x(d,t.textfont,e,r)}(k,n,t._fullLayout.font),I=function(t,e,r){return x(g,t.insidetextfont,e,r)}(k,n,P),O=function(t,e,r){return x(m,t.outsidetextfont,e,r)}(k,n,P),D=t._fullLayout.barmode,R="relative"===D,B="stack"===D||R,F=r[n],N=!B||F._outmost,j=Math.abs(a-i)-2*v,V=Math.abs(u-l)-2*v;"outside"===h&&(N||(h="inside"));if("auto"===h)if(N){h="inside",T=w(e,A,I),S=c.bBox(T.node()),E=S.width,C=S.height;var U=E>0&&C>0,q=E<=j&&C<=V,H=E<=V&&C<=j,G="h"===M?j>=E*(V/C):V>=C*(j/E);U&&(q||H||G)?h="inside":(h="outside",T.remove(),T=null)}else h="inside";if(!T&&(T=w(e,A,"outside"===h?O:I),S=c.bBox(T.node()),E=S.width,C=S.height,E<=0||C<=0))return void T.remove();"outside"===h?(z="both"===k.constraintext||"outside"===k.constraintext,L=function(t,e,r,n,i,a,o){var s,l="h"===a?Math.abs(n-r):Math.abs(e-t);l>2*v&&(s=v);var c=1;o&&(c="h"===a?Math.min(1,l/i.height):Math.min(1,l/i.width));var u,h,f,p,d=(i.left+i.right)/2,g=(i.top+i.bottom)/2;u=c*i.width,h=c*i.height,"h"===a?er?(f=(t+e)/2,p=n+s+h/2):(f=(t+e)/2,p=n-s-h/2);return y(d,g,f,p,c,!1)}(i,a,l,u,S,M,z)):(z="both"===k.constraintext||"inside"===k.constraintext,L=function(t,e,r,n,i,a,o){var s,l,c,u,h,f,p,d=i.width,g=i.height,m=(i.left+i.right)/2,x=(i.top+i.bottom)/2,b=Math.abs(e-t),_=Math.abs(n-r);b>2*v&&_>2*v?(b-=2*(h=v),_-=2*h):h=0;d<=b&&g<=_?(f=!1,p=1):d<=_&&g<=b?(f=!0,p=1):dr?(c=(t+e)/2,u=n-h-l/2):(c=(t+e)/2,u=n+h+l/2);return y(m,x,c,u,p,f)}(i,a,l,u,S,M,z));T.attr("transform",L)}(t,z,r,u,A,E,C,L),e.layerClipId&&c.hideOutsideRangePoint(r[u],z.select("text"),h,w,M.xcalendar,M.ycalendar)}else z.remove();function N(t){return 0===k.bargap&&0===k.bargroupgap?n.round(Math.round(t)-B,2):t}});var C=!1===r[0].trace.cliponaxis;c.setClipUrl(A,C?null:e.layerClipId)}),u.getComponentMethod("errorbars","plot")(M,e)}},{"../../components/color":558,"../../components/drawing":583,"../../lib":684,"../../lib/svg_text_utils":708,"../../registry":817,"./attributes":827,d3:147,"fast-isnumeric":214,tinycolor2:499}],835:[function(t,e,r){"use strict";e.exports=function(t,e){var r,n=t.cd,i=t.xaxis,a=t.yaxis,o=[];if(!1===e)for(r=0;rh+c||!n(u))&&(p=!0,g(f,t))}for(var m=0;m1||0===s.bargap&&0===s.bargroupgap&&!t[0].trace.marker.line.width)&&n.select(this).attr("shape-rendering","crispEdges")}),r.selectAll("g.points").each(function(e){o(n.select(this),e[0].trace,t)}),a.getComponentMethod("errorbars","style")(r)},styleOnSelect:function(t,e){var r=e[0].node3,n=e[0].trace;n.selectedpoints?(i.selectedPointStyle(r.selectAll("path"),n),i.selectedTextStyle(r.selectAll("text"),n)):o(r,n,t)}}},{"../../components/drawing":583,"../../registry":817,d3:147}],839:[function(t,e,r){"use strict";var n=t("../../components/color"),i=t("../../components/colorscale/has_colorscale"),a=t("../../components/colorscale/defaults");e.exports=function(t,e,r,o,s){r("marker.color",o),i(t,"marker")&&a(t,e,s,r,{prefix:"marker.",cLetter:"c"}),r("marker.line.color",n.defaultLine),i(t,"marker.line")&&a(t,e,s,r,{prefix:"marker.line.",cLetter:"c"}),r("marker.line.width"),r("marker.opacity"),r("selected.marker.color"),r("unselected.marker.color")}},{"../../components/color":558,"../../components/colorscale/defaults":568,"../../components/colorscale/has_colorscale":572}],840:[function(t,e,r){"use strict";var n=t("../scatter/attributes"),i=t("../../components/color/attributes"),a=t("../../lib/extend").extendFlat,o=n.marker,s=o.line;e.exports={y:{valType:"data_array",editType:"calc+clearAxisTypes"},x:{valType:"data_array",editType:"calc+clearAxisTypes"},x0:{valType:"any",editType:"calc+clearAxisTypes"},y0:{valType:"any",editType:"calc+clearAxisTypes"},name:{valType:"string",editType:"calc+clearAxisTypes"},text:a({},n.text,{}),whiskerwidth:{valType:"number",min:0,max:1,dflt:.5,editType:"calcIfAutorange"},notched:{valType:"boolean",editType:"calcIfAutorange"},notchwidth:{valType:"number",min:0,max:.5,dflt:.25,editType:"calcIfAutorange"},boxpoints:{valType:"enumerated",values:["all","outliers","suspectedoutliers",!1],dflt:"outliers",editType:"calcIfAutorange"},boxmean:{valType:"enumerated",values:[!0,"sd",!1],dflt:!1,editType:"calcIfAutorange"},jitter:{valType:"number",min:0,max:1,editType:"calcIfAutorange"},pointpos:{valType:"number",min:-2,max:2,editType:"calcIfAutorange"},orientation:{valType:"enumerated",values:["v","h"],editType:"calc+clearAxisTypes"},marker:{outliercolor:{valType:"color",dflt:"rgba(0, 0, 0, 0)",editType:"style"},symbol:a({},o.symbol,{arrayOk:!1,editType:"plot"}),opacity:a({},o.opacity,{arrayOk:!1,dflt:1,editType:"style"}),size:a({},o.size,{arrayOk:!1,editType:"calcIfAutorange"}),color:a({},o.color,{arrayOk:!1,editType:"style"}),line:{color:a({},s.color,{arrayOk:!1,dflt:i.defaultLine,editType:"style"}),width:a({},s.width,{arrayOk:!1,dflt:0,editType:"style"}),outliercolor:{valType:"color",editType:"style"},outlierwidth:{valType:"number",min:0,dflt:1,editType:"style"},editType:"style"},editType:"plot"},line:{color:{valType:"color",editType:"style"},width:{valType:"number",min:0,dflt:2,editType:"style"},editType:"plot"},fillcolor:n.fillcolor,selected:{marker:n.selected.marker,editType:"style"},unselected:{marker:n.unselected.marker,editType:"style"},hoveron:{valType:"flaglist",flags:["boxes","points"],dflt:"boxes+points",editType:"style"}}},{"../../components/color/attributes":557,"../../lib/extend":673,"../scatter/attributes":1015}],841:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../../lib"),a=i._,o=t("../../plots/cartesian/axes");function s(t,e,r){var n={text:"tx"};for(var i in n)Array.isArray(e[i])&&(t[n[i]]=e[i][r])}function l(t,e){return t.v-e.v}function c(t){return t.v}e.exports=function(t,e){var r,u,h,f,p,d=t._fullLayout,g=o.getFromId(t,e.xaxis||"x"),m=o.getFromId(t,e.yaxis||"y"),v=[],y="violin"===e.type?"_numViolins":"_numBoxes";"h"===e.orientation?(u=g,h="x",f=m,p="y"):(u=m,h="y",f=g,p="x");var x=u.makeCalcdata(e,h),b=function(t,e,r,a,o){if(e in t)return r.makeCalcdata(t,e);var s;s=e+"0"in t?t[e+"0"]:"name"in t&&("category"===r.type||n(t.name)&&-1!==["linear","log"].indexOf(r.type)||i.isDateTime(t.name)&&"date"===r.type)?t.name:o;var l=r.d2c(s,0,t[e+"calendar"]);return a.map(function(){return l})}(e,p,f,x,d[y]),_=i.distinctVals(b),w=_.vals,k=_.minDiff/2,M=function(t,e){for(var r=t.length,n=new Array(r+1),i=0;i=0&&E0){var L=T[r].sort(l),z=L.map(c),P=z.length,I={pos:w[r],pts:L};I.min=z[0],I.max=z[P-1],I.mean=i.mean(z,P),I.sd=i.stdev(z,P,I.mean),I.q1=i.interp(z,.25),I.med=i.interp(z,.5),I.q3=i.interp(z,.75),I.lf=Math.min(I.q1,z[Math.min(i.findBin(2.5*I.q1-1.5*I.q3,z,!0)+1,P-1)]),I.uf=Math.max(I.q3,z[Math.max(i.findBin(2.5*I.q3-1.5*I.q1,z),0)]),I.lo=4*I.q1-3*I.q3,I.uo=4*I.q3-3*I.q1;var O=1.57*(I.q3-I.q1)/Math.sqrt(P);I.ln=I.med-O,I.un=I.med+O,v.push(I)}return function(t,e){if(i.isArrayOrTypedArray(e.selectedpoints))for(var r=0;r0?(v[0].t={num:d[y],dPos:k,posLetter:p,valLetter:h,labels:{med:a(t,"median:"),min:a(t,"min:"),q1:a(t,"q1:"),q3:a(t,"q3:"),max:a(t,"max:"),mean:"sd"===e.boxmean?a(t,"mean \xb1 \u03c3:"):a(t,"mean:"),lf:a(t,"lower fence:"),uf:a(t,"upper fence:")}},d[y]++,v):[{t:{empty:!0}}]}},{"../../lib":684,"../../plots/cartesian/axes":732,"fast-isnumeric":214}],842:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../registry"),a=t("../../components/color"),o=t("./attributes");function s(t,e,r,n){var a,o,s=r("y"),l=r("x"),c=l&&l.length;if(s&&s.length)a="v",c?o=Math.min(l.length,s.length):(r("x0"),o=s.length);else{if(!c)return void(e.visible=!1);a="h",r("y0"),o=l.length}e._length=o,i.getComponentMethod("calendars","handleTraceDefaults")(t,e,["x","y"],n),r("orientation",a)}function l(t,e,r,i){var a=i.prefix,s=n.coerce2(t,e,o,"marker.outliercolor"),l=r("marker.line.outliercolor"),c=r(a+"points",s||l?"suspectedoutliers":void 0);c?(r("jitter","all"===c?.3:0),r("pointpos","all"===c?-1.5:0),r("marker.symbol"),r("marker.opacity"),r("marker.size"),r("marker.color",e.line.color),r("marker.line.color"),r("marker.line.width"),"suspectedoutliers"===c&&(r("marker.line.outliercolor",e.marker.color),r("marker.line.outlierwidth")),r("selected.marker.color"),r("unselected.marker.color"),r("selected.marker.size"),r("unselected.marker.size"),r("text")):delete e.marker,r("hoveron"),n.coerceSelectionMarkerOpacity(e,r)}e.exports={supplyDefaults:function(t,e,r,i){function c(r,i){return n.coerce(t,e,o,r,i)}s(t,e,c,i),!1!==e.visible&&(c("line.color",(t.marker||{}).color||r),c("line.width"),c("fillcolor",a.addOpacity(e.line.color,.5)),c("whiskerwidth"),c("boxmean"),c("notched",void 0!==t.notchwidth)&&c("notchwidth"),l(t,e,c,{prefix:"box"}))},handleSampleDefaults:s,handlePointsDefaults:l}},{"../../components/color":558,"../../lib":684,"../../registry":817,"./attributes":840}],843:[function(t,e,r){"use strict";var n=t("../../plots/cartesian/axes"),i=t("../../lib"),a=t("../../components/fx"),o=t("../../components/color"),s=t("../scatter/fill_hover_text");function l(t,e,r,s){var l,c,u,h,f,p,d,g,m,v,y,x,b=t.cd,_=t.xa,w=t.ya,k=b[0].trace,M=b[0].t,A="violin"===k.type,T=[],S=M.bdPos,E=M.wHover,C=function(t){return t.pos+M.bPos-p};A&&"both"!==k.side?("positive"===k.side&&(m=function(t){var e=C(t);return a.inbox(e,e+E,v)}),"negative"===k.side&&(m=function(t){var e=C(t);return a.inbox(e-E,e,v)})):m=function(t){var e=C(t);return a.inbox(e-E,e+E,v)},x=A?function(t){return a.inbox(t.span[0]-f,t.span[1]-f,v)}:function(t){return a.inbox(t.min-f,t.max-f,v)},"h"===k.orientation?(f=e,p=r,d=x,g=m,l="y",u=w,c="x",h=_):(f=r,p=e,d=m,g=x,l="x",u=_,c="y",h=w);var L=Math.min(1,S/Math.abs(u.r2c(u.range[1])-u.r2c(u.range[0])));function z(t){return(d(t)+g(t))/2}v=t.maxHoverDistance-L,y=t.maxSpikeDistance-L;var P=a.getDistanceFunction(s,d,g,z);if(a.getClosest(b,P,t),!1===t.index)return[];var I=b[t.index],O=k.line.color,D=(k.marker||{}).color;o.opacity(O)&&k.line.width?t.color=O:o.opacity(D)&&k.boxpoints?t.color=D:t.color=k.fillcolor,t[l+"0"]=u.c2p(I.pos+M.bPos-S,!0),t[l+"1"]=u.c2p(I.pos+M.bPos+S,!0),t[l+"LabelVal"]=I.pos;var R=l+"Spike";t.spikeDistance=z(I)*y/v,t[R]=u.c2p(I.pos,!0);var B={},F=["med","min","q1","q3","max"];(k.boxmean||(k.meanline||{}).visible)&&F.push("mean"),(k.boxpoints||k.points)&&F.push("lf","uf");for(var N=0;Nt.uf}),l=Math.max((t.max-t.min)/10,t.q3-t.q1),c=1e-9*l,p=l*s,d=[],g=0;if(r.jitter){if(0===l)for(g=1,d=new Array(a.length),e=0;et.lo&&(_.so=!0)}return a});d.enter().append("path").classed("point",!0),d.exit().remove(),d.call(a.translatePoints,l,c)}function u(t,e,r,a){var o,s,l=e.pos,c=e.val,u=a.bPos,h=a.bPosPxOffset||0,f=r.boxmean||(r.meanline||{}).visible;Array.isArray(a.bdPos)?(o=a.bdPos[0],s=a.bdPos[1]):(o=a.bdPos,s=a.bdPos);var p=t.selectAll("path.mean").data("box"===r.type&&r.boxmean||"violin"===r.type&&r.box&&r.meanline?i.identity:[]);p.enter().append("path").attr("class","mean").style({fill:"none","vector-effect":"non-scaling-stroke"}),p.exit().remove(),p.each(function(t){var e=l.c2p(t.pos+u,!0)+h,i=l.c2p(t.pos+u-o,!0)+h,a=l.c2p(t.pos+u+s,!0)+h,p=c.c2p(t.mean,!0),d=c.c2p(t.mean-t.sd,!0),g=c.c2p(t.mean+t.sd,!0);"h"===r.orientation?n.select(this).attr("d","M"+p+","+i+"V"+a+("sd"===f?"m0,0L"+d+","+e+"L"+p+","+i+"L"+g+","+e+"Z":"")):n.select(this).attr("d","M"+i+","+p+"H"+a+("sd"===f?"m0,0L"+e+","+d+"L"+i+","+p+"L"+e+","+g+"Z":""))})}e.exports={plot:function(t,e,r,i){var a=t._fullLayout,o=e.xaxis,s=e.yaxis,h=i.selectAll("g.trace.boxes").data(r,function(t){return t[0].trace.uid});h.enter().append("g").attr("class","trace boxes"),h.exit().remove(),h.order(),h.each(function(t){var r=t[0],i=r.t,h=r.trace,f=n.select(this);e.isRangePlot||(r.node3=f);var p,d,g=a._numBoxes,m=1-a.boxgap,v="group"===a.boxmode&&g>1,y=i.dPos*m*(1-a.boxgroupgap)/(v?g:1),x=v?2*i.dPos*((i.num+.5)/g-.5)*m:0,b=y*h.whiskerwidth;!0!==h.visible||i.empty?f.remove():("h"===h.orientation?(p=s,d=o):(p=o,d=s),i.bPos=x,i.bdPos=y,i.wdPos=b,i.wHover=i.dPos*(v?m/g:1),l(f,{pos:p,val:d},h,i),c(f,{x:o,y:s},h,i),u(f,{pos:p,val:d},h,i))})},plotBoxAndWhiskers:l,plotPoints:c,plotBoxMean:u}},{"../../components/drawing":583,"../../lib":684,d3:147}],848:[function(t,e,r){"use strict";e.exports=function(t,e){var r,n,i=t.cd,a=t.xaxis,o=t.yaxis,s=[];if(!1===e)for(r=0;r=10)return null;var i=1/0;var a=-1/0;var o=e.length;for(var s=0;s0?Math.floor:Math.ceil,P=C>0?Math.ceil:Math.floor,I=C>0?Math.min:Math.max,O=C>0?Math.max:Math.min,D=z(S+L),R=P(E-L),B=[[h=T(S)]];for(a=D;a*C=0;i--)a[u-i]=t[h][i],o[u-i]=e[h][i];for(s.push({x:a,y:o,bicubic:l}),i=h,a=[],o=[];i>=0;i--)a[h-i]=t[i][0],o[h-i]=e[i][0];return s.push({x:a,y:o,bicubic:c}),s}},{}],863:[function(t,e,r){"use strict";var n=t("../../plots/cartesian/axes"),i=t("../../lib/extend").extendFlat;e.exports=function(t,e,r){var a,o,s,l,c,u,h,f,p,d,g,m,v,y,x=t["_"+e],b=t[e+"axis"],_=b._gridlines=[],w=b._minorgridlines=[],k=b._boundarylines=[],M=t["_"+r],A=t[r+"axis"];"array"===b.tickmode&&(b.tickvals=x.slice());var T=t._xctrl,S=t._yctrl,E=T[0].length,C=T.length,L=t._a.length,z=t._b.length;n.prepTicks(b),"array"===b.tickmode&&delete b.tickvals;var P=b.smoothing?3:1;function I(n){var i,a,o,s,l,c,u,h,p,d,g,m,v=[],y=[],x={};if("b"===e)for(a=t.b2j(n),o=Math.floor(Math.max(0,Math.min(z-2,a))),s=a-o,x.length=z,x.crossLength=L,x.xy=function(e){return t.evalxy([],e,a)},x.dxy=function(e,r){return t.dxydi([],e,o,r,s)},i=0;i0&&(p=t.dxydi([],i-1,o,0,s),v.push(l[0]+p[0]/3),y.push(l[1]+p[1]/3),d=t.dxydi([],i-1,o,1,s),v.push(h[0]-d[0]/3),y.push(h[1]-d[1]/3)),v.push(h[0]),y.push(h[1]),l=h;else for(i=t.a2i(n),c=Math.floor(Math.max(0,Math.min(L-2,i))),u=i-c,x.length=L,x.crossLength=z,x.xy=function(e){return t.evalxy([],i,e)},x.dxy=function(e,r){return t.dxydj([],c,e,u,r)},a=0;a0&&(g=t.dxydj([],c,a-1,u,0),v.push(l[0]+g[0]/3),y.push(l[1]+g[1]/3),m=t.dxydj([],c,a-1,u,1),v.push(h[0]-m[0]/3),y.push(h[1]-m[1]/3)),v.push(h[0]),y.push(h[1]),l=h;return x.axisLetter=e,x.axis=b,x.crossAxis=A,x.value=n,x.constvar=r,x.index=f,x.x=v,x.y=y,x.smoothing=A.smoothing,x}function O(n){var i,a,o,s,l,c=[],u=[],h={};if(h.length=x.length,h.crossLength=M.length,"b"===e)for(o=Math.max(0,Math.min(z-2,n)),l=Math.min(1,Math.max(0,n-o)),h.xy=function(e){return t.evalxy([],e,n)},h.dxy=function(e,r){return t.dxydi([],e,o,r,l)},i=0;ix.length-1||_.push(i(O(o),{color:b.gridcolor,width:b.gridwidth}));for(f=u;fx.length-1||g<0||g>x.length-1))for(m=x[s],v=x[g],a=0;ax[x.length-1]||w.push(i(I(d),{color:b.minorgridcolor,width:b.minorgridwidth}));b.startline&&k.push(i(O(0),{color:b.startlinecolor,width:b.startlinewidth})),b.endline&&k.push(i(O(x.length-1),{color:b.endlinecolor,width:b.endlinewidth}))}else{for(l=5e-15,u=(c=[Math.floor((x[x.length-1]-b.tick0)/b.dtick*(1+l)),Math.ceil((x[0]-b.tick0)/b.dtick/(1+l))].sort(function(t,e){return t-e}))[0],h=c[1],f=u;f<=h;f++)p=b.tick0+b.dtick*f,_.push(i(I(p),{color:b.gridcolor,width:b.gridwidth}));for(f=u-1;fx[x.length-1]||w.push(i(I(d),{color:b.minorgridcolor,width:b.minorgridwidth}));b.startline&&k.push(i(I(x[0]),{color:b.startlinecolor,width:b.startlinewidth})),b.endline&&k.push(i(I(x[x.length-1]),{color:b.endlinecolor,width:b.endlinewidth}))}}},{"../../lib/extend":673,"../../plots/cartesian/axes":732}],864:[function(t,e,r){"use strict";var n=t("../../plots/cartesian/axes"),i=t("../../lib/extend").extendFlat;e.exports=function(t,e){var r,a,o,s=e._labels=[],l=e._gridlines;for(r=0;re.length&&(t=t.slice(0,e.length)):t=[],i=0;i90&&(p-=180,l=-l),{angle:p,flip:l,p:t.c2p(n,e,r),offsetMultplier:c}}},{}],878:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../components/drawing"),a=t("./map_1d_array"),o=t("./makepath"),s=t("./orient_text"),l=t("../../lib/svg_text_utils"),c=t("../../lib"),u=t("../../constants/alignment"),h=t("../../plots/get_data").getUidsFromCalcData;function f(t,e,r,n){var i=r[0],l=r[0].trace,u=e.xaxis,h=e.yaxis,f=l.aaxis,g=l.baxis,m=t._fullLayout._clips,y=c.ensureSingle(n,"g","carpet"+l.uid).classed("trace",!0),x=c.ensureSingle(y,"g","minorlayer"),b=c.ensureSingle(y,"g","majorlayer"),_=c.ensureSingle(y,"g","boundarylayer"),w=c.ensureSingle(y,"g","labellayer");y.style("opacity",l.opacity),p(u,h,b,f,"a",f._gridlines),p(u,h,b,g,"b",g._gridlines),p(u,h,x,f,"a",f._minorgridlines),p(u,h,x,g,"b",g._minorgridlines),p(u,h,_,f,"a-boundary",f._boundarylines),p(u,h,_,g,"b-boundary",g._boundarylines),function(t,e,r,n,i,a,o,l){var u,h,f,p;u=.5*(r.a[0]+r.a[r.a.length-1]),h=r.b[0],f=r.ab2xy(u,h,!0),p=r.dxyda_rough(u,h),void 0===o.angle&&c.extendFlat(o,s(r,i,a,f,r.dxydb_rough(u,h)));v(t,e,r,n,f,p,r.aaxis,i,a,o,"a-title"),u=r.a[0],h=.5*(r.b[0]+r.b[r.b.length-1]),f=r.ab2xy(u,h,!0),p=r.dxydb_rough(u,h),void 0===l.angle&&c.extendFlat(l,s(r,i,a,f,r.dxyda_rough(u,h)));v(t,e,r,n,f,p,r.baxis,i,a,l,"b-title")}(t,w,l,i,u,h,d(t,u,h,l,i,w,f._labels,"a-label"),d(t,u,h,l,i,w,g._labels,"b-label")),function(t,e,r,n,i){var s,l,u,h,f=r.select("#"+t._clipPathId);f.size()||(f=r.append("clipPath").classed("carpetclip",!0));var p=c.ensureSingle(f,"path","carpetboundary"),d=e.clipsegments,g=[];for(h=0;h0?"start":"end","data-notex":1}).call(i.font,o.font).text(o.text).call(l.convertToTspans,t),m=i.bBox(this);g.attr("transform","translate("+u.p[0]+","+u.p[1]+") rotate("+u.angle+")translate("+o.axis.labelpadding*f+","+.3*m.height+")"),p=Math.max(p,m.width+o.axis.labelpadding)}),f.exit().remove(),d.maxExtent=p,d}e.exports=function(t,e,r,i){var a=h(r);i.selectAll("g.trace").each(function(){var t=n.select(this).attr("class").split("carpet")[1].split(/\s/)[0];a[t]||n.select(this).remove()});for(var o=0;o90&&d<270,y=n.select(this);y.text(u.title||"").call(l.convertToTspans,t),v&&(x=(-l.lineCount(y)+m)*g*a-x),y.attr("transform","translate("+e.p[0]+","+e.p[1]+") rotate("+e.angle+") translate(0,"+x+")").classed("user-select-none",!0).attr("text-anchor","middle").call(i.font,u.titlefont)}),y.exit().remove()}},{"../../components/drawing":583,"../../constants/alignment":656,"../../lib":684,"../../lib/svg_text_utils":708,"../../plots/get_data":768,"./makepath":875,"./map_1d_array":876,"./orient_text":877,d3:147}],879:[function(t,e,r){"use strict";var n=t("./constants"),i=t("../../lib/search").findBin,a=t("./compute_control_points"),o=t("./create_spline_evaluator"),s=t("./create_i_derivative_evaluator"),l=t("./create_j_derivative_evaluator");e.exports=function(t){var e=t._a,r=t._b,c=e.length,u=r.length,h=t.aaxis,f=t.baxis,p=e[0],d=e[c-1],g=r[0],m=r[u-1],v=e[e.length-1]-e[0],y=r[r.length-1]-r[0],x=v*n.RELATIVE_CULL_TOLERANCE,b=y*n.RELATIVE_CULL_TOLERANCE;p-=x,d+=x,g-=b,m+=b,t.isVisible=function(t,e){return t>p&&tg&&ed||em},t.setScale=function(){var e=t._x,r=t._y,n=a(t._xctrl,t._yctrl,e,r,h.smoothing,f.smoothing);t._xctrl=n[0],t._yctrl=n[1],t.evalxy=o([t._xctrl,t._yctrl],c,u,h.smoothing,f.smoothing),t.dxydi=s([t._xctrl,t._yctrl],h.smoothing,f.smoothing),t.dxydj=l([t._xctrl,t._yctrl],h.smoothing,f.smoothing)},t.i2a=function(t){var r=Math.max(0,Math.floor(t[0]),c-2),n=t[0]-r;return(1-n)*e[r]+n*e[r+1]},t.j2b=function(t){var e=Math.max(0,Math.floor(t[1]),c-2),n=t[1]-e;return(1-n)*r[e]+n*r[e+1]},t.ij2ab=function(e){return[t.i2a(e[0]),t.j2b(e[1])]},t.a2i=function(t){var r=Math.max(0,Math.min(i(t,e),c-2)),n=e[r],a=e[r+1];return Math.max(0,Math.min(c-1,r+(t-n)/(a-n)))},t.b2j=function(t){var e=Math.max(0,Math.min(i(t,r),u-2)),n=r[e],a=r[e+1];return Math.max(0,Math.min(u-1,e+(t-n)/(a-n)))},t.ab2ij=function(e){return[t.a2i(e[0]),t.b2j(e[1])]},t.i2c=function(e,r){return t.evalxy([],e,r)},t.ab2xy=function(n,i,a){if(!a&&(ne[c-1]|ir[u-1]))return[!1,!1];var o=t.a2i(n),s=t.b2j(i),l=t.evalxy([],o,s);if(a){var h,f,p,d,g=0,m=0,v=[];ne[c-1]?(h=c-2,f=1,g=(n-e[c-1])/(e[c-1]-e[c-2])):f=o-(h=Math.max(0,Math.min(c-2,Math.floor(o)))),ir[u-1]?(p=u-2,d=1,m=(i-r[u-1])/(r[u-1]-r[u-2])):d=s-(p=Math.max(0,Math.min(u-2,Math.floor(s)))),g&&(t.dxydi(v,h,p,f,d),l[0]+=v[0]*g,l[1]+=v[1]*g),m&&(t.dxydj(v,h,p,f,d),l[0]+=v[0]*m,l[1]+=v[1]*m)}return l},t.c2p=function(t,e,r){return[e.c2p(t[0]),r.c2p(t[1])]},t.p2x=function(t,e,r){return[e.p2c(t[0]),r.p2c(t[1])]},t.dadi=function(t){var r=Math.max(0,Math.min(e.length-2,t));return e[r+1]-e[r]},t.dbdj=function(t){var e=Math.max(0,Math.min(r.length-2,t));return r[e+1]-r[e]},t.dxyda=function(e,r,n,i){var a=t.dxydi(null,e,r,n,i),o=t.dadi(e,n);return[a[0]/o,a[1]/o]},t.dxydb=function(e,r,n,i){var a=t.dxydj(null,e,r,n,i),o=t.dbdj(r,i);return[a[0]/o,a[1]/o]},t.dxyda_rough=function(e,r,n){var i=v*(n||.1),a=t.ab2xy(e+i,r,!0),o=t.ab2xy(e-i,r,!0);return[.5*(a[0]-o[0])/i,.5*(a[1]-o[1])/i]},t.dxydb_rough=function(e,r,n){var i=y*(n||.1),a=t.ab2xy(e,r+i,!0),o=t.ab2xy(e,r-i,!0);return[.5*(a[0]-o[0])/i,.5*(a[1]-o[1])/i]},t.dpdx=function(t){return t._m},t.dpdy=function(t){return t._m}}},{"../../lib/search":703,"./compute_control_points":867,"./constants":868,"./create_i_derivative_evaluator":869,"./create_j_derivative_evaluator":870,"./create_spline_evaluator":871}],880:[function(t,e,r){"use strict";var n=t("../../lib");e.exports=function(t,e,r){var i,a,o,s=[],l=[],c=t[0].length,u=t.length;function h(e,r){var n,i=0,a=0;return e>0&&void 0!==(n=t[r][e-1])&&(a++,i+=n),e0&&void 0!==(n=t[r-1][e])&&(a++,i+=n),r0&&a0&&i1e-5);return n.log("Smoother converged to",M,"after",A,"iterations"),t}},{"../../lib":684}],881:[function(t,e,r){"use strict";var n=t("../../lib").isArray1D;e.exports=function(t,e,r){var i=r("x"),a=i&&i.length,o=r("y"),s=o&&o.length;if(!a&&!s)return!1;if(e._cheater=!i,a&&!n(i)||s&&!n(o))e._length=null;else{var l=a?i.length:1/0;s&&(l=Math.min(l,o.length)),e.a&&e.a.length&&(l=Math.min(l,e.a.length)),e.b&&e.b.length&&(l=Math.min(l,e.b.length)),e._length=l}return!0}},{"../../lib":684}],882:[function(t,e,r){"use strict";var n=t("../scattergeo/attributes"),i=t("../../components/colorscale/attributes"),a=t("../../components/colorbar/attributes"),o=t("../../plots/attributes"),s=t("../../lib/extend").extendFlat,l=n.marker.line;e.exports=s({locations:{valType:"data_array",editType:"calc"},locationmode:n.locationmode,z:{valType:"data_array",editType:"calc"},text:s({},n.text,{}),marker:{line:{color:l.color,width:s({},l.width,{dflt:1}),editType:"calc"},opacity:{valType:"number",arrayOk:!0,min:0,max:1,dflt:1,editType:"style"},editType:"calc"},selected:{marker:{opacity:n.selected.marker.opacity,editType:"plot"},editType:"plot"},unselected:{marker:{opacity:n.unselected.marker.opacity,editType:"plot"},editType:"plot"},hoverinfo:s({},o.hoverinfo,{editType:"calc",flags:["location","z","text","name"]})},i("",{cLetter:"z",editTypeOverride:"calc"}),{colorbar:a})},{"../../components/colorbar/attributes":559,"../../components/colorscale/attributes":565,"../../lib/extend":673,"../../plots/attributes":729,"../scattergeo/attributes":1053}],883:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../../constants/numerical").BADNUM,a=t("../../components/colorscale/calc"),o=t("../scatter/arrays_to_calcdata"),s=t("../scatter/calc_selection");e.exports=function(t,e){for(var r=e._length,l=new Array(r),c=0;c")}(t,h,o,f.mockAxis),[t]}},{"../../plots/cartesian/axes":732,"../scatter/fill_hover_text":1022,"./attributes":882}],887:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.colorbar=t("../heatmap/colorbar"),n.calc=t("./calc"),n.plot=t("./plot"),n.style=t("./style").style,n.styleOnSelect=t("./style").styleOnSelect,n.hoverPoints=t("./hover"),n.eventData=t("./event_data"),n.selectPoints=t("./select"),n.moduleType="trace",n.name="choropleth",n.basePlotModule=t("../../plots/geo"),n.categories=["geo","noOpacity"],n.meta={},e.exports=n},{"../../plots/geo":762,"../heatmap/colorbar":928,"./attributes":882,"./calc":883,"./defaults":884,"./event_data":885,"./hover":886,"./plot":888,"./select":889,"./style":890}],888:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../lib"),a=t("../../lib/polygon"),o=t("../../lib/topojson_utils").getTopojsonFeatures,s=t("../../lib/geo_location_utils").locationToFeature,l=t("./style").style;function c(t,e){for(var r=t[0].trace,n=t.length,i=o(r,e),a=0;a0&&t[e+1][0]<0)return e;return null}switch(e="RUS"===l||"FJI"===l?function(t){var e;if(null===u(t))e=t;else for(e=new Array(t.length),i=0;ie?r[n++]=[t[i][0]+360,t[i][1]]:i===e?(r[n++]=t[i],r[n++]=[t[i][0],-90]):r[n++]=t[i];var o=a.tester(r);o.pts.pop(),c.push(o)}:function(t){c.push(a.tester(t))},o.type){case"MultiPolygon":for(r=0;r":h.value>f&&(s.prefixBoundary=!0);break;case"<":h.valuef)&&(s.prefixBoundary=!0);break;case"][":a=Math.min.apply(null,h.value),o=Math.max.apply(null,h.value),af&&(s.prefixBoundary=!0)}}},{}],899:[function(t,e,r){"use strict";var n=t("../../components/colorbar/draw"),i=t("./make_color_map"),a=t("./end_plus");e.exports=function(t,e){var r=e[0].trace,o="cb"+r.uid;if(t._fullLayout._infolayer.selectAll("."+o).remove(),r.showscale){var s=n(t,o);e[0].t.cb=s;var l=r.contours,c=r.line,u=l.size||1,h=l.coloring,f=i(r,{isColorbar:!0});"heatmap"===h&&s.filllevels({start:r.zmin,end:r.zmax,size:(r.zmax-r.zmin)/254}),s.fillcolor("fill"===h||"heatmap"===h?f:"").line({color:"lines"===h?f:c.color,width:!1!==l.showlines?c.width:0,dash:c.dash}).levels({start:l.start,end:a(l),size:u}).options(r.colorbar)()}}},{"../../components/colorbar/draw":563,"./end_plus":907,"./make_color_map":912}],900:[function(t,e,r){"use strict";e.exports={BOTTOMSTART:[1,9,13,104,713],TOPSTART:[4,6,7,104,713],LEFTSTART:[8,12,14,208,1114],RIGHTSTART:[2,3,11,208,1114],NEWDELTA:[null,[-1,0],[0,-1],[-1,0],[1,0],null,[0,-1],[-1,0],[0,1],[0,1],null,[0,1],[1,0],[1,0],[0,-1]],CHOOSESADDLE:{104:[4,1],208:[2,8],713:[7,13],1114:[11,14]},SADDLEREMAINDER:{1:4,2:8,4:1,7:13,8:2,11:14,13:7,14:11},LABELDISTANCE:2,LABELINCREASE:10,LABELMIN:3,LABELMAX:10,LABELOPTIMIZER:{EDGECOST:1,ANGLECOST:1,NEIGHBORCOST:5,SAMELEVELFACTOR:10,SAMELEVELDISTANCE:5,MAXCOST:100,INITIALSEARCHPOINTS:10,ITERATIONS:5}}},{}],901:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("./label_defaults"),a=t("../../components/color"),o=a.addOpacity,s=a.opacity,l=t("../../constants/filter_ops"),c=l.CONSTRAINT_REDUCTION,u=l.COMPARISON_OPS2;e.exports=function(t,e,r,a,l,h){var f,p,d,g=e.contours,m=r("contours.operation");(g._operation=c[m],function(t,e){var r;-1===u.indexOf(e.operation)?(t("contours.value",[0,1]),Array.isArray(e.value)?e.value.length>2?e.value=e.value.slice(2):0===e.length?e.value=[0,1]:e.length<2?(r=parseFloat(e.value[0]),e.value=[r,r+1]):e.value=[parseFloat(e.value[0]),parseFloat(e.value[1])]:n(e.value)&&(r=parseFloat(e.value),e.value=[r,r+1])):(t("contours.value",0),n(e.value)||(Array.isArray(e.value)?e.value=parseFloat(e.value[0]):e.value=0))}(r,g),"="===m?f=g.showlines=!0:(f=r("contours.showlines"),d=r("fillcolor",o((t.line||{}).color||l,.5))),f)&&(p=r("line.color",d&&s(d)?o(e.fillcolor,1):l),r("line.width",2),r("line.dash"));r("line.smoothing"),i(r,a,p,h)}},{"../../components/color":558,"../../constants/filter_ops":657,"./label_defaults":911,"fast-isnumeric":214}],902:[function(t,e,r){"use strict";var n=t("../../constants/filter_ops"),i=t("fast-isnumeric");function a(t,e){var r,a=Array.isArray(e);function o(t){return i(t)?+t:null}return-1!==n.COMPARISON_OPS2.indexOf(t)?r=o(a?e[0]:e):-1!==n.INTERVAL_OPS.indexOf(t)?r=a?[o(e[0]),o(e[1])]:[o(e),o(e)]:-1!==n.SET_OPS.indexOf(t)&&(r=a?e.map(o):[o(e)]),r}function o(t){return function(e){e=a(t,e);var r=Math.min(e[0],e[1]),n=Math.max(e[0],e[1]);return{start:r,end:n,size:n-r}}}function s(t){return function(e){return{start:e=a(t,e),end:1/0,size:1/0}}}e.exports={"[]":o("[]"),"][":o("]["),">":s(">"),"<":s("<"),"=":s("=")}},{"../../constants/filter_ops":657,"fast-isnumeric":214}],903:[function(t,e,r){"use strict";e.exports=function(t,e,r,n){var i=n("contours.start"),a=n("contours.end"),o=!1===i||!1===a,s=r("contours.size");!(o?e.autocontour=!0:r("autocontour",!1))&&s||r("ncontours")}},{}],904:[function(t,e,r){"use strict";var n=t("../../lib");function i(t){return n.extendFlat({},t,{edgepaths:n.extendDeep([],t.edgepaths),paths:n.extendDeep([],t.paths)})}e.exports=function(t,e){var r,a,o,s=function(t){return t.reverse()},l=function(t){return t};switch(e){case"=":case"<":return t;case">":for(1!==t.length&&n.warn("Contour data invalid for the specified inequality operation."),a=t[0],r=0;r1e3){n.warn("Too many contours, clipping at 1000",t);break}return l}},{"../../lib":684,"./constraint_mapping":902,"./end_plus":907}],907:[function(t,e,r){"use strict";e.exports=function(t){return t.end+t.size/1e6}},{}],908:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("./constants");function a(t,e,r,n){return Math.abs(t[0]-e[0])20&&e?208===t||1114===t?n=0===r[0]?1:-1:a=0===r[1]?1:-1:-1!==i.BOTTOMSTART.indexOf(t)?a=1:-1!==i.LEFTSTART.indexOf(t)?n=1:-1!==i.TOPSTART.indexOf(t)?a=-1:n=-1;return[n,a]}(f,r,e),d=[s(t,e,[-p[0],-p[1]])],g=p.join(","),m=t.z.length,v=t.z[0].length;for(c=0;c<1e4;c++){if(f>20?(f=i.CHOOSESADDLE[f][(p[0]||p[1])<0?0:1],t.crossings[h]=i.SADDLEREMAINDER[f]):delete t.crossings[h],!(p=i.NEWDELTA[f])){n.log("Found bad marching index:",f,e,t.level);break}d.push(s(t,e,p)),e[0]+=p[0],e[1]+=p[1],a(d[d.length-1],d[d.length-2],o,l)&&d.pop(),h=e.join(",");var y=p[0]&&(e[0]<0||e[0]>v-2)||p[1]&&(e[1]<0||e[1]>m-2);if(h===u&&p.join(",")===g||r&&y)break;f=t.crossings[h]}1e4===c&&n.log("Infinite loop in contour?");var x,b,_,w,k,M,A,T,S,E,C,L,z,P,I,O=a(d[0],d[d.length-1],o,l),D=0,R=.2*t.smoothing,B=[],F=0;for(c=1;c=F;c--)if((x=B[c])=F&&x+B[b]T&&S--,t.edgepaths[S]=C.concat(d,E));break}U||(t.edgepaths[T]=d.concat(E))}for(T=0;Tt?0:1)+(e[0][1]>t?0:2)+(e[1][1]>t?0:4)+(e[1][0]>t?0:8);return 5===r||10===r?t>(e[0][0]+e[0][1]+e[1][0]+e[1][1])/4?5===r?713:1114:5===r?104:208:15===r?0:r}e.exports=function(t){var e,r,a,o,s,l,c,u,h,f=t[0].z,p=f.length,d=f[0].length,g=2===p||2===d;for(r=0;rt.level}return r?"M"+e.join("L")+"Z":""}(t,e),f=0,p=t.edgepaths.map(function(t,e){return e}),d=!0;function g(t){return Math.abs(t[1]-e[2][1])<.01}function m(t){return Math.abs(t[0]-e[0][0])<.01}function v(t){return Math.abs(t[0]-e[2][0])<.01}for(;p.length;){for(c=a.smoothopen(t.edgepaths[f],t.smoothing),h+=d?c:c.replace(/^M/,"L"),p.splice(p.indexOf(f),1),r=t.edgepaths[f][t.edgepaths[f].length-1],s=-1,o=0;o<4;o++){if(!r){i.log("Missing end?",f,t);break}for(u=r,Math.abs(u[1]-e[0][1])<.01&&!v(r)?n=e[1]:m(r)?n=e[0]:g(r)?n=e[3]:v(r)&&(n=e[2]),l=0;l=0&&(n=y,s=l):Math.abs(r[1]-n[1])<.01?Math.abs(r[1]-y[1])<.01&&(y[0]-r[0])*(n[0]-y[0])>=0&&(n=y,s=l):i.log("endpt to newendpt is not vert. or horz.",r,n,y)}if(r=n,s>=0)break;h+="L"+n}if(s===t.edgepaths.length){i.log("unclosed perimeter path");break}f=s,(d=-1===p.indexOf(f))&&(f=p[0],h+="Z")}for(f=0;fn.center?n.right-s:s-n.left)/(u+Math.abs(Math.sin(c)*o)),p=(l>n.middle?n.bottom-l:l-n.top)/(Math.abs(h)+Math.cos(c)*o);if(f<1||p<1)return 1/0;var d=v.EDGECOST*(1/(f-1)+1/(p-1));d+=v.ANGLECOST*c*c;for(var g=s-u,m=l-h,y=s+u,x=l+h,b=0;b2*v.MAXCOST)break;p&&(s/=2),l=(o=c-s/2)+1.5*s}if(f<=v.MAXCOST)return u},r.addLabelData=function(t,e,r,n){var i=e.width/2,a=e.height/2,o=t.x,s=t.y,l=t.theta,c=Math.sin(l),u=Math.cos(l),h=i*u,f=a*c,p=i*c,d=-a*u,g=[[o-h-f,s-p-d],[o+h-f,s+p-d],[o+h+f,s+p+d],[o-h+f,s-p+d]];r.push({text:e.text,x:o,y:s,dy:e.dy,theta:l,level:e.level,width:e.width,height:e.height}),n.push(g)},r.drawLabels=function(t,e,r,a,s){var l=t.selectAll("text").data(e,function(t){return t.text+","+t.x+","+t.y+","+t.theta});if(l.exit().remove(),l.enter().append("text").attr({"data-notex":1,"text-anchor":"middle"}).each(function(t){var e=t.x+Math.sin(t.theta)*t.dy,i=t.y-Math.cos(t.theta)*t.dy;n.select(this).text(t.text).attr({x:e,y:i,transform:"rotate("+180*t.theta/Math.PI+" "+e+" "+i+")"}).call(o.convertToTspans,r)}),s){for(var c="",u=0;ue.end&&(e.start=e.end=(e.start+e.end)/2),t._input.contours||(t._input.contours={}),i.extendFlat(t._input.contours,{start:e.start,end:e.end,size:e.size}),t._input.autocontour=!0}else if("constraint"!==e.type){var l,c=e.start,u=e.end,h=t._input.contours;if(c>u&&(e.start=h.start=u,u=e.end=h.end=c,c=e.start),!(e.size>0))l=c===u?1:a(c,u,t.ncontours).dtick,h.size=e.size=l}}},{"../../lib":684,"../../plots/cartesian/axes":732}],916:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../components/drawing"),a=t("../heatmap/style"),o=t("./make_color_map");e.exports=function(t){var e=n.select(t).selectAll("g.contour");e.style("opacity",function(t){return t.trace.opacity}),e.each(function(t){var e=n.select(this),r=t.trace,a=r.contours,s=r.line,l=a.size||1,c=a.start,u="constraint"===a.type,h=!u&&"lines"===a.coloring,f=!u&&"fill"===a.coloring,p=h||f?o(r):null;e.selectAll("g.contourlevel").each(function(t){n.select(this).selectAll("path").call(i.lineGroupStyle,s.width,h?p(t.level):s.color,s.dash)});var d=a.labelfont;if(e.selectAll("g.contourlabels text").each(function(t){i.font(n.select(this),{family:d.family,size:d.size,color:d.color||(h?p(t.level):s.color)})}),u)e.selectAll("g.contourfill path").style("fill",r.fillcolor);else if(f){var g;e.selectAll("g.contourfill path").style("fill",function(t){return void 0===g&&(g=t.level),p(t.level+.5*l)}),void 0===g&&(g=c),e.selectAll("g.contourbg path").style("fill",p(g-.5*l))}}),a(t)}},{"../../components/drawing":583,"../heatmap/style":938,"./make_color_map":912,d3:147}],917:[function(t,e,r){"use strict";var n=t("../../components/colorscale/defaults"),i=t("./label_defaults");e.exports=function(t,e,r,a,o){var s,l=r("contours.coloring"),c="";"fill"===l&&(s=r("contours.showlines")),!1!==s&&("lines"!==l&&(c=r("line.color","#000")),r("line.width",.5),r("line.dash")),"none"!==l&&n(t,e,a,r,{prefix:"",cLetter:"z"}),r("line.smoothing"),i(r,a,c,o)}},{"../../components/colorscale/defaults":568,"./label_defaults":911}],918:[function(t,e,r){"use strict";var n=t("../heatmap/attributes"),i=t("../contour/attributes"),a=i.contours,o=t("../scatter/attributes"),s=t("../../components/colorscale/attributes"),l=t("../../components/colorbar/attributes"),c=t("../../lib/extend").extendFlat,u=o.line;e.exports=c({carpet:{valType:"string",editType:"calc"},z:n.z,a:n.x,a0:n.x0,da:n.dx,b:n.y,b0:n.y0,db:n.dy,text:n.text,transpose:n.transpose,atype:n.xtype,btype:n.ytype,fillcolor:i.fillcolor,autocontour:i.autocontour,ncontours:i.ncontours,contours:{type:a.type,start:a.start,end:a.end,size:a.size,coloring:{valType:"enumerated",values:["fill","lines","none"],dflt:"fill",editType:"calc"},showlines:a.showlines,showlabels:a.showlabels,labelfont:a.labelfont,labelformat:a.labelformat,operation:a.operation,value:a.value,editType:"calc",impliedEdits:{autocontour:!1}},line:{color:c({},u.color,{}),width:u.width,dash:u.dash,smoothing:c({},u.smoothing,{}),editType:"plot"}},s("",{cLetter:"z",autoColorDflt:!1}),{colorbar:l})},{"../../components/colorbar/attributes":559,"../../components/colorscale/attributes":565,"../../lib/extend":673,"../contour/attributes":896,"../heatmap/attributes":925,"../scatter/attributes":1015}],919:[function(t,e,r){"use strict";var n=t("../../components/colorscale/calc"),i=t("../../lib").isArray1D,a=t("../heatmap/convert_column_xyz"),o=t("../heatmap/clean_2d_array"),s=t("../heatmap/max_row_length"),l=t("../heatmap/interp2d"),c=t("../heatmap/find_empties"),u=t("../heatmap/make_bound_array"),h=t("./defaults"),f=t("../carpet/lookup_carpetid"),p=t("../contour/set_contours");e.exports=function(t,e){var r=e._carpetTrace=f(t,e);if(r&&r.visible&&"legendonly"!==r.visible){if(!e.a||!e.b){var d=t.data[r.index],g=t.data[e.index];g.a||(g.a=d.a),g.b||(g.b=d.b),h(g,e,e._defaultColor,t._fullLayout)}var m=function(t,e){var r,h,f,p,d,g,m,v=e._carpetTrace,y=v.aaxis,x=v.baxis;y._minDtick=0,x._minDtick=0,i(e.z)&&a(e,y,x,"a","b",["z"]);r=e._a=e._a||e.a,p=e._b=e._b||e.b,r=r?y.makeCalcdata(e,"_a"):[],p=p?x.makeCalcdata(e,"_b"):[],h=e.a0||0,f=e.da||1,d=e.b0||0,g=e.db||1,m=e._z=o(e._z||e.z,e.transpose),e._emptypoints=c(m),l(m,e._emptypoints);var b=s(m),_="scaled"===e.xtype?"":r,w=u(e,_,h,f,b,y),k="scaled"===e.ytype?"":p,M=u(e,k,d,g,m.length,x),A={a:w,b:M,z:m};"levels"===e.contours.type&&"none"!==e.contours.coloring&&n(e,m,"","z");return[A]}(0,e);return p(e),m}}},{"../../components/colorscale/calc":566,"../../lib":684,"../carpet/lookup_carpetid":874,"../contour/set_contours":915,"../heatmap/clean_2d_array":927,"../heatmap/convert_column_xyz":929,"../heatmap/find_empties":931,"../heatmap/interp2d":934,"../heatmap/make_bound_array":935,"../heatmap/max_row_length":936,"./defaults":920}],920:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../heatmap/xyz_defaults"),a=t("./attributes"),o=t("../contour/constraint_defaults"),s=t("../contour/contours_defaults"),l=t("../contour/style_defaults");e.exports=function(t,e,r,c){function u(r,i){return n.coerce(t,e,a,r,i)}if(u("carpet"),t.a&&t.b){if(!i(t,e,u,c,"a","b"))return void(e.visible=!1);u("text");var h="constraint"===u("contours.type");h||delete e.showlegend,h?o(t,e,u,c,r,{hasHover:!1}):(s(t,e,u,function(r){return n.coerce2(t,e,a,r)}),l(t,e,u,c,{hasHover:!1}))}else e._defaultColor=r,e._length=null}},{"../../lib":684,"../contour/constraint_defaults":901,"../contour/contours_defaults":903,"../contour/style_defaults":917,"../heatmap/xyz_defaults":940,"./attributes":918}],921:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.colorbar=t("../contour/colorbar"),n.calc=t("./calc"),n.plot=t("./plot"),n.style=t("../contour/style"),n.moduleType="trace",n.name="contourcarpet",n.basePlotModule=t("../../plots/cartesian"),n.categories=["cartesian","svg","carpet","contour","symbols","showLegend","hasLines","carpetDependent"],n.meta={},e.exports=n},{"../../plots/cartesian":743,"../contour/colorbar":899,"../contour/style":916,"./attributes":918,"./calc":919,"./defaults":920,"./plot":924}],922:[function(t,e,r){"use strict";var n=t("../../components/drawing"),i=t("../carpet/axis_aligned_line"),a=t("../../lib");e.exports=function(t,e,r,o,s,l,c,u){var h,f,p,d,g,m,v,y="",x=e.edgepaths.map(function(t,e){return e}),b=!0,_=1e-4*Math.abs(r[0][0]-r[2][0]),w=1e-4*Math.abs(r[0][1]-r[2][1]);function k(t){return Math.abs(t[1]-r[0][1])=0&&(p=C,g=m):Math.abs(f[1]-p[1])=0&&(p=C,g=m):a.log("endpt to newendpt is not vert. or horz.",f,p,C)}if(g>=0)break;y+=S(f,p),f=p}if(g===e.edgepaths.length){a.log("unclosed perimeter path");break}h=g,(b=-1===x.indexOf(h))&&(h=x[0],y+=S(f,p)+"Z",f=null)}for(h=0;h=0;q--)j=M.clipsegments[q],V=i([],j.x,C.c2p),U=i([],j.y,L.c2p),V.reverse(),U.reverse(),G.push(a(V,U,j.bicubic));var W="M"+G.join("L")+"Z";!function(t,e,r,n,o,l){var c,u,h,f,p=s.ensureSingle(t,"g","contourbg").selectAll("path").data("fill"!==l||o?[]:[0]);p.enter().append("path"),p.exit().remove();var d=[];for(f=0;fm&&(n.max=m);n.len=n.max-n.min}(this,r,t,n,c,e.height),!(n.len<(e.width+e.height)*f.LABELMIN)))for(var i=Math.min(Math.ceil(n.len/P),f.LABELMAX),a=0;az){C("x scale is not linear");break}}if(m.length&&"fast"===S){var P=(m[m.length-1]-m[0])/(m.length-1),I=Math.abs(P/100);for(b=0;bI){C("y scale is not linear");break}}}var O=c(x),D="scaled"===e.xtype?"":r,R=p(e,D,d,g,O,w),B="scaled"===e.ytype?"":m,F=p(e,B,v,y,x.length,k);T||(a.expand(w,R),a.expand(k,F));var N={x:R,y:F,z:x,text:e._text||e.text};if(D&&D.length===R.length-1&&(N.xCenter=D),B&&B.length===F.length-1&&(N.yCenter=B),A&&(N.xRanges=_.xRanges,N.yRanges=_.yRanges,N.pts=_.pts),M&&"constraint"===e.contours.type||s(e,x,"","z"),M&&e.contours&&"heatmap"===e.contours.coloring){var j={type:"contour"===e.type?"heatmap":"histogram2d",xcalendar:e.xcalendar,ycalendar:e.ycalendar};N.xfill=p(j,D,d,g,O,w),N.yfill=p(j,B,v,y,x.length,k)}return[N]}},{"../../components/colorscale/calc":566,"../../lib":684,"../../plots/cartesian/axes":732,"../../registry":817,"../histogram2d/calc":957,"./clean_2d_array":927,"./convert_column_xyz":929,"./find_empties":931,"./interp2d":934,"./make_bound_array":935,"./max_row_length":936}],927:[function(t,e,r){"use strict";var n=t("fast-isnumeric");e.exports=function(t,e){var r,i,a,o,s,l;function c(t){if(n(t))return+t}if(e){for(r=0,s=0;s=0;o--)(s=((h[[(r=(a=f[o])[0])-1,i=a[1]]]||g)[2]+(h[[r+1,i]]||g)[2]+(h[[r,i-1]]||g)[2]+(h[[r,i+1]]||g)[2])/20)&&(l[a]=[r,i,s],f.splice(o,1),c=!0);if(!c)throw"findEmpties iterated with no new neighbors";for(a in l)h[a]=l[a],u.push(l[a])}return u.sort(function(t,e){return e[2]-t[2]})}},{"./max_row_length":936}],932:[function(t,e,r){"use strict";var n=t("../../components/fx"),i=t("../../lib"),a=t("../../plots/cartesian/axes");e.exports=function(t,e,r,o,s,l){var c,u,h,f,p=t.cd[0],d=p.trace,g=t.xa,m=t.ya,v=p.x,y=p.y,x=p.z,b=p.xCenter,_=p.yCenter,w=p.zmask,k=[d.zmin,d.zmax],M=d.zhoverformat,A=v,T=y;if(!1!==t.index){try{h=Math.round(t.index[1]),f=Math.round(t.index[0])}catch(e){return void i.error("Error hovering on heatmap, pointNumber must be [row,col], found:",t.index)}if(h<0||h>=x[0].length||f<0||f>x.length)return}else{if(n.inbox(e-v[0],e-v[v.length-1],0)>0||n.inbox(r-y[0],r-y[y.length-1],0)>0)return;if(l){var S;for(A=[2*v[0]-v[1]],S=1;Sg&&(v=Math.max(v,Math.abs(t[a][o]-d)/(m-g))))}return v}e.exports=function(t,e){var r,i=1;for(o(t,e),r=0;r.01;r++)i=o(t,e,a(i));return i>.01&&n.log("interp2d didn't converge quickly",i),t}},{"../../lib":684}],935:[function(t,e,r){"use strict";var n=t("../../registry"),i=t("../../lib").isArrayOrTypedArray;e.exports=function(t,e,r,a,o,s){var l,c,u,h=[],f=n.traceIs(t,"contour"),p=n.traceIs(t,"histogram"),d=n.traceIs(t,"gl2d");if(i(e)&&e.length>1&&!p&&"category"!==s.type){var g=e.length;if(!(g<=o))return f?e.slice(0,o):e.slice(0,o+1);if(f||d)h=e.slice(0,o);else if(1===o)h=[e[0]-.5,e[0]+.5];else{for(h=[1.5*e[0]-.5*e[1]],u=1;u0;)h=_.c2p(A[y]),y--;for(h0;)v=w.c2p(T[y]),y--;if(v image").each(function(t){var e=t.trace||{};a[e.uid]||n.select(this.parentNode).remove()});for(var o=0;o0&&(a=!0);for(var l=0;la){var o=a-r[t];return r[t]=a,o}}return 0},max:function(t,e,r,i){var a=i[e];if(n(a)){if(a=Number(a),!n(r[t]))return r[t]=a,a;if(r[t]c?t>o?t>1.1*i?i:t>1.1*a?a:o:t>s?s:t>l?l:c:Math.pow(10,Math.floor(Math.log(t)/Math.LN10))}function p(t,e,r,n,a,s){if(n&&t>o){var l=d(e,a,s),c=d(r,a,s),u=t===i?0:1;return l[u]!==c[u]}return Math.floor(r/t)-Math.floor(e/t)>.1}function d(t,e,r){var n=e.c2d(t,i,r).split("-");return""===n[0]&&(n.unshift(),n[0]="-"+n[0]),n}e.exports=function(t,e,r,n,a){var s,l,c=-1.1*e,f=-.1*e,p=t-f,d=r[0],g=r[1],m=Math.min(h(d+f,d+p,n,a),h(g+f,g+p,n,a)),v=Math.min(h(d+c,d+f,n,a),h(g+c,g+f,n,a));if(m>v&&vo){var y=s===i?1:6,x=s===i?"M12":"M1";return function(e,r){var o=n.c2d(e,i,a),s=o.indexOf("-",y);s>0&&(o=o.substr(0,s));var c=n.d2c(o,0,a);if(cu.size/1.9?u.size:u.size/Math.ceil(u.size/x);var A=u.start+(u.size-x)/2;b=A-x*Math.ceil((A-b)/x)}for(s=0;s=0&&w=0;n--)s(n);else if("increasing"===e){for(n=1;n=0;n--)t[n]+=t[n+1];"exclude"===r&&(t.push(0),t.shift())}}(d,x.direction,x.currentbin);var Z=Math.min(h.length,d.length),$=[],J=0,K=Z-1;for(r=0;r=J;r--)if(d[r]){K=r;break}for(r=J;r<=K;r++)if(n(h[r])&&n(d[r])){var Q={p:h[r],s:d[r],b:0};x.enabled||(Q.pts=z[r],H?Q.p0=Q.p1=z[r].length?A[z[r][0]]:h[r]:(Q.p0=U(S[r]),Q.p1=U(S[r+1],!0))),$.push(Q)}return 1===$.length&&($[0].width1=a.tickIncrement($[0].p,M.size,!1,y)-$[0].p),o($,e),i.isArrayOrTypedArray(e.selectedpoints)&&i.tagSelected($,e,Y),$}}},{"../../constants/numerical":661,"../../lib":684,"../../plots/cartesian/axes":732,"../bar/arrays_to_calcdata":826,"./average":945,"./bin_functions":947,"./bin_label_vals":948,"./clean_bins":950,"./norm_functions":955,"fast-isnumeric":214}],950:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../../lib").cleanDate,a=t("../../constants/numerical"),o=a.ONEDAY,s=a.BADNUM;e.exports=function(t,e,r){var a=e.type,l=r+"bins",c=t[l];c||(c=t[l]={});var u="date"===a?function(t){return t||0===t?i(t,s,c.calendar):null}:function(t){return n(t)?Number(t):null};c.start=u(c.start),c.end=u(c.end);var h="date"===a?o:1,f=c.size;if(n(f))c.size=f>0?Number(f):h;else if("string"!=typeof f)c.size=h;else{var p=f.charAt(0),d=f.substr(1);((d=n(d)?Number(d):0)<=0||"date"!==a||"M"!==p||d!==Math.round(d))&&(c.size=h)}var g="autobin"+r;"boolean"!=typeof t[g]&&(t[g]=t._fullInput[g]=t._input[g]=!((c.start||0===c.start)&&(c.end||0===c.end))),t[g]||(delete t["nbins"+r],delete t._fullInput["nbins"+r])}},{"../../constants/numerical":661,"../../lib":684,"fast-isnumeric":214}],951:[function(t,e,r){"use strict";var n=t("../../registry"),i=t("../../lib"),a=t("../../components/color"),o=t("./bin_defaults"),s=t("../bar/style_defaults"),l=t("./attributes");e.exports=function(t,e,r,c){function u(r,n){return i.coerce(t,e,l,r,n)}var h=u("x"),f=u("y");u("cumulative.enabled")&&(u("cumulative.direction"),u("cumulative.currentbin")),u("text");var p=u("orientation",f&&!h?"h":"v"),d="v"===p?"x":"y",g="v"===p?"y":"x",m=h&&f?Math.min(h.length&&f.length):(e[d]||[]).length;if(m){e._length=m,n.getComponentMethod("calendars","handleTraceDefaults")(t,e,["x","y"],c),e[g]&&u("histfunc"),o(t,e,u,[d]),s(t,e,u,r,c);var v=n.getComponentMethod("errorbars","supplyDefaults");v(t,e,a.defaultLine,{axis:"y"}),v(t,e,a.defaultLine,{axis:"x",inherit:"y"}),i.coerceSelectionMarkerOpacity(e,u)}else e.visible=!1}},{"../../components/color":558,"../../lib":684,"../../registry":817,"../bar/style_defaults":839,"./attributes":944,"./bin_defaults":946}],952:[function(t,e,r){"use strict";e.exports=function(t,e,r,n,i){if(t.x="xVal"in e?e.xVal:e.x,t.y="yVal"in e?e.yVal:e.y,e.xa&&(t.xaxis=e.xa),e.ya&&(t.yaxis=e.ya),!(r.cumulative||{}).enabled){var a,o=Array.isArray(i)?n[0].pts[i[0]][i[1]]:n[i].pts;if(t.pointNumbers=o,t.binNumber=t.pointNumber,delete t.pointNumber,delete t.pointIndex,r._indexToPoints){a=[];for(var s=0;sA&&m.splice(A,m.length-A),y.length>A&&y.splice(A,y.length-A),u(e,"x",m,g,_,k,x),u(e,"y",y,v,w,M,b);var T=[],S=[],E=[],C="string"==typeof e.xbins.size,L="string"==typeof e.ybins.size,z=[],P=[],I=C?z:e.xbins,O=L?P:e.ybins,D=0,R=[],B=[],F=e.histnorm,N=e.histfunc,j=-1!==F.indexOf("density"),V="max"===N||"min"===N?null:0,U=a.count,q=o[F],H=!1,G=[],W=[],Y="z"in e?e.z:"marker"in e&&Array.isArray(e.marker.color)?e.marker.color:"";Y&&"count"!==N&&(H="avg"===N,U=a[N]);var X=e.xbins,Z=_(X.start),$=_(X.end)+(Z-i.tickIncrement(Z,X.size,!1,x))/1e6;for(r=Z;r<$;r=i.tickIncrement(r,X.size,!1,x))S.push(V),z.push(r),H&&E.push(0);z.push(r);var J=S.length,K=_(e.xbins.start),Q=(r-K)/J,tt=k(K+Q/2);for(Z=w((X=e.ybins).start),$=w(X.end)+(Z-i.tickIncrement(Z,X.size,!1,b))/1e6,r=Z;r<$;r=i.tickIncrement(r,X.size,!1,b)){T.push(S.slice()),P.push(r);var et=new Array(J);for(l=0;l=0&&c=0&&d0)u=a(t.alphahull,h);else{var p=["x","y","z"].indexOf(t.delaunayaxis);u=i(h.map(function(t){return[t[(p+1)%3],t[(p+2)%3]]}))}var d={positions:h,cells:u,lightPosition:[t.lightposition.x,t.lightposition.y,t.lightposition.z],ambient:t.lighting.ambient,diffuse:t.lighting.diffuse,specular:t.lighting.specular,roughness:t.lighting.roughness,fresnel:t.lighting.fresnel,vertexNormalsEpsilon:t.lighting.vertexnormalsepsilon,faceNormalsEpsilon:t.lighting.facenormalsepsilon,opacity:t.opacity,contourEnable:t.contour.show,contourColor:l(t.contour.color).slice(0,3),contourWidth:t.contour.width,useFacetNormals:t.flatshading};t.intensity?(this.color="#fff",d.vertexIntensity=t.intensity,d.vertexIntensityBounds=[t.cmin,t.cmax],d.colormap=s(t.colorscale)):t.vertexcolor?(this.color=t.vertexcolor[0],d.vertexColors=f(t.vertexcolor)):t.facecolor?(this.color=t.facecolor[0],d.cellColors=f(t.facecolor)):(this.color=t.color,d.meshColor=l(t.color)),this.mesh.update(d)},h.dispose=function(){this.scene.glplot.remove(this.mesh),this.mesh.dispose()},e.exports=function(t,e){var r=t.glplot.gl,i=n({gl:r}),a=new u(t,i,e.uid);return i._trace=a,a.update(e),t.glplot.add(i),a}},{"../../lib/gl_format_color":680,"../../lib/str2rgbarray":707,"../../plots/gl3d/zip3":785,"alpha-shape":55,"convex-hull":117,"delaunay-triangulate":149,"gl-mesh3d":268}],968:[function(t,e,r){"use strict";var n=t("../../registry"),i=t("../../lib"),a=t("../../components/colorscale/defaults"),o=t("./attributes");e.exports=function(t,e,r,s){function l(r,n){return i.coerce(t,e,o,r,n)}function c(t){var e=t.map(function(t){var e=l(t);return e&&i.isArrayOrTypedArray(e)?e:null});return e.every(function(t){return t&&t.length===e[0].length})&&e}var u=c(["x","y","z"]),h=c(["i","j","k"]);u?(h&&h.forEach(function(t){for(var e=0;ed):p=_>y,d=_;var w=s(y,x,b,_);w.pos=v,w.yc=(y+_)/2,w.i=m,w.dir=p?"increasing":"decreasing",f&&(w.tx=e.text[m]),g.push(w)}}return a.expand(n,u.concat(c),{padded:!0}),g.length&&(g[0].t={labels:{open:i(t,"open:")+" ",high:i(t,"high:")+" ",low:i(t,"low:")+" ",close:i(t,"close:")+" "}}),g}e.exports={calc:function(t,e){var r=a.getFromId(t,e.xaxis),i=a.getFromId(t,e.yaxis),o=function(t,e,r){var i=r._minDiff;if(!i){var a,o=t._fullData,s=[];for(i=1/0,a=0;a"),t.y0=t.y1=h.c2p(E.yc,!0),[t]}},{"../../components/color":558,"../../components/fx":600,"../../plots/cartesian/axes":732,"../scatter/fill_hover_text":1022}],974:[function(t,e,r){"use strict";e.exports={moduleType:"trace",name:"ohlc",basePlotModule:t("../../plots/cartesian"),categories:["cartesian","svg","showLegend"],meta:{},attributes:t("./attributes"),supplyDefaults:t("./defaults"),calc:t("./calc").calc,plot:t("./plot"),style:t("./style"),hoverPoints:t("./hover"),selectPoints:t("./select")}},{"../../plots/cartesian":743,"./attributes":970,"./calc":971,"./defaults":972,"./hover":973,"./plot":976,"./select":977,"./style":978}],975:[function(t,e,r){"use strict";var n=t("../../registry");e.exports=function(t,e,r,i){var a=r("x"),o=r("open"),s=r("high"),l=r("low"),c=r("close");if(n.getComponentMethod("calendars","handleTraceDefaults")(t,e,["x"],i),o&&s&&l&&c){var u=Math.min(o.length,s.length,l.length,c.length);return a&&(u=Math.min(u,a.length)),e._length=u,u}}},{"../../registry":817}],976:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../lib");e.exports=function(t,e,r,a){var o=e.xaxis,s=e.yaxis,l=a.selectAll("g.trace").data(r,function(t){return t[0].trace.uid});l.enter().append("g").attr("class","trace ohlc"),l.exit().remove(),l.order(),l.each(function(t){var r=t[0],a=r.t,l=r.trace,c=n.select(this);if(e.isRangePlot||(r.node3=c),!0!==l.visible||a.empty)c.remove();else{var u=a.tickLen,h=c.selectAll("path").data(i.identity);h.enter().append("path"),h.exit().remove(),h.attr("d",function(t){var e=o.c2p(t.pos,!0),r=o.c2p(t.pos-u,!0),n=o.c2p(t.pos+u,!0);return"M"+r+","+s.c2p(t.o,!0)+"H"+e+"M"+e+","+s.c2p(t.h,!0)+"V"+s.c2p(t.l,!0)+"M"+n+","+s.c2p(t.c,!0)+"H"+e})}})}},{"../../lib":684,d3:147}],977:[function(t,e,r){"use strict";e.exports=function(t,e){var r,n=t.cd,i=t.xaxis,a=t.yaxis,o=[],s=n[0].t.bPos||0;if(!1===e)for(r=0;r=0;a--){var o=t[a];if(e>h(n,o))return c(n,i);if(e>o||a===t.length-1)return c(o,n);i=n,n=o}}function d(t,e){for(var r=0;r=e[r][0]&&t<=e[r][1])return!0;return!1}function g(t){t.attr("x",-n.bar.captureWidth/2).attr("width",n.bar.captureWidth)}function m(t){t.attr("visibility","visible").style("visibility","visible").attr("fill","yellow").attr("opacity",0)}function v(t){if(!t.brush.filterSpecified)return"0,"+t.height;for(var e,r,n,i=y(t.brush.filter.getConsolidated(),t.height),a=[0],o=i.length?i[0][0]:null,s=0;se){f=r;break}}if(a=u,isNaN(a)&&(a=isNaN(h)||isNaN(f)?isNaN(h)?f:h:e-c[h][1]t[1]+r||e=.9*t[1]+.1*t[0]?"n":e<=.9*t[0]+.1*t[1]?"s":"ns"}(d,e);g&&(o.interval=l[a],o.intervalPix=d,o.region=g)}}if(t.ordinal&&!o.region){var m=t.unitTickvals,v=t.unitToPaddedPx.invert(e);for(r=0;r=x[0]&&v<=x[1]){o.clickableOrdinalRange=x;break}}}return o}function k(t){t.on("mousemove",function(t){if(i.event.preventDefault(),!t.parent.inBrushDrag){var e=w(t,t.height-i.mouse(this)[1]-2*n.verticalPadding),r="crosshair";e.clickableOrdinalRange?r="pointer":e.region&&(r=e.region+"-resize"),i.select(document.body).style("cursor",r)}}).on("mouseleave",function(t){t.parent.inBrushDrag||x()}).call(i.behavior.drag().on("dragstart",function(t){i.event.sourceEvent.stopPropagation();var e=t.height-i.mouse(this)[1]-2*n.verticalPadding,r=t.unitToPaddedPx.invert(e),a=t.brush,o=w(t,e),s=o.interval,l=a.svgBrush;if(l.wasDragged=!1,l.grabbingBar="ns"===o.region,l.grabbingBar){var c=s.map(t.unitToPaddedPx);l.grabPoint=e-c[0]-n.verticalPadding,l.barLength=c[1]-c[0]}l.clickableOrdinalRange=o.clickableOrdinalRange,l.stayingIntervals=t.multiselect&&a.filterSpecified?a.filter.getConsolidated():[],s&&(l.stayingIntervals=l.stayingIntervals.filter(function(t){return t[0]!==s[0]&&t[1]!==s[1]})),l.startExtent=o.region?s["s"===o.region?1:0]:r,t.parent.inBrushDrag=!0,l.brushStartCallback()}).on("drag",function(t){i.event.sourceEvent.stopPropagation();var e=t.height-i.mouse(this)[1]-2*n.verticalPadding,r=t.brush.svgBrush;r.wasDragged=!0,r.grabbingBar?r.newExtent=[e-r.grabPoint,e+r.barLength-r.grabPoint].map(t.unitToPaddedPx.invert):r.newExtent=[r.startExtent,t.unitToPaddedPx.invert(e)].sort(s);var a=Math.max(0,-r.newExtent[0]),o=Math.max(0,r.newExtent[1]-1);r.newExtent[0]+=a,r.newExtent[1]-=o,r.grabbingBar&&(r.newExtent[1]+=a,r.newExtent[0]-=o),t.brush.filterSpecified=!0,r.extent=r.stayingIntervals.concat([r.newExtent]),r.brushCallback(t),_(this.parentNode)}).on("dragend",function(t){i.event.sourceEvent.stopPropagation();var e=t.brush,r=e.filter,n=e.svgBrush,a=n.grabbingBar;if(n.grabbingBar=!1,n.grabLocation=void 0,t.parent.inBrushDrag=!1,x(),!n.wasDragged)return n.wasDragged=void 0,n.clickableOrdinalRange?e.filterSpecified&&t.multiselect?n.extent.push(n.clickableOrdinalRange):(n.extent=[n.clickableOrdinalRange],e.filterSpecified=!0):a?(n.extent=n.stayingIntervals,0===n.extent.length&&A(e)):A(e),n.brushCallback(t),_(this.parentNode),void n.brushEndCallback(e.filterSpecified?r.getConsolidated():[]);var o=function(){r.set(r.getConsolidated())};if(t.ordinal){var s=t.unitTickvals;s[s.length-1]n.newExtent[0];n.extent=n.stayingIntervals.concat(l?[n.newExtent]:[]),n.extent.length||A(e),n.brushCallback(t),l?_(this.parentNode,o):(o(),_(this.parentNode))}else o();n.brushEndCallback(e.filterSpecified?r.getConsolidated():[])}))}function M(t,e){return t[0]-e[0]}function A(t){t.filterSpecified=!1,t.svgBrush.extent=[[0,1]]}function T(t){for(var e,r=t.slice(),n=[],i=r.shift();i;){for(e=i.slice();(i=r.shift())&&i[0]<=e[1];)e[1]=Math.max(e[1],i[1]);n.push(e)}return n}e.exports={makeBrush:function(t,e,r,n,i,a){var o,l=function(){var t,e,r=[];return{set:function(n){r=n.map(function(t){return t.slice().sort(s)}).sort(M),t=T(r),e=r.reduce(function(t,e){return[Math.min(t[0],e[0]),Math.max(t[1],e[1])]},[1/0,-1/0])},get:function(){return r.slice()},getConsolidated:function(){return t},getBounds:function(){return e}}}();return l.set(r),{filter:l,filterSpecified:e,svgBrush:{extent:[],brushStartCallback:n,brushCallback:(o=i,function(t){var e=t.brush,r=function(t){return t.svgBrush.extent.map(function(t){return t.slice()})}(e).slice();e.filter.set(r),o()}),brushEndCallback:a}}},ensureAxisBrush:function(t){var e=t.selectAll("."+n.cn.axisBrush).data(o,a);e.enter().append("g").classed(n.cn.axisBrush,!0),function(t){var e=t.selectAll(".background").data(o);e.enter().append("rect").classed("background",!0).call(g).call(m).style("pointer-events","auto").attr("transform","translate(0 "+n.verticalPadding+")"),e.call(k).attr("height",function(t){return t.height-n.verticalPadding});var r=t.selectAll(".highlight-shadow").data(o);r.enter().append("line").classed("highlight-shadow",!0).attr("x",-n.bar.width/2).attr("stroke-width",n.bar.width+n.bar.strokeWidth).attr("stroke",n.bar.strokeColor).attr("opacity",n.bar.strokeOpacity).attr("stroke-linecap","butt"),r.attr("y1",function(t){return t.height}).call(b);var i=t.selectAll(".highlight").data(o);i.enter().append("line").classed("highlight",!0).attr("x",-n.bar.width/2).attr("stroke-width",n.bar.width-n.bar.strokeWidth).attr("stroke",n.bar.fillColor).attr("opacity",n.bar.fillOpacity).attr("stroke-linecap","butt"),i.attr("y1",function(t){return t.height}).call(b)}(e)},cleanRanges:function(t,e){if(Array.isArray(t[0])?(t=t.map(function(t){return t.sort(s)}),t=e.multiselect?T(t.sort(M)):[t[0]]):t=[t.sort(s)],e.tickvals){var r=e.tickvals.slice().sort(s);if(!(t=t.map(function(t){var e=[f(r,t[0],[]),p(r,t[1],[])];if(e[1]>e[0])return e}).filter(function(t){return t})).length)return}return t.length>1?t:t[0]}}},{"../../lib":684,"../../lib/gup":681,"./constants":983,d3:147}],981:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../plots/get_data").getModuleCalcData,a=t("./plot"),o=t("../../constants/xmlns_namespaces");r.name="parcoords",r.plot=function(t){var e=i(t.calcdata,"parcoords")[0];e.length&&a(t,e)},r.clean=function(t,e,r,n){var i=n._has&&n._has("parcoords"),a=e._has&&e._has("parcoords");i&&!a&&(n._paperdiv.selectAll(".parcoords").remove(),n._glimages.selectAll("*").remove())},r.toSVG=function(t){var e=t._fullLayout._glimages,r=n.select(t).selectAll(".svg-container");r.filter(function(t,e){return e===r.size()-1}).selectAll(".gl-canvas-context, .gl-canvas-focus").each(function(){var t=this.toDataURL("image/png");e.append("svg:image").attr({xmlns:o.svg,"xlink:href":t,preserveAspectRatio:"none",x:0,y:0,width:this.width,height:this.height})}),window.setTimeout(function(){n.selectAll("#filterBarPattern").attr("id","filterBarPattern")},60)}},{"../../constants/xmlns_namespaces":663,"../../plots/get_data":768,"./plot":989,d3:147}],982:[function(t,e,r){"use strict";var n=t("../../components/colorscale/has_colorscale"),i=t("../../components/colorscale/calc"),a=t("../../lib"),o=t("../../lib/gup").wrap;e.exports=function(t,e){var r=!!e.line.colorscale&&a.isArrayOrTypedArray(e.line.color),s=r?e.line.color:function(t){for(var e=new Array(t),r=0;ru&&(n.log("parcoords traces support up to "+u+" dimensions at the moment"),d.splice(u));var g=s(t,e,{name:"dimensions",handleItemDefaults:f}),m=function(t,e,r,o,s){var l=s("line.color",r);if(i(t,"line")&&n.isArrayOrTypedArray(l)){if(l.length)return s("line.colorscale"),a(t,e,o,s,{prefix:"line.",cLetter:"c"}),l.length;e.line.color=r}return 1/0}(t,e,r,c,p);o(e,c,p),Array.isArray(g)&&g.length||(e.visible=!1),h(e,g,"values",m);var v={family:c.font.family,size:Math.round(c.font.size/1.2),color:c.font.color};n.coerceFont(p,"labelfont",v),n.coerceFont(p,"tickfont",v),n.coerceFont(p,"rangefont",v)}},{"../../components/colorscale/defaults":568,"../../components/colorscale/has_colorscale":572,"../../lib":684,"../../plots/array_container_defaults":728,"../../plots/domain":757,"./attributes":979,"./axisbrush":980,"./constants":983,"./merge_length":987}],985:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.calc=t("./calc"),n.plot=t("./plot"),n.colorbar={container:"line",min:"cmin",max:"cmax"},n.moduleType="trace",n.name="parcoords",n.basePlotModule=t("./base_plot"),n.categories=["gl","regl","noOpacity"],n.meta={},e.exports=n},{"./attributes":979,"./base_plot":981,"./calc":982,"./defaults":984,"./plot":989}],986:[function(t,e,r){"use strict";var n=t("glslify"),i=n(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec4 p0, p1, p2, p3,\n p4, p5, p6, p7,\n p8, p9, pa, pb,\n pc, pd, pe;\n\nattribute vec4 pf;\n\nuniform mat4 dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D,\n loA, hiA, loB, hiB, loC, hiC, loD, hiD;\n\nuniform vec2 resolution,\n viewBoxPosition,\n viewBoxSize;\n\nuniform sampler2D palette;\nuniform sampler2D mask;\nuniform float maskHeight;\n\nuniform vec2 colorClamp;\n\nvarying vec4 fragColor;\n\nvec4 unit_1 = vec4(1, 1, 1, 1);\n\nfloat val(mat4 p, mat4 v) {\n return dot(matrixCompMult(p, v) * unit_1, unit_1);\n}\n\nfloat axisY(\n float x,\n mat4 d[4],\n mat4 dim1A, mat4 dim2A, mat4 dim1B, mat4 dim2B, mat4 dim1C, mat4 dim2C, mat4 dim1D, mat4 dim2D\n ) {\n\n float y1 = val(d[0], dim1A) + val(d[1], dim1B) + val(d[2], dim1C) + val(d[3], dim1D);\n float y2 = val(d[0], dim2A) + val(d[1], dim2B) + val(d[2], dim2C) + val(d[3], dim2D);\n return y1 * (1.0 - x) + y2 * x;\n}\n\nconst int bitsPerByte = 8;\n\nint mod2(int a) {\n return a - 2 * (a / 2);\n}\n\nint mod8(int a) {\n return a - 8 * (a / 8);\n}\n\nvec4 zero = vec4(0, 0, 0, 0);\nvec4 unit_0 = vec4(1, 1, 1, 1);\nvec2 xyProjection = vec2(1, 1);\n\nmat4 mclamp(mat4 m, mat4 lo, mat4 hi) {\n return mat4(clamp(m[0], lo[0], hi[0]),\n clamp(m[1], lo[1], hi[1]),\n clamp(m[2], lo[2], hi[2]),\n clamp(m[3], lo[3], hi[3]));\n}\n\nbool mshow(mat4 p, mat4 lo, mat4 hi) {\n return mclamp(p, lo, hi) == p;\n}\n\nbool withinBoundingBox(\n mat4 d[4],\n mat4 loA, mat4 hiA, mat4 loB, mat4 hiB, mat4 loC, mat4 hiC, mat4 loD, mat4 hiD\n ) {\n\n return mshow(d[0], loA, hiA) &&\n mshow(d[1], loB, hiB) &&\n mshow(d[2], loC, hiC) &&\n mshow(d[3], loD, hiD);\n}\n\nbool withinRasterMask(mat4 d[4], sampler2D mask, float height) {\n bool result = true;\n int bitInByteStepper;\n float valY, valueY, scaleX;\n int hit, bitmask, valX;\n for(int i = 0; i < 4; i++) {\n for(int j = 0; j < 4; j++) {\n for(int k = 0; k < 4; k++) {\n bitInByteStepper = mod8(j * 4 + k);\n valX = i * 2 + j / 2;\n valY = d[i][j][k];\n valueY = valY * (height - 1.0) + 0.5;\n scaleX = (float(valX) + 0.5) / 8.0;\n hit = int(texture2D(mask, vec2(scaleX, (valueY + 0.5) / height))[3] * 255.0) / int(pow(2.0, float(bitInByteStepper)));\n result = result && mod2(hit) == 1;\n }\n }\n }\n return result;\n}\n\nvec4 position(\n float depth,\n vec2 resolution, vec2 viewBoxPosition, vec2 viewBoxSize,\n mat4 dims[4],\n float signum,\n mat4 dim1A, mat4 dim2A, mat4 dim1B, mat4 dim2B, mat4 dim1C, mat4 dim2C, mat4 dim1D, mat4 dim2D,\n mat4 loA, mat4 hiA, mat4 loB, mat4 hiB, mat4 loC, mat4 hiC, mat4 loD, mat4 hiD,\n sampler2D mask, float maskHeight\n ) {\n\n float x = 0.5 * signum + 0.5;\n float y = axisY(x, dims, dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D);\n\n float show = float(\n withinBoundingBox(dims, loA, hiA, loB, hiB, loC, hiC, loD, hiD)\n && withinRasterMask(dims, mask, maskHeight)\n );\n\n vec2 viewBoxXY = viewBoxPosition + viewBoxSize * vec2(x, y);\n float depthOrHide = depth + 2.0 * (1.0 - show);\n\n return vec4(\n xyProjection * (2.0 * viewBoxXY / resolution - 1.0),\n depthOrHide,\n 1.0\n );\n}\n\nvoid main() {\n\n float prominence = abs(pf[3]);\n\n mat4 p[4];\n p[0] = mat4(p0, p1, p2, p3);\n p[1] = mat4(p4, p5, p6, p7);\n p[2] = mat4(p8, p9, pa, pb);\n p[3] = mat4(pc, pd, pe, abs(pf));\n\n gl_Position = position(\n 1.0 - prominence,\n resolution, viewBoxPosition, viewBoxSize,\n p,\n sign(pf[3]),\n dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D,\n loA, hiA, loB, hiB, loC, hiC, loD, hiD,\n mask, maskHeight\n );\n\n float clampedColorIndex = clamp((prominence - colorClamp[0]) / (colorClamp[1] - colorClamp[0]), 0.0, 1.0);\n fragColor = texture2D(palette, vec2((clampedColorIndex * 255.0 + 0.5) / 256.0, 0.5));\n}\n"]),a=n(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec4 p0, p1, p2, p3,\n p4, p5, p6, p7,\n p8, p9, pa, pb,\n pc, pd, pe;\n\nattribute vec4 pf;\n\nuniform mat4 dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D;\n\nuniform vec2 resolution,\n viewBoxPosition,\n viewBoxSize;\n\nuniform sampler2D palette;\n\nuniform vec2 colorClamp;\n\nvarying vec4 fragColor;\n\nvec2 xyProjection = vec2(1, 1);\n\nvec4 unit = vec4(1, 1, 1, 1);\n\nfloat val(mat4 p, mat4 v) {\n return dot(matrixCompMult(p, v) * unit, unit);\n}\n\nfloat axisY(\n float x,\n mat4 d[4],\n mat4 dim1A, mat4 dim2A, mat4 dim1B, mat4 dim2B, mat4 dim1C, mat4 dim2C, mat4 dim1D, mat4 dim2D\n ) {\n\n float y1 = val(d[0], dim1A) + val(d[1], dim1B) + val(d[2], dim1C) + val(d[3], dim1D);\n float y2 = val(d[0], dim2A) + val(d[1], dim2B) + val(d[2], dim2C) + val(d[3], dim2D);\n return y1 * (1.0 - x) + y2 * x;\n}\n\nvec4 position(\n float depth,\n vec2 resolution, vec2 viewBoxPosition, vec2 viewBoxSize,\n mat4 dims[4],\n float signum,\n mat4 dim1A, mat4 dim2A, mat4 dim1B, mat4 dim2B, mat4 dim1C, mat4 dim2C, mat4 dim1D, mat4 dim2D\n ) {\n\n float x = 0.5 * signum + 0.5;\n float y = axisY(x, dims, dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D);\n\n vec2 viewBoxXY = viewBoxPosition + viewBoxSize * vec2(x, y);\n\n return vec4(\n xyProjection * (2.0 * viewBoxXY / resolution - 1.0),\n depth,\n 1.0\n );\n}\n\nvoid main() {\n\n float prominence = abs(pf[3]);\n\n mat4 p[4];\n p[0] = mat4(p0, p1, p2, p3);\n p[1] = mat4(p4, p5, p6, p7);\n p[2] = mat4(p8, p9, pa, pb);\n p[3] = mat4(pc, pd, pe, abs(pf));\n\n gl_Position = position(\n 1.0 - prominence,\n resolution, viewBoxPosition, viewBoxSize,\n p,\n sign(pf[3]),\n dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D\n );\n\n float clampedColorIndex = clamp((prominence - colorClamp[0]) / (colorClamp[1] - colorClamp[0]), 0.0, 1.0);\n fragColor = texture2D(palette, vec2((clampedColorIndex * 255.0 + 0.5) / 256.0, 0.5));\n}\n"]),o=n(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec4 p0, p1, p2, p3,\n p4, p5, p6, p7,\n p8, p9, pa, pb,\n pc, pd, pe;\n\nattribute vec4 pf;\n\nuniform mat4 dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D,\n loA, hiA, loB, hiB, loC, hiC, loD, hiD;\n\nuniform vec2 resolution,\n viewBoxPosition,\n viewBoxSize;\n\nuniform sampler2D mask;\nuniform float maskHeight;\n\nuniform vec2 colorClamp;\n\nvarying vec4 fragColor;\n\nvec4 unit_1 = vec4(1, 1, 1, 1);\n\nfloat val(mat4 p, mat4 v) {\n return dot(matrixCompMult(p, v) * unit_1, unit_1);\n}\n\nfloat axisY(\n float x,\n mat4 d[4],\n mat4 dim1A, mat4 dim2A, mat4 dim1B, mat4 dim2B, mat4 dim1C, mat4 dim2C, mat4 dim1D, mat4 dim2D\n ) {\n\n float y1 = val(d[0], dim1A) + val(d[1], dim1B) + val(d[2], dim1C) + val(d[3], dim1D);\n float y2 = val(d[0], dim2A) + val(d[1], dim2B) + val(d[2], dim2C) + val(d[3], dim2D);\n return y1 * (1.0 - x) + y2 * x;\n}\n\nconst int bitsPerByte = 8;\n\nint mod2(int a) {\n return a - 2 * (a / 2);\n}\n\nint mod8(int a) {\n return a - 8 * (a / 8);\n}\n\nvec4 zero = vec4(0, 0, 0, 0);\nvec4 unit_0 = vec4(1, 1, 1, 1);\nvec2 xyProjection = vec2(1, 1);\n\nmat4 mclamp(mat4 m, mat4 lo, mat4 hi) {\n return mat4(clamp(m[0], lo[0], hi[0]),\n clamp(m[1], lo[1], hi[1]),\n clamp(m[2], lo[2], hi[2]),\n clamp(m[3], lo[3], hi[3]));\n}\n\nbool mshow(mat4 p, mat4 lo, mat4 hi) {\n return mclamp(p, lo, hi) == p;\n}\n\nbool withinBoundingBox(\n mat4 d[4],\n mat4 loA, mat4 hiA, mat4 loB, mat4 hiB, mat4 loC, mat4 hiC, mat4 loD, mat4 hiD\n ) {\n\n return mshow(d[0], loA, hiA) &&\n mshow(d[1], loB, hiB) &&\n mshow(d[2], loC, hiC) &&\n mshow(d[3], loD, hiD);\n}\n\nbool withinRasterMask(mat4 d[4], sampler2D mask, float height) {\n bool result = true;\n int bitInByteStepper;\n float valY, valueY, scaleX;\n int hit, bitmask, valX;\n for(int i = 0; i < 4; i++) {\n for(int j = 0; j < 4; j++) {\n for(int k = 0; k < 4; k++) {\n bitInByteStepper = mod8(j * 4 + k);\n valX = i * 2 + j / 2;\n valY = d[i][j][k];\n valueY = valY * (height - 1.0) + 0.5;\n scaleX = (float(valX) + 0.5) / 8.0;\n hit = int(texture2D(mask, vec2(scaleX, (valueY + 0.5) / height))[3] * 255.0) / int(pow(2.0, float(bitInByteStepper)));\n result = result && mod2(hit) == 1;\n }\n }\n }\n return result;\n}\n\nvec4 position(\n float depth,\n vec2 resolution, vec2 viewBoxPosition, vec2 viewBoxSize,\n mat4 dims[4],\n float signum,\n mat4 dim1A, mat4 dim2A, mat4 dim1B, mat4 dim2B, mat4 dim1C, mat4 dim2C, mat4 dim1D, mat4 dim2D,\n mat4 loA, mat4 hiA, mat4 loB, mat4 hiB, mat4 loC, mat4 hiC, mat4 loD, mat4 hiD,\n sampler2D mask, float maskHeight\n ) {\n\n float x = 0.5 * signum + 0.5;\n float y = axisY(x, dims, dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D);\n\n float show = float(\n withinBoundingBox(dims, loA, hiA, loB, hiB, loC, hiC, loD, hiD)\n && withinRasterMask(dims, mask, maskHeight)\n );\n\n vec2 viewBoxXY = viewBoxPosition + viewBoxSize * vec2(x, y);\n float depthOrHide = depth + 2.0 * (1.0 - show);\n\n return vec4(\n xyProjection * (2.0 * viewBoxXY / resolution - 1.0),\n depthOrHide,\n 1.0\n );\n}\n\nvoid main() {\n\n float prominence = abs(pf[3]);\n\n mat4 p[4];\n p[0] = mat4(p0, p1, p2, p3);\n p[1] = mat4(p4, p5, p6, p7);\n p[2] = mat4(p8, p9, pa, pb);\n p[3] = mat4(pc, pd, pe, abs(pf));\n\n gl_Position = position(\n 1.0 - prominence,\n resolution, viewBoxPosition, viewBoxSize,\n p,\n sign(pf[3]),\n dim1A, dim2A, dim1B, dim2B, dim1C, dim2C, dim1D, dim2D,\n loA, hiA, loB, hiB, loC, hiC, loD, hiD,\n mask, maskHeight\n );\n\n fragColor = vec4(pf.rgb, 1.0);\n}\n"]),s=n(["precision lowp float;\n#define GLSLIFY 1\n\nvarying vec4 fragColor;\n\nvoid main() {\n gl_FragColor = fragColor;\n}\n"]),l=t("../../lib"),c=1e-6,u=1e-7,h=2048,f=64,p=2,d=4,g=8,m=f/g,v=[119,119,119],y=new Uint8Array(4),x=new Uint8Array(4),b={shape:[256,1],format:"rgba",type:"uint8",mag:"nearest",min:"nearest"};function _(t,e,r,n,i){var a=t._gl;a.enable(a.SCISSOR_TEST),a.scissor(e,r,n,i),t.clear({color:[0,0,0,0],depth:1})}function w(t,e,r,n,i,a){var o=a.key;r.drawCompleted||(!function(t){t.read({x:0,y:0,width:1,height:1,data:y})}(t),r.drawCompleted=!0),function s(l){var c;c=Math.min(n,i-l*n),a.offset=p*l*n,a.count=p*c,0===l&&(window.cancelAnimationFrame(r.currentRafs[o]),delete r.currentRafs[o],_(t,a.scissorX,a.scissorY,a.scissorWidth,a.viewBoxSize[1])),r.clearOnly||(e(a),l*n+c>>8*e)%256/255}function M(t,e,r){var n,i,a,o=[];for(i=0;i=f-4?k(o,f-2-s):.5);return a}(d,p,i);!function(t,e,r){for(var n=0;n<16;n++)t["p"+n.toString(16)](M(e,r,n))}(C,d,o),L=S.texture(l.extendFlat({data:function(t,e,r){for(var n=[],i=0;i<256;i++){var a=t(i/255);n.push((e?v:a).concat(r))}return n}(r.unitToColor,A,Math.round(255*(A?a:1)))},b))}var I=[0,1];var O=[];function D(t,e,n,i,a,o,s,c,u,h,f){var p,d,g,m,v=[t,e],y=[0,1].map(function(){return[0,1,2,3].map(function(){return new Float32Array(16)})});for(p=0;p<2;p++)for(m=v[p],d=0;d<4;d++)for(g=0;g<16;g++)y[p][d][g]=g+16*d===m?1:0;var x=r.lines.canvasOverdrag,b=r.domain,_=r.canvasWidth,w=r.canvasHeight;return l.extendFlat({key:s,resolution:[_,w],viewBoxPosition:[n+x,i],viewBoxSize:[a,o],i:t,ii:e,dim1A:y[0][0],dim1B:y[0][1],dim1C:y[0][2],dim1D:y[0][3],dim2A:y[1][0],dim2B:y[1][1],dim2C:y[1][2],dim2D:y[1][3],colorClamp:I,scissorX:(c===u?0:n+x)+(r.pad.l-x)+r.layoutWidth*b.x[0],scissorWidth:(c===h?_-n+x:a+.5)+(c===u?n+x:0),scissorY:i+r.pad.b+r.layoutHeight*b.y[0],scissorHeight:o,viewportX:r.pad.l-x+r.layoutWidth*b.x[0],viewportY:r.pad.b+r.layoutHeight*b.y[0],viewportWidth:_,viewportHeight:w},f)}return{setColorDomain:function(t){I[0]=t[0],I[1]=t[1]},render:function(t,e,n){var i,a,o,s=t.length,l=1/0,c=-1/0;for(i=0;ic&&(c=t[i].dim2.canvasX,o=i),t[i].dim1.canvasXn._length&&(M=M.slice(0,n._length));var A,T=n.tickvals;function S(t,e){return{val:t,text:A[e]}}function E(t,e){return t.val-e.val}if(Array.isArray(T)&&T.length){A=n.ticktext,Array.isArray(A)&&A.length?A.length>T.length?A=A.slice(0,T.length):T.length>A.length&&(T=T.slice(0,A.length)):A=T.map(o.format(n.tickformat));for(var C=1;C=r||s>=n)return;var l=t.lineLayer.readPixel(a,n-1-s),c=0!==l[3],u=c?l[2]+256*(l[1]+256*l[0]):null,h={x:a,y:s,clientX:e.clientX,clientY:e.clientY,dataIndex:t.model.key,curveNumber:u};u!==M&&(c?d.hover(h):d.unhover&&d.unhover(h),M=u)}}),k.style("opacity",function(t){return t.pick?.01:1}),e.style("background","rgba(255, 255, 255, 0)");var A=e.selectAll("."+i.cn.parcoords).data(w,c);A.exit().remove(),A.enter().append("g").classed(i.cn.parcoords,!0).style("shape-rendering","crispEdges").style("pointer-events","none"),A.attr("transform",function(t){return"translate("+t.model.translateX+","+t.model.translateY+")"});var T=A.selectAll("."+i.cn.parcoordsControlView).data(u,c);T.enter().append("g").classed(i.cn.parcoordsControlView,!0),T.attr("transform",function(t){return"translate("+t.model.pad.l+","+t.model.pad.t+")"});var S=T.selectAll("."+i.cn.yAxis).data(function(t){return t.dimensions},c);function E(t,e){for(var r=e.panels||(e.panels=[]),n=t.data(),i=n.length-1,a=0;aline").attr("fill","none").attr("stroke","black").attr("stroke-opacity",.25).attr("stroke-width","1px"),L.selectAll("text").style("text-shadow","1px 1px 1px #fff, -1px -1px 1px #fff, 1px -1px 1px #fff, -1px 1px 1px #fff").style("cursor","default").style("user-select","none");var z=C.selectAll("."+i.cn.axisHeading).data(u,c);z.enter().append("g").classed(i.cn.axisHeading,!0);var P=z.selectAll("."+i.cn.axisTitle).data(u,c);P.enter().append("text").classed(i.cn.axisTitle,!0).attr("text-anchor","middle").style("cursor","ew-resize").style("user-select","none").style("pointer-events","auto"),P.attr("transform","translate(0,"+-i.axisTitleOffset+")").text(function(t){return t.label}).each(function(t){s.font(o.select(this),t.model.labelFont)});var I=C.selectAll("."+i.cn.axisExtent).data(u,c);I.enter().append("g").classed(i.cn.axisExtent,!0);var O=I.selectAll("."+i.cn.axisExtentTop).data(u,c);O.enter().append("g").classed(i.cn.axisExtentTop,!0),O.attr("transform","translate(0,"+-i.axisExtentOffset+")");var D=O.selectAll("."+i.cn.axisExtentTopText).data(u,c);function R(t,e){if(t.ordinal)return"";var r=t.domainScale.domain();return o.format(t.tickFormat)(r[e?r.length-1:0])}D.enter().append("text").classed(i.cn.axisExtentTopText,!0).call(y),D.text(function(t){return R(t,!0)}).each(function(t){s.font(o.select(this),t.model.rangeFont)});var B=I.selectAll("."+i.cn.axisExtentBottom).data(u,c);B.enter().append("g").classed(i.cn.axisExtentBottom,!0),B.attr("transform",function(t){return"translate(0,"+(t.model.height+i.axisExtentOffset)+")"});var F=B.selectAll("."+i.cn.axisExtentBottomText).data(u,c);F.enter().append("text").classed(i.cn.axisExtentBottomText,!0).attr("dy","0.75em").call(y),F.text(function(t){return R(t)}).each(function(t){s.font(o.select(this),t.model.rangeFont)}),f.ensureAxisBrush(C)}},{"../../components/drawing":583,"../../lib":684,"../../lib/gup":681,"./axisbrush":980,"./constants":983,"./lines":986,d3:147}],989:[function(t,e,r){"use strict";var n=t("./parcoords"),i=t("../../lib/prepare_regl");e.exports=function(t,e){var r=t._fullLayout,a=r._toppaper,o=r._paperdiv,s=r._glcontainer;if(i(t)){var l={},c={},u=r._size;e.forEach(function(e,r){l[r]=t.data[r].dimensions,c[r]=t.data[r].dimensions.slice()});n(o,a,s,e,{width:u.w,height:u.h,margin:{t:u.t,r:u.r,b:u.b,l:u.l}},{filterChanged:function(e,r,n){var i=c[e][r],a=n.map(function(t){return t.slice()});a.length?(1===a.length&&(a=a[0]),i.constraintrange=a,a=[a]):(delete i.constraintrange,a=null);var o={};o["dimensions["+r+"].constraintrange"]=a,t.emit("plotly_restyle",[o,[e]])},hover:function(e){t.emit("plotly_hover",e)},unhover:function(e){t.emit("plotly_unhover",e)},axesMoved:function(e,r){function n(t){return!("visible"in t)||t.visible}function i(t,e,r){var n=e.indexOf(r),i=t.indexOf(n);return-1===i&&(i+=e.length),i}var a=function(t){return function(e,n){return i(r,t,e)-i(r,t,n)}}(c[e].filter(n));l[e].sort(a),c[e].filter(function(t){return!n(t)}).sort(function(t){return c[e].indexOf(t)}).forEach(function(t){l[e].splice(l[e].indexOf(t),1),l[e].splice(c[e].indexOf(t),0,t)}),t.emit("plotly_restyle")}})}}},{"../../lib/prepare_regl":697,"./parcoords":988}],990:[function(t,e,r){"use strict";var n=t("../../components/color/attributes"),i=t("../../plots/font_attributes"),a=t("../../plots/attributes"),o=t("../../plots/domain").attributes,s=t("../../lib/extend").extendFlat,l=i({editType:"calc",colorEditType:"style"});e.exports={labels:{valType:"data_array",editType:"calc"},label0:{valType:"number",dflt:0,editType:"calc"},dlabel:{valType:"number",dflt:1,editType:"calc"},values:{valType:"data_array",editType:"calc"},marker:{colors:{valType:"data_array",editType:"calc"},line:{color:{valType:"color",dflt:n.defaultLine,arrayOk:!0,editType:"style"},width:{valType:"number",min:0,dflt:0,arrayOk:!0,editType:"style"},editType:"calc"},editType:"calc"},text:{valType:"data_array",editType:"calc"},hovertext:{valType:"string",dflt:"",arrayOk:!0,editType:"style"},scalegroup:{valType:"string",dflt:"",editType:"calc"},textinfo:{valType:"flaglist",flags:["label","text","value","percent"],extras:["none"],editType:"calc"},hoverinfo:s({},a.hoverinfo,{flags:["label","text","value","percent","name"]}),textposition:{valType:"enumerated",values:["inside","outside","auto","none"],dflt:"auto",arrayOk:!0,editType:"calc"},textfont:s({},l,{}),insidetextfont:s({},l,{}),outsidetextfont:s({},l,{}),domain:o({name:"pie",trace:!0,editType:"calc"}),hole:{valType:"number",min:0,max:1,dflt:0,editType:"calc"},sort:{valType:"boolean",dflt:!0,editType:"calc"},direction:{valType:"enumerated",values:["clockwise","counterclockwise"],dflt:"counterclockwise",editType:"calc"},rotation:{valType:"number",min:-360,max:360,dflt:0,editType:"calc"},pull:{valType:"number",min:0,max:1,dflt:0,arrayOk:!0,editType:"calc"}}},{"../../components/color/attributes":557,"../../lib/extend":673,"../../plots/attributes":729,"../../plots/domain":757,"../../plots/font_attributes":758}],991:[function(t,e,r){"use strict";var n=t("../../registry"),i=t("../../plots/get_data").getModuleCalcData;r.name="pie",r.plot=function(t){var e=n.getModule("pie"),r=i(t.calcdata,e)[0];r.length&&e.plot(t,r)},r.clean=function(t,e,r,n){var i=n._has&&n._has("pie"),a=e._has&&e._has("pie");i&&!a&&n._pielayer.selectAll("g.trace").remove()}},{"../../plots/get_data":768,"../../registry":817}],992:[function(t,e,r){"use strict";var n,i=t("fast-isnumeric"),a=t("../../lib").isArrayOrTypedArray,o=t("tinycolor2"),s=t("../../components/color"),l=t("./helpers");function c(t,e){if(!n){var r=s.defaults;n=u(r)}var i=e||n;return i[t%i.length]}function u(t){var e,r=t.slice();for(e=0;e")}}return y}},{"../../components/color":558,"../../lib":684,"./helpers":995,"fast-isnumeric":214,tinycolor2:499}],993:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("./attributes"),a=t("../../plots/domain").defaults;e.exports=function(t,e,r,o){function s(r,a){return n.coerce(t,e,i,r,a)}var l,c=n.coerceFont,u=s("values"),h=n.isArrayOrTypedArray(u),f=s("labels");if(Array.isArray(f)?(l=f.length,h&&(l=Math.min(l,u.length))):h&&(l=u.length,s("label0"),s("dlabel")),l){e._length=l,s("marker.line.width")&&s("marker.line.color"),s("marker.colors"),s("scalegroup");var p=s("text"),d=s("textinfo",Array.isArray(p)?"text+percent":"percent");if(s("hovertext"),d&&"none"!==d){var g=s("textposition"),m=Array.isArray(g)||"auto"===g,v=m||"inside"===g,y=m||"outside"===g;if(v||y){var x=c(s,"textfont",o.font);v&&c(s,"insidetextfont",x),y&&c(s,"outsidetextfont",x)}}a(e,o,s),s("hole"),s("sort"),s("direction"),s("rotation"),s("pull")}else e.visible=!1}},{"../../lib":684,"../../plots/domain":757,"./attributes":990}],994:[function(t,e,r){"use strict";var n=t("../../components/fx/helpers").appendArrayMultiPointValues;e.exports=function(t,e){var r={curveNumber:e.index,pointNumbers:t.pts,data:e._input,fullData:e,label:t.label,color:t.color,value:t.v,v:t.v};return 1===t.pts.length&&(r.pointNumber=r.i=t.pts[0]),n(r,e,t.pts),r}},{"../../components/fx/helpers":597}],995:[function(t,e,r){"use strict";var n=t("../../lib");r.formatPiePercent=function(t,e){var r=(100*t).toPrecision(3);return-1!==r.lastIndexOf(".")&&(r=r.replace(/[.]?0+$/,"")),n.numSeparate(r,e)+"%"},r.formatPieValue=function(t,e){var r=t.toPrecision(10);return-1!==r.lastIndexOf(".")&&(r=r.replace(/[.]?0+$/,"")),n.numSeparate(r,e)},r.getFirstFilled=function(t,e){if(Array.isArray(t))for(var r=0;r0?1:-1)/2,y:a/(1+r*r/(n*n)),outside:!0}}e.exports=function(t,e){var r=t._fullLayout;!function(t,e){var r,n,i,a,o,s,l,c,u,h=[];for(i=0;il&&(l=s.pull[a]);o.r=Math.min(r,n)/(2+2*l),o.cx=e.l+e.w*(s.domain.x[1]+s.domain.x[0])/2,o.cy=e.t+e.h*(2-s.domain.y[1]-s.domain.y[0])/2,s.scalegroup&&-1===h.indexOf(s.scalegroup)&&h.push(s.scalegroup)}for(a=0;ai.vTotal/2?1:0)}(e),p.each(function(){var p=n.select(this).selectAll("g.slice").data(e);p.enter().append("g").classed("slice",!0),p.exit().remove();var m=[[[],[]],[[],[]]],v=!1;p.each(function(e){if(e.hidden)n.select(this).selectAll("path,g").remove();else{e.pointNumber=e.i,e.curveNumber=g.index,m[e.pxmid[1]<0?0:1][e.pxmid[0]<0?0:1].push(e);var a=d.cx,p=d.cy,y=n.select(this),x=y.selectAll("path.surface").data([e]),b=!1,_=!1;if(x.enter().append("path").classed("surface",!0).style({"pointer-events":"all"}),y.select("path.textline").remove(),y.on("mouseover",function(){var o=t._fullLayout,s=t._fullData[g.index];if(!t._dragging&&!1!==o.hovermode){var l=s.hoverinfo;if(Array.isArray(l)&&(l=i.castHoverinfo({hoverinfo:[c.castOption(l,e.pts)],_module:g._module},o,0)),"all"===l&&(l="label+text+value+percent+name"),"none"!==l&&"skip"!==l&&l){var f=h(e,d),m=a+e.pxmid[0]*(1-f),v=p+e.pxmid[1]*(1-f),y=r.separators,x=[];if(-1!==l.indexOf("label")&&x.push(e.label),-1!==l.indexOf("text")){var w=c.castOption(s.hovertext||s.text,e.pts);w&&x.push(w)}-1!==l.indexOf("value")&&x.push(c.formatPieValue(e.v,y)),-1!==l.indexOf("percent")&&x.push(c.formatPiePercent(e.v/d.vTotal,y));var k=g.hoverlabel,M=k.font;i.loneHover({x0:m-f*d.r,x1:m+f*d.r,y:v,text:x.join("
"),name:-1!==l.indexOf("name")?s.name:void 0,idealAlign:e.pxmid[0]<0?"left":"right",color:c.castOption(k.bgcolor,e.pts)||e.color,borderColor:c.castOption(k.bordercolor,e.pts),fontFamily:c.castOption(M.family,e.pts),fontSize:c.castOption(M.size,e.pts),fontColor:c.castOption(M.color,e.pts)},{container:o._hoverlayer.node(),outerContainer:o._paper.node(),gd:t}),b=!0}t.emit("plotly_hover",{points:[u(e,s)],event:n.event}),_=!0}}).on("mouseout",function(r){var a=t._fullLayout,o=t._fullData[g.index];_&&(r.originalEvent=n.event,t.emit("plotly_unhover",{points:[u(e,o)],event:n.event}),_=!1),b&&(i.loneUnhover(a._hoverlayer.node()),b=!1)}).on("click",function(){var r=t._fullLayout,a=t._fullData[g.index];t._dragging||!1===r.hovermode||(t._hoverdata=[u(e,a)],i.click(t,n.event))}),g.pull){var w=+c.castOption(g.pull,e.pts)||0;w>0&&(a+=w*e.pxmid[0],p+=w*e.pxmid[1])}e.cxFinal=a,e.cyFinal=p;var k=g.hole;if(e.v===d.vTotal){var M="M"+(a+e.px0[0])+","+(p+e.px0[1])+C(e.px0,e.pxmid,!0,1)+C(e.pxmid,e.px0,!0,1)+"Z";k?x.attr("d","M"+(a+k*e.px0[0])+","+(p+k*e.px0[1])+C(e.px0,e.pxmid,!1,k)+C(e.pxmid,e.px0,!1,k)+"Z"+M):x.attr("d",M)}else{var A=C(e.px0,e.px1,!0,1);if(k){var T=1-k;x.attr("d","M"+(a+k*e.px1[0])+","+(p+k*e.px1[1])+C(e.px1,e.px0,!1,k)+"l"+T*e.px0[0]+","+T*e.px0[1]+A+"Z")}else x.attr("d","M"+a+","+p+"l"+e.px0[0]+","+e.px0[1]+A+"Z")}var S=c.castOption(g.textposition,e.pts),E=y.selectAll("g.slicetext").data(e.text&&"none"!==S?[0]:[]);E.enter().append("g").classed("slicetext",!0),E.exit().remove(),E.each(function(){var r=s.ensureSingle(n.select(this),"text","",function(t){t.attr("data-notex",1)});r.text(e.text).attr({class:"slicetext",transform:"","text-anchor":"middle"}).call(o.font,"outside"===S?g.outsidetextfont:g.insidetextfont).call(l.convertToTspans,t);var i,c=o.bBox(r.node());"outside"===S?i=f(c,e):(i=function(t,e,r){var n=Math.sqrt(t.width*t.width+t.height*t.height),i=t.width/t.height,a=Math.PI*Math.min(e.v/r.vTotal,.5),o=1-r.trace.hole,s=h(e,r),l={scale:s*r.r*2/n,rCenter:1-s,rotate:0};if(l.scale>=1)return l;var c=i+1/(2*Math.tan(a)),u=r.r*Math.min(1/(Math.sqrt(c*c+.5)+c),o/(Math.sqrt(i*i+o/2)+i)),f={scale:2*u/t.height,rCenter:Math.cos(u/r.r)-u*i/r.r,rotate:(180/Math.PI*e.midangle+720)%180-90},p=1/i,d=p+1/(2*Math.tan(a)),g=r.r*Math.min(1/(Math.sqrt(d*d+.5)+d),o/(Math.sqrt(p*p+o/2)+p)),m={scale:2*g/t.width,rCenter:Math.cos(g/r.r)-g/i/r.r,rotate:(180/Math.PI*e.midangle+810)%180-90},v=m.scale>f.scale?m:f;return l.scale<1&&v.scale>l.scale?v:l}(c,e,d),"auto"===S&&i.scale<1&&(r.call(o.font,g.outsidetextfont),g.outsidetextfont.family===g.insidetextfont.family&&g.outsidetextfont.size===g.insidetextfont.size||(c=o.bBox(r.node())),i=f(c,e)));var u=a+e.pxmid[0]*i.rCenter+(i.x||0),m=p+e.pxmid[1]*i.rCenter+(i.y||0);i.outside&&(e.yLabelMin=m-c.height/2,e.yLabelMid=m,e.yLabelMax=m+c.height/2,e.labelExtraX=0,e.labelExtraY=0,v=!0),r.attr("transform","translate("+u+","+m+")"+(i.scale<1?"scale("+i.scale+")":"")+(i.rotate?"rotate("+i.rotate+")":"")+"translate("+-(c.left+c.right)/2+","+-(c.top+c.bottom)/2+")")})}function C(t,r,n,i){return"a"+i*d.r+","+i*d.r+" 0 "+e.largeArc+(n?" 1 ":" 0 ")+i*(r[0]-t[0])+","+i*(r[1]-t[1])}}),v&&function(t,e){var r,n,i,a,o,s,l,u,h,f,p,d,g;function m(t,e){return t.pxmid[1]-e.pxmid[1]}function v(t,e){return e.pxmid[1]-t.pxmid[1]}function y(t,r){r||(r={});var i,u,h,p,d,g,m=r.labelExtraY+(n?r.yLabelMax:r.yLabelMin),v=n?t.yLabelMin:t.yLabelMax,y=n?t.yLabelMax:t.yLabelMin,x=t.cyFinal+o(t.px0[1],t.px1[1]),b=m-v;if(b*l>0&&(t.labelExtraY=b),Array.isArray(e.pull))for(u=0;u=(c.castOption(e.pull,h.pts)||0)||((t.pxmid[1]-h.pxmid[1])*l>0?(p=h.cyFinal+o(h.px0[1],h.px1[1]),(b=p-v-t.labelExtraY)*l>0&&(t.labelExtraY+=b)):(y+t.labelExtraY-x)*l>0&&(i=3*s*Math.abs(u-f.indexOf(t)),d=h.cxFinal+a(h.px0[0],h.px1[0]),(g=d+i-(t.cxFinal+t.pxmid[0])-t.labelExtraX)*s>0&&(t.labelExtraX+=g)))}for(n=0;n<2;n++)for(i=n?m:v,o=n?Math.max:Math.min,l=n?1:-1,r=0;r<2;r++){for(a=r?Math.max:Math.min,s=r?1:-1,(u=t[n][r]).sort(i),h=t[1-n][r],f=h.concat(u),d=[],p=0;pMath.abs(c)?o+="l"+c*t.pxmid[0]/t.pxmid[1]+","+c+"H"+(i+t.labelExtraX+s):o+="l"+t.labelExtraX+","+l+"v"+(c-l)+"h"+s}else o+="V"+(t.yLabelMid+t.labelExtraY)+"h"+s;e.append("path").classed("textline",!0).call(a.stroke,g.outsidetextfont.color).attr({"stroke-width":Math.min(2,g.outsidetextfont.size/8),d:o,fill:"none"})}})})}),setTimeout(function(){p.selectAll("tspan").each(function(){var t=n.select(this);t.attr("dy")&&t.attr("dy",t.attr("dy"))})},0)}},{"../../components/color":558,"../../components/drawing":583,"../../components/fx":600,"../../lib":684,"../../lib/svg_text_utils":708,"./event_data":994,"./helpers":995,d3:147}],1000:[function(t,e,r){"use strict";var n=t("d3"),i=t("./style_one");e.exports=function(t){t._fullLayout._pielayer.selectAll(".trace").each(function(t){var e=t[0].trace,r=n.select(this);r.style({opacity:e.opacity}),r.selectAll("path.surface").each(function(t){n.select(this).call(i,t,e)})})}},{"./style_one":1001,d3:147}],1001:[function(t,e,r){"use strict";var n=t("../../components/color"),i=t("./helpers").castOption;e.exports=function(t,e,r){var a=r.marker.line,o=i(a.color,e.pts)||n.defaultLine,s=i(a.width,e.pts)||0;t.style({"stroke-width":s}).call(n.fill,e.color).call(n.stroke,o)}},{"../../components/color":558,"./helpers":995}],1002:[function(t,e,r){"use strict";var n=t("../scatter/attributes");e.exports={x:n.x,y:n.y,xy:{valType:"data_array",editType:"calc"},indices:{valType:"data_array",editType:"calc"},xbounds:{valType:"data_array",editType:"calc"},ybounds:{valType:"data_array",editType:"calc"},text:n.text,marker:{color:{valType:"color",arrayOk:!1,editType:"calc"},opacity:{valType:"number",min:0,max:1,dflt:1,arrayOk:!1,editType:"calc"},blend:{valType:"boolean",dflt:null,editType:"calc"},sizemin:{valType:"number",min:.1,max:2,dflt:.5,editType:"calc"},sizemax:{valType:"number",min:.1,dflt:20,editType:"calc"},border:{color:{valType:"color",arrayOk:!1,editType:"calc"},arearatio:{valType:"number",min:0,max:1,dflt:0,editType:"calc"},editType:"calc"},editType:"calc"}}},{"../scatter/attributes":1015}],1003:[function(t,e,r){"use strict";var n=t("gl-pointcloud2d"),i=t("../../lib/str2rgbarray"),a=t("../../plots/cartesian/autorange").expand,o=t("../scatter/get_trace_color");function s(t,e){this.scene=t,this.uid=e,this.type="pointcloud",this.pickXData=[],this.pickYData=[],this.xData=[],this.yData=[],this.textLabels=[],this.color="rgb(0, 0, 0)",this.name="",this.hoverinfo="all",this.idToIndex=new Int32Array(0),this.bounds=[0,0,0,0],this.pointcloudOptions={positions:new Float32Array(0),idToIndex:this.idToIndex,sizemin:.5,sizemax:12,color:[0,0,0,1],areaRatio:1,borderColor:[0,0,0,1]},this.pointcloud=n(t.glplot,this.pointcloudOptions),this.pointcloud._trace=this}var l=s.prototype;l.handlePick=function(t){var e=this.idToIndex[t.pointId];return{trace:this,dataCoord:t.dataCoord,traceCoord:this.pickXYData?[this.pickXYData[2*e],this.pickXYData[2*e+1]]:[this.pickXData[e],this.pickYData[e]],textLabel:Array.isArray(this.textLabels)?this.textLabels[e]:this.textLabels,color:this.color,name:this.name,pointIndex:e,hoverinfo:this.hoverinfo}},l.update=function(t){this.index=t.index,this.textLabels=t.text,this.name=t.name,this.hoverinfo=t.hoverinfo,this.bounds=[1/0,1/0,-1/0,-1/0],this.updateFast(t),this.color=o(t,{})},l.updateFast=function(t){var e,r,n,a,o,s,l=this.xData=this.pickXData=t.x,c=this.yData=this.pickYData=t.y,u=this.pickXYData=t.xy,h=t.xbounds&&t.ybounds,f=t.indices,p=this.bounds;if(u){if(n=u,e=u.length>>>1,h)p[0]=t.xbounds[0],p[2]=t.xbounds[1],p[1]=t.ybounds[0],p[3]=t.ybounds[1];else for(s=0;sp[2]&&(p[2]=a),op[3]&&(p[3]=o);if(f)r=f;else for(r=new Int32Array(e),s=0;sp[2]&&(p[2]=a),op[3]&&(p[3]=o);this.idToIndex=r,this.pointcloudOptions.idToIndex=r,this.pointcloudOptions.positions=n;var d=i(t.marker.color),g=i(t.marker.border.color),m=t.opacity*t.marker.opacity;d[3]*=m,this.pointcloudOptions.color=d;var v=t.marker.blend;if(null===v){v=l.length<100||c.length<100}this.pointcloudOptions.blend=v,g[3]*=m,this.pointcloudOptions.borderColor=g;var y=t.marker.sizemin,x=Math.max(t.marker.sizemax,t.marker.sizemin);this.pointcloudOptions.sizeMin=y,this.pointcloudOptions.sizeMax=x,this.pointcloudOptions.areaRatio=t.marker.border.arearatio,this.pointcloud.update(this.pointcloudOptions),this.expandAxesFast(p,x/2)},l.expandAxesFast=function(t,e){var r=e||.5;a(this.scene.xaxis,[t[0],t[2]],{ppad:r}),a(this.scene.yaxis,[t[1],t[3]],{ppad:r})},l.dispose=function(){this.pointcloud.dispose()},e.exports=function(t,e){var r=new s(t,e.uid);return r.update(e),r}},{"../../lib/str2rgbarray":707,"../../plots/cartesian/autorange":731,"../scatter/get_trace_color":1024,"gl-pointcloud2d":279}],1004:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("./attributes");e.exports=function(t,e,r){function a(r,a){return n.coerce(t,e,i,r,a)}a("x"),a("y"),a("xbounds"),a("ybounds"),t.xy&&t.xy instanceof Float32Array&&(e.xy=t.xy),t.indices&&t.indices instanceof Int32Array&&(e.indices=t.indices),a("text"),a("marker.color",r),a("marker.opacity"),a("marker.blend"),a("marker.sizemin"),a("marker.sizemax"),a("marker.border.color",r),a("marker.border.arearatio"),e._length=null}},{"../../lib":684,"./attributes":1002}],1005:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.calc=t("../scatter3d/calc"),n.plot=t("./convert"),n.moduleType="trace",n.name="pointcloud",n.basePlotModule=t("../../plots/gl2d"),n.categories=["gl","gl2d","showLegend"],n.meta={},e.exports=n},{"../../plots/gl2d":771,"../scatter3d/calc":1041,"./attributes":1002,"./convert":1003,"./defaults":1004}],1006:[function(t,e,r){"use strict";var n=t("../../plots/font_attributes"),i=t("../../plots/attributes"),a=t("../../components/color/attributes"),o=t("../../components/fx/attributes"),s=t("../../plots/domain").attributes,l=t("../../lib/extend").extendFlat,c=t("../../plot_api/edit_types").overrideAll;e.exports=c({hoverinfo:l({},i.hoverinfo,{flags:["label","text","value","percent","name"]}),hoverlabel:o.hoverlabel,domain:s({name:"sankey",trace:!0}),orientation:{valType:"enumerated",values:["v","h"],dflt:"h"},valueformat:{valType:"string",dflt:".3s"},valuesuffix:{valType:"string",dflt:""},arrangement:{valType:"enumerated",values:["snap","perpendicular","freeform","fixed"],dflt:"snap"},textfont:n({}),node:{label:{valType:"data_array",dflt:[]},color:{valType:"color",arrayOk:!0},line:{color:{valType:"color",dflt:a.defaultLine,arrayOk:!0},width:{valType:"number",min:0,dflt:.5,arrayOk:!0}},pad:{valType:"number",arrayOk:!1,min:0,dflt:20},thickness:{valType:"number",arrayOk:!1,min:1,dflt:20}},link:{label:{valType:"data_array",dflt:[]},color:{valType:"color",arrayOk:!0},line:{color:{valType:"color",dflt:a.defaultLine,arrayOk:!0},width:{valType:"number",min:0,dflt:0,arrayOk:!0}},source:{valType:"data_array",dflt:[]},target:{valType:"data_array",dflt:[]},value:{valType:"data_array",dflt:[]}}},"calc","nested")},{"../../components/color/attributes":557,"../../components/fx/attributes":592,"../../lib/extend":673,"../../plot_api/edit_types":715,"../../plots/attributes":729,"../../plots/domain":757,"../../plots/font_attributes":758}],1007:[function(t,e,r){"use strict";var n=t("../../plot_api/edit_types").overrideAll,i=t("../../plots/get_data").getModuleCalcData,a=t("./plot"),o=t("../../components/fx/layout_attributes");r.name="sankey",r.baseLayoutAttrOverrides=n({hoverlabel:o.hoverlabel},"plot","nested"),r.plot=function(t){var e=i(t.calcdata,"sankey")[0];a(t,e)},r.clean=function(t,e,r,n){var i=n._has&&n._has("sankey"),a=e._has&&e._has("sankey");i&&!a&&n._paperdiv.selectAll(".sankey").remove()}},{"../../components/fx/layout_attributes":601,"../../plot_api/edit_types":715,"../../plots/get_data":768,"./plot":1012}],1008:[function(t,e,r){"use strict";var n=t("strongly-connected-components"),i=t("../../lib"),a=t("../../lib/gup").wrap;e.exports=function(t,e){return function(t,e,r){for(var a=t.length,o=i.init2dArray(a,0),s=0;s1})}(e.node.label,e.link.source,e.link.target)&&(i.error("Circularity is present in the Sankey data. Removing all nodes and links."),e.link.label=[],e.link.source=[],e.link.target=[],e.link.value=[],e.link.color=[],e.node.label=[],e.node.color=[]),a({link:e.link,node:e.node})}},{"../../lib":684,"../../lib/gup":681,"strongly-connected-components":491}],1009:[function(t,e,r){"use strict";e.exports={nodeTextOffsetHorizontal:4,nodeTextOffsetVertical:3,nodePadAcross:10,sankeyIterations:50,forceIterations:5,forceTicksPerFrame:10,duration:500,ease:"cubic-in-out",cn:{sankey:"sankey",sankeyLinks:"sankey-links",sankeyLink:"sankey-link",sankeyNodeSet:"sankey-node-set",sankeyNode:"sankey-node",nodeRect:"node-rect",nodeCapture:"node-capture",nodeCentered:"node-entered",nodeLabelGuide:"node-label-guide",nodeLabel:"node-label",nodeLabelTextPath:"node-label-text-path"}}},{}],1010:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("./attributes"),a=t("../../components/color"),o=t("tinycolor2"),s=t("../../plots/domain").defaults;e.exports=function(t,e,r,l){function c(r,a){return n.coerce(t,e,i,r,a)}c("node.label"),c("node.pad"),c("node.thickness"),c("node.line.color"),c("node.line.width");var u=l.colorway;c("node.color",e.node.label.map(function(t,e){return a.addOpacity(function(t){return u[t%u.length]}(e),.8)})),c("link.label"),c("link.source"),c("link.target"),c("link.value"),c("link.line.color"),c("link.line.width"),c("link.color",e.link.value.map(function(){return o(l.paper_bgcolor).getLuminance()<.333?"rgba(255, 255, 255, 0.6)":"rgba(0, 0, 0, 0.2)"})),s(e,l,c),c("orientation"),c("valueformat"),c("valuesuffix"),c("arrangement"),n.coerceFont(c,"textfont",n.extendFlat({},l.font)),e._length=null}},{"../../components/color":558,"../../lib":684,"../../plots/domain":757,"./attributes":1006,tinycolor2:499}],1011:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.calc=t("./calc"),n.plot=t("./plot"),n.moduleType="trace",n.name="sankey",n.basePlotModule=t("./base_plot"),n.categories=["noOpacity"],n.meta={},e.exports=n},{"./attributes":1006,"./base_plot":1007,"./calc":1008,"./defaults":1010,"./plot":1012}],1012:[function(t,e,r){"use strict";var n=t("d3"),i=t("./render"),a=t("../../components/fx"),o=t("../../components/color"),s=t("../../lib"),l=t("./constants").cn,c=s._;function u(t){return""!==t}function h(t,e){return t.filter(function(t){return t.key===e.traceId})}function f(t,e){n.select(t).select("path").style("fill-opacity",e),n.select(t).select("rect").style("fill-opacity",e)}function p(t){n.select(t).select("text.name").style("fill","black")}function d(t){return function(e){return-1!==t.node.sourceLinks.indexOf(e.link)||-1!==t.node.targetLinks.indexOf(e.link)}}function g(t){return function(e){return-1!==e.node.sourceLinks.indexOf(t.link)||-1!==e.node.targetLinks.indexOf(t.link)}}function m(t,e,r){e&&r&&h(r,e).selectAll("."+l.sankeyLink).filter(d(e)).call(y.bind(0,e,r,!1))}function v(t,e,r){e&&r&&h(r,e).selectAll("."+l.sankeyLink).filter(d(e)).call(x.bind(0,e,r,!1))}function y(t,e,r,n){var i=n.datum().link.label;n.style("fill-opacity",.4),i&&h(e,t).selectAll("."+l.sankeyLink).filter(function(t){return t.link.label===i}).style("fill-opacity",.4),r&&h(e,t).selectAll("."+l.sankeyNode).filter(g(t)).call(m)}function x(t,e,r,n){var i=n.datum().link.label;n.style("fill-opacity",function(t){return t.tinyColorAlpha}),i&&h(e,t).selectAll("."+l.sankeyLink).filter(function(t){return t.link.label===i}).style("fill-opacity",function(t){return t.tinyColorAlpha}),r&&h(e,t).selectAll(l.sankeyNode).filter(g(t)).call(v)}function b(t,e){var r=t.hoverlabel||{},n=s.nestedProperty(r,e).get();return!Array.isArray(n)&&n}e.exports=function(t,e){var r=t._fullLayout,s=r._paper,h=r._size,d=c(t,"source:")+" ",g=c(t,"target:")+" ",_=c(t,"incoming flow count:")+" ",w=c(t,"outgoing flow count:")+" ";i(s,e,{width:h.w,height:h.h,margin:{t:h.t,r:h.r,b:h.b,l:h.l}},{linkEvents:{hover:function(e,r,i){n.select(e).call(y.bind(0,r,i,!0)),t.emit("plotly_hover",{event:n.event,points:[r.link]})},follow:function(e,i){var s=i.link.trace,l=t._fullLayout._paperdiv.node().getBoundingClientRect(),c=e.getBoundingClientRect(),h=c.left+c.width/2,m=c.top+c.height/2,v=a.loneHover({x:h-l.left,y:m-l.top,name:n.format(i.valueFormat)(i.link.value)+i.valueSuffix,text:[i.link.label||"",d+i.link.source.label,g+i.link.target.label].filter(u).join("
"),color:b(s,"bgcolor")||o.addOpacity(i.tinyColorHue,1),borderColor:b(s,"bordercolor"),fontFamily:b(s,"font.family"),fontSize:b(s,"font.size"),fontColor:b(s,"font.color"),idealAlign:n.event.x"),color:b(o,"bgcolor")||i.tinyColorHue,borderColor:b(o,"bordercolor"),fontFamily:b(o,"font.family"),fontSize:b(o,"font.size"),fontColor:b(o,"font.color"),idealAlign:"left"},{container:r._hoverlayer.node(),outerContainer:r._paper.node(),gd:t});f(v,.85),p(v)},unhover:function(e,i,o){n.select(e).call(v,i,o),t.emit("plotly_unhover",{event:n.event,points:[i.node]}),a.loneUnhover(r._hoverlayer.node())},select:function(e,r,i){var o=r.node;o.originalEvent=n.event,t._hoverdata=[o],n.select(e).call(v,r,i),a.click(t,{target:!0})}}})}},{"../../components/color":558,"../../components/fx":600,"../../lib":684,"./constants":1009,"./render":1013,d3:147}],1013:[function(t,e,r){"use strict";var n=t("./constants"),i=t("d3"),a=t("tinycolor2"),o=t("../../components/color"),s=t("../../components/drawing"),l=t("@plotly/d3-sankey").sankey,c=t("d3-force"),u=t("../../lib"),h=u.isArrayOrTypedArray,f=u.isIndex,p=t("../../lib/gup"),d=p.keyFun,g=p.repeat,m=p.unwrap;function v(t){t.lastDraggedX=t.x,t.lastDraggedY=t.y}function y(t){return function(e){return e.node.originalX===t.node.originalX}}function x(t){for(var e=0;e1||t.linkLineWidth>0}function T(t){return"translate("+t.translateX+","+t.translateY+")"+(t.horizontal?"matrix(1 0 0 1 0 0)":"matrix(0 1 1 0 0 0)")}function S(t){return"translate("+(t.horizontal?0:t.labelY)+" "+(t.horizontal?t.labelY:0)+")"}function E(t){return i.svg.line()([[t.horizontal?t.left?-t.sizeAcross:t.visibleWidth+n.nodeTextOffsetHorizontal:n.nodeTextOffsetHorizontal,0],[t.horizontal?t.left?-n.nodeTextOffsetHorizontal:t.sizeAcross:t.visibleHeight-n.nodeTextOffsetHorizontal,0]])}function C(t){return t.horizontal?"matrix(1 0 0 1 0 0)":"matrix(0 1 1 0 0 0)"}function L(t){return t.horizontal?"scale(1 1)":"scale(-1 1)"}function z(t){return t.darkBackground&&!t.horizontal?"rgb(255,255,255)":"rgb(0,0,0)"}function P(t){return t.horizontal&&t.left?"100%":"0%"}function I(t,e,r){t.on(".basic",null).on("mouseover.basic",function(t){t.interactionState.dragInProgress||(r.hover(this,t,e),t.interactionState.hovered=[this,t])}).on("mousemove.basic",function(t){t.interactionState.dragInProgress||(r.follow(this,t),t.interactionState.hovered=[this,t])}).on("mouseout.basic",function(t){t.interactionState.dragInProgress||(r.unhover(this,t,e),t.interactionState.hovered=!1)}).on("click.basic",function(t){t.interactionState.hovered&&(r.unhover(this,t,e),t.interactionState.hovered=!1),t.interactionState.dragInProgress||r.select(this,t,e)})}function O(t,e,r){var a=i.behavior.drag().origin(function(t){return t.node}).on("dragstart",function(i){if("fixed"!==i.arrangement&&(u.raiseToTop(this),i.interactionState.dragInProgress=i.node,v(i.node),i.interactionState.hovered&&(r.nodeEvents.unhover.apply(0,i.interactionState.hovered),i.interactionState.hovered=!1),"snap"===i.arrangement)){var a=i.traceId+"|"+Math.floor(i.node.originalX);i.forceLayouts[a]?i.forceLayouts[a].alpha(1):function(t,e,r){var i=r.sankey.nodes().filter(function(t){return t.originalX===r.node.originalX});r.forceLayouts[e]=c.forceSimulation(i).alphaDecay(0).force("collide",c.forceCollide().radius(function(t){return t.dy/2+r.nodePad/2}).strength(1).iterations(n.forceIterations)).force("constrain",function(t,e,r,i){return function(){for(var t=0,a=0;a0&&i.forceLayouts[e].alpha(0)}}(0,e,i,r)).stop()}(0,a,i),function(t,e,r,i){window.requestAnimationFrame(function a(){for(var o=0;o0&&window.requestAnimationFrame(a)})}(t,e,i,a)}}).on("drag",function(r){if("fixed"!==r.arrangement){var n=i.event.x,a=i.event.y;"snap"===r.arrangement?(r.node.x=n,r.node.y=a):("freeform"===r.arrangement&&(r.node.x=n),r.node.y=Math.max(r.node.dy/2,Math.min(r.size-r.node.dy/2,a))),v(r.node),"snap"!==r.arrangement&&(r.sankey.relayout(),k(t.filter(y(r)),e))}}).on("dragend",function(t){t.interactionState.dragInProgress=!1});t.on(".drag",null).call(a)}e.exports=function(t,e,r,i){var c=t.selectAll("."+n.cn.sankey).data(e.filter(function(t){return m(t).trace.visible}).map(function(t,e,r){var i,a=m(e).trace,o=a.domain,s=a.node,c=a.link,u=a.arrangement,p="h"===a.orientation,d=a.node.pad,g=a.node.thickness,v=a.node.line.color,y=a.node.line.width,b=a.link.line.color,_=a.link.line.width,w=a.valueformat,k=a.valuesuffix,M=a.textfont,A=t.width*(o.x[1]-o.x[0]),T=t.height*(o.y[1]-o.y[0]),S=[],E=h(c.color),C={},L=s.label.length;for(i=0;i0&&f(P,L)&&f(I,L)&&(I=+I,C[P=+P]=C[I]=!0,S.push({pointNumber:i,label:c.label[i],color:E?c.color[i]:c.color,source:P,target:I,value:+z}))}var O=h(s.color),D=[],R=!1,B={};for(i=0;i5?t.node.label:""}).attr("text-anchor",function(t){return t.horizontal&&t.left?"end":"start"}),F.transition().ease(n.ease).duration(n.duration).attr("startOffset",P).style("fill",z)}},{"../../components/color":558,"../../components/drawing":583,"../../lib":684,"../../lib/gup":681,"./constants":1009,"@plotly/d3-sankey":49,d3:147,"d3-force":143,tinycolor2:499}],1014:[function(t,e,r){"use strict";var n=t("../../lib");e.exports=function(t,e){for(var r=0;r=0;i--){var a=t[i];if("scatter"===a.type&&a.xaxis===r.xaxis&&a.yaxis===r.yaxis){a.opacity=void 0;break}}}}}},{}],1019:[function(t,e,r){"use strict";var n=t("../../components/colorscale/has_colorscale"),i=t("../../components/colorscale/calc"),a=t("./subtypes");e.exports=function(t){a.hasLines(t)&&n(t,"line")&&i(t,t.line.color,"line","c"),a.hasMarkers(t)&&(n(t,"marker")&&i(t,t.marker.color,"marker","c"),n(t,"marker.line")&&i(t,t.marker.line.color,"marker.line","c"))}},{"../../components/colorscale/calc":566,"../../components/colorscale/has_colorscale":572,"./subtypes":1037}],1020:[function(t,e,r){"use strict";e.exports={PTS_LINESONLY:20,minTolerance:.2,toleranceGrowth:10,maxScreensAway:20}},{}],1021:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../registry"),a=t("./attributes"),o=t("./constants"),s=t("./subtypes"),l=t("./xy_defaults"),c=t("./marker_defaults"),u=t("./line_defaults"),h=t("./line_shape_defaults"),f=t("./text_defaults"),p=t("./fillcolor_defaults");e.exports=function(t,e,r,d){function g(r,i){return n.coerce(t,e,a,r,i)}var m=l(t,e,d,g),v=mV!=(I=E[T][1])>=V&&(L=E[T-1][0],z=E[T][0],I-P&&(C=L+(z-L)*(V-P)/(I-P),B=Math.min(B,C),F=Math.max(F,C)));B=Math.max(B,0),F=Math.min(F,f._length);var U=s.defaultLine;return s.opacity(h.fillcolor)?U=h.fillcolor:s.opacity((h.line||{}).color)&&(U=h.line.color),n.extendFlat(t,{distance:t.maxHoverDistance,x0:B,x1:F,y0:V,y1:V,color:U}),delete t.index,h.text&&!Array.isArray(h.text)?t.text=String(h.text):t.text=h.name,[t]}}}},{"../../components/color":558,"../../components/fx":600,"../../lib":684,"../../registry":817,"./fill_hover_text":1022,"./get_trace_color":1024}],1026:[function(t,e,r){"use strict";var n={},i=t("./subtypes");n.hasLines=i.hasLines,n.hasMarkers=i.hasMarkers,n.hasText=i.hasText,n.isBubble=i.isBubble,n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.cleanData=t("./clean_data"),n.calc=t("./calc").calc,n.arraysToCalcdata=t("./arrays_to_calcdata"),n.plot=t("./plot"),n.colorbar=t("./marker_colorbar"),n.style=t("./style").style,n.styleOnSelect=t("./style").styleOnSelect,n.hoverPoints=t("./hover"),n.selectPoints=t("./select"),n.animatable=!0,n.moduleType="trace",n.name="scatter",n.basePlotModule=t("../../plots/cartesian"),n.categories=["cartesian","svg","symbols","errorBarsOK","showLegend","scatter-like","zoomScale"],n.meta={},e.exports=n},{"../../plots/cartesian":743,"./arrays_to_calcdata":1014,"./attributes":1015,"./calc":1016,"./clean_data":1018,"./defaults":1021,"./hover":1025,"./marker_colorbar":1032,"./plot":1034,"./select":1035,"./style":1036,"./subtypes":1037}],1027:[function(t,e,r){"use strict";var n=t("../../lib").isArrayOrTypedArray,i=t("../../components/colorscale/has_colorscale"),a=t("../../components/colorscale/defaults");e.exports=function(t,e,r,o,s,l){var c=(t.marker||{}).color;(s("line.color",r),i(t,"line"))?a(t,e,o,s,{prefix:"line.",cLetter:"c"}):s("line.color",!n(c)&&c||r);s("line.width"),(l||{}).noDash||s("line.dash")}},{"../../components/colorscale/defaults":568,"../../components/colorscale/has_colorscale":572,"../../lib":684}],1028:[function(t,e,r){"use strict";var n=t("../../constants/numerical").BADNUM,i=t("../../lib"),a=i.segmentsIntersect,o=i.constrain,s=t("./constants");e.exports=function(t,e){var r,l,c,u,h,f,p,d,g,m,v,y,x,b,_,w,k,M,A=e.xaxis,T=e.yaxis,S=e.connectGaps,E=e.baseTolerance,C=e.shape,L="linear"===C,z=[],P=s.minTolerance,I=new Array(t.length),O=0;function D(e){var r=t[e];if(!r)return!1;var i=A.c2p(r.x),a=T.c2p(r.y);return i===n||a===n?r.intoCenter||!1:[i,a]}function R(t,e,r,n){var i=r-t,a=n-e,o=.5-t,s=.5-e,l=i*i+a*a,c=i*o+a*s;if(c>0&&cX||t[1]$)return[o(t[0],Y,X),o(t[1],Z,$)]}function Q(t,e){return t[0]===e[0]&&(t[0]===Y||t[0]===X)||(t[1]===e[1]&&(t[1]===Z||t[1]===$)||void 0)}function tt(t,e,r){return function(n,a){var o=K(n),s=K(a),l=[];if(o&&s&&Q(o,s))return l;o&&l.push(o),s&&l.push(s);var c=2*i.constrain((n[t]+a[t])/2,e,r)-((o||n)[t]+(s||a)[t]);c&&((o&&s?c>0==o[t]>s[t]?o:s:o||s)[t]+=c);return l}}function et(t){var e=t[0],r=t[1],n=e===I[O-1][0],i=r===I[O-1][1];if(!n||!i)if(O>1){var a=e===I[O-2][0],o=r===I[O-2][1];n&&(e===Y||e===X)&&a?o?O--:I[O-1]=t:i&&(r===Z||r===$)&&o?a?O--:I[O-1]=t:I[O++]=t}else I[O++]=t}function rt(t){I[O-1][0]!==t[0]&&I[O-1][1]!==t[1]&&et([V,U]),et(t),q=null,V=U=0}function nt(t){if(k=t[0]/A._length,M=t[1]/T._length,N=t[0]X?X:0,j=t[1]$?$:0,N||j){if(O)if(q){var e=G(q,t);e.length>1&&(rt(e[0]),I[O++]=e[1])}else H=G(I[O-1],t)[0],I[O++]=H;else I[O++]=[N||t[0],j||t[1]];var r=I[O-1];N&&j&&(r[0]!==N||r[1]!==j)?(q&&(V!==N&&U!==j?et(V&&U?(n=q,a=(i=t)[0]-n[0],o=(i[1]-n[1])/a,(n[1]*i[0]-i[1]*n[0])/a>0?[o>0?Y:X,$]:[o>0?X:Y,Z]):[V||N,U||j]):V&&U&&et([V,U])),et([N,j])):V-N&&U-j&&et([N||V,j||U]),q=t,V=N,U=j}else q&&rt(G(q,t)[0]),I[O++]=t;var n,i,a,o}for("linear"===C||"spline"===C?G=function(t,e){for(var r=[],n=0,i=0;i<4;i++){var o=J[i],s=a(t[0],t[1],e[0],e[1],o[0],o[1],o[2],o[3]);s&&(!n||Math.abs(s.x-r[0][0])>1||Math.abs(s.y-r[0][1])>1)&&(s=[s.x,s.y],n&&F(s,t)B(f,it))break;c=f,(x=g[0]*d[0]+g[1]*d[1])>v?(v=x,u=f,p=!1):x=t.length||!f)break;nt(f),l=f}}else nt(u)}q&&et([V||q[0],U||q[1]]),z.push(I.slice(0,O))}return z}},{"../../constants/numerical":661,"../../lib":684,"./constants":1020}],1029:[function(t,e,r){"use strict";e.exports=function(t,e,r){"spline"===r("line.shape")&&r("line.smoothing")}},{}],1030:[function(t,e,r){"use strict";e.exports=function(t,e,r){var n,i,a=null;for(i=0;i0?Math.max(e,i):0}}},{"fast-isnumeric":214}],1032:[function(t,e,r){"use strict";e.exports={container:"marker",min:"cmin",max:"cmax"}},{}],1033:[function(t,e,r){"use strict";var n=t("../../components/color"),i=t("../../components/colorscale/has_colorscale"),a=t("../../components/colorscale/defaults"),o=t("./subtypes");e.exports=function(t,e,r,s,l,c){var u=o.isBubble(t),h=(t.line||{}).color;(c=c||{},h&&(r=h),l("marker.symbol"),l("marker.opacity",u?.7:1),l("marker.size"),l("marker.color",r),i(t,"marker")&&a(t,e,s,l,{prefix:"marker.",cLetter:"c"}),c.noSelect||(l("selected.marker.color"),l("unselected.marker.color"),l("selected.marker.size"),l("unselected.marker.size")),c.noLine||(l("marker.line.color",h&&!Array.isArray(h)&&e.marker.color!==h?h:u?n.background:n.defaultLine),i(t,"marker.line")&&a(t,e,s,l,{prefix:"marker.line.",cLetter:"c"}),l("marker.line.width",u?1:0)),u&&(l("marker.sizeref"),l("marker.sizemin"),l("marker.sizemode")),c.gradient)&&("none"!==l("marker.gradient.type")&&l("marker.gradient.color"))}},{"../../components/color":558,"../../components/colorscale/defaults":568,"../../components/colorscale/has_colorscale":572,"./subtypes":1037}],1034:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../registry"),a=t("../../lib"),o=t("../../components/drawing"),s=t("./subtypes"),l=t("./line_points"),c=t("./link_traces"),u=t("../../lib/polygon").tester;function h(t,e,r,c,h,f,p){var d,g;!function(t,e,r,i,o){var l=r.xaxis,c=r.yaxis,u=n.extent(a.simpleMap(l.range,l.r2c)),h=n.extent(a.simpleMap(c.range,c.r2c)),f=i[0].trace;if(!s.hasMarkers(f))return;var p=f.marker.maxdisplayed;if(0===p)return;var d=i.filter(function(t){return t.x>=u[0]&&t.x<=u[1]&&t.y>=h[0]&&t.y<=h[1]}),g=Math.ceil(d.length/p),m=0;o.forEach(function(t,r){var n=t[0].trace;s.hasMarkers(n)&&n.marker.maxdisplayed>0&&r0;function v(t){return m?t.transition():t}var y=r.xaxis,x=r.yaxis,b=c[0].trace,_=b.line,w=n.select(f);if(i.getComponentMethod("errorbars","plot")(w,r,p),!0===b.visible){var k,M;v(w).style("opacity",b.opacity);var A=b.fill.charAt(b.fill.length-1);"x"!==A&&"y"!==A&&(A=""),r.isRangePlot||(c[0].node3=w);var T="",S=[],E=b._prevtrace;E&&(T=E._prevRevpath||"",M=E._nextFill,S=E._polygons);var C,L,z,P,I,O,D,R,B,F="",N="",j=[],V=a.noop;if(k=b._ownFill,s.hasLines(b)||"none"!==b.fill){for(M&&M.datum(c),-1!==["hv","vh","hvh","vhv"].indexOf(_.shape)?(z=o.steps(_.shape),P=o.steps(_.shape.split("").reverse().join(""))):z=P="spline"===_.shape?function(t){var e=t[t.length-1];return t.length>1&&t[0][0]===e[0]&&t[0][1]===e[1]?o.smoothclosed(t.slice(1),_.smoothing):o.smoothopen(t,_.smoothing)}:function(t){return"M"+t.join("L")},I=function(t){return P(t.reverse())},j=l(c,{xaxis:y,yaxis:x,connectGaps:b.connectgaps,baseTolerance:Math.max(_.width||1,3)/4,shape:_.shape,simplify:_.simplify}),B=b._polygons=new Array(j.length),g=0;g1){var r=n.select(this);if(r.datum(c),t)v(r.style("opacity",0).attr("d",C).call(o.lineGroupStyle)).style("opacity",1);else{var i=v(r);i.attr("d",C),o.singleLineStyle(c,i)}}}}}var U=w.selectAll(".js-line").data(j);v(U.exit()).style("opacity",0).remove(),U.each(V(!1)),U.enter().append("path").classed("js-line",!0).style("vector-effect","non-scaling-stroke").call(o.lineGroupStyle).each(V(!0)),o.setClipUrl(U,r.layerClipId),j.length?(k?O&&R&&(A?("y"===A?O[1]=R[1]=x.c2p(0,!0):"x"===A&&(O[0]=R[0]=y.c2p(0,!0)),v(k).attr("d","M"+R+"L"+O+"L"+F.substr(1)).call(o.singleFillStyle)):v(k).attr("d",F+"Z").call(o.singleFillStyle)):M&&("tonext"===b.fill.substr(0,6)&&F&&T?("tonext"===b.fill?v(M).attr("d",F+"Z"+T+"Z").call(o.singleFillStyle):v(M).attr("d",F+"L"+T.substr(1)+"Z").call(o.singleFillStyle),b._polygons=b._polygons.concat(S)):(H(M),b._polygons=null)),b._prevRevpath=N,b._prevPolygons=B):(k?H(k):M&&H(M),b._polygons=b._prevRevpath=b._prevPolygons=null);var q=w.selectAll(".points");d=q.data([c]),q.each(Z),d.enter().append("g").classed("points",!0).each(Z),d.exit().remove(),d.each(function(t){var e=!1===t[0].trace.cliponaxis;o.setClipUrl(n.select(this),e?null:r.layerClipId)})}function H(t){v(t).attr("d","M0,0Z")}function G(t){return t.filter(function(t){return t.vis})}function W(t){return t.id}function Y(t){if(t.ids)return W}function X(){return!1}function Z(e){var i,l=e[0].trace,c=n.select(this),u=s.hasMarkers(l),h=s.hasText(l),f=Y(l),p=X,d=X;u&&(p=l.marker.maxdisplayed||l._needsCull?G:a.identity),h&&(d=l.marker.maxdisplayed||l._needsCull?G:a.identity);var g,b=(i=c.selectAll("path.point").data(p,f)).enter().append("path").classed("point",!0);m&&b.call(o.pointStyle,l,t).call(o.translatePoints,y,x).style("opacity",0).transition().style("opacity",1),i.order(),u&&(g=o.makePointStyleFns(l)),i.each(function(e){var i=n.select(this),a=v(i);o.translatePoint(e,a,y,x)?(o.singlePointStyle(e,a,l,g,t),r.layerClipId&&o.hideOutsideRangePoint(e,a,y,x,l.xcalendar,l.ycalendar),l.customdata&&i.classed("plotly-customdata",null!==e.data&&void 0!==e.data)):a.remove()}),m?i.exit().transition().style("opacity",0).remove():i.exit().remove(),(i=c.selectAll("g").data(d,f)).enter().append("g").classed("textpoint",!0).append("text"),i.order(),i.each(function(t){var e=n.select(this),i=v(e.select("text"));o.translatePoint(t,i,y,x)?r.layerClipId&&o.hideOutsideRangePoint(t,e,y,x,l.xcalendar,l.ycalendar):e.remove()}),i.selectAll("text").call(o.textPointStyle,l,t).each(function(t){var e=y.c2p(t.x),r=x.c2p(t.y);n.select(this).selectAll("tspan.line").each(function(){v(n.select(this)).attr({x:e,y:r})})}),i.exit().remove()}}e.exports=function(t,e,r,i,a,s){var l,u,f,p,d=!a,g=!!a&&a.duration>0;for((f=i.selectAll("g.trace").data(r,function(t){return t[0].trace.uid})).enter().append("g").attr("class",function(t){return"trace scatter trace"+t[0].trace.uid}).style("stroke-miterlimit",2),c(t,e,r),function(t,e,r){var i;e.selectAll("g.trace").each(function(t){var e=n.select(this);if((i=t[0].trace)._nexttrace){if(i._nextFill=e.select(".js-fill.js-tonext"),!i._nextFill.size()){var a=":first-child";e.select(".js-fill.js-tozero").size()&&(a+=" + *"),i._nextFill=e.insert("path",a).attr("class","js-fill js-tonext")}}else e.selectAll(".js-fill.js-tonext").remove(),i._nextFill=null;i.fill&&("tozero"===i.fill.substr(0,6)||"toself"===i.fill||"to"===i.fill.substr(0,2)&&!i._prevtrace)?(i._ownFill=e.select(".js-fill.js-tozero"),i._ownFill.size()||(i._ownFill=e.insert("path",":first-child").attr("class","js-fill js-tozero"))):(e.selectAll(".js-fill.js-tozero").remove(),i._ownFill=null),e.selectAll(".js-fill").call(o.setClipUrl,r.layerClipId)})}(0,i,e),l=0,u={};lu[e[0].trace.uid]?1:-1}),g)?(s&&(p=s()),n.transition().duration(a.duration).ease(a.easing).each("end",function(){p&&p()}).each("interrupt",function(){p&&p()}).each(function(){i.selectAll("g.trace").each(function(n,i){h(t,i,e,n,r,this,a)})})):i.selectAll("g.trace").each(function(n,i){h(t,i,e,n,r,this,a)});d&&f.exit().remove(),i.selectAll("path:not([d])").remove()}},{"../../components/drawing":583,"../../lib":684,"../../lib/polygon":696,"../../registry":817,"./line_points":1028,"./link_traces":1030,"./subtypes":1037,d3:147}],1035:[function(t,e,r){"use strict";var n=t("./subtypes");e.exports=function(t,e){var r,i,a,o,s=t.cd,l=t.xaxis,c=t.yaxis,u=[],h=s[0].trace;if(!n.hasMarkers(h)&&!n.hasText(h))return[];if(!1===e)for(r=0;r=0&&(p[1]+=1),f.indexOf("top")>=0&&(p[1]-=1),f.indexOf("left")>=0&&(p[0]-=1),f.indexOf("right")>=0&&(p[0]+=1),p)),r.textColor=u(e.textfont,1,C),r.textSize=x(e.textfont.size,C,l.identity,12),r.textFont=e.textfont.family,r.textAngle=0);var O=["x","y","z"];for(r.project=[!1,!1,!1],r.projectScale=[1,1,1],r.projectOpacity=[1,1,1],n=0;n<3;++n){var D=e.projection[O[n]];(r.project[n]=D.show)&&(r.projectOpacity[n]=D.opacity,r.projectScale[n]=D.scale)}r.errorBounds=d(e,b);var R=function(t){for(var e=[0,0,0],r=[[0,0,0],[0,0,0],[0,0,0]],n=[0,0,0],i=0;i<3;i++){var a=t[i];a&&!1!==a.copy_zstyle&&(a=t[2]),a&&(e[i]=a.width/2,r[i]=c(a.color),n=a.thickness)}return{capSize:e,color:r,lineWidth:n}}([e.error_x,e.error_y,e.error_z]);return r.errorColor=R.color,r.errorLineWidth=R.lineWidth,r.errorCapSize=R.capSize,r.delaunayAxis=e.surfaceaxis,r.delaunayColor=c(e.surfacecolor),r}function _(t){if(Array.isArray(t)){var e=t[0];return Array.isArray(e)&&(t=e),"rgb("+t.slice(0,3).map(function(t){return Math.round(255*t)})+")"}return null}m.handlePick=function(t){if(t.object&&(t.object===this.linePlot||t.object===this.delaunayMesh||t.object===this.textMarkers||t.object===this.scatterPlot)){var e=t.index=t.data.index;return t.object.highlight&&t.object.highlight(null),this.scatterPlot&&(t.object=this.scatterPlot,this.scatterPlot.highlight(t.data)),t.textLabel="",this.textLabels&&(Array.isArray(this.textLabels)?(this.textLabels[e]||0===this.textLabels[e])&&(t.textLabel=this.textLabels[e]):t.textLabel=this.textLabels),t.traceCoordinate=[this.data.x[e],this.data.y[e],this.data.z[e]],!0}},m.update=function(t){var e,r,l,c,u=this.scene.glplot.gl,h=f.solid;this.data=t;var p=b(this.scene,t);"mode"in p&&(this.mode=p.mode),"lineDashes"in p&&p.lineDashes in f&&(h=f[p.lineDashes]),this.color=_(p.scatterColor)||_(p.lineColor),this.dataPoints=p.position,e={gl:u,position:p.position,color:p.lineColor,lineWidth:p.lineWidth||1,dashes:h[0],dashScale:h[1],opacity:t.opacity,connectGaps:t.connectgaps},-1!==this.mode.indexOf("lines")?this.linePlot?this.linePlot.update(e):(this.linePlot=n(e),this.linePlot._trace=this,this.scene.glplot.add(this.linePlot)):this.linePlot&&(this.scene.glplot.remove(this.linePlot),this.linePlot.dispose(),this.linePlot=null);var d=t.opacity;if(t.marker&&t.marker.opacity&&(d*=t.marker.opacity),r={gl:u,position:p.position,color:p.scatterColor,size:p.scatterSize,glyph:p.scatterMarker,opacity:d,orthographic:!0,lineWidth:p.scatterLineWidth,lineColor:p.scatterLineColor,project:p.project,projectScale:p.projectScale,projectOpacity:p.projectOpacity},-1!==this.mode.indexOf("markers")?this.scatterPlot?this.scatterPlot.update(r):(this.scatterPlot=i(r),this.scatterPlot._trace=this,this.scatterPlot.highlightScale=1,this.scene.glplot.add(this.scatterPlot)):this.scatterPlot&&(this.scene.glplot.remove(this.scatterPlot),this.scatterPlot.dispose(),this.scatterPlot=null),c={gl:u,position:p.position,glyph:p.text,color:p.textColor,size:p.textSize,angle:p.textAngle,alignment:p.textOffset,font:p.textFont,orthographic:!0,lineWidth:0,project:!1,opacity:t.opacity},this.textLabels=t.hovertext||t.text,-1!==this.mode.indexOf("text")?this.textMarkers?this.textMarkers.update(c):(this.textMarkers=i(c),this.textMarkers._trace=this,this.textMarkers.highlightScale=1,this.scene.glplot.add(this.textMarkers)):this.textMarkers&&(this.scene.glplot.remove(this.textMarkers),this.textMarkers.dispose(),this.textMarkers=null),l={gl:u,position:p.position,color:p.errorColor,error:p.errorBounds,lineWidth:p.errorLineWidth,capSize:p.errorCapSize,opacity:t.opacity},this.errorBars?p.errorBounds?this.errorBars.update(l):(this.scene.glplot.remove(this.errorBars),this.errorBars.dispose(),this.errorBars=null):p.errorBounds&&(this.errorBars=a(l),this.errorBars._trace=this,this.scene.glplot.add(this.errorBars)),p.delaunayAxis>=0){var g=function(t,e,r){var n,i=(r+1)%3,a=(r+2)%3,o=[],l=[];for(n=0;n=0&&h("surfacecolor",f||p);for(var d=["x","y","z"],g=0;g<3;++g){var m="projection."+d[g];h(m+".show")&&(h(m+".opacity"),h(m+".scale"))}var v=n.getComponentMethod("errorbars","supplyDefaults");v(t,e,r,{axis:"z"}),v(t,e,r,{axis:"y",inherit:"z"}),v(t,e,r,{axis:"x",inherit:"z"})}else e.visible=!1}},{"../../lib":684,"../../registry":817,"../scatter/line_defaults":1027,"../scatter/marker_defaults":1033,"../scatter/subtypes":1037,"../scatter/text_defaults":1038,"./attributes":1040}],1045:[function(t,e,r){"use strict";var n={};n.plot=t("./convert"),n.attributes=t("./attributes"),n.markerSymbols=t("../../constants/gl3d_markers"),n.supplyDefaults=t("./defaults"),n.colorbar=t("../scatter/marker_colorbar"),n.calc=t("./calc"),n.moduleType="trace",n.name="scatter3d",n.basePlotModule=t("../../plots/gl3d"),n.categories=["gl3d","symbols","showLegend"],n.meta={},e.exports=n},{"../../constants/gl3d_markers":659,"../../plots/gl3d":774,"../scatter/marker_colorbar":1032,"./attributes":1040,"./calc":1041,"./convert":1043,"./defaults":1044}],1046:[function(t,e,r){"use strict";var n=t("../scatter/attributes"),i=t("../../plots/attributes"),a=t("../../components/colorscale/attributes"),o=t("../../components/colorbar/attributes"),s=t("../../lib/extend").extendFlat,l=n.marker,c=n.line,u=l.line;e.exports={carpet:{valType:"string",editType:"calc"},a:{valType:"data_array",editType:"calc"},b:{valType:"data_array",editType:"calc"},mode:s({},n.mode,{dflt:"markers"}),text:s({},n.text,{}),line:{color:c.color,width:c.width,dash:c.dash,shape:s({},c.shape,{values:["linear","spline"]}),smoothing:c.smoothing,editType:"calc"},connectgaps:n.connectgaps,fill:s({},n.fill,{values:["none","toself","tonext"]}),fillcolor:n.fillcolor,marker:s({symbol:l.symbol,opacity:l.opacity,maxdisplayed:l.maxdisplayed,size:l.size,sizeref:l.sizeref,sizemin:l.sizemin,sizemode:l.sizemode,line:s({width:u.width,editType:"calc"},a("marker.line")),gradient:l.gradient,editType:"calc"},a("marker"),{colorbar:o}),textfont:n.textfont,textposition:n.textposition,selected:n.selected,unselected:n.unselected,hoverinfo:s({},i.hoverinfo,{flags:["a","b","text","name"]}),hoveron:n.hoveron}},{"../../components/colorbar/attributes":559,"../../components/colorscale/attributes":565,"../../lib/extend":673,"../../plots/attributes":729,"../scatter/attributes":1015}],1047:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../scatter/colorscale_calc"),a=t("../scatter/arrays_to_calcdata"),o=t("../scatter/calc_selection"),s=t("../scatter/calc").calcMarkerSize,l=t("../carpet/lookup_carpetid");e.exports=function(t,e){var r=e._carpetTrace=l(t,e);if(r&&r.visible&&"legendonly"!==r.visible){var c;e.xaxis=r.xaxis,e.yaxis=r.yaxis;var u,h,f=e._length,p=new Array(f),d=!1;for(c=0;c"),a}function w(t,e){var r;r=t.labelprefix&&t.labelprefix.length>0?t.labelprefix.replace(/ = $/,""):t._hovertitle,g.push(r+": "+e.toFixed(3)+t.labelsuffix)}}},{"../scatter/hover":1025}],1051:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.colorbar=t("../scatter/marker_colorbar"),n.calc=t("./calc"),n.plot=t("./plot"),n.style=t("../scatter/style").style,n.styleOnSelect=t("../scatter/style").styleOnSelect,n.hoverPoints=t("./hover"),n.selectPoints=t("../scatter/select"),n.eventData=t("./event_data"),n.moduleType="trace",n.name="scattercarpet",n.basePlotModule=t("../../plots/cartesian"),n.categories=["svg","carpet","symbols","showLegend","carpetDependent","zoomScale"],n.meta={},e.exports=n},{"../../plots/cartesian":743,"../scatter/marker_colorbar":1032,"../scatter/select":1035,"../scatter/style":1036,"./attributes":1046,"./calc":1047,"./defaults":1048,"./event_data":1049,"./hover":1050,"./plot":1052}],1052:[function(t,e,r){"use strict";var n=t("../scatter/plot"),i=t("../../plots/cartesian/axes"),a=t("../../components/drawing");e.exports=function(t,e,r,o){var s,l,c,u=r[0][0].carpet,h={xaxis:i.getFromId(t,u.xaxis||"x"),yaxis:i.getFromId(t,u.yaxis||"y"),plot:e.plot};for(n(t,h,r,o),s=0;s")}(u,m,p.mockAxis,c[0].t.labels),[t]}}},{"../../components/fx":600,"../../constants/numerical":661,"../../plots/cartesian/axes":732,"../scatter/fill_hover_text":1022,"../scatter/get_trace_color":1024,"./attributes":1053}],1058:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.colorbar=t("../scatter/marker_colorbar"),n.calc=t("./calc"),n.plot=t("./plot"),n.style=t("./style"),n.styleOnSelect=t("../scatter/style").styleOnSelect,n.hoverPoints=t("./hover"),n.eventData=t("./event_data"),n.selectPoints=t("./select"),n.moduleType="trace",n.name="scattergeo",n.basePlotModule=t("../../plots/geo"),n.categories=["geo","symbols","showLegend","scatter-like"],n.meta={},e.exports=n},{"../../plots/geo":762,"../scatter/marker_colorbar":1032,"../scatter/style":1036,"./attributes":1053,"./calc":1054,"./defaults":1055,"./event_data":1056,"./hover":1057,"./plot":1059,"./select":1060,"./style":1061}],1059:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../lib"),a=t("../../constants/numerical").BADNUM,o=t("../../lib/topojson_utils").getTopojsonFeatures,s=t("../../lib/geo_location_utils").locationToFeature,l=t("../../lib/geojson_utils"),c=t("../scatter/subtypes"),u=t("./style");function h(t,e){var r=t[0].trace;if(Array.isArray(r.locations))for(var n=o(r,e),i=r.locationmode,l=0;ld.TOO_MANY_POINTS?"rect":f.hasMarkers(e)?"rect":"round";if(o&&e.connectgaps){var l=n[0],c=n[1];for(i=0;i1?l[i]:l[0]:l,d=Array.isArray(c)?c.length>1?c[i]:c[0]:c,g=m[p],v=m[d],y=u?u/.8+1:0,x=-v*y-.5*v;o.offset[i]=[g*y/h,x/h]}}return o}}},{"../../components/drawing":583,"../../constants/interactions":660,"../../lib":684,"../../lib/gl_format_color":680,"../../plots/cartesian/axes":732,"../../plots/cartesian/axis_ids":735,"../../registry":817,"../scatter/make_bubble_size_func":1031,"../scatter/subtypes":1037,"./constants":1063,"color-normalize":107,"fast-isnumeric":214,"svg-path-sdf":497}],1065:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../registry"),a=t("./attributes"),o=t("../scatter/constants"),s=t("../scatter/subtypes"),l=t("../scatter/xy_defaults"),c=t("../scatter/marker_defaults"),u=t("../scatter/line_defaults"),h=t("../scatter/fillcolor_defaults"),f=t("../scatter/text_defaults");e.exports=function(t,e,r,p){function d(r,i){return n.coerce(t,e,a,r,i)}var g=!!t.marker&&/-open/.test(t.marker.symbol),m=s.isBubble(t),v=l(t,e,p,d);if(v){var y=v1&&u.extendFlat(o.line,_.linePositions(t,r,n)),o.errorX||o.errorY){var s=_.errorBarPositions(t,r,n,i,a);o.errorX&&u.extendFlat(o.errorX,s.x),o.errorY&&u.extendFlat(o.errorY,s.y)}return o.text&&(u.extendFlat(o.text,{positions:n},_.textPosition(t,r,o.text,o.marker)),u.extendFlat(o.textSel,{positions:n},_.textPosition(t,r,o.text,o.markerSel)),u.extendFlat(o.textUnsel,{positions:n},_.textPosition(t,r,o.text,o.markerUnsel))),o}function T(t,e){var r=e._scene,n={count:0,dirty:!0,lineOptions:[],fillOptions:[],markerOptions:[],markerSelectedOptions:[],markerUnselectedOptions:[],errorXOptions:[],errorYOptions:[],textOptions:[],textSelectedOptions:[],textUnselectedOptions:[]},i={selectBatch:null,unselectBatch:null,fill2d:!1,scatter2d:!1,error2d:!1,line2d:!1,glText:!1,select2d:null};return e._scene||((r=e._scene={}).init=function(){u.extendFlat(r,i,n)},r.init(),r.update=function(t){var e,n=new Array(r.count);for(e=0;e=k&&(M.marker.cluster=p.tree),S.lineOptions.push(M.line),S.errorXOptions.push(M.errorX),S.errorYOptions.push(M.errorY),S.fillOptions.push(M.fill),S.markerOptions.push(M.marker),S.markerSelectedOptions.push(M.markerSel),S.markerUnselectedOptions.push(M.markerUnsel),S.textOptions.push(M.text),S.textSelectedOptions.push(M.textSel),S.textUnselectedOptions.push(M.textUnsel),S.count++,p._scene=S,p.index=S.count-1,p.x=d,p.y=y,p.positions=x,p.count=u,t.firstscatter=!1,[{x:!1,y:!1,t:p,trace:e}]},plot:function(t,e,r){if(r.length){var o,s=t._fullLayout,c=r[0][0].t._scene,p=s.dragmode;if(c){var d=s._size,g=s.width,m=s.height;if(h(t,["ANGLE_instanced_arrays","OES_element_index_uint"])){var v=s._glcanvas.data()[0].regl;if(y(t,e,r),c.dirty){if(!0===c.error2d&&(c.error2d=a(v)),!0===c.line2d&&(c.line2d=i(v)),!0===c.scatter2d&&(c.scatter2d=n(v)),!0===c.fill2d&&(c.fill2d=i(v)),!0===c.glText)for(c.glText=new Array(c.count),o=0;o=0?Math.floor((e+180)/360):Math.ceil((e-180)/360)),d=e-p;if(n.getClosest(l,function(t){var e=t.lonlat;if(e[0]===s)return 1/0;var n=i.wrap180(e[0]),a=e[1],o=f.project([n,a]),l=o.x-u.c2p([d,a]),c=o.y-h.c2p([n,r]),p=Math.max(3,t.mrc||0);return Math.max(Math.sqrt(l*l+c*c)-p,1-3/p)},t),!1!==t.index){var g=l[t.index],m=g.lonlat,v=[i.wrap180(m[0])+p,m[1]],y=u.c2p(v),x=h.c2p(v),b=g.mrc||1;return t.x0=y-b,t.x1=y+b,t.y0=x-b,t.y1=x+b,t.color=a(c,g),t.extraText=function(t,e,r){var n=(e.hi||t.hoverinfo).split("+"),i=-1!==n.indexOf("all"),a=-1!==n.indexOf("lon"),s=-1!==n.indexOf("lat"),l=e.lonlat,c=[];function u(t){return t+"\xb0"}i||a&&s?c.push("("+u(l[0])+", "+u(l[1])+")"):a?c.push(r.lon+u(l[0])):s&&c.push(r.lat+u(l[1]));(i||-1!==n.indexOf("text"))&&o(e,t,c);return c.join("
")}(c,g,l[0].t.labels),[t]}}},{"../../components/fx":600,"../../constants/numerical":661,"../../lib":684,"../scatter/fill_hover_text":1022,"../scatter/get_trace_color":1024}],1072:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.colorbar=t("../scatter/marker_colorbar"),n.calc=t("../scattergeo/calc"),n.plot=t("./plot"),n.hoverPoints=t("./hover"),n.eventData=t("./event_data"),n.selectPoints=t("./select"),n.style=function(t,e){e&&e[0].trace._glTrace.update(e)},n.moduleType="trace",n.name="scattermapbox",n.basePlotModule=t("../../plots/mapbox"),n.categories=["mapbox","gl","symbols","showLegend","scatterlike"],n.meta={},e.exports=n},{"../../plots/mapbox":789,"../scatter/marker_colorbar":1032,"../scattergeo/calc":1054,"./attributes":1067,"./defaults":1069,"./event_data":1070,"./hover":1071,"./plot":1073,"./select":1074}],1073:[function(t,e,r){"use strict";var n=t("./convert");function i(t,e){this.subplot=t,this.uid=e,this.sourceIds={fill:e+"-source-fill",line:e+"-source-line",circle:e+"-source-circle",symbol:e+"-source-symbol"},this.layerIds={fill:e+"-layer-fill",line:e+"-layer-line",circle:e+"-layer-circle",symbol:e+"-layer-symbol"},this.order=["fill","line","circle","symbol"]}var a=i.prototype;a.addSource=function(t,e){this.subplot.map.addSource(this.sourceIds[t],{type:"geojson",data:e.geojson})},a.setSourceData=function(t,e){this.subplot.map.getSource(this.sourceIds[t]).setData(e.geojson)},a.addLayer=function(t,e){this.subplot.map.addLayer({type:t,id:this.layerIds[t],source:this.sourceIds[t],layout:e.layout,paint:e.paint})},a.update=function(t){for(var e=this.subplot,r=n(t),i=0;i")}e.exports={hoverPoints:function(t,e,r,i){var a=n(t,e,r,i);if(a&&!1!==a[0].index){var s=a[0];if(void 0===s.index)return a;var l=t.subplot,c=s.cd[s.index],u=s.trace;if(l.isPtWithinSector(c))return s.xLabelVal=void 0,s.yLabelVal=void 0,s.extraText=o(c,u,l),a}},makeHoverPointText:o}},{"../../lib":684,"../../plots/cartesian/axes":732,"../scatter/hover":1025}],1079:[function(t,e,r){"use strict";e.exports={moduleType:"trace",name:"scatterpolar",basePlotModule:t("../../plots/polar"),categories:["polar","symbols","showLegend","scatter-like"],attributes:t("./attributes"),supplyDefaults:t("./defaults"),colorbar:t("../scatter/marker_colorbar"),calc:t("./calc"),plot:t("./plot"),style:t("../scatter/style").style,hoverPoints:t("./hover").hoverPoints,selectPoints:t("../scatter/select"),meta:{}}},{"../../plots/polar":798,"../scatter/marker_colorbar":1032,"../scatter/select":1035,"../scatter/style":1036,"./attributes":1075,"./calc":1076,"./defaults":1077,"./hover":1078,"./plot":1080}],1080:[function(t,e,r){"use strict";var n=t("../scatter/plot"),i=t("../../constants/numerical").BADNUM;e.exports=function(t,e,r){var a,o,s,l={xaxis:e.xaxis,yaxis:e.yaxis,plot:e.framework,layerClipId:e._hasClipOnAxisFalse?e.clipIds.forTraces:null},c=e.radialAxis,u=c.range;for(s=u[0]>u[1]?function(t){return t<=0}:function(t){return t>=0},a=0;a=0?(m=o.c2r(g)-l[0],T=v,y=s.c2rad(T,b.thetaunit),C[d]=E[2*d]=m*Math.cos(y),L[d]=E[2*d+1]=m*Math.sin(y)):C[d]=L[d]=E[2*d]=E[2*d+1]=NaN;var z=a.sceneOptions(t,e,b,E);z.fill&&!h.fill2d&&(h.fill2d=!0),z.marker&&!h.scatter2d&&(h.scatter2d=!0),z.line&&!h.line2d&&(h.line2d=!0),!z.errorX&&!z.errorY||h.error2d||(h.error2d=!0),_.tree=n(E),z.marker&&S>=u&&(z.marker.cluster=_.tree),c.hasMarkers(b)&&(z.markerSel.positions=z.markerUnsel.positions=z.marker.positions),h.lineOptions.push(z.line),h.errorXOptions.push(z.errorX),h.errorYOptions.push(z.errorY),h.fillOptions.push(z.fill),h.markerOptions.push(z.marker),h.markerSelectedOptions.push(z.markerSel),h.markerUnselectedOptions.push(z.markerUnsel),h.count=r.length,_._scene=h,_.index=p,_.x=C,_.y=L,_.rawx=C,_.rawy=L,_.r=w,_.theta=k,_.positions=E,_.count=S}}),a.plot(t,e,r)},hoverPoints:function(t,e,r,n){var i=t.cd[0].t,o=i.r,s=i.theta,c=a.hoverPoints(t,e,r,n);if(c&&!1!==c[0].index){var u=c[0];if(void 0===u.index)return c;var h=t.subplot,f=h.angularAxis,p=u.cd[u.index],d=u.trace;if(p.r=o[u.index],p.theta=s[u.index],p.rad=f.c2rad(p.theta,d.thetaunit),h.isPtWithinSector(p))return u.xLabelVal=void 0,u.yLabelVal=void 0,u.extraText=l(p,d,h),c}},style:a.style,selectPoints:a.selectPoints,meta:{}}},{"../../plots/cartesian/axes":732,"../../plots/polar":798,"../scatter/colorscale_calc":1019,"../scatter/marker_colorbar":1032,"../scatter/subtypes":1037,"../scattergl":1066,"../scattergl/constants":1063,"../scatterpolar/hover":1078,"./attributes":1081,"./defaults":1082,"fast-isnumeric":214,"point-cluster":436}],1084:[function(t,e,r){"use strict";var n=t("../scatter/attributes"),i=t("../../plots/attributes"),a=t("../../components/colorscale/attributes"),o=t("../../components/colorbar/attributes"),s=t("../../components/drawing/attributes").dash,l=t("../../lib/extend").extendFlat,c=n.marker,u=n.line,h=c.line;e.exports={a:{valType:"data_array",editType:"calc"},b:{valType:"data_array",editType:"calc"},c:{valType:"data_array",editType:"calc"},sum:{valType:"number",dflt:0,min:0,editType:"calc"},mode:l({},n.mode,{dflt:"markers"}),text:l({},n.text,{}),hovertext:l({},n.hovertext,{}),line:{color:u.color,width:u.width,dash:s,shape:l({},u.shape,{values:["linear","spline"]}),smoothing:u.smoothing,editType:"calc"},connectgaps:n.connectgaps,cliponaxis:n.cliponaxis,fill:l({},n.fill,{values:["none","toself","tonext"]}),fillcolor:n.fillcolor,marker:l({symbol:c.symbol,opacity:c.opacity,maxdisplayed:c.maxdisplayed,size:c.size,sizeref:c.sizeref,sizemin:c.sizemin,sizemode:c.sizemode,line:l({width:h.width,editType:"calc"},a("marker.line")),gradient:c.gradient,editType:"calc"},a("marker"),{colorbar:o}),textfont:n.textfont,textposition:n.textposition,selected:n.selected,unselected:n.unselected,hoverinfo:l({},i.hoverinfo,{flags:["a","b","c","text","name"]}),hoveron:n.hoveron}},{"../../components/colorbar/attributes":559,"../../components/colorscale/attributes":565,"../../components/drawing/attributes":582,"../../lib/extend":673,"../../plots/attributes":729,"../scatter/attributes":1015}],1085:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../scatter/colorscale_calc"),a=t("../scatter/arrays_to_calcdata"),o=t("../scatter/calc_selection"),s=t("../scatter/calc").calcMarkerSize,l=["a","b","c"],c={a:["b","c"],b:["a","c"],c:["a","b"]};e.exports=function(t,e){var r,u,h,f,p,d,g=t._fullLayout[e.subplot].sum,m=e.sum||g,v={a:e.a,b:e.b,c:e.c};for(r=0;r"),o}function v(t,e){m.push(t._hovertitle+": "+i.tickText(t,e,"hover").text)}}},{"../../plots/cartesian/axes":732,"../scatter/hover":1025}],1089:[function(t,e,r){"use strict";var n={};n.attributes=t("./attributes"),n.supplyDefaults=t("./defaults"),n.colorbar=t("../scatter/marker_colorbar"),n.calc=t("./calc"),n.plot=t("./plot"),n.style=t("../scatter/style").style,n.styleOnSelect=t("../scatter/style").styleOnSelect,n.hoverPoints=t("./hover"),n.selectPoints=t("../scatter/select"),n.eventData=t("./event_data"),n.moduleType="trace",n.name="scatterternary",n.basePlotModule=t("../../plots/ternary"),n.categories=["ternary","symbols","showLegend","scatter-like"],n.meta={},e.exports=n},{"../../plots/ternary":810,"../scatter/marker_colorbar":1032,"../scatter/select":1035,"../scatter/style":1036,"./attributes":1084,"./calc":1085,"./defaults":1086,"./event_data":1087,"./hover":1088,"./plot":1090}],1090:[function(t,e,r){"use strict";var n=t("../scatter/plot");e.exports=function(t,e,r){var i=e.plotContainer;i.select(".scatterlayer").selectAll("*").remove();var a={xaxis:e.xaxis,yaxis:e.yaxis,plot:i,layerClipId:e._hasClipOnAxisFalse?e.clipIdRelative:null},o=e.layers.frontplot.select("g.scatterlayer");n(t,a,r,o)}},{"../scatter/plot":1034}],1091:[function(t,e,r){"use strict";var n=t("../scattergl/attributes"),i=t("../../plots/cartesian/constants").idRegex,a=t("../../plot_api/plot_template").templatedArray;function o(t){return{valType:"info_array",freeLength:!0,editType:"calc",items:{valType:"subplotid",regex:i[t],editType:"plot"}}}e.exports={dimensions:a("dimension",{visible:{valType:"boolean",dflt:!0,editType:"calc"},label:{valType:"string",editType:"calc"},values:{valType:"data_array",editType:"calc+clearAxisTypes"},editType:"calc+clearAxisTypes"}),text:n.text,marker:n.marker,xaxes:o("x"),yaxes:o("y"),diagonal:{visible:{valType:"boolean",dflt:!0,editType:"calc"},editType:"calc"},showupperhalf:{valType:"boolean",dflt:!0,editType:"calc"},showlowerhalf:{valType:"boolean",dflt:!0,editType:"calc"},selected:{marker:n.selected.marker,editType:"calc"},unselected:{marker:n.unselected.marker,editType:"calc"},opacity:n.opacity}},{"../../plot_api/plot_template":722,"../../plots/cartesian/constants":737,"../scattergl/attributes":1062}],1092:[function(t,e,r){"use strict";var n=t("regl-line2d"),i=t("../../registry"),a=t("../../lib"),o=t("../../lib/prepare_regl"),s=t("../../plots/get_data").getModuleCalcData,l=t("../../plots/cartesian"),c=t("../../plots/cartesian/axis_ids"),u="splom";function h(t,e,r){for(var n=e.dimensions,i=r.matrixOptions.data.length,a=new Array(i),o=0,s=0;o1&&ra&&l?r._splomSubplots[y]=1:iv;for(r=0,n=0;r2?t.slice(1,e-1):2===e?[(t[0]+t[1])/2]:t}function p(t){var e=t.length;return 1===e?[.5,.5]:[t[1]-t[0],t[e-1]-t[e-2]]}function d(t,e){var r=t.fullSceneLayout,i=t.dataScale,c=e._len,u={};function d(t,e){var n=r[e],o=i[l[e]];return a.simpleMap(t,function(t){return n.d2l(t)*o})}u.vectors=s(d(e.u,"xaxis"),d(e.v,"yaxis"),d(e.w,"zaxis"),c);var g=h(e.x.slice(0,c)),m=h(e.y.slice(0,c)),v=h(e.z.slice(0,c));if(g.length*m.length*v.length>c)return{positions:[],cells:[]};var y=d(g,"xaxis"),x=d(m,"yaxis"),b=d(v,"zaxis");if(u.meshgrid=[y,x,b],e.starts){var _=e._slen;u.startingPositions=s(d(e.starts.x.slice(0,_),"xaxis"),d(e.starts.y.slice(0,_),"yaxis"),d(e.starts.z.slice(0,_),"zaxis"))}else{for(var w=x[0],k=f(y),M=f(b),A=new Array(k.length*M.length),T=0,S=0;S",maxDimensionCount:60,overdrag:45,releaseTransitionDuration:120,releaseTransitionEase:"cubic-out",scrollbarCaptureWidth:18,scrollbarHideDelay:1e3,scrollbarHideDuration:1e3,scrollbarOffset:5,scrollbarWidth:8,transitionDuration:100,transitionEase:"cubic-out",uplift:5,wrapSpacer:" ",wrapSplitCharacter:" ",cn:{table:"table",tableControlView:"table-control-view",scrollBackground:"scroll-background",yColumn:"y-column",columnBlock:"column-block",scrollAreaClip:"scroll-area-clip",scrollAreaClipRect:"scroll-area-clip-rect",columnBoundary:"column-boundary",columnBoundaryClippath:"column-boundary-clippath",columnBoundaryRect:"column-boundary-rect",columnCells:"column-cells",columnCell:"column-cell",cellRect:"cell-rect",cellText:"cell-text",cellTextHolder:"cell-text-holder",scrollbarKit:"scrollbar-kit",scrollbar:"scrollbar",scrollbarSlider:"scrollbar-slider",scrollbarGlyph:"scrollbar-glyph",scrollbarCaptureZone:"scrollbar-capture-zone"}}},{}],1109:[function(t,e,r){"use strict";var n=t("./constants"),i=t("../../lib/extend").extendFlat,a=t("fast-isnumeric");function o(t){if(Array.isArray(t)){for(var e=0,r=0;r=e||c===t.length-1)&&(n[i]=o,o.key=l++,o.firstRowIndex=s,o.lastRowIndex=c,o={firstRowIndex:null,lastRowIndex:null,rows:[]},i+=a,s=c+1,a=0);return n}e.exports=function(t,e){var r=l(e.cells.values),p=function(t){return t.slice(e.header.values.length,t.length)},d=l(e.header.values);d.length&&!d[0].length&&(d[0]=[""],d=l(d));var g=d.concat(p(r).map(function(){return c((d[0]||[""]).length)})),m=e.domain,v=Math.floor(t._fullLayout._size.w*(m.x[1]-m.x[0])),y=Math.floor(t._fullLayout._size.h*(m.y[1]-m.y[0])),x=e.header.values.length?g[0].map(function(){return e.header.height}):[n.emptyHeaderHeight],b=r.length?r[0].map(function(){return e.cells.height}):[],_=x.reduce(s,0),w=f(b,y-_+n.uplift),k=h(f(x,_),[]),M=h(w,k),A={},T=e._fullInput.columnorder.concat(p(r.map(function(t,e){return e}))),S=g.map(function(t,r){var n=Array.isArray(e.columnwidth)?e.columnwidth[Math.min(r,e.columnwidth.length-1)]:e.columnwidth;return a(n)?Number(n):1}),E=S.reduce(s,0);S=S.map(function(t){return t/E*v});var C=Math.max(o(e.header.line.width),o(e.cells.line.width)),L={key:e.index,translateX:m.x[0]*t._fullLayout._size.w,translateY:t._fullLayout._size.h*(1-m.y[1]),size:t._fullLayout._size,width:v,maxLineWidth:C,height:y,columnOrder:T,groupHeight:y,rowBlocks:M,headerRowBlocks:k,scrollY:0,cells:i({},e.cells,{values:r}),headerCells:i({},e.header,{values:g}),gdColumns:g.map(function(t){return t[0]}),gdColumnsOriginalOrder:g.map(function(t){return t[0]}),prevPages:[0,0],scrollbarState:{scrollbarScrollInProgress:!1},columns:g.map(function(t,e){var r=A[t];return A[t]=(r||0)+1,{key:t+"__"+A[t],label:t,specIndex:e,xIndex:T[e],xScale:u,x:void 0,calcdata:void 0,columnWidth:S[e]}})};return L.columns.forEach(function(t){t.calcdata=L,t.x=u(t)}),L}},{"../../lib/extend":673,"./constants":1108,"fast-isnumeric":214}],1110:[function(t,e,r){"use strict";var n=t("../../lib/extend").extendFlat;r.splitToPanels=function(t){var e=[0,0],r=n({},t,{key:"header",type:"header",page:0,prevPages:e,currentRepaint:[null,null],dragHandle:!0,values:t.calcdata.headerCells.values[t.specIndex],rowBlocks:t.calcdata.headerRowBlocks,calcdata:n({},t.calcdata,{cells:t.calcdata.headerCells})});return[n({},t,{key:"cells1",type:"cells",page:0,prevPages:e,currentRepaint:[null,null],dragHandle:!1,values:t.calcdata.cells.values[t.specIndex],rowBlocks:t.calcdata.rowBlocks}),n({},t,{key:"cells2",type:"cells",page:1,prevPages:e,currentRepaint:[null,null],dragHandle:!1,values:t.calcdata.cells.values[t.specIndex],rowBlocks:t.calcdata.rowBlocks}),r]},r.splitToCells=function(t){var e=function(t){var e=t.rowBlocks[t.page],r=e?e.rows[0].rowIndex:0,n=e?r+e.rows.length:0;return[r,n]}(t);return(t.values||[]).slice(e[0],e[1]).map(function(r,n){return{keyWithinBlock:n+("string"==typeof r&&r.match(/[<$&> ]/)?"_keybuster_"+Math.random():""),key:e[0]+n,column:t,calcdata:t.calcdata,page:t.page,rowBlocks:t.rowBlocks,value:r}})}},{"../../lib/extend":673}],1111:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("./attributes"),a=t("../../plots/domain").defaults;e.exports=function(t,e,r,o){function s(r,a){return n.coerce(t,e,i,r,a)}a(e,o,s),s("columnwidth"),s("header.values"),s("header.format"),s("header.align"),s("header.prefix"),s("header.suffix"),s("header.height"),s("header.line.width"),s("header.line.color"),s("header.fill.color"),n.coerceFont(s,"header.font",n.extendFlat({},o.font)),function(t,e){for(var r=t.columnorder||[],n=t.header.values.length,i=r.slice(0,n),a=i.slice().sort(function(t,e){return t-e}),o=i.map(function(t){return a.indexOf(t)}),s=o.length;s/i),l=!o||s;t.mayHaveMarkup=o&&a.match(/[<&>]/);var c,u="string"==typeof(c=a)&&c.match(n.latexCheck);t.latex=u;var h,f,p=u?"":_(t.calcdata.cells.prefix,e,r)||"",d=u?"":_(t.calcdata.cells.suffix,e,r)||"",g=u?null:_(t.calcdata.cells.format,e,r)||null,m=p+(g?i.format(g)(t.value):t.value)+d;if(t.wrappingNeeded=!t.wrapped&&!l&&!u&&(h=b(m)),t.cellHeightMayIncrease=s||u||t.mayHaveMarkup||(void 0===h?b(m):h),t.needsConvertToTspans=t.mayHaveMarkup||t.wrappingNeeded||t.latex,t.wrappingNeeded){var v=(" "===n.wrapSplitCharacter?m.replace(/
i&&n.push(a),i+=l}return n}(i,l,s);1===c.length&&(c[0]===i.length-1?c.unshift(c[0]-1):c.push(c[0]+1)),c[0]%2&&c.reverse(),e.each(function(t,e){t.page=c[e],t.scrollY=l}),e.attr("transform",function(t){return"translate(0 "+(I(t.rowBlocks,t.page)-t.scrollY)+")"}),t&&(E(t,r,e,c,n.prevPages,n,0),E(t,r,e,c,n.prevPages,n,1),v(r,t))}}function S(t,e,r,a){return function(o){var s=o.calcdata?o.calcdata:o,l=e.filter(function(t){return s.key===t.key}),c=r||s.scrollbarState.dragMultiplier;s.scrollY=void 0===a?s.scrollY+c*i.event.dy:a;var u=l.selectAll("."+n.cn.yColumn).selectAll("."+n.cn.columnBlock).filter(k);T(t,u,l)}}function E(t,e,r,n,i,a,o){n[o]!==i[o]&&(clearTimeout(a.currentRepaint[o]),a.currentRepaint[o]=setTimeout(function(){var a=r.filter(function(t,e){return e===o&&n[e]!==i[e]});y(t,e,a,r),i[o]=n[o]}))}function C(t,e,r){return function(){var a=i.select(e.parentNode);a.each(function(t){var e=t.fragments;a.selectAll("tspan.line").each(function(t,r){e[r].width=this.getComputedTextLength()});var r,i,o=e[e.length-1].width,s=e.slice(0,-1),l=[],c=0,u=t.column.columnWidth-2*n.cellPad;for(t.value="";s.length;)c+(i=(r=s.shift()).width+o)>u&&(t.value+=l.join(n.wrapSpacer)+n.lineBreaker,l=[],c=0),l.push(r.text),c+=i;c&&(t.value+=l.join(n.wrapSpacer)),t.wrapped=!0}),a.selectAll("tspan.line").remove(),x(a.select("."+n.cn.cellText),r,t),i.select(e.parentNode.parentNode).call(P)}}function L(t,e,r,a,o){return function(){if(!o.settledY){var s=i.select(e.parentNode),l=R(o),c=o.key-l.firstRowIndex,u=l.rows[c].rowHeight,h=o.cellHeightMayIncrease?e.parentNode.getBoundingClientRect().height+2*n.cellPad:u,f=Math.max(h,u);f-l.rows[c].rowHeight&&(l.rows[c].rowHeight=f,t.selectAll("."+n.cn.columnCell).call(P),T(null,t.filter(k),0),v(r,a,!0)),s.attr("transform",function(){var t=this.parentNode.getBoundingClientRect(),e=i.select(this.parentNode).select("."+n.cn.cellRect).node().getBoundingClientRect(),r=this.transform.baseVal.consolidate(),a=e.top-t.top+(r?r.matrix.f:n.cellPad);return"translate("+z(o,i.select(this.parentNode).select("."+n.cn.cellTextHolder).node().getBoundingClientRect().width)+" "+a+")"}),o.settledY=!0}}}function z(t,e){switch(t.align){case"left":return n.cellPad;case"right":return t.column.columnWidth-(e||0)-n.cellPad;case"center":return(t.column.columnWidth-(e||0))/2;default:return n.cellPad}}function P(t){t.attr("transform",function(t){var e=t.rowBlocks[0].auxiliaryBlocks.reduce(function(t,e){return t+O(e,1/0)},0);return"translate(0 "+(O(R(t),t.key)+e)+")"}).selectAll("."+n.cn.cellRect).attr("height",function(t){return(e=R(t),r=t.key,e.rows[r-e.firstRowIndex]).rowHeight;var e,r})}function I(t,e){for(var r=0,n=e-1;n>=0;n--)r+=D(t[n]);return r}function O(t,e){for(var r=0,n=0;n0){var y,x,b,_,w,k=t.xa,M=t.ya;"h"===f.orientation?(w=e,y="y",b=M,x="x",_=k):(w=r,y="x",b=k,x="y",_=M);var A=h[t.index];if(w>=A.span[0]&&w<=A.span[1]){var T=n.extendFlat({},t),S=_.c2p(w,!0),E=o.getKdeValue(A,f,w),C=o.getPositionOnKdePath(A,f,S),L=b._offset,z=b._length;T[y+"0"]=C[0],T[y+"1"]=C[1],T[x+"0"]=T[x+"1"]=S,T[x+"Label"]=x+": "+i.hoverLabelText(_,w)+", "+h[0].t.labels.kde+" "+E.toFixed(3),T.spikeDistance=v[0].spikeDistance;var P=y+"Spike";T[P]=v[0][P],v[0].spikeDistance=void 0,v[0][P]=void 0,m.push(T),(u={stroke:t.color})[y+"1"]=n.constrain(L+C[0],L,L+z),u[y+"2"]=n.constrain(L+C[1],L,L+z),u[x+"1"]=u[x+"2"]=_._offset+S}}}-1!==p.indexOf("points")&&(c=a.hoverOnPoints(t,e,r));var I=l.selectAll(".violinline-"+f.uid).data(u?[0]:[]);return I.enter().append("line").classed("violinline-"+f.uid,!0).attr("stroke-width",1.5),I.exit().remove(),I.attr(u),"closest"===s?c?[c]:m:c?(m.push(c),m):m}},{"../../lib":684,"../../plots/cartesian/axes":732,"../box/hover":843,"./helpers":1117}],1119:[function(t,e,r){"use strict";e.exports={attributes:t("./attributes"),layoutAttributes:t("./layout_attributes"),supplyDefaults:t("./defaults"),supplyLayoutDefaults:t("./layout_defaults"),calc:t("./calc"),setPositions:t("./set_positions"),plot:t("./plot"),style:t("./style"),styleOnSelect:t("../scatter/style").styleOnSelect,hoverPoints:t("./hover"),selectPoints:t("../box/select"),moduleType:"trace",name:"violin",basePlotModule:t("../../plots/cartesian"),categories:["cartesian","svg","symbols","oriented","box-violin","showLegend","violinLayout","zoomScale"],meta:{}}},{"../../plots/cartesian":743,"../box/select":848,"../scatter/style":1036,"./attributes":1114,"./calc":1115,"./defaults":1116,"./hover":1118,"./layout_attributes":1120,"./layout_defaults":1121,"./plot":1122,"./set_positions":1123,"./style":1124}],1120:[function(t,e,r){"use strict";var n=t("../box/layout_attributes"),i=t("../../lib").extendFlat;e.exports={violinmode:i({},n.boxmode,{}),violingap:i({},n.boxgap,{}),violingroupgap:i({},n.boxgroupgap,{})}},{"../../lib":684,"../box/layout_attributes":845}],1121:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("./layout_attributes"),a=t("../box/layout_defaults");e.exports=function(t,e,r){a._supply(t,e,r,function(r,a){return n.coerce(t,e,i,r,a)},"violin")}},{"../../lib":684,"../box/layout_defaults":846,"./layout_attributes":1120}],1122:[function(t,e,r){"use strict";var n=t("d3"),i=t("../../lib"),a=t("../../components/drawing"),o=t("../box/plot"),s=t("../scatter/line_points"),l=t("./helpers");e.exports=function(t,e,r,c){var u=t._fullLayout,h=e.xaxis,f=e.yaxis;function p(t){var e=s(t,{xaxis:h,yaxis:f,connectGaps:!0,baseTolerance:.75,shape:"spline",simplify:!0});return a.smoothopen(e[0],1)}var d=c.selectAll("g.trace.violins").data(r,function(t){return t[0].trace.uid});d.enter().append("g").attr("class","trace violins"),d.exit().remove(),d.order(),d.each(function(t){var r=t[0],a=r.t,s=r.trace,c=n.select(this);e.isRangePlot||(r.node3=c);var d=u._numViolins,g="group"===u.violinmode&&d>1,m=1-u.violingap,v=a.bdPos=a.dPos*m*(1-u.violingroupgap)/(g?d:1),y=a.bPos=g?2*a.dPos*((a.num+.5)/d-.5)*m:0;if(a.wHover=a.dPos*(g?m/d:1),!0!==s.visible||a.empty)n.select(this).remove();else{var x=e[a.valLetter+"axis"],b=e[a.posLetter+"axis"],_="both"===s.side,w=_||"positive"===s.side,k=_||"negative"===s.side,M=u._violinScaleGroupStats[s.scalegroup],A=c.selectAll("path.violin").data(i.identity);A.enter().append("path").style("vector-effect","non-scaling-stroke").attr("class","violin"),A.exit().remove(),A.each(function(t){var e,r,i,o,l,c,u,h,f=n.select(this),d=t.density,g=d.length,m=t.pos+y,A=b.c2p(m);switch(s.scalemode){case"width":e=M.maxWidth/v;break;case"count":e=M.maxWidth/v*(M.maxCount/t.pts.length)}if(w){for(u=new Array(g),l=0;la&&(a=u,o=c)}}return a?i(o):s};case"rms":return function(t,e){for(var r=0,a=0,o=0;o":return function(t){return f(t)>s};case">=":return function(t){return f(t)>=s};case"[]":return function(t){var e=f(t);return e>=s[0]&&e<=s[1]};case"()":return function(t){var e=f(t);return e>s[0]&&e=s[0]&&es[0]&&e<=s[1]};case"][":return function(t){var e=f(t);return e<=s[0]||e>=s[1]};case")(":return function(t){var e=f(t);return es[1]};case"](":return function(t){var e=f(t);return e<=s[0]||e>s[1]};case")[":return function(t){var e=f(t);return e=s[1]};case"{}":return function(t){return-1!==s.indexOf(f(t))};case"}{":return function(t){return-1===s.indexOf(f(t))}}}(r,a.getDataToCoordFunc(t,e,s,i),f),x={},b={},_=0;d?(m=function(t){x[t.astr]=n.extendDeep([],t.get()),t.set(new Array(h))},v=function(t,e){var r=x[t.astr][e];t.get()[e]=r}):(m=function(t){x[t.astr]=n.extendDeep([],t.get()),t.set([])},v=function(t,e){var r=x[t.astr][e];t.get().push(r)}),M(m);for(var w=o(e.transforms,r),k=0;k1?"%{group} (%{trace})":"%{group}");var l=t.styles,c=o.styles=[];if(l)for(a=0;a + + + + File Not Found + + + +

Some yahoo probably stole your data??!

+ + \ No newline at end of file diff --git a/calbridgesensors/templates/base.html b/calbridgesensors/templates/base.html new file mode 100644 index 0000000..ac2a13f --- /dev/null +++ b/calbridgesensors/templates/base.html @@ -0,0 +1,176 @@ + + +{% load static %} + + + Cal Bridge Sensors + + + + + {% block header %} +
+ {% endblock %} + + + {% block alert %} + {% endblock %} + + + {% block content %} + {% endblock %} + + \ No newline at end of file diff --git a/calbridgesensors/templates/home.html b/calbridgesensors/templates/home.html new file mode 100644 index 0000000..75b327a --- /dev/null +++ b/calbridgesensors/templates/home.html @@ -0,0 +1,64 @@ + + +{% load static %} + + + Cal Bridge Sensors + + + +{% block content %} +

Bridge Settlement

+
+ {% if user.is_authenticated %} +
  • Manage
  • + {% else %} +
  • Log In
  • + {% endif %} +
  • Admin
  • +
    +{% endblock %} + \ No newline at end of file diff --git a/calbridgesensors/templates/registration/login.html b/calbridgesensors/templates/registration/login.html new file mode 100644 index 0000000..aff6191 --- /dev/null +++ b/calbridgesensors/templates/registration/login.html @@ -0,0 +1,38 @@ +{% extends "base.html" %} + +{% block content %} + +{% if form.errors %} +

    Your username and password didn't match. Please try again.

    +{% endif %} + +{% if next %} + {% if user.is_authenticated %} +

    Your account doesn't have access to this page. To proceed, + please login with an account that has access.

    + {% else %} +

    Please login to see this page.

    + {% endif %} +{% endif %} + +
    +{% csrf_token %} + + + + + + + + + +
    {{ form.username.label_tag }}{{ form.username }}
    {{ form.password.label_tag }}{{ form.password }}
    + + + +
    + +{# Assumes you setup the password_reset view in your URLconf #} +

    Lost password?

    + +{% endblock %} \ No newline at end of file diff --git a/calbridgesensors/templates/sensors/detail.html b/calbridgesensors/templates/sensors/detail.html new file mode 100644 index 0000000..fbd7576 --- /dev/null +++ b/calbridgesensors/templates/sensors/detail.html @@ -0,0 +1,125 @@ +{% extends 'base.html' %} + +{% block content %} +
    +
      +
    • Bridge Name
    • +
    • Bridge reading x
    • +
    • Bridge reading y
    • +
    • Broken Record
    • +
    • Repair Record
    • +
    +
    +
      +
    • {{ bridge.name }}
    • + {% if reading %} + + + + + {% else %} +
    • {{ 0.0 }}
    • +
    • {{ 0.0 }}
    • + {% endif %} + + {% if damage_recs %} + + {% else %} +
    • No Damages
    • + {% endif %} + + {% if repair_recs %} + + {% else %} +
    • No Repairs
    • + {% endif %} +
    +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/calbridgesensors/templates/sensors/index.html b/calbridgesensors/templates/sensors/index.html new file mode 100644 index 0000000..d99b195 --- /dev/null +++ b/calbridgesensors/templates/sensors/index.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} +{% load sensors_filters %} + +{% block alert %} +
    + {% if broken_bridges %} +

    Bridge In Danger!

    + {% for bb in broken_bridges %} +
  • {{ bb.bridge }}
  • +
  • Time broken: {{ bb.broken_time }}
  • + {% endfor %} + {% else %} +

    All Bridges Are Healthy

    + {% endif %} +
    +{% endblock %} + +{% block content %} +
    + + +
    +{% endblock %} \ No newline at end of file diff --git a/calib3/Calibration_DX.xlsx b/calib3/Calibration_DX.xlsx new file mode 100755 index 0000000..268ac9d Binary files /dev/null and b/calib3/Calibration_DX.xlsx differ diff --git a/calib4/Calibration_DX.csv b/calib4/Calibration_DX.csv new file mode 100755 index 0000000..3719877 --- /dev/null +++ b/calib4/Calibration_DX.csv @@ -0,0 +1 @@ +"Camera module mounted on Albert's calibration mount, bolted to grid board. Grid board is not fixed to table. Table will not be moved due to impracticality of moving table." Laser module is mounted to rails. Distance between camera and laser can be changed. Rail and centerline of camera mount are aligned with laser "Imprecision in laesr mount and rail installation are significant in location of crosshairs. At beginning of each DX iteration, we will change location of camera module to capture crosshairs. " Rotation of either module is not changed. Independent variable: Distance between modules "Camera not of concern" "Accelerometer axes are: x facing other module, z vertical, y accordingly determined" DX Img file Phone deg (mount slab) Novo 1 [in] Novo 2 [in] Novo 3 [in] Novo 4 [in] Pixel_X Pixel_Y Novo's represent differential displacements of camera module in Albert's mount. 8.5 59 0.7 0 0 0 0 -1 -1 "Facing Laser module, behind camera module, [LR, UR, UL, LL] = Novo [1,2,3,4]" 8.5 60 0.7 0 0 0 0 -1 -1 8.5 61 0.7 0 0 0 0 -1 -1 8.5 62 0.5 -0.501 -0.502 -0.501 -0.503 -1 -1 8.5 63 0.5 -0.501 -0.502 -0.501 -0.503 -1 -1 8.5 64 0.5 -0.501 -0.502 -0.501 -0.503 -1 -1 8.5 65 0.7 -1.007 -1.005 -1.001 -1.008 -1 -1 8.5 66 0.7 -1.007 -1.005 -1.001 -1.008 -1 -1 8.5 67 0.7 -1.007 -1.005 -1.001 -1.008 -1 -1 8.5 73 0.7 -1.007 -1.005 -1.001 -1.008 -1 -1 8.5 74 0.7 -1.007 -1.005 -1.001 -1.008 -1 -1 8.5 75 0.7 -1.007 -1.005 -1.001 -1.008 -1 -1 8.5 77 0.8 -1.513 -1.509 -1.504 -1.512 -1 -1 8.5 78 0.8 -1.513 -1.509 -1.504 -1.512 -1 -1 8.5 79 0.8 -1.513 -1.509 -1.504 -1.512 -1 -1 8.5 80 0.6 -1.256 -1.255 -1.253 -1.26 310.7142857 198.5714286 8.5 81 0.6 -1.256 -1.255 -1.253 -1.26 313.7777778 199.6 8.5 82 0.6 -1.256 -1.255 -1.253 -1.26 313 198.1 8.5 83 0.6 -1.256 -1.255 -1.253 -1.26 313.333333 197.8 8 84 0.3 0 0 0 0 130.777778 244 8 85 0.3 0 0 0 0 129.33333 245.6363636 8 86 0.3 0 0 0 0 129.2857143 249.4285714 8 87 0.3 0 0 0 0 130.8888889 246.7272727 8 88 0.4 -0.255 -0.251 -0.251 -0.252 174.625 249.375 8 89 0.4 -0.255 -0.251 -0.251 -0.252 172.6666667 247.8181818 8 90 0.4 -0.255 -0.251 -0.251 -0.252 172.8888889 249.2727273 8 91 0.4 -0.255 -0.251 -0.251 -0.252 177.1428571 248 8 92 0.5 -0.505 -0.5 -0.502 -0.506 213.8888889 249.1 8 93 0.5 -0.505 -0.5 -0.502 -0.506 211 252.3636364 8 94 0.5 -0.505 -0.5 -0.502 -0.506 210.7777778 259 8 95 0.5 -0.505 -0.5 -0.502 -0.506 212.5 255.75 8 96 0.2 -0.753 -0.755 -0.756 -0.752 255.5555556 253.7 8 97 0.2 -0.753 -0.755 -0.756 -0.752 256.3333333 253.9 8 98 0.2 -0.753 -0.755 -0.756 -0.752 256.1111111 254.1 8 99 0.2 -0.753 -0.755 -0.756 -0.752 256.4444444 254.1 8 100 0.3 -1.004 -1.007 -1.006 -1.001 297.8888889 252.8 8 101 0.3 -1.004 -1.007 -1.006 -1.001 298.6666667 252.8 8 102 0.3 -1.004 -1.007 -1.006 -1.001 298.1111111 253.4545455 8 103 0.3 -1.004 -1.007 -1.006 -1.001 298 252.8 8 104 0.4 -1.251 -1.251 -1.253 -1.254 334.4444444 247.75 8 105 0.4 -1.251 -1.251 -1.253 -1.254 339.5555556 250.8181818 8 107 0.4 -1.251 -1.251 -1.253 -1.254 338.7777778 250.1818182 8 108 0.4 -1.251 -1.251 -1.253 -1.254 336.8888889 246.4166667 7.5 113 0.1 0 0 0 0 270.8888889 306.8333333 7.5 114 0.1 0 0 0 0 272 306.1666667 7.5 115 0.1 0 0 0 0 272.8571429 308.8888889 7.5 116 0.1 0 0 0 0 271.125 306 7.5 117 0.3 -0.255 -0.251 -0.253 -0.25 313.5555556 307.4545455 7.5 118 0.3 -0.255 -0.251 -0.253 -0.25 313.1111111 306.75 7.5 119 0.3 -0.255 -0.251 -0.253 -0.25 312.8888889 307.9090909 7.5 120 0.3 -0.255 -0.251 -0.253 -0.25 313.2222222 305.6666667 7.5 121 0.3 -0.503 -0.5 -0.503 -0.501 350.6666667 310.7777778 7.5 122 0.3 -0.503 -0.5 -0.503 -0.501 354.8888889 311.2727273 7.5 123 0.3 -0.503 -0.5 -0.503 -0.501 355 307.7272727 7.5 124 0.3 -0.503 -0.5 -0.503 -0.501 355.1111111 307.1818182 7.5 125 0.2 -1.009 -1.006 -1.005 -1.002 442.8571429 314.8571429 7.5 126 0.2 -1.009 -1.006 -1.005 -1.002 437.1111111 314.8333333 7.5 127 0.2 -1.009 -1.006 -1.005 -1.002 436.1111111 316.8181818 7.5 128 0.2 -1.009 -1.006 -1.005 -1.002 440.25 318.7 7.5 129 0.3 -1.251 -1.252 -1.249 -1.252 477 315.9166667 7.5 130 0.3 -1.251 -1.252 -1.249 -1.252 477.7777778 316.8333333 7.5 131 0.3 -1.251 -1.252 -1.249 -1.252 477.1111111 317.5454545 7.5 132 0.3 -1.251 -1.252 -1.249 -1.252 481.75 316.5555556 7 133 0.2 -0.5 -0.5 -0.503 -0.502 63.375 292.4166667 Moved camera module horizontally to capture crosshairs 7 134 0.2 -0.5 -0.5 -0.503 -0.502 91.85714286 290.4444444 Not beginning at 0 in order to capture crosshairs. Tared to 0 initially. 7 135 0.2 -0.5 -0.5 -0.503 -0.502 90.25 293.0909091 7 136 0.2 -0.5 -0.5 -0.503 -0.502 62.75 291.6666667 7 137 0.3 -0.752 -0.751 -0.756 -0.754 126.4444444 290.875 7 138 0.3 -0.752 -0.751 -0.756 -0.754 103.2222222 294.9166667 7 139 0.3 -0.752 -0.751 -0.756 -0.754 103.1111111 295.4166667 7 140 0.3 -0.752 -0.751 -0.756 -0.754 103.75 291.3333333 7 141 0.4 -0.852 -0.849 -0.854 -0.852 120.5714286 295.6666667 7 142 0.4 -0.852 -0.849 -0.854 -0.852 123 294.9166667 7 143 0.4 -0.852 -0.849 -0.854 -0.852 121 294.9166667 7 144 0.4 -0.852 -0.849 -0.854 -0.852 121.1111111 295 7 145 0.3 -1.001 -1 -1.004 -0.994 146.6666667 293.6 7 146 0.3 -1.001 -1 -1.004 -0.994 148.375 292.2 7 147 0.3 -1.001 -1 -1.004 -0.994 147.2222222 293.1 7 148 0.3 -1.001 -1 -1.004 -0.994 146.7777778 293.5 7 149 0.3 -1.251 -1.25 -1.253 -1.252 186 296.5454545 7 150 0.3 -1.251 -1.25 -1.253 -1.252 186.8888889 296.0909091 7 151 0.3 -1.251 -1.25 -1.253 -1.252 185.6666667 295.8181818 7 152 0.3 -1.251 -1.25 -1.253 -1.252 185.7777778 295.5454545 5 153 0.3 0 0 0 0 184.75 327.2727273 5 154 0.3 0 0 0 0 184.7777778 327 5 155 0.3 0 0 0 0 185.2222222 327 5 156 0.3 0 0 0 0 184.7777778 327.75 5 157 0.2 -0.251 -0.25 -0.254 -0.251 227.5555556 327.1666667 5 158 0.2 -0.251 -0.25 -0.254 -0.251 226.3333333 327 5 159 0.2 -0.251 -0.25 -0.254 -0.251 227.2222222 328.2727273 5 160 0.2 -0.251 -0.25 -0.254 -0.251 226 327.0833333 5 161 0.1 -0.503 -0.503 -0.506 -0.502 270.4444444 329.3636364 5 162 0.1 -0.503 -0.503 -0.506 -0.502 269.2222222 328.5833333 5 163 0.1 -0.503 -0.503 -0.506 -0.502 271 329 5 164 0.1 -0.503 -0.503 -0.506 -0.502 270.3333333 330.1818182 5 165 0.2 -0.75 -0.749 -0.753 -0.749 310.6666667 306.9166667 5 166 0.2 -0.75 -0.749 -0.753 -0.749 309.8888889 329.9090909 5 167 0.2 -0.75 -0.749 -0.753 -0.749 310.8888889 330 5 168 0.2 -0.75 -0.749 -0.753 -0.749 310.2222222 329.9090909 5 169 0.2 -1.253 -1.25 -1.253 -1.25 392.3333333 332.3636364 5 170 0.2 -1.253 -1.25 -1.253 -1.25 393.3333333 330.0833333 5 171 0.2 -1.253 -1.25 -1.253 -1.25 393.5 332.4545455 5 172 0.2 -1.253 -1.25 -1.253 -1.25 393.25 332.3636364 6 173 0.2 0 0 0 0 181 150.0909091 6 174 0.2 0 0 0 0 179.1111111 149.4545455 stood in front of camera 6 175 0.2 0 0 0 0 180.2222222 150.1818182 6 176 0.2 0 0 0 0 179.4444444 149.2727273 6 177 0.3 -0.253 -0.25 -0.253 -0.251 222.3333333 153 6 178 0.3 -0.253 -0.25 -0.253 -0.251 222.6666667 152.4444444 6 179 0.3 -0.253 -0.25 -0.253 -0.251 222.4444444 152.1111111 6 180 0.3 -0.253 -0.25 -0.253 -0.251 223.8888889 152.2222222 6 181 0 -0.5 -0.502 -0.507 -0.503 265 155.6363636 6 182 0 -0.5 -0.502 -0.507 -0.503 264.8888889 141.9090909 6 183 0 -0.5 -0.502 -0.507 -0.503 264.5555556 154.6363636 6 184 0 -0.5 -0.502 -0.507 -0.503 263.8888889 154.5454545 6 185 0.2 -0.751 -0.751 -0.75 -0.757 306.8888889 153.6363636 6 186 0.2 -0.751 -0.751 -0.75 -0.757 307 153.1 6 187 0.2 -0.751 -0.751 -0.75 -0.757 306 153.8181818 6 188 0.2 -0.751 -0.751 -0.75 -0.757 306.5555556 154.5 6 189 0.2 -1.253 -1.253 -1.255 -1.252 389 157.6363636 6 190 0.2 -1.253 -1.253 -1.255 -1.252 390 156.0909091 6 191 0.2 -1.253 -1.253 -1.255 -1.252 388.7777778 157.1 6 192 0.2 -1.253 -1.253 -1.255 -1.252 388.8888889 157.0909091 \ No newline at end of file diff --git a/calib4/Calibration_DX_DONTUSE.xlsx b/calib4/Calibration_DX_DONTUSE.xlsx new file mode 100755 index 0000000..d8325ba Binary files /dev/null and b/calib4/Calibration_DX_DONTUSE.xlsx differ diff --git a/calib4/DX_Reg.m b/calib4/DX_Reg.m new file mode 100755 index 0000000..4b88f09 --- /dev/null +++ b/calib4/DX_Reg.m @@ -0,0 +1,46 @@ +%% Import & Parse Data +filename = '/Volumes/HENRY_TENG/Research/Calibrations/DX/Calibration_DX.csv'; +delimiter = ','; +startRow = 9; +formatSpec = '%q%q%q%q%q%q%q%q%q%[^\n\r]'; +fileID = fopen(filename,'r','n','UTF-8'); +fseek(fileID, 3, 'bof'); +temp = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'TextType', 'string', 'HeaderLines' ,startRow-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); +fclose(fileID); +temp = [temp{:}]; +[m,n] = size(temp); +for i = 1:m + for j = 1:n-1 + dat(i,j) = str2num(temp(i,j)); + end +end + +img = dat(:,2); +DX = unique(dat(:,1)); +deg = dat(:,3); +novo = dat(:,4:7); +p_X = dat(:,8); +p_Y = dat(:,9); + +%% Generate Values +DZ = abs(mean(novo,2)); +for i = 1:length(DX) + ind = find(dat(:,1) == DX(i)); + b = polyfit(DZ(ind),p_X(ind),1); + temp = [min(DZ(ind)):0.01:max(DZ(ind))]; + figure(i) + plot(DZ(ind),p_X(ind),'b-o'), hold on + plot(temp,b(2) + b(1).*temp, '--r') + xlabel('DZ [in]') + ylabel('[Pixel]') + annotation('textbox',[0.2,0.5,0.3,0.3],'String',strcat('Slope: ',num2str(b(1))),'FitBoxToText','on'); + legend('p_X', 'Regression'); + title(strcat('DX: ', num2str(DX(i)), ' [m]')); +end + + + + + + + diff --git a/communication_module/com_test.py b/communication_module/com_test.py new file mode 100644 index 0000000..a99d3ec --- /dev/null +++ b/communication_module/com_test.py @@ -0,0 +1,35 @@ +import requests +from requests import Session +import json +from datetime import datetime +from dateutil import parser +from random import randint + +BRIDGE_NAME = 'dummy' +dest = "http://127.0.0.1:8000/sensors/"+BRIDGE_NAME+"/update/" +PASSWORD = "djioewfj34jod2jdoi3jr0jl983jsa" + + +def send_data_to_server(x=0.0, y=0.0, z=0.0, theta=0.0, phi=0.0, psi=0.0): + payload = {'x': x, 'y': y, 'z': z, 'theta': theta, 'phi': phi, 'psi': psi} + dt = datetime.now() + cookies = {'csrftoken': encode(dt), 'time': str(dt)} + r = requests.post(dest, data=payload, cookies=cookies) + print(r.status_code) + if r.status_code == 403: + raise RuntimeWarning("CSRF ALERT ON, INSPECT YOUR SYSTEM") + else: + return r.text + + +def encode(time_sign): + len_pw = len(PASSWORD) + index = (time_sign.year + time_sign.month * 100 + time_sign.day + time_sign.hour * time_sign.minute + * time_sign.second) % len_pw + repl = chr(randint(97, 122)) + return PASSWORD[:index] + repl + PASSWORD[index+1:] + + +print(send_data_to_server(0.5, 1.5, 1.5)) +#send_data_form(1.0, 2.0, 3.0) +#cookies = {'csrftoken': "djioewfj34jod2jdoi3jr0jl983jsa", 'TIME': datetime.now()} diff --git a/communication_module/communication.py b/communication_module/communication.py new file mode 100644 index 0000000..0891fbe --- /dev/null +++ b/communication_module/communication.py @@ -0,0 +1,29 @@ +import requests +from requests import Session +import json +from datetime import datetime +from dateutil import parser +from random import randint + +BRIDGE_NAME = 'dummy' +dest = "http://192.168.15.101:8000/sensors/"+BRIDGE_NAME+"/update/" +PASSWORD = "djioewfj34jod2jdoi3jr0jl983jsa" + + +def send_data_to_server(x=0.0, y=0.0, z=0.0, theta=0.0, phi=0.0, psi=0.0): + payload = {'x': x, 'y': y, 'z': z, 'theta': theta, 'phi': phi, 'psi': psi} + dt = datetime.now() + cookies = {'csrftoken': encode(dt), 'time': str(dt)} + r = requests.post(dest, data=payload, cookies=cookies) + if r.status_code == 403: + raise RuntimeWarning("CSRF ALERT ON, INSPECT YOUR SYSTEM") + else: + return r.text + + +def encode(time_sign): + len_pw = len(PASSWORD) + index = (time_sign.year + time_sign.month * 100 + time_sign.day + time_sign.hour * time_sign.minute + * time_sign.second) % len_pw + repl = chr(randint(97, 122)) + return PASSWORD[:index] + repl + PASSWORD[index+1:] diff --git a/expr.py b/expr.py new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/FastDataMatrixTest.py b/img_rec_module/FastDataMatrixTest.py new file mode 100644 index 0000000..21cdf8d --- /dev/null +++ b/img_rec_module/FastDataMatrixTest.py @@ -0,0 +1,45 @@ +from img_rec_module.sig_proc_test import FM +import numpy as np +from random import randint +import traceback +import sys + +matrix = np.random.rand(20, 30) + + +def segmentation_test(sample): + ax = randint(0, 1) + target = randint(0, 19) if ax == 1 else randint(0, 29) + fmat = FM(matrix, ax, target) + assert fmat.irange() == 20 if ax == 1 else fmat.irange() == 30 + cap = len(fmat) + for i in range(sample): + start = randint(0, cap - 1) + end = randint(start + 1, cap) + fmat.segmentize(start, end) + assert len(fmat.extract_array()) == end - start, "start: {0}, end: {1}".format(start, end) + elem = randint(0, len(fmat) - 1) + assert fmat[elem] == matrix.item(target, elem + start) if ax == 1 \ + else fmat[elem] == matrix.item(elem + start, target) + print("Test 1 passed!") + return fmat.copy() + + +def shape_change_test(sample): + fmat = mat + print(len(fmat), "start: {0}, end: {1}, ax: {2}, index: {3}".format(fmat.start, fmat.end, fmat._ax, fmat._index)) + for i in range(sample): + ax = randint(0, 1) + target = randint(0, 19) if ax == 1 else randint(0, 29) + try: + fmat = fmat.copy(ax, target) + elem = randint(0, len(fmat) - 1) + assert fmat[elem] == matrix.item(target, elem) if ax == 1 else fmat[elem] == matrix.item(elem, target), "start: {0}, end: {1}, ax: {2}, index: {3}, changed:{4}, elem: {5}".format(fmat.start, fmat.end, ax, fmat._index, target, elem) + except IndexError: + print("Index Error, start: {0}, end: {1}, ax: {2}, index: {3}".format(fmat.start, fmat.end, fmat._ax, fmat._index)) + traceback.print_exc(file=sys.stderr) + sys.exit(0) + print("Test 2 passed!") + +mat = segmentation_test(1000000) +shape_change_test(1000000) \ No newline at end of file diff --git a/img_rec_module/HoughLineTest.py b/img_rec_module/HoughLineTest.py new file mode 100644 index 0000000..a338b2c --- /dev/null +++ b/img_rec_module/HoughLineTest.py @@ -0,0 +1,70 @@ +from img_rec_module.sig_proc_test import HoughLine, angle_interp, normalize_angle +import numpy as np +from random import uniform +from math import sin, cos, asin, acos, degrees + + +def angle_interp_test(sample): + for t in range(4): + angle = np.pi * t / 2 + angle_test(angle) + for i in range(sample): + angle = uniform(0, 2 * np.pi) + angle_test(angle) + print("All tests passed!") + + +def angle_test(angle): + s, c = sin(angle), cos(angle) + aint = angle_interp(s, c) + e = abs(aint - angle) + assert e < 10 ** (-8), "angle: {0} aint: {3} sin: {1}, cos: {2}".format(degrees(angle), s, c, degrees(aint)) + + +data1 = [(50, 93.58985799408744), (100, 94.83752561512769), (150, 93.46476622047003), (200, 92.12757475618413), (250, 91.21899822237681), (300, 94.66610143151713), (350, 93.39700158152765), (400, 93.55400856320203), (450, 94.81488837189904)] +data2 = [(50, 220.68898677024384), (150, 207.0369850844262), (200, 219.1873113806197), (250, 218.4221525438996), (300, 215.83141259108666), (350, 216.1097540779057), (400, 214.30630223604018), (450, 211.84789180370862), (500, 211.03929058602466), (550, 208.37556376057634), (600, 208.1358916890448)] + + +def diagnose(): + x1 = np.array([d[1] for d in data1]) + y1 = np.array([d[0] for d in data1]) + line1 = HoughLine(x=x1, data=y1) + x2 = np.array([d[0] for d in data2]) + y2 = np.array([d[1] for d in data2]) + line2 = HoughLine(x=x2, data=y2) + xmean = sum(x1) / len(x1) + ymean = sum(y2) / len(y2) + print(line1._r, line1._t) + print(line2._r, line2._t) + print((xmean, ymean), HoughLine.intersect(line1, line2)) + + +def normalize_angle_test(sample): + for t in range(4): + angle = np.pi * t / 2 + test_normalize(angle) + for i in range(sample): + angle = uniform(0, 1000000) + test_normalize(angle) + print('All tests passed!') + + +def test_normalize(angle): + s, c = sin(angle), cos(angle) + norm_ang = normalize_angle(angle) + ns, nc = sin(norm_ang), cos(norm_ang) + case1 = equal_within_error(s, ns) and equal_within_error(c, nc) + case2 = equal_within_error(s, -ns) and equal_within_error(c, -nc) + assert case1 or case2, 's:{0} c:{1}, ns:{2}, nc:{3}, angle:{4}, norm:{5}'.format(s, c, ns, nc, angle, norm_ang) + + + +def equal_within_error(v1, v2): + e = abs(v1 - v2) + return e < 10 ** (-8) + + +if __name__ == '__main__': + #angle_interp_test(100000000) + #diagnose() + normalize_angle_test(1000000) \ No newline at end of file diff --git a/img_rec_module/__init__.py b/img_rec_module/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/centers.txt b/img_rec_module/centers.txt new file mode 100644 index 0000000..ea1e64b --- /dev/null +++ b/img_rec_module/centers.txt @@ -0,0 +1,640 @@ +135.5 +134.5 +134.0 +127.5 +131.0 +131.0 +133.5 +131.0 +131.5 +131.5 +129.5 +135.5 +135.5 +126.5 +134.0 +131.5 +132.5 +128.5 +131.5 +134.5 +130.5 +1.0 +132.5 +129.5 +70.5 +131.5 +132.5 +132.0 +132.5 +129.5 +135.5 +129.5 +132.5 +130.5 +131.5 +134.0 +72.0 +67.5 +130.5 +135.0 +132.0 +133.5 +130.5 +129.5 +129.5 +132.0 +130.5 +134.0 +129.5 +136.0 +129.5 +127.5 +133.5 +131.0 +134.0 +131.5 +128.5 +132.0 +132.5 +136.0 +132.0 +133.5 +132.0 +132.5 +132.0 +129.0 +138.5 +133.5 +134.0 +132.5 +132.5 +134.0 +134.5 +131.5 +133.0 +135.5 +132.0 +130.5 +130.5 +128.0 +130.0 +133.0 +132.0 +136.0 +135.5 +132.5 +135.5 +130.5 +136.5 +136.5 +129.5 +129.0 +130.0 +138.5 +135.0 +127.5 +126.5 +135.5 +135.5 +130.5 +127.5 +131.5 +136.5 +134.5 +136.5 +133.5 +133.0 +131.5 +130.0 +136.5 +135.5 +135.0 +134.0 +133.0 +131.5 +130.5 +132.5 +135.5 +133.5 +129.5 +133.0 +136.5 +129.0 +135.5 +133.5 +133.5 +134.0 +129.5 +133.5 +132.0 +134.5 +137.0 +130.5 +129.5 +130.5 +131.5 +133.5 +137.5 +134.5 +130.5 +131.0 +134.0 +137.5 +132.5 +128.0 +129.0 +132.0 +136.5 +129.5 +128.0 +127.5 +128.0 +135.0 +128.5 +129.0 +135.0 +137.5 +136.0 +131.5 +131.0 +130.0 +134.0 +135.5 +133.0 +134.5 +134.0 +133.0 +132.0 +135.0 +132.0 +135.5 +132.5 +130.5 +127.5 +131.5 +131.0 +134.0 +131.0 +129.0 +130.0 +129.0 +129.5 +133.0 +132.0 +127.5 +131.5 +135.0 +134.0 +133.0 +133.0 +130.0 +130.5 +127.5 +133.0 +135.0 +134.0 +135.5 +131.5 +129.5 +128.5 +138.5 +134.0 +132.0 +135.5 +132.0 +128.0 +127.5 +134.5 +130.0 +130.5 +131.0 +129.5 +125.5 +130.0 +130.5 +134.5 +137.5 +129.5 +132.5 +134.0 +131.5 +134.0 +128.5 +131.5 +134.0 +133.5 +134.0 +133.0 +132.5 +130.5 +126.5 +128.5 +130.0 +128.0 +131.5 +131.0 +129.5 +132.5 +131.0 +129.5 +127.5 +135.0 +126.5 +141.5 +132.5 +133.0 +136.0 +131.0 +129.0 +134.5 +130.5 +127.5 +133.0 +133.5 +131.5 +135.5 +134.0 +131.0 +133.5 +133.5 +133.5 +127.5 +132.0 +132.5 +134.5 +132.0 +132.0 +128.0 +132.0 +136.0 +136.0 +132.5 +134.5 +137.0 +131.0 +131.5 +137.0 +130.5 +128.0 +133.0 +129.5 +135.0 +140.0 +130.5 +134.5 +129.0 +136.0 +128.0 +133.5 +136.5 +135.0 +127.5 +131.5 +139.5 +131.5 +128.5 +136.0 +135.0 +131.5 +131.5 +133.5 +127.5 +135.5 +135.5 +128.0 +130.0 +127.5 +128.0 +130.0 +126.5 +142.5 +134.5 +134.5 +124.5 +126.5 +129.5 +131.0 +129.5 +131.5 +127.0 +127.5 +135.0 +134.5 +131.5 +126.0 +130.5 +132.0 +138.0 +131.5 +135.5 +125.0 +133.0 +127.5 +136.5 +131.5 +131.5 +131.0 +124.0 +128.5 +137.5 +133.5 +130.0 +131.0 +129.0 +133.0 +131.0 +125.5 +129.5 +132.0 +129.5 +137.5 +128.5 +130.0 +131.0 +134.5 +130.0 +131.5 +131.5 +136.5 +134.0 +132.0 +136.0 +126.5 +128.0 +133.5 +135.5 +129.0 +133.0 +131.5 +132.0 +129.5 +126.0 +126.0 +130.5 +135.0 +129.0 +131.0 +130.5 +131.5 +135.5 +133.5 +134.0 +131.5 +126.0 +130.0 +131.0 +131.5 +130.5 +133.5 +130.0 +125.0 +126.5 +133.5 +132.0 +129.5 +133.5 +130.5 +132.5 +136.0 +135.0 +130.0 +129.5 +134.0 +135.5 +131.5 +135.5 +135.5 +131.5 +130.0 +130.0 +131.5 +132.0 +129.5 +131.5 +127.5 +136.0 +131.0 +134.5 +135.0 +126.5 +128.0 +131.5 +131.5 +127.0 +130.0 +130.5 +136.5 +130.5 +129.0 +130.0 +130.5 +135.5 +125.5 +130.5 +130.0 +127.5 +132.5 +133.5 +130.0 +127.5 +126.0 +132.0 +127.0 +126.0 +130.5 +127.5 +127.5 +129.5 +131.5 +133.0 +129.5 +127.0 +129.0 +126.5 +130.5 +130.0 +126.5 +128.5 +126.5 +126.5 +127.5 +134.0 +136.5 +129.5 +130.0 +128.5 +130.0 +127.5 +130.5 +135.0 +137.5 +130.0 +129.5 +134.5 +130.5 +127.5 +132.5 +129.0 +132.5 +130.0 +133.5 +127.5 +129.5 +129.0 +124.5 +126.5 +126.0 +128.0 +130.0 +133.0 +129.5 +131.0 +128.5 +132.5 +129.5 +199.5 +133.5 +133.5 +130.0 +127.5 +114.0 +227.5 +113.5 +134.5 +129.5 +130.0 +128.5 +130.0 +132.5 +126.5 +127.5 +129.0 +135.5 +129.5 +126.5 +127.5 +132.5 +127.0 +131.0 +124.5 +132.5 +128.0 +129.5 +135.5 +131.5 +129.0 +131.5 +132.0 +131.5 +130.5 +130.5 +136.5 +135.5 +131.5 +129.0 +130.5 +130.0 +129.0 +130.5 +128.0 +126.5 +133.5 +131.0 +129.0 +128.0 +131.5 +132.5 +128.5 +134.5 +130.0 +127.5 +130.0 +129.5 +131.5 +127.5 +131.0 +129.0 +127.5 +135.5 +128.0 +127.0 +131.0 +131.0 +129.5 +126.0 +128.5 +128.5 +131.0 +126.0 +132.5 +128.0 +130.0 +133.0 +127.5 +128.5 +131.5 +135.5 +133.0 +133.0 +131.0 +132.0 +128.0 +132.0 +130.0 +132.5 +128.5 +127.5 +130.5 +130.0 +131.5 +128.5 +126.5 +132.0 +126.5 +129.5 +128.0 +127.0 +126.5 +133.5 +128.5 +135.5 +133.5 +132.5 +132.0 +132.5 +131.5 +131.0 +131.0 +129.5 +130.5 +127.0 +127.5 +125.0 +129.5 +130.5 +130.5 +132.5 +128.0 +129.5 +126.5 +125.5 +125.0 +131.5 +130.0 +131.5 +128.5 +127.0 +134.0 +129.0 +132.5 +130.0 +129.5 +129.0 +129.0 +126.5 +127.5 +128.0 +125.5 +131.0 +129.5 diff --git a/img_rec_module/flags.txt b/img_rec_module/flags.txt new file mode 100644 index 0000000..b15d479 --- /dev/null +++ b/img_rec_module/flags.txt @@ -0,0 +1,274 @@ +COLOR_BAYER_BG2BGR +COLOR_BAYER_BG2BGRA +COLOR_BAYER_BG2BGR_EA +COLOR_BAYER_BG2BGR_VNG +COLOR_BAYER_BG2GRAY +COLOR_BAYER_BG2RGB +COLOR_BAYER_BG2RGBA +COLOR_BAYER_BG2RGB_EA +COLOR_BAYER_BG2RGB_VNG +COLOR_BAYER_GB2BGR +COLOR_BAYER_GB2BGRA +COLOR_BAYER_GB2BGR_EA +COLOR_BAYER_GB2BGR_VNG +COLOR_BAYER_GB2GRAY +COLOR_BAYER_GB2RGB +COLOR_BAYER_GB2RGBA +COLOR_BAYER_GB2RGB_EA +COLOR_BAYER_GB2RGB_VNG +COLOR_BAYER_GR2BGR +COLOR_BAYER_GR2BGRA +COLOR_BAYER_GR2BGR_EA +COLOR_BAYER_GR2BGR_VNG +COLOR_BAYER_GR2GRAY +COLOR_BAYER_GR2RGB +COLOR_BAYER_GR2RGBA +COLOR_BAYER_GR2RGB_EA +COLOR_BAYER_GR2RGB_VNG +COLOR_BAYER_RG2BGR +COLOR_BAYER_RG2BGRA +COLOR_BAYER_RG2BGR_EA +COLOR_BAYER_RG2BGR_VNG +COLOR_BAYER_RG2GRAY +COLOR_BAYER_RG2RGB +COLOR_BAYER_RG2RGBA +COLOR_BAYER_RG2RGB_EA +COLOR_BAYER_RG2RGB_VNG +COLOR_BGR2BGR555 +COLOR_BGR2BGR565 +COLOR_BGR2BGRA +COLOR_BGR2GRAY +COLOR_BGR2HLS +COLOR_BGR2HLS_FULL +COLOR_BGR2HSV +COLOR_BGR2HSV_FULL +COLOR_BGR2LAB +COLOR_BGR2LUV +COLOR_BGR2Lab +COLOR_BGR2Luv +COLOR_BGR2RGB +COLOR_BGR2RGBA +COLOR_BGR2XYZ +COLOR_BGR2YCR_CB +COLOR_BGR2YCrCb +COLOR_BGR2YUV +COLOR_BGR2YUV_I420 +COLOR_BGR2YUV_IYUV +COLOR_BGR2YUV_YV12 +COLOR_BGR5552BGR +COLOR_BGR5552BGRA +COLOR_BGR5552GRAY +COLOR_BGR5552RGB +COLOR_BGR5552RGBA +COLOR_BGR5652BGR +COLOR_BGR5652BGRA +COLOR_BGR5652GRAY +COLOR_BGR5652RGB +COLOR_BGR5652RGBA +COLOR_BGRA2BGR +COLOR_BGRA2BGR555 +COLOR_BGRA2BGR565 +COLOR_BGRA2GRAY +COLOR_BGRA2RGB +COLOR_BGRA2RGBA +COLOR_BGRA2YUV_I420 +COLOR_BGRA2YUV_IYUV +COLOR_BGRA2YUV_YV12 +COLOR_BayerBG2BGR +COLOR_BayerBG2BGRA +COLOR_BayerBG2BGR_EA +COLOR_BayerBG2BGR_VNG +COLOR_BayerBG2GRAY +COLOR_BayerBG2RGB +COLOR_BayerBG2RGBA +COLOR_BayerBG2RGB_EA +COLOR_BayerBG2RGB_VNG +COLOR_BayerGB2BGR +COLOR_BayerGB2BGRA +COLOR_BayerGB2BGR_EA +COLOR_BayerGB2BGR_VNG +COLOR_BayerGB2GRAY +COLOR_BayerGB2RGB +COLOR_BayerGB2RGBA +COLOR_BayerGB2RGB_EA +COLOR_BayerGB2RGB_VNG +COLOR_BayerGR2BGR +COLOR_BayerGR2BGRA +COLOR_BayerGR2BGR_EA +COLOR_BayerGR2BGR_VNG +COLOR_BayerGR2GRAY +COLOR_BayerGR2RGB +COLOR_BayerGR2RGBA +COLOR_BayerGR2RGB_EA +COLOR_BayerGR2RGB_VNG +COLOR_BayerRG2BGR +COLOR_BayerRG2BGRA +COLOR_BayerRG2BGR_EA +COLOR_BayerRG2BGR_VNG +COLOR_BayerRG2GRAY +COLOR_BayerRG2RGB +COLOR_BayerRG2RGBA +COLOR_BayerRG2RGB_EA +COLOR_BayerRG2RGB_VNG +COLOR_COLORCVT_MAX +COLOR_GRAY2BGR +COLOR_GRAY2BGR555 +COLOR_GRAY2BGR565 +COLOR_GRAY2BGRA +COLOR_GRAY2RGB +COLOR_GRAY2RGBA +COLOR_HLS2BGR +COLOR_HLS2BGR_FULL +COLOR_HLS2RGB +COLOR_HLS2RGB_FULL +COLOR_HSV2BGR +COLOR_HSV2BGR_FULL +COLOR_HSV2RGB +COLOR_HSV2RGB_FULL +COLOR_LAB2BGR +COLOR_LAB2LBGR +COLOR_LAB2LRGB +COLOR_LAB2RGB +COLOR_LBGR2LAB +COLOR_LBGR2LUV +COLOR_LBGR2Lab +COLOR_LBGR2Luv +COLOR_LRGB2LAB +COLOR_LRGB2LUV +COLOR_LRGB2Lab +COLOR_LRGB2Luv +COLOR_LUV2BGR +COLOR_LUV2LBGR +COLOR_LUV2LRGB +COLOR_LUV2RGB +COLOR_Lab2BGR +COLOR_Lab2LBGR +COLOR_Lab2LRGB +COLOR_Lab2RGB +COLOR_Luv2BGR +COLOR_Luv2LBGR +COLOR_Luv2LRGB +COLOR_Luv2RGB +COLOR_M_RGBA2RGBA +COLOR_RGB2BGR +COLOR_RGB2BGR555 +COLOR_RGB2BGR565 +COLOR_RGB2BGRA +COLOR_RGB2GRAY +COLOR_RGB2HLS +COLOR_RGB2HLS_FULL +COLOR_RGB2HSV +COLOR_RGB2HSV_FULL +COLOR_RGB2LAB +COLOR_RGB2LUV +COLOR_RGB2Lab +COLOR_RGB2Luv +COLOR_RGB2RGBA +COLOR_RGB2XYZ +COLOR_RGB2YCR_CB +COLOR_RGB2YCrCb +COLOR_RGB2YUV +COLOR_RGB2YUV_I420 +COLOR_RGB2YUV_IYUV +COLOR_RGB2YUV_YV12 +COLOR_RGBA2BGR +COLOR_RGBA2BGR555 +COLOR_RGBA2BGR565 +COLOR_RGBA2BGRA +COLOR_RGBA2GRAY +COLOR_RGBA2M_RGBA +COLOR_RGBA2RGB +COLOR_RGBA2YUV_I420 +COLOR_RGBA2YUV_IYUV +COLOR_RGBA2YUV_YV12 +COLOR_RGBA2mRGBA +COLOR_XYZ2BGR +COLOR_XYZ2RGB +COLOR_YCR_CB2BGR +COLOR_YCR_CB2RGB +COLOR_YCrCb2BGR +COLOR_YCrCb2RGB +COLOR_YUV2BGR +COLOR_YUV2BGRA_I420 +COLOR_YUV2BGRA_IYUV +COLOR_YUV2BGRA_NV12 +COLOR_YUV2BGRA_NV21 +COLOR_YUV2BGRA_UYNV +COLOR_YUV2BGRA_UYVY +COLOR_YUV2BGRA_Y422 +COLOR_YUV2BGRA_YUNV +COLOR_YUV2BGRA_YUY2 +COLOR_YUV2BGRA_YUYV +COLOR_YUV2BGRA_YV12 +COLOR_YUV2BGRA_YVYU +COLOR_YUV2BGR_I420 +COLOR_YUV2BGR_IYUV +COLOR_YUV2BGR_NV12 +COLOR_YUV2BGR_NV21 +COLOR_YUV2BGR_UYNV +COLOR_YUV2BGR_UYVY +COLOR_YUV2BGR_Y422 +COLOR_YUV2BGR_YUNV +COLOR_YUV2BGR_YUY2 +COLOR_YUV2BGR_YUYV +COLOR_YUV2BGR_YV12 +COLOR_YUV2BGR_YVYU +COLOR_YUV2GRAY_420 +COLOR_YUV2GRAY_I420 +COLOR_YUV2GRAY_IYUV +COLOR_YUV2GRAY_NV12 +COLOR_YUV2GRAY_NV21 +COLOR_YUV2GRAY_UYNV +COLOR_YUV2GRAY_UYVY +COLOR_YUV2GRAY_Y422 +COLOR_YUV2GRAY_YUNV +COLOR_YUV2GRAY_YUY2 +COLOR_YUV2GRAY_YUYV +COLOR_YUV2GRAY_YV12 +COLOR_YUV2GRAY_YVYU +COLOR_YUV2RGB +COLOR_YUV2RGBA_I420 +COLOR_YUV2RGBA_IYUV +COLOR_YUV2RGBA_NV12 +COLOR_YUV2RGBA_NV21 +COLOR_YUV2RGBA_UYNV +COLOR_YUV2RGBA_UYVY +COLOR_YUV2RGBA_Y422 +COLOR_YUV2RGBA_YUNV +COLOR_YUV2RGBA_YUY2 +COLOR_YUV2RGBA_YUYV +COLOR_YUV2RGBA_YV12 +COLOR_YUV2RGBA_YVYU +COLOR_YUV2RGB_I420 +COLOR_YUV2RGB_IYUV +COLOR_YUV2RGB_NV12 +COLOR_YUV2RGB_NV21 +COLOR_YUV2RGB_UYNV +COLOR_YUV2RGB_UYVY +COLOR_YUV2RGB_Y422 +COLOR_YUV2RGB_YUNV +COLOR_YUV2RGB_YUY2 +COLOR_YUV2RGB_YUYV +COLOR_YUV2RGB_YV12 +COLOR_YUV2RGB_YVYU +COLOR_YUV420P2BGR +COLOR_YUV420P2BGRA +COLOR_YUV420P2GRAY +COLOR_YUV420P2RGB +COLOR_YUV420P2RGBA +COLOR_YUV420SP2BGR +COLOR_YUV420SP2BGRA +COLOR_YUV420SP2GRAY +COLOR_YUV420SP2RGB +COLOR_YUV420SP2RGBA +COLOR_YUV420p2BGR +COLOR_YUV420p2BGRA +COLOR_YUV420p2GRAY +COLOR_YUV420p2RGB +COLOR_YUV420p2RGBA +COLOR_YUV420sp2BGR +COLOR_YUV420sp2BGRA +COLOR_YUV420sp2GRAY +COLOR_YUV420sp2RGB +COLOR_YUV420sp2RGBA +COLOR_mRGBA2RGBA diff --git a/img_rec_module/img_1_1_meas.txt b/img_rec_module/img_1_1_meas.txt new file mode 100644 index 0000000..97ed4c5 --- /dev/null +++ b/img_rec_module/img_1_1_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 384.9492753623189; +y: zero_crossing: 128.7986577181208, edge_converge: 124.79086538461539 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 385.07291666666663; +y: zero_crossing: 129.5, edge_converge: 125.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 383.90625, edge_converge: 379.9741379310345; +y: zero_crossing: 129.52727272727273, edge_converge: 130.70366132723112 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 379.9741379310345; +y: zero_crossing: 129.6, edge_converge: 130.70366132723112 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 379.9741379310345; +y: zero_crossing: 129.68627450980392, edge_converge: 130.70366132723112 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 383.6551724137931, edge_converge: 379.9741379310345; +y: zero_crossing: 129.55172413793105, edge_converge: 130.70366132723112 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 383.55172413793105, edge_converge: 379.9741379310345; +y: zero_crossing: 129.5, edge_converge: 130.70366132723112 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 383.90625, edge_converge: 379.9741379310345; +y: zero_crossing: 129.5, edge_converge: 130.70366132723112 diff --git a/img_rec_module/img_1_1new_meas.txt b/img_rec_module/img_1_1new_meas.txt new file mode 100644 index 0000000..70d4297 --- /dev/null +++ b/img_rec_module/img_1_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 323.66566716641677; +y: zero_crossing: -1, edge_converge: 828.3849673202615 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 597.0; +y: zero_crossing: -1, edge_converge: 792.34375 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 880.0; +y: zero_crossing: -1, edge_converge: 796.6236413043478 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 716.546875; +y: zero_crossing: -1, edge_converge: 832.172697368421 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 321.5, edge_converge: 308.0; +y: zero_crossing: -1, edge_converge: -1 diff --git a/img_rec_module/img_20_1_meas.txt b/img_rec_module/img_20_1_meas.txt new file mode 100644 index 0000000..8f3d333 --- /dev/null +++ b/img_rec_module/img_20_1_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 225.33333333333334, edge_converge: 222.40969899665552; +y: zero_crossing: 222.44086021505376, edge_converge: 232.5 +ksize:(7, 7), sigmax:0 +x: zero_crossing: 224.90625, edge_converge: 212.425; +y: zero_crossing: 222.7012987012987, edge_converge: 244.8653846153846 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 224.55172413793105, edge_converge: 225.7096153846154; +y: zero_crossing: 222.8507462686567, edge_converge: 233.3653846153846 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 224.86363636363637, edge_converge: 207.6159420289855; +y: zero_crossing: 223.22413793103448, edge_converge: 215.5216346153846 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.37254901960785, edge_converge: 238.5 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.33333333333334, edge_converge: 238.5 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 224.8421052631579, edge_converge: 198.0; +y: zero_crossing: 223.46341463414635, edge_converge: 238.5 +ksize:(19, 19), sigmax:0 +x: zero_crossing: 224.56521739130434, edge_converge: 198.0; +y: zero_crossing: 223.57894736842104, edge_converge: 238.5 diff --git a/img_rec_module/img_20_2_meas.txt b/img_rec_module/img_20_2_meas.txt new file mode 100644 index 0000000..4e85aab --- /dev/null +++ b/img_rec_module/img_20_2_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 225.58333333333331; +y: zero_crossing: -1, edge_converge: 182.35897435897436 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 227.5; +y: zero_crossing: -1, edge_converge: 224.0 +ksize:(9, 9), sigmax:0 +x: zero_crossing: 218.89655172413794, edge_converge: 212.9415292353823; +y: zero_crossing: -1, edge_converge: 232.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 218.86363636363637, edge_converge: 266.84375; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 218.5, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: -1, edge_converge: -1 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 213.0; +y: zero_crossing: 191.76923076923077, edge_converge: -1 diff --git a/img_rec_module/img_20_3_meas.txt b/img_rec_module/img_20_3_meas.txt new file mode 100644 index 0000000..b228fdb --- /dev/null +++ b/img_rec_module/img_20_3_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: 43.1578947368421, edge_converge: 27.907894736842106; +y: zero_crossing: 222.41739130434783, edge_converge: 224.8991379310345 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 222.0; +y: zero_crossing: 222.53191489361703, edge_converge: 228.6346153846154 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 225.0; +y: zero_crossing: 222.6338028169014, edge_converge: 213.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.75, edge_converge: 291.0 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.79166666666666, edge_converge: 200.0 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.7450980392157, edge_converge: 200.0 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.92105263157896, edge_converge: 200.0 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: 222.9268292682927, edge_converge: 200.0 diff --git a/img_rec_module/img_2_1new_meas.txt b/img_rec_module/img_2_1new_meas.txt new file mode 100644 index 0000000..a8b0bc8 --- /dev/null +++ b/img_rec_module/img_2_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 1178.6311475409836; +y: zero_crossing: -1, edge_converge: 376.4716202270382 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: -1; +y: zero_crossing: -1, edge_converge: 635.5 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 1582.0; +y: zero_crossing: -1, edge_converge: 723.0 +ksize:(11, 11), sigmax:0 +x: zero_crossing: -1, edge_converge: 1682.4423076923076; +y: zero_crossing: -1, edge_converge: -1 +ksize:(13, 13), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(15, 15), sigmax:0 +x: zero_crossing: 72.5, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(17, 17), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 1081.9783653846152; +y: zero_crossing: -1, edge_converge: 558.15625 diff --git a/img_rec_module/img_3_1new_meas.txt b/img_rec_module/img_3_1new_meas.txt new file mode 100644 index 0000000..8cf1d3c --- /dev/null +++ b/img_rec_module/img_3_1new_meas.txt @@ -0,0 +1,24 @@ +ksize:(5, 5), sigmax:0 +x: zero_crossing: -1, edge_converge: 485.2365079365079; +y: zero_crossing: -1, edge_converge: 463.47727272727275 +ksize:(7, 7), sigmax:0 +x: zero_crossing: -1, edge_converge: 484.8125; +y: zero_crossing: -1, edge_converge: 464.0 +ksize:(9, 9), sigmax:0 +x: zero_crossing: -1, edge_converge: 482.4; +y: zero_crossing: 462.8421052631579, edge_converge: 464.13461538461536 +ksize:(11, 11), sigmax:0 +x: zero_crossing: 480.5, edge_converge: 475.3696120689655; +y: zero_crossing: 462.5, edge_converge: 478.50674662668666 +ksize:(13, 13), sigmax:0 +x: zero_crossing: 485.2307692307692, edge_converge: 493.35480943738656; +y: zero_crossing: 462.1875, edge_converge: 448.98519736842104 +ksize:(15, 15), sigmax:0 +x: zero_crossing: -1, edge_converge: 493.35480943738656; +y: zero_crossing: 462.5, edge_converge: 448.98519736842104 +ksize:(17, 17), sigmax:0 +x: zero_crossing: 487.5, edge_converge: 493.35480943738656; +y: zero_crossing: 462.1875, edge_converge: 448.98519736842104 +ksize:(19, 19), sigmax:0 +x: zero_crossing: -1, edge_converge: 493.35480943738656; +y: zero_crossing: 462.4347826086956, edge_converge: 448.98519736842104 diff --git a/img_rec_module/img_filter.py b/img_rec_module/img_filter.py new file mode 100644 index 0000000..3b8b0dc --- /dev/null +++ b/img_rec_module/img_filter.py @@ -0,0 +1,23 @@ +import cv2 +import numpy as np +from matplotlib import pyplot as plt + +img = cv2.imread('../testpic/img_20_1.png',0) +blur = cv2.GaussianBlur(img,(5,5),0) +cv2.imshow("ok", blur) +img = blur + +laplacian = cv2.Laplacian(img,cv2.CV_64F) +sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5) +sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5) + +plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray') +plt.title('Original'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray') +plt.title('Laplacian'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') +plt.title('Sobel X'), plt.xticks([]), plt.yticks([]) +plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') +plt.title('Sobel Y'), plt.xticks([]), plt.yticks([]) + +plt.show() \ No newline at end of file diff --git a/img_rec_module/img_rec.py b/img_rec_module/img_rec.py new file mode 100644 index 0000000..eac36ff --- /dev/null +++ b/img_rec_module/img_rec.py @@ -0,0 +1,176 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +import os +from img_rec_module.sig_proc_test import FM, compare_data_plots, compare_images + + +def identity(img): + return img + + +def grayscale(img): + return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + +def grad_detect(img, n, ori, func): + #img = np.array(img) + if ori == 'h': + grad = [func(img, n, i+1) - func(img, n, i) for i in range(img.shape[1]-1)] + else: + grad = [func(img, i+1, n) - func(img, i, n) for i in range(img.shape[0]-1)] + return grad + + +def abs_detect(img, n, ori, func): + if ori == 'h': + return [func(img, n, i) for i in range(img.shape[1])] + else: + return [func(img, i, n) for i in range(img.shape[0])] + + +def visualize_data(folder, oname, sample, orient, func, data_p=grad_detect, img_p=identity): + dirs = os.listdir(folder) + for f in dirs: + try: + img = img_p(cv2.imread(folder + f)) + interval = int(img.shape[1 if orient == 'v' else 0] / sample) + for j in range(sample): + n = j * interval + data = data_p(img, n, orient, func) + plt_save_data(data, oname + 'data_{0}{1}_'.format(orient, n) + f) + except: + print(f) + + +def max_entry(img): + max_e = 0 + for row in img: + temp = max(row) + if temp > max_e: + max_e = temp + + +def record_file(vals, fname): + f = open(fname, 'w') + for v in vals: + f.write(str(v) + '\n') + f.close() + + +def rel_lumin(img, r, c): + b = img.item(r, c, 0) + g = img.item(r, c, 1) + r = img.item(r, c, 2) + return 0.2126 * r + 0.7152 * g + 0.0722 * b + + +def max_method(img): + index = [] + s = 0 + for i in range(img.shape[1]): + val = np.argmax(img[:, i]) + index.append(val) + s += val + return s / len(index) + + +def plot_show_data(data): + plt.figure(figsize=(16, 8)) + #plt.xticks(range(0, img.shape[0], 20), range(0, img.shape[0], 20)) + plt.plot(data, 'b-') + plt.show() + plt.close() + + +def plt_save_data(data, fname): + plt.figure(figsize=(16, 8)) + plt.plot(data, 'b-') + plt.savefig(fname) + plt.close() + + +def centroid(img, func): + r = img.shape[0] + c = img.shape[1] + aggr_i = 0 + aggr_j = 0 + aggr = 0 + for i in range(r): + for j in range(c): + lum = func(img, i, j) + aggr_i += lum * i + aggr_j += lum * j + aggr += lum + dim = r * c + return aggr_i / aggr, aggr_j / aggr + # return aggr_i / dim, aggr_j / dim + + +def centroid_test(fname, n, trials, func, img_p=identity): + for i in range(1, n+1): + for j in range(1, trials+1): + cf = fname.format(i, j) + print(cf) + im = img_p(cv2.imread(cf)) + print(centroid(im, func)) + + +def brightness_test(): + BASE_DIR = '../calib/' + image_name = 'shutter_{0}_iso_{1}_bright_{2}.jpeg' + img_path = BASE_DIR + image_name + shutter = [100, 1000, 5000, 10000] + isos = [100, 400, 800] + brightness = [0, 50, 100] + expo_modes = ['auto', 'very_long'] + for ss in shutter[0:]: + comp = [] + plts = [] + print(ss) + for iso in isos: + name = img_path.format(ss, iso, 'very_long') + imgr = cv2.imread(name) + tp = (imgr, name) + comp.append(tp) + img = cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY) + plts.append((FM(img, FM.HOR, img.shape[0] // 2).extract_array(), name)) + compare_images(ilist=comp) + compare_data_plots(ilist=plts) + + +gray_p = lambda img, r, c: img.item(r, c) + +if __name__ == '__main__': + #centroid_test("../testpic/img_{0}_{1}.png", 25, 3, gray_p, img_p=grayscale) + # centroid_test("../testpic/img_{0}_{1}.png", 25, 3, rel_lumin) + + """img = cv2.imread("../testpic/png_1_1.png") + plot_show_data(abs_detect(img, 0, 'v', rel_lumin))""" + + """img = cv2.imread("../testpic/png_1_1.png") + print(img.shape) + cv2.imshow('all', img) + gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + cv2.imshow('gray', gs) + print(sum(centers) / len(centers)) + print(max_method(gs)) + record_file(centers, 'centers.txt') + + while True: + prompt = input("type in an index to draw or q to quit") + if prompt == 'q': + break + else: + plot_i(int(prompt)) + + centers = [] + for i in range(gs.shape[1]): + grad = grad_detect(gs, i, 'v', rel_lumin) + max_v = max(range(len(grad)), key=lambda i: grad[i]) + min_v = min(range(len(grad)), key=lambda i: grad[i]) + centers.append((max_v + min_v) / 2)""" + + #visualize_data("../testpic/", "../absdataplot/", 10, 'h', rel_lumin, data_p=abs_detect) + brightness_test() + diff --git a/img_rec_module/log.docx b/img_rec_module/log.docx new file mode 100644 index 0000000..b574f98 Binary files /dev/null and b/img_rec_module/log.docx differ diff --git a/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(100, 200).txt b/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(100, 200).txt new file mode 100644 index 0000000..06ac13b --- /dev/null +++ b/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(100, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 291.03499068467625, poly: 289.2972972972973, gaussian: 289.8178178178178; +y: edge_centroid: 250.59977810650898, poly: 256.96096096096096, gaussian: 216.0 diff --git a/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(100, 300).txt b/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(100, 300).txt new file mode 100644 index 0000000..c66127c --- /dev/null +++ b/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(100, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 291.03499068467625, poly: 289.2972972972973, gaussian: 289.8408408408408; +y: edge_centroid: -1, poly: 0, gaussian: 0 diff --git a/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(120, 300).txt b/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(120, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(490, 50).txt b/img_rec_module/meas/calib4/img_100_{0}/img_100_{0}_(490, 50).txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(100, 150).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(100, 150).txt new file mode 100644 index 0000000..5cc8360 --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(100, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.0200477822787, poly: 474.4554554554555, gaussian: 475.0960960960961; +y: edge_centroid: 319.75075987841956, poly: 352.0, gaussian: 317.5045045045045 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(150, 200).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(150, 200).txt new file mode 100644 index 0000000..c181231 --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(150, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 483.1316033979296, poly: 479.963963963964, gaussian: 472.96596596596595; +y: edge_centroid: 326.8176090597337, poly: 325.0900900900901, gaussian: 325.9259259259259 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(20, 300).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(20, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 250).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 250).txt new file mode 100644 index 0000000..8e70bbf --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 324.4145637296835, poly: 318.4034034034034, gaussian: 328.4984984984985 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 300).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 300).txt new file mode 100644 index 0000000..0858c20 --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 315.5961538461538, poly: 301.93293293293294, gaussian: 314.3693693693694 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 500).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 500).txt new file mode 100644 index 0000000..f65380f --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7850568145749, poly: 483.3743743743744, gaussian: 481.3453453453453; +y: edge_centroid: 307.213521344408, poly: 323.22522522522524, gaussian: 322.5015015015015 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(250, 300).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(250, 300).txt new file mode 100644 index 0000000..41d732a --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(250, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.7974399164053, poly: 480.7717717717718, gaussian: 478.4754754754755; +y: edge_centroid: 315.5961538461538, poly: 301.93293293293294, gaussian: 314.3693693693694 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(30, 100).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(30, 100).txt new file mode 100644 index 0000000..9a0a702 --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(30, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 477.7408469342743, poly: 474.3133133133133, gaussian: 475.96296296296293; +y: edge_centroid: 312.8755548978987, poly: 312.6666666666667, gaussian: 313.2162162162162 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(300, 350).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(300, 350).txt new file mode 100644 index 0000000..9fcb0bd --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(300, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 478.06332670022255, poly: 479.2022022022022, gaussian: 478.8808808808809; +y: edge_centroid: 315.1341000267452, poly: 314.23823823823824, gaussian: 347.0 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(300, 400).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(300, 400).txt new file mode 100644 index 0000000..002895d --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 478.06332670022255, poly: 479.2022022022022, gaussian: 478.8808808808809; +y: edge_centroid: 310.42203052422025, poly: 313.1111111111111, gaussian: 312.4864864864865 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(350, 400).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(350, 400).txt new file mode 100644 index 0000000..99ae642 --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(350, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 476.5766195632225, poly: 479.4594594594595, gaussian: 477.3223223223223; +y: edge_centroid: 310.42203052422025, poly: 313.1111111111111, gaussian: 312.4864864864865 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(400, 450).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(400, 450).txt new file mode 100644 index 0000000..0101161 --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(400, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 481.25031779661015, poly: 481.04804804804803, gaussian: 480.36036036036035; +y: edge_centroid: 320.51106920874355, poly: 322.13113113113116, gaussian: 321.7687687687688 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(450, 550).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(450, 550).txt new file mode 100644 index 0000000..f859e85 --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(450, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 480.90588235294115, poly: 479.13613613613614, gaussian: 479.12312312312315; +y: edge_centroid: 316.68044077134977, poly: 313.73273273273276, gaussian: 315.5095095095095 diff --git a/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(50, 100).txt b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(50, 100).txt new file mode 100644 index 0000000..c0a15fe --- /dev/null +++ b/img_rec_module/meas/calib4/img_130_{0}/img_130_{0}_(50, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 474.3070001323277, poly: 472.996996996997, gaussian: 472.81081081081084; +y: edge_centroid: 312.8755548978987, poly: 312.6666666666667, gaussian: 313.2162162162162 diff --git a/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(250, 100).txt b/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(250, 100).txt new file mode 100644 index 0000000..f2af609 --- /dev/null +++ b/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(250, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 277.76777028087247, poly: 281.1461461461461, gaussian: 278.5765765765766; +y: edge_centroid: 302.41199200532964, poly: 296.71771771771773, gaussian: 299.7837837837838 diff --git a/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(250, 50).txt b/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(250, 50).txt new file mode 100644 index 0000000..b79b4f9 --- /dev/null +++ b/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(250, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 277.76777028087247, poly: 281.1461461461461, gaussian: 278.5765765765766; +y: edge_centroid: 266.9218650877565, poly: 284.07207207207205, gaussian: 279.6546546546547 diff --git a/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(300, 550).txt b/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(300, 550).txt new file mode 100644 index 0000000..84b1934 --- /dev/null +++ b/img_rec_module/meas/calib4/img_133_{0}/img_133_{0}.png_(300, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 81.92717111682785, poly: 81.3933933933934, gaussian: 81.24724724724724; +y: edge_centroid: 289.13216374268995, poly: 286.6216216216216, gaussian: 288.1381381381381 diff --git a/img_rec_module/meas/calib4/img_134_{0}/img_134_{0}.png_(200, 150).txt b/img_rec_module/meas/calib4/img_134_{0}/img_134_{0}.png_(200, 150).txt new file mode 100644 index 0000000..0d980c5 --- /dev/null +++ b/img_rec_module/meas/calib4/img_134_{0}/img_134_{0}.png_(200, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 58.87142186766776, poly: 57.72372372372372, gaussian: 58.56256256256256; +y: edge_centroid: 298.5141452126122, poly: 298.53453453453454, gaussian: 299.05505505505505 diff --git a/img_rec_module/meas/calib4/img_157_{0}/img_157_{0}.png_(250, 450).txt b/img_rec_module/meas/calib4/img_157_{0}/img_157_{0}.png_(250, 450).txt new file mode 100644 index 0000000..bc8985f --- /dev/null +++ b/img_rec_module/meas/calib4/img_157_{0}/img_157_{0}.png_(250, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 231.9349172144786, poly: 229.16516516516518, gaussian: 230.4204204204204; +y: edge_centroid: 324.7964368509638, poly: 320.92092092092093, gaussian: 322.7027027027027 diff --git a/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(100, 500).txt b/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(100, 500).txt new file mode 100644 index 0000000..7b9d1b7 --- /dev/null +++ b/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(100, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 225.6382858488344, poly: 219.85385385385385, gaussian: 223.6846846846847; +y: edge_centroid: 326.9082845283447, poly: 329.64864864864865, gaussian: 329.45245245245246 diff --git a/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(300, 400).txt b/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(300, 400).txt new file mode 100644 index 0000000..a009916 --- /dev/null +++ b/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 218.77561608300925, poly: 224.71471471471472, gaussian: 223.88388388388387; +y: edge_centroid: 325.48699770378875, poly: 323.76576576576576, gaussian: 321.72972972972974 diff --git a/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(350, 450).txt b/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(350, 450).txt new file mode 100644 index 0000000..7dca8cd --- /dev/null +++ b/img_rec_module/meas/calib4/img_160_{0}/img_160_{0}_(350, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 221.86800998243837, poly: 223.86086086086087, gaussian: 222.33833833833833; +y: edge_centroid: 324.95901767558263, poly: 319.3243243243243, gaussian: 320.1621621621622 diff --git a/img_rec_module/meas/calib4/img_170_{0}/img_170_{0}_(200, 350).txt b/img_rec_module/meas/calib4/img_170_{0}/img_170_{0}_(200, 350).txt new file mode 100644 index 0000000..deecda3 --- /dev/null +++ b/img_rec_module/meas/calib4/img_170_{0}/img_170_{0}_(200, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 392.6319532908705, poly: 390.93993993993996, gaussian: 391.22222222222223; +y: edge_centroid: 332.7505637119807, poly: 333.94494494494495, gaussian: 333.13613613613614 diff --git a/img_rec_module/meas/calib4/img_170_{0}/img_170_{0}_(200, 450).txt b/img_rec_module/meas/calib4/img_170_{0}/img_170_{0}_(200, 450).txt new file mode 100644 index 0000000..b69498b --- /dev/null +++ b/img_rec_module/meas/calib4/img_170_{0}/img_170_{0}_(200, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 392.6319532908705, poly: 390.93993993993996, gaussian: 391.22222222222223; +y: edge_centroid: 340.36645473811694, poly: 333.6066066066066, gaussian: 333.86686686686687 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(100, 150).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(100, 150).txt new file mode 100644 index 0000000..0564307 --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(100, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 220.7910065139735, poly: 217.15515515515517, gaussian: 220.11711711711712; +y: edge_centroid: 160.24814595075648, poly: 158.1981981981982, gaussian: 155.2112112112112 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(150, 200).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(150, 200).txt new file mode 100644 index 0000000..1f815cd --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(150, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 226.56943727413525, poly: 233.0, gaussian: 231.61461461461462; +y: edge_centroid: -1, poly: 157.03003003003002, gaussian: 159.97997997998 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(200, 250).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(200, 250).txt new file mode 100644 index 0000000..7084079 --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(200, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 224.38829323735553, poly: 221.4204204204204, gaussian: 222.997997997998; +y: edge_centroid: -1, poly: 136.21621621621622, gaussian: 153.43543543543544 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(200, 50).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(200, 50).txt new file mode 100644 index 0000000..751271c --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(200, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 224.38829323735553, poly: 221.4204204204204, gaussian: 222.997997997998; +y: edge_centroid: 159.31560235197594, poly: 147.12512512512512, gaussian: 138.0 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(250, 300).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(250, 300).txt new file mode 100644 index 0000000..e2f1dfc --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(250, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.60011869116025, poly: 215.4144144144144, gaussian: 201.0; +y: edge_centroid: 155.03382867757378, poly: 157.1791791791792, gaussian: 158.998998998999 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(300, 350).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(300, 350).txt new file mode 100644 index 0000000..238ae5c --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(300, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.2786542650262, poly: 231.36236236236238, gaussian: 224.34534534534535; +y: edge_centroid: -1, poly: 139.21621621621622, gaussian: 139.81581581581582 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(350, 400).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(350, 400).txt new file mode 100644 index 0000000..c508eef --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(350, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 218.11615628299896, poly: 221.07207207207207, gaussian: 219.3013013013013; +y: edge_centroid: 155.50516848445383, poly: 152.59459459459458, gaussian: 152.37137137137137 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(400, 450).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(400, 450).txt new file mode 100644 index 0000000..4c33dde --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(400, 450).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 228.5702052689802, poly: 220.84284284284286, gaussian: 200.0; +y: edge_centroid: 148.5988915951851, poly: 134.5095095095095, gaussian: 135.5895895895896 diff --git a/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(50, 100).txt b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(50, 100).txt new file mode 100644 index 0000000..45a7482 --- /dev/null +++ b/img_rec_module/meas/calib4/img_180_{0}/img_180_{0}_(50, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 225.69889181411875, poly: 219.86186186186185, gaussian: 228.002002002002; +y: edge_centroid: 156.60606647930996, poly: 154.3803803803804, gaussian: 151.83083083083082 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(200, 50).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(200, 50).txt new file mode 100644 index 0000000..cb9440f --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(200, 50).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 93.01701701701703, gaussian: 92.54954954954955; +y: edge_centroid: 220.67972613160907, poly: 205.44544544544544, gaussian: 220.13513513513513 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 100).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 100).txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 150).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 150).txt new file mode 100644 index 0000000..4e7e731 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 207.25707213578505, poly: 211.72972972972974, gaussian: 210.05605605605606 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 250).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 250).txt new file mode 100644 index 0000000..0b0c80e --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 218.612658674189, poly: 210.37037037037038, gaussian: 216.64864864864865 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 550).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 550).txt new file mode 100644 index 0000000..5d716b8 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(250, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: 208.3091801113311, poly: 194.96096096096096, gaussian: 207.03603603603602 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(300, 500).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(300, 500).txt new file mode 100644 index 0000000..7669241 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}.png_(300, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.85585585585585, gaussian: 94.37537537537537; +y: edge_centroid: 211.19331646152077, poly: 195.86786786786786, gaussian: 209.42642642642642 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(100, 10).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(100, 10).txt new file mode 100644 index 0000000..c7c4711 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(100, 10).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.53349610865254, poly: 90.78078078078079, gaussian: 90.11711711711712; +y: edge_centroid: 221.0741458686698, poly: 244.62762762762765, gaussian: 258.0 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(100, 400).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(100, 400).txt new file mode 100644 index 0000000..e9008a5 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(100, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.53349610865254, poly: 92.03003003003003, gaussian: 92.93793793793793; +y: edge_centroid: 214.17900156837212, poly: 209.03203203203202, gaussian: 214.83483483483485 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 100).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 100).txt new file mode 100644 index 0000000..34f75b7 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64864864864865; +y: edge_centroid: -1, poly: 196.7027027027027, gaussian: 220.20220220220222 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 300).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 300).txt new file mode 100644 index 0000000..b1e658b --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 215.8282069593912, poly: 200.8108108108108, gaussian: 203.97297297297297 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 350).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 350).txt new file mode 100644 index 0000000..ae51c4c --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 215.93902685241267, poly: 199.14814814814815, gaussian: 201.96296296296296 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 40).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 40).txt new file mode 100644 index 0000000..35d04b6 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 40).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 92.74474474474475, gaussian: 92.64264264264264; +y: edge_centroid: 213.46588200238375, poly: 187.52852852852854, gaussian: 250.0 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 400).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 400).txt new file mode 100644 index 0000000..dd9188e --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.21657196969699, poly: 93.01701701701703, gaussian: 92.54954954954955; +y: edge_centroid: 214.17900156837212, poly: 209.03203203203202, gaussian: 214.83483483483485 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(240, 320).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(240, 320).txt new file mode 100644 index 0000000..beaeadc --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.95545171339562, poly: 92.43843843843844, gaussian: 92.54054054054055; +y: edge_centroid: 216.32595947660937, poly: 197.66066066066065, gaussian: 203.43843843843842 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(250, 100).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(250, 100).txt new file mode 100644 index 0000000..d73fc36 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(250, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.0, poly: 90.61461461461461, gaussian: 90.76176176176176; +y: edge_centroid: -1, poly: 198.59459459459458, gaussian: 236.03003003003005 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(30, 300).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(30, 300).txt new file mode 100644 index 0000000..8c9068f --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(30, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 106.90241734802697, poly: 130.08608608608608, gaussian: 137.0; +y: edge_centroid: 215.8282069593912, poly: 200.8108108108108, gaussian: 203.94794794794794 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(300, 150).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(300, 150).txt new file mode 100644 index 0000000..00f639b --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(300, 150).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.85585585585585, gaussian: 94.37537537537537; +y: edge_centroid: 207.25707213578505, poly: 211.72972972972974, gaussian: 210.05605605605606 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(300, 400).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(300, 400).txt new file mode 100644 index 0000000..07a7d5e --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(300, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.67445813854653, poly: 94.72372372372372, gaussian: 94.26126126126127; +y: edge_centroid: 214.17900156837212, poly: 194.24424424424424, gaussian: 197.8028028028028 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(350, 200).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(350, 200).txt new file mode 100644 index 0000000..031f3ef --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(350, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30997090716743, poly: 92.7907907907908, gaussian: 93.55555555555556; +y: edge_centroid: 219.13322627053438, poly: 210.43043043043042, gaussian: 218.1951951951952 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(400, 250).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(400, 250).txt new file mode 100644 index 0000000..525a96e --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(400, 250).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.80265120132562, poly: 93.7977977977978, gaussian: 93.90190190190191; +y: edge_centroid: 218.612658674189, poly: 210.37037037037038, gaussian: 216.64864864864865 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(450, 300).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(450, 300).txt new file mode 100644 index 0000000..013cc84 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(450, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 94.75074524191695, poly: 94.30530530530531, gaussian: 94.26426426426427; +y: edge_centroid: 215.8282069593912, poly: 211.35135135135135, gaussian: 215.15915915915917 diff --git a/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(50, 550).txt b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(50, 550).txt new file mode 100644 index 0000000..7db67f4 --- /dev/null +++ b/img_rec_module/meas/calib4/img_59_{0}/img_59_{0}_(50, 550).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.89583756345176, poly: 92.57657657657657, gaussian: 92.48648648648648; +y: edge_centroid: 208.3091801113311, poly: 189.6096096096096, gaussian: 209.03303303303304 diff --git a/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}.png_(200, 600).txt b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}.png_(200, 600).txt new file mode 100644 index 0000000..ed07d5f --- /dev/null +++ b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}.png_(200, 600).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.32846573208725, poly: 92.23423423423424, gaussian: 92.21921921921921; +y: edge_centroid: 196.4742684157417, poly: 195.8928928928929, gaussian: 196.3783783783784 diff --git a/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(200, 500).txt b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(200, 500).txt new file mode 100644 index 0000000..a483322 --- /dev/null +++ b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.32846573208725, poly: 92.03003003003003, gaussian: 92.08708708708708; +y: edge_centroid: 210.0317535296279, poly: 189.0990990990991, gaussian: 212.75375375375376 diff --git a/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(240, 320).txt b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(240, 320).txt new file mode 100644 index 0000000..302af08 --- /dev/null +++ b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 92.0877174261018, poly: 92.41741741741741, gaussian: 92.28528528528528; +y: edge_centroid: 221.40502732240432, poly: 205.07807807807808, gaussian: 206.8998998998999 diff --git a/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(400, 100).txt b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(400, 100).txt new file mode 100644 index 0000000..b340acb --- /dev/null +++ b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(400, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30595634480204, poly: 94.14414414414415, gaussian: 93.81681681681681; +y: edge_centroid: 307.8291557805356, poly: 354.0, gaussian: 308.5155155155155 diff --git a/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(400, 400).txt b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(400, 400).txt new file mode 100644 index 0000000..461ddb4 --- /dev/null +++ b/img_rec_module/meas/calib4/img_60_{0}/img_60_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.30595634480204, poly: 94.14414414414415, gaussian: 93.81681681681681; +y: edge_centroid: 212.21240264432728, poly: 190.33833833833833, gaussian: 193.35135135135135 diff --git a/img_rec_module/meas/calib4/img_61_{0}/img_61_{0}_(240, 320).txt b/img_rec_module/meas/calib4/img_61_{0}/img_61_{0}_(240, 320).txt new file mode 100644 index 0000000..750c5f3 --- /dev/null +++ b/img_rec_module/meas/calib4/img_61_{0}/img_61_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 91.9518581931715, poly: 92.18618618618618, gaussian: 91.98798798798799; +y: edge_centroid: 218.40512573697507, poly: 201.44444444444446, gaussian: 206.24924924924926 diff --git a/img_rec_module/meas/calib4/img_61_{0}/img_61_{0}_(400, 400).txt b/img_rec_module/meas/calib4/img_61_{0}/img_61_{0}_(400, 400).txt new file mode 100644 index 0000000..7978897 --- /dev/null +++ b/img_rec_module/meas/calib4/img_61_{0}/img_61_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 93.19376913380157, poly: 94.17417417417417, gaussian: 94.03603603603604; +y: edge_centroid: 212.52264302981456, poly: 190.97897897897897, gaussian: 194.45845845845847 diff --git a/img_rec_module/meas/calib4/img_62_{0}/img_62_{0}_(240, 320).txt b/img_rec_module/meas/calib4/img_62_{0}/img_62_{0}_(240, 320).txt new file mode 100644 index 0000000..d58a228 --- /dev/null +++ b/img_rec_module/meas/calib4/img_62_{0}/img_62_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 178.91803535934721, poly: 178.44144144144144, gaussian: 178.33333333333334; +y: edge_centroid: -1, poly: 184.47747747747746, gaussian: 265.93293293293294 diff --git a/img_rec_module/meas/calib4/img_63_{0}/img_63_{0}_(240, 320).txt b/img_rec_module/meas/calib4/img_63_{0}/img_63_{0}_(240, 320).txt new file mode 100644 index 0000000..52cbf69 --- /dev/null +++ b/img_rec_module/meas/calib4/img_63_{0}/img_63_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 178.97878718007834, poly: 178.87387387387386, gaussian: 178.72972972972974; +y: edge_centroid: -1, poly: 182.97297297297297, gaussian: 227.4954954954955 diff --git a/img_rec_module/meas/calib4/img_73_{0}/img_73_{0}_(400, 400).txt b/img_rec_module/meas/calib4/img_73_{0}/img_73_{0}_(400, 400).txt new file mode 100644 index 0000000..3c97a4b --- /dev/null +++ b/img_rec_module/meas/calib4/img_73_{0}/img_73_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 283.485064401206, poly: 323.0, gaussian: 286.4864864864865; +y: edge_centroid: 195.9362609551483, poly: 189.6016016016016, gaussian: 190.22222222222223 diff --git a/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(100, 300).txt b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(100, 300).txt new file mode 100644 index 0000000..462740a --- /dev/null +++ b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(100, 300).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 278.09682467236087, poly: 268.2682682682683, gaussian: 274.5575575575576; +y: edge_centroid: 174.44361763022326, poly: 175.0990990990991, gaussian: 174.0 diff --git a/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(150, 350).txt b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(150, 350).txt new file mode 100644 index 0000000..3abe0ab --- /dev/null +++ b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(150, 350).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 264.6934011476264, poly: 267.4674674674675, gaussian: 265.3213213213213; +y: edge_centroid: 212.65002063557583, poly: 193.16216216216216, gaussian: 205.15315315315314 diff --git a/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(200, 100).txt b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(200, 100).txt new file mode 100644 index 0000000..ec7eba6 --- /dev/null +++ b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(200, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 299.2048811389324, poly: 298.0, gaussian: 299.0900900900901; +y: edge_centroid: 212.06545603775513, poly: 211.82282282282281, gaussian: 212.06006006006007 diff --git a/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(200, 400).txt b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(200, 400).txt new file mode 100644 index 0000000..0fc7e6b --- /dev/null +++ b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 299.2048811389324, poly: 298.0, gaussian: 299.0900900900901; +y: edge_centroid: 216.82302078726215, poly: 193.26126126126127, gaussian: 186.53453453453454 diff --git a/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(250, 150).txt b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(250, 150).txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(250, 450).txt b/img_rec_module/meas/calib4/img_74_{0}/img_74_{0}_(250, 450).txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/meas/calib4/img_78_{0}/img_78_{0}_(400, 260).txt b/img_rec_module/meas/calib4/img_78_{0}/img_78_{0}_(400, 260).txt new file mode 100644 index 0000000..6892c16 --- /dev/null +++ b/img_rec_module/meas/calib4/img_78_{0}/img_78_{0}_(400, 260).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 366.0705646776132, poly: 403.0, gaussian: 402.0; +y: edge_centroid: 206.59396835595538, poly: 198.7157157157157, gaussian: 201.34434434434434 diff --git a/img_rec_module/meas/calib4/img_79_{0}/img_79_{0}_(100, 200).txt b/img_rec_module/meas/calib4/img_79_{0}/img_79_{0}_(100, 200).txt new file mode 100644 index 0000000..de27310 --- /dev/null +++ b/img_rec_module/meas/calib4/img_79_{0}/img_79_{0}_(100, 200).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 361.17140024783157, poly: 351.23423423423424, gaussian: 355.06006006006004; +y: edge_centroid: 206.05061553818015, poly: 197.32232232232232, gaussian: 204.25025025025025 diff --git a/img_rec_module/meas/calib4/img_79_{0}/img_79_{0}_(200, 200).txt b/img_rec_module/meas/calib4/img_79_{0}/img_79_{0}_(200, 200).txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/meas/calib4/img_80_{0}/img_80_{0}_(200, 300).txt b/img_rec_module/meas/calib4/img_80_{0}/img_80_{0}_(200, 300).txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/meas/calib4/img_80_{0}/img_80_{0}_(300, 280).txt b/img_rec_module/meas/calib4/img_80_{0}/img_80_{0}_(300, 280).txt new file mode 100644 index 0000000..5df82f5 --- /dev/null +++ b/img_rec_module/meas/calib4/img_80_{0}/img_80_{0}_(300, 280).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 311.3298049296839, poly: 319.7637637637638, gaussian: 319.5735735735736; +y: edge_centroid: -1, poly: 0, gaussian: 0 diff --git a/img_rec_module/meas/calib4/img_86_{0}/img_86_{0}.png_(150, 100).txt b/img_rec_module/meas/calib4/img_86_{0}/img_86_{0}.png_(150, 100).txt new file mode 100644 index 0000000..639b64b --- /dev/null +++ b/img_rec_module/meas/calib4/img_86_{0}/img_86_{0}.png_(150, 100).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 122.42161046111492, poly: 124.84684684684684, gaussian: 124.58358358358359; +y: edge_centroid: 268.99951226309923, poly: 263.5865865865866, gaussian: 263.9189189189189 diff --git a/img_rec_module/meas/calib4/img_86_{0}/img_86_{0}.png_(200, 400).txt b/img_rec_module/meas/calib4/img_86_{0}/img_86_{0}.png_(200, 400).txt new file mode 100644 index 0000000..34cfc9d --- /dev/null +++ b/img_rec_module/meas/calib4/img_86_{0}/img_86_{0}.png_(200, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 326.7772293517605, poly: 326.3703703703704, gaussian: 326.84684684684686; +y: edge_centroid: 247.36609869795853, poly: 246.3783783783784, gaussian: 244.63563563563565 diff --git a/img_rec_module/meas/calib4/img_97_{0}/img_97_{0}_(240, 320).txt b/img_rec_module/meas/calib4/img_97_{0}/img_97_{0}_(240, 320).txt new file mode 100644 index 0000000..5d771cc --- /dev/null +++ b/img_rec_module/meas/calib4/img_97_{0}/img_97_{0}_(240, 320).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 249.44900531810134, poly: 248.6956956956957, gaussian: 249.67667667667666; +y: edge_centroid: 259.66796296933614, poly: 261.015015015015, gaussian: 261.4074074074074 diff --git a/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(200, 500).txt b/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(200, 500).txt new file mode 100644 index 0000000..653e98a --- /dev/null +++ b/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(200, 500).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 248.7235796541028, poly: 252.58858858858858, gaussian: 249.82882882882882; +y: edge_centroid: 262.84957891453524, poly: 258.80680680680683, gaussian: 260.3963963963964 diff --git a/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(373, 234).txt b/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(373, 234).txt new file mode 100644 index 0000000..550694b --- /dev/null +++ b/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(373, 234).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 246.9395417318486, poly: 256.96296296296293, gaussian: 253.03203203203202; +y: edge_centroid: 280.6590576754352, poly: 258.1631631631632, gaussian: 257.65765765765764 diff --git a/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(400, 400).txt b/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(400, 400).txt new file mode 100644 index 0000000..ceb5b0e --- /dev/null +++ b/img_rec_module/meas/calib4/img_99_{0}/img_99_{0}_(400, 400).txt @@ -0,0 +1,2 @@ +x: edge_centroid: 263.7749063060128, poly: 262.6166166166166, gaussian: 263.40440440440443; +y: edge_centroid: 255.54966073622904, poly: 253.15915915915917, gaussian: 254.85185185185185 diff --git a/img_rec_module/meas/convergence_naive_std1.5.csv b/img_rec_module/meas/convergence_naive_std1.5.csv new file mode 100644 index 0000000..cd215cf --- /dev/null +++ b/img_rec_module/meas/convergence_naive_std1.5.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.32510644540474,217.16136239737153,0.6182377010412883,3.437860778311802 +60,94.65266061580076,212.6177146123835,0.765212453826913,3.6739543947311417 +61,94.61401364788813,214.22486674207525,0.8412783951060775,3.3611479966616367 +62,178.35158089537316,221.847988586586,0.9403897569392258,2.7273751079265014 +63,178.77936146556561,222.1382787309958,0.9463391509324931,2.657550420078367 +64,178.51870559728806,224.63353150383256,1.0071690155319815,4.55962144903764 +65,265.4101380731767,202.08888192291917,2.9369222816228366,13.78987315189462 +66,265.6989344950027,207.74953132239617,3.0204535635810923,3.1036977294508623 +67,263.08964545761665,205.42187070515965,4.431842546811981,2.358949151269513 +73,273.4831703233573,203.64459660353015,7.04945617162013,7.94901069703423 +74,273.07076432835294,204.06679372614934,6.89788799009703,8.626898083569905 +75,272.1738130844689,203.78689920903042,7.135173768291136,8.947454341776009 +77,351.279939281129,204.46673588623955,6.045106258240715,3.909769225255067 +78,351.9201632813107,203.06242013391767,6.757744778249452,2.7563070866266073 +79,351.5222044161429,203.62412359740455,6.8762860015843,2.4772722541589194 +80,311.4321457450739,203.50054128359008,6.239505058348041,5.6340319630028475 +81,309.7350900557848,200.1189157557026,6.786112432854393,3.7532785541909637 +82,311.0972982876571,199.22509501936744,6.892343194786746,3.2293740231207715 +83,311.16518083066256,199.25055482945473,7.010045021779638,2.7712015561427807 +84,131.23754348858074,252.26390581496943,4.531133252555627,5.315476076691151 +85,130.00327880890623,253.73048027246645,5.394441049750279,5.395681634052309 +86,129.11103579380026,255.02208812060525,5.279052334030264,5.613375422087035 +87,129.85581048785428,254.17406429530502,5.674102333754549,5.78050786879303 +88,173.6706310017366,256.75225947929334,5.866553313440161,5.378715368726579 +89,173.10982411900085,251.5446731759652,6.879373651171615,2.5523562516540665 +90,172.75015150634195,248.10188260321166,7.047271185711796,2.007986084013029 +91,174.99352952512763,256.09184964129855,5.235714833141598,3.313609851436995 +92,213.8661562238959,255.830056426469,6.707076930736432,2.458271305003053 +93,213.4468844061598,254.50412813549863,6.518799611232329,3.278464480563131 +94,212.79962250914713,255.43887452853883,6.766022500672822,2.705140416783796 +95,212.4983956286567,255.64768535613388,8.38922518196436,1.1489063054666482 +96,256.74603239035036,253.07252663449168,6.865986829223564,2.6663521829239336 +97,256.72510650144056,252.79028393976105,6.828380413657813,2.603426429287444 +98,256.8221014295006,252.7889068984261,6.821267955887984,2.7406932410109657 +99,256.95819898248175,253.16068182860602,6.8533044126794715,2.6857466734869786 +100,298.0833417924816,255.11218204520893,6.68748523503982,2.5312282089724154 +101,298.2658386968296,255.0162251091937,6.972265462941957,2.391655492853278 +102,298.07594362921077,254.9831987261273,6.694673144383624,2.446242469655284 +103,298.2353998576801,255.3627222097245,6.715087554789903,2.4808962893039186 +104,337.3091830161018,251.4473414930906,6.239563573099407,3.9949672494208963 +105,338.50157961505033,251.25839644260412,5.899400220598736,4.074419748640388 +107,338.2423485650474,252.9079453166733,5.969934007979263,2.2333183687357447 +108,338.5801482804283,250.28634549329695,5.539855669597802,4.858284281787599 +113,275.59876651558005,307.46189968535816,3.9436251120891708,5.10683987641902 +114,276.1686694961398,308.57204326970526,5.356119731482595,4.772688054972327 +115,276.8157548930389,309.70713161790934,5.002026768143788,2.583003901658473 +116,277.0444072504442,310.2242983789689,5.093238900500282,3.2415570106605673 +117,308.9662148000703,311.7697205368066,2.2792009412856546,5.410806300828905 +118,308.46078668862316,311.92138655579373,2.3941030136668364,5.421098042888929 +119,308.7154324709243,310.66348827344274,2.3309057135226756,3.5206003610285515 +120,308.24434710841035,311.76621158888577,2.470183201647586,5.328252659543528 +121,363.68682214557504,313.51876571316154,3.8856640715067936,4.058166847376938 +122,349.14935421068765,314.03103766657546,2.329671674152375,2.776838944594597 +123,367.58471869225144,311.42252084107196,3.923615531492719,4.789041635546242 +124,366.2205639783599,312.0147408219617,3.7204140057381685,3.975220041758474 +125,443.4421791253585,317.0454064337059,3.8532517828906077,3.2746926716250857 +126,442.3085572430623,315.4881011805151,2.1017637979425676,5.638134747002355 +127,444.0456031701909,315.5453281878035,2.457515375747752,5.721606221790266 +128,441.29274663891704,315.9751158703776,2.8445523791239578,3.391499475116884 +129,480.1126176912876,317.72874213425126,1.9715561431765554,2.8371867515089835 +130,480.7028108376642,316.04711281162145,2.1090053401415116,3.7239493086812376 +131,480.3028282756367,316.9828674719394,1.931835914107085,2.6912419384547803 +132,480.759709821911,316.6390215996198,1.8855815838100882,3.2368313913566618 +133,9.357026815909922,301.1394481670515,7.424860692299219,3.8886973359748533 +134,60.799946985869205,290.82662639382374,2.410669490697829,3.3307667086551547 +135,60.28851015248002,299.3626408593879,2.610803253456402,3.4448392908334102 +136,59.58730981243586,299.348986354774,2.4093805788992184,3.557779220380588 +137,103.27374468276936,295.56230309563284,2.5132133127505014,4.351160826227996 +138,99.75383058106173,296.569880707365,2.5218334720238236,3.501899754104677 +139,95.32232328874625,296.73397752555695,2.877040509030959,3.4555743629781466 +140,100.87147176733903,296.3324977713732,2.4143008563576176,3.405547995808848 +141,119.67590393924556,299.5719162206477,2.715209640937237,2.3146688915381275 +142,117.02401243356974,298.35207687180383,3.08539437068056,3.0048819093528643 +143,116.04574600753108,299.0124296372606,2.8382177918151514,3.279021572744144 +144,117.37742445192025,299.4258416995056,3.1697222157479636,3.228779441784994 +145,142.9769721583903,296.5366900343606,3.0832619899763425,2.644094161149235 +146,144.05541849455753,296.38389634445554,2.9996657202962216,2.5996279341099453 +147,142.7610177499935,296.49057527125143,3.132429288120055,2.6497556402515237 +148,140.654399096409,296.487509133948,3.0056568959849406,2.058048941223319 +149,183.71806867676824,297.5062440925511,2.457573643605339,3.0504821593031735 +150,183.33793283890802,297.31881173151646,2.392042666256841,3.050918286277636 +151,183.61600393859536,296.51652050691774,2.4097480630875605,2.764147393280351 +152,183.8339373966336,297.2945340604019,2.460682969826688,3.050060229583357 +153,181.09589492836406,329.6242218226362,1.0425141465757852,3.0368750466096333 +154,186.11052367996277,329.36778207951437,1.3324891141111836,3.0102790481884694 +155,186.71507659948506,329.31046601919013,1.491127987331188,2.737120605219304 +156,186.77967822458413,329.3378404603494,1.4948700160207713,2.734563650578621 +157,230.65228943659753,327.7840930500721,2.295828556135942,2.4982820936800283 +158,208.88398865586805,327.9985148865243,2.02425621449308,2.350854989534598 +159,230.76774042649313,328.3139314865929,1.058343333489383,2.1110955225257957 +160,252.12645006163774,327.8829847714941,1.9966581003411814,2.5372848351369273 +161,273.4567736740019,329.5617685669899,1.9537976371799024,2.0154389968753095 +162,282.2315955976967,329.51993412315335,1.6558383645274921,2.0452106688498017 +163,273.720574310258,329.68024219956664,1.5653369253681564,1.8342890718749 +164,273.889758529857,330.16719840873463,1.5821177076586581,1.694040868940706 +165,313.5406083274413,330.6880662983543,1.5169373766112113,1.9512244512786259 +166,312.99217961793585,330.84544281473285,1.9687039019856765,2.6822749686071305 +167,313.7630009835721,330.8583984920328,1.4848333229111295,1.9827954471887683 +168,312.9401442321904,330.7254552672906,1.7568824225422763,1.9323110607855833 +169,395.7207767219437,332.183165147594,2.4577717664195537,1.7621285751654179 +170,395.3337266028771,331.43381176706987,2.181281870585342,3.1337432803521126 +171,395.85186369230047,332.27068551595306,2.518966823398722,1.7204609744266823 +172,395.8084329126563,332.26796527945555,2.6126143387145087,1.724913210963549 +173,172.9730835697278,153.07041804847032,2.9494726617733757,3.382217579007034 +174,167.91626071048515,153.50090831100303,2.2490783825049045,3.4124393018031505 +175,174.36354763148583,153.16813701756828,3.0454139103327917,3.4583182798940344 +176,163.9948808388554,153.12115036518048,2.245850905919589,3.0039836826659077 +177,217.69107890505612,155.58013869177068,2.7767507060557537,3.794972875980232 +178,214.66253412696085,155.42760092218833,2.282992010999303,3.7924195042280746 +179,217.2668815139982,155.37466732788673,2.82114799379885,3.7715102977100545 +180,213.54537138523426,155.3242530398654,2.39080632265553,3.8737974440740692 +181,261.6939418857524,157.09312093358466,2.9274288743236836,4.2654996092602575 +182,259.5388851666542,156.21847108548155,2.740600451522983,4.256469485200473 +183,261.7749420583441,156.80848263234637,2.8761845595169624,3.611268367181998 +184,261.7034113220799,157.33345113871377,2.9950641148825974,3.4845516638308904 +185,303.89901305026916,155.6612518414893,2.621571563900723,3.473866833204008 +186,301.62587627334796,157.29265691699584,2.567822100277209,3.8190983468951436 +187,302.2849628418849,157.1968491242557,3.008452770801469,3.8181849057828567 +188,303.7565642594758,155.85469430778133,2.429239927505623,3.326076201679362 +189,384.98371808681327,157.38821592622213,3.1474479877455135,2.841847047972341 +190,385.6953493035584,155.9304125075569,3.6373602156895406,3.649388391215581 +191,386.1522285343919,157.13110788307986,3.4178090658584948,1.681812080594319 +192,385.09319956411656,157.18765906545738,3.129473983251964,2.975867208927914 +1 +59,93.00875717999857,213.0864805157829,0.5227911458975513,6.19713029420415 +60,94.33424540812612,209.6207769002175,0.712959043184757,5.35016277729406 +61,95.1076356890004,210.44116297321946,0.8764776639925613,5.547156704495216 +62,207.5747279334015,229.35385437625325,0.5721218590130254,7.308688366893414 +63,178.26435087496964,230.13928425075747,0.9163078266059032,7.241140371768349 +64,177.90044660433097,228.64882156245648,0.8264625430894746,6.592321670041416 +65,261.4355459288758,202.518302086519,4.641943406474736,13.108375146006386 +66,263.67870524819034,208.7072384357703,3.5858326934539724,2.433228596876354 +67,262.17751550130487,206.93217537761328,3.452444759098905,3.8722633351342384 +73,271.56705521542676,202.40830594251935,6.020267230118504,8.477756512699672 +74,271.73829194020016,202.86157549101065,6.298067280843489,8.419553297292511 +75,271.44195864454383,203.13378150076727,6.235685371158418,8.78878791063504 +77,350.3978097520949,205.99099129354195,5.486198418330991,4.23015499642844 +78,350.8542007403272,204.8726031135868,5.884173027734943,2.402879521643992 +79,350.33767761544766,202.27664047975287,8.070802178703657,1.9426946744270117 +80,311.14553424067776,202.4869088895573,6.8627096705514905,3.849897420660647 +81,308.5842159554098,198.77298238575344,6.52057770401923,6.006445353466768 +82,310.7458930121221,195.62555942687163,5.367642235757289,7.169712735992463 +83,310.4462741092919,196.04905416426502,5.898927104709222,7.285208599925228 +84,130.13558933089806,251.82817494602546,7.150925955550858,5.341680351200341 +85,130.18397703583258,253.52743282837022,6.541689138699417,6.299622234665423 +86,127.98319134864182,250.82109733724317,4.738368491228839,2.57221862750688 +87,130.22115190707984,252.63693413729288,7.110134503566371,5.544397590264715 +88,170.3259733642306,255.66266877807428,5.690121369029169,5.9867577312345635 +89,172.0725262476556,250.99873611079994,6.021708452291268,4.7312867200629105 +90,171.99327618907063,249.17936838672563,6.229499399540459,5.078719873917035 +91,172.29510140368106,254.5565739501181,6.451006926460406,3.9136334301532982 +92,213.1828066056623,254.92363133767387,4.131010753144876,3.5262173672553687 +93,212.87022485654242,254.1472663576613,6.024553307028744,4.36937145736752 +94,212.13601387505264,254.10698963113109,5.484917596658879,4.460238419613106 +95,214.87325400509656,254.39310436749193,5.506727817013678,3.986223925190019 +96,255.87095795884755,251.70990738025452,6.095777014998389,3.032297848733597 +97,255.63216745384443,251.63937961156105,6.119873150459129,3.4431842597866478 +98,256.06917412538536,251.38312888217393,6.172049945445992,3.0818160436840696 +99,256.44518378286506,252.4176024183597,6.2866487953086825,2.5551750914715052 +100,297.8311949255675,253.9653171752207,5.924725404966239,3.1672044636908576 +101,297.57833588228533,253.99818141838037,5.944381655046086,2.746686532181724 +102,297.50136975432514,253.68544368933334,5.860286142652836,2.8473861302268335 +103,297.7295288163928,253.7737365687886,6.239643764909305,3.2568997394492816 +104,336.7180543456296,252.55145794454867,5.584269888775618,3.3139652271056144 +105,338.49750522296745,252.07705913627754,5.543320366201012,5.442573748366097 +107,338.0150937851073,252.18608250396494,6.036908819248115,5.0311597932446395 +108,337.2951518337468,250.18224258519146,5.881938681047152,6.491905854296189 +113,273.4815993508197,307.6936923289109,3.1012639427533784,5.154672012501804 +114,275.70060000212146,308.5897280752863,3.9037828113839366,4.201910703737281 +115,275.8323442926472,308.5631016742169,4.908621601004965,3.639510737864438 +116,275.6606088252997,309.15745128264456,5.248785953237486,4.1594464461611045 +117,306.56743395611335,311.7534996826885,2.112121697069489,5.820314553091814 +118,319.6052247158424,309.2092876138521,3.0994427567914853,8.01149636027687 +119,308.98961216723023,310.3876530882548,1.9815028323151676,4.505358981721892 +120,307.0431037398603,309.3570250757065,2.1228582042961364,8.133763836800041 +121,364.6612653249806,312.867105648696,3.6082645560201403,4.907320783558812 +122,359.5565312405258,310.50474411241805,2.3300472525322222,3.6383073582313625 +123,359.67023843236564,311.274718807607,2.359429636308929,4.812109039516953 +124,359.55652211431163,309.9599256178089,2.821256013884825,3.8133629555932114 +125,444.4021410207277,317.8526352360211,4.078133482194948,3.9911353122263296 +126,439.64702159418067,315.15017744463006,2.254461458911636,5.747036062574868 +127,440.69585939100426,315.0579828759502,2.7149707354695605,5.752920657180591 +128,441.8625387527503,317.7326376075549,3.3446365437819154,4.190002229264773 +129,478.5750112776985,317.8659165254805,1.7655709538040265,3.094544391955392 +130,480.50423944788866,317.3650260367778,1.6290524950029868,3.015416485400363 +131,478.66450057520063,316.38942944947695,1.7953728376964107,2.42227888620822 +132,483.0153971429184,314.7305690623162,2.7300211118973263,3.080445570051542 +133,90.20291039246604,298.07507002916145,7.598743409857649,4.552890998174248 +134,57.81287299171998,292.38407844216607,2.514015918277811,5.136006470534924 +135,56.72481683615359,300.0118009139173,2.857620857781098,4.750166949488199 +136,45.96616366715866,299.693904996051,2.6917302124926694,4.645496991603487 +137,88.02035707489331,293.3669429657606,2.0117005484316364,3.9293747558559278 +138,160.04855077999034,293.33750956777976,2.7841652419514227,3.7908670426694497 +139,353.4092012789472,292.0076334322056,3.014363497918401,2.928043350479415 +140,89.97636900626323,292.9113392808752,2.65494720185284,2.8719276763310857 +141,115.9594791110215,297.7222868684274,1.9069874131620126,3.352456382715099 +142,132.15536640954062,297.2171229012815,2.706901698676143,2.9568780838711826 +143,127.1646193746793,298.2335745308878,2.769134247080161,4.01114038711725 +144,130.87079961636513,297.89834733182647,2.818953624476529,3.8997116282895603 +145,150.31209355255865,296.8214130757569,2.725175079922067,4.209022465413865 +146,148.97786084884208,296.6038327691481,2.7067927491075574,4.17492062013239 +147,150.24661339572495,296.7796929595484,2.810800536874064,4.312780918203187 +148,152.5470386382202,296.79763117851934,2.8754159917495565,3.731793392125523 +149,178.862609212918,295.9186248626812,2.5841961653378953,3.1991556673695176 +150,180.89610810712188,295.92807355671397,1.6842427525491304,3.8890257041235543 +151,180.40049251926752,295.77981228572037,2.6591704134491323,3.917421171009508 +152,179.72946886796663,296.05583778880305,2.564660161772704,3.9159370208085704 +153,185.76625246646185,327.4055525477087,1.9261688345955168,2.5002553115545973 +154,185.68007483081436,328.060632980561,2.609970861940605,1.946219519924639 +155,185.37113250572602,328.73195534315664,2.4795691921165655,3.2840453584363116 +156,185.5418021015136,327.6689562730928,2.375786778236521,2.651340769524802 +157,229.27152294423166,327.3561714417115,2.4437228704779783,3.2195371224858063 +158,232.28441597607784,328.09402673325656,1.357599811770978,3.094542048630364 +159,231.00284475154749,327.9998620514896,1.2108444033536565,2.66674404960965 +160,230.25470725406453,328.0859285158972,1.7316362106698195,2.88263756637543 +161,275.7222561716378,329.45078955534507,1.5401263844373954,1.7585024676985501 +162,747.2675063983792,324.7536431546597,2.1073598387590406,1.9846975991560125 +163,272.00721091330865,328.94613162616673,1.9128906508563452,2.480037037665106 +164,272.2943718583655,329.13463420388416,1.8135422013484646,2.333221321023227 +165,312.27917579462644,330.90999638474113,1.8158878550164057,1.9866753158839707 +166,312.63990435472545,330.70825140967025,1.9310585450982856,3.1257959767437193 +167,312.13911877602334,330.8661550202716,1.8464663431187927,1.573517775693253 +168,312.52858835763556,330.76426646797455,2.161251844547869,1.933118359992701 +169,395.14083600756334,331.87815070527694,1.448023063266429,2.3167851906782087 +170,396.5732738072064,331.21301140029664,2.7671279378720532,3.432678442805089 +171,395.3116027704574,331.9375695732541,1.4531763607459942,2.2989452818042047 +172,396.71305866511483,332.1630656147329,1.4224167184507017,2.910921037939185 +173,172.38094968570545,152.05413649604458,3.009792250294108,3.523757740020178 +174,173.8453388820814,151.9722418163993,2.4225092170582014,3.3547430273206764 +175,173.7469031569836,152.01702715147732,2.992197181370308,3.5878204759260535 +176,173.94321589450442,151.8994649734145,2.441865274900331,3.3191803731856986 +177,220.05954791045562,153.93486125597713,2.916964654294944,5.161796303421409 +178,219.06032109265325,153.8679197592309,3.02283014757281,5.214692401346838 +179,220.20248145797134,153.83037812747935,2.811916018641933,5.135768243874929 +180,219.8402257665675,153.69441590096454,2.365027188775977,5.195182563087241 +181,260.4380890463525,156.1736753615838,3.5506189837569733,4.210885005617385 +182,261.1508899611818,155.0680682988112,2.839394772014497,3.5985227200258616 +183,260.30310151802394,155.61059359790818,3.5432570320956893,3.1707993199082107 +184,260.4910132005214,155.66192708074522,3.478073697651597,3.1191145304607857 +185,300.5406946589481,154.9084556815696,2.3966410747454683,4.257306637411747 +186,301.78308068276635,155.27677811490247,3.0779278021862946,5.064316807047082 +187,302.2761713726962,155.27023677113314,2.993547760611472,5.214144626020445 +188,302.8236206973499,154.69674142960957,2.4778587529647105,4.640007316386941 +189,385.48180701984114,155.92489835616408,3.473675270188691,3.1517197697620283 +190,385.08967578482293,157.6459314691889,3.5586590950004457,2.667151842484689 +191,385.58591970819674,157.30125119156654,3.631613447401373,1.9082302724245561 +192,385.21072355609897,155.7094594652936,3.6798775544177063,3.5067454833259255 +2 +59,92.65376110690876,217.01497137821914,0.8683837090191788,4.157428729871967 +60,94.82990413785946,219.90540926030366,0.7890608958947835,6.846135813191627 +61,94.29121037749401,220.03685469388876,1.0749214557030176,6.838018547816678 +62,177.10956003057285,218.90103728250688,1.3905251660790856,2.7497320728371646 +63,177.74456263111466,220.06649622720403,1.2185587916549738,4.188825256215504 +64,177.4433366943884,223.83295887197295,1.371218908578905,5.2592726336887425 +65,265.6878095601755,206.65513281700575,5.33587015800756,16.669713322142147 +66,269.2923498741563,209.05824066438973,4.66895680216908,5.263799522185158 +67,264.42528410909586,207.364718342118,7.577757476106213,4.472335501339223 +73,280.9764776348652,202.68253855726255,1.6546267117994216,6.318822469408919 +74,274.03045869010333,206.973282686757,7.997571675272475,7.243843769359161 +75,276.0822341347654,205.61933530967025,6.510520268907271,10.3236022000293 +77,352.4139935670206,203.48156974798098,8.32458599948799,4.470725516378897 +78,352.6633237122737,201.43070660774114,8.497380645406677,5.377940688297667 +79,351.62852667070297,202.74208620682512,8.658775240139533,6.487198309406779 +80,310.6751701124307,204.64495746423012,8.062037456416205,7.444446872078048 +81,309.7010694340917,201.889057384221,9.465643221743878,4.651552993103335 +82,310.6335818256993,200.22299800671655,8.67387089777447,4.664159850458751 +83,310.8614265739441,199.458651883236,8.510118775528804,2.8724484284650633 +84,132.03262725456108,249.4924232903857,3.0768121962170567,5.169014220579259 +85,129.09144907108433,251.7203734728845,5.198191014751725,5.290792123590904 +86,128.11492684472694,253.65236303540686,5.978168978981718,4.352921913597757 +87,128.5504980446596,252.95544188750205,5.339963887657365,5.754904964464613 +88,173.85018852313817,255.81968964851026,6.482400441297941,3.4989983294150475 +89,172.52528902354035,249.2499609079768,7.275410666068803,2.2756893414086514 +90,172.38753943021908,247.6577135955906,7.222779487902638,1.831029568977615 +91,174.91415300342587,249.18228108995524,5.447412274608176,0.9909035227650256 +92,212.05665773319856,256.1820062089689,6.711658598234498,2.9976841684576496 +93,212.8172314127949,253.39712914171187,6.857530904039771,3.977160865721656 +94,211.8792430432469,255.82761299122967,7.222038595318558,3.1694534357454573 +95,215.0833848468073,256.1212830567826,8.467407782374746,1.9473456404121796 +96,256.9743035103019,254.71512762526666,7.44290569053337,2.68632372187447 +97,257.1457284865542,253.4535805850962,7.332108489145229,2.4944378698026863 +98,257.03430784028274,254.5812608515072,7.2764048131626184,2.4480433538371873 +99,257.11318563543705,254.84544472082902,7.423089718980076,2.5660592893878267 +100,297.53329552210926,253.81655725507431,6.852565823032563,2.567811443943226 +101,298.60461192426146,254.17438371162478,7.905691877078718,1.825741321015611 +102,297.69407107379396,254.4850393852944,6.836012542442264,1.946205259389151 +103,297.9023244730469,254.38868473138925,6.751896664205788,3.3116178759031087 +104,339.48285905633736,251.81900285371069,5.942208628240243,4.945594824336877 +105,339.1205482251966,251.30122032806455,6.500886426061445,4.808751958411583 +107,338.4272019992697,252.19848894388656,6.48687937625559,2.8213077726348095 +108,339.54299063145817,250.0031283857795,5.812146409240677,5.287653170857336 +113,275.910952296904,305.86738853882827,5.34030651381748,5.289299280058491 +114,276.35015397667075,312.1081102609041,5.162726712460268,6.6369445658697455 +115,279.0736812899919,311.07994680544203,4.951788309478035,5.01744381383027 +116,279.87420391551683,310.72506489150953,4.822827709017515,4.736286987210306 +117,304.24552486172325,309.69865127849215,3.00277312239498,4.555283930061753 +118,302.7212817727547,309.2230592598733,3.16363749983184,6.857616858633486 +119,327.09308351776593,310.69024753529516,5.288987908246067,4.6842841758469556 +120,301.0220842644409,308.7703307062073,3.8966104642189516,6.518991290453131 +121,367.6098676953658,314.58028508890305,9.39615711787979,5.649531231448145 +122,397.3328204276317,315.34567189868795,5.7108612456732715,3.258105059687543 +123,390.7453940415891,311.6470607282421,5.5964184306698455,6.030687385605649 +124,432.23467177419724,311.2122511991688,5.881307854257575,4.563765149392382 +125,446.24432082170046,315.27649965719536,6.395392871846412,2.4772515296514643 +126,438.8511287502254,316.37095567311974,1.799887035029369,6.635379091123845 +127,440.35515062380387,316.80874455617004,2.7747867554906676,6.796381592950393 +128,448.99707714791936,316.64328100115915,4.9199468672846844,3.6299256024726247 +129,480.21281513978687,318.2237602367352,1.939096401014579,3.836710322440239 +130,478.7339197387106,314.27301630895124,2.087142296065961,5.08374236725423 +131,479.4617027213679,318.2468896366567,1.5978214301813713,3.688680674174361 +132,484.13323268726947,316.73499335627196,2.002291195085977,3.781086788196597 +133,85.29652368782442,299.9267050080891,7.827458514431236,3.9374236627298966 +134,59.630826345700406,299.5528993065781,2.293779231438959,5.560856320277098 +135,55.11028578417307,298.40091605755845,2.4753999616786904,3.1001830452921184 +136,52.88374765283322,297.62420743734526,2.052251163735395,3.0356052182771274 +137,102.2627134309745,296.1781450112869,1.2262813798013208,5.212420406396804 +138,78.25837410035345,298.6824898421718,2.6075704778239923,3.377654496084566 +139,109.1163322762621,297.6290300025382,2.3024123744989207,3.1885843136710754 +140,48.41182620962574,297.1931703451722,2.625583107839479,2.7907983124386684 +141,119.51602776789325,300.10453175611184,3.4424531063915236,2.642126479181898 +142,118.1973619086592,298.0334936483938,4.076098186731008,2.6346682961879635 +143,115.46104139376924,297.8312691405318,4.279452761468254,3.2247085556456048 +144,119.86152598306575,298.3571523952646,3.493981329511576,2.953550317426917 +145,145.90006454487417,294.33120612383067,3.8031724141145062,2.4031438376062857 +146,145.39522138169184,293.9045479404022,4.534922195360379,2.5317897016901143 +147,145.56468242678977,294.28930454392895,4.470204993442609,3.0933985628535288 +148,139.98418133069634,294.72850928798835,4.278137116722635,3.048819187424443 +149,184.61384435804203,298.9796024091839,2.529497564999449,4.490567912543599 +150,184.64043155451438,298.7318610841073,2.6174338934133505,4.277160291745099 +151,184.44418125715643,298.25564342712596,2.4439277524700747,4.343490136232689 +152,184.66560803927564,298.18036927693134,2.564579983473208,4.385135450871558 +153,194.19362024463055,330.1400811375832,1.1767713277123986,2.6700939408054847 +154,174.86887852527403,329.979989704711,1.8484097857820594,2.591571956692586 +155,180.79865067404023,329.8562242828808,1.738097755840568,2.338466226674033 +156,179.56170004415435,330.31834841798707,1.7754061019312333,2.638869441184331 +157,231.71308757803595,328.672133593381,2.575835953649238,2.9234623232364685 +158,255.4632386220983,327.6416302142385,4.012448382356306,3.42068392727793 +159,205.50139246153256,329.9023818846584,1.9582108272811507,3.923308113475421 +160,235.88906246092358,329.0473855498786,3.444258781962619,2.6163214632167398 +161,276.3094789576173,330.4608109053376,3.4419490584726287,2.564981348675966 +162,285.59180034302733,329.7481991930167,1.8378511022559236,2.962363935958349 +163,276.28783266348086,330.4003933681143,2.1081569415614108,2.0262424617108703 +164,197.25002629984402,331.7884197277611,1.7077843114772655,1.9623226431578948 +165,288.0915533470578,330.8983776107492,2.6656921890922276,2.4733683795597825 +166,318.99404577369717,330.52622945989987,2.512905677477683,3.0041332311662914 +167,347.80228956810066,330.51035383722933,2.7357481343278547,2.6900125091285605 +168,295.96785278892344,330.8541466179879,2.7327133833859794,2.5553494567631065 +169,399.4046364026606,331.7493713707221,3.23644714671924,1.744053910168871 +170,397.57150520306647,333.3787113091005,2.0553328419425942,2.9972979280312493 +171,399.5202454111206,331.87094628141256,3.319483494438871,1.7408731153504877 +172,399.37556911546983,332.0970117083097,3.2770522011812937,2.0503115948740924 +173,167.59893809491587,154.3249244129017,3.578104764139934,3.3198423220094764 +174,172.84296794779806,154.0436851912386,4.065505613610561,3.1479614150013635 +175,172.53685506876784,153.5142164683417,4.048705697811711,2.906116813730039 +176,172.4903195543538,153.75399965885978,4.181462595099683,3.2085629045903814 +177,219.17346400289313,157.06361150991273,3.7208701762725958,3.977297645616966 +178,218.5571656670773,157.04802019919677,3.903522619785598,4.337287440506104 +179,219.08587325813014,157.06764805172753,3.794218226236283,4.170614188910467 +180,220.20815419984615,156.9157243686214,2.7714160963084615,4.408356106260135 +181,260.19885472358294,157.7365391738532,3.7452159562165885,4.8366413757834135 +182,241.9395975737316,156.28097820179985,3.450826603860176,5.030259376007136 +183,260.2353298294739,156.54302588067847,3.729468016831249,3.948234547478585 +184,260.7848372561543,157.9506538637672,3.5754121929574882,3.800985332770269 +185,302.7343292496292,155.53108168722034,3.3675563663327583,3.3417704291330135 +186,332.63645946919394,156.3859992454305,2.765786036774427,6.391527497892834 +187,284.71333669266966,157.72636771256072,3.3503763444766745,6.365038877320703 +188,304.3997409110315,156.17999029402282,3.740908409488698,2.700855536462382 +189,386.0604531581429,157.4606593487467,3.503153843484056,3.8679991937676528 +190,385.18009669613696,156.2333983389331,3.2976202226268665,3.788089778011118 +191,385.0925046602618,156.67041836007596,2.6210706316937795,3.2806588007554622 +192,386.2128341829654,156.16694016460218,3.3738623057156985,4.160360297012765 diff --git a/img_rec_module/meas/convergence_naive_std2.csv b/img_rec_module/meas/convergence_naive_std2.csv new file mode 100644 index 0000000..9c454aa --- /dev/null +++ b/img_rec_module/meas/convergence_naive_std2.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.33971469075367,218.50270598733297,0.6182377010412883,4.519603519601824 +60,94.65266061580076,212.6177146123835,0.765212453826913,3.6739543947311417 +61,95.41265351990087,214.21478810961165,1.1080389271434514,3.3611479966616367 +62,177.68104319925217,221.8562022028197,1.210105165576976,2.7273751079265014 +63,178.12474883940652,222.14572970009505,1.2756265672756038,2.657550420078367 +64,177.98709471591388,224.6454307841806,1.232576692361491,4.55962144903764 +65,262.5800156706123,202.10797896730915,3.9515122758252583,13.78987315189462 +66,263.12260735580236,208.6888275933953,3.996672369259087,3.8323992242499187 +67,263.2208458621908,207.81872361983278,4.431842546811981,4.012811725696324 +73,273.4831703233573,203.64459660353015,7.04945617162013,7.94901069703423 +74,273.07076432835294,204.06679372614934,6.89788799009703,8.626898083569905 +75,272.1738130844689,203.78689920903042,7.135173768291136,8.947454341776009 +77,351.28674760518,204.59842941618587,6.045106258240715,4.408743803212035 +78,351.93164737416873,203.26383152358028,6.757744778249452,3.4138998666946025 +79,351.51705628039196,203.5492416308136,6.8762860015843,3.019482596125626 +80,311.4321457450739,203.50054128359008,6.239505058348041,5.6340319630028475 +81,309.71370799855777,199.8072317333757,6.786112432854393,5.546655412414925 +82,311.0912672829532,199.1202501566774,6.892343194786746,5.054703376541651 +83,311.1638007195464,199.2269266475195,7.010045021779638,4.7578939104794555 +84,131.25454150771196,252.74638995613617,4.531133252555627,6.22007738425752 +85,130.00327880890623,253.73048027246645,5.394441049750279,5.395681634052309 +86,129.22821068759833,257.7545799264177,5.279052334030264,7.778585552031296 +87,129.85581048785428,254.17406429530502,5.674102333754549,5.78050786879303 +88,173.6706310017366,256.75225947929334,5.866553313440161,5.378715368726579 +89,173.19230063382054,252.91916601625073,6.879373651171615,3.4635068657166914 +90,172.94503754837874,251.33290936706462,7.047271185711796,3.2903077685151048 +91,175.02952167330142,257.0499364883758,5.235714833141598,4.602554026194267 +92,213.7890816038331,254.6249053619213,6.707076930736432,3.4712358181628 +93,213.4468844061598,254.50412813549863,6.518799611232329,3.278464480563131 +94,212.79962250914713,255.43887452853883,6.766022500672822,2.705140416783796 +95,215.7691494277275,256.0321075659609,11.50061919709342,2.706589746451831 +96,256.7694241536286,253.44332189577563,6.865986829223564,3.232990348543302 +97,256.72510650144056,252.79028393976105,6.828380413657813,2.603426429287444 +98,256.8442650233618,253.14460283696363,6.821267955887984,3.254494004204524 +99,256.9799728864509,253.50866793284385,6.8533044126794715,3.166075950840959 +100,298.0833417924816,255.11218204520893,6.68748523503982,2.5312282089724154 +101,298.2658386968296,255.0162251091937,6.972265462941957,2.391655492853278 +102,298.07594362921077,254.9831987261273,6.694673144383624,2.446242469655284 +103,298.1576505106038,253.88763222872188,6.715087554789903,3.885076107906952 +104,337.3091830161018,251.4473414930906,6.239563573099407,3.9949672494208963 +105,338.52343083029405,251.73143621714976,5.899400220598736,4.827509891673079 +107,338.1840923615987,251.65216202919063,5.969934007979263,3.751028655396448 +108,337.64939708910254,250.30336435438954,6.249968722123418,4.858284281787599 +113,273.95099656515106,308.7034217127645,4.47709247898054,5.982967845021163 +114,276.2427158717565,309.6243826995124,5.356119731482595,5.519574978016204 +115,276.84469790647285,310.1401260519893,5.002026768143788,3.605341196767828 +116,277.0444072504442,310.2242983789689,5.093238900500282,3.2415570106605673 +117,320.1389402262641,311.63009189142485,4.939108050053555,5.410806300828905 +118,320.02073795683015,309.86619068708495,5.027296431375431,8.060815849838507 +119,320.1219104879224,311.65149736236003,5.012337784903855,4.875094660414595 +120,320.07204598420145,309.7142498435185,5.096615721025626,7.995525189669432 +121,361.50564549283087,313.53985202649335,4.795734938117528,4.058166847376938 +122,361.26704674904295,312.86969370023394,4.911340820107842,5.091228854756303 +123,361.2967353862394,312.27740018121676,5.035196497174981,5.584514630261738 +124,361.10126473389414,312.0592776230653,4.783581913783201,5.306719192876605 +125,443.007863468424,317.0482807576108,5.010510348067979,3.2746926716250857 +126,440.19719004623624,315.5077064666447,2.501683625204251,5.638134747002355 +127,440.39835940889833,315.5795170075373,2.85606034332895,5.721606221790266 +128,441.67660517656856,316.6947608213303,3.639566862837229,4.302035563866815 +129,480.016363698198,317.9126206681539,2.233190012581438,3.490216783801077 +130,480.61644673663056,318.57621643309193,2.3716485330417605,4.382988558323238 +131,480.2151199142978,317.2082517588217,2.247293593796934,3.5149416209558377 +132,480.759709821911,316.6390215996198,1.8855815838100882,3.2368313913566618 +133,9.357026815909922,301.1394481670515,7.424860692299219,3.8886973359748533 +134,60.67253427636335,295.1565427193327,2.410669490697829,4.491297160618824 +135,60.246223227743805,300.40587765988005,2.610803253456402,3.8238226248434817 +136,59.58730981243586,299.348986354774,2.4093805788992184,3.557779220380588 +137,101.23721185167861,297.1740950583595,3.1474540219144633,4.890082550289469 +138,99.63203134966024,298.11971146106544,2.5218334720238236,4.231121185206979 +139,95.14237458574763,297.9444005267218,2.877040509030959,4.1131387022222885 +140,100.78477416100239,297.8704635718194,2.4143008563576176,4.154160490535302 +141,119.7250471805502,298.01476664170673,2.715209640937237,3.093112605602225 +142,117.02401243356974,298.35207687180383,3.08539437068056,3.0048819093528643 +143,115.80692312962971,302.2766266204045,2.8382177918151514,5.138019098209974 +144,117.37742445192025,299.4258416995056,3.1697222157479636,3.228779441784994 +145,142.90918088465534,297.6178016264094,3.0832619899763425,3.60199958241714 +146,143.99054736678715,297.3373199008806,2.9996657202962216,3.476044966382911 +147,142.68589497073927,297.6157999040096,3.132429288120055,3.6266815665628562 +148,140.49454000047197,298.03917216089854,3.0056568959849406,3.734214838274721 +149,181.1180739987013,297.45610301892515,2.9102280695661635,3.430326706550376 +150,179.8095562359686,297.27756454662233,3.021840744008918,3.4405430793578002 +151,180.86813470943852,297.15918644525635,2.8691980137577318,3.454347921701997 +152,181.2406356303146,297.2424283977706,2.9384917862774746,3.4319912000139534 +153,186.63497292825323,329.71520796854617,1.8343875090418584,3.3743188292573 +154,187.13559762838133,329.51685230643136,2.083912846195953,3.300784079309373 +155,187.40105015626258,329.53867670663755,2.14805160685666,3.2933937706575724 +156,187.47298980472146,329.56496093677737,2.1638184471687887,3.301333072095006 +157,231.53011125776158,328.40789450036294,2.6073775062440263,2.988502538747351 +158,232.95501178876998,327.80492336093096,2.424236811554027,2.350854989534598 +159,229.72646596258252,329.3298075897175,1.7204738903289671,3.0704923118251815 +160,231.2073236731834,328.6714932883225,2.4438861147678295,2.994769224677437 +161,272.85319893527105,329.5668274175589,2.341440048111982,2.0154389968753095 +162,282.2212417820937,329.4367762421606,1.6558383645274921,2.653180738201903 +163,272.98005102373446,329.914142628833,2.0535729706681347,2.386063407880205 +164,272.95435454694245,330.43431753911966,2.0639940112617947,2.36112135650202 +165,312.8967133138425,330.7228636434229,2.4191353299335647,2.683491777579408 +166,312.8953561925438,330.8465788842154,2.4840737872275156,2.6822749686071305 +167,313.02590086745846,330.8849995926087,2.3762208918687464,2.697650571027151 +168,312.9409779932792,330.75973451781795,1.7568824225422763,2.681011243704313 +169,395.70755072087877,331.7781381458078,2.4577717664195537,2.5638227463557386 +170,395.3337266028771,331.43381176706987,2.181281870585342,3.1337432803521126 +171,395.80626830723384,331.83504925004354,3.343168830623854,2.549566986608766 +172,395.9132452906355,331.8528749734858,3.487324246008807,2.5438283475869454 +173,172.9730835697278,153.07041804847032,2.9494726617733757,3.382217579007034 +174,174.54971679519662,153.38021154909217,2.9795452304182835,3.4124393018031505 +175,174.36354763148583,153.16813701756828,3.0454139103327917,3.4583182798940344 +176,174.35826919924722,153.1700612928826,3.0211141262576273,3.4091382049295103 +177,217.2505549073576,156.64130212161544,3.566395537735253,5.205239829046527 +178,217.6980323106648,156.20521332851527,3.441914436456696,5.052429489736655 +179,217.06819564151806,156.2917309214015,3.586543606555209,5.007013880138526 +180,217.747171393919,156.15624360378254,2.801603355598029,5.1577319803732085 +181,260.65829263531697,157.11165943543224,4.071932875596254,4.2654996092602575 +182,260.2873418729937,156.01133511605644,3.8080469436278466,4.739826748647123 +183,260.65241208670443,156.65264585083804,4.066095494476047,4.309005262298059 +184,260.7008275437579,157.3470048006293,4.0954566230931215,3.4845516638308904 +185,303.74815224402664,155.66355774568396,3.170947192231751,3.473866833204008 +186,302.12965337523497,155.7857969814269,2.9930059801075064,6.048866083796893 +187,300.60769039476713,155.76327680748759,3.9951348071403796,5.998453375045407 +188,303.74316048048706,155.85489621294607,2.9236413377489514,3.326076201679362 +189,384.93902681068244,157.58958174688522,3.689645238386051,3.2199234634363325 +190,385.6953493035584,155.9304125075569,3.6373602156895406,3.649388391215581 +191,384.52200141722733,157.28840768944934,4.29808384390818,2.2580181721891828 +192,385.00974793928197,156.45140110834245,3.6598188496146618,4.150545508756308 +1 +59,93.01404247432006,213.5226271525372,0.5227911458975513,6.748081819440171 +60,94.33424540812612,209.6207769002175,0.712959043184757,5.35016277729406 +61,96.49374458366215,210.39800263419923,1.1303680657085802,5.547156704495216 +62,176.2808701725152,230.63601199191507,1.0055010380867206,7.308688366893414 +63,177.7659470241458,230.15931042185892,1.1083723356140194,7.241140371768349 +64,177.32083639697316,228.6702361548934,0.9940812742434725,6.592321670041416 +65,261.4355459288758,202.518302086519,4.641943406474736,13.108375146006386 +66,261.77358521125467,208.71156784518865,4.228802506962239,2.433228596876354 +67,262.2239840728469,206.93200819390404,3.913133965048002,3.8722633351342384 +73,271.56840159049864,202.43979307690176,6.020267230118504,9.252928727047907 +74,271.7499513480728,203.11926113487155,6.298067280843489,9.460113190107432 +75,271.44195864454383,203.13378150076727,6.235685371158418,8.78878791063504 +77,350.3678386604973,205.31362830989096,5.486198418330991,5.167398353061708 +78,350.84767505700546,204.7348154139331,5.884173027734943,3.1267473645330095 +79,350.3672092162146,202.65537701706708,8.070802178703657,2.602867171044783 +80,311.14553424067776,202.4869088895573,6.8627096705514905,3.849897420660647 +81,308.52906773639614,197.89051485190024,6.52057770401923,6.5753546391985545 +82,310.7458930121221,195.62555942687163,5.367642235757289,7.169712735992463 +83,310.4462741092919,196.04905416426502,5.898927104709222,7.285208599925228 +84,132.59882836689548,252.18106881985727,9.792699149145234,6.074176114983168 +85,130.27271083469327,255.0125898993776,6.541689138699417,7.5432442383212415 +86,128.24730309169942,258.24673630933165,4.738368491228839,8.535578411913749 +87,130.45275524711,255.95852341410014,7.110134503566371,8.006575003774147 +88,170.36255985278285,256.37507510380607,5.690121369029169,6.698852732879058 +89,172.0725262476556,250.99873611079994,6.021708452291268,4.7312867200629105 +90,172.12065301401947,251.62393859671212,6.229499399540459,5.814534676493482 +91,176.161018968339,256.37597941761925,9.979846996542312,5.435649021007985 +92,212.93760785065032,253.73852022713282,4.877015070829818,4.420381137303506 +93,212.87022485654242,254.1472663576613,6.024553307028744,4.36937145736752 +94,212.6901735716537,254.11072679512063,6.253967049885242,4.460238419613106 +95,214.72029157599158,253.32794140075904,10.942416527294561,4.6292928147759165 +96,255.87095795884755,251.70990738025452,6.095777014998389,3.032297848733597 +97,255.65851168088042,252.1188764922263,6.119873150459129,4.2912655878809405 +98,256.06917412538536,251.38312888217393,6.172049945445992,3.0818160436840696 +99,256.4256676707784,252.06892690237498,6.2866487953086825,3.3887198764991386 +100,297.8256649973607,253.8462555802079,5.924725404966239,4.397206605295746 +101,297.5756213294392,253.9391774660706,5.944381655046086,4.005013371810662 +102,297.502368857641,253.7073727620472,5.860286142652836,4.041363460966722 +103,297.7274471303382,253.7310964744231,6.239643764909305,4.305568077335959 +104,336.6561093798173,251.17938258703765,5.584269888775618,4.812738974889911 +105,338.49750522296745,252.07705913627754,5.543320366201012,5.442573748366097 +107,338.0150937851073,252.18608250396494,6.036908819248115,5.0311597932446395 +108,337.2951518337468,250.18224258519146,5.881938681047152,6.491905854296189 +113,272.4491338841411,308.8369345911772,3.9306201818330053,5.901638358317446 +114,274.3616111627661,308.84705520975774,4.644046045611964,5.516775342288276 +115,276.16521348060496,307.7328192973856,5.477181608323385,4.274725827291863 +116,275.7219694287137,310.13716548933456,5.248785953237486,4.9634566528627255 +117,318.9497922417631,311.557654756341,4.404954111761173,5.820314553091814 +118,319.1412036522322,309.2162698967087,4.478984811722864,8.01149636027687 +119,319.0529158028501,311.2794691857636,4.084462770697858,5.557665052342318 +120,319.10116577059574,309.1842470522271,4.386098755065277,8.133763836800041 +121,361.7830962316519,312.9030603457879,4.571180054194281,4.907320783558812 +122,363.0043086937134,311.7292896961028,2.8960472677148883,5.951933529573732 +123,363.19625593743865,311.0733660860651,2.9383205358529714,6.1061913146876945 +124,359.63316117679994,311.552139939443,2.821256013884825,5.5763574754572796 +125,442.75956343881825,316.115466064729,4.778336574085548,5.530606828021713 +126,439.5856299442215,315.1505995864219,2.585590965608122,5.747036062574868 +127,440.69585939100426,315.0579828759502,2.7149707354695605,5.752920657180591 +128,442.14857834779656,315.935012126325,3.816863855176525,5.744951427518666 +129,480.0220424915058,318.0508150479775,2.545818620191014,3.655165569690837 +130,480.2961674860558,317.54390725750557,2.605035779868517,3.5415144855244005 +131,480.2157699796402,316.6071568907418,2.6092555233226427,3.3584986805507486 +132,483.0300110911751,315.06269628406767,2.7300211118973263,3.898312260468843 +133,87.11667489567593,294.14241735058243,7.598743409857649,5.19998245236602 +134,57.81287299171998,292.38407844216607,2.514015918277811,5.136006470534924 +135,56.72481683615359,300.0118009139173,2.857620857781098,4.750166949488199 +136,47.21055945404092,294.95922659039326,2.6917302124926694,5.369878030902169 +137,82.9740487845219,293.3928921084636,2.4848999003333803,3.9293747558559278 +138,161.9550663905005,295.0453226209086,2.7841652419514227,4.6158307977098305 +139,360.9021185534379,293.4515559554225,3.014363497918401,4.4291415710214785 +140,89.27996833990208,295.47084639542686,2.65494720185284,4.648541410028614 +141,116.08881622892042,295.90714432478194,1.9069874131620126,4.150080850969694 +142,132.15536640954062,297.2171229012815,2.706901698676143,2.9568780838711826 +143,127.63875390271042,301.4424845378769,2.769134247080161,5.578151587102764 +144,130.87079961636513,297.89834733182647,2.818953624476529,3.8997116282895603 +145,150.31209355255865,296.8214130757569,2.725175079922067,4.209022465413865 +146,148.97786084884208,296.6038327691481,2.7067927491075574,4.17492062013239 +147,150.24661339572495,296.7796929595484,2.810800536874064,4.312780918203187 +148,152.60600094096128,297.232015083595,2.8754159917495565,4.377707355346677 +149,210.67045705478267,296.141990804855,3.265568007984475,4.047456332372859 +150,197.09292075504828,296.3228305878953,3.180756798374725,4.46039907916231 +151,119.65069386862973,297.0907409886854,3.355490697464104,4.394699915307226 +152,227.24737645933865,295.9919464826721,3.29596076395495,4.365046047151038 +153,185.29407593743096,328.9756512787473,2.4739170556894745,3.6908535828009685 +154,187.84229703035945,328.67458417656786,3.441179047809909,3.032614629941614 +155,186.58809302809905,328.98652600447394,2.9369976692797604,3.5987191187020073 +156,186.9163443606333,328.6316285416275,2.8964425091038914,3.4524747234516604 +157,229.29082047745888,328.15179687646463,2.4437228704779783,3.75376327066602 +158,229.7362726809719,328.8007493567453,1.7377499391208846,3.510569661296656 +159,208.26809226199518,328.86828867681027,1.5607659119719737,3.1037014684154176 +160,229.09214710427673,328.6178358476461,2.260028006988348,3.6920398661292713 +161,272.30550005795965,329.31313118492073,2.228336338998844,3.1347450587831363 +162,744.7928105338103,324.23769166614653,2.1073598387590406,2.539759184702161 +163,271.92463381929605,329.4914525203367,2.354794935998881,3.3821523721928775 +164,272.0763070212753,329.43329625041076,2.2564082813073223,2.976824453200896 +165,312.5002968548282,330.6396470335998,2.4980562783012132,3.342049851550277 +166,312.6633003087961,330.708018763403,2.485750243447884,3.1257959767437193 +167,312.43290491220614,330.60640551938684,2.5861522827731918,3.1384938126252546 +168,312.53461746652715,330.59614144293295,2.6327977881534315,3.2738519720709336 +169,395.4235565349371,332.05857012716825,3.042284807396061,2.6618134827186033 +170,395.89575300552235,331.2204950674755,3.5075609281016074,3.432678442805089 +171,395.42995858598874,332.11325844782596,3.0389919063576745,2.634943595710816 +172,395.74810123344724,332.1696223944591,3.3020110174888058,2.910921037939185 +173,172.38094968570545,152.05413649604458,3.009792250294108,3.523757740020178 +174,173.8277034486298,151.97246989575592,2.927263574496173,3.3547430273206764 +175,173.7469031569836,152.01702715147732,2.992197181370308,3.5878204759260535 +176,173.87444349441117,151.90034527705913,3.001730291594699,3.3191803731856986 +177,220.05954791045562,153.93486125597713,2.916964654294944,5.161796303421409 +178,219.06032109265325,153.8679197592309,3.02283014757281,5.214692401346838 +179,220.20248145797134,153.83037812747935,2.811916018641933,5.135768243874929 +180,219.8662882177588,153.69386761094438,2.8932331677602288,5.195182563087241 +181,258.7941680380869,156.20170959987001,4.509844805839375,4.210885005617385 +182,260.70623290807583,155.5691133699838,3.9964474629559583,4.494356603934025 +183,258.66062861832245,156.13098164693182,4.524480095522743,4.217380456749666 +184,258.7614643354862,156.22967958243044,4.5086857868814425,4.199456605512427 +185,303.22935297897106,154.43469284754158,2.9235122344572497,5.0253634772759375 +186,301.737374625956,154.2611896143699,3.0779278021862946,6.153602357601281 +187,302.23615729321835,154.26453424384667,2.993547760611472,6.256352853265299 +188,303.7378760514983,154.33358903047713,3.094665979648467,5.269632450902677 +189,385.4931704373973,156.2752179977739,3.473675270188691,3.9607689131121706 +190,385.00254984000435,155.26821198570494,3.5586590950004457,5.391583365108707 +191,384.0813093792461,157.57737240690167,4.44594499401667,2.8998689471390326 +192,385.1801338588461,154.8206336674526,3.6798775544177063,5.162336041483175 +2 +59,91.30284200670633,218.07642242545626,1.1539219073226616,4.534512576080954 +60,94.47064527098745,219.916516135159,1.2005691862986814,6.846135813191627 +61,94.15679646295986,220.04095088976442,1.4155925768586246,6.838018547816678 +62,177.10956003057285,218.90103728250688,1.3905251660790856,2.7497320728371646 +63,177.74456263111466,220.06649622720403,1.2185587916549738,4.188825256215504 +64,177.49917127590462,225.5014059314746,1.662625480516144,6.3447162872422735 +65,260.83235784169676,206.768453469812,6.640373185442694,16.669713322142147 +66,264.61912522766306,211.23389035030604,6.418829493449439,6.7515824557814765 +67,264.56313646993567,208.898424261183,7.577757476106213,5.397905740603194 +73,275.0807583567399,203.46314981555653,7.529121753107468,7.79068598394073 +74,273.3391581028213,206.03543897900892,10.405037115613153,8.539004741937488 +75,273.12815716759474,205.75279846700272,10.383171899212439,10.3236022000293 +77,352.39736693776445,203.25064337648874,8.32458599948799,5.647682458487953 +78,352.6804091269042,201.66565569114204,8.497380645406677,6.217216240364239 +79,351.5731625392584,202.19179726341497,8.658775240139533,7.111128909229292 +80,310.6751701124307,204.64495746423012,8.062037456416205,7.444446872078048 +81,309.6670401069309,201.55447995655948,9.465643221743878,6.881819412692541 +82,310.6335818256993,200.22299800671655,8.67387089777447,4.664159850458751 +83,310.9019318418565,200.02015346830518,8.510118775528804,3.8829013885017067 +84,131.06337257497074,251.28475092908215,5.159471427859664,7.099566355433584 +85,129.09144907108433,251.7203734728845,5.198191014751725,5.290792123590904 +86,128.14221980812886,254.23635236985004,5.978168978981718,6.3363646857946305 +87,128.5504980446596,252.95544188750205,5.339963887657365,5.754904964464613 +88,173.96747545182777,257.59357552003803,6.482400441297941,5.234590780368996 +89,172.64797467848848,251.12847549296245,7.275410666068803,3.2555916560823848 +90,172.60455067578906,251.16298927626656,7.222779487902638,3.496102713076582 +91,178.63195743713817,256.00196219903546,8.724215688749194,4.5367531498363824 +92,213.30204486943944,254.65697701565333,7.662137596538662,4.165845349061372 +93,212.8172314127949,253.39712914171187,6.857530904039771,3.977160865721656 +94,211.8792430432469,255.82761299122967,7.222038595318558,3.1694534357454573 +95,213.7978436356281,256.0278412645292,15.452080822376551,2.4945072295635016 +96,256.93972703527453,254.22973688137205,7.44290569053337,3.428653114933794 +97,257.1457284865542,253.4535805850962,7.332108489145229,2.4944378698026863 +98,257.00282187401416,254.12419273967237,7.2764048131626184,3.3193016977855763 +99,257.04994365436653,253.94432494945963,7.423089718980076,2.973336749681888 +100,297.56026404755863,254.32212106774926,6.852565823032563,2.8493609623085123 +101,298.63371928814155,254.61437178101048,7.905691877078718,2.165690092942747 +102,297.69407107379396,254.4850393852944,6.836012542442264,1.946205259389151 +103,297.9023244730469,254.38868473138925,6.751896664205788,3.3116178759031087 +104,338.0053276434522,251.83336967087538,7.799885374056114,4.945594824336877 +105,339.1582769256123,251.94932873663424,6.500886426061445,6.047632898215193 +107,338.3102566581982,250.25272692617727,6.48687937625559,4.657479797529445 +108,337.9547753028731,250.03478792262877,7.680658310818983,5.287653170857336 +113,275.910952296904,305.86738853882827,5.34030651381748,5.289299280058491 +114,277.42120270272227,311.21743667247097,6.194812315610025,7.468012633884288 +115,278.93960224322814,309.638371888345,4.951788309478035,5.6357014265428536 +116,279.87420391551683,310.72506489150953,4.822827709017515,4.736286987210306 +117,319.79423896861897,311.2133693181722,5.668930716768623,6.682907491520234 +118,320.5540626961792,310.68709367641236,6.419719926410251,8.237770206306163 +119,319.33379454853355,310.70701535995903,6.465185367234193,7.897980684891891 +120,320.2722313120129,310.1782745929597,6.268219945694488,8.023329923606077 +121,367.6098676953658,314.58028508890305,9.39615711787979,5.649531231448145 +122,363.74508504031036,313.48439864622117,6.684116998496468,6.329996512810745 +123,363.29642172711425,312.67626164324315,6.400837328497925,6.909673033958756 +124,365.0277447799763,311.6147364893551,6.720810503358312,6.645516125018006 +125,446.2253017919773,314.99416404393594,6.395392871846412,3.382574041643381 +126,441.1237388588513,316.35150200412727,2.5546429518376508,6.635379091123845 +127,442.10117921669377,316.7934137028694,3.617061357493329,6.796381592950393 +128,446.6969923351063,318.5296550554647,5.9848567355794176,4.343944361749059 +129,479.94558754651956,318.22536134864447,2.220264608006834,3.836710322440239 +130,481.2539099375137,312.640306388908,2.593318771161441,6.6486224400214775 +131,479.45347062880376,318.2469542979415,2.0004364038172557,3.688680674174361 +132,484.13323268726947,316.73499335627196,2.002291195085977,3.781086788196597 +133,85.29652368782442,299.9267050080891,7.827458514431236,3.9374236627298966 +134,59.67355911737736,298.3611375665026,2.293779231438959,7.12389408216543 +135,54.93006667794998,299.54260321894077,2.4753999616786904,3.512718857180827 +136,52.88374765283322,297.62420743734526,2.052251163735395,3.0356052182771274 +137,100.22096248097169,296.1954497008577,4.3012641162676175,5.212420406396804 +138,77.57773257938949,300.1917036834339,2.6075704778239923,4.343174316530481 +139,114.23749297790368,298.69307716260715,2.9175645781194874,4.154406732926865 +140,45.03330152423734,300.5503452125839,2.625583107839479,4.294099847159548 +141,119.51809674004014,300.04111347523275,3.4424531063915236,3.6098269870345647 +142,118.45488030550041,293.42435614635554,4.076098186731008,5.934920124944857 +143,110.877037200568,302.13823496880946,4.847942451776839,5.374114325813509 +144,116.6620641371857,298.368278265185,4.685262545376076,2.953550317426917 +145,142.45731006430879,295.1000575604827,5.189856548842566,3.111987985605453 +146,143.20014617587012,294.78019680871137,6.0198625121087534,3.3010521003465834 +147,142.56298735658783,295.1170233357802,5.20261559459805,3.442242559647229 +148,139.89055528539328,295.48129747000496,4.278137116722635,3.3562006136085 +149,182.28248910013076,298.8925711419297,3.882958147572496,4.932530677517502 +150,181.93047252438868,298.64825753275414,4.0369897133739485,4.744932625303357 +151,181.98693496359542,298.1631625286757,3.8155850034361163,4.774725772494465 +152,182.3110519597161,298.0855672750618,3.9895325459128514,4.794576201460771 +153,259.4920457606562,329.2756913744665,2.454071420423271,3.5104389207411675 +154,191.55276246651394,330.10335406699386,2.7535159658488753,3.735374001963311 +155,194.48534159817734,329.9443292127414,2.1365830195361943,3.127947562092398 +156,193.39092086391267,330.38614167206975,2.1963679483715697,3.459040917080195 +157,236.17750038130092,329.0436536647159,3.1786720809581777,3.1430140286789383 +158,30.916842755515052,331.29060642770753,4.841452724981102,3.7495713033876124 +159,247.27788073241743,329.51692678380493,3.088707102960316,3.923308113475421 +160,250.22189392231115,329.26270263655886,4.2316219686433225,2.8273483917495277 +161,276.3128460929227,330.511230724005,3.4419490584726287,3.1926367377041047 +162,285.59180034302733,329.7481991930167,1.8378511022559236,2.962363935958349 +163,276.2745382801029,330.0900901745128,2.1081569415614108,2.3238295865477 +164,287.0159796232469,331.2727625321787,2.716127438341672,2.4485626997745595 +165,317.7395849994937,330.4138825095169,3.3757057306286984,2.8095989664256256 +166,314.6572377648183,330.5793633642782,3.194427388751986,3.0041332311662914 +167,317.00117777059165,330.6383247898892,3.201153763642872,3.0057526788151607 +168,319.284335249175,330.4196934261666,3.436552449874256,2.8793534460468897 +169,398.9491001935992,332.1016164460315,4.590701775382649,2.4853527290993047 +170,397.4873909051454,331.4430567330248,2.0553328419425942,5.097090036367185 +171,399.09113630168383,332.21159139918905,4.665806570428414,2.438404994920128 +172,397.7907669635104,332.21375146950754,4.160036511822063,2.302533773606481 +173,167.6549194927225,154.8195960714067,3.578104764139934,4.293948219715187 +174,172.8857977008767,154.73930238156944,4.065505613610561,4.397450234808648 +175,172.58520462200156,154.29013402780822,4.048705697811711,4.112000867673462 +176,172.5358949970105,154.45532035873933,4.181462595099683,4.211635985550709 +177,191.54370072344057,157.73353022270507,4.841190533624689,4.763972692389171 +178,204.05445279340313,157.37702899559486,4.494318996136587,4.337287440506104 +179,191.65543785128887,157.74655585598282,4.883158661002671,4.919623053094591 +180,189.28378158246906,157.63000871303564,3.5274346584972274,4.408356106260135 +181,260.37023207173655,157.73328509764173,4.261494343445461,4.8366413757834135 +182,256.12032377018954,156.0742352828994,4.281428257218825,5.030259376007136 +183,260.3960744140202,156.38669157075003,4.242232860054043,4.583829032686845 +184,260.6791000228129,157.9519422581545,4.2747999006513835,3.800985332770269 +185,302.4998205898764,155.53480279841136,4.116529613451282,3.3417704291330135 +186,294.8930629353272,157.4031130939023,3.9041732736595818,6.391527497892834 +187,297.53924094539656,157.38305310411857,4.3287195790389985,6.365038877320703 +188,294.8108560332771,156.29685130271133,4.759679064189887,2.700855536462382 +189,379.62100651919303,157.52580336807762,4.648970244832296,4.614333688454686 +190,385.0749564946942,156.23453384699377,4.097215876576247,3.788089778011118 +191,384.1197434977094,156.68532544972354,4.287357345412347,3.2806588007554622 +192,379.3432570533363,156.93410438422325,4.592318070059131,4.5896206349551 diff --git a/img_rec_module/meas/convergence_naive_std2_p20.csv b/img_rec_module/meas/convergence_naive_std2_p20.csv new file mode 100644 index 0000000..2961aa4 --- /dev/null +++ b/img_rec_module/meas/convergence_naive_std2_p20.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392,0.9677151865944192,4.009449743264753 +60,95.68692886974831,217.86446645631813,0.7424975144337135,5.151973582834018 +61,95.27930768267886,218.4321212539979,0.7270480243366128,5.212134543408362 +62,179.68821344888678,221.21713400884485,1.1147842657503555,2.1332525060692515 +63,180.64677254143638,221.7765304937586,0.83092419657981,2.5740660863437568 +64,179.86073442223173,223.68541859670074,1.1381174020649096,3.626058878513354 +65,267.0750705461852,204.74717443096984,2.241840204786577,13.182457200661304 +66,267.19879488924516,209.60901887734772,2.3697667509990565,5.035545962902496 +67,266.1798697712201,208.51040145394091,3.540061676733699,4.595558869507625 +73,274.3400431870006,204.75610310411912,6.491531432619202,7.31888797087335 +74,273.44321864391185,205.81069417739437,8.261574847627143,7.257546441830887 +75,273.15099171429256,205.61817173382607,8.395328002698498,7.565385107130859 +77,353.2630018061804,204.6061088758629,5.493098240735283,4.29566322817894 +78,353.8852531441488,203.30592180203516,6.087365194189325,3.3836943891959814 +79,352.21840596322596,204.15679894425952,6.557195072515586,3.1954900594475086 +80,312.34313113441607,204.52530436142615,5.588158051911466,5.745243989851365 +81,313.1160349693985,201.4084182788836,6.025875449926955,3.654284157032464 +82,312.11840038067925,201.00669797880116,7.0864910249072635,4.406813194332426 +83,312.29317276741347,200.45780062295867,7.089188755441932,3.1660046223221405 +84,132.42237239805132,254.29214663519284,4.3067464843901515,6.417058493680035 +85,131.29521858798734,255.4865958538821,4.908850345384105,6.3671100735668835 +86,135.9988356956537,254.77748611685175,8.584433337345413,4.9941716761414146 +87,130.98094102950247,254.42187606024922,5.117211446405824,5.370134929913309 +88,174.56636927613675,254.4831815599854,4.7275771979909464,3.1678947409316813 +89,173.67935580024877,254.09783447631526,6.437695363099053,3.474606588647915 +90,173.36920502447623,252.290452181076,6.593885801251147,2.7873975371893436 +91,175.2895186608897,257.2751667704358,4.729209363054509,4.452820054846227 +92,215.07500705655937,253.80949363235624,6.334123387607411,1.9488808007329534 +93,216.94462220467622,255.47756358425315,8.080773269328214,2.7211585139427834 +94,217.3834915918711,256.4745644877478,8.267318853585852,2.211181525286066 +95,219.6648004345676,255.57239348461326,9.86068974730619,1.4652046608845635 +96,257.50957542067664,254.1259284055811,6.675780060232609,2.704136241957288 +97,257.570545197815,253.88751117668164,6.647657278502652,2.9140751377307628 +98,257.6089813372307,253.78662089019835,6.605179609252467,2.6809454420956143 +99,257.6936671647974,254.2498517060511,6.576722939133856,2.7069332019005827 +100,298.2952436151055,254.76909617478606,6.705809824561147,2.981349985017069 +101,298.1169393001307,255.21794911950758,6.624534032640799,2.181605220236403 +102,298.3189654536773,255.25096983760508,6.750900350115645,2.3083727544087247 +103,298.4415890038736,254.35763625124292,6.663590033871669,3.2667839890941295 +104,337.66969489877954,251.71635156144524,6.210728685673001,3.377413692122266 +105,338.1116560201459,251.7179090471175,6.338074391942699,3.587185716331372 +107,337.93979130669914,251.84264636476274,6.288961573364599,3.0282904644933937 +108,338.18833275957206,250.67508565210196,6.186589358792703,4.10107941402743 +113,274.2817559120019,308.9374117445766,3.892956777078502,4.794749659977309 +114,275.7421347767481,310.2555996702759,4.535765938235691,4.66622650744931 +115,276.0461325201841,310.02072804280994,4.545655403672037,2.2262514157125017 +116,276.2417374542582,310.24048782871637,4.6497847767530995,2.8951312130050146 +117,319.6559290654899,310.99105624588617,4.410519998245082,3.0198480458627897 +118,319.6313092726346,312.1826263203713,4.334709687203355,3.9909339754311914 +119,319.46776160473627,311.841371820779,4.471689460416843,3.8980513701355664 +120,319.76654338764155,311.98447027104925,4.4491853585047645,3.9716440216868176 +121,360.82585188540037,313.3258908241004,4.744138263484551,3.1950268933478396 +122,360.64739266264627,312.8307783296112,4.673876604017344,4.0505350195787555 +123,360.689270210389,312.2626467099784,4.717842951294665,4.331175918113057 +124,360.8335382258014,312.5428875466125,4.7257637014968825,4.238743771700391 +125,442.1542117060401,317.1277309025985,5.1708505304868275,2.8339991015485375 +126,441.42140737582423,315.78584607818385,2.592454459875001,4.6687701093869 +127,441.5300773440553,315.90717126090226,2.8050705738429227,4.687041451309435 +128,441.95769286933466,316.8407357397122,4.805859396667629,3.6325916039286454 +129,481.35090878368925,317.4272946632326,3.3586867882998677,3.2305216999009705 +130,481.4725819590857,316.6159681822135,3.546147101969164,3.2838056303462357 +131,481.1535576706723,316.8819465108059,3.263691605498864,3.2346725461032757 +132,482.21933609621834,316.90676933858305,3.3334111968000197,2.8211028940841043 +133,59.55768321914789,300.29871844382603,3.8761928423107794,3.6951665481304303 +134,61.376816545951996,298.3523691730104,2.113993300917673,3.899220174332725 +135,60.60960139542109,300.5877018018443,3.3916290934001863,3.597118842410694 +136,59.19985355062283,300.1851062687214,3.520034988226608,3.5453648546285197 +137,102.6280068014727,297.40383468175656,2.749638491064498,3.880988203100239 +138,102.40955557323258,298.7865911290351,2.7573372442370903,4.089700063188653 +139,100.57013333623348,296.8202762296189,2.9651756626973564,3.163333481381463 +140,102.67850653460079,298.5730025774653,2.656076828883503,4.008870765124035 +141,120.23221696171454,300.1898879495705,2.3495738375350714,3.7101386992401784 +142,118.10535832779757,301.85912326532906,2.662771758344228,4.434372354516663 +143,118.16700474619614,302.0417496311767,2.810926040633238,4.442752618047973 +144,118.19187121087131,302.5378510894045,2.8502302470584953,4.428574269320613 +145,143.380762851227,297.65106023170455,2.9029598644975594,2.9494319243206975 +146,142.46748228973178,297.3647432540817,3.516542953167025,2.7867411900804395 +147,143.2239805848247,297.5672414624104,2.925450223126345,2.8821527557517435 +148,140.51718892104998,297.9845023911149,3.134479693224828,3.0837592352072623 +149,182.6593569656309,298.1418468359333,2.648390300198232,3.275571713707499 +150,182.64828488417706,297.92582445480707,2.7260433370787203,3.287985243918374 +151,182.92797391602642,297.87455852433123,2.5754349127258473,3.303821768124996 +152,183.0029286817877,297.8637465373881,2.6850779296217095,3.268506780902108 +153,186.1728851830908,329.8083307385874,1.6988565395865438,3.2857803265960546 +154,186.5492243440529,329.1491955430002,1.9159248202789043,3.190026296337793 +155,186.0292302003802,329.23752125561214,1.630100824234192,3.143397778827556 +156,186.05706501583137,329.3191466220413,1.6185913035274193,3.18627620460259 +157,233.36795685970054,328.463961880729,2.643309826783174,1.9867341998292147 +158,232.82586842848798,327.60883484043825,2.477588134745834,2.5854098103097747 +159,229.71350413783279,328.3780985513343,1.4377331090494412,3.4686128953627313 +160,232.72525153041173,327.7700361791668,2.4530240891852237,2.5077492129850194 +161,273.76316751955034,329.73823826493043,2.394688280474286,1.806427127995776 +162,275.7575781134558,329.9125721193857,1.3584269354839966,2.5506427041479443 +163,273.60940070127293,330.0025820738042,2.4087695062685763,2.2557767070416954 +164,273.7244999819209,330.09757535831045,2.4201727937672897,1.7894497412511505 +165,313.3973669095876,330.59163642669836,2.5664663718925884,2.5175272820859127 +166,313.23094160288184,330.71155384663837,2.556749103943359,2.517895305394224 +167,313.2083786255443,330.77428522126553,2.440925958919023,2.523508078782979 +168,313.36106959216625,330.6523370232485,2.5105680868176643,2.5022918306323914 +169,396.3640143494862,332.05477157898144,2.544597691516881,2.2242293500191375 +170,395.617460222669,331.85554030819173,3.094183882820774,2.2794261534246627 +171,396.3911361968549,332.1303447002533,2.5527965384171347,2.1830363581679078 +172,395.89256887798285,332.16822339411516,3.601013097767017,2.1716024486759946 +173,176.02029170516317,153.71245910000232,2.3779159513262353,3.409134278667166 +174,176.10545306203875,155.20318481126037,2.4825478178566596,4.418906030455666 +175,176.03197440143745,154.95241321278883,2.42399408636437,4.430327097224612 +176,175.6846804297304,154.63359606135103,2.5997462043064927,4.219400830122209 +177,219.46327960613064,157.23609785750858,2.529672116014354,5.058864568041901 +178,221.0564853241154,157.3435472260885,2.2463229070198545,5.480115541197549 +179,219.62129396536662,157.2666553285107,2.5021134486595593,5.352065132338259 +180,219.69587995502016,157.1490063640601,2.516169881431476,5.470652636210902 +181,263.23636033723557,157.46707082247306,2.6921936322678013,4.204926201545835 +182,261.3833848255912,157.14497162705263,3.132796451668047,4.135023908563071 +183,263.2875985178052,157.05504332147794,2.6601053814719973,4.186611997777448 +184,263.16270089611913,157.68858593709763,2.7082086799182084,3.4205893941412424 +185,304.0771964580808,156.36708101762838,2.6882263261194885,3.319861960122729 +186,303.2325028543831,156.57995759281437,2.7961523629805916,5.391517197327435 +187,303.42630311491723,156.4924674158584,2.783092188384192,5.365203962414015 +188,304.6158660912609,156.4818813819881,2.506720194343099,3.179833381166062 +189,385.45560134261797,158.37035395252553,3.5085984360932585,2.735043850552565 +190,385.8286612719259,156.9884186905783,3.520976122354819,3.199129896839037 +191,386.1864174896063,157.19189241238993,3.2937940620339354,3.0663737335825165 +192,385.6347971660166,158.1411858434322,3.4609224939824603,2.846649085773437 +1 +59,93.1287423931208,218.29700908810787,0.586116217920642,4.982728971287442 +60,94.70512938803542,212.6540109552706,0.7530580888942188,5.342989457535182 +61,90.1361278577332,213.33121631876608,0.7741246171980174,5.183322455003788 +62,163.05397573990066,223.03302231371174,8.768671109743122,3.608965585949599 +63,178.56039861950646,222.19098474984543,0.900267664385944,2.917664454486164 +64,178.37920648184422,223.51557294327878,1.0988445958401813,3.973656567077689 +65,255.80438353417117,203.04815455047097,6.766813492476352,13.29699627358335 +66,262.478672605179,208.85138164100843,3.5774987545822987,3.7830932795933596 +67,263.60616955216886,207.2183121488101,3.5771988890480593,4.252166210585195 +73,272.29022155441146,203.26015396542505,7.667403148427107,8.484726496612334 +74,271.46793735704193,204.00075736023095,7.006836949843662,8.57906517149974 +75,271.0412882240347,203.67673019265595,6.9166949430129225,8.702335904677817 +77,350.53069989533947,205.1215453780687,6.3913113962364445,4.675912501749536 +78,351.5335450988067,203.6132402057685,6.914935781146339,3.647320534476688 +79,350.54080463471854,202.80860415043412,7.576153280744988,2.405442522969295 +80,310.84312359894454,203.07084060099984,7.338460358520777,5.637962269519666 +81,309.4303871248667,198.8260778916456,7.8402558918165015,5.732595151892859 +82,312.8487475083582,197.88498609405823,5.545843437300968,5.5454679231566235 +83,312.4494378330193,198.02482356912975,6.100953297862154,5.205602033075617 +84,129.73316120742015,252.31402870350382,5.182904459352007,5.7859701617993196 +85,130.09936826716955,255.07600217340146,5.535923397107699,7.036159941672144 +86,136.48684968097632,256.98593054341063,10.027649034484337,7.342825955920834 +87,129.96018632025633,253.63904238622214,5.660756401038712,5.8266843261131385 +88,180.12754728190527,256.91804818977533,10.57223062780983,6.228147264882277 +89,173.42291095269067,255.58833819764322,6.700532645820975,6.247923198559783 +90,173.0543226504001,252.5748838461415,6.760737603124655,5.231000998435721 +91,174.29585433427428,254.46270745029543,5.389533179624763,2.8578511182829476 +92,216.78511969207446,254.5914187233686,8.95047307481889,4.249360054724529 +93,215.97344562124545,254.7054640425066,8.196439917611718,4.011111129846635 +94,219.24024367384476,255.41662872012847,10.121690584983755,3.367632134220822 +95,213.81498670140752,252.60321047848737,6.581085797491111,2.395105254724356 +96,257.3830982530756,252.6691612485834,6.880768996147865,2.9353265504494703 +97,256.07878148245777,252.5850508469038,7.193370431289156,3.536434124406424 +98,256.6563709830754,252.14302077100646,7.020255474285572,2.742516414019443 +99,257.10274737541874,252.44669038983187,6.759367673913806,2.5065554147623534 +100,297.3527413648711,254.3197859755712,6.974691942771777,4.204342914024384 +101,297.36935919598676,254.31625883281748,7.003782434070834,3.8132099844257588 +102,297.45043676182286,253.29006124829388,7.147301062318091,3.0312100621116413 +103,297.15639353267426,254.26565823155238,7.3776805534006185,3.914660604118064 +104,337.0838455883894,250.64743017278894,5.921815081770851,4.024140676300613 +105,338.2943046084806,250.9606925384406,5.481575455905726,4.1053232838414155 +107,338.46927119138405,251.82861699933284,6.654167871317137,4.251478363049102 +108,337.6321115297869,249.87042147419172,6.005664399486008,5.04451473974955 +113,273.20050531167254,309.1760573916311,3.4219821116654865,4.957144824013617 +114,275.593658985165,308.5727448984995,4.702522493967433,4.008413607725532 +115,276.45985797306344,307.75120186662025,5.767076285351399,2.479883936569082 +116,276.6589541465393,307.7328403118153,6.184525915073467,3.409658651068851 +117,323.8680795155452,311.25555593462394,5.6467354698699,4.163445875643856 +118,323.990822160368,310.23497244583933,6.354306297639026,3.605863723170547 +119,324.4759468599942,310.5137190042532,5.951639025695133,3.8742178925550625 +120,325.7385894442358,310.39579583995135,7.723927817628718,3.904269142941334 +121,361.82046220765505,312.6906221126212,4.3915079798209895,3.595391320936084 +122,360.25109899783934,312.73975566628565,3.3364555278083112,2.7719078470887877 +123,361.13964194906663,312.4482596768938,4.009973777907947,3.338550731387954 +124,360.8021695665512,312.55731463103996,5.178975914859417,3.147724551644225 +125,443.60378722604213,316.81523544669056,5.441494217460369,5.859512902880808 +126,462.74164751366203,314.6397925160877,3.1723106571758315,4.673495905701873 +127,284.4684422338389,315.96181914108945,3.781047749264403,4.799446710082581 +128,451.0537747662026,315.05034330850094,4.165022446102917,5.582872998184059 +129,486.2262311408019,318.917422588962,4.360015955842124,4.24279052637777 +130,484.203371665194,317.155262043757,4.666439360195373,3.538660983437178 +131,493.1775485408943,316.3518621311899,4.495507964960477,4.044073143583547 +132,483.79815450187516,313.87456269013853,5.0513219188547716,3.976286497193232 +133,58.415796919717515,296.3367806354237,2.745318197812863,5.347714894650585 +134,59.66992690532717,295.46552315023496,3.0521020998678443,5.04724168228645 +135,58.30852857429605,301.14443002474417,3.0314355414314353,4.891148165556274 +136,57.19875149216512,296.2038703275876,3.0187024946676813,5.430283114579736 +137,101.88869112962361,295.36699152796956,3.0605704820563435,3.976231975252619 +138,97.74223572831934,296.64159635228486,2.388879471730324,4.818867004598817 +139,95.13971714462463,297.63279866894925,2.5874115321204054,5.108323412261206 +140,100.97448449522825,296.37143206657936,2.23273639508488,4.835560641819327 +141,119.6488680328135,295.99857882673734,2.945034185014498,4.051944183392203 +142,116.04630564586442,300.9428981940468,3.646493643610884,4.201903655805421 +143,115.93833802312685,301.4015147621542,2.7752574824028806,4.899750014060764 +144,117.66427038686425,301.67621994166734,3.2562262537824718,4.934112992862415 +145,143.61862339021508,296.87569921241607,2.9793460068872264,4.493879539069787 +146,143.84226240395634,296.5995702000957,2.6657882037152505,4.487866588043545 +147,143.41726284468888,296.4604242772443,2.892883624851368,4.50539522391336 +148,139.90710854861246,297.05847391439454,3.4669655178811123,4.588153704670423 +149,177.97012292111646,297.29360417935067,2.9817918310917375,3.750304964672955 +150,179.09943783225685,297.22176671479934,3.0286986838896457,3.881572977421466 +151,178.4595029850307,297.07969710485736,2.9749987384442655,3.775627144339658 +152,178.9990807254096,297.58186299960556,3.0418692927202193,3.8833402396923353 +153,187.06432524491635,327.5110792134713,1.9103539442817077,3.1747672773580633 +154,187.40611165319353,327.24266469486685,2.028936750132528,3.039992572908433 +155,187.48202253723917,328.1910452260973,2.046736087360523,4.07325152306089 +156,187.4554203440108,326.77537509295496,2.0468424040406785,3.0346527434557236 +157,230.1275716483488,327.66375493177526,1.3064642552426002,4.735119343666496 +158,230.19455285047118,329.6573791501422,1.6872246668899367,3.583570894848579 +159,236.39481488323716,328.4457905246168,2.716174379714519,3.4183380314351863 +160,230.1984260911562,328.23405030487964,1.818805777200218,4.578868396563749 +161,272.1545894887068,329.32912181766994,2.0716370234969204,3.1939556616595848 +162,272.8983988300567,328.70387641284987,2.430197123109527,3.1487498704390036 +163,271.6162444327857,329.4696874435773,2.203277751618005,4.017476086378616 +164,271.6290916788945,328.8920615225914,2.008299706725287,3.3041284732956586 +165,313.03716740034986,330.7975522275865,3.0420523810535003,3.7108953229128367 +166,312.7612082311074,331.01658878813123,2.756286496478564,3.635011569085448 +167,312.555857804164,330.94886104868783,2.895089352246948,3.630322203243039 +168,312.99233681057194,330.7594147506374,2.9514521257261572,3.7325921124368473 +169,395.6599712440442,331.38000769767353,3.6713668117121325,3.4549858187839337 +170,395.7269407162828,332.3551932767835,3.1249445864849728,3.2139419865878307 +171,395.64772093777225,331.19728501985406,3.652929258669073,3.3877347902405988 +172,394.5822232990254,331.28589367585266,3.5115519861174,3.4415616827579543 +173,172.19300877613125,153.8677984100333,2.9936489675181246,4.5406288069622285 +174,174.43739755929997,152.4534316026212,3.1172372976035665,3.3179648689547276 +175,174.29318678572136,152.18270882980445,3.1219958686591287,3.3048067882101986 +176,174.37774565459176,153.9168218422937,3.148891388697558,4.4895441435882795 +177,218.8977614990739,156.58401687998017,2.7063981074883805,5.2876376907111124 +178,218.82234457362887,155.93775870476483,2.6795499708167725,5.033370956683506 +179,218.14869261453913,156.17880976796908,2.747386160206801,5.050217973950996 +180,219.6136087965169,156.013833915525,2.654919821631967,5.093161539439035 +181,260.39420520785944,156.89107932316213,3.256704661733587,4.125191869561575 +182,260.75752017274766,156.5286129544145,3.674975253680245,4.728421517934744 +183,260.0769741828374,156.73605149236164,3.2485067302773727,4.2314614221050855 +184,260.3205919730126,156.89282130924727,3.016527309499428,4.22117756304117 +185,302.8007745851293,155.22452212795463,2.1986861092464727,4.536996509806027 +186,301.70658980492703,155.39202732491273,3.616906361622583,5.809560313914322 +187,301.9655960101498,155.27173302476598,3.5367891506442364,5.787704448891815 +188,307.3464400351471,155.7530563647103,1.0636861640988715,3.4615533986219376 +189,385.16837677047874,156.43907420157797,3.813439832275512,4.1547295279172625 +190,383.77693943350675,155.96991177533516,4.219569642219233,3.833536791723274 +191,384.2249550976313,157.41263864645526,4.594412135572423,2.424078159567562 +192,385.2223566829572,156.31521854739066,3.877568024165435,4.253414111013303 +2 +59,94.17681256320567,218.7493975260511,0.6672950811803234,4.0696236612012 +60,95.60291842116452,220.23420259378253,1.2432894303505535,6.268557799628915 +61,95.02957510532019,220.4523644522619,1.03897231445469,6.283961945108087 +62,177.79543145664374,219.57549575966527,1.1635891534947462,2.4336404189113736 +63,179.18294098400213,220.75147009194285,0.9073027108364632,4.022599904522527 +64,178.6879893390563,223.61664229341952,1.4338252285037825,4.345355288391667 +65,263.02108805781836,206.8238570753259,5.5378567029179875,16.167997116958563 +66,265.3281568315068,210.99878283626376,5.500522890838178,6.34492497544118 +67,264.9755279946045,209.25693017899349,6.61860699217799,5.010726338500632 +73,274.91234547074936,204.52721235111983,7.271387658815161,7.492660955010252 +74,273.0873606007509,206.72185414526035,10.116961928861889,7.92146394391769 +75,272.91870930424335,206.4183338799366,10.032578813526321,9.289382922896465 +77,352.6038013638071,203.61911600747297,7.436756719086957,5.005556173534007 +78,353.00800784867783,202.31796836001985,7.664430224814655,5.213297761872742 +79,351.746134852955,203.05786731461058,8.028743708479537,6.197058831659775 +80,311.08741311854095,205.08798593428077,7.289167841693958,7.075120130726391 +81,310.4676353064527,202.3951467032501,8.630027200417027,6.3233804917837135 +82,311.07935156741206,200.8328753632899,8.282608636183143,5.648212100237218 +83,311.4698975682484,201.29198895046432,8.073700564520845,3.988913299124529 +84,131.85526420446874,252.0193765605421,4.710522724823439,6.327903412535792 +85,130.09901692321196,252.49815518747823,4.810325247545613,4.925112427111756 +86,128.98108803670195,254.22164770572394,5.286838664341266,5.5052487948351745 +87,129.58841891167637,253.33496272524005,5.004724826446331,5.207955764055635 +88,174.3431769252481,257.67973667788516,5.936812237283513,5.016793813986966 +89,173.08617175672723,252.22705318297471,6.9528446346151735,2.9206960921180114 +90,173.16612346262423,251.83252079351362,6.7445812273675925,3.0963895698154125 +91,175.31435856398238,256.47051595889315,5.036171505418926,4.369569543933027 +92,214.0019796882893,255.64524660837301,6.840266287108221,3.3162161792801035 +93,213.6417614987187,254.76260041862824,6.181548205388113,3.4669409389809114 +94,212.59841286272757,256.77538398368796,6.642291270826204,2.865009376798548 +95,214.6340156872122,257.02599392382655,14.761579728638067,2.9573164604380775 +96,257.12202196483105,254.71576094200717,6.982679389033818,2.9625204035270136 +97,257.3916794657995,254.02867969902485,6.8307722895588965,2.3226285735907486 +98,257.2278305685032,254.5619736557002,6.809772888664755,2.8383983340571364 +99,257.16282933783424,254.477050995793,6.931960195707054,2.6611905102158038 +100,297.5612747805052,254.68621271243086,6.616832054817872,2.682409735201763 +101,298.3394946306158,254.9149917819558,7.4103859236839025,2.0032533635948298 +102,297.7037470787607,254.32926027245796,6.697390437340011,2.6035794639192695 +103,297.9018444784966,254.79769770872946,6.481459768864603,2.9116637606731044 +104,337.7041120241776,252.2287315192184,6.785308450450591,4.100479545727181 +105,338.43934115988196,252.2496982308047,6.235731773413765,4.82066583664529 +107,337.8271824583213,250.73973826046893,6.0034125806830785,3.931922093279878 +108,337.86197274862946,250.42655028770324,6.756971947757317,4.556599933768003 +113,275.3004995531795,306.83564646386503,4.779925536315024,4.424861919299598 +114,276.88576480308285,311.35434787217997,5.549501601726021,6.526755225085992 +115,277.14029465508577,309.65039091667654,4.580940412764937,5.080639071791438 +116,277.4324777875824,310.4960617480911,4.471359740657681,4.32292480362113 +117,319.3288258962187,311.6702225501444,5.058071424215753,5.61952659445947 +118,319.8591509274496,310.989524065149,5.676606774774989,7.467429803565788 +119,318.99005649592243,312.4173775749036,5.750237766169274,5.397366324681752 +120,319.6131328938472,310.5522979637107,5.5022885295904205,7.263578897387779 +121,365.29517640566365,314.6454813265486,8.460762409909734,4.6709015542721914 +122,361.82211363523294,313.68568720200915,5.985773405781822,5.263777316141343 +123,361.4480761928614,313.0382171673784,5.736550096606568,5.653009750209729 +124,362.77676743108657,312.1993102338357,5.979547887317892,5.588195075901747 +125,444.8280999329621,315.2874742212303,6.27290398703566,3.2254871043818376 +126,440.039105136866,316.4990582369399,2.717419411362314,5.5021381149114275 +127,440.1448707987162,316.91453325930746,3.591630687306421,5.692686701585921 +128,444.4735843873624,318.5837135172218,5.650865106238081,3.8098846947664695 +129,480.4945871932981,317.7789400812657,2.8473874205661946,3.2846798443123237 +130,480.34502455519726,313.1237155709503,2.8405711463483505,5.887133881466956 +131,479.79765238044547,317.8026694666446,2.5364142708665374,3.2181996809796747 +132,480.81626241860704,316.98435781490645,2.135649445640601,3.5315188723853113 +133,482.1126824365287,292.7236746644675,6.795795621748642,3.589777249851841 +134,60.57986058588791,298.3572263782008,2.0715574011265097,6.518875203291838 +135,60.26789543218528,299.7821310194954,2.4359457319030224,3.302053162843642 +136,59.50091999103519,298.34107118829087,2.338468862304903,3.0546922696738714 +137,101.38271621918946,296.483247325443,3.5173219751207268,4.497162712521202 +138,100.43332664554771,300.16356781590855,2.6915212734293545,4.145281353905138 +139,88.95536885340141,299.07746679015054,2.783698934533499,3.917152490131537 +140,100.29389089950519,299.8972675509202,2.566259282658186,4.137718806425782 +141,119.96308784890563,299.8312652747876,2.8076039128455625,3.487604969893026 +142,119.21634890704448,298.4258068241335,3.1000278549881677,4.175736792274726 +143,112.26314328941838,302.0132035682278,4.497193147167675,4.627836503294436 +144,118.63154926153814,299.5090092566827,3.3112468547584886,2.82625813066952 +145,140.22829557703238,295.83589398019353,4.880610377957939,2.876734137897074 +146,143.96502880541922,295.45158153676647,4.250115873207735,3.0733240603225105 +147,140.66008917985863,295.75005128745903,4.893542903008491,3.138028915535486 +148,141.21893535376495,296.1533805219746,3.774408848238054,3.0467012666428333 +149,183.47872058961224,299.0180109809012,3.257615072049357,4.1723220562822725 +150,183.1202811035564,298.79425325159076,3.469002943022174,3.997120410978376 +151,183.2016789609457,298.4838438451825,3.1679502308294953,4.084970750698522 +152,183.56716590770395,298.3764936397965,3.3471833496481467,4.077681465171855 +153,190.41048704769,330.4978785855013,2.083041500838133,3.4668015126104454 +154,188.96675676778156,329.9036439013521,1.9931882571475936,3.508215161643373 +155,188.33490314035438,329.81417912235116,1.8728073653310773,3.0484929469157747 +156,188.31414516895805,330.23186734474723,1.8830058285338804,3.3131134887294613 +157,231.30258441852257,329.2869590111576,2.1015883812262706,2.7686520980654414 +158,635.9719402081547,323.45669801247647,3.890586665705017,3.4262788642164947 +159,231.58692741290457,329.78511421313885,2.073756648357063,3.6457128678010338 +160,251.94245026669623,329.3621392921355,3.4400207042718804,2.525297437969197 +161,275.38274900691636,330.6582764942376,2.7758194307457162,2.781269710685483 +162,288.16094061378243,329.96864420502334,1.7425792225683983,2.7891999383989616 +163,273.9343912983064,330.28517683915425,1.88697235808454,2.153903027764216 +164,277.40318080027276,331.32724722075693,2.51910988134524,2.2364789702215044 +165,294.8273106877241,330.7078842677868,2.0202421142551663,2.645341711239525 +166,317.03626643514605,330.57896380392424,1.9865816645763301,2.776754699862097 +167,314.93276908458336,330.67614347282944,2.6509184944650532,2.7861880759516926 +168,299.640483801822,330.68496013319924,2.1034251306897223,2.6995826605586095 +169,397.31504374955824,332.3446123671715,4.011960577043935,2.119261063102862 +170,396.5580357804531,331.5612694467712,2.1013176840578547,4.345997085530413 +171,397.49205012933754,332.4442253933989,4.083617010295474,2.083000027123604 +172,396.4373476151805,332.4498304809778,3.6443064475289324,1.9520773323350806 +173,172.71708638362486,155.60703919548823,3.073597315308788,4.401620808681049 +174,174.69066860790247,155.66811371703272,3.3201919365119563,4.524189384907778 +175,174.36012639095586,155.21688748228445,3.313966666920818,4.280738433967948 +176,174.27542002212184,155.33243945954135,3.4684361769046457,4.3256192119148285 +177,211.35953547851577,157.84363965463723,3.719577632132569,4.52395842333967 +178,215.49817946473246,157.8061035073585,3.420835243071113,5.204301731036066 +179,211.58080964064885,157.9196266744007,3.750774395208928,4.781345943827068 +180,212.21010780634873,157.82655078622685,3.0477176203472505,5.171003834767582 +181,261.951692200774,158.03145626439886,3.3820588588480125,4.517024497962329 +182,258.53106462200054,156.41654274449266,3.610545283020404,4.607365869710835 +183,261.9931127261629,156.844374467896,3.3582923289081412,4.203836335498702 +184,261.97037263466234,158.27263012263947,3.4440759214867183,3.5700855150119994 +185,303.2394620820782,156.27343358354165,3.4728086741188746,3.133134636490943 +186,281.81947814044815,157.07330827651708,2.3587900891205402,7.458771102609963 +187,296.79672730554864,156.66963976209618,2.4956604990337636,7.422350136504288 +188,300.202613978401,156.83041886564462,3.6244136435867715,2.652614592092425 +189,383.13489230058434,158.29028886500078,3.9437889097096543,4.109817373692409 +190,385.65899984883004,157.07389261777607,3.7243534642349445,3.3291912053378807 +191,385.5178115620514,157.22774057918932,3.5586432492433517,3.220168950341415 +192,383.2113575049479,157.78585537067738,3.864821842971764,4.094143758353614 diff --git a/img_rec_module/meas/convergence_naive_std_1.2.csv b/img_rec_module/meas/convergence_naive_std_1.2.csv new file mode 100644 index 0000000..5f851e0 --- /dev/null +++ b/img_rec_module/meas/convergence_naive_std_1.2.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical, +0,,,,, +59,93.31359188,216.1040838,0.618237701,2.897325933, +60,94.25152003,211.5127273,0.358870938,3.374833177, +61,94.64301786,213.3034423,0.841278395,3.062799586, +62,178.7915698,221.842599,0.620940525,2.727375108, +63,178.7793615,222.1382787,0.946339151,2.65755042, +64,178.9998276,224.6227623,0.61583784,4.559621449, +65,267.3253475,202.0759585,1.85039789,13.78987315, +66,267.6140114,206.8004802,1.867849351,1.710489483, +67,264.4386823,205.8818785,3.840233588,1.91476041, +73,274.5584796,203.6589219,4.505342013,7.217491136, +74,277.6065739,204.8403967,2.53813086,7.562467947, +75,273.475128,204.5665369,6.401795049,8.18811108, +77,350.1228767,205.4123371,5.43844845,2.525576348, +78,350.6271681,203.2043449,6.076846255,2.128968071, +79,353.5340449,203.7901342,5.894050026,2.029409224, +80,314.0476596,202.7447844,4.208062302,4.422405408, +81,303.4655309,200.20082,5.864841166,3.753278554, +82,309.7350728,199.2472142,6.146777379,3.229374023, +83,309.8136405,199.2700541,6.473807505,2.771201556, +84,131.8274832,250.45136,3.454262443,4.292952578, +85,130.5911362,251.9466741,5.088611576,3.864515618, +86,128.8594455,249.1550605,5.279052334,1.307516431, +87,129.6418099,249.7265599,5.674102334,2.163786429, +88,173.670631,256.7522595,5.866553313,5.378715369, +89,172.1209707,251.555845,6.337603661,2.552356252, +90,171.7976064,248.0992246,6.534417234,2.007986084, +91,175.4092531,250.5219813,4.288839034,0.449640845, +92,212.7821633,254.033097,4.812117576,1.782691476, +93,207.3837324,254.5046734,0.604104252,3.278464481, +94,205.878535,255.4463699,1.55981283,2.705140417, +95,215.1501942,255.6424315,6.824346381,1.148906305, +96,255.9885149,253.6259804,6.494243171,2.421806172, +97,255.9826219,253.3646297,6.468647931,2.314616274, +98,256.1173538,253.322848,6.512173805,2.525898973, +99,256.2712916,253.7108958,6.57082344,2.465309527, +100,298.0833418,255.112182,6.687485235,2.531228209, +101,298.2465484,254.6691023,6.972265463,2.244339125, +102,298.0574205,254.6292176,6.694673144,2.290234567, +103,298.2353999,255.3627222,6.715087555,2.480896289, +104,338.9662203,251.6682432,4.494612613,2.181306735, +105,338.561305,252.5513452,5.899400221,2.549982168, +107,338.2423486,252.9079453,5.969934008,2.233318369, +108,338.5868489,250.286223,5.33707157,4.858284282, +113,277.5107012,307.0031736,3.046533561,4.079715047, +114,255.1425714,309.5914535,2.510342558,4.047091188, +115,163.3300795,311.0088971,1.739802853,2.119176746, +116,280.0267197,310.1878877,3.540974806,3.241557011, +117,309.0100015,310.4995789,2.279200941,3.89632061, +118,308.5100407,310.6270883,2.394103014,3.880968022, +119,308.7154325,310.6634883,2.330905714,3.520600361, +120,308.2952932,310.4657549,2.470183202,3.733393577, +121,343.0092421,313.7186642,2.116047292,4.058166847, +122,349.1493542,314.0310377,2.329671674,2.776838945, +123,349.1687586,313.2820578,2.324583878,3.911303408, +124,349.4798254,312.2673706,2.167920266,2.618473133, +125,447.2714051,317.0089575,2.288747629,2.283465886, +126,502.0743419,314.9331407,1.859257159,5.638134747, +127,442.2191901,315.5624488,2.275416429,5.721606222, +128,440.9195945,316.1320465,1.959733233,2.12793613, +129,482.4868589,317.7187731,1.760711011,2.837186752, +130,485.077771,315.7744691,1.876571793,2.865671883, +131,482.3554415,316.9661161,1.737629421,2.691241938, +132,480.7531236,316.3363629,1.885581584,2.381456819, +133,9.357026816,301.1394482,7.424860692,3.888697336, +134,60.72228834,293.4657307,2.410669491,2.816753402, +135,60.53625758,293.2506041,2.610803253,2.504754891, +136,59.62145759,298.4361014,2.409380579,3.230447055, +137,103.2748467,295.0002111,2.285610091,3.448504993, +138,108.7313646,294.0818247,1.941384263,2.600507881, +139,98.77723689,295.1770333,2.394266051,2.756924387, +140,109.8090092,293.9924853,1.789054477,2.547258237, +141,121.6681385,299.5494119,1.285859505,2.314668892, +142,117.0240124,298.3520769,3.085394371,3.004881909, +143,118.231263,298.9916067,2.3397467,3.279021573, +144,119.3795533,299.4061851,2.582789129,3.228779442, +145,145.2816959,296.1970142,2.38417805,2.058778107, +146,20.45948253,296.5421431,2.681947682,2.011036224, +147,145.2227435,296.1268899,2.395705671,2.043939485, +148,140.6543991,296.4875091,3.005656896,2.058048941, +149,176.9462544,296.4796109,2.24719876,2.122544254, +150,148.5858476,296.4403641,2.206492677,2.144769353, +151,65.25284426,296.7475332,2.121864812,2.069698061, +152,178.3156184,296.2248128,2.213752826,2.117494282, +153,181.1171007,328.9279925,1.042514147,2.315998788, +154,159.2464172,329.6605288,0.722943069,2.202447441, +155,181.1092004,329.3955388,0.942331973,2.157325361, +156,181.3698422,329.4487599,0.935400997,2.159791188, +157,231.0298311,328.6050525,1.743400369,2.014717548, +158,240.4715846,328.1027257,1.297159757,1.643873703, +159,230.7677404,328.3139315,1.058343333,2.111095523, +160,229.5831095,328.8765845,1.186522348,2.087957983, +161,274.5137789,329.787221,1.746109884,1.564619793, +162,282.1821412,329.1227352,1.655838365,1.70307133, +163,274.4928638,329.3941296,1.454030821,1.270915558, +164,273.8955019,330.3408954,1.582117708,1.359498013, +165,313.5529536,331.0516411,1.516937377,1.509223594, +166,313.3897344,330.8407781,1.689424981,2.682274969, +167,313.7752015,331.2133122,1.484833323,1.572483211, +168,313.5745346,331.0747921,1.494009096,1.508575908, +169,396.3749593,331.9599787,2.151936274,1.343475157, +170,395.4237167,331.4329569,1.38376668,3.13374328, +171,396.5362021,332.0594479,2.233402524,1.33687979, +172,396.1637403,332.0628234,2.324809169,1.357494946, +173,159.2585618,152.0587907,2.454979661,2.419010121, +174,167.764136,151.9791958,2.249078383,2.39506924, +175,174.3513505,152.8927439,3.04541391,3.046012787, +176,163.8593125,152.1163908,2.245850906,2.431233894, +177,205.7580054,155.8305562,1.827178353,3.281469065, +178,214.6691565,155.4932254,2.282992011,3.193875104, +179,181.5625169,155.9851325,1.905636989,3.261743342, +180,222.7501825,155.2467436,0.53759681,3.263462486, +181,262.2540038,157.0830956,2.25298472,4.265499609, +182,259.441742,154.8143458,2.740600452,3.54091322, +183,262.3021049,155.3844415,2.205532074,1.69929688, +184,262.2291226,157.3954305,2.293182978,2.60561097, +185,304.5189197,156.0942392,1.719384081,2.919789238, +186,303.0823173,157.2681966,1.029613582,3.819098347, +187,301.7653099,157.2055926,2.575352453,3.818184906, +188,304.453398,156.148651,1.750578234,2.570731724, +189,384.9615182,156.8279163,3.147447988,2.436219831, +190,385.142509,155.9370708,3.034486866,3.649388391, +191,386.1865606,157.1308598,3.021833082,1.681812081, +192,385.0689288,156.5647839,3.129473983,2.464805802, +1,,,,, +59,92.98020296,210.7301638,0.522791146,3.672149354, +60,94.33424541,209.6207769,0.712959043,5.350162777, +61,92.64802764,210.5177497,0.595418733,5.547156704, +62,207.5747279,229.3538544,0.572121859,7.308688367, +63,178.2643509,230.1392843,0.916307827,7.241140372, +64,178.1218968,228.6406397,0.596703167,6.59232167, +65,263.1356007,202.5171299,2.993282392,13.10837515, +66,263.5498432,207.7381358,3.121060979,1.878113055, +67,263.39403,208.059889,3.084362941,2.375246951, +73,271.8260844,202.3394456,4.989389367,8.076149884, +74,271.8410755,202.8123375,5.31885568,8.053726527, +75,271.4096589,203.2728694,5.377230076,7.871267788, +77,349.9253798,206.1879045,4.582862379,3.702027552, +78,350.3296416,205.0583594,4.842890663,1.299663431, +79,350.0649697,202.2775243,5.79411775,1.942694674, +80,309.6366463,202.5052936,5.826833998,3.849897421, +81,304.2156432,197.8316841,5.835220622,4.295831468, +82,309.9442683,195.4976857,4.627150851,6.342731115, +83,309.7147295,197.0265133,5.058831189,5.889513251, +84,130.7344064,251.8116871,6.430453555,5.341680351, +85,129.1112752,251.1902156,6.008621382,4.323092999, +86,127.9831913,250.8210973,4.738368491,2.572218628, +87,130.1965719,252.2844149,7.110134504,5.09323269, +88,170.3002318,255.161434,5.690121369,4.700436401, +89,171.2585947,250.0133249,5.680641798,3.776527602, +90,172.1235758,251.6800326,6.2294994,4.20315816, +91,173.3400802,254.5386511,5.543590958,3.91363343, +92,213.2603045,252.3008681,2.335677624,2.872250524, +93,215.0902707,254.1583026,4.339354721,4.369371457, +94,211.9678785,254.1058558,4.275784379,4.46023842, +95,214.8368785,253.4169863,5.506727817,1.911466032, +96,256.517454,252.3881478,5.815407196,2.550431856, +97,255.6478728,251.9252364,6.11987315,2.152700053, +98,256.1374083,252.0516904,5.782654633,2.667395102, +99,257.7228752,252.1299079,5.335083237,2.128049929, +100,297.8311949,253.9653172,5.924725405,3.167204464, +101,297.5128414,253.9978911,5.638642622,2.746686532, +102,297.4725186,253.0521962,5.860286143,2.352795437, +103,297.3362522,254.4734242,5.715730646,2.516042898, +104,337.4351662,252.5457049,4.125562667,3.313965227, +105,337.8624427,251.5183513,4.989598867,3.12923061, +107,338.2193223,252.1032549,5.515561111,2.99820905, +108,336.3124802,250.2062703,4.716755758,6.491905854, +113,273.4054239,309.0245598,2.007529628,4.545176202, +114,275.7006,308.5897281,3.903782811,4.201910704, +115,275.6098701,308.5642409,4.631427944,3.639510738, +116,277.3921761,308.2813594,3.80169276,3.534953726, +117,293.8297693,310.7195738,1.521629374,4.613201387, +118,291.7659335,310.0988882,1.468614673,3.891663176, +119,309.4115342,310.3821357,1.182104119,4.505358982, +120,292.5515413,310.0542368,1.424775019,4.061589902, +121,347.8690582,312.263906,2.086860469,4.058200539, +122,359.5565312,310.5047441,2.330047253,3.638307358, +123,359.6470891,310.5270923,2.359429636,4.285573798, +124,361.5717357,311.4896921,2.501565545,3.082805746, +125,445.1246388,317.8559644,2.770881273,3.991135312, +126,416.7634163,315.3075299,1.770909628,5.747036063, +127,446.3346171,315.0196018,2.263014967,5.752920657, +128,442.282108,318.1603279,3.090257217,3.581681297, +129,478.5480048,315.9810021,1.765570954,2.41855109, +130,479.1318974,315.5731843,1.398148504,2.403118465, +131,478.6645006,316.3894294,1.795372838,2.422278886, +132,485.0663804,314.7146343,2.330786814,3.08044557, +133,87.59543272,294.7524772,7.59874341,3.091737517, +134,57.18983221,299.3908146,2.514015918,4.165559587, +135,57.04702337,296.9718239,2.857620858,3.649136041, +136,46.33616939,298.2861068,2.691730212,4.096440805, +137,100.69449,290.5774527,1.724170339,3.065422071, +138,159.3624208,292.72289,2.784165242,2.962548105, +139,353.4092013,292.0076334,3.014363498,2.92804335, +140,89.97636901,292.9113393,2.654947202,2.871927676, +141,122.0853563,297.6938028,0.685452566,3.352456383, +142,132.1553664,297.2171229,2.706901699,2.956878084, +143,127.1646194,298.2335745,2.769134247,4.011140387, +144,130.8707996,297.8983473,2.818953624,3.899711628, +145,150.2748279,296.4426353,2.72517508,3.718234377, +146,148.9487989,296.2260643,2.706792749,3.704570535, +147,150.1580396,295.8625463,2.810800537,2.960921611, +148,152.5470386,296.7976312,2.875415992,3.731793392, +149,178.2623154,295.1070469,1.566658642,2.765605075, +150,180.9716772,294.9012941,1.684242753,3.139648254, +151,182.3315967,293.1571828,1.88832792,2.268070032, +152,181.137088,293.5579351,1.671971687,2.330347328, +153,185.9711466,327.425234,1.691859372,2.387374111, +154,185.6800748,328.060633,2.609970862,1.94621952, +155,185.8166898,327.7405073,1.727258135,1.871705694, +156,186.4702702,327.2910587,1.608306647,1.866211656, +157,232.0471896,327.1305533,1.526798514,2.151252107, +158,229.4438949,328.3898306,1.156559873,2.225493584, +159,231.0122446,328.2692359,1.210844403,2.221420963, +160,244.7640449,328.8696047,1.374765582,1.935943501, +161,272.0799492,329.052411,1.166202217,1.28745393, +162,752.5860223,325.8625051,2.107359839,1.609035927, +163,272.5343254,328.9438388,1.464422622,2.480037038, +164,283.0401036,328.6492917,1.198989734,1.977731191, +165,314.9483725,330.5771118,0.672009898,1.622968038, +166,313.958339,330.6951411,1.098557555,3.125795977, +167,312.3748044,330.5081672,1.235648115,0.963304922, +168,312.8132723,330.7618727,1.348540765,1.93311836, +169,395.1307954,331.5074481,1.448023063,1.892084895, +170,378.9013814,331.4082092,1.792713799,3.432678443, +171,395.3009462,331.5620671,1.453176361,1.84090791, +172,396.6957515,331.684604,1.422416718,2.181389097, +173,172.4328077,153.1365897,3.00979225,3.273591347, +174,174.8689464,151.9590035,1.271482898,3.354743027, +175,173.7469032,152.0170272,2.992197181,3.587820476, +176,175.0489368,152.9142709,1.273711372,3.067651219, +177,220.2914705,153.9301722,2.661722075,5.161796303, +178,218.8061959,153.873329,2.751169022,5.214692401, +179,220.2111266,153.8301993,2.528867915,5.135768244, +180,221.0904806,153.6681136,1.36428459,5.195182563, +181,260.2185867,156.1774186,3.167143162,4.210885006, +182,276.9192779,155.752447,2.098877657,3.126639131, +183,260.0002443,154.9000065,3.142718258,2.746624899, +184,260.1158035,154.8963762,3.210429251,2.62793041, +185,298.167749,156.5262689,2.118650858,2.472370547, +186,303.7104855,155.0312339,2.739066062,3.598984306, +187,302.2662231,155.0201999,2.993547761,3.828128242, +188,168.6937164,157.3888805,0.989603153,4.043452094, +189,380.4478403,157.1834126,2.567599568,2.068498326, +190,385.0896758,157.6459315,3.558659095,2.667151842, +191,385.9717948,157.3015558,2.616974703,1.908230272, +192,379.9755719,157.0348278,2.624845194,2.4242362, +2,,,,, +59,92.80774775,223.3561377,0.63373947,3.204356685, +60,94.82990414,219.9054093,0.789060896,6.846135813, +61,90.4092595,220.1551552,0.922257111,6.838018548, +62,177.10956,218.9010373,1.390525166,2.749732073, +63,177.7445626,220.0664962,1.218558792,4.188825256, +64,177.3811761,221.4094598,1.295990619,3.612508185, +65,265.6878096,206.6551328,5.335870158,16.66971332, +66,273.1624412,205.5267621,2.216267652,3.574602068, +67,266.4284457,207.3593812,7.16312328,4.472335501, +73,280.9659797,202.1605676,1.654626712,5.681306637, +74,280.0193239,205.0374117,2.330531985,6.377333876, +75,280.9384725,204.351971,1.646830184,7.965623143, +77,354.887108,203.2393539,7.442012113,3.928986671, +78,355.1071844,201.8006435,7.656540481,5.190365035, +79,354.3451992,201.3442388,7.686501926,5.138973819, +80,289.243447,204.0055532,4.58144207,5.795627738, +81,302.5452164,202.0428129,8.253331974,4.651552993, +82,308.7167046,199.8020174,7.194696682,4.047995764, +83,308.8793972,199.482231,6.945358429,2.872448428, +84,131.9672656,247.4466899,3.076812196,3.459870992, +85,129.8883587,249.5830759,4.540042819,3.450294622, +86,128.1149268,253.652363,5.978168979,4.352921914, +87,128.537252,252.6585171,5.339963888,4.941548474, +88,174.7763496,255.8013916,5.728268852,3.498998329, +89,172.4531156,250.0851165,6.313071019,1.962531993, +90,171.3409715,247.6560238,6.581855503,1.831029569, +91,174.6659473,249.1824453,4.505611672,0.990903523, +92,212.1155467,257.1963349,6.711658598,2.240845082, +93,214.992281,253.3937445,4.95745259,3.977160866, +94,204.873601,255.8708178,2.120263764,3.169453436, +95,215.0833848,256.1212831,8.467407782,1.94734564, +96,255.92502,254.9921917,6.763112158,2.141438665, +97,256.1940783,254.3374307,6.713514562,2.121641996, +98,256.0021708,254.8322904,6.607905276,2.023401889, +99,256.0562427,254.8473944,6.760889792,2.566059289, +100,297.8613113,254.3084187,6.299358006,1.871267236, +101,297.5090684,254.1732975,7.403403204,1.825741321, +102,297.570531,254.484813,6.393439895,1.946205259, +103,298.2356864,254.3132468,6.191791543,2.014387656, +104,339.4930838,252.0286054,5.942208628,3.19529963, +105,339.8235924,252.7216561,5.056927498,3.013043648, +107,337.8947682,251.0496843,5.760272081,2.151022333, +108,339.5429906,250.0031284,5.812146409,5.287653171, +113,278.5304079,306.5030719,4.761955088,2.589866432, +114,276.3287806,311.8059975,5.162726712,5.347412476, +115,279.5195273,309.7197114,3.678439981,3.528386683, +116,277.8341863,310.7569919,3.685601883,4.736286987, +117,304.2455249,309.6986513,3.002773122,4.55528393, +118,302.5910518,310.8630341,3.1636375,4.959892925, +119,296.4299281,310.9683457,3.025514328,4.684284176, +120,303.1474392,308.7545195,3.172637676,6.51899129, +121,365.2154226,314.6041009,4.98222295,5.649531231, +122,341.3097453,313.954716,4.082311959,2.23304854, +123,341.7161701,313.5306694,3.968339357,2.174027249, +124,345.5257173,313.0220584,3.990163672,3.578776944, +125,469.1330131,315.0513307,4.437377537,2.47725153, +126,438.8511288,316.3709557,1.799887035,6.635379091, +127,437.9643787,316.8297365,2.404378501,6.796381593, +128,456.5949916,316.0343792,3.316370103,3.022194886, +129,478.3667044,317.5900476,1.477074747,2.534323472, +130,478.6797334,315.61719,1.885919089,3.697683958, +131,484.2348696,317.9951215,0.962093158,3.007330919, +132,484.1170489,316.4021371,2.002291195,2.919700186, +133,85.29652369,299.926705,7.827458514,3.937423663, +134,59.67047635,298.4471118,2.293779231,4.907606339, +135,55.46090118,296.1797692,2.475399962,2.485135918, +136,52.88374765,297.6242074,2.052251164,3.035605218, +137,102.2355224,295.6763876,1.22628138,4.920419862, +138,107.0183407,296.2388908,2.187701543,2.202721291, +139,108.9649908,296.1444929,2.302412374,2.209906061, +140,106.7279343,296.3701875,2.251034343,2.356004223, +141,120.9447868,299.1646936,2.931034996,1.870227654, +142,118.1973619,298.0334936,4.076098187,2.634668296, +143,117.626087,297.8252302,2.900494158,3.224708556, +144,119.861526,298.3571524,3.49398133,2.953550317, +145,145.9000645,294.3312061,3.803172414,2.403143838, +146,145.4214846,294.4868154,3.267697342,1.825315104, +147,145.7428138,294.1450033,3.987455312,2.437598704, +148,143.0284346,294.5618795,3.649189497,2.401468767, +149,185.8282608,298.0425231,1.272428277,3.643826725, +150,185.9498776,297.7664853,1.248367103,3.441098707, +151,185.6174834,297.1887106,1.024053665,3.507686463, +152,185.7795824,297.0711508,1.20747523,3.5087149, +153,194.1877708,330.071149,1.176771328,2.255752122, +154,189.2603762,329.3370618,1.370351835,2.119976972, +155,183.5303914,329.4293977,1.576418861,2.023661479, +156,183.3754904,329.9333334,1.585241848,2.049146037, +157,232.8780299,328.5197502,1.546698079,2.435561977, +158,255.3837334,327.39891,4.012448382,2.890275591, +159,205.5013925,329.9023819,1.958210827,3.923308113, +160,216.4453637,329.1893338,2.373852392,2.222571188, +161,277.1390123,330.8696438,2.264039169,2.174324696, +162,273.7246411,328.1831137,1.667751192,0.989783278, +163,322.3699595,329.7367532,1.852350787,1.37665533, +164,197.2500263,331.7884197,1.707784311,1.962322643, +165,301.3391123,330.7070529,2.05808286,1.699031874, +166,318.9940458,330.5262295,2.512905677,3.004133231, +167,285.6755255,330.6208442,2.005104058,1.510838797, +168,303.3766759,330.6890426,2.123836632,1.561502074, +169,399.4469649,332.5112476,3.236447147,1.345904021, +170,399.4479821,332.1869344,1.78598569,2.110197381, +171,399.5666501,332.7032035,3.319483494,1.271894754, +172,403.9857431,332.7091106,2.841535249,1.352866247, +173,272.0791472,152.2310031,3.137638063,3.319842322, +174,171.1803293,154.0741983,3.043033059,3.147961415, +175,172.5368551,153.5142165,4.048705698,2.906116814, +176,173.5537003,153.7359113,3.18246475,3.208562905, +177,220.452141,156.7383818,2.725644558,3.229124685, +178,219.9369118,157.0167193,2.929832633,4.337287441, +179,220.2700191,156.7580906,2.801366932,3.436425987, +180,220.212808,156.9960205,2.771416096,3.551997, +181,260.8297065,157.7245607,2.864867836,4.836641376, +182,299.4671643,156.5779657,3.042758034,4.175090355, +183,260.8703321,155.9495176,2.856985202,3.724198165, +184,261.1959859,157.7695767,2.671200412,2.608809478, +185,303.7898051,155.2967427,1.996466596,2.949035097, +186,312.0293319,157.0403841,2.517021055,4.306578124, +187,335.3153106,156.695305,2.879498971,4.237238691, +188,304.3482421,155.9405605,3.14362489,2.311963161, +189,386.0460662,157.1564715,3.503153843,3.344989582, +190,383.2598233,156.2541372,2.931096625,3.788089778, +191,385.0925047,156.6704184,2.621070632,3.280658801, +192,386.2252536,156.4378146,3.373862306,3.19857897, \ No newline at end of file diff --git a/img_rec_module/meas/convergence_prime.csv b/img_rec_module/meas/convergence_prime.csv new file mode 100644 index 0000000..54b1f8f --- /dev/null +++ b/img_rec_module/meas/convergence_prime.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392,0.9677151865944192,4.009449743264753 +60,95.68692886974831,217.86446645631813,0.7424975144337135,5.151973582834018 +61,95.27930768267886,218.4321212539979,0.7270480243366128,5.212134543408362 +62,179.76038347611592,223.31234892921998,1.1147842657503555,4.609101395283265 +63,180.6656249576765,223.71898099246778,0.83092419657981,4.560940210510493 +64,179.89926897794987,225.49954804120625,1.1381174020649096,5.315085189344285 +65,267.2846565814505,205.23349976223787,2.3312417949986513,12.645312337636021 +66,267.49589526309217,209.85177109164337,2.394374307275872,4.5107503315754 +67,266.1835519250078,208.6210325552379,3.540061676733699,4.360052044157361 +73,274.3400431870006,204.75610310411912,6.491531432619202,7.31888797087335 +74,273.48666750879767,206.22331690671257,8.261574847627143,6.971589386730805 +75,273.15099171429256,205.61817173382607,8.395328002698498,7.565385107130859 +77,353.2863004930388,205.14959199780805,5.493098240735283,4.2828384868245655 +78,353.9238420531685,204.12742442066988,6.087365194189325,3.791338436749506 +79,352.21840596322596,204.15679894425952,6.557195072515586,3.1954900594475086 +80,312.16235018388227,202.94043465851004,5.386818198872637,9.493830520912068 +81,313.14659922988295,201.99717866560937,6.025875449926955,4.661460417025812 +82,312.11840038067925,201.00669797880116,7.0864910249072635,4.406813194332426 +83,312.29317276741347,200.45780062295867,7.089188755441932,3.1660046223221405 +84,132.42237239805132,254.29214663519284,4.3067464843901515,6.417058493680035 +85,131.29521858798734,255.4865958538821,4.908850345384105,6.3671100735668835 +86,136.03545039679358,255.0814813071878,8.584433337345413,4.807018608010044 +87,130.98094102950247,254.42187606024922,5.117211446405824,5.370134929913309 +88,174.55795757665564,254.28580927665664,4.7275771979909464,2.9159640887010574 +89,173.67935580024877,254.09783447631526,6.437695363099053,3.474606588647915 +90,173.43573264703227,253.47071779954354,6.593885801251147,3.4291368786010663 +91,182.2241727196623,255.67658212128163,9.720017436299852,2.9496717195778195 +92,215.12055072666627,254.67325551865426,6.334123387607411,3.0867909122735444 +93,216.94462220467622,255.47756358425315,8.080773269328214,2.7211585139427834 +94,217.3834915918711,256.4745644877478,8.267318853585852,2.211181525286066 +95,221.02053888484144,254.6506021697632,9.359150594815015,2.1628014762683434 +96,257.50957542067664,254.1259284055811,6.675780060232609,2.704136241957288 +97,257.570545197815,253.88751117668164,6.647657278502652,2.9140751377307628 +98,257.6089813372307,253.78662089019835,6.605179609252467,2.6809454420956143 +99,257.6936671647974,254.2498517060511,6.576722939133856,2.7069332019005827 +100,298.2952436151055,254.76909617478606,6.705809824561147,2.981349985017069 +101,298.1169393001307,255.21794911950758,6.624534032640799,2.181605220236403 +102,298.3189654536773,255.25096983760508,6.750900350115645,2.3083727544087247 +103,298.4415890038736,254.35763625124292,6.663590033871669,3.2667839890941295 +104,337.61901332805763,250.6788168722553,6.210728685673001,4.844297880273439 +105,338.06248003559915,250.78747044533233,6.338074391942699,5.000637757727747 +107,337.90938740495653,251.25867480332388,6.288961573364599,3.8152539451454097 +108,338.18833275957206,250.67508565210196,6.186589358792703,4.10107941402743 +113,274.2817559120019,308.9374117445766,3.892956777078502,4.794749659977309 +114,275.7421347767481,310.2555996702759,4.535765938235691,4.66622650744931 +115,276.0461325201841,310.02072804280994,4.545655403672037,2.2262514157125017 +116,276.2417374542582,310.24048782871637,4.6497847767530995,2.8951312130050146 +117,319.70071456271313,311.8764440530121,4.410519998245082,4.1053878934009775 +118,319.6313092726346,312.1826263203713,4.334709687203355,3.9909339754311914 +119,319.3774988742649,309.9857812246406,4.471689460416843,7.048323199965066 +120,319.76654338764155,311.98447027104925,4.4491853585047645,3.9716440216868176 +121,360.8050494733246,312.9126753058037,4.744138263484551,3.2959591069664484 +122,360.64739266264627,312.8307783296112,4.673876604017344,4.0505350195787555 +123,360.689270210389,312.2626467099784,4.717842951294665,4.331175918113057 +124,360.8335382258014,312.5428875466125,4.7257637014968825,4.238743771700391 +125,442.06586848771724,315.54047492369574,5.1708505304868275,4.096628870255675 +126,441.42140737582423,315.78584607818385,2.592454459875001,4.6687701093869 +127,441.5300773440553,315.90717126090226,2.8050705738429227,4.687041451309435 +128,441.95769286933466,316.8407357397122,4.805859396667629,3.6325916039286454 +129,481.35090878368925,317.4272946632326,3.3586867882998677,3.2305216999009705 +130,481.4725819590857,316.6159681822135,3.546147101969164,3.2838056303462357 +131,481.2522465836884,319.49752085243165,3.263691605498864,4.032091628707869 +132,482.31846086642565,319.45748209732994,3.3334111968000197,3.4001948797889874 +133,59.55768321914789,300.29871844382603,3.8761928423107794,3.6951665481304303 +134,61.376816545951996,298.3523691730104,2.113993300917673,3.899220174332725 +135,60.796935680150746,298.09076040109204,3.3916290934001863,3.4328323193984733 +136,59.19985355062283,300.1851062687214,3.520034988226608,3.5453648546285197 +137,102.6280068014727,297.40383468175656,2.749638491064498,3.880988203100239 +138,102.40955557323258,298.7865911290351,2.7573372442370903,4.089700063188653 +139,100.57013333623348,296.8202762296189,2.9651756626973564,3.163333481381463 +140,102.67850653460079,298.5730025774653,2.656076828883503,4.008870765124035 +141,120.23221696171454,300.1898879495705,2.3495738375350714,3.7101386992401784 +142,118.10535832779757,301.85912326532906,2.662771758344228,4.434372354516663 +143,118.16700474619614,302.0417496311767,2.810926040633238,4.442752618047973 +144,118.19187121087131,302.5378510894045,2.8502302470584953,4.428574269320613 +145,143.380762851227,297.65106023170455,2.9029598644975594,2.9494319243206975 +146,142.46748228973178,297.3647432540817,3.516542953167025,2.7867411900804395 +147,143.2239805848247,297.5672414624104,2.925450223126345,2.8821527557517435 +148,140.51718892104998,297.9845023911149,3.134479693224828,3.0837592352072623 +149,182.6593569656309,298.1418468359333,2.648390300198232,3.275571713707499 +150,182.64828488417706,297.92582445480707,2.7260433370787203,3.287985243918374 +151,182.92797391602642,297.87455852433123,2.5754349127258473,3.303821768124996 +152,183.0029286817877,297.8637465373881,2.6850779296217095,3.268506780902108 +153,186.1728851830908,329.8083307385874,1.6988565395865438,3.2857803265960546 +154,186.5492243440529,329.1491955430002,1.9159248202789043,3.190026296337793 +155,186.0292302003802,329.23752125561214,1.630100824234192,3.143397778827556 +156,186.05706501583137,329.3191466220413,1.6185913035274193,3.18627620460259 +157,233.36795685970054,328.463961880729,2.643309826783174,1.9867341998292147 +158,232.82586842848798,327.60883484043825,2.477588134745834,2.5854098103097747 +159,229.71350413783279,328.3780985513343,1.4377331090494412,3.4686128953627313 +160,232.72525153041173,327.7700361791668,2.4530240891852237,2.5077492129850194 +161,273.76316751955034,329.73823826493043,2.394688280474286,1.806427127995776 +162,275.7575781134558,329.9125721193857,1.3584269354839966,2.5506427041479443 +163,273.60940070127293,330.0025820738042,2.4087695062685763,2.2557767070416954 +164,273.7244999819209,330.09757535831045,2.4201727937672897,1.7894497412511505 +165,313.3973669095876,330.59163642669836,2.5664663718925884,2.5175272820859127 +166,313.23094160288184,330.71155384663837,2.556749103943359,2.517895305394224 +167,313.2083786255443,330.77428522126553,2.440925958919023,2.523508078782979 +168,313.36106959216625,330.6523370232485,2.5105680868176643,2.5022918306323914 +169,396.3640143494862,332.05477157898144,2.544597691516881,2.2242293500191375 +170,395.617460222669,331.85554030819173,3.094183882820774,2.2794261534246627 +171,396.3911361968549,332.1303447002533,2.5527965384171347,2.1830363581679078 +172,395.89256887798285,332.16822339411516,3.601013097767017,2.1716024486759946 +173,176.02029170516317,153.71245910000232,2.3779159513262353,3.409134278667166 +174,176.10545306203875,155.20318481126037,2.4825478178566596,4.418906030455666 +175,176.03197440143745,154.95241321278883,2.42399408636437,4.430327097224612 +176,175.6846804297304,154.63359606135103,2.5997462043064927,4.219400830122209 +177,219.46327960613064,157.23609785750858,2.529672116014354,5.058864568041901 +178,221.0564853241154,157.3435472260885,2.2463229070198545,5.480115541197549 +179,219.62129396536662,157.2666553285107,2.5021134486595593,5.352065132338259 +180,219.69587995502016,157.1490063640601,2.516169881431476,5.470652636210902 +181,263.23636033723557,157.46707082247306,2.6921936322678013,4.204926201545835 +182,261.4098116420003,157.70610911447298,3.132796451668047,4.302605485582752 +183,263.2875985178052,157.05504332147794,2.6601053814719973,4.186611997777448 +184,263.16270089611913,157.68858593709763,2.7082086799182084,3.4205893941412424 +185,304.06394490620954,155.96888190631856,2.6882263261194885,4.294769105680108 +186,303.2325028543831,156.57995759281437,2.7961523629805916,5.391517197327435 +187,303.42630311491723,156.4924674158584,2.783092188384192,5.365203962414015 +188,304.6158660912609,156.4818813819881,2.506720194343099,3.179833381166062 +189,385.42176721515784,157.40021026648142,3.5085984360932585,3.721190877059472 +190,385.8286612719259,156.9884186905783,3.520976122354819,3.199129896839037 +191,386.21040345226567,157.9321486459702,3.2937940620339354,3.184759624897468 +192,385.60316481175545,157.2028302886849,3.4609224939824603,3.763410712575745 +1 +59,93.1287423931208,218.29700908810787,0.586116217920642,4.982728971287442 +60,94.70512938803542,212.6540109552706,0.7530580888942188,5.342989457535182 +61,90.1361278577332,213.33121631876608,0.7741246171980174,5.183322455003788 +62,165.64289497225215,225.874391036669,8.768671109743122,6.55018459819764 +63,178.59192480601794,225.09457355443593,0.900267664385944,6.339222495180265 +64,178.41449448989624,226.08373120485984,1.0988445958401813,6.645297501896177 +65,260.3568485015321,203.21378596696644,6.531586140510156,12.691771056267052 +66,263.21633393064695,208.05235410434855,3.3776181785676784,3.91127933981223 +67,263.60509933731674,207.1941441096728,3.5771988890480593,4.045622146226897 +73,272.29022155441146,203.26015396542505,7.667403148427107,8.484726496612334 +74,271.44632269355435,203.63647815827935,7.006836949843662,8.247800147818172 +75,271.0412882240347,203.67673019265595,6.9166949430129225,8.702335904677817 +77,350.55117323928704,205.53824540412742,6.3913113962364445,4.535767728612248 +78,351.5831370996324,204.56554912486993,6.914935781146339,4.208591544669765 +79,350.54080463471854,202.80860415043412,7.576153280744988,2.405442522969295 +80,310.6203346770107,198.9727284928463,7.295908168915119,8.99449222675377 +81,309.4303871248667,198.8260778916456,7.8402558918165015,5.732595151892859 +82,312.8487475083582,197.88498609405823,5.545843437300968,5.5454679231566235 +83,312.4494378330193,198.02482356912975,6.100953297862154,5.205602033075617 +84,129.73316120742015,252.31402870350382,5.182904459352007,5.7859701617993196 +85,130.09936826716955,255.07600217340146,5.535923397107699,7.036159941672144 +86,135.81702697516587,252.10204054872278,10.027649034484337,4.399918094601206 +87,129.96018632025633,253.63904238622214,5.660756401038712,5.8266843261131385 +88,179.7261278913035,255.3456126662452,10.57223062780983,5.845563121104949 +89,173.42291095269067,255.58833819764322,6.700532645820975,6.247923198559783 +90,173.10761109611573,253.5025139362306,6.760737603124655,5.536745737424702 +91,174.12745797775463,253.2601960722921,4.897753124735466,2.522716607958386 +92,216.78511969207446,254.5914187233686,8.95047307481889,4.249360054724529 +93,215.97344562124545,254.7054640425066,8.196439917611718,4.011111129846635 +94,219.24024367384476,255.41662872012847,10.121690584983755,3.367632134220822 +95,213.91037600886813,255.01236900202147,6.258734602959029,3.284512606242694 +96,257.3830982530756,252.6691612485834,6.880768996147865,2.9353265504494703 +97,256.07878148245777,252.5850508469038,7.193370431289156,3.536434124406424 +98,256.6563709830754,252.14302077100646,7.020255474285572,2.742516414019443 +99,257.10274737541874,252.44669038983187,6.759367673913806,2.5065554147623534 +100,297.3527413648711,254.3197859755712,6.974691942771777,4.204342914024384 +101,297.36935919598676,254.31625883281748,7.003782434070834,3.8132099844257588 +102,297.45043676182286,253.29006124829388,7.147301062318091,3.0312100621116413 +103,297.15639353267426,254.26565823155238,7.3776805534006185,3.914660604118064 +104,337.0467224043386,249.84436792649663,5.921815081770851,5.271202014540857 +105,338.2530319319246,250.01216730218792,5.481575455905726,5.469000206273413 +107,338.4288143610566,251.12173304980342,6.654167871317137,5.370828824572206 +108,337.6321115297869,249.87042147419172,6.005664399486008,5.04451473974955 +113,273.20050531167254,309.1760573916311,3.4219821116654865,4.957144824013617 +114,275.593658985165,308.5727448984995,4.702522493967433,4.008413607725532 +115,276.45985797306344,307.75120186662025,5.767076285351399,2.479883936569082 +116,276.6589541465393,307.7328403118153,6.184525915073467,3.409658651068851 +117,323.8680795155452,311.25555593462394,5.6467354698699,4.163445875643856 +118,323.990822160368,310.23497244583933,6.354306297639026,3.605863723170547 +119,324.32484229774974,308.2748476589923,5.951639025695133,8.081943297913417 +120,325.7385894442358,310.39579583995135,7.723927817628718,3.904269142941334 +121,361.79131456676873,312.1771387146637,4.3915079798209895,3.778217894990519 +122,360.25109899783934,312.73975566628565,3.3364555278083112,2.7719078470887877 +123,361.13964194906663,312.4482596768938,4.009973777907947,3.338550731387954 +124,360.8021695665512,312.55731463103996,5.178975914859417,3.147724551644225 +125,443.6146844651626,316.9499823437052,5.441494217460369,5.589514223334737 +126,462.74164751366203,314.6397925160877,3.1723106571758315,4.673495905701873 +127,284.4684422338389,315.96181914108945,3.781047749264403,4.799446710082581 +128,451.0537747662026,315.05034330850094,4.165022446102917,5.582872998184059 +129,486.2262311408019,318.917422588962,4.360015955842124,4.24279052637777 +130,484.203371665194,317.155262043757,4.666439360195373,3.538660983437178 +131,493.89209637934295,319.54817622659806,4.495507964960477,5.054370244042043 +132,483.79815450187516,313.87456269013853,5.0513219188547716,3.976286497193232 +133,58.415796919717515,296.3367806354237,2.745318197812863,5.347714894650585 +134,59.66992690532717,295.46552315023496,3.0521020998678443,5.04724168228645 +135,58.43814573925214,299.01257928228273,3.0314355414314353,4.680341029748839 +136,57.19875149216512,296.2038703275876,3.0187024946676813,5.430283114579736 +137,101.88869112962361,295.36699152796956,3.0605704820563435,3.976231975252619 +138,97.74223572831934,296.64159635228486,2.388879471730324,4.818867004598817 +139,95.13971714462463,297.63279866894925,2.5874115321204054,5.108323412261206 +140,100.97448449522825,296.37143206657936,2.23273639508488,4.835560641819327 +141,119.46912848294882,301.03987366288305,2.945034185014498,5.579249063467622 +142,116.04630564586442,300.9428981940468,3.646493643610884,4.201903655805421 +143,115.93833802312685,301.4015147621542,2.7752574824028806,4.899750014060764 +144,117.66427038686425,301.67621994166734,3.2562262537824718,4.934112992862415 +145,143.61862339021508,296.87569921241607,2.9793460068872264,4.493879539069787 +146,143.84226240395634,296.5995702000957,2.6657882037152505,4.487866588043545 +147,143.41726284468888,296.4604242772443,2.892883624851368,4.50539522391336 +148,139.90710854861246,297.05847391439454,3.4669655178811123,4.588153704670423 +149,177.97012292111646,297.29360417935067,2.9817918310917375,3.750304964672955 +150,179.09943783225685,297.22176671479934,3.0286986838896457,3.881572977421466 +151,178.4595029850307,297.07969710485736,2.9749987384442655,3.775627144339658 +152,178.9990807254096,297.58186299960556,3.0418692927202193,3.8833402396923353 +153,187.06432524491635,327.5110792134713,1.9103539442817077,3.1747672773580633 +154,187.40611165319353,327.24266469486685,2.028936750132528,3.039992572908433 +155,187.48202253723917,328.1910452260973,2.046736087360523,4.07325152306089 +156,187.4554203440108,326.77537509295496,2.0468424040406785,3.0346527434557236 +157,230.1275716483488,327.66375493177526,1.3064642552426002,4.735119343666496 +158,230.19455285047118,329.6573791501422,1.6872246668899367,3.583570894848579 +159,236.39481488323716,328.4457905246168,2.716174379714519,3.4183380314351863 +160,230.1984260911562,328.23405030487964,1.818805777200218,4.578868396563749 +161,272.1545894887068,329.32912181766994,2.0716370234969204,3.1939556616595848 +162,272.8983988300567,328.70387641284987,2.430197123109527,3.1487498704390036 +163,271.6162444327857,329.4696874435773,2.203277751618005,4.017476086378616 +164,271.6290916788945,328.8920615225914,2.008299706725287,3.3041284732956586 +165,313.03716740034986,330.7975522275865,3.0420523810535003,3.7108953229128367 +166,312.7612082311074,331.01658878813123,2.756286496478564,3.635011569085448 +167,312.555857804164,330.94886104868783,2.895089352246948,3.630322203243039 +168,312.99233681057194,330.7594147506374,2.9514521257261572,3.7325921124368473 +169,395.6599712440442,331.38000769767353,3.6713668117121325,3.4549858187839337 +170,395.7269407162828,332.3551932767835,3.1249445864849728,3.2139419865878307 +171,395.64772093777225,331.19728501985406,3.652929258669073,3.3877347902405988 +172,395.7526488830209,331.2745983423243,3.9055257304944306,3.4415616827579543 +173,172.19300877613125,153.8677984100333,2.9936489675181246,4.5406288069622285 +174,174.43739755929997,152.4534316026212,3.1172372976035665,3.3179648689547276 +175,174.29318678572136,152.18270882980445,3.1219958686591287,3.3048067882101986 +176,174.37774565459176,153.9168218422937,3.148891388697558,4.4895441435882795 +177,218.92125782027884,157.06267339391565,2.7063981074883805,5.4304455216655905 +178,218.85237431972325,156.51579863987993,2.6795499708167725,5.289366508551004 +179,218.17652673671887,156.67648159701702,2.747386160206801,5.224977213644244 +180,219.63668315938992,156.54252374150602,2.654919821631967,5.2993336248236345 +181,260.39420520785944,156.89107932316213,3.256704661733587,4.125191869561575 +182,260.7451262620054,156.26061389330727,3.674975253680245,4.673081143856457 +183,260.0769741828374,156.73605149236164,3.2485067302773727,4.2314614221050855 +184,260.3205919730126,156.89282130924727,3.016527309499428,4.22117756304117 +185,302.8007745851293,155.22452212795463,2.1986861092464727,4.536996509806027 +186,301.70658980492703,155.39202732491273,3.616906361622583,5.809560313914322 +187,301.9655960101498,155.27173302476598,3.5367891506442364,5.787704448891815 +188,307.3464400351471,155.7530563647103,1.0636861640988715,3.4615533986219376 +189,385.2275499165649,158.1706520863393,3.813439832275512,3.640361036690412 +190,383.77693943350675,155.96991177533516,4.219569642219233,3.833536791723274 +191,384.1919840339305,156.6889394336518,4.594412135572423,2.0156822112075097 +192,385.249022040249,157.09793266480662,3.877568024165435,4.522637183712553 +2 +59,94.17681256320567,218.7493975260511,0.6672950811803234,4.0696236612012 +60,95.60291842116452,220.23420259378253,1.2432894303505535,6.268557799628915 +61,95.02957510532019,220.4523644522619,1.03897231445469,6.283961945108087 +62,177.88668491962127,221.41680696479915,1.1635891534947462,4.266168737180917 +63,179.2047201008017,222.0714847243557,0.9073027108364632,4.622657461501109 +64,178.76685855250403,226.32660678265475,1.4338252285037825,6.163194163231048 +65,254.59096062439968,207.56765796649344,6.468811941167413,15.484181828020908 +66,262.3514299707784,211.47058512229123,6.200035074796359,5.723850290560224 +67,265.06237168987434,210.4005448238059,6.61860699217799,5.422654412058275 +73,274.91234547074936,204.52721235111983,7.271387658815161,7.492660955010252 +74,273.2143306337384,207.55888389096398,10.116961928861889,7.899368121489383 +75,272.91870930424335,206.4183338799366,10.032578813526321,9.289382922896465 +77,352.6324668691135,204.06675998471425,7.436756719086957,4.8581936941677935 +78,353.05135609325134,202.98520282433685,7.664430224814655,5.142377982862242 +79,351.746134852955,203.05786731461058,8.028743708479537,6.197058831659775 +80,310.21870253063406,204.63993652062547,6.829422420637117,11.038982037055565 +81,310.5482455608953,203.3161899769199,8.630027200417027,6.825063086136599 +82,311.07935156741206,200.8328753632899,8.282608636183143,5.648212100237218 +83,311.4698975682484,201.29198895046432,8.073700564520845,3.988913299124529 +84,131.85526420446874,252.0193765605421,4.710522724823439,6.327903412535792 +85,130.09901692321196,252.49815518747823,4.810325247545613,4.925112427111756 +86,129.09877923534668,257.0902057833205,5.286838664341266,6.0960063153090545 +87,129.58841891167637,253.33496272524005,5.004724826446331,5.207955764055635 +88,174.34014870627018,257.6293741682174,5.936812237283513,4.578268483473221 +89,173.08617175672723,252.22705318297471,6.9528446346151735,2.9206960921180114 +90,173.29362621289272,254.03640143495207,6.7445812273675925,4.594746547363893 +91,183.93566207705527,256.40769459187646,11.366675081342697,4.086344657301128 +92,214.000238044348,255.61808278157844,6.840266287108221,3.162185843886936 +93,213.6417614987187,254.76260041862824,6.181548205388113,3.4669409389809114 +94,212.59841286272757,256.77538398368796,6.642291270826204,2.865009376798548 +95,219.36862273251444,256.7917930393642,15.042021453799604,2.839050343283112 +96,257.12202196483105,254.71576094200717,6.982679389033818,2.9625204035270136 +97,257.3916794657995,254.02867969902485,6.8307722895588965,2.3226285735907486 +98,257.2278305685032,254.5619736557002,6.809772888664755,2.8383983340571364 +99,257.16282933783424,254.477050995793,6.931960195707054,2.6611905102158038 +100,297.5612747805052,254.68621271243086,6.616832054817872,2.682409735201763 +101,298.3394946306158,254.9149917819558,7.4103859236839025,2.0032533635948298 +102,297.7037470787607,254.32926027245796,6.697390437340011,2.6035794639192695 +103,297.9018444784966,254.79769770872946,6.481459768864603,2.9116637606731044 +104,337.7041120241776,252.2287315192184,6.785308450450591,4.100479545727181 +105,338.5071288183876,253.47618492583723,6.235731773413765,5.665420262300457 +107,337.8271824583213,250.73973826046893,6.0034125806830785,3.931922093279878 +108,337.86197274862946,250.42655028770324,6.756971947757317,4.556599933768003 +113,275.3004995531795,306.83564646386503,4.779925536315024,4.424861919299598 +114,276.88576480308285,311.35434787217997,5.549501601726021,6.526755225085992 +115,277.14029465508577,309.65039091667654,4.580940412764937,5.080639071791438 +116,277.4324777875824,310.4960617480911,4.471359740657681,4.32292480362113 +117,319.2852262928977,311.077818303166,5.058071424215753,5.709272247895537 +118,319.8591509274496,310.989524065149,5.676606774774989,7.467429803565788 +119,319.02916641933683,312.90617379038326,5.750237766169274,5.40025366381934 +120,319.6131328938472,310.5522979637107,5.5022885295904205,7.263578897387779 +121,365.2832995228827,314.5597006669066,8.460762409909734,4.458496704270642 +122,361.82211363523294,313.68568720200915,5.985773405781822,5.263777316141343 +123,361.4480761928614,313.0382171673784,5.736550096606568,5.653009750209729 +124,362.77676743108657,312.1993102338357,5.979547887317892,5.588195075901747 +125,444.73301900096925,313.7677536345598,6.27290398703566,4.75455241049808 +126,440.039105136866,316.4990582369399,2.717419411362314,5.5021381149114275 +127,440.1448707987162,316.91453325930746,3.591630687306421,5.692686701585921 +128,444.4735843873624,318.5837135172218,5.650865106238081,3.8098846947664695 +129,480.4945871932981,317.7789400812657,2.8473874205661946,3.2846798443123237 +130,480.34502455519726,313.1237155709503,2.8405711463483505,5.887133881466956 +131,479.84017942259044,319.58019508589905,2.5364142708665374,3.470339268830257 +132,480.860280231984,318.72555273736816,2.135649445640601,3.5691704658960353 +133,482.1126824365287,292.7236746644675,6.795795621748642,3.589777249851841 +134,60.57986058588791,298.3572263782008,2.0715574011265097,6.518875203291838 +135,60.46461499266122,295.5965103880334,2.4359457319030224,3.521159186195473 +136,59.50091999103519,298.34107118829087,2.338468862304903,3.0546922696738714 +137,101.38271621918946,296.483247325443,3.5173219751207268,4.497162712521202 +138,100.43332664554771,300.16356781590855,2.6915212734293545,4.145281353905138 +139,88.95536885340141,299.07746679015054,2.783698934533499,3.917152490131537 +140,100.29389089950519,299.8972675509202,2.566259282658186,4.137718806425782 +141,119.97612156854062,299.369658232651,2.8076039128455625,3.339917039106144 +142,119.21634890704448,298.4258068241335,3.1000278549881677,4.175736792274726 +143,112.26314328941838,302.0132035682278,4.497193147167675,4.627836503294436 +144,118.63154926153814,299.5090092566827,3.3112468547584886,2.82625813066952 +145,140.22829557703238,295.83589398019353,4.880610377957939,2.876734137897074 +146,143.96502880541922,295.45158153676647,4.250115873207735,3.0733240603225105 +147,140.66008917985863,295.75005128745903,4.893542903008491,3.138028915535486 +148,141.21893535376495,296.1533805219746,3.774408848238054,3.0467012666428333 +149,183.47872058961224,299.0180109809012,3.257615072049357,4.1723220562822725 +150,183.1202811035564,298.79425325159076,3.469002943022174,3.997120410978376 +151,183.2016789609457,298.4838438451825,3.1679502308294953,4.084970750698522 +152,183.56716590770395,298.3764936397965,3.3471833496481467,4.077681465171855 +153,190.41048704769,330.4978785855013,2.083041500838133,3.4668015126104454 +154,188.96675676778156,329.9036439013521,1.9931882571475936,3.508215161643373 +155,188.33490314035438,329.81417912235116,1.8728073653310773,3.0484929469157747 +156,188.31414516895805,330.23186734474723,1.8830058285338804,3.3131134887294613 +157,231.30258441852257,329.2869590111576,2.1015883812262706,2.7686520980654414 +158,635.9719402081547,323.45669801247647,3.890586665705017,3.4262788642164947 +159,231.58692741290457,329.78511421313885,2.073756648357063,3.6457128678010338 +160,251.94245026669623,329.3621392921355,3.4400207042718804,2.525297437969197 +161,275.38274900691636,330.6582764942376,2.7758194307457162,2.781269710685483 +162,288.16094061378243,329.96864420502334,1.7425792225683983,2.7891999383989616 +163,273.9343912983064,330.28517683915425,1.88697235808454,2.153903027764216 +164,277.40318080027276,331.32724722075693,2.51910988134524,2.2364789702215044 +165,294.8273106877241,330.7078842677868,2.0202421142551663,2.645341711239525 +166,317.03626643514605,330.57896380392424,1.9865816645763301,2.776754699862097 +167,314.93276908458336,330.67614347282944,2.6509184944650532,2.7861880759516926 +168,299.640483801822,330.68496013319924,2.1034251306897223,2.6995826605586095 +169,397.31504374955824,332.3446123671715,4.011960577043935,2.119261063102862 +170,396.5580357804531,331.5612694467712,2.1013176840578547,4.345997085530413 +171,397.49205012933754,332.4442253933989,4.083617010295474,2.083000027123604 +172,396.4373476151805,332.4498304809778,3.6443064475289324,1.9520773323350806 +173,172.71708638362486,155.60703919548823,3.073597315308788,4.401620808681049 +174,174.69066860790247,155.66811371703272,3.3201919365119563,4.524189384907778 +175,174.36012639095586,155.21688748228445,3.313966666920818,4.280738433967948 +176,174.27542002212184,155.33243945954135,3.4684361769046457,4.3256192119148285 +177,211.35953547851577,157.84363965463723,3.719577632132569,4.52395842333967 +178,215.49817946473246,157.8061035073585,3.420835243071113,5.204301731036066 +179,211.58080964064885,157.9196266744007,3.750774395208928,4.781345943827068 +180,212.21010780634873,157.82655078622685,3.0477176203472505,5.171003834767582 +181,261.951692200774,158.03145626439886,3.3820588588480125,4.517024497962329 +182,258.6077504340104,157.3952123759144,3.610545283020404,5.537995823967975 +183,261.9931127261629,156.844374467896,3.3582923289081412,4.203836335498702 +184,261.97037263466234,158.27263012263947,3.4440759214867183,3.5700855150119994 +185,303.22094845720875,155.75474871290248,3.4728086741188746,4.537460217001407 +186,281.81947814044815,157.07330827651708,2.3587900891205402,7.458771102609963 +187,296.79672730554864,156.66963976209618,2.4956604990337636,7.422350136504288 +188,300.202613978401,156.83041886564462,3.6244136435867715,2.652614592092425 +189,383.13489230058434,158.29028886500078,3.9437889097096543,4.109817373692409 +190,385.65899984883004,157.07389261777607,3.7243534642349445,3.3291912053378807 +191,385.5898403232217,158.93279796052937,3.5586432492433517,4.719422333593461 +192,383.2113575049479,157.78585537067738,3.864821842971764,4.094143758353614 diff --git a/img_rec_module/meas/convergence_v1.csv b/img_rec_module/meas/convergence_v1.csv new file mode 100644 index 0000000..418d98a --- /dev/null +++ b/img_rec_module/meas/convergence_v1.csv @@ -0,0 +1,373 @@ +Image Number,Center X,Center Y,StdDev Horizontal,Std Dev Vertical +0 +59,93.83385757004997,219.40402585566392 +60,95.68692886974831,217.86446645631813 +61,95.27930768267886,218.4321212539979 +62,179.68821344888678,221.21713400884485 +63,180.64677254143638,221.7765304937586 +64,179.86073442223173,223.68541859670074 +65,267.0750705461852,204.74717443096984 +66,267.19879488924516,209.60901887734772 +67,266.1798697712201,208.51040145394091 +73,274.3400431870006,204.75610310411912 +74,273.44321864391185,205.81069417739437 +75,273.15099171429256,205.61817173382607 +77,353.2630018061804,204.6061088758629 +78,353.8852531441488,203.30592180203516 +79,352.21840596322596,204.15679894425952 +80,312.34313113441607,204.52530436142615 +81,313.1160349693985,201.4084182788836 +82,312.11840038067925,201.00669797880116 +83,312.29317276741347,200.45780062295867 +84,132.42237239805132,254.29214663519284 +85,131.29521858798734,255.4865958538821 +86,135.9988356956537,254.77748611685175 +87,130.98094102950247,254.42187606024922 +88,174.56636927613675,254.4831815599854 +89,173.67935580024877,254.09783447631526 +90,173.36920502447623,252.290452181076 +91,175.2895186608897,257.2751667704358 +92,215.07500705655937,253.80949363235624 +93,216.94462220467622,255.47756358425315 +94,217.3834915918711,256.4745644877478 +95,219.6648004345676,255.57239348461326 +96,257.50957542067664,254.1259284055811 +97,257.570545197815,253.88751117668164 +98,257.6089813372307,253.78662089019835 +99,257.6936671647974,254.2498517060511 +100,298.2952436151055,254.76909617478606 +101,298.1169393001307,255.21794911950758 +102,298.3189654536773,255.25096983760508 +103,298.4415890038736,254.35763625124292 +104,337.66969489877954,251.71635156144524 +105,338.1116560201459,251.7179090471175 +107,337.93979130669914,251.84264636476274 +108,338.18833275957206,250.67508565210196 +113,274.2817559120019,308.9374117445766 +114,275.7421347767481,310.2555996702759 +115,276.0461325201841,310.02072804280994 +116,276.2417374542582,310.24048782871637 +117,319.6559290654899,310.99105624588617 +118,319.6313092726346,312.1826263203713 +119,319.46776160473627,311.841371820779 +120,319.76654338764155,311.98447027104925 +121,360.82585188540037,313.3258908241004 +122,360.64739266264627,312.8307783296112 +123,360.689270210389,312.2626467099784 +124,360.8335382258014,312.5428875466125 +125,442.1542117060401,317.1277309025985 +126,441.42140737582423,315.78584607818385 +127,441.5300773440553,315.90717126090226 +128,441.95769286933466,316.8407357397122 +129,481.35090878368925,317.4272946632326 +130,481.4725819590857,316.6159681822135 +131,481.1535576706723,316.8819465108059 +132,482.21933609621834,316.90676933858305 +133,59.55768321914789,300.29871844382603 +134,61.376816545951996,298.3523691730104 +135,60.60960139542109,300.5877018018443 +136,59.19985355062283,300.1851062687214 +137,102.6280068014727,297.40383468175656 +138,102.40955557323258,298.7865911290351 +139,100.57013333623348,296.8202762296189 +140,102.67850653460079,298.5730025774653 +141,120.23221696171454,300.1898879495705 +142,118.10535832779757,301.85912326532906 +143,118.16700474619614,302.0417496311767 +144,118.19187121087131,302.5378510894045 +145,143.380762851227,297.65106023170455 +146,142.46748228973178,297.3647432540817 +147,143.2239805848247,297.5672414624104 +148,140.51718892104998,297.9845023911149 +149,182.6593569656309,298.1418468359333 +150,182.64828488417706,297.92582445480707 +151,182.92797391602642,297.87455852433123 +152,183.0029286817877,297.8637465373881 +153,186.1728851830908,329.8083307385874 +154,186.5492243440529,329.1491955430002 +155,186.0292302003802,329.23752125561214 +156,186.05706501583137,329.3191466220413 +157,233.36795685970054,328.463961880729 +158,232.82586842848798,327.60883484043825 +159,229.71350413783279,328.3780985513343 +160,232.72525153041173,327.7700361791668 +161,273.76316751955034,329.73823826493043 +162,275.7575781134558,329.9125721193857 +163,273.60940070127293,330.0025820738042 +164,273.7244999819209,330.09757535831045 +165,313.3973669095876,330.59163642669836 +166,313.23094160288184,330.71155384663837 +167,313.2083786255443,330.77428522126553 +168,313.36106959216625,330.6523370232485 +169,396.3640143494862,332.05477157898144 +170,395.617460222669,331.85554030819173 +171,396.3911361968549,332.1303447002533 +172,395.89256887798285,332.16822339411516 +173,176.02029170516317,153.71245910000232 +174,176.10545306203875,155.20318481126037 +175,176.03197440143745,154.95241321278883 +176,175.6846804297304,154.63359606135103 +177,219.46327960613064,157.23609785750858 +178,221.0564853241154,157.3435472260885 +179,219.62129396536662,157.2666553285107 +180,219.69587995502016,157.1490063640601 +181,263.23636033723557,157.46707082247306 +182,261.3833848255912,157.14497162705263 +183,263.2875985178052,157.05504332147794 +184,263.16270089611913,157.68858593709763 +185,304.0771964580808,156.36708101762838 +186,303.2325028543831,156.57995759281437 +187,303.42630311491723,156.4924674158584 +188,304.6158660912609,156.4818813819881 +189,385.45560134261797,158.37035395252553 +190,385.8286612719259,156.9884186905783 +191,386.1864174896063,157.19189241238993 +192,385.6347971660166,158.1411858434322 +1 +59,93.1287423931208,218.29700908810787 +60,94.70512938803542,212.6540109552706 +61,90.1361278577332,213.33121631876608 +62,163.05397573990066,223.03302231371174 +63,178.56039861950646,222.19098474984543 +64,178.37920648184422,223.51557294327878 +65,255.80438353417117,203.04815455047097 +66,262.478672605179,208.85138164100843 +67,263.60616955216886,207.2183121488101 +73,272.29022155441146,203.26015396542505 +74,271.46793735704193,204.00075736023095 +75,271.0412882240347,203.67673019265595 +77,350.53069989533947,205.1215453780687 +78,351.5335450988067,203.6132402057685 +79,350.54080463471854,202.80860415043412 +80,310.84312359894454,203.07084060099984 +81,309.4303871248667,198.8260778916456 +82,312.8487475083582,197.88498609405823 +83,312.4494378330193,198.02482356912975 +84,129.73316120742015,252.31402870350382 +85,130.09936826716955,255.07600217340146 +86,136.48684968097632,256.98593054341063 +87,129.96018632025633,253.63904238622214 +88,180.12754728190527,256.91804818977533 +89,173.42291095269067,255.58833819764322 +90,173.0543226504001,252.5748838461415 +91,174.29585433427428,254.46270745029543 +92,216.78511969207446,254.5914187233686 +93,215.97344562124545,254.7054640425066 +94,219.24024367384476,255.41662872012847 +95,213.81498670140752,252.60321047848737 +96,257.3830982530756,252.6691612485834 +97,256.07878148245777,252.5850508469038 +98,256.6563709830754,252.14302077100646 +99,257.10274737541874,252.44669038983187 +100,297.3527413648711,254.3197859755712 +101,297.36935919598676,254.31625883281748 +102,297.45043676182286,253.29006124829388 +103,297.15639353267426,254.26565823155238 +104,337.0838455883894,250.64743017278894 +105,338.2943046084806,250.9606925384406 +107,338.46927119138405,251.82861699933284 +108,337.6321115297869,249.87042147419172 +113,273.20050531167254,309.1760573916311 +114,275.593658985165,308.5727448984995 +115,276.45985797306344,307.75120186662025 +116,276.6589541465393,307.7328403118153 +117,323.8680795155452,311.25555593462394 +118,323.990822160368,310.23497244583933 +119,324.4759468599942,310.5137190042532 +120,325.7385894442358,310.39579583995135 +121,361.82046220765505,312.6906221126212 +122,360.25109899783934,312.73975566628565 +123,361.13964194906663,312.4482596768938 +124,360.8021695665512,312.55731463103996 +125,443.60378722604213,316.81523544669056 +126,462.74164751366203,314.6397925160877 +127,284.4684422338389,315.96181914108945 +128,451.0537747662026,315.05034330850094 +129,486.2262311408019,318.917422588962 +130,484.203371665194,317.155262043757 +131,493.1775485408943,316.3518621311899 +132,483.79815450187516,313.87456269013853 +133,58.415796919717515,296.3367806354237 +134,59.66992690532717,295.46552315023496 +135,58.30852857429605,301.14443002474417 +136,57.19875149216512,296.2038703275876 +137,101.88869112962361,295.36699152796956 +138,97.74223572831934,296.64159635228486 +139,95.13971714462463,297.63279866894925 +140,100.97448449522825,296.37143206657936 +141,119.6488680328135,295.99857882673734 +142,116.04630564586442,300.9428981940468 +143,115.93833802312685,301.4015147621542 +144,117.66427038686425,301.67621994166734 +145,143.61862339021508,296.87569921241607 +146,143.84226240395634,296.5995702000957 +147,143.41726284468888,296.4604242772443 +148,139.90710854861246,297.05847391439454 +149,177.97012292111646,297.29360417935067 +150,179.09943783225685,297.22176671479934 +151,178.4595029850307,297.07969710485736 +152,178.9990807254096,297.58186299960556 +153,187.06432524491635,327.5110792134713 +154,187.40611165319353,327.24266469486685 +155,187.48202253723917,328.1910452260973 +156,187.4554203440108,326.77537509295496 +157,230.1275716483488,327.66375493177526 +158,230.19455285047118,329.6573791501422 +159,236.39481488323716,328.4457905246168 +160,230.1984260911562,328.23405030487964 +161,272.1545894887068,329.32912181766994 +162,272.8983988300567,328.70387641284987 +163,271.6162444327857,329.4696874435773 +164,271.6290916788945,328.8920615225914 +165,313.03716740034986,330.7975522275865 +166,312.7612082311074,331.01658878813123 +167,312.555857804164,330.94886104868783 +168,312.99233681057194,330.7594147506374 +169,395.6599712440442,331.38000769767353 +170,395.7269407162828,332.3551932767835 +171,395.64772093777225,331.19728501985406 +172,394.5822232990254,331.28589367585266 +173,172.19300877613125,153.8677984100333 +174,174.43739755929997,152.4534316026212 +175,174.29318678572136,152.18270882980445 +176,174.37774565459176,153.9168218422937 +177,218.8977614990739,156.58401687998017 +178,218.82234457362887,155.93775870476483 +179,218.14869261453913,156.17880976796908 +180,219.6136087965169,156.013833915525 +181,260.39420520785944,156.89107932316213 +182,260.75752017274766,156.5286129544145 +183,260.0769741828374,156.73605149236164 +184,260.3205919730126,156.89282130924727 +185,302.8007745851293,155.22452212795463 +186,301.70658980492703,155.39202732491273 +187,301.9655960101498,155.27173302476598 +188,307.3464400351471,155.7530563647103 +189,385.16837677047874,156.43907420157797 +190,383.77693943350675,155.96991177533516 +191,384.2249550976313,157.41263864645526 +192,385.2223566829572,156.31521854739066 +2 +59,94.17681256320567,218.7493975260511 +60,95.60291842116452,220.23420259378253 +61,95.02957510532019,220.4523644522619 +62,177.79543145664374,219.57549575966527 +63,179.18294098400213,220.75147009194285 +64,178.6879893390563,223.61664229341952 +65,263.02108805781836,206.8238570753259 +66,265.3281568315068,210.99878283626376 +67,264.9755279946045,209.25693017899349 +73,274.91234547074936,204.52721235111983 +74,273.0873606007509,206.72185414526035 +75,272.91870930424335,206.4183338799366 +77,352.6038013638071,203.61911600747297 +78,353.00800784867783,202.31796836001985 +79,351.746134852955,203.05786731461058 +80,311.08741311854095,205.08798593428077 +81,310.4676353064527,202.3951467032501 +82,311.07935156741206,200.8328753632899 +83,311.4698975682484,201.29198895046432 +84,131.85526420446874,252.0193765605421 +85,130.09901692321196,252.49815518747823 +86,128.98108803670195,254.22164770572394 +87,129.58841891167637,253.33496272524005 +88,174.3431769252481,257.67973667788516 +89,173.08617175672723,252.22705318297471 +90,173.16612346262423,251.83252079351362 +91,175.31435856398238,256.47051595889315 +92,214.0019796882893,255.64524660837301 +93,213.6417614987187,254.76260041862824 +94,212.59841286272757,256.77538398368796 +95,214.6340156872122,257.02599392382655 +96,257.12202196483105,254.71576094200717 +97,257.3916794657995,254.02867969902485 +98,257.2278305685032,254.5619736557002 +99,257.16282933783424,254.477050995793 +100,297.5612747805052,254.68621271243086 +101,298.3394946306158,254.9149917819558 +102,297.7037470787607,254.32926027245796 +103,297.9018444784966,254.79769770872946 +104,337.7041120241776,252.2287315192184 +105,338.43934115988196,252.2496982308047 +107,337.8271824583213,250.73973826046893 +108,337.86197274862946,250.42655028770324 +113,275.3004995531795,306.83564646386503 +114,276.88576480308285,311.35434787217997 +115,277.14029465508577,309.65039091667654 +116,277.4324777875824,310.4960617480911 +117,319.3288258962187,311.6702225501444 +118,319.8591509274496,310.989524065149 +119,318.99005649592243,312.4173775749036 +120,319.6131328938472,310.5522979637107 +121,365.29517640566365,314.6454813265486 +122,361.82211363523294,313.68568720200915 +123,361.4480761928614,313.0382171673784 +124,362.77676743108657,312.1993102338357 +125,444.8280999329621,315.2874742212303 +126,440.039105136866,316.4990582369399 +127,440.1448707987162,316.91453325930746 +128,444.4735843873624,318.5837135172218 +129,480.4945871932981,317.7789400812657 +130,480.34502455519726,313.1237155709503 +131,479.79765238044547,317.8026694666446 +132,480.81626241860704,316.98435781490645 +133,482.1126824365287,292.7236746644675 +134,60.57986058588791,298.3572263782008 +135,60.26789543218528,299.7821310194954 +136,59.50091999103519,298.34107118829087 +137,101.38271621918946,296.483247325443 +138,100.43332664554771,300.16356781590855 +139,88.95536885340141,299.07746679015054 +140,100.29389089950519,299.8972675509202 +141,119.96308784890563,299.8312652747876 +142,119.21634890704448,298.4258068241335 +143,112.26314328941838,302.0132035682278 +144,118.63154926153814,299.5090092566827 +145,140.22829557703238,295.83589398019353 +146,143.96502880541922,295.45158153676647 +147,140.66008917985863,295.75005128745903 +148,141.21893535376495,296.1533805219746 +149,183.47872058961224,299.0180109809012 +150,183.1202811035564,298.79425325159076 +151,183.2016789609457,298.4838438451825 +152,183.56716590770395,298.3764936397965 +153,190.41048704769,330.4978785855013 +154,188.96675676778156,329.9036439013521 +155,188.33490314035438,329.81417912235116 +156,188.31414516895805,330.23186734474723 +157,231.30258441852257,329.2869590111576 +158,635.9719402081547,323.45669801247647 +159,231.58692741290457,329.78511421313885 +160,251.94245026669623,329.3621392921355 +161,275.38274900691636,330.6582764942376 +162,288.16094061378243,329.96864420502334 +163,273.9343912983064,330.28517683915425 +164,277.40318080027276,331.32724722075693 +165,294.8273106877241,330.7078842677868 +166,317.03626643514605,330.57896380392424 +167,314.93276908458336,330.67614347282944 +168,299.640483801822,330.68496013319924 +169,397.31504374955824,332.3446123671715 +170,396.5580357804531,331.5612694467712 +171,397.49205012933754,332.4442253933989 +172,396.4373476151805,332.4498304809778 +173,172.71708638362486,155.60703919548823 +174,174.69066860790247,155.66811371703272 +175,174.36012639095586,155.21688748228445 +176,174.27542002212184,155.33243945954135 +177,211.35953547851577,157.84363965463723 +178,215.49817946473246,157.8061035073585 +179,211.58080964064885,157.9196266744007 +180,212.21010780634873,157.82655078622685 +181,261.951692200774,158.03145626439886 +182,258.53106462200054,156.41654274449266 +183,261.9931127261629,156.844374467896 +184,261.97037263466234,158.27263012263947 +185,303.2394620820782,156.27343358354165 +186,281.81947814044815,157.07330827651708 +187,296.79672730554864,156.66963976209618 +188,300.202613978401,156.83041886564462 +189,383.13489230058434,158.29028886500078 +190,385.65899984883004,157.07389261777607 +191,385.5178115620514,157.22774057918932 +192,383.2113575049479,157.78585537067738 diff --git a/img_rec_module/meas/truth.txt b/img_rec_module/meas/truth.txt new file mode 100644 index 0000000..dcf364f --- /dev/null +++ b/img_rec_module/meas/truth.txt @@ -0,0 +1,32 @@ +new_test +img_4 237, 325 + +calib +img_29 140, 203 + +testpic +img_1 385, 130 E: (2, 1) +img_2 385, 130 E: (2, 1) +img_3 385, 130 E: (2, 1) +img_4 -2, -2 175, 113 E: (4, 7) (DATA) +img_5 176, 52 E: (1, 3) +img_6 174, -1 E: (1, 0) +img_7 158, -1 E: (0, 0) +img_8 -2, -2 159, -1 E: (F, 0) (DATA) +img_9 242, 212 E: (0, 2) +img_10 278, 215 E: (1, 3) +img_11 -2, -2 325, 218 E: (1, 4) (DATA) +img_12 143, 215 E: (0, 1) +img_13 53, 219 E: (0, 4) +img_14 -1, 17 E: (0, 0) +img_15 138, 19 E: (0, 0) +img_16 355, 14 E: (1, 0) +img_17 288, -1 E: (1, 0) +img_18 369, 180 E: (1, 0) +img_19 357, 265 E: (0, 1) +img_20 225, 224 E: (3, 1) +img_21 41, 224 E: (0, 1) +img_22 -1, 59 E: (0, 3) +img_23 -2, -2 -1, -1 E: (0, T) (DATA) +img_24 -1, 160 E: (0, 1) +img_25 445, 166 E: (2, 4) diff --git a/img_rec_module/robust_reg/calib4/convergence.txt b/img_rec_module/robust_reg/calib4/convergence.txt new file mode 100644 index 0000000..e69de29 diff --git a/img_rec_module/sig_proc.py b/img_rec_module/sig_proc.py new file mode 100644 index 0000000..c0dcf47 --- /dev/null +++ b/img_rec_module/sig_proc.py @@ -0,0 +1,1211 @@ +import cv2 +import numpy as np +import csv +from scipy.optimize import curve_fit +from scipy.optimize import least_squares +import heapq +from decimal import Decimal +from math import atan, sqrt, tan, radians, acos, asin, degrees, sin, cos + +""" =================================== +========== ANALYTIC GEOMETRY ========== +======================================= """ + + +class Line: + inf = float('inf') + + def __init__(self, a=inf, b=inf, p1=None, p2=None, data=None): + if p1 and p2: + self.point(p1, p2) + elif data: + self.reg(data) + else: + self.a = a + self.b = b + + def reg(self, data): + D = np.array([[d[0], 1] for d in data]) + y = np.array([d[1] for d in data]) + self.a, self.b = leastSquares(D, y) + + def point(self, p1, p2): + self.a = 1 + + @staticmethod + def intersect(l1, l2): + x = (l2.b - l1.b) / (l1.a - l2.a) + y = l1.a * x + l1.b + return x, y + + +class HoughLine: + def __init__(self, theta=0, rho=0, x=None, data=None, new=True, r_bound=np.inf, loss='soft_l1'): + if data is not None and x is not None: + self.x = x + self.data = data + self.r_bound = r_bound + self.loss = loss + if new: + self.reg = self.reg_new + else: + self.reg = self.reg_old + self.reg(x, data) + else: + self._r = rho + self._t = theta + self._s = sin(theta) + self._c = cos(theta) + + def reg_old(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + + x1, x2 = np.mean(x[:int(len(x) / 2)]), np.mean(x[int(len(x) / 2):]) + y1, y2 = np.mean(data[:int(len(data) / 2)]), np.mean(data[int(len(data) / 2):]) + theta0 = theta_pred(x1, y1, x2, y2) + p0 = [theta0, np.mean(x) * np.cos(theta0) + np.mean(data) * np.sin(theta0)] + """ + x1, x2 = x[0], x[-1] + y1, y2 = data[0], data[-1] + theta0 = theta_pred(x1, y1, x2, y2) + # print(degrees(theta0)) + p0 = [theta0, x1 * cos(theta0) + y1 * sin(theta0)]""" + pm, vm = curve_fit(hough_line, x, data, p0=p0) + # data_pred = hough_line(x, *pm) + # print('PRED', data_pred) + # res = data_pred - data + # print("RES", res) + # stderr = np.linalg.norm(res, 2) + # print("ERR", stderr) + # rankerr = res / stderr + # print("Z", rankerr) + if pm[1] < 0: + pm[1] = -pm[1] + pm[0] -= HC + # pm[0] = 2 * np.pi + angle = normalize_angle(pm[0]) + self._t = angle + self._r = pm[1] + self._s = sin(angle) + self._c = cos(angle) + + def reg_new(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + x1, x2 = np.mean(x[:int(len(x) / 2)]), np.mean(x[int(len(x) / 2):]) + y1, y2 = np.mean(data[:int(len(data) / 2)]), np.mean(data[int(len(data) / 2):]) + theta0 = theta_pred(x1, y1, x2, y2) + p0 = [theta0, np.mean(x) * np.cos(theta0) + np.mean(data) * np.sin(theta0)] + res = least_squares(self.get_err, p0, loss=self.loss, f_scale=3, args=(x, data)) + # data_pred = hough_line(x, *pm) + # print('PRED', data_pred) + # res = data_pred - data + # print("RES", res) + # stderr = np.linalg.norm(res, 2) + # print("ERR", stderr) + # rankerr = res / stderr + # print("Z", rankerr) + angle = normalize_angle(res.x[0]) + self._t = angle + self._r = res.x[1] + self._s = sin(angle) + self._c = cos(angle) + + def get_err(self, vars, xs, ys): + return xs * np.cos(vars[0]) + ys * np.sin(vars[0]) - vars[1] + + def fit_x(self, x): + # print(self._r, self._t) + return (self._r - x * self._c) / self._s if self._s != 0 else 'undef' + + def debias(self, thres=1.0): + """ @:returns tuple with a) zerr_before: regression error before debias + b) zerr_after: regression error after debias""" + x, y = self.x, self.data + zero_hat_before = x * self._c + y * self._s - self._r + #y_hat_before = self.fit_x(x) + zerr_before = np.square(zero_hat_before) + #yerr_before = np.square(y_hat_before - y) + conds = (zerr_before - np.mean(zerr_before)) / np.std(zerr_before) <= thres + new_x, new_y = x[conds], y[conds] + self.x, self.data = new_x, new_y + self.reg(new_x, new_y) + zero_hat_after = new_x * self._c + new_y * self._s - self._r + #y_hat_after = self.fit_x(new_x) + zerr_after = np.square(zero_hat_after) + #yerr_after = np.square(y_hat_after - new_y) + return zerr_before, zerr_after + + def point_gen(self): + x0 = self._c * self._r + y0 = self._s * self._r + x1 = int(x0 + 1000 * (-self._s)) + y1 = int(y0 + 1000 * (self._c)) + x2 = int(x0 - 1000 * (-self._s)) + y2 = int(y0 - 1000 * (self._c)) + return (x1, y1), (x2, y2) + + def __str__(self): + return 'hough line with cos:{0}, sin:{1}, rho:{2}, theta:{3}'.format(self._c, self._s, + self._r, degrees(self._t)) + + @staticmethod + def intersect(l1, l2): + if l1._s == 0 and l2._s == 0: + return float('inf'), float('inf') + if l1._s == 0: + return l1._r, l2.fit_x(l1._r) + elif l2._s == 0: + return l2._r, l1.fit_x(l2._r) + x = (l2._r / l2._s - l1._r / l1._s) / (l2._c / l2._s - l1._c / l1._s) + y = l1.fit_x(x) + return x, y + + +# QC: QUARTER_CYCLE, HC: HALF_CYCLE, TQC: THIRD_QUARTER_CYCLE, FC: FULL_CYCLE +QC = np.pi / 2 +HC = np.pi +TQC = 3 * np.pi / 2 +FC = 2 * np.pi + + +def angle_interp(s, c): + if c == 1.0: + return 0 + elif s == 1.0: + return np.pi / 2 + elif c == -1.0: + return np.pi + elif s == -1.0: + return np.pi * 3 / 2 + elif c < 0 < s: + return acos(c) + elif s < 0 and c < 0: + return 2 * np.pi - acos(c) + elif s < 0 < c: + return asin(s) + 2 * np.pi + else: + return asin(s) + + +def normalize_angle(angle): + res = angle - (angle // FC) * FC + return res + + + +def theta_pred(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + angle = sin_angle_from_points(dx, dy) + if dx * dy <= 0: + return np.pi / 2 - angle + else: + root = root_finding(x1, x2, y1, y2) + if root < 0: + return np.pi / 2 + angle + else: + return angle + 3 * np.pi / 2 + + +def sin_angle_from_points(dx, dy): + return asin(abs(dy) / sqrt(dx ** 2 + dy ** 2)) + + +def poly_curve(params, x_input): + # params contains the coefficients that multiply the polynomial terms, in degree of lowest degree to highest degree + degree = len(params) - 1 + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = x * 0 + + for k in range(0, degree + 1): + coeff = params[k] + y = y + list(map(lambda z: coeff * z ** k, x)) + return x, y + + +def gauss_2d(x, y, a, b1, c_s1, b2, c_s2): + return a * np.exp(- ((x - b1) ** 2 / (2 * c_s1) + (y - b2) ** 2) / (2 * c_s2)) + + +def gauss_hat(x, a, b, c_s): + return a * np.exp(- (x - b) ** 2 / (2 * c_s)) + + +def gaussian_curve(x_input, a, b, c_s): + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = a * np.exp(- (x - b) ** 2 / (2 * c_s)) + return x, y + + +def hough_line(x, theta, rho): + return (rho - x * np.cos(theta)) / np.sin(theta) + + +""" =================================== +========== MATRIX-ARRAY UTIL ========== +======================================= """ + + +class PseudoLL(list): + def push(self, obj): + self.append(obj) + + def __getitem__(self, item): + return super().__getitem__(len(self) - 1 - item) + + def __repr__(self): + rep = '[' + ls = len(self) + for i in range(ls): + if i > 0: + rep += ', ' + val = self[i] + rep += str(val) + rep += ']' + return rep + + +class FastDataMatrix2D: + # TODO: HANDLE THE CASE WHEN IT WRAPS 1D + + HOR = 1 + VER = 0 + + def __init__(self, data, ax, index): + self._data = data + self._ax = ax + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + self.itr = 0 + self.initialize() + + def segmentize(self, start, end): + assert 0 <= start < end <= self._data.shape[self._ax], \ + "start: {0}, end: {1}, ax: {2}, index: {3}".format(start, end, self._ax, self._index) + self.start = start + self.end = end + + def initialize(self): + self.segmentize(0, self._data.shape[self._ax]) + + def irange(self): + # index range of the fast matrix array + return self._data.shape[1 - self._ax] + + def set_axis(self, ax): + """USE copy when trying to switch axis and index""" + self._ax = ax + if self._index >= self.irange(): + raise IndexError("Old index {0} is too large for the new axis".format(self._index)) + self.initialize() + + def set_index(self, index): + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + + def extract_array(self): + """Optimize later for better performance""" + arr = self._data[self._index, self.start:self.end] if self._ax == FastDataMatrix2D.HOR \ + else self._data[self.start:self.end, self._index] + return np.array(arr) + + def copy(self, ax=None, index=None): + if ax is not None and index is not None: + return FastDataMatrix2D(self._data, ax, index) + else: + return FastDataMatrix2D(self._data, self._ax, self._index) + + def __iter__(self): + raise RuntimeError("You need the ITER method!") + + def __next__(self): + raise RuntimeError("You need the NEXT method!") + + def __getitem__(self, item): + return self._data[self._index, item + self.start] if self._ax == FastDataMatrix2D.HOR else self._data[item + self.start, self._index] + + def __setitem__(self, key, value): + if self._ax == FastDataMatrix2D.HOR: + self._data[self._index, key + self.start] = value + else: + self._data[key + self.start, self._index] = value + + def __len__(self): + return self.end - self.start + + +""" =================================== +=========== REGRESSION UTILS ========== +======================================= """ + + +# Generic Regression Tools 128-133 +def leastSquares(D, y): + return np.linalg.lstsq(D, y, rcond=None)[0] + + +def MSE(y, y_hat, N): + return np.linalg.norm(y - y_hat) ** 2 / N + + +def std_dev(data): + std_dev = 0 + len_data = len(data) + mean = sum(data) / len_data + for i in range(len_data): + std_dev += (data[i] - mean) ** 2 + return sqrt(std_dev / len_data) + + +def reg_pre_debias(ind, data): + sd = np.std(data) + miu = np.mean(data) + debiased_data = [] + debiased_ind = [] + for i in range(len(data)): + dev = abs((data[i] - miu) / sd) + if dev < 2: + debiased_data.append(data[i]) + debiased_ind.append(ind[i]) + return debiased_ind, debiased_data + + +# Polynomial Regression Tools 137-171 +def poly_data_matrix(input_data, degree): + # degree is the degree of the polynomial you plan to fit the data with + Data = np.zeros((len(input_data), degree + 1)) + + for k in range(0, degree + 1): + Data[:, k] = (list(map(lambda x: x ** k, input_data))) + + return Data + + +def poly_error(params, D_a, y_a): + '''degree=len(params)-1 + y=x_a*0 + + for k in range(0,degree+1): + coeff=params[k] + y=y+list(map(lambda z:coeff*z**k,x_a))''' + y = np.dot(D_a, params) + return np.linalg.norm(y - y_a) ** 2 + + +def improvedCost(x, y, x_test, y_test, start, end): + """Given a set of x and y points training points, + this function calculates polynomial approximations of varying + degrees from start to end. Then it returns the cost, with + the polynomial tested on test points of each degree in an array""" + c = [] + degrees = range(start, end) + ps = [] + for degree in degrees: + # YOUR CODE HERE + D = poly_data_matrix(x, degree) + p = leastSquares(D, y) + ps.append(p) + D_t = poly_data_matrix(x_test, degree) + y_hat = np.dot(D_t, p) + c.append(MSE(y_test, y_hat, len(x_test))) + return np.array(degrees), ps, np.array(c) + + +# Gaussian Regression Tools 184-210 +def gauss_data_matrix(data): + return np.array([[1, x ** 2, x, 1] for x in data]) + + +def gauss_reg(x, y, p0): + """Given a set of x and y training points, this function + calculates the gaussian approximation function""" + """skip_x = np.array([x[i] for i in range(len(y)) if y[i] != 0]) + y_prime = np.array([y[i] for i in range(len(y)) if y[i] != 0]) + logy = np.log(y_prime) + + sol = leastSquares(gauss_data_matrix(skip_x), logy) + alp, bet, gam, lam = sol + a = np.e ** alp + c_s = - 1 / (2 * bet) + b = gam * c_s + maxi, mini = max_min(y) + pred = gauss_hat(maxi, a, b, c_s) + real = y[maxi] + a = real / pred // 1000000000 * 10""" + # timeb = datetime.now() + param, vm = curve_fit(gauss_hat, x, y, p0=p0) + # timea = datetime.now() + # print(timea - timeb) + return param + + +def gauss_mat(shape, a, b1, c_s1, b2, c_s2): + mat = np.zeros(shape) + for r in range(mat.shape[0]): + for c in range(mat.shape[1]): + mat[r, c] = gauss_2d(c, r, a, b1, c_s1, b2, c_s2) + + return mat + + +# Hough Transform Regression Tools +def hough_data_matrix(x, y): + dim = len(x) + mat = np.full((dim, 3), -1.0) + for i in range(dim): + mat[i][0] = x[i] + mat[i][1] = y[i] + return mat + + +""" ======================================= +========= EDGE DETECTION UTILS ============ +=========================================== """ + + +def gather_all(imgr, sample_int=30, gk=9, ks=-1): + """ @:returns centers_v, centers_h, list of possible centers gathered by algorithm, represented as (row, col) + """ + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # Parameter Setting + nr = sample_int + nc = sample_int + # Gathering Data + centers_v = [] + centers_h = [] + while nr < dimr: + data_x = sobelx[nr, :] + am = gather_centers(data_x, img[nr, :], centers_v, 0, nr, gaussian_center) + nr += sample_int + while nc < dimc: + data_y = sobely[:, nc] + raw_y = img[:, nc] + am = gather_centers(data_y, img[:, nc], centers_h, 1, nc, gaussian_center) + nc += sample_int + return centers_v, centers_h + + +def gather_centers(grad, raw_data, reserve, ax, ax_n, center_method): + # Given grad and raw_data, insert the possible beam centers to reserves + max_grad, min_grad = get_maxi_mini(grad) + max_q, min_q, locs = bi_order_sort(max_grad, min_grad) + miu, sig = np.mean(raw_data), np.std(raw_data) + avant = lambda locs, i: locs[i - 1] if i - 1 >= 0 else None + apres = lambda locs, i: locs[i + 1] if i + 1 < len(locs) else None + i = 0 + peaked = False + while (i < 2 or peaked) and max_q and min_q: + if peaked: + top = min_q.pop() + av = avant(locs, top[1]) + if av in max_q and beam_bound(raw_data, miu, sig, av, top): + mid = center_method(grad, raw_data, av[0], top[0]) + reserve.append((ax_n, mid) if ax == 0 else (mid, ax_n)) + max_q.remove(av) + i += 1 + peaked = False + else: + max_top = max_q.pop() + min_top = min_q[0] + if beam_bound(raw_data, miu, sig, max_top, min_top): + # print("MaxMin: ", max_top, min_top) + mid = center_method(grad, raw_data, max_top[0], min_top[0]) + reserve.append((ax_n, mid) if ax == 0 else (mid, ax_n)) + min_q.remove(min_top) + i += 1 + else: + peaked = True + ap = apres(locs, max_top[1]) + # QUICK FIX HERE, THINK MORE + if ap in min_q and beam_bound(raw_data, miu, sig, max_top, ap): + # print("Max_apres: ", max_top, ap) + mid = center_method(grad, raw_data, max_top[0], ap[0]) + reserve.append((ax_n, mid) if ax == 0 else (mid, ax_n)) + min_q.remove(ap) + i += 1 + return i + + +def sup_tout(max_q, min_q, d, guess): + if guess == 0: + prem, deux = max_q, min_q + else: + prem, deux = min_q, max_q + if d in prem: + prem.remove(d) + elif d in prem: + deux.remove(d) + else: + raise RuntimeError("Tried to remove already removed term! {0}, {1}".format(d, guess)) + + +def get_maxi_mini(data, ceil=3): + # Given data, pluck the maxis and minis and store them in minpq and maxpq respectively + max_grad = [] + min_grad = [] + nat_select = lambda a, b: a if a[0] >= b[0] else b + maxer = lambda d: len(max_grad) < ceil or d > max_grad[0][0] + miner = lambda d: len(min_grad) < ceil or d > min_grad[0][0] + active_max, active_min = None, None + + for i, d in enumerate(data): + if not active_max: + if maxer(d): + active_max = (d, i) + else: + curr = (d, i) + active_max = nat_select(curr, active_max) + if active_max and (check_crossing(data, i) or i == len(data) - 1): + heapq.heappush(max_grad, active_max) + if len(max_grad) > ceil: + heapq.heappop(max_grad) + active_max = None + + if not active_min: + if miner(-d): + active_min = (-d, i) + else: + curr = (-d, i) + active_min = nat_select(curr, active_min) + if active_min and (check_crossing(data, i) or i == len(data) - 1): + heapq.heappush(min_grad, active_min) + if len(min_grad) > ceil: + heapq.heappop(min_grad) + active_min = None + + return max_grad, min_grad + + +def bi_order_sort(max_grad, min_grad): + # Takes in a max_grad and min_grad (heapq), returns a locational ordered array and a magnitude queue. + locs = [] + max_q, min_q = PseudoLL(), PseudoLL() + while len(max_grad) and len(min_grad): + mat = heapq.heappop(max_grad) + mit = heapq.heappop(min_grad) + maxt, mint = [mat[1], None], [mit[1], None] + locs.append(maxt) + locs.append(mint) + max_q.push(maxt) + min_q.push(mint) + locs.sort(key=lambda pair: pair[0]) + for i in range(len(locs)): + locs[i][1] = i + return max_q, min_q, locs + + +def beam_bound(raw, miu, sig, a1, a2, thres=2): + # given raw data, determine if a1, a2 are beam bound entries, where a1, a2 are tuples [index, *(loc)] + return a1 and a2 and a2[1] == a1[1] + 1 and (raw[(a1[0] + a2[0]) // 2] - miu) / sig >= thres + + +# Generic Helper +def max_min(data): + # Returns the maximum and minimum for the data + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + return max_ind, min_ind + + +def edge_max_min(data): + # Returns a *safe* edge maxi, mini for the data + # TODO: OPTIMIZE THE WIDTH AND VALUE THRESHOLD + width_thres = 90 + value_thres = 20 + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + maxi, mini = max_ind, min_ind + assert data[maxi] >= value_thres and mini - maxi <= width_thres and maxi < mini + return maxi, mini + + +def min_max(data, max, min): + """ Converts the data to min max space. """ + g_diff = max - min + return [(d - min) / g_diff for d in data] + + +def root_finding(x1, x2, y1, y2): + """Given two points on a line, finds its zero crossing root.""" + return - y1 * (x2 - x1) / (y2 - y1) + x1 + + +def check_crossing(data, i): + return i + 1 < len(data) and check_cross(data[i], data[i+1]) + + +def check_cross(a, b): + # Checks whether two points are of opposite signs + return a * b < 0 + + +def round_up(num): + down = int(num) + if num - down > 0: + return num + 1 + else: + return num + + +def smart_interval(start, end, data): + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + return start, end + + +def edge_preprocess(data, padding): + maxi, mini = edge_max_min(data) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end + + +# ZERO CROSSING (PEAK FINDING) +def zero_crossing(data): + # Yields the center with zero-crossing method + maxi, mini = max_min(data) + cross = -1 + cross_count = 0 + for j in range(maxi, mini): + y1 = data[j] + x2 = j + 1 + y2 = data[x2] + if check_cross(y1, y2): + cross = root_finding(j, x2, y1, y2) # change to function later + cross_count += 1 + return -1 if cross_count > 1 else cross + + +# AVERAGE METHOD FOR EDGE CENTER FINDING +def edge_converge_base(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + else: + return (maxi + mini) / 2 + + +# PSEUDO EDGE (closest noise gradient change) CENTER FINDING +def edge_converge_extreme(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + emax = -1 + emin = -1 + maxflag = True + minflag = True + cmax = maxi + cmin = mini + while cmax > 0 and cmin < len(data) - 1 and (maxflag or minflag): + max2 = cmax - 1 + maxy1, maxy2 = data[cmax], data[max2] + min2 = cmin + 1 + miny1, miny2 = data[cmin], data[min2] + if check_cross(maxy1, maxy2) and maxflag: + emax = root_finding(cmax, max2, maxy1, maxy2) + maxflag = False + if check_cross(miny1, miny2) and minflag: + emin = root_finding(cmin, min2, miny1, miny2) + minflag = False + if maxflag: + cmax -= 1 + if minflag: + cmin += 1 + return -1 if (emax == -1 or emin == -1) else (emax + emin) / 2 + + +def extract_extrema(data): + len_data = len(data) + mean = sum(data) / len_data + std_dev = 0 + for x in data: + std_dev += (x - mean) ** 2 + std_dev = sqrt(std_dev / len_data) + signifmax = [] + signifmin = [] + coeff = 3 + for i, x in enumerate(data): + diff = (x - mean) / std_dev + if diff >= coeff: + signifmax.append(i) + elif diff <= -coeff: + signifmin.append(i) + return signifmax, signifmin + + +# CENTROID METHOD FOR EDGE CENTER FINDING +def edge_centroid(data, img_data, padding=20): + # With Gaussian Blur might achieve the best performance + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + isums = 0 + total = 0 + for i in range(start, end): + isums += img_data[i] * i + total += img_data[i] + return isums / total if total else -1 + + +def centroid_seg(data, start, end): + """ Given a segment (start, end) of the data, + find the centroid. """ + isums = 0 + total = 0 + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + for i in range(start, end): + isums += data[i] * i + total += data[i] + return isums / total if total else -1 + + +# POLYNOMIAL FITTING +def poly_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + #y = np.array(img_data[start:end]) + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + curve_x, curve_y = poly_curve(param, x) + center_id = np.argmax(curve_y) + return curve_x[center_id] + + +def poly_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + 1 + start, end = smart_interval(start, end, data) + if start > end: + try: + print(maxi, mini, img_data._ax, start, end) + except: + print("else", maxi, mini, start, end) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + return param, x + + +DEGREES = {} + + +def degree_register(elem): + if elem in DEGREES: + DEGREES[elem] += 1 + else: + DEGREES[elem] = 1 + + +def gaussian_center(data, img_data, maxi, mini, padding=20): + #padding = (mini - maxi) // 2 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +# GAUSSIAN FITTING +def gaussian_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + try: + maxi, mini = edge_max_min(data) + print((mini - maxi) // 2) + except AssertionError: + return -1 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end-start) + for i in range(start, end): + idata[i-start] = img_data[i] + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +def gaussian_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 # TODO: CONSOLIDATE THIS VALUE + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + start, end = smart_interval(start, end, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i-start] = img_data[i] + return gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]), x + + +"""====================================== +======== IMAGE PROCESSING UTIL ========== +========================================= """ + + +def image_diff(img1, img2): + i1 = img1.astype(np.int16) + i2 = img2.astype(np.int16) + res = i1 - i2 + dst = np.zeros_like(res, dtype=np.int8) + return cv2.normalize(res, dst=dst, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=8) + + +def gauss_bg_deduce(x, img_data): + # TODO: OPTIMIZE PERFORMANCE + idata = img_data.extract_array() + p0 = [1, len(img_data) / 2, std_dev(idata)] + a, b, c_s = gauss_reg(x, idata, p0=p0) + rem_gauss = gauss_hat(x, a, b, c_s) + new_y = idata - rem_gauss + return x, rem_gauss, new_y + + +def significance_test(data, val): + """Outputs whether the maximum or minimum value is a significant value.""" + return val in extract_extrema(data)[0] or val in extract_extrema(data)[1] + + +def edge_detect_expr(edges, original): + """ + TODO: 1. SIMPLE Approach: pairwise mask over original image, then compute total + 2. Traverse the image to mark the image. + """ + se = 0 + row_sum = 0 + col_sum = 0 + tot_sum = 0 + for i in range(edges.shape[0]): + for j in range(edges.shape[1]): + if edges[i][j] > 0: + row_sum += i * original[i][j] + col_sum += j * original[i][j] + tot_sum += original[i][j] + se += 1 + print(se) + if tot_sum != 0: + print(row_sum / tot_sum) + print(col_sum / tot_sum) + + +def hori(img, i, j, d): + dest = j + d + if dest < 0 or dest >= img.shape[1]: + return img.item(i, j) + return img.item(i, dest) + + +def verti(img, i, j, d): + dest = i + d + if dest < 0 or dest >= img.shape[0]: + return img.item(i, j) + return img.item(dest, j) + + +def test_blur_then_nr(iname): + imgs = iname + numIMG = 5 + imgr = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + target = cv2.GaussianBlur(target, (9, 9), 0) + if i == 1: + imgr = np.uint16(target) + else: + imgr = imgr + target + return imgr / numIMG + + +def get_center_val(img): + return img.item(img.shape[0] // 2, img.shape[1] // 2) + + +def test_noise_reduce(iname, numIMG=5): + imgs = iname + imgr = None + original = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + if target is None: + raise AttributeError("File {0} not found".format(iname)) + if i == 1: + imgr = np.uint16(target) + original = target + else: + imgr = imgr + target + return imgr / numIMG, original + + +def img_add(dest, src): + """Destructive!""" + row, col = dest.shape + for i in range(row): + for j in range(col): + dest[i][j] += src[i][j] + + +FM = FastDataMatrix2D + + +def folder_to_imgs(img_name_scheme, num_sample): + """This function takes img files and return cv imgs""" + return [cv2.imread(img_name_scheme.format(i)) for i in range(1, num_sample + 1)] + + +def center_detect_hough(img): + centers_v, centers_h = gather_all(img) + centpointsv = np.zeros_like(img, dtype=np.uint8) + centpointsh = np.zeros_like(img, dtype=np.uint8) + #print(centers_v+centers_h) + for r, c in centers_v: + try: + centpointsv[int(r)][int(c)] = 255 + except: + continue + for r, c in centers_h: + try: + centpointsh[int(r)][int(c)] = 255 + except: + continue + linesv = cv2.HoughLines(centpointsv, 0.5, 0.005, 1) + linesh = cv2.HoughLines(centpointsh, 0.5, 0.005, 1) + all_lines = [] + try: + for rho, theta in linesv[0]: + #print(rho, theta) + all_lines.append(HoughLine(theta, rho)) + except: + print(linesv) + for rho, theta in linesh[0]: + all_lines.append(HoughLine(theta, rho)) + ct = HoughLine.intersect(all_lines[0], all_lines[-1]) + return ct + + +def center_detect(ins, sample_int=30, gk=9, ks=-1, l='soft_l1'): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + ambi, laser = cv2.imread(ins.format(0), 0), cv2.imread(ins.format(1), 0) + res = image_diff(laser, ambi) + centers_v, centers_h = gather_all(res, sample_int, gk, ks) + centers_v, centers_h = np.array(centers_v), np.array(centers_h) + centers_vx, centers_vy = centers_v[:, 1], centers_v[:, 0] + centers_hx, centers_hy = centers_h[:, 1], centers_h[:, 0] + line_v, line_h = HoughLine(x=centers_vx, data=centers_vy), HoughLine(x=centers_hx, data=centers_hy, loss=l) + zv_err_av, zv_err_ap = line_v.debias() + zh_err_av, zh_err_ap = line_h.debias() + return HoughLine.intersect(line_h, line_v) + + +def center_detect_test(imgr, sample_int=30, gk=9, ks=-1, l='soft_l1'): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + centers_v, centers_h = gather_all(imgr, sample_int, gk, ks) + centers_v, centers_h = np.array(centers_v), np.array(centers_h) + centers_vx, centers_vy = centers_v[:, 1], centers_v[:, 0] + centers_hx, centers_hy = centers_h[:, 1], centers_h[:, 0] + line_v, line_h = HoughLine(x=centers_vx, data=centers_vy), HoughLine(x=centers_hx, data=centers_hy, loss=l) + zv_err_av, zv_err_ap = line_v.debias() + zh_err_av, zh_err_ap = line_h.debias() + return HoughLine.intersect(line_h, line_v) + + +def expr2(series): + folder = '../calib5/' + ns = 'img_{0}.png' + ins = folder + ns + repertoire = [] + i = 0 + while i < len(series): + try: + ambi, laser = cv2.imread(ins.format(series[i]), 0), cv2.imread(ins.format(series[i+1]), 0) + res = image_diff(laser, ambi) + except: + print(ins.format(series[i])) + repertoire.append(center_detect_test(res)) + i+= 2 + for i, ct in enumerate(repertoire): + print((series[2*i], series[2*i+1]), ct) + CALIB_VAL = 118.6 + print(repertoire) + i = 0 + while i < len(repertoire): + dx, dy = (np.array(repertoire[i+1]) - np.array(repertoire[i])) / CALIB_VAL + print((series[2*i], series[2*i+1], series[2*i+2], series[2*i+3]), dx, dy) + i+=2 + + +def convergence_test_final(folder, ns): + offset = '../' + convergence = {} + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ls = range(5) + fwrite = open('meas/convergence_rob.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + loss_types = ['huber', 'soft_l1', 'arctan', 'linear', 'cauchy'] + for l in loss_types: + cwriter.writerow([l]) + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + # print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + #x, y = center_detect(fpath + imgfile, 5, m=m) TODO: RESOLVE THE CHANGE + x, y = center_detect(fpath, imgfile.format(1), l=l) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + #x, y = center_detect(fpath + imgfile, 5, m=m) TODO: RESOLVE THE CHANGE + x, y = center_detect(fpath, imgfile.format(1), l=l) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + msepv = sqrt(pv / pvs) + cvg = {'PicConsistency': msepv} + convergence[l] = cvg + variations.append(msepv) + print(convergence) + fwrite.close() + +if __name__ == '__main__': + #print(center_detect('../calib4/img_59_{0}.png', 5)) + #convergence_test_final('calib4/', 'img_{0}') + repertoire = expr2([10, 11, 15, 14, 18, 19, 22, 23]) + + + + diff --git a/img_rec_module/sig_proc_old.py b/img_rec_module/sig_proc_old.py new file mode 100644 index 0000000..e416d0f --- /dev/null +++ b/img_rec_module/sig_proc_old.py @@ -0,0 +1,988 @@ +import cv2 +import numpy as np +import csv +from scipy.optimize import curve_fit +from math import atan, sqrt, tan, radians, acos, asin, degrees, sin, cos + +""" =================================== +========== ANALYTIC GEOMETRY ========== +======================================= """ + + +class Line: + inf = float('inf') + + def __init__(self, a=inf, b=inf, p1=None, p2=None, data=None): + if p1 and p2: + self.point(p1, p2) + elif data: + self.reg(data) + else: + self.a = a + self.b = b + + def reg(self, data): + D = np.array([[d[0], 1] for d in data]) + y = np.array([d[1] for d in data]) + self.a, self.b = leastSquares(D, y) + + def point(self, p1, p2): + self.a = 1 + + @staticmethod + def intersect(l1, l2): + x = (l2.b - l1.b) / (l1.a - l2.a) + y = l1.a * x + l1.b + return x, y + + +class HoughLine: + def __init__(self, theta=0, rho=0, x=None, data=None): + if data is not None and x is not None: + self.reg(x, data) + else: + self._r = rho + self._t = theta + self._s = sin(theta) + self._c = cos(theta) + + def reg(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + x1, x2 = x[0], x[-1] + y1, y2 = data[0], data[-1] + theta0 = theta_pred(x1, y1, x2, y2) + # print(degrees(theta0)) + p0 = [theta0, x1 * cos(theta0) + y1 * sin(theta0)] + pm, vm = curve_fit(hough_line, x, data, p0=p0) + # data_pred = hough_line(x, *pm) + # print('PRED', data_pred) + # res = data_pred - data + # print("RES", res) + # stderr = np.linalg.norm(res, 2) + # print("ERR", stderr) + # rankerr = res / stderr + # print("Z", rankerr) + if pm[1] < 0: + pm[1] = -pm[1] + pm[0] -= HC + # pm[0] = 2 * np.pi + angle = normalize_angle(pm[0]) + self._t = angle + self._r = pm[1] + self._s = sin(angle) + self._c = cos(angle) + + def extract_points(self, x_input): + x1 = int(x_input[0]) + x2 = int(x_input[-1]) + y1 = int(self.fit_x(x1)) + y2 = int(self.fit_x(x2)) + return (x1, y1), (x2, y2) + + def fit_x(self, x): + # print(self._r, self._t) + return (self._r - x * self._c) / self._s + + def __str__(self): + return 'hough line with cos:{0}, sin:{1}, rho:{2}, theta:{3}'.format(self._c, self._s, + self._r, degrees(self._t)) + + @staticmethod + def intersect(l1, l2): + if l1._s == 0: + return l1._r, l2.fit_x(l1._r) + elif l2._s == 0: + return l2._r, l1.fit_x(l2._r) + x = (l2._r / l2._s - l1._r / l1._s) / (l2._c / l2._s - l1._c / l1._s) + y = l1.fit_x(x) + return x, y + + +# QC: QUARTER_CYCLE, HC: HALF_CYCLE, TQC: THIRD_QUARTER_CYCLE, FC: FULL_CYCLE +QC = np.pi / 2 +HC = np.pi +TQC = 3 * np.pi / 2 +FC = 2 * np.pi + + +def angle_interp(s, c): + if c == 1.0: + return 0 + elif s == 1.0: + return np.pi / 2 + elif c == -1.0: + return np.pi + elif s == -1.0: + return np.pi * 3 / 2 + elif c < 0 < s: + return acos(c) + elif s < 0 and c < 0: + return 2 * np.pi - acos(c) + elif s < 0 < c: + return asin(s) + 2 * np.pi + else: + return asin(s) + + +def normalize_angle(angle): + res = angle - (angle // FC) * FC + return res + """ + if QC < res < HC: + return res + HC + elif HC <= res <= TQC: + return res - HC + else: + return res""" + + +def theta_pred(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + angle = sin_angle_from_points(dx, dy) + if dx * dy <= 0: + return np.pi / 2 - angle + else: + root = root_finding(x1, x2, y1, y2) + if root < 0: + return np.pi / 2 + angle + else: + return angle + 3 * np.pi / 2 + + +def sin_angle_from_points(dx, dy): + return asin(abs(dy) / sqrt(dx ** 2 + dy ** 2)) + + +def poly_curve(params, x_input): + # params contains the coefficients that multiply the polynomial terms, in degree of lowest degree to highest degree + degree = len(params) - 1 + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = x * 0 + + for k in range(0, degree + 1): + coeff = params[k] + y = y + list(map(lambda z: coeff * z ** k, x)) + return x, y + + +def gauss_2d(x, y, a, b1, c_s1, b2, c_s2): + return a * np.exp(- ((x - b1) ** 2 / (2 * c_s1) + (y - b2) ** 2) / (2 * c_s2)) + + +def gauss_hat(x, a, b, c_s): + return a * np.exp(- (x - b) ** 2 / (2 * c_s)) + + +def gaussian_curve(x_input, a, b, c_s): + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = a * np.exp(- (x - b) ** 2 / (2 * c_s)) + return x, y + + +def hough_line(x, theta, rho): + return (rho - x * cos(theta)) / sin(theta) + + +""" =================================== +========== MATRIX-ARRAY UTIL ========== +======================================= """ + + +class FastDataMatrix2D: + # TODO: HANDLE THE CASE WHEN IT WRAPS 1D + + HOR = 1 + VER = 0 + + def __init__(self, data, ax, index): + self._data = data + self._ax = ax + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + self.itr = 0 + self.initialize() + + def segmentize(self, start, end): + assert 0 <= start < end <= self._data.shape[self._ax], "start: {0}, end: {1}, ax: {2}, index: {3}".format(start, + end, + self._ax, + self._index) + self.start = start + self.end = end + + def initialize(self): + self.segmentize(0, self._data.shape[self._ax]) + + def irange(self): + # index range of the fast matrix array + return self._data.shape[1 - self._ax] + + def set_axis(self, ax): + """USE copy when trying to switch axis and index""" + self._ax = ax + if self._index >= self.irange(): + raise IndexError("Old index {0} is too large for the new axis".format(self._index)) + self.initialize() + + def set_index(self, index): + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + + def extract_array(self): + """Optimize later for better performance""" + arr = self._data[self._index, self.start:self.end] if self._ax == FastDataMatrix2D.HOR \ + else self._data[self.start:self.end, self._index] + return np.array(arr) + + def copy(self, ax=None, index=None): + if ax is not None and index is not None: + return FastDataMatrix2D(self._data, ax, index) + else: + return FastDataMatrix2D(self._data, self._ax, self._index) + + def __iter__(self): + raise RuntimeError("You need the ITER method!") + + def __next__(self): + raise RuntimeError("You need the NEXT method!") + + def __getitem__(self, item): + return self._data[self._index, item + self.start] if self._ax == FastDataMatrix2D.HOR else self._data[item + self.start, self._index] + + def __setitem__(self, key, value): + if self._ax == FastDataMatrix2D.HOR: + self._data[self._index, key + self.start] = value + else: + self._data[key + self.start, self._index] = value + + def __len__(self): + return self.end - self.start + + +""" =================================== +=========== REGRESSION UTILS ========== +======================================= """ + + +# Generic Regression Tools 128-133 +def leastSquares(D, y): + return np.linalg.lstsq(D, y, rcond=None)[0] + + +def MSE(y, y_hat, N): + return np.linalg.norm(y - y_hat) ** 2 / N + + +def std_dev(data): + std_dev = 0 + len_data = len(data) + mean = sum(data) / len_data + for i in range(len_data): + std_dev += (data[i] - mean) ** 2 + return sqrt(std_dev / len_data) + + +def reg_pre_debias(ind, data): + sd = np.std(data) + miu = np.mean(data) + debiased_data = [] + debiased_ind = [] + for i in range(len(data)): + dev = abs((data[i] - miu) / sd) + if dev < 2: + debiased_data.append(data[i]) + debiased_ind.append(ind[i]) + return debiased_ind, debiased_data + + + + +# Polynomial Regression Tools 137-171 +def poly_data_matrix(input_data, degree): + # degree is the degree of the polynomial you plan to fit the data with + Data = np.zeros((len(input_data), degree + 1)) + + for k in range(0, degree + 1): + Data[:, k] = (list(map(lambda x: x ** k, input_data))) + + return Data + + +def poly_error(params, D_a, y_a): + '''degree=len(params)-1 + y=x_a*0 + + for k in range(0,degree+1): + coeff=params[k] + y=y+list(map(lambda z:coeff*z**k,x_a))''' + y = np.dot(D_a, params) + return np.linalg.norm(y - y_a) ** 2 + + +def improvedCost(x, y, x_test, y_test, start, end): + """Given a set of x and y points training points, + this function calculates polynomial approximations of varying + degrees from start to end. Then it returns the cost, with + the polynomial tested on test points of each degree in an array""" + c = [] + degrees = range(start, end) + ps = [] + for degree in degrees: + # YOUR CODE HERE + D = poly_data_matrix(x, degree) + p = leastSquares(D, y) + ps.append(p) + D_t = poly_data_matrix(x_test, degree) + y_hat = np.dot(D_t, p) + c.append(MSE(y_test, y_hat, len(x_test))) + return np.array(degrees), ps, np.array(c) + + +# Gaussian Regression Tools 184-210 +def gauss_data_matrix(data): + return np.array([[1, x ** 2, x, 1] for x in data]) + + +def gauss_reg(x, y, p0): + """Given a set of x and y training points, this function + calculates the gaussian approximation function""" + """skip_x = np.array([x[i] for i in range(len(y)) if y[i] != 0]) + y_prime = np.array([y[i] for i in range(len(y)) if y[i] != 0]) + logy = np.log(y_prime) + + sol = leastSquares(gauss_data_matrix(skip_x), logy) + alp, bet, gam, lam = sol + a = np.e ** alp + c_s = - 1 / (2 * bet) + b = gam * c_s + maxi, mini = max_min(y) + pred = gauss_hat(maxi, a, b, c_s) + real = y[maxi] + a = real / pred // 1000000000 * 10""" + # timeb = datetime.now() + param, vm = curve_fit(gauss_hat, x, y, p0=p0) + # timea = datetime.now() + # print(timea - timeb) + return param + + +def gauss_mat(shape, a, b1, c_s1, b2, c_s2): + mat = np.zeros(shape) + for r in range(mat.shape[0]): + for c in range(mat.shape[1]): + mat[r, c] = gauss_2d(c, r, a, b1, c_s1, b2, c_s2) + + return mat + + +# Hough Transform Regression Tools +def hough_data_matrix(x, y): + dim = len(x) + mat = np.full((dim, 3), -1.0) + for i in range(dim): + mat[i][0] = x[i] + mat[i][1] = y[i] + return mat + + +""" ======================================= +========= EDGE DETECTION UTILS ============ +=========================================== """ + + +# Generic Helper +def max_min(data): + # Returns the maximum and minimum for the data + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + return max_ind, min_ind + + +def edge_max_min(data): + # Returns a *safe* edge maxi, mini for the data + # TODO: OPTIMIZE THE WIDTH AND VALUE THRESHOLD + width_thres = 90 + value_thres = 20 + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + maxi, mini = max_ind, min_ind + assert data[maxi] >= value_thres and mini - maxi <= width_thres and maxi < mini + return maxi, mini + + +def min_max(data, max, min): + """ Converts the data to min max space. """ + g_diff = max - min + return [(d - min) / g_diff for d in data] + + +def root_finding(x1, x2, y1, y2): + """Given two points on a line, finds its zero crossing root.""" + return - y1 * (x2 - x1) / (y2 - y1) + x1 + + +def check_crossing(data, i): + return i + 1 < len(data) and check_cross(data[i], data[i+1]) + + +def check_cross(a, b): + # Checks whether two points are of opposite signs + return a * b < 0 + + +def round_up(num): + down = int(num) + if num - down > 0: + return num + 1 + else: + return num + + +def smart_interval(start, end, data): + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + return start, end + + +def edge_preprocess(data, padding): + maxi, mini = edge_max_min(data) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end + + +# ZERO CROSSING (PEAK FINDING) +def zero_crossing(data): + # Yields the center with zero-crossing method + maxi, mini = max_min(data) + cross = -1 + cross_count = 0 + for j in range(maxi, mini): + y1 = data[j] + x2 = j + 1 + y2 = data[x2] + if check_cross(y1, y2): + cross = root_finding(j, x2, y1, y2) # change to function later + cross_count += 1 + return -1 if cross_count > 1 else cross + + +# AVERAGE METHOD FOR EDGE CENTER FINDING +def edge_converge_base(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + else: + return (maxi + mini) / 2 + + +# PSEUDO EDGE (closest noise gradient change) CENTER FINDING +def edge_converge_extreme(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + emax = -1 + emin = -1 + maxflag = True + minflag = True + cmax = maxi + cmin = mini + while cmax > 0 and cmin < len(data) - 1 and (maxflag or minflag): + max2 = cmax - 1 + maxy1, maxy2 = data[cmax], data[max2] + min2 = cmin + 1 + miny1, miny2 = data[cmin], data[min2] + if check_cross(maxy1, maxy2) and maxflag: + emax = root_finding(cmax, max2, maxy1, maxy2) + maxflag = False + if check_cross(miny1, miny2) and minflag: + emin = root_finding(cmin, min2, miny1, miny2) + minflag = False + if maxflag: + cmax -= 1 + if minflag: + cmin += 1 + return -1 if (emax == -1 or emin == -1) else (emax + emin) / 2 + + +def extract_extrema(data): + len_data = len(data) + mean = sum(data) / len_data + std_dev = 0 + for x in data: + std_dev += (x - mean) ** 2 + std_dev = sqrt(std_dev / len_data) + signifmax = [] + signifmin = [] + coeff = 3 + for i, x in enumerate(data): + diff = (x - mean) / std_dev + if diff >= coeff: + signifmax.append(i) + elif diff <= -coeff: + signifmin.append(i) + return signifmax, signifmin + + +# CENTROID METHOD FOR EDGE CENTER FINDING +def edge_centroid(data, img_data, padding=20): + # With Gaussian Blur might achieve the best performance + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + isums = 0 + total = 0 + for i in range(start, end): + isums += img_data[i] * i + total += img_data[i] + return isums / total if total else -1 + + +def centroid_seg(data, start, end): + """ Given a segment (start, end) of the data, + find the centroid. """ + isums = 0 + total = 0 + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + for i in range(start, end): + isums += data[i] * i + total += data[i] + return isums / total if total else -1 + + +# POLYNOMIAL FITTING +def poly_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + #y = np.array(img_data[start:end]) + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + curve_x, curve_y = poly_curve(param, x) + center_id = np.argmax(curve_y) + return curve_x[center_id] + + +def poly_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + 1 + start, end = smart_interval(start, end, data) + if start > end: + try: + print(maxi, mini, img_data._ax, start, end) + except: + print("else", maxi, mini, start, end) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + return param, x + + +DEGREES = {} + + +def degree_register(elem): + if elem in DEGREES: + DEGREES[elem] += 1 + else: + DEGREES[elem] = 1 + + +def gaussian_center(data, img_data, maxi, mini, padding=20): + #padding = (mini - maxi) // 2 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +# GAUSSIAN FITTING +def gaussian_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + try: + maxi, mini = edge_max_min(data) + print((mini - maxi) // 2) + except AssertionError: + return -1 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end-start) + for i in range(start, end): + idata[i-start] = img_data[i] + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +def gaussian_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 # TODO: CONSOLIDATE THIS VALUE + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + start, end = smart_interval(start, end, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i-start] = img_data[i] + return gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]), x + + +"""====================================== +======== IMAGE PROCESSING UTIL ========== +========================================= """ + + +def gauss_bg_deduce(x, img_data): + # TODO: OPTIMIZE PERFORMANCE + idata = img_data.extract_array() + p0 = [1, len(img_data) / 2, std_dev(idata)] + a, b, c_s = gauss_reg(x, idata, p0=p0) + rem_gauss = gauss_hat(x, a, b, c_s) + new_y = idata - rem_gauss + return x, rem_gauss, new_y + + +def significance_test(data, val): + """Outputs whether the maximum or minimum value is a significant value.""" + return val in extract_extrema(data)[0] or val in extract_extrema(data)[1] + + +def edge_detect_expr(edges, original): + """ + TODO: 1. SIMPLE Approach: pairwise mask over original image, then compute total + 2. Traverse the image to mark the image. + """ + se = 0 + row_sum = 0 + col_sum = 0 + tot_sum = 0 + for i in range(edges.shape[0]): + for j in range(edges.shape[1]): + if edges[i][j] > 0: + row_sum += i * original[i][j] + col_sum += j * original[i][j] + tot_sum += original[i][j] + se += 1 + print(se) + if tot_sum != 0: + print(row_sum / tot_sum) + print(col_sum / tot_sum) + + +def hori(img, i, j, d): + dest = j + d + if dest < 0 or dest >= img.shape[1]: + return img.item(i, j) + return img.item(i, dest) + + +def verti(img, i, j, d): + dest = i + d + if dest < 0 or dest >= img.shape[0]: + return img.item(i, j) + return img.item(dest, j) + + +def test_blur_then_nr(iname): + imgs = iname + numIMG = 5 + imgr = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + target = cv2.GaussianBlur(target, (9, 9), 0) + if i == 1: + imgr = np.uint16(target) + else: + imgr = imgr + target + return imgr / numIMG + + +def get_center_val(img): + return img.item(img.shape[0] // 2, img.shape[1] // 2) + + +def test_noise_reduce(iname, numIMG=5): + imgs = iname + imgr = None + original = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + if target is None: + raise AttributeError("File {0} not found".format(iname)) + if i == 1: + imgr = np.uint16(target) + original = target + else: + imgr = imgr + target + return imgr / numIMG, original + + +def img_add(dest, src): + """Destructive!""" + row, col = dest.shape + for i in range(row): + for j in range(col): + dest[i][j] += src[i][j] + + +FM = FastDataMatrix2D + + +def folder_to_imgs(img_name_scheme, num_sample): + """This function takes img files and return cv imgs""" + return [cv2.imread(img_name_scheme.format(i)) for i in range(1, num_sample + 1)] + + +# The image taken is flipped horizontally, result x should be img.shape[1] - x +# The image sometimes has two peaks, try experimenting with different gaussian kernels +def center_detect(img_name_scheme, num_sample, sample_int=50, gk=9, ks=-1, m=0, p=20, + b=1, c=0): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # ------------------------------------------------------------ + # Parameter Setting + METHODS = {0: gaussian_fitting, 1: poly_fitting, 2: edge_centroid, + 3: zero_crossing, 4: edge_converge_base, 5: edge_converge_extreme} + edge_method = METHODS[m] + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + # ------------------------------------------------------------ + # Gathering Data + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + if m < 3: + ec_x = edge_method(data_x, FM(img, FM.HOR, nr), p) + else: + ec_x = edge_method(data_x) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, ec_x)) + + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + if m < 3: + ec_y = edge_method(data_y, FM(img, FM.VER, nc), p) + else: + ec_y = edge_method(data_y) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, ec_y)) + len_hs = len(hs) + len_vs = len(vs) + # ------------------------------------------------------------ + # --------------- PRE-CHECK DATA VALUES ---------------------- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + x_valid = False + y_valid = False + # OUTLIER DETECTION TODO: OPTIMIZE, THIS IS NAIVE + if len_hs >= r_thresh: + x_valid = True + hys, hxs = reg_pre_debias(hys, hxs) + line_a = HoughLine(x=hxs, data=hys) + if len_vs >= c_thresh: + y_valid = True + vxs, vys = reg_pre_debias(vxs, vys) + line_b = HoughLine(x=vxs, data=vys) + # ------------------------------------------------------------ + # ----- Following Modules Handles Hough Line Drawing --------- + # ------------------------------------------------------------ + # DATA RECORDING AND PROCESSING + if c == 1: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + else: + if x_valid and y_valid: + center_x, center_y = HoughLine.intersect(line_a, line_b) + else: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + # --------------------------------------------------------- + return center_x, center_y + + + +def convergence_test_final(folder, ns): + offset = '../' + convergence = {} + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence_v1.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + # print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + msepv = sqrt(pv / pvs) + cvg = {'PicConsistency': msepv} + convergence[m] = cvg + variations.append(msepv) + print(convergence) + fwrite.close() + +if __name__ == '__main__': + #print(center_detect('../calib4/img_59_{0}.png', 5)) + convergence_test_final('calib4/', 'img_{0}') + + + diff --git a/img_rec_module/sig_proc_rob.py b/img_rec_module/sig_proc_rob.py new file mode 100644 index 0000000..8a42d95 --- /dev/null +++ b/img_rec_module/sig_proc_rob.py @@ -0,0 +1,1485 @@ +import cv2 +import numpy as np +import csv +from scipy.optimize import curve_fit +from scipy.optimize import least_squares +import heapq +from decimal import Decimal +from math import atan, sqrt, tan, radians, acos, asin, degrees, sin, cos +import matplotlib.pyplot as plt + +""" =================================== +========== ANALYTIC GEOMETRY ========== +======================================= """ + + +class Line: + inf = float('inf') + + def __init__(self, a=inf, b=inf, p1=None, p2=None, data=None): + if p1 and p2: + self.point(p1, p2) + elif data: + self.reg(data) + else: + self.a = a + self.b = b + + def reg(self, data): + D = np.array([[d[0], 1] for d in data]) + y = np.array([d[1] for d in data]) + self.a, self.b = leastSquares(D, y) + + def point(self, p1, p2): + self.a = 1 + + @staticmethod + def intersect(l1, l2): + x = (l2.b - l1.b) / (l1.a - l2.a) + y = l1.a * x + l1.b + return x, y + + +class HoughLine: + def __init__(self, theta=0, rho=0, x=None, data=None, new=True, r_bound=np.inf, loss='soft_l1'): + if data is not None and x is not None: + self.x = x + self.data = data + self.r_bound = r_bound + self.loss = loss + if new: + self.reg = self.reg_new + else: + self.reg = self.reg_old + self.reg(x, data) + else: + self._r = rho + self._t = theta + self._s = sin(theta) + self._c = cos(theta) + + def reg_old(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + + x1, x2 = np.mean(x[:int(len(x) / 2)]), np.mean(x[int(len(x) / 2):]) + y1, y2 = np.mean(data[:int(len(data) / 2)]), np.mean(data[int(len(data) / 2):]) + theta0 = theta_pred(x1, y1, x2, y2) + p0 = [theta0, np.mean(x) * np.cos(theta0) + np.mean(data) * np.sin(theta0)] + """ + x1, x2 = x[0], x[-1] + y1, y2 = data[0], data[-1] + theta0 = theta_pred(x1, y1, x2, y2) + # print(degrees(theta0)) + p0 = [theta0, x1 * cos(theta0) + y1 * sin(theta0)]""" + pm, vm = curve_fit(hough_line, x, data, p0=p0) + # data_pred = hough_line(x, *pm) + # print('PRED', data_pred) + # res = data_pred - data + # print("RES", res) + # stderr = np.linalg.norm(res, 2) + # print("ERR", stderr) + # rankerr = res / stderr + # print("Z", rankerr) + if pm[1] < 0: + pm[1] = -pm[1] + pm[0] -= HC + # pm[0] = 2 * np.pi + angle = normalize_angle(pm[0]) + self._t = angle + self._r = pm[1] + self._s = sin(angle) + self._c = cos(angle) + + def reg_new(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + x1, x2 = np.mean(x[:int(len(x) / 2)]), np.mean(x[int(len(x) / 2):]) + y1, y2 = np.mean(data[:int(len(data) / 2)]), np.mean(data[int(len(data) / 2):]) + theta0 = theta_pred(x1, y1, x2, y2) + p0 = [theta0, np.mean(x) * np.cos(theta0) + np.mean(data) * np.sin(theta0)] + res = least_squares(self.get_err, p0, loss=self.loss, f_scale=3, args=(x, data)) + # data_pred = hough_line(x, *pm) + # print('PRED', data_pred) + # res = data_pred - data + # print("RES", res) + # stderr = np.linalg.norm(res, 2) + # print("ERR", stderr) + # rankerr = res / stderr + # print("Z", rankerr) + angle = normalize_angle(res.x[0]) + self._t = angle + self._r = res.x[1] + self._s = sin(angle) + self._c = cos(angle) + + def get_err(self, vars, xs, ys): + return xs * np.cos(vars[0]) + ys * np.sin(vars[0]) - vars[1] + + def fit_x(self, x): + # print(self._r, self._t) + return (self._r - x * self._c) / self._s if self._s != 0 else 'undef' + + def debias(self, thres=1.0): + """ @:returns tuple with a) zerr_before: regression error before debias + b) zerr_after: regression error after debias""" + x, y = self.x, self.data + zero_hat_before = x * self._c + y * self._s - self._r + #y_hat_before = self.fit_x(x) + zerr_before = np.square(zero_hat_before) + #yerr_before = np.square(y_hat_before - y) + conds = (zerr_before - np.mean(zerr_before)) / np.std(zerr_before) <= thres + new_x, new_y = x[conds], y[conds] + self.x, self.data = new_x, new_y + self.reg(new_x, new_y) + zero_hat_after = new_x * self._c + new_y * self._s - self._r + #y_hat_after = self.fit_x(new_x) + zerr_after = np.square(zero_hat_after) + #yerr_after = np.square(y_hat_after - new_y) + return zerr_before, zerr_after + + def point_gen(self): + x0 = self._c * self._r + y0 = self._s * self._r + x1 = int(x0 + 1000 * (-self._s)) + y1 = int(y0 + 1000 * (self._c)) + x2 = int(x0 - 1000 * (-self._s)) + y2 = int(y0 - 1000 * (self._c)) + return (x1, y1), (x2, y2) + + def __str__(self): + return 'hough line with cos:{0}, sin:{1}, rho:{2}, theta:{3}'.format(self._c, self._s, + self._r, degrees(self._t)) + + @staticmethod + def intersect(l1, l2): + if l1._s == 0 and l2._s == 0: + return float('inf'), float('inf') + if l1._s == 0: + return l1._r, l2.fit_x(l1._r) + elif l2._s == 0: + return l2._r, l1.fit_x(l2._r) + x = (l2._r / l2._s - l1._r / l1._s) / (l2._c / l2._s - l1._c / l1._s) + y = l1.fit_x(x) + return x, y + + +# QC: QUARTER_CYCLE, HC: HALF_CYCLE, TQC: THIRD_QUARTER_CYCLE, FC: FULL_CYCLE +QC = np.pi / 2 +HC = np.pi +TQC = 3 * np.pi / 2 +FC = 2 * np.pi + + +def angle_interp(s, c): + if c == 1.0: + return 0 + elif s == 1.0: + return np.pi / 2 + elif c == -1.0: + return np.pi + elif s == -1.0: + return np.pi * 3 / 2 + elif c < 0 < s: + return acos(c) + elif s < 0 and c < 0: + return 2 * np.pi - acos(c) + elif s < 0 < c: + return asin(s) + 2 * np.pi + else: + return asin(s) + + +def normalize_angle(angle): + res = angle - (angle // FC) * FC + return res + """ + if QC < res < HC: + return res + HC + elif HC <= res <= TQC: + return res - HC + else: + return res""" + + +def theta_pred(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + angle = sin_angle_from_points(dx, dy) + if dx * dy <= 0: + return np.pi / 2 - angle + else: + root = root_finding(x1, x2, y1, y2) + if root < 0: + return np.pi / 2 + angle + else: + return angle + 3 * np.pi / 2 + + +def sin_angle_from_points(dx, dy): + return asin(abs(dy) / sqrt(dx ** 2 + dy ** 2)) + + +def poly_curve(params, x_input): + # params contains the coefficients that multiply the polynomial terms, in degree of lowest degree to highest degree + degree = len(params) - 1 + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = x * 0 + + for k in range(0, degree + 1): + coeff = params[k] + y = y + list(map(lambda z: coeff * z ** k, x)) + return x, y + + +def gauss_2d(x, y, a, b1, c_s1, b2, c_s2): + return a * np.exp(- ((x - b1) ** 2 / (2 * c_s1) + (y - b2) ** 2) / (2 * c_s2)) + + +def gauss_hat(x, a, b, c_s): + return a * np.exp(- (x - b) ** 2 / (2 * c_s)) + + +def gaussian_curve(x_input, a, b, c_s): + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = a * np.exp(- (x - b) ** 2 / (2 * c_s)) + return x, y + + +def hough_line(x, theta, rho): + return (rho - x * np.cos(theta)) / np.sin(theta) + + +""" =================================== +========== MATRIX-ARRAY UTIL ========== +======================================= """ + + +class PseudoLL(list): + def push(self, obj): + self.append(obj) + + def __getitem__(self, item): + return super().__getitem__(len(self) - 1 - item) + + def __repr__(self): + rep = '[' + ls = len(self) + for i in range(ls): + if i > 0: + rep += ', ' + val = self[i] + rep += str(val) + rep += ']' + return rep + + +class FastDataMatrix2D: + # TODO: HANDLE THE CASE WHEN IT WRAPS 1D + + HOR = 1 + VER = 0 + + def __init__(self, data, ax, index): + self._data = data + self._ax = ax + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + self.itr = 0 + self.initialize() + + def segmentize(self, start, end): + assert 0 <= start < end <= self._data.shape[self._ax], \ + "start: {0}, end: {1}, ax: {2}, index: {3}".format(start, end, self._ax, self._index) + self.start = start + self.end = end + + def initialize(self): + self.segmentize(0, self._data.shape[self._ax]) + + def irange(self): + # index range of the fast matrix array + return self._data.shape[1 - self._ax] + + def set_axis(self, ax): + """USE copy when trying to switch axis and index""" + self._ax = ax + if self._index >= self.irange(): + raise IndexError("Old index {0} is too large for the new axis".format(self._index)) + self.initialize() + + def set_index(self, index): + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + + def extract_array(self): + """Optimize later for better performance""" + arr = self._data[self._index, self.start:self.end] if self._ax == FastDataMatrix2D.HOR \ + else self._data[self.start:self.end, self._index] + return np.array(arr) + + def copy(self, ax=None, index=None): + if ax is not None and index is not None: + return FastDataMatrix2D(self._data, ax, index) + else: + return FastDataMatrix2D(self._data, self._ax, self._index) + + def __iter__(self): + raise RuntimeError("You need the ITER method!") + + def __next__(self): + raise RuntimeError("You need the NEXT method!") + + def __getitem__(self, item): + return self._data[self._index, item + self.start] if self._ax == FastDataMatrix2D.HOR else self._data[item + self.start, self._index] + + def __setitem__(self, key, value): + if self._ax == FastDataMatrix2D.HOR: + self._data[self._index, key + self.start] = value + else: + self._data[key + self.start, self._index] = value + + def __len__(self): + return self.end - self.start + + +""" =================================== +=========== REGRESSION UTILS ========== +======================================= """ + + +# Generic Regression Tools 128-133 +def leastSquares(D, y): + return np.linalg.lstsq(D, y, rcond=None)[0] + + +def MSE(y, y_hat, N): + return np.linalg.norm(y - y_hat) ** 2 / N + + +def std_dev(data): + std_dev = 0 + len_data = len(data) + mean = sum(data) / len_data + for i in range(len_data): + std_dev += (data[i] - mean) ** 2 + return sqrt(std_dev / len_data) + + +def reg_pre_debias(ind, data): + sd = np.std(data) + miu = np.mean(data) + debiased_data = [] + debiased_ind = [] + for i in range(len(data)): + dev = abs((data[i] - miu) / sd) + if dev < 2: + debiased_data.append(data[i]) + debiased_ind.append(ind[i]) + return debiased_ind, debiased_data + + +# Polynomial Regression Tools 137-171 +def poly_data_matrix(input_data, degree): + # degree is the degree of the polynomial you plan to fit the data with + Data = np.zeros((len(input_data), degree + 1)) + + for k in range(0, degree + 1): + Data[:, k] = (list(map(lambda x: x ** k, input_data))) + + return Data + + +def poly_error(params, D_a, y_a): + '''degree=len(params)-1 + y=x_a*0 + + for k in range(0,degree+1): + coeff=params[k] + y=y+list(map(lambda z:coeff*z**k,x_a))''' + y = np.dot(D_a, params) + return np.linalg.norm(y - y_a) ** 2 + + +def improvedCost(x, y, x_test, y_test, start, end): + """Given a set of x and y points training points, + this function calculates polynomial approximations of varying + degrees from start to end. Then it returns the cost, with + the polynomial tested on test points of each degree in an array""" + c = [] + degrees = range(start, end) + ps = [] + for degree in degrees: + # YOUR CODE HERE + D = poly_data_matrix(x, degree) + p = leastSquares(D, y) + ps.append(p) + D_t = poly_data_matrix(x_test, degree) + y_hat = np.dot(D_t, p) + c.append(MSE(y_test, y_hat, len(x_test))) + return np.array(degrees), ps, np.array(c) + + +# Gaussian Regression Tools 184-210 +def gauss_data_matrix(data): + return np.array([[1, x ** 2, x, 1] for x in data]) + + +def gauss_reg(x, y, p0): + """Given a set of x and y training points, this function + calculates the gaussian approximation function""" + """skip_x = np.array([x[i] for i in range(len(y)) if y[i] != 0]) + y_prime = np.array([y[i] for i in range(len(y)) if y[i] != 0]) + logy = np.log(y_prime) + + sol = leastSquares(gauss_data_matrix(skip_x), logy) + alp, bet, gam, lam = sol + a = np.e ** alp + c_s = - 1 / (2 * bet) + b = gam * c_s + maxi, mini = max_min(y) + pred = gauss_hat(maxi, a, b, c_s) + real = y[maxi] + a = real / pred // 1000000000 * 10""" + # timeb = datetime.now() + param, vm = curve_fit(gauss_hat, x, y, p0=p0) + # timea = datetime.now() + # print(timea - timeb) + return param + + +def gauss_mat(shape, a, b1, c_s1, b2, c_s2): + mat = np.zeros(shape) + for r in range(mat.shape[0]): + for c in range(mat.shape[1]): + mat[r, c] = gauss_2d(c, r, a, b1, c_s1, b2, c_s2) + + return mat + + +# Hough Transform Regression Tools +def hough_data_matrix(x, y): + dim = len(x) + mat = np.full((dim, 3), -1.0) + for i in range(dim): + mat[i][0] = x[i] + mat[i][1] = y[i] + return mat + + +""" ======================================= +========= EDGE DETECTION UTILS ============ +=========================================== """ + + +def gather_all(imgr, sample_int=30, gk=9, ks=-1): + """ @:returns centers_v, centers_h, list of possible centers gathered by algorithm, represented as (row, col) + """ + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # Parameter Setting + nr = sample_int + nc = sample_int + # Gathering Data + centers_v = [] + centers_h = [] + while nr < dimr: + data_x = sobelx[nr, :] + am = gather_centers(data_x, img[nr, :], centers_v, 0, nr, gaussian_center) + nr += sample_int + while nc < dimc: + data_y = sobely[:, nc] + raw_y = img[:, nc] + am = gather_centers(data_y, img[:, nc], centers_h, 1, nc, gaussian_center) + nc += sample_int + return centers_v, centers_h + + +def gather_centers(grad, raw_data, reserve, ax, ax_n, center_method): + # Given grad and raw_data, insert the possible beam centers to reserves + max_grad, min_grad = get_maxi_mini(grad) + max_q, min_q, locs = bi_order_sort(max_grad, min_grad) + miu, sig = np.mean(raw_data), np.std(raw_data) + avant = lambda locs, i: locs[i - 1] if i - 1 >= 0 else None + apres = lambda locs, i: locs[i + 1] if i + 1 < len(locs) else None + i = 0 + peaked = False + while (i < 2 or peaked) and max_q and min_q: + if peaked: + top = min_q.pop() + av = avant(locs, top[1]) + if av in max_q and beam_bound(raw_data, miu, sig, av, top): + mid = center_method(grad, raw_data, av[0], top[0]) + reserve.append((ax_n, mid) if ax == 0 else (mid, ax_n)) + max_q.remove(av) + i += 1 + peaked = False + else: + max_top = max_q.pop() + min_top = min_q[0] + if beam_bound(raw_data, miu, sig, max_top, min_top): + # print("MaxMin: ", max_top, min_top) + mid = center_method(grad, raw_data, max_top[0], min_top[0]) + reserve.append((ax_n, mid) if ax == 0 else (mid, ax_n)) + min_q.remove(min_top) + i += 1 + else: + peaked = True + ap = apres(locs, max_top[1]) + # QUICK FIX HERE, THINK MORE + if ap in min_q and beam_bound(raw_data, miu, sig, max_top, ap): + # print("Max_apres: ", max_top, ap) + mid = center_method(grad, raw_data, max_top[0], ap[0]) + reserve.append((ax_n, mid) if ax == 0 else (mid, ax_n)) + min_q.remove(ap) + i += 1 + return i + + +def sup_tout(max_q, min_q, d, guess): + if guess == 0: + prem, deux = max_q, min_q + else: + prem, deux = min_q, max_q + if d in prem: + prem.remove(d) + elif d in prem: + deux.remove(d) + else: + raise RuntimeError("Tried to remove already removed term! {0}, {1}".format(d, guess)) + + +def get_maxi_mini(data, ceil=3): + # Given data, pluck the maxis and minis and store them in minpq and maxpq respectively + max_grad = [] + min_grad = [] + nat_select = lambda a, b: a if a[0] >= b[0] else b + maxer = lambda d: len(max_grad) < ceil or d > max_grad[0][0] + miner = lambda d: len(min_grad) < ceil or d > min_grad[0][0] + active_max, active_min = None, None + + for i, d in enumerate(data): + if not active_max: + if maxer(d): + active_max = (d, i) + else: + curr = (d, i) + active_max = nat_select(curr, active_max) + if active_max and (check_crossing(data, i) or i == len(data) - 1): + heapq.heappush(max_grad, active_max) + if len(max_grad) > ceil: + heapq.heappop(max_grad) + active_max = None + + if not active_min: + if miner(-d): + active_min = (-d, i) + else: + curr = (-d, i) + active_min = nat_select(curr, active_min) + if active_min and (check_crossing(data, i) or i == len(data) - 1): + heapq.heappush(min_grad, active_min) + if len(min_grad) > ceil: + heapq.heappop(min_grad) + active_min = None + + return max_grad, min_grad + + +def bi_order_sort(max_grad, min_grad): + # Takes in a max_grad and min_grad (heapq), returns a locational ordered array and a magnitude queue. + locs = [] + max_q, min_q = PseudoLL(), PseudoLL() + while len(max_grad) and len(min_grad): + mat = heapq.heappop(max_grad) + mit = heapq.heappop(min_grad) + maxt, mint = [mat[1], None], [mit[1], None] + locs.append(maxt) + locs.append(mint) + max_q.push(maxt) + min_q.push(mint) + locs.sort(key=lambda pair: pair[0]) + for i in range(len(locs)): + locs[i][1] = i + return max_q, min_q, locs + + +def beam_bound(raw, miu, sig, a1, a2, thres=2): + # given raw data, determine if a1, a2 are beam bound entries, where a1, a2 are tuples [index, *(loc)] + return a1 and a2 and a2[1] == a1[1] + 1 and (raw[(a1[0] + a2[0]) // 2] - miu) / sig >= thres + + +# Generic Helper +def max_min(data): + # Returns the maximum and minimum for the data + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + return max_ind, min_ind + + +def edge_max_min(data): + # Returns a *safe* edge maxi, mini for the data + # TODO: OPTIMIZE THE WIDTH AND VALUE THRESHOLD + width_thres = 90 + value_thres = 20 + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + maxi, mini = max_ind, min_ind + assert data[maxi] >= value_thres and mini - maxi <= width_thres and maxi < mini + return maxi, mini + + +def min_max(data, max, min): + """ Converts the data to min max space. """ + g_diff = max - min + return [(d - min) / g_diff for d in data] + + +def root_finding(x1, x2, y1, y2): + """Given two points on a line, finds its zero crossing root.""" + return - y1 * (x2 - x1) / (y2 - y1) + x1 + + +def check_crossing(data, i): + return i + 1 < len(data) and check_cross(data[i], data[i+1]) + + +def check_cross(a, b): + # Checks whether two points are of opposite signs + return a * b < 0 + + +def round_up(num): + down = int(num) + if num - down > 0: + return num + 1 + else: + return num + + +def smart_interval(start, end, data): + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + return start, end + + +def edge_preprocess(data, padding): + maxi, mini = edge_max_min(data) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end + + +# ZERO CROSSING (PEAK FINDING) +def zero_crossing(data): + # Yields the center with zero-crossing method + maxi, mini = max_min(data) + cross = -1 + cross_count = 0 + for j in range(maxi, mini): + y1 = data[j] + x2 = j + 1 + y2 = data[x2] + if check_cross(y1, y2): + cross = root_finding(j, x2, y1, y2) # change to function later + cross_count += 1 + return -1 if cross_count > 1 else cross + + +# AVERAGE METHOD FOR EDGE CENTER FINDING +def edge_converge_base(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + else: + return (maxi + mini) / 2 + + +# PSEUDO EDGE (closest noise gradient change) CENTER FINDING +def edge_converge_extreme(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + emax = -1 + emin = -1 + maxflag = True + minflag = True + cmax = maxi + cmin = mini + while cmax > 0 and cmin < len(data) - 1 and (maxflag or minflag): + max2 = cmax - 1 + maxy1, maxy2 = data[cmax], data[max2] + min2 = cmin + 1 + miny1, miny2 = data[cmin], data[min2] + if check_cross(maxy1, maxy2) and maxflag: + emax = root_finding(cmax, max2, maxy1, maxy2) + maxflag = False + if check_cross(miny1, miny2) and minflag: + emin = root_finding(cmin, min2, miny1, miny2) + minflag = False + if maxflag: + cmax -= 1 + if minflag: + cmin += 1 + return -1 if (emax == -1 or emin == -1) else (emax + emin) / 2 + + +def extract_extrema(data): + len_data = len(data) + mean = sum(data) / len_data + std_dev = 0 + for x in data: + std_dev += (x - mean) ** 2 + std_dev = sqrt(std_dev / len_data) + signifmax = [] + signifmin = [] + coeff = 3 + for i, x in enumerate(data): + diff = (x - mean) / std_dev + if diff >= coeff: + signifmax.append(i) + elif diff <= -coeff: + signifmin.append(i) + return signifmax, signifmin + + +# CENTROID METHOD FOR EDGE CENTER FINDING +def edge_centroid(data, img_data, padding=20): + # With Gaussian Blur might achieve the best performance + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + isums = 0 + total = 0 + for i in range(start, end): + isums += img_data[i] * i + total += img_data[i] + return isums / total if total else -1 + + +def centroid_seg(data, start, end): + """ Given a segment (start, end) of the data, + find the centroid. """ + isums = 0 + total = 0 + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + for i in range(start, end): + isums += data[i] * i + total += data[i] + return isums / total if total else -1 + + +# POLYNOMIAL FITTING +def poly_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + try: + start, end = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + #y = np.array(img_data[start:end]) + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + curve_x, curve_y = poly_curve(param, x) + center_id = np.argmax(curve_y) + return curve_x[center_id] + + +def poly_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + 1 + start, end = smart_interval(start, end, data) + if start > end: + try: + print(maxi, mini, img_data._ax, start, end) + except: + print("else", maxi, mini, start, end) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + return param, x + + +DEGREES = {} + + +def degree_register(elem): + if elem in DEGREES: + DEGREES[elem] += 1 + else: + DEGREES[elem] = 1 + + +def gaussian_center(data, img_data, maxi, mini, padding=20): + #padding = (mini - maxi) // 2 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i - start] = img_data[i] + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +# GAUSSIAN FITTING +def gaussian_fitting(data, img_data, padding=20): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + try: + maxi, mini = edge_max_min(data) + print((mini - maxi) // 2) + except AssertionError: + return -1 + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end-start) + for i in range(start, end): + idata[i-start] = img_data[i] + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +def gaussian_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 # TODO: CONSOLIDATE THIS VALUE + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + start, end = smart_interval(start, end, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.zeros(end - start) + for i in range(start, end): + idata[i-start] = img_data[i] + return gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]), x + + +"""====================================== +======== IMAGE PROCESSING UTIL ========== +========================================= """ + + +def image_diff(img1, img2): + i1 = img1.astype(np.int16) + i2 = img2.astype(np.int16) + res = i1 - i2 + dst = np.zeros_like(res, dtype=np.int8) + return cv2.normalize(res, dst=dst, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=8) + + +def gauss_bg_deduce(x, img_data): + # TODO: OPTIMIZE PERFORMANCE + idata = img_data.extract_array() + p0 = [1, len(img_data) / 2, std_dev(idata)] + a, b, c_s = gauss_reg(x, idata, p0=p0) + rem_gauss = gauss_hat(x, a, b, c_s) + new_y = idata - rem_gauss + return x, rem_gauss, new_y + + +def significance_test(data, val): + """Outputs whether the maximum or minimum value is a significant value.""" + return val in extract_extrema(data)[0] or val in extract_extrema(data)[1] + + +def edge_detect_expr(edges, original): + """ + TODO: 1. SIMPLE Approach: pairwise mask over original image, then compute total + 2. Traverse the image to mark the image. + """ + se = 0 + row_sum = 0 + col_sum = 0 + tot_sum = 0 + for i in range(edges.shape[0]): + for j in range(edges.shape[1]): + if edges[i][j] > 0: + row_sum += i * original[i][j] + col_sum += j * original[i][j] + tot_sum += original[i][j] + se += 1 + print(se) + if tot_sum != 0: + print(row_sum / tot_sum) + print(col_sum / tot_sum) + + +def hori(img, i, j, d): + dest = j + d + if dest < 0 or dest >= img.shape[1]: + return img.item(i, j) + return img.item(i, dest) + + +def verti(img, i, j, d): + dest = i + d + if dest < 0 or dest >= img.shape[0]: + return img.item(i, j) + return img.item(dest, j) + + +def test_blur_then_nr(iname): + imgs = iname + numIMG = 5 + imgr = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + target = cv2.GaussianBlur(target, (9, 9), 0) + if i == 1: + imgr = np.uint16(target) + else: + imgr = imgr + target + return imgr / numIMG + + +def get_center_val(img): + return img.item(img.shape[0] // 2, img.shape[1] // 2) + + +def test_noise_reduce(iname, numIMG=5): + imgs = iname + imgr = None + original = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + if target is None: + raise AttributeError("File {0} not found".format(iname)) + if i == 1: + imgr = np.uint16(target) + original = target + else: + imgr = imgr + target + return imgr / numIMG, original + + +def img_add(dest, src): + """Destructive!""" + row, col = dest.shape + for i in range(row): + for j in range(col): + dest[i][j] += src[i][j] + + +"""====================================== +========== VISUALIZATION UTIL =========== +========================================= """ + + +def visualize_centers(img, centers_v, centers_h, ax): + xsv = [c[1] for c in centers_v] + ysv = [c[0] for c in centers_v] + xsh = [c[1] for c in centers_h] + ysh = [c[0] for c in centers_h] + ax.imshow(img, cmap='gray') + ax.scatter(xsv, ysv, facecolor='blue', linewidths=1) + ax.scatter(xsh, ysh, facecolor='red', linewidths=1) + + +FM = FastDataMatrix2D + + +def folder_to_imgs(img_name_scheme, num_sample): + """This function takes img files and return cv imgs""" + return [cv2.imread(img_name_scheme.format(i)) for i in range(1, num_sample + 1)] + + +def center_detect_hough(img): + centers_v, centers_h = gather_all(img) + centpointsv = np.zeros_like(img, dtype=np.uint8) + centpointsh = np.zeros_like(img, dtype=np.uint8) + #print(centers_v+centers_h) + for r, c in centers_v: + try: + centpointsv[int(r)][int(c)] = 255 + except: + continue + for r, c in centers_h: + try: + centpointsh[int(r)][int(c)] = 255 + except: + continue + linesv = cv2.HoughLines(centpointsv, 0.5, 0.005, 1) + linesh = cv2.HoughLines(centpointsh, 0.5, 0.005, 1) + all_lines = [] + try: + for rho, theta in linesv[0]: + #print(rho, theta) + all_lines.append(HoughLine(theta, rho)) + except: + print(linesv) + for rho, theta in linesh[0]: + all_lines.append(HoughLine(theta, rho)) + ct = HoughLine.intersect(all_lines[0], all_lines[-1]) + return ct + + +# The image taken is flipped horizontally, result x should be img.shape[1] - x +# The image sometimes has two peaks, try experimenting with different gaussian kernels +def center_detect_test(img_name, sample_int=30, gk=9, ks=-1): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + # TODO: CHANGE DEBIAS AND CHANGE VISUALIZATION PART TO HAVE: + # TODO: 1. CENTER_VISUALIZATION WITH LINE DRAWN + # TODO: 2. ERROR BEFORE AND AFTER + imgr = cv2.imread(img_name, 0) + centers_v, centers_h = gather_all(imgr, sample_int, gk, ks) + centers_v, centers_h = np.array(centers_v), np.array(centers_h) + centers_vx, centers_vy = centers_v[:, 1], centers_v[:, 0] + centers_hx, centers_hy = centers_h[:, 1], centers_h[:, 0] + loss_regs = [] + loss_types = ['huber', 'soft_l1', 'arctan', 'linear', 'cauchy'] + for loss in loss_types: + print(loss) + line_v, line_h = HoughLine(x=centers_vx, data=centers_vy), HoughLine(x=centers_hx, data=centers_hy, loss=loss) + vp1_av, vp2_av = line_v.point_gen() + hp1_av, hp2_av = line_h.point_gen() + zv_err_av, zv_err_ap = line_v.debias() + zh_err_av, zh_err_ap = line_h.debias() + loss_regs.append(np.mean(zh_err_ap) ** 2 + np.mean(zv_err_ap) ** 2) + print(loss_regs[-1]) + xv_av, xv_ap = np.arange(len(zv_err_av)), np.arange(len(zv_err_ap)) + xh_av, xh_ap = np.arange(len(zh_err_av)), np.arange(len(zh_err_ap)) + hp1_ap, hp2_ap = line_h.point_gen() + vp1_ap, vp2_ap = line_v.point_gen() + cenhs = list(zip(line_h.data, line_h.x)) + cenvs = list(zip(line_v.data, line_v.x)) + cv2.line(imgr, hp1_ap, hp2_ap, (0, 0, 255), 1) + cv2.line(imgr, vp1_ap, vp2_ap, (0, 0, 255), 1) + + fig1 = plt.figure(figsize=(20, 10)) + ax1 = fig1.add_subplot(121) + visualize_centers(imgr, centers_v, centers_h, ax1) + ax1.set_title('Before') + ax2 = fig1.add_subplot(122) + visualize_centers(imgr, cenvs, cenhs, ax2) + ax2.set_title('After') + fig2 = plt.figure(figsize=(20, 10)) + ax3 = fig2.add_subplot(211) + ax3.plot(xh_av, zh_err_av, 'mo-', xh_ap, zh_err_ap, 'bo-') + ax3.set_title('HOR Loss Avant et Apres') + ax3.legend(['Avant', 'Apres']) + ax4 = fig2.add_subplot(212) + ax4.plot(xv_av, zv_err_av, 'mo-', xv_ap, zv_err_ap, 'bo-') + ax4.set_title('VER Loss Avant et Apres') + ax4.legend(['Avant', 'Apres']) + plt.show() + plt.figure() + plt.plot(range(5), loss_regs, 'b-') + plt.xticks(range(5), loss_types) + plt.show() + return center_detect_hough(imgr) + + +def center_detect(folder_path, img_name, sample_int=30, gk=9, ks=-1, l='soft_l1', visual=False): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + # TODO: CHANGE DEBIAS AND CHANGE VISUALIZATION PART TO HAVE: + # TODO: 1. CENTER_VISUALIZATION WITH LINE DRAWN + # TODO: 2. ERROR BEFORE AND AFTER + imgr = cv2.imread(folder_path+img_name, 0) + centers_v, centers_h = gather_all(imgr, sample_int, gk, ks) + centers_v, centers_h = np.array(centers_v), np.array(centers_h) + centers_vx, centers_vy = centers_v[:, 1], centers_v[:, 0] + centers_hx, centers_hy = centers_h[:, 1], centers_h[:, 0] + + line_v, line_h = HoughLine(x=centers_vx, data=centers_vy), HoughLine(x=centers_hx, data=centers_hy, loss=l) + if visual: + namespace = 'robust_reg/{0}{1}_{2}'.format(folder_path[3:], l, img_name) + vp1_av, vp2_av = line_v.point_gen() + hp1_av, hp2_av = line_h.point_gen() + zv_err_av, zv_err_ap = line_v.debias() + zh_err_av, zh_err_ap = line_h.debias() + + if visual: + xv_av, xv_ap = np.arange(len(zv_err_av)), np.arange(len(zv_err_ap)) + xh_av, xh_ap = np.arange(len(zh_err_av)), np.arange(len(zh_err_ap)) + hp1_ap, hp2_ap = line_h.point_gen() + vp1_ap, vp2_ap = line_v.point_gen() + cenhs = list(zip(line_h.data, line_h.x)) + cenvs = list(zip(line_v.data, line_v.x)) + cv2.line(imgr, hp1_ap, hp2_ap, (0, 0, 255), 1) + cv2.line(imgr, vp1_ap, vp2_ap, (0, 0, 255), 1) + + fig1 = plt.figure(figsize=(20, 10)) + ax1 = fig1.add_subplot(121) + visualize_centers(imgr, centers_v, centers_h, ax1) + ax1.set_title('Before') + ax2 = fig1.add_subplot(122) + visualize_centers(imgr, cenvs, cenhs, ax2) + ax2.set_title('After') + fig2 = plt.figure(figsize=(20, 10)) + ax3 = fig2.add_subplot(211) + ax3.plot(xh_av, zh_err_av, 'mo-', xh_ap, zh_err_ap, 'bo-') + ax3.set_title('HOR Loss Before and After') + ax3.legend(['Before', 'After']) + ax4 = fig2.add_subplot(212) + ax4.plot(xv_av, zv_err_av, 'mo-', xv_ap, zv_err_ap, 'bo-') + ax4.set_title('VER Loss Before and After') + ax4.legend(['Before', 'After']) + fig1.savefig(namespace[:-4]+'_lines'+namespace[-4:]) + fig2.savefig(namespace[:-4] + '_errs' + namespace[-4:]) + return HoughLine.intersect(line_h, line_v) + + +def center_detect_invar(imgr, sample_int=30, gk=9, ks=-1, l='soft_l1', visual=False, + folder_path="../", img_name='.png'): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + centers_v, centers_h = gather_all(imgr, sample_int, gk, ks) + centers_v, centers_h = np.array(centers_v), np.array(centers_h) + centers_vx, centers_vy = centers_v[:, 1], centers_v[:, 0] + centers_hx, centers_hy = centers_h[:, 1], centers_h[:, 0] + + line_v, line_h = HoughLine(x=centers_vx, data=centers_vy), HoughLine(x=centers_hx, data=centers_hy, loss=l) + if visual: + namespace = 'robust_reg/{0}{1}_{2}'.format(folder_path[3:], l, img_name) + vp1_av, vp2_av = line_v.point_gen() + hp1_av, hp2_av = line_h.point_gen() + zv_err_av, zv_err_ap = line_v.debias() + zh_err_av, zh_err_ap = line_h.debias() + + if visual: + xv_av, xv_ap = np.arange(len(zv_err_av)), np.arange(len(zv_err_ap)) + xh_av, xh_ap = np.arange(len(zh_err_av)), np.arange(len(zh_err_ap)) + hp1_ap, hp2_ap = line_h.point_gen() + vp1_ap, vp2_ap = line_v.point_gen() + cenhs = list(zip(line_h.data, line_h.x)) + cenvs = list(zip(line_v.data, line_v.x)) + cv2.line(imgr, hp1_ap, hp2_ap, (0, 0, 255), 1) + cv2.line(imgr, vp1_ap, vp2_ap, (0, 0, 255), 1) + + fig1 = plt.figure(figsize=(20, 10)) + ax1 = fig1.add_subplot(121) + visualize_centers(imgr, centers_v, centers_h, ax1) + ax1.set_title('Before') + ax2 = fig1.add_subplot(122) + visualize_centers(imgr, cenvs, cenhs, ax2) + ax2.set_title('After') + fig2 = plt.figure(figsize=(20, 10)) + ax3 = fig2.add_subplot(211) + ax3.plot(xh_av, zh_err_av, 'mo-', xh_ap, zh_err_ap, 'bo-') + ax3.set_title('HOR Loss Before and After') + ax3.legend(['Before', 'After']) + ax4 = fig2.add_subplot(212) + ax4.plot(xv_av, zv_err_av, 'mo-', xv_ap, zv_err_ap, 'bo-') + ax4.set_title('VER Loss Before and After') + ax4.legend(['Before', 'After']) + fig1.savefig(namespace[:-4]+'_lines'+namespace[-4:]) + fig2.savefig(namespace[:-4] + '_errs' + namespace[-4:]) + return HoughLine.intersect(line_h, line_v) + + +def center_detect_old(img, sample_int=50, gk=9, ks=-1, m=0, p=20, + b=1, c=0): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = img + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # ------------------------------------------------------------ + # Parameter Setting + METHODS = {0: gaussian_fitting, 1: poly_fitting, 2: edge_centroid, + 3: zero_crossing, 4: edge_converge_base, 5: edge_converge_extreme} + edge_method = METHODS[m] + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + # ------------------------------------------------------------ + # Gathering Data + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + if m < 3: + ec_x = edge_method(data_x, FM(img, FM.HOR, nr), p) + else: + ec_x = edge_method(data_x) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, ec_x)) + + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + if m < 3: + ec_y = edge_method(data_y, FM(img, FM.VER, nc), p) + else: + ec_y = edge_method(data_y) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, ec_y)) + len_hs = len(hs) + len_vs = len(vs) + # ------------------------------------------------------------ + # --------------- PRE-CHECK DATA VALUES ---------------------- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + x_valid = False + y_valid = False + # OUTLIER DETECTION TODO: OPTIMIZE, THIS IS NAIVE + if len_hs >= r_thresh: + x_valid = True + hys, hxs = reg_pre_debias(hys, hxs) + line_a = HoughLine(x=hxs, data=hys) + if len_vs >= c_thresh: + y_valid = True + vxs, vys = reg_pre_debias(vxs, vys) + line_b = HoughLine(x=vxs, data=vys) + # ------------------------------------------------------------ + # ----- Following Modules Handles Hough Line Drawing --------- + # ------------------------------------------------------------ + # DATA RECORDING AND PROCESSING + if c == 1: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + else: + if x_valid and y_valid: + center_x, center_y = HoughLine.intersect(line_a, line_b) + else: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + # --------------------------------------------------------- + return center_x, center_y + + +def expr2(series): + folder = '../calib5/' + ns = 'img_{0}.png' + ins = folder + 'img_{0}.png' + repertoire = [] + i = 0 + while i < len(series): + try: + ambi, laser = cv2.imread(ins.format(series[i]), 0), cv2.imread(ins.format(series[i+1]), 0) + res = image_diff(laser, ambi) + except: + print(ins.format(series[i])) + repertoire.append(center_detect_invar(res, visual=True, folder_path=folder, img_name=ns.format(series[i+1]))) + i+= 2 + for i, ct in enumerate(repertoire): + print((series[2*i], series[2*i+1]), ct) + CALIB_VAL = 118.6 + print(repertoire) + i = 0 + while i < len(repertoire): + dx, dy = (np.array(repertoire[i+1]) - np.array(repertoire[i])) / CALIB_VAL + print((series[2*i], series[2*i+1], series[2*i+2], series[2*i+3]), dx, dy) + i+=2 + + +def convergence_test_final(folder, ns): + offset = '../' + convergence = {} + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ls = range(5) + fwrite = open('meas/convergence_rob.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + loss_types = ['huber', 'soft_l1', 'arctan', 'linear', 'cauchy'] + for l in loss_types: + cwriter.writerow([l]) + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + # print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + #x, y = center_detect(fpath + imgfile, 5, m=m) TODO: RESOLVE THE CHANGE + x, y = center_detect(fpath, imgfile.format(1), l=l) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + #x, y = center_detect(fpath + imgfile, 5, m=m) TODO: RESOLVE THE CHANGE + x, y = center_detect(fpath, imgfile.format(1), l=l) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + msepv = sqrt(pv / pvs) + cvg = {'PicConsistency': msepv} + convergence[l] = cvg + variations.append(msepv) + print(convergence) + fwrite.close() + plt.figure(figsize=(20, 10)) + plt.style.use(['seaborn-dark', 'seaborn-paper']) + plt.subplot(111) + plt.plot(ls, variations, color='#FA5B3D', marker='o', markeredgewidth=1, linestyle='-', linewidth=2) + plt.xticks(ls, loss_types) + plt.ylabel('deviations(+/-px)') + plt.xlabel('loss functions') + plt.title('Convergence By Loss Function Rho') + plt.show() + +if __name__ == '__main__': + #print(center_detect('../calib4/img_59_{0}.png', 5)) + #convergence_test_final('calib4/', 'img_{0}') + repertoire = expr2([10, 11, 15, 14, 18, 19, 22, 23]) + """skewed = '../skewed/' + bright = '../bright/' + imgn = 'img_{0}_1.png' + #center_detect('../calib4/', 'img_113_1.png', visual=True) + for i in range(90, 96): + ns = imgn.format(i) + print(skewed + ns) + print(center_detect(skewed, ns, visual=True)) + + ns = imgn.format(81) + print(bright + ns) + try: + print(center_detect(bright, ns, visual=True)) + except: + print('NON IDEE') + + for i in range(193, 195): + ns = imgn.format(i) + print(bright + ns) + try: + print(center_detect(bright, ns, visual=True)) + except: + print('NON IDEE')""" + + + + + diff --git a/img_rec_module/sig_proc_test.py b/img_rec_module/sig_proc_test.py new file mode 100644 index 0000000..b73fd88 --- /dev/null +++ b/img_rec_module/sig_proc_test.py @@ -0,0 +1,2830 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from scipy.optimize import curve_fit +from mpl_toolkits.mplot3d import Axes3D +#from img_rec_module import img_rec +from random import randint +import os +import csv +from datetime import datetime +from math import atan, sqrt, tan, radians, acos, asin, degrees, sin, cos + + +""" =================================== +========== ANALYTIC GEOMETRY ========== +======================================= """ + + +class Line: + + inf = float('inf') + + def __init__(self, a=inf, b=inf, p1=None, p2=None, data=None): + if p1 and p2: + self.point(p1, p2) + elif data: + self.reg(data) + else: + self.a = a + self.b = b + + def reg(self, data): + D = np.array([[d[0], 1] for d in data]) + y = np.array([d[1] for d in data]) + self.a, self.b = leastSquares(D, y) + + def point(self, p1, p2): + self.a = 1 + + @staticmethod + def intersect(l1, l2): + x = (l2.b - l1.b) / (l1.a - l2.a) + y = l1.a * x + l1.b + return x, y + + +class HoughLine: + + def __init__(self, rho_rad=0, theta=0, x=None, data=None): + if data is not None and x is not None: + self.reg(x, data) + else: + self._r = degrees(rho_rad) + self._t = theta + self._s = sin(rho_rad) + self._c = cos(rho_rad) + + def reg(self, x, data): + """D = hough_data_matrix(x, data) + print(D) + y = np.zeros(len(data)) + cosine, sine, self._r = leastSquares(D, y) + self._t = angle_interp(sine, cosine) + self._s = sine + self._c = cosine""" + x1, x2 = x[0], x[-1] + y1, y2 = data[0], data[-1] + theta0 = theta_pred(x1, y1, x2, y2) + #print(degrees(theta0)) + p0 = [theta0, x1 * cos(theta0) + y1 * sin(theta0)] + pm, vm = curve_fit(hough_line, x, data, p0=p0) + #data_pred = hough_line(x, *pm) + #print('PRED', data_pred) + #res = data_pred - data + #print("RES", res) + #stderr = np.linalg.norm(res, 2) + #print("ERR", stderr) + #rankerr = res / stderr + #print("Z", rankerr) + """if pm[1] < 0: + pm[1] = -pm[1] + pm[0] -= HC + #pm[0] = 2 * np.pi""" + angle = normalize_angle(pm[0]) + self._t = angle + self._r = pm[1] + self._s = sin(angle) + self._c = cos(angle) + + def extract_points(self, x_input): + x1 = int(x_input[0]) + x2 = int(x_input[-1]) + y1 = int(self.fit_x(x1)) + y2 = int(self.fit_x(x2)) + return (x1, y1), (x2, y2) + + def fit_x(self, x): + #print(self._r, self._t) + return (self._r - x * self._c) / self._s + + def __str__(self): + return 'hough line with cos:{0}, sin:{1}, rho:{2}, theta:{3}'.format(self._c, self._s, + self._r, degrees(self._t)) + + @staticmethod + def intersect(l1, l2): + x = (l2._r / l2._s - l1._r / l1._s) / (l2._c / l2._s - l1._c / l1._s) + y = l1.fit_x(x) + return x, y + + +# QC: QUARTER_CYCLE, HC: HALF_CYCLE, TQC: THIRD_QUARTER_CYCLE, FC: FULL_CYCLE +QC = np.pi / 2 +HC = np.pi +TQC = 3 * np.pi / 2 +FC = 2 * np.pi + + +def angle_interp(s, c): + if c == 1.0: + return 0 + elif s == 1.0: + return np.pi / 2 + elif c == -1.0: + return np.pi + elif s == -1.0: + return np.pi * 3 / 2 + elif c < 0 < s: + return acos(c) + elif s < 0 and c < 0: + return 2 * np.pi - acos(c) + elif s < 0 < c: + return asin(s) + 2 * np.pi + else: + return asin(s) + + +def normalize_angle(angle): + res = angle - (angle // FC) * FC + return res + """ + if QC < res < HC: + return res + HC + elif HC <= res <= TQC: + return res - HC + else: + return res""" + + +def theta_pred(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + angle = sin_angle_from_points(dx, dy) + if dx * dy <= 0: + return np.pi / 2 - angle + else: + root = root_finding(x1, x2, y1, y2) + if root < 0: + return np.pi / 2 + angle + else: + return angle + 3 * np.pi / 2 + + +def sin_angle_from_points(dx, dy): + return asin(abs(dy) / sqrt(dx ** 2 + dy ** 2)) + + +def poly_curve(params, x_input): + # params contains the coefficients that multiply the polynomial terms, in degree of lowest degree to highest degree + degree = len(params) - 1 + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = x * 0 + + for k in range(0, degree + 1): + coeff = params[k] + y = y + list(map(lambda z: coeff * z ** k, x)) + return x, y + + +def gauss_2d(x, y, a, b1, c_s1, b2, c_s2): + return a * np.exp(- ((x - b1) ** 2 / (2 * c_s1) + (y - b2) ** 2) / (2 * c_s2)) + + +def gauss_hat(x, a, b, c_s): + return a * np.exp(- (x - b) ** 2 / (2 * c_s)) + + +def gaussian_curve(x_input, a, b, c_s): + x_range = [x_input[1], x_input[-1]] + x = np.linspace(x_range[0], x_range[1], 1000) + y = a * np.exp(- (x - b) ** 2 / (2 * c_s)) + return x, y + + +def hough_line(x, theta, rho): + return (rho - x * cos(theta)) / sin(theta) + + +""" =================================== +========== MATRIX-ARRAY UTIL ========== +======================================= """ + + +class FastDataMatrix2D: + # TODO: HANDLE THE CASE WHEN IT WRAPS 1D + + HOR = 1 + VER = 0 + + def __init__(self, data, ax, index): + self._data = data + self._ax = ax + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, + self._ax, index) + self._index = index + self.itr = 0 + self.initialize() + + def segmentize(self, start, end): + assert 0 <= start < end <= self._data.shape[self._ax], "start: {0}, end: {1}, ax: {2}, index: {3}".format(start, end, self._ax, self._index) + self.start = start + self.end = end + + def initialize(self): + self.segmentize(0, self._data.shape[self._ax]) + + def irange(self): + # index range of the fast matrix array + return self._data.shape[1 - self._ax] + + def set_axis(self, ax): + """USE copy when trying to switch axis and index""" + self._ax = ax + if self._index >= self.irange(): + raise IndexError("Old index {0} is too large for the new axis".format(self._index)) + self.initialize() + + def set_index(self, index): + assert 0 <= index < self.irange(), "start: {0}, end: {1}, ax: {2}, index: {3}".format(self.start, self.end, self._ax, index) + self._index = index + + def extract_array(self): + """Optimize later for better performance""" + arr = self._data[self._index, self.start:self.end] if self._ax == FastDataMatrix2D.HOR \ + else self._data[self.start:self.end, self._index] + return np.array(arr) + + def copy(self, ax=None, index=None): + if ax is not None and index is not None: + return FastDataMatrix2D(self._data, ax, index) + else: + return FastDataMatrix2D(self._data, self._ax, self._index) + + def __iter__(self): + raise RuntimeError("You need the ITER method!") + + def __next__(self): + raise RuntimeError("You need the NEXT method!") + + def __getitem__(self, item): + return self._data[self._index, item + self.start] if self._ax == FastDataMatrix2D.HOR \ + else self._data[item + self.start, self._index] + + def __setitem__(self, key, value): + if self._ax == FastDataMatrix2D.HOR: + self._data[self._index, key + self.start] = value + else: + self._data[key + self.start, self._index] = value + + def __len__(self): + return self.end - self.start + + +""" =================================== +=========== REGRESSION UTILS ========== +======================================= """ + + +# Generic Regression Tools 128-133 +def leastSquares(D, y): + return np.linalg.lstsq(D, y, rcond=None)[0] + + +def MSE(y, y_hat, N): + return np.linalg.norm(y - y_hat) ** 2 / N + + +def std_dev(data): + std_dev = 0 + len_data = len(data) + mean = sum(data) / len_data + for i in range(len_data): + std_dev += (data[i] - mean) ** 2 + return sqrt(std_dev / len_data) + + +def reg_pre_debias(ind, data): + sd = np.std(data) + miu = np.mean(data) + debiased_data = [] + debiased_ind = [] + for i in range(len(data)): + dev = abs((data[i] - miu) / sd) + if dev < 2: + debiased_data.append(data[i]) + debiased_ind.append(ind[i]) + return debiased_ind, debiased_data + + +# Polynomial Regression Tools 137-171 +def poly_data_matrix(input_data, degree): + # degree is the degree of the polynomial you plan to fit the data with + Data = np.zeros((len(input_data), degree + 1)) + + for k in range(0, degree + 1): + Data[:, k] = (list(map(lambda x: x ** k, input_data))) + + return Data + + +def poly_error(params, D_a, y_a): + '''degree=len(params)-1 + y=x_a*0 + + for k in range(0,degree+1): + coeff=params[k] + y=y+list(map(lambda z:coeff*z**k,x_a))''' + y = np.dot(D_a, params) + return np.linalg.norm(y - y_a) ** 2 + + +def improvedCost(x, y, x_test, y_test, start, end): + """Given a set of x and y points training points, + this function calculates polynomial approximations of varying + degrees from start to end. Then it returns the cost, with + the polynomial tested on test points of each degree in an array""" + c = [] + degrees = range(start, end) + ps = [] + for degree in degrees: + # YOUR CODE HERE + D = poly_data_matrix(x, degree) + p = leastSquares(D, y) + ps.append(p) + D_t = poly_data_matrix(x_test, degree) + y_hat = np.dot(D_t, p) + c.append(MSE(y_test, y_hat, len(x_test))) + return np.array(degrees), ps, np.array(c) + + +# Gaussian Regression Tools 184-210 +def gauss_data_matrix(data): + return np.array([[1, x ** 2, x, 1] for x in data]) + + +def gauss_reg(x, y, p0): + """Given a set of x and y training points, this function + calculates the gaussian approximation function""" + """skip_x = np.array([x[i] for i in range(len(y)) if y[i] != 0]) + y_prime = np.array([y[i] for i in range(len(y)) if y[i] != 0]) + logy = np.log(y_prime) + + sol = leastSquares(gauss_data_matrix(skip_x), logy) + alp, bet, gam, lam = sol + a = np.e ** alp + c_s = - 1 / (2 * bet) + b = gam * c_s + maxi, mini = max_min(y) + pred = gauss_hat(maxi, a, b, c_s) + real = y[maxi] + a = real / pred // 1000000000 * 10""" + #timeb = datetime.now() + param, vm = curve_fit(gauss_hat, x, y, p0=p0) + #timea = datetime.now() + #print(timea - timeb) + return param + + +def gauss_mat(shape, a, b1, c_s1, b2, c_s2): + mat = np.zeros(shape) + for r in range(mat.shape[0]): + for c in range(mat.shape[1]): + mat[r, c] = gauss_2d(c, r, a, b1, c_s1, b2, c_s2) + + return mat + + +# Hough Transform Regression Tools +def hough_data_matrix(x, y): + dim = len(x) + mat = np.full((dim, 3), -1.0) + for i in range(dim): + mat[i][0] = x[i] + mat[i][1] = y[i] + return mat + + +""" ======================================= +========= EDGE DETECTION UTILS ============ +=========================================== """ +# TODO: CHANGED!!! + + +# Generic Helper +def max_min(data): + # Returns the maximum and minimum for the data + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + return max_ind, min_ind + + +def edge_max_min(data): + # Returns a *safe* edge maxi, mini for the data + # TODO: OPTIMIZE THE WIDTH AND VALUE THRESHOLD + # TODO: MADE CHANGES, BUT THE WIDTH CHECK NEEDS TO BE OPTIMIZED + width_thres = 90 + value_thres = 20 + maxi = data[0] + max_ind = 0 + mini = data[0] + min_ind = 0 + for i in range(1, len(data)): + target = data[i] + if target > maxi: + maxi = target + max_ind = i + if target < mini: + mini = target + min_ind = i + maxi, mini = max_ind, min_ind + assert data[maxi] >= value_thres and mini - maxi <= width_thres + return maxi, mini + + +def min_max(data, max, min): + """ Converts the data to min max space. """ + g_diff = max - min + return [(d - min) / g_diff for d in data] + + +def zscore_calc(data): + # Takes in a numpy + data_len = len(data) + if type(data) != np.ndarray: + sd = std_dev(data) + mn = sum(data) / data_len + else: + sd = np.std(data) + mn = np.mean(data) + res = np.empty(data_len, dtype=type(data[0])) + for i in range(data_len): + res[i] = (data[i] - mn) / sd + return res + + +def root_finding(x1, x2, y1, y2): + """Given two points on a line, finds its zero crossing root.""" + return - y1 * (x2 - x1) / (y2 - y1) + x1 + + +def check_cross(a, b): + # Checks whether two points are of opposite signs + return a * b < 0 + + +def round_up(num): + down = int(num) + if num - down > 0: + return num + 1 + else: + return num + + +def max_seg(data, start, end): + # returns the maxima index from start to end in data + cursor = start + 1 + maxi_ind = start + maxi = data[start] + while cursor < end: + target = data[cursor] + if target > maxi: + maxi_ind = cursor + maxi = target + cursor += 1 + return maxi_ind + + +def smart_interval(start, end, data): + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + return start, end + + +def edge_preprocess(data, padding): + maxi, mini = edge_max_min(data) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end, maxi, mini + + +def edge_preprocess_new(data, padding): + beam_found = False + while not beam_found: + maxi, mini = edge_max_min(data) + seg_max_ind = max_seg(data, maxi, mini) + start, end = smart_interval(maxi - padding, mini + padding + 1, data) + return start, end, maxi, mini + + +# ZERO CROSSING (PEAK FINDING) +def zero_crossing(data): + # Yields the center with zero-crossing method + maxi, mini = max_min(data) + cross = -1 + cross_count = 0 + for j in range(maxi, mini): + y1 = data[j] + x2 = j + 1 + y2 = data[x2] + if check_cross(y1, y2): + cross = root_finding(j, x2, y1, y2) # change to function later + cross_count += 1 + return -1 if cross_count > 1 else cross + + +# AVERAGE METHOD FOR EDGE CENTER FINDING +def edge_converge_base(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + else: + return (maxi + mini) / 2 + + +# PSEUDO EDGE (closest noise gradient change) CENTER FINDING +def edge_converge_extreme(data): + maxi, mini = max_min(data) + width_thres = 70 + if mini - maxi > width_thres: + return -1 + emax = -1 + emin = -1 + maxflag = True + minflag = True + cmax = maxi + cmin = mini + while cmax > 0 and cmin < len(data) - 1 and (maxflag or minflag): + max2 = cmax - 1 + maxy1, maxy2 = data[cmax], data[max2] + min2 = cmin + 1 + miny1, miny2 = data[cmin], data[min2] + if check_cross(maxy1, maxy2) and maxflag: + emax = root_finding(cmax, max2, maxy1, maxy2) + maxflag = False + if check_cross(miny1, miny2) and minflag: + emin = root_finding(cmin, min2, miny1, miny2) + minflag = False + if maxflag: + cmax -= 1 + if minflag: + cmin += 1 + return -1 if (emax == -1 or emin == -1) else (emax + emin) / 2 + + +def extract_extrema(data): + len_data = len(data) + mean = sum(data) / len_data + std_dev = 0 + for x in data: + std_dev += (x - mean) ** 2 + std_dev = sqrt(std_dev / len_data) + signifmax = [] + signifmin = [] + coeff = 3 + for i, x in enumerate(data): + diff = (x - mean) / std_dev + if diff >= coeff: + signifmax.append(i) + elif diff <= -coeff: + signifmin.append(i) + return signifmax, signifmin + + +# CENTROID METHOD FOR EDGE CENTER FINDING +def edge_centroid(data, img_data, padding=10): + # With Gaussian Blur might achieve the best performance + try: + start, end, maxi, mini = edge_preprocess(data, padding) + except AssertionError: + return -1 + isums = 0 + total = 0 + for i in range(start, end): + isums += img_data[i] * i + total += img_data[i] + return isums / total if total else -1 + + +def centroid_seg(data, start, end): + """ Given a segment (start, end) of the data, + find the centroid. """ + isums = 0 + total = 0 + start = 0 if start < 0 else start + end = len(data) if end > len(data) else end + for i in range(start, end): + isums += data[i] * i + total += data[i] + return isums / total if total else -1 + + +# POLYNOMIAL FITTING +def poly_fitting(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + try: + start, end, maxi, mini = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + y = np.array(img_data[start:end]) + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + curve_x, curve_y = poly_curve(param, x) + center_id = np.argmax(curve_y) + return curve_x[center_id] + + +def poly_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING AND THE EXTRACT_ARRAY + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + 1 + start, end = smart_interval(start, end, data) + if start > end: + try: + print(maxi, mini, img_data._ax, start, end) + except: + print("else", maxi, mini, start, end) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + y = img_data.extract_array() + else: + y = np.array(img_data[start:end]) + degrees, params, cost = improvedCost(x, y, x, y, 1, 7) + ind = np.argmin(cost) + degree = degrees[ind] + param = params[ind] + degree_register(degree) + return param, x + + +DEGREES = {} + + +def degree_register(elem): + if elem in DEGREES: + DEGREES[elem] += 1 + else: + DEGREES[elem] = 1 + + +# GAUSSIAN FITTING +def gaussian_fitting(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + try: + start, end, maxi, mini = edge_preprocess(data, padding) + except AssertionError: + return -1 + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.array(img_data[start:end]) + try: + param = gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]) + except RuntimeError: + return -1 + return param[1] + + +def gaussian_fitting_params(data, img_data, padding=10): + # TODO: OPTIMIZE THE AWKWARD TYPE CHECKING, ALONG WITH THE WIDTH THRESHOLD + maxi, mini = max_min(data) + width_thres = 90 + value_thres = 20 # TODO: CONSOLIDATE THIS VALUE + if data[maxi] < value_thres or mini - maxi > width_thres: + print(data[maxi], mini, maxi) + raise AssertionError("Bad column or row") + start = maxi - padding + end = mini + padding + start, end = smart_interval(start, end, data) + x = np.array(range(start, end)) + if type(img_data) == FastDataMatrix2D: + img_data.segmentize(start, end) + idata = img_data.extract_array() + else: + idata = np.array(img_data[start:end]) + return gauss_reg(x, idata, p0=[10, (maxi + mini) / 2, std_dev(idata)]), x +"""========================================SIG_PROC HAS ABOVE======================================================""" + + +"""====================================== +======== IMAGE PROCESSING UTIL ========== +========================================= """ + + +def gradient_calc(img, ks=-1): + # TODO: This Function IS ADDED, MOVE TO SIGPROC + if len(img.shape) == 3: + img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + dimr, dimc = img.shape + gradient = np.empty((dimr, dimc), dtype=np.float64) + for i in range(dimr): + for j in range(dimc): + gradient[i, j] = sqrt(sobelx.item(i, j) ** 2 + sobely.item(i, j) ** 2) + return sobelx, sobely, gradient + + +def gauss_bg_deduce(x, img_data): + # TODO: OPTIMIZE PERFORMANCE + idata = img_data.extract_array() + p0 = [1, len(img_data) / 2, std_dev(idata)] + try: + a, b, c_s = gauss_reg(x, idata, p0=p0) + except RuntimeError: + return x, np.zeros(len(img_data)), idata + rem_gauss = gauss_hat(x, a, b, c_s) + new_y = idata - rem_gauss + return x, rem_gauss, new_y + + +def fourier_trans(img): + f = np.fft.fft2(img) + fshift = np.fft.fftshift(f) + magnitude_spectrum = 20 * np.log(np.abs(fshift)) + return f, fshift, magnitude_spectrum + + +def data_masked(data, ratio_lr, ratio_lc, ratio_ur, ratio_uc): + row, col = data.shape + #pad_q = (1 - ratio) / 2 + #pad_r = int(pad_q * row) + #pad_c = int(pad_q * col) + lr = int(ratio_lr * row) + ur = row - int(ratio_ur * row) + lc = int(ratio_lc * col) + uc = col - int(ratio_uc * col) + mask = np.zeros_like(data) + mask[lr:ur] = 1 + mask[lc:uc] = 1 + return data * mask + + +def sobel_process(imgr, gks, sig): + gksize = (gks, gks) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(imgr.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + return img, sobelx, sobely + + +def test_canny_detect(): + imgn = "img_89_{0}.png" + IMGDIR = "../calib4/" + NAME = IMGDIR + imgn + + while True: + lowp = input("Type the Lower Bound or c to cancel: ") + if lowp == 'c': + break + while True: + try: + low = int(lowp) + break + except ValueError: + lowp = input("Bad input Try again! ") + highp = input("Type the Upper Bound or c to cancel: ") + if highp == 'c': + break + while True: + try: + high = int(highp) + break + except ValueError: + highp = input("Bad input Try again! ") + + denoised, original = test_noise_reduce(NAME) + print(get_center_val(denoised)) + NL_denoised = cv2.fastNlMeansDenoising(original) + bdenoise = test_blur_then_nr(NAME) + + dblur, sobelx, sobely = sobel_process(denoised, 9, 0) + nldblur = sobel_process(NL_denoised, 9, 0)[0] + pblur, sobelx, sobely = sobel_process(original, 9, 0) + + de_edges = canny_detect(denoised, low, high) + db_edges = canny_detect(dblur, low, high) + nld_edges = canny_detect(nldblur, low, high) + blur_denoise = canny_detect(bdenoise, low, high) + blur_edges = canny_detect(pblur, low, high) + #edge_detect_expr(db_edges, original) + """compare_images((imgr, 'Original'), (edges, 'Canny Edge'), + (sobelx, 'Sobel X'), (sobely, 'Sobel Y'))""" + compare_images((original, 'Original'), (NL_denoised, "NLMEANS"), (de_edges, 'DENOISE Edges'), + (blur_edges, 'Plain Blur Edges'), (denoised, 'Denoised'), (nld_edges, 'NIDE-BLUR Edges'), + (db_edges, 'DE-BLUR Edges'), (blur_denoise, "BDENOISE Edges"), color_map='gray') + + +def canny_detect(src, low=4, high=10): + return cv2.Canny(np.uint8(src), 4, 10, L2gradient=True) + + +def extract_verge(edges, i, j, max_blank, dir, axis): + """ + :param edges: img MAT resulting from canny edge procedure + :param i: starting row i + :param j: starting col j + :param max_blank: maximum number of blanks to rule out the existence of a verge outside of the current verge (in which case would be a fake verge) + :param dir: Directions of movement, 1 for right or down, -1 for left or up + :param axis: + :return: (r, c) index of the verge on the given 'axis' in the given 'dir' from the starting point (i, j) + """ + + +def significance_test(data, val): + """Outputs whether the maximum or minimum value is a significant value.""" + return val in extract_extrema(data)[0] or val in extract_extrema(data)[1] + + +def fourier_expr(): + while True: + root = input("type the image directory you wanna test in: ") + number = input("type the picture number u wanna test or c to cancel: ") + ratio_lrp = input("type in a lower row masking ratio: ") + ratio_urp = input("type in a upper row masking ratio: ") + ratio_lcp = input("type in a lower column masking ratio: ") + ratio_ucp = input("type in a upper column masking ratio: ") + + if number == 'c': + break + try: + imgn = "img_%d_{0}" % int(number) + ratio_lr = float(ratio_lrp) + ratio_ur = float(ratio_urp) + ratio_lc = float(ratio_lcp) + ratio_uc = float(ratio_ucp) + except ValueError as e: + print("Bad name or ratio format! ") + continue + print(imgn) + IMGDIR = "../{0}/".format(root) + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS + IMGDIR[3:] + imgn + "/" + num_img = 3 if root == 'testpic' else 1 + try: + imgr, ori = test_noise_reduce(IMGDIR + imgn + ".png", numIMG=num_img) + except AttributeError as e: + print(e.args) + continue + dimc = imgr.shape[1] + dimr = imgr.shape[0] + sig = 0 + gk = 9 + + # ----------------- Preliminary IMG_PROCESSING --------------------- + # INITIALIZATION + gksize = (gk, gk) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + img = imgr + + # IMAGE PROCESSING + sobelx, sobely, gradient = gradient_calc(img, ks=-1) + f_r, fshift_r, magnitude_r = fourier_trans(img) + f_r_mask = data_masked(f_r, ratio_lr, ratio_lc, ratio_ur, ratio_uc) + inv_r_mask = np.abs(np.fft.ifft2(f_r_mask)) + f_b, fshift_b, magnitude_b = fourier_trans(blur) + f_b_mask = data_masked(f_b, ratio_lr, ratio_lc, ratio_ur, ratio_uc) + inv_b_mask = np.abs(np.fft.ifft2(f_b_mask)) + sobelx_r_fm, sobely_r_fm, gradient_r_fm = gradient_calc(inv_r_mask, ks=-1) + sobelx_b_fm, sobely_b_fm, gradient_b_fm = gradient_calc(inv_b_mask, ks=-1) + f = np.fft.fft2(img) + compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), (gradient, 'Raw Gradient'), + (20 * np.log(np.abs(f_r)), 'Fourier Original'), (20 * np.log(np.abs(fshift_r)), 'FShift Original'), + (magnitude_r, 'Mag Original'), (inv_r_mask, 'FourierR Inverse'), (img, 'original'), + (sobelx_r_fm, 'SobelX Original Fourier'), (sobely_r_fm, 'SobelY Original Fourier'), + (gradient_r_fm, 'Fourier Original Gradient'), + (sobelx_b_fm, 'SobelX Blur Fourier'), (sobely_b_fm, 'SobelY Blur Fourier'), + (gradient_b_fm, 'Fourier Blur Gradient'), + color_map='gray', suptitle=IMGDIR+imgn[:-4]) + + + +def edge_detect_expr(edges, original): + """ + TODO: 1. SIMPLE Approach: pairwise mask over original image, then compute total + 2. Traverse the image to mark the image. + """ + se = 0 + row_sum = 0 + col_sum = 0 + tot_sum = 0 + for i in range(edges.shape[0]): + for j in range(edges.shape[1]): + if edges[i][j] > 0: + row_sum += i * original[i][j] + col_sum += j * original[i][j] + tot_sum += original[i][j] + se += 1 + print(se) + if tot_sum != 0: + print(row_sum / tot_sum) + print(col_sum / tot_sum) + + +def hori(img, i, j, d): + dest = j + d + if dest < 0 or dest >= img.shape[1]: + return img.item(i, j) + return img.item(i, dest) + + +def verti(img, i, j, d): + dest = i + d + if dest < 0 or dest >= img.shape[0]: + return img.item(i, j) + return img.item(dest, j) + + +def test_blur_then_nr(iname): + imgs = iname + numIMG = 5 + imgr = None + for i in range(1, numIMG + 1): + target = cv2.imread(imgs.format(i), 0) + target = cv2.GaussianBlur(target, (9, 9), 0) + if i == 1: + imgr = np.uint16(target) + else: + imgr = imgr + target + return imgr / numIMG + + +def get_center_val(img): + return img.item(img.shape[0] // 2, img.shape[1] // 2) + + +def test_noise_reduce(iname, numIMG=5): + imgs = iname + imgr = None + original = None + for i in range(1, numIMG+1): + target = cv2.imread(imgs.format(i), 0) + if target is None: + raise AttributeError("File {0} not found".format(iname)) + if i == 1: + imgr = np.uint16(target) + original = target + else: + imgr = imgr + target + return imgr / numIMG, original + + +def img_add(dest, src): + """Destructive!""" + row, col = dest.shape + for i in range(row): + for j in range(col): + dest[i][j] += src[i][j] + + +""" =================================== + ============ PLOTTING ============= + ============= HELPER ============== + =================================== """ + + +def quick_plot(data, xs=None): + plt.figure() + if xs: + plt.plot(xs, data, 'bo-') + else: + plt.plot(data, 'bo-') + plt.show() + plt.close() + + +def compare_images(*args, ilist=None, color_map=None, suptitle=None): + # Takes in a sequence of IMG(Gray) and TITLE pairs and plot them side by side + if ilist: + args = ilist + graph_amount = len(args) + row = int(sqrt(graph_amount)) + col = round_up(float(graph_amount) / row) + plt.figure(figsize=(16, 8)) + if suptitle: + plt.suptitle(suptitle, fontsize=14) + for i, pair in enumerate(args): + plt.subplot(row, col, i+1) + if color_map: + plt.imshow(pair[0], cmap=color_map) + else: + plt.imshow(pair[0]) + plt.xticks([]), plt.yticks([]) + plt.title(pair[1]) + plt.show() + plt.close() + + +def compare_data_plots(*args, ilist=None, suptitle=None, symbol='b-'): + # Takes in a sequence of tuples with data, xs, and title pairs + if ilist: + args = ilist + graph_amount = len(args) + row = int(sqrt(graph_amount)) + col = round_up(float(graph_amount) / row) + plt.figure(figsize=(16, 8)) + if suptitle: + plt.suptitle(suptitle, fontsize=14) + for i, pair in enumerate(args): + plt.subplot(row, col, i + 1) + if len(pair) == 2: + plt.plot(pair[0], symbol) + plt.title(pair[1]) + else: + plt.plot(pair[1], pair[0], symbol) + plt.title(pair[2]) + plt.show() + + +def line_graph_contrast(img, xs, ys): + line = HoughLine(x=xs, data=ys) + #print(xs) + x0 = line._c * line._r + y0 = line._s * line._r + + print('x0:{0}, y0:{1}, cos:{2}, sin:{3}, rho:{4}, theta:{5}'.format(x0, y0, line._c, line._s, line._r, degrees(line._t))) + x1 = int(x0 + 1000 * (-line._s)) + y1 = int(y0 + 1000 * (line._c)) + x2 = int(x0 - 1000 * (-line._s)) + y2 = int(y0 - 1000 * (line._c)) + p1, p2 = (x1, y1), (x2, y2) + cv2.line(img, p1, p2, (255, 0, 0), 1) + return p1, p2, line + + +def plot_img(img, cmap='coolwarm'): + img = cv2.convertScaleAbs(img) + r, c = img.shape + rs = np.arange(0, r) + cs = np.arange(0, c) + xs, ys = np.meshgrid(cs, rs) + + fig = plt.figure() + ax = fig.gca(projection='3d') + surf = ax.plot_surface(xs, ys, img, cmap=cmap, linewidth=0, antialiased=False) + fig.colorbar(surf, shrink=0.5, aspect=5) + plt.show() + plt.close() + + +# 1. Try Noise Reduction: +# ---- 1.1 Reduction By Averaging, without FastNIMEANS ~~ GOOD +# ---- 1.2 Reduction By FastNIMEANS ~~ INFERIOR +# ---- 1.3 Reduction By Combination ~~ INFERIOR +# ---- 1 NOTE: USE PLOTTING OF ORIGINAL GRAPH TO SEE RESULT +# 2. Try Di-Axial Scharr Kernel +# ---- 2.1 Add To Name Scheme, record graphs and compare them +# ---- 2 NOTE: GRAPH TO SAVE: 4-CONTRAST, TRANSITION PLOTS +# 3. Optimizing Data Processing: +# ---- 3.1 Marking point as edge maxima and minima according to STD Dev values +# ---- 3.2 Taking Sequential Samples +# ---- 3.3 Explore Thresholding Techniques + + +def register(img): + lval = [] + for i in range(img.shape[0]): + for j in range(img.shape[1]): + if img.item(i, j) > 250: + lval.append((i, j, img.item(i, j))) + print(lval) + + +""" TEST GAUSSIAN BLUR'S influence on noise distribution: + Method: + 1. Preliminary + 1. Generate a random noise matrix with n * n, change shape to a vector + 2. Gaussian blur applied, change shape to a vector + 3. Compare noise level + 2. Secondary + 1. Generate a Gaussian / Cosine Matrix and add random noise matrix + 2. Gaussian blur applied + 3. Compare a randomly selected row of each one +""" + +IMGDIRALL = {'bright/': (5, [193, 194]), 'calib/': (5, [1, 2, 3] + list(range(28, 34))), + 'calib2/': (5, range(32, 46)), 'calib3/': (5, range(16, 60)), 'calib4/': (5, range(59, 193)), + 'testpic/': (3, range(1, 26)), 'new_test/': (5, range(1, 6)), 'skewed/': (5, range(90, 96))} + +def test_old(): + # SETTINGS + imgn = "img_193_{0}" + + IMGDIR = "../bright/" + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS + IMGDIR[3:] + imgn + "/" + #imgr = cv2.imread(IMGDIR + imgn + ".png") + imgr, ori = test_noise_reduce(IMGDIR + imgn + ".png", 5) + dimc = imgr.shape[1] + dimr = imgr.shape[0] + r_int = dimr // 2 + c_int = 450 #dimc // 2 + start = 7 + end = 10 + sig = 0 + ins = range(start, end, 2) + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + # INITIALIZATION + cenvalsx = [] + cenvalsy = [] + edgvalsx = [] + edgvalsy = [] + ebvalsx = [] + ebvalsy = [] + ecvalsx = [] + ecvalsy = [] + ecbvalsx = [] + ecbvalsy = [] + #cv2.imshow("denoised", np.uint8(imgr)) # REMOVES TO SHOW IMAGE + x = np.array(range(dimc)) + x2 = np.array(range(dimr)) + + for i in ins: + # INITIALIZATION + gksize = (i, i) + sigmaX = sig + blur = cv2.GaussianBlur(imgr,gksize,sigmaX) + #cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + """kernel = np.array([[-1, -1, -1], + [-1, 8, -1], + [-1, -1, -1]]) + kerneled = cv2.filter2D(img, -1, kernel) + cv2.imshow("kerneled", kerneled)""" # KERNEL EXPERIMENT + #laplacian = cv2.Laplacian(img,cv2.CV_64F) # LAPLACIAN FILTERING + """plt.subplot(2,2,1),plt.imshow(cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY),cmap = 'gray') + plt.title('Original'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,2),plt.imshow(img,cmap = 'gray') + plt.title('Gaussian Filter'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') + plt.title('Scharr X'), plt.xticks([]), plt.yticks([]) + plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') + plt.title('Scharr Y'), plt.xticks([]), plt.yticks([])""" + #plt.savefig(NAME_HEADER + "filters.png") + #plt.savefig(NAME_HEADER + "2D_filters.png") + #plt.close() # REMOVES TO SHOW CONTRAST OF FILTERS + + + # DETECTION INIT + gk_setting = "ksize:{0}, sigmax:{1}".format(gksize, sigmaX) + y_s_x = np.array([sobelx.item(r_int, c) for c in x]) + y_s_y = np.array([sobely.item(r, c_int) for r in x2]) + imgx = [imgr.item(r_int, c) for c in x] + imgy = [imgr.item(r, c_int) for r in x2] + blurimgx = [img.item(r_int, c) for c in x] + blurimgy = [img.item(r, c_int) for r in x2] + print(gk_setting) + print(extract_extrema(y_s_x)) + print(extract_extrema(y_s_y)) + fwrite.write(gk_setting) + fwrite.write('\n') + + # EDGE DETECTION + zx = zero_crossing(y_s_x) + cenvalsx.append(zx) + ex = edge_converge_extreme(y_s_x) + edgvalsx.append(ex) + ebx = edge_converge_base(y_s_x) + ebvalsx.append(ebx) + ecx = edge_centroid(y_s_x, imgx) + ecvalsx.append(ecx) + ecbx = edge_centroid(y_s_x, blurimgx) + ecbvalsx.append(ecbx) + + zy = zero_crossing(y_s_y) + cenvalsy.append(zy) + ey = edge_converge_extreme(y_s_y) + edgvalsy.append(ey) + eby = edge_converge_base(y_s_y) + ebvalsy.append(eby) + ecy = edge_centroid(y_s_y, imgy) + ecvalsy.append(ecy) + ecby = edge_centroid(y_s_y, blurimgy) + ecbvalsy.append(ecby) + + # DATA RECORDING + fwrite.write("x: zero_crossing: {0}, edge_converge: {1}; ".format(zx, ex)) + fwrite.write('\n') + fwrite.write("y: zero_crossing: {0}, edge_converge: {1}\n".format(zy, ey)) + + # GK_PLOT + """if i == 9: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + #plt.savefig(NAME_HEADER + "_" + gk_setting + ".png")""" + + #if i >= 13: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + plt.show() + # plt.savefig(NAME_HEADER + "_" + gk_setting + ".png") # UNCOMMENT WHEN SAVING PLOTS + + # USING MIN-MAX + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(221) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(222) + plt.plot(min_max(y_s_x, max(y_s_x), min(y_s_x)), 'b-') + plt.subplot(223) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + plt.xlabel("Plain") + plt.subplot(224) + plt.plot(min_max(y_s_y, max(y_s_y), min(y_s_y)), 'b-') + plt.xlabel("MINMAX") + plt.show() + + + fig = plt.figure(figsize=(16, 8)) + plt.subplot(2, 1, 1) + #plt.plot(ins, cenvalsx, 'b-', ins, edgvalsx, 'r-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + #plt.legend(['zero crossing', 'edge_converging_extreme', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + #plt.plot(ins, cenvalsx, 'b-', ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + #plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'],loc="lower left") + plt.plot(ins, ebvalsx, 'g-', ins, ecvalsx, 'c-', ins, ecbvalsx, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'],loc="lower left") + plt.ylabel("x_meas") + plt.subplot(2, 1, 2) + #plt.plot(ins, cenvalsy, 'b-', ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + #plt.legend(['zero crossing', 'edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.plot(ins, ebvalsy, 'g-', ins, ecvalsy, 'c-', ins, ecbvalsy, 'm-') + plt.legend(['edge_converging_base', 'edge_centroid', 'edge_centroid_blurred'], loc="lower left") + plt.ylabel("y_meas") + plt.xlabel("kernel size") + plt.show() + #fig.savefig(plot_save) + #plt.savefig(plot_save) + + +def test_interactive(): + # TODO: TEST OUT FACET MODEL AND CONDITIONAL CONVOLUTIONAL KERNEL + # SETTINGS + while True: + number = input("type the picture number u wanna test or c to cancel: ") + if number == 'c': + break + imgn = "img_%d_{0}" % int(number) + print(imgn) + IMGDIR = "../calib4/" + #IMGDIR = "../skewed/" + ROOTMEAS = "meas/" + SAVEDIR =ROOTMEAS + IMGDIR[3:] + imgn + "/" + #SAVEDIR = ROOTMEAS + imgn + "/" + # imgr = cv2.imread(IMGDIR + imgn + ".png") + num_img = 3 if ROOTMEAS == 'testpic' else 5 + imgr, ori = test_noise_reduce(IMGDIR + imgn + ".png", numIMG=num_img) + dimc = imgr.shape[1] + dimr = imgr.shape[0] + sig = 0 + gk = 9 + + # ----------------- Preliminary IMG_PROCESSING --------------------- + # INITIALIZATION + gksize = (gk, gk) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # IMAGE PROCESSING + sobelx, sobely, gradient = gradient_calc(img, ks=-1) + f_r, fshift_r, magnitude_r = fourier_trans(imgr) + f_r_mask = data_masked(f_r, 0, 0, 0.9, 0.9) + inv_r_mask = np.abs(np.fft.ifft2(f_r_mask)) + sobelx_r_fm, sobely_r_fm, gradient_r_fm = gradient_calc(inv_r_mask, ks=-1) + compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), (gradient, 'Raw Gradient'), (magnitude_r, 'Mag Original'), + (sobelx_r_fm, 'SobelX Fourier', (sobely_r_fm, 'SobelY Fourier'), (gradient_r_fm, 'Gradient Fourier')), + color_map='gray', suptitle=IMGDIR+imgn[:-4]) + #img, sobelx, sobely, gradient = inv_r_mask, sobelx_r_fm, sobely_r_fm, gradient_r_fm + plot_img(img) + plot_img(gradient) + + # --------------------- INTERACTIVE SESSION ----------------------- + while True: + r_prompt = input("Type in the index for horizontal slice or c to cancel: (range: [0, {0}]) ".format(dimr - 1)) #dimr // 2 + if r_prompt == 'c': + break + c_prompt = input("Type in the index for vertical slice: (range: [0, {0}]) ".format(dimc - 1)) #dimc // 2 + while True: + try: + r_int = int(r_prompt) + assert 0 <= r_int < dimr + break + except ValueError: + r_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + except AssertionError: + r_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimr - 1)) + while True: + try: + c_int = int(c_prompt) + assert 0 <= c_int < dimc + break + except ValueError: + c_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + except AssertionError: + c_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + + # ---------------- DATA RECORDING ----------------- + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + # DETECTION INIT + xh = np.array(range(dimc)) + xv = np.array(range(dimr)) + zeroh = np.zeros(dimc) + zerov = np.zeros(dimr) + y_s_x = FM(sobelx, FM.HOR, r_int) + y_s_y = FM(sobely, FM.VER, c_int) + ysx_t = y_s_x.extract_array() + ysy_t = y_s_y.extract_array() + zscorex = zscore_calc(ysx_t) + zscorey = zscore_calc(ysy_t) + imgx = FM(imgr, FM.HOR, r_int) + imgy = FM(imgr, FM.VER, c_int) + blurimgx = FM(img, FM.HOR, r_int) + blurimgy = FM(img, FM.VER, c_int) + gx, bgx, deducedx = gauss_bg_deduce(xh, imgx) + gy, bgy, deducedy = gauss_bg_deduce(xv, imgy) + minmax_xsobel = min_max(ysx_t, max(ysx_t), min(ysx_t)) + minmax_ysobel = min_max(ysy_t, max(ysy_t), min(ysy_t)) + sdevx = np.std(minmax_xsobel) + sdevy = np.std(minmax_ysobel) + DEV_MESSAGE = "SobelX StdDev: {0}, SobelY StdDev: {1}\n".format(sdevx, sdevy) + print(DEV_MESSAGE) + + # EDGE DETECTION + zx = zero_crossing(y_s_x) + ex = edge_converge_extreme(y_s_x) + ebx = edge_converge_base(y_s_x) + ecbx = edge_centroid(y_s_x, blurimgx) + ecx = edge_centroid(y_s_x, imgx) + try: + #paramhp, xp1 = poly_fitting_params(y_s_x, deducedx) + #paramhg, xg1 = gaussian_fitting_params(y_s_x, deducedx) + paramhp, xp1 = poly_fitting_params(y_s_x, imgx) + paramhg, xg1 = gaussian_fitting_params(y_s_x, imgx) + xp_h_plot, yp_h_plot = poly_curve(paramhp, xp1) + xg_h_plot, yg_h_plot = gaussian_curve(xg1, paramhg[0], paramhg[1], paramhg[2]) + except (AssertionError, RuntimeError): + print("No image data for horizontal slice!") + xp_h_plot, yp_h_plot = xh, zeroh + xg_h_plot, yg_h_plot = xh, zeroh + + px, gx = xp_h_plot[np.argmax(yp_h_plot)], xg_h_plot[np.argmax(yg_h_plot)] + print("edge: {0}, poly:{1}, gaussian:{2}".format(ecx, px, gx)) + + zy = zero_crossing(y_s_y) + ey = edge_converge_extreme(y_s_y) + eby = edge_converge_base(y_s_y) + ecby = edge_centroid(y_s_y, blurimgy) + ecy = edge_centroid(y_s_y, imgy) + try: + paramvp, xp2 = poly_fitting_params(y_s_y, imgy) + paramvg, xg2 = gaussian_fitting_params(y_s_y, imgy) + xp_v_plot, yp_v_plot = poly_curve(paramvp, xp2) + xg_v_plot, yg_v_plot = gaussian_curve(xg2, paramvg[0], paramvg[1], paramvg[2]) + except (AssertionError, RuntimeError): + print("No image data for vertical slice!") + xp_v_plot, yp_v_plot = xv, zerov + xg_v_plot, yg_v_plot = xv, zerov + py, gy = xp_v_plot[np.argmax(yp_v_plot)], xg_v_plot[np.argmax(yg_v_plot)] + print("edge: {0} poly:{1}, gaussian:{2}".format(ecy, py, gy)) + + + # DATA RECORDING + fwrite.write("x: edge_centroid: {0}, poly: {1}, gaussian: {2}; ".format(ecx, px, gx)) + fwrite.write('\n') + fwrite.write("y: edge_centroid: {0}, poly: {1}, gaussian: {2}\n".format(ecy, py, gy)) + fwrite.write(DEV_MESSAGE) + + # GK_PLOT + """if i == 9: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + #plt.savefig(NAME_HEADER + "_" + gk_setting + ".png")""" + + imgx.initialize() + imgy.initialize() + imgxarr = imgx.extract_array() + imgyarr = imgy.extract_array() + indic_up_x = np.full(len(imgxarr), 1) + indic_down_x = np.full(len(imgxarr), -1) + indic_up_y = np.full(len(imgyarr), 1) + indic_down_y = np.full(len(imgyarr), -1) + # if i >= 13: + fig = plt.figure(figsize=(16, 8)) + plt.subplot(611) + #plt.plot(min_max(ysx_t, max(ysx_t), min(ysx_t)), 'b-') + plt.plot(xh, ysx_t, 'b-') + plt.ylabel("sobel_x") + plt.subplot(612) + plt.plot(xh, zscore_calc(imgxarr), 'b-', xh, zscorex, 'c-', xh, indic_up_x, 'r:', xh, indic_down_x, 'r:') + plt.ylabel("zscoresX") + plt.legend(['zscoreIMGX', 'zscoreSobelX'], loc="upper right") + plt.subplot(613) + plt.plot(xh, imgxarr, 'b-', xh, bgx, 'm-', xh, deducedx, 'c-', xp_h_plot, yp_h_plot, 'g-', + xg_h_plot, yg_h_plot, 'r-') + plt.ylabel("Horizontal Slice, ECX: {0}".format(ecx)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.subplot(614) + #plt.plot(min_max(ysy_t, max(ysy_t), min(ysy_t)), 'b-') + plt.plot(xv, ysy_t, 'b-') + plt.ylabel("sobel_y") + plt.subplot(615) + plt.plot(xv, zscore_calc(imgyarr), 'b-', xv, zscorey, 'c-', xv, indic_up_y, 'r:', xv, indic_down_y, 'r:') + plt.ylabel("zscoresY") + plt.legend(['zscoreIMGY', 'zscoreSobelY'], loc="upper right") + plt.subplot(616) + plt.plot(xv, imgyarr, 'b-', xv, bgy, 'm-', xv, deducedy, 'c-', xp_v_plot, yp_v_plot, 'g-', + xg_v_plot, yg_v_plot, 'r-') + plt.ylabel("Vertical Slice, ECY: {0}".format(ecy)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.show() + fig.savefig(NAME_HEADER + "_r{0}_c{1}.png".format(r_int, c_int)) # UNCOMMENT WHEN SAVING PLOTS + + +def test_record(): + # TODO: TEST OUT FACET MODEL AND CONDITIONAL CONVOLUTIONAL KERNEL + # SETTINGS + img_ns = "img_%d_{0}" + IMGDIRS = IMGDIRALL + ROOTMEAS = "meas/" + OFFSET = '../' + rslice = range(10, 480, 50) + cslice = range(20, 640, 50) + errors = open(ROOTMEAS + 'errors.txt', 'w') + for IMGDIR, spec in IMGDIRS.items(): + IMGDIR = OFFSET + IMGDIR + numPic, img_range = spec + for img_i in img_range: + imgn = img_ns % img_i + print(imgn) + # IMGDIR = "../calib4/" + SAVEDIR = ROOTMEAS + IMGDIR[3:] + imgn + "/" + # SAVEDIR = ROOTMEAS + imgn + "/" + # imgr = cv2.imread(IMGDIR + imgn + ".png") + try: + imgr, ori = test_noise_reduce(IMGDIR + imgn + ".png", numIMG=numPic) + except AttributeError as e: + print(e.args) + continue + try: + dimc = imgr.shape[1] + dimr = imgr.shape[0] + sig = 0 + gk = 9 + + # ----------------- Preliminary IMG_PROCESSING --------------------- + # INITIALIZATION + gksize = (gk, gk) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # IMAGE PROCESSING + sobelx, sobely, gradient = gradient_calc(img, ks=-1) + #compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), (gradient, 'Raw Gradient'), color_map='gray') + #plot_img(img) + #plot_img(gradient) + + # --------------------- INTERACTIVE SESSION ----------------------- + for r_int, c_int in zip(rslice, cslice): + # ---------------- DATA RECORDING ----------------- + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + # DETECTION INIT + xh = np.array(range(dimc)) + xv = np.array(range(dimr)) + zeroh = np.zeros(dimc) + zerov = np.zeros(dimr) + y_s_x = FM(sobelx, FM.HOR, r_int) + y_s_y = FM(sobely, FM.VER, c_int) + ysx_t = y_s_x.extract_array() + ysy_t = y_s_y.extract_array() + zscorex = zscore_calc(ysx_t) + zscorey = zscore_calc(ysy_t) + imgx = FM(imgr, FM.HOR, r_int) + imgy = FM(imgr, FM.VER, c_int) + blurimgx = FM(img, FM.HOR, r_int) + blurimgy = FM(img, FM.VER, c_int) + gx, bgx, deducedx = gauss_bg_deduce(xh, imgx) + gy, bgy, deducedy = gauss_bg_deduce(xv, imgy) + minmax_xsobel = min_max(ysx_t, max(ysx_t), min(ysx_t)) + minmax_ysobel = min_max(ysy_t, max(ysy_t), min(ysy_t)) + sdevx = np.std(minmax_xsobel) + sdevy = np.std(minmax_ysobel) + DEV_MESSAGE = "SobelX StdDev: {0}, SobelY StdDev: {1}\n".format(sdevx, sdevy) + print(DEV_MESSAGE) + + # EDGE DETECTION + zx = zero_crossing(y_s_x) + ex = edge_converge_extreme(y_s_x) + ebx = edge_converge_base(y_s_x) + ecbx = edge_centroid(y_s_x, blurimgx) + ecx = edge_centroid(y_s_x, imgx) + try: + # paramhp, xp1 = poly_fitting_params(y_s_x, deducedx) + # paramhg, xg1 = gaussian_fitting_params(y_s_x, deducedx) + paramhp, xp1 = poly_fitting_params(y_s_x, imgx) + paramhg, xg1 = gaussian_fitting_params(y_s_x, imgx) + xp_h_plot, yp_h_plot = poly_curve(paramhp, xp1) + xg_h_plot, yg_h_plot = gaussian_curve(xg1, paramhg[0], paramhg[1], paramhg[2]) + except (AssertionError, RuntimeError): + print("No image data for horizontal slice!") + xp_h_plot, yp_h_plot = xh, zeroh + xg_h_plot, yg_h_plot = xh, zeroh + + px, gx = xp_h_plot[np.argmax(yp_h_plot)], xg_h_plot[np.argmax(yg_h_plot)] + print("edge: {0}, poly:{1}, gaussian:{2}".format(ecx, px, gx)) + + zy = zero_crossing(y_s_y) + ey = edge_converge_extreme(y_s_y) + eby = edge_converge_base(y_s_y) + ecby = edge_centroid(y_s_y, blurimgy) + ecy = edge_centroid(y_s_y, imgy) + try: + paramvp, xp2 = poly_fitting_params(y_s_y, imgy) + paramvg, xg2 = gaussian_fitting_params(y_s_y, imgy) + xp_v_plot, yp_v_plot = poly_curve(paramvp, xp2) + xg_v_plot, yg_v_plot = gaussian_curve(xg2, paramvg[0], paramvg[1], paramvg[2]) + except (AssertionError, RuntimeError): + print("No image data for vertical slice!") + xp_v_plot, yp_v_plot = xv, zerov + xg_v_plot, yg_v_plot = xv, zerov + py, gy = xp_v_plot[np.argmax(yp_v_plot)], xg_v_plot[np.argmax(yg_v_plot)] + print("edge: {0} poly:{1}, gaussian:{2}".format(ecy, py, gy)) + + # DATA RECORDING + fwrite.write("x: edge_centroid: {0}, poly: {1}, gaussian: {2}; ".format(ecx, px, gx)) + fwrite.write('\n') + fwrite.write("y: edge_centroid: {0}, poly: {1}, gaussian: {2}\n".format(ecy, py, gy)) + fwrite.write(DEV_MESSAGE) + + # GK_PLOT + """if i == 9: + fig = plt.figure(figsize=(16, 8)) + fig.canvas.set_window_title(gk_setting) + plt.subplot(211) + plt.plot(y_s_x, 'b-') + plt.ylabel("sobel_x") + plt.subplot(212) + plt.plot(y_s_y, 'b-') + plt.ylabel("sobel_y") + #plt.savefig(NAME_HEADER + "_" + gk_setting + ".png")""" + + imgx.initialize() + imgy.initialize() + imgxarr = imgx.extract_array() + imgyarr = imgy.extract_array() + indic_up_x = np.full(len(imgxarr), 1) + indic_down_x = np.full(len(imgxarr), -1) + indic_up_y = np.full(len(imgyarr), 1) + indic_down_y = np.full(len(imgyarr), -1) + # if i >= 13: + """ + fig = plt.figure(figsize=(16, 8)) + plt.subplot(611) + # plt.plot(min_max(ysx_t, max(ysx_t), min(ysx_t)), 'b-') + plt.plot(xh, ysx_t, 'b-') + plt.ylabel("sobel_x") + plt.subplot(612) + plt.plot(xh, zscore_calc(imgxarr), 'b-', xh, zscorex, 'c-', xh, indic_up_x, 'r:', xh, indic_down_x, 'r:') + plt.ylabel("zscoresX") + plt.legend(['zscoreIMGX', 'zscoreSobelX'], loc="upper right") + plt.subplot(613) + plt.plot(xh, imgxarr, 'b-', xh, bgx, 'm-', xh, deducedx, 'c-', xp_h_plot, yp_h_plot, 'g-', + xg_h_plot, yg_h_plot, 'r-') + plt.ylabel("Horizontal Slice, ECX: {0}".format(ecx)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], + loc="upper right") + plt.subplot(614) + # plt.plot(min_max(ysy_t, max(ysy_t), min(ysy_t)), 'b-') + plt.plot(xv, ysy_t, 'b-') + plt.ylabel("sobel_y") + plt.subplot(615) + plt.plot(xv, zscore_calc(imgyarr), 'b-', xv, zscorey, 'c-', xv, indic_up_y, 'r:', xv, indic_down_y, 'r:') + plt.ylabel("zscoresY") + plt.legend(['zscoreIMGY', 'zscoreSobelY'], loc="upper right") + plt.subplot(616) + plt.plot(xv, imgyarr, 'b-', xv, bgy, 'm-', xv, deducedy, 'c-', xp_v_plot, yp_v_plot, 'g-', + xg_v_plot, yg_v_plot, 'r-') + plt.ylabel("Vertical Slice, ECY: {0}".format(ecy)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], + loc="upper right") + #plt.show() + fig.savefig(NAME_HEADER + "_r{0}_c{1}.png".format(r_int, c_int)) # UNCOMMENT WHEN SAVING PLOTS + plt.close() + fwrite.close()""" + except TypeError as e: + message = 'ERROR in {0}: '.format(IMGDIR + imgn) + str(e.args) + '\n' + print(message) + fwrite.write(message) + fwrite.close() + errors.write(message) + continue + errors.close() + + +def test(folder, imgn): + # TODO: TEST OUT FACET MODEL AND CONDITIONAL CONVOLUTIONAL KERNEL + # SETTINGS + ROOTMEAS = "meas/" + SAVEDIR = ROOTMEAS + folder[3:] + imgn[:-4] + "/" + # imgr = cv2.imread(IMGDIR + imgn + ".png") + + imgr, ori = test_noise_reduce(folder + imgn, numIMG=5) + dimc = imgr.shape[1] + dimr = imgr.shape[0] + while True: + r_prompt = input("Type in the index for horizontal slice or c to cancel: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + c_prompt = input("Type in the index for vertical slice: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + if r_prompt == 'c': + break + while True: + try: + r_int = int(r_prompt) + assert 0 <= r_int < dimr + break + except ValueError: + r_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimr - 1)) # dimr // 2 + except AssertionError: + r_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimr - 1)) + while True: + try: + c_int = int(c_prompt) + assert 0 <= c_int < dimc + break + except ValueError: + c_prompt = input("Bad Input, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + except AssertionError: + c_prompt = input("Out of Bound, try again: (range: [0, {0}]) ".format(dimc - 1)) # dimc // 2 + # start = 7 + # end = 10 + sig = 0 + gk = 9 + name_scheme = imgn + ("_({0}, {1})").format(r_int, c_int) + NAME_HEADER = SAVEDIR + name_scheme + if not os.path.exists(SAVEDIR): + os.mkdir(SAVEDIR) + fwrite = open(NAME_HEADER + ".txt", "w") + plot_save = NAME_HEADER + ".png" + + # INITIALIZATION + # cv2.imshow("denoised", np.uint8(imgr)) # REMOVES TO SHOW IMAGE + # x = np.array(range(dimc)) + # x2 = np.array(range(dimr)) + + # INITIALIZATION + gksize = (gk, gk) + sigmaX = sig + blur = cv2.GaussianBlur(imgr, gksize, sigmaX) + # cv2.imshow("blurred", blur) # REMOVES TO SHOW BLURRED IMAGE + if len(blur.shape) == 3: + img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) + else: + img = blur + + # GAUSSIAN PROCESSING # UNCOMMENT TO SHOW GAUSSIAN PROCESSING + """x = np.array(range(dimc)) + #y = np.array([img_rec.rel_lumin(img, 0, c) for c in x]) + y = np.array([img.item(dimr // 2, c) for c in x]) + a1, b1, c_s1 = gauss_reg(x, y) + + x2 = np.array(range(dimr)) + y2 = np.array([img.item(r, dimc // 2) for r in x2]) + a2, b2, c_s2 = gauss_reg(x2, y2) + rem_gauss = gauss_mat(img.shape, (a1+a2) / 2, b1, c_s1, b2, c_s2) + img = img - rem_gauss + cv2.imshow("denoise", img) + y_hat = gauss_hat(x, a1, b1, c_s1) + plt.figure(figsize=(16, 8)) + plt.plot(x, y, 'b-', x, y_hat, 'r-') + plt.show() + plt.close() + plt.figure(figsize=(16,8)) + plt.plot(x, y-y_hat, 'b-') + plt.show()""" + + # IMAGE PROCESSING + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + + + # DETECTION INIT + xh = np.array(range(dimc)) + xv = np.array(range(dimr)) + zeroh = np.zeros(dimc) + zerov = np.zeros(dimr) + y_s_x = FM(sobelx, FM.HOR, r_int) + y_s_y = FM(sobely, FM.VER, c_int) + imgx = FM(imgr, FM.HOR, r_int) + imgy = FM(imgr, FM.VER, c_int) + blurimgx = FM(img, FM.HOR, r_int) + blurimgy = FM(img, FM.VER, c_int) + gx, bgx, deducedx = gauss_bg_deduce(xh, imgx) + gy, bgy, deducedy = gauss_bg_deduce(xv, imgy) + # print(extract_extrema(y_s_x)) + # print(extract_extrema(y_s_y)) + # EDGE DETECTION + ecx = edge_centroid(y_s_x, imgx) + try: + # paramhp, xp1 = poly_fitting_params(y_s_x, deducedx) + # paramhg, xg1 = gaussian_fitting_params(y_s_x, deducedx) + paramhp, xp1 = poly_fitting_params(y_s_x, imgx) + paramhg, xg1 = gaussian_fitting_params(y_s_x, imgx) + xp_h_plot, yp_h_plot = poly_curve(paramhp, xp1) + xg_h_plot, yg_h_plot = gaussian_curve(xg1, paramhg[0], paramhg[1], paramhg[2]) + except AssertionError: + print("No image data for horizontal slice!") + xp_h_plot, yp_h_plot = xh, zeroh + xg_h_plot, yg_h_plot = xh, zeroh + except RuntimeError: + print("No image data for horizontal slice!") + xp_h_plot, yp_h_plot = xh, zeroh + xg_h_plot, yg_h_plot = xh, zeroh + + px, gx = xp_h_plot[np.argmax(yp_h_plot)], xg_h_plot[np.argmax(yg_h_plot)] + print("edge: {0}, poly:{1}, gaussian:{2}".format(ecx, px, gx)) + + ecy = edge_centroid(y_s_y, imgy) + try: + paramvp, xp2 = poly_fitting_params(y_s_y, imgy) + paramvg, xg2 = gaussian_fitting_params(y_s_y, imgy) + xp_v_plot, yp_v_plot = poly_curve(paramvp, xp2) + xg_v_plot, yg_v_plot = gaussian_curve(xg2, paramvg[0], paramvg[1], paramvg[2]) + except AssertionError: + print("No image data for vertical slice!") + xp_v_plot, yp_v_plot = xv, zerov + xg_v_plot, yg_v_plot = xv, zerov + except RuntimeError: + print("No image data for vertical slice!") + xp_v_plot, yp_v_plot = xv, zerov + xg_v_plot, yg_v_plot = xv, zerov + py, gy = xp_v_plot[np.argmax(yp_v_plot)], xg_v_plot[np.argmax(yg_v_plot)] + print("edge: {0} poly:{1}, gaussian:{2}".format(ecy, py, gy)) + + # DATA RECORDING + fwrite.write("x: edge_centroid: {0}, poly: {1}, gaussian: {2}; ".format(ecx, px, gx)) + fwrite.write('\n') + fwrite.write("y: edge_centroid: {0}, poly: {1}, gaussian: {2}\n".format(ecy, py, gy)) + + # if i >= 13: + fig = plt.figure(figsize=(16, 8)) + plt.subplot(411) + plt.plot(y_s_x.extract_array(), 'b-') + plt.ylabel("sobel_x") + plt.subplot(412) + imgx.initialize() + plt.plot(xh, imgx.extract_array(), 'b-', xh, bgx, 'm-', xh, deducedx, 'c-', xp_h_plot, yp_h_plot, 'g-', + xg_h_plot, yg_h_plot, 'r-') + plt.ylabel("Horizontal Slice, ECX: {0}".format(ecx)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.subplot(413) + plt.plot(y_s_y.extract_array(), 'b-') + plt.ylabel("sobel_y") + plt.subplot(414) + imgy.initialize() + plt.plot(xv, imgy.extract_array(), 'b-', xv, bgy, 'm-', xv, deducedy, 'c-', xp_v_plot, yp_v_plot, 'g-', + xg_v_plot, yg_v_plot, 'r-') + plt.ylabel("Vertical Slice, ECY: {0}".format(ecy)) + plt.legend(['Raw image data', 'gaussian background', 'remnant', 'polynomial', 'gaussian'], loc="upper right") + plt.show() + # plt.savefig(NAME_HEADER + "_" + gk_setting + ".png") # UNCOMMENT WHEN SAVING PLOTS + + +FM = FastDataMatrix2D + + +def folder_to_imgs(img_name_scheme, num_sample): + """This function takes img files and return cv imgs""" + return [cv2.imread(img_name_scheme.format(i)) for i in range(1, num_sample+1)] + + +def center_detect_old(img_name_scheme, num_sample, sample_int=50): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair""" + imgs = folder_to_imgs(img_name_scheme, num_sample) + num_imgs = len(imgs) + dimr = imgs[0].shape[0] + dimc = imgs[0].shape[1] + xnum_imgs = num_imgs + ynum_imgs = num_imgs + xsum = 0 + ysum = 0 + zw = 0 + ew = 1 + gk = 9 + count = 1 + for imgr in imgs: + if count == num_sample: + imgshow = imgr + count += 1 + #print(imgr.shape) + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1) + # Gathering Data + nr = sample_int + r_thresh = dimr * 2.0 / (sample_int * 3) + xs = [] + xdummies = [] + ys = [] + ydummies = [] + while nr < dimr: + data_x = sobelx[nr, :] + zc_x = zero_crossing(data_x) + print("row:", nr) + ed_x = edge_centroid(data_x, FM(img, FM.HOR, nr)) + print("At {0}: {1}".format(nr, ed_x)) + nr += sample_int + xdummies.append(zc_x * zw + ed_x * ew) + if zc_x == -1: + continue + else: + xs.append(zc_x * zw + ed_x * ew) + nc = sample_int + c_thresh = dimc * 2.0 / (sample_int * 3) + while nc < dimc: + data_y = sobely[:, nc] + zc_y = zero_crossing(data_y) + ed_y = edge_centroid(data_y, FM(img, FM.VER, nc)) + nc += sample_int + ydummies.append(zc_y * zw + ed_y * ew) + if zc_y == -1: + continue + else: + ys.append(zc_y * zw + ed_y * ew) + #print("x") + #print(xdummies) + #print(xs) + #print("y") + #print(ydummies) + #print(ys) + len_xs = len(xs) + len_ys = len(ys) + print("img {0}: {1}".format(count - 1, xs)) + if len_xs < r_thresh: + xnum_imgs -= 1 + else: + xsum += sum(xs) / len(xs) + if len_ys < c_thresh: + ynum_imgs -= 1 + else: + ysum += sum(ys) / len(ys) + + plt.show() + + center_x = -1 if xnum_imgs == 0 else xsum / xnum_imgs + center_y = -1 if ynum_imgs == 0 else ysum / ynum_imgs + return center_x, center_y + +# The image taken is flipped horizontally, result x should be img.shape[1] - x +# The image sometimes has two peaks, try experimenting with different gaussian kernels + + +def center_detect_test(folder_path, img_name_scheme, num_sample, sample_int=50, debug=False, gk=9, ks=-1, m=0, p=20, b=1, c=0, hough=True): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(folder_path + img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + #sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + #sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + sobelx, sobely, gradient = gradient_calc(img, ks) + # ------------------------------------------------------------ + # Parameter Setting + METHODS = {0: gaussian_fitting, 1: poly_fitting, 2: edge_centroid, + 3: zero_crossing, 4: edge_converge_base, 5: edge_converge_extreme} + edge_method = METHODS[m] + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + # ------------------------------------------------------------ + # Gathering Data + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + if m < 3: + ec_x = edge_method(data_x, FM(img, FM.HOR, nr), p) + else: + ec_x = edge_method(data_x) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, ec_x)) + + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + if m < 3: + ec_y = edge_method(data_y, FM(img, FM.VER, nc), p) + else: + ec_y = edge_method(data_y) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, ec_y)) + len_hs = len(hs) + len_vs = len(vs) + # --------------- PRE-CHECK DATA VALUES ---------------------- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + x_valid = False + y_valid = False + stdh = -1 + stdv = -1 + #valuesH = [d[1] for d in hs] + #valuesV = [d[1] for d in vs] + if len_hs >= r_thresh: + x_valid = True + stdh = std_dev(hxs) + if len_vs >= c_thresh: + y_valid = True + stdv = std_dev(vys) + #hough_img = img_name_scheme.format(1) + + # OUTLIER DETECTION TODO: OPTIMIZE, THIS IS NAIVE + if x_valid: # NAIVE + hys, hxs = reg_pre_debias(hys, hxs) + if y_valid: + vxs, vys = reg_pre_debias(vxs, vys) + # --------------------------------------------------------- + # ----- Following Modules Handles Hough Line Drawing --------- + if hough: + hough_img = folder_path + img_name_scheme.format(1) + print(hough_img) + img_h = cv2.imread(hough_img) + if len_hs: + hp1, hp2, line_a = line_graph_contrast(img_h, hxs, hys) + print('Drawn H') + if len_vs: + vp1, vp2, line_b = line_graph_contrast(img_h, vxs, vys) + print('Drawn V') + namespace = 'houghs/hough_{0}{1}_{2}'.format(folder_path[3:], m, img_name_scheme.format(1)) + if len_hs: + print(hp1, hp2) + if len_vs: + print(vp1, vp2) + print(namespace) + cv2.imwrite(namespace, img_h) + else: + #print("MEAS", hys) + line_a = HoughLine(x=hxs, data=hys) + #print("MEAS", vys) + line_b = HoughLine(x=vxs, data=vys) + # ------------------------------------------------------------ + # DEBUG MODULE + if debug: + print((dimr, dimc)) + print("imgX(BEFORE):", hs) + print("imgX:", list(zip(hys, hxs))) + print("imgY(BEFORE):", vs) + print("imgY:", list(zip(vxs, vys))) + compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), color_map='gray') + test(folder_path, img_name_scheme) + # -------------------------------------------------------- + # DATA RECORDING AND PROCESSING + if len_hs >= r_thresh: + x_valid = True + stdh = std_dev(hxs) + if len_vs >= c_thresh: + y_valid = True + stdv = std_dev(vys) + if c == 1: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + else: + if x_valid and y_valid: + center_x, center_y = HoughLine.intersect(line_a, line_b) + else: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + # --------------------------------------------------------- + return center_x, center_y, stdh, stdv + + +def center_detect(img_name_scheme, num_sample, sample_int=50, debug=False, gk=9, ks=-1, m=1, p=10, b=1): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + zw = 0 + ew = 1 + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # Gathering Data + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + zc_x = zero_crossing(data_x) + ec_x = edge_centroid(data_x, FM(img, FM.HOR, nr)) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, zc_x * zw + ec_x * ew)) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + zc_y = zero_crossing(data_y) + ec_y = edge_centroid(data_y, FM(img, FM.VER, nc)) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, zc_y * zw + ec_y * ew)) + len_hs = len(hs) + len_vs = len(vs) + if debug: + print((dimr, dimc)) + print("imgX:", hs) + print("imgY:", vs) + compare_images((sobelx, 'Sobel X'), (sobely, 'Sobel Y'), color_map='gray') + while True: + ax = input("Input the axis you wanna debug, h for horizontal, v for vertical, or c to cancel: ") + if ax == 'c': + break + inds = input("Input the index you wanna debug: ") + while True: + try: + index = int(inds) + axis = FM.HOR if ax == 'h' else FM.VER + assert 0 <= index < imgr.shape[1 - axis] + break + except ValueError: + inds = input("Invalid input, do it again: ") + except AssertionError: + inds = input("Index Out of Bound, do it again: {0} ".format(imgr.shape)) + sobelop = sobelx if axis else sobely + quick_plot(FM(sobelop, axis, index).extract_array()) + + # ----- Following Modules Handles Hough Line Drawing ----- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + + hough_img = img_name_scheme.format(1) + img_h = cv2.imread(hough_img) + if len_hs: + hp1, hp2, lina = line_graph_contrast(img_h, hxs, hys) + print('Drawn H') + if len_vs: + vp1, vp2, linb = line_graph_contrast(img_h, vxs, vys) + print('Drawn V') + namespace = 'houghs/hough_{0}'.format(hough_img[3:]) + if len_hs: + print(hp1, hp2) + if len_vs: + print(vp1, vp2) + print(namespace) + cv2.imwrite(namespace, img_h) + # -------------------------------------------------------- + x_invalid = False + y_invalid = False + if len_hs < r_thresh: + x_invalid = True + if len_vs < c_thresh: + y_invalid = True + + center_x = -1 if x_invalid else sum([d[1] for d in hs]) / len_hs + center_y = -1 if y_invalid else sum([d[1] for d in vs]) / len_vs + return center_x, center_y + + +def center_detect(img_name_scheme, num_sample, sample_int=50, gk=9, ks=-1, m=0, p=20, + b=1, c=0): + """This function takes in a list of images and output x, y [pixel] coordinates of the center of the cross hair + hs: HORIZONTAL SLICE! vs: VERTICAL SLICE!""" + imgr = test_noise_reduce(img_name_scheme, num_sample)[0] + dimr = imgr.shape[0] + dimc = imgr.shape[1] + # Image Processing + gksize = (gk, gk) + sigmaX = 0 + img = cv2.GaussianBlur(imgr, gksize, sigmaX) + sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=ks) + sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=ks) + # ------------------------------------------------------------ + # Parameter Setting + METHODS = {0: gaussian_fitting, 1: poly_fitting, 2: edge_centroid, + 3: zero_crossing, 4: edge_converge_base, 5: edge_converge_extreme} + edge_method = METHODS[m] + nr = sample_int + r_thresh = dimr / (sample_int * 3.0) + nc = sample_int + c_thresh = dimc / (sample_int * 3.0) + # ------------------------------------------------------------ + # Gathering Data + hs = [] + vs = [] + while nr < dimr: + data_x = FM(sobelx, FM.HOR, nr) + if m < 3: + ec_x = edge_method(data_x, FM(img, FM.HOR, nr), p) + else: + ec_x = edge_method(data_x) + nr += sample_int + if ec_x == -1: + continue + else: + hs.append((nr - sample_int, ec_x)) + + while nc < dimc: + data_y = FM(sobely, FM.VER, nc) + if m < 3: + ec_y = edge_method(data_y, FM(img, FM.VER, nc), p) + else: + ec_y = edge_method(data_y) + nc += sample_int + if ec_y == -1: + continue + else: + vs.append((nc - sample_int, ec_y)) + len_hs = len(hs) + len_vs = len(vs) + # ------------------------------------------------------------ + # --------------- PRE-CHECK DATA VALUES ---------------------- + hxs = np.zeros(len_hs) + hys = np.zeros(len_hs) + for i in range(len_hs): + hxs[i] = hs[i][1] + hys[i] = hs[i][0] + vxs = np.zeros(len_vs) + vys = np.zeros(len_vs) + for i in range(len_vs): + vxs[i] = vs[i][0] + vys[i] = vs[i][1] + x_valid = False + y_valid = False + # OUTLIER DETECTION TODO: OPTIMIZE, THIS IS NAIVE + if len_hs >= r_thresh: + x_valid = True + hys, hxs = reg_pre_debias(hys, hxs) + line_a = HoughLine(x=hxs, data=hys) + if len_vs >= c_thresh: + y_valid = True + vxs, vys = reg_pre_debias(vxs, vys) + line_b = HoughLine(x=vxs, data=vys) + # ------------------------------------------------------------ + # ----- Following Modules Handles Hough Line Drawing --------- + # ------------------------------------------------------------ + # DATA RECORDING AND PROCESSING + if c == 1: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + else: + if x_valid and y_valid: + center_x, center_y = HoughLine.intersect(line_a, line_b) + else: + center_x = sum(hxs) / len_hs if x_valid else -1 + center_y = sum(vys) / len_vs if y_valid else -1 + # --------------------------------------------------------- + return center_x, center_y + + + +def random_test(): + data = [27, 21, 22, 21, 21, 18, 41, 69, 83, 62, 38, 16, 21, 20, 18, 17] + print(len(data)) + ids = 0 + gs = 0 + for i, d in enumerate(data): + if d == 83: + print(i) + ids += i * d + gs += d + print(ids / gs) + + +TEST_PIC_TRUTH = [(385, 130), + (385, 130), + (385, 130), + (-2, -2), + (176, 52), + (174, -1), + (158, -1), + (159, -1), + (242, 212), + (278, 215), + (325, 218), + (143, 215), + (53, 219), + (-1, 17), + (138, 19), + (355, 14), + (288, -1), + (369, 180), + (357, 265), + (225, 224), + (-1, 195), + (-1, 59), + (-1, -1), + (-1, 160), + (445, 166)] + + +def read_truth(filename): + with open(filename) as truth: + TRUTH = {} + active = None + for line in truth: + meas = line.replace(',', ' ').split() + if len(meas) == 0: + pass + elif len(meas) == 1: + active = {} + TRUTH[meas[0]] = active + + else: + tp = (int(meas[1]), int(meas[2])) + active[meas[0]] = tp + return TRUTH + + +def error_calc(meas, truth): + E = 0 + T = 0 + F = 0 + terms = 0 + #ls = ['img_5', 'img_6', 'img_7', 'img_12', 'img_13', 'img_14', 'img_15', 'img_16', 'img_17', 'img_18', 'img_20', 'img_21', 'img_22', 'img_25'] + #ms = [] + #es = [] + for m, vals in meas.items(): + """if m in ls: + continue""" + mx, my = vals + tx, ty = truth[m] + if tx == -2 or ty == -2: + pass + elif (mx == -1 and tx != -1) or (my == -1 and ty != -1): + F += 1 + #ms.append(m) + elif (mx != -1 and tx == -1) or (my != -1 and ty == -1): + T += 1 + else: + dx = mx - tx + dy = my - ty + E += (dx) ** 2 + (dy) ** 2 + #es.append((dx, dy)) + terms += 2 + # print(ms) + # print(es) + error = sqrt(E / terms) if terms else float('inf') + return {'E': error, 'T': T, 'F': F} + + +TRUTH_FILE = "meas/truth.txt" +TRUTH = read_truth(TRUTH_FILE) + + +""" ================================= +============= Parameter ============= +=========== Optimization ============ +===================================== """ + + +# TODO: OPTIMIZE ON THE THE GAUSSIAN KERNEL PARAMETER. WHAT HAPPENED THAT MAKES THE SMALL KERNEL BETTER??? +def gaussian_kernel_expr(folder, ns): + offset = '../' + truth_doc = TRUTH[folder] + error = {} + gs = range(1, 20, 2) + Es = [] + Ts = [] + Fs = [] + for g in gs: + meas = {} + #print(g) + for i in range(1, 26): + img_name = ns.format(i) + imgfile = offset + folder + "/%s_{0}.png" % img_name + # if i in [11, 13, 21, 23, 25]: + if i == 0: + val = center_detect(imgfile, 3, debug=True, gk=g) + else: + val = center_detect(imgfile, 3, gk=g) + #print(str(i), val) + meas[img_name] = val + # print(str(i), val) + + ed = error_calc(meas, truth_doc) + Es.append(ed['E']) + Ts.append(ed['T']) + Fs.append(ed['F']) + error[g] = ed + print(error) + compare_data_plots((Es, gs, 'Error'), (Ts, gs, 'False Positive'), (Fs, gs, 'False Negative'), suptitle="Gaussian Blur Test") + + +def sobel_kernel_expr(folder, ns): + offset = '../' + truth_doc = TRUTH[folder] + error = {} + #ks = [-1] + #ks.extend(list(range(3, 8, 2))) + ks = range(-1, 8, 2) + Es = [] + Ts = [] + Fs = [] + for k in ks: + # print(k) + meas = {} + for i in range(1, 26): + img_name = ns.format(i) + imgfile = offset + folder + "/%s_{0}.png" % img_name + # if i in [11, 13, 21, 23, 25]: + if i == 0: + val = center_detect(imgfile, 3, debug=True, ks=k) + else: + val = center_detect(imgfile, 3, ks=k) + #print(str(i), val) + meas[img_name] = val + # print(str(i), val) + + ed = error_calc(meas, truth_doc) + Es.append(ed['E']) + Ts.append(ed['T']) + Fs.append(ed['F']) + error[k] = ed + print(error) + compare_data_plots((Es, ks, 'Error'), (Ts, ks, 'False Positive'), (Fs, ks, 'False Negative'), suptitle="Sobel Kernel Test") + + +def convergence_test(folder, ns): + offset = '../' + convergence = {} + line_stdh = [] + line_stdv = [] + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence_v1.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Convergence + lrh = 0 + lrhs = 0 + lrv = 0 + lrvs = 0 + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + #print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y, stdh, stdv = center_detect_test(fpath, imgfile, 5, debug=False, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y), str(stdh), str(stdv)]) + # CONVERGENCE + if x != -1: + lrh += stdh ** 2 + lrhs += 1 + if y != -1: + lrv += stdv ** 2 + lrvs += 1 + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y, stdh, stdv = center_detect_test(fpath, imgfile, 5, debug=False, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y), str(stdh), str(stdv)]) + # CONVERGENCE + if x != -1: + lrh += stdh ** 2 + lrhs += 1 + if y != -1: + lrv += stdv ** 2 + lrvs += 1 + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + mselrh = sqrt(lrh / lrhs) + mselrv = sqrt(lrv / lrvs) + msepv = sqrt(pv / pvs) + cvg = {'LineConvergenceH': mselrh if lrhs else float('inf'), + 'LineConvergenceV': mselrv if lrvs else float('inf'), + 'PicConsistency': msepv} + convergence[m] = cvg + line_stdh.append(mselrh) + line_stdv.append(mselrv) + variations.append(msepv) + print(convergence) + compare_data_plots((line_stdh, ms, 'Line Convergence Hor'), (line_stdv, ms, 'Line Convergence Ver'), + (variations, ms, 'Reading Consistency'), suptitle="Convergence/Consistency Test") + fwrite.close() + + +def convergence_test_final(folder, ns): + offset = '../' + convergence = {} + variations = [] + startNP = 59 + startP = 80 + endP = 193 + ms = range(3) + fwrite = open('meas/convergence_v1.csv', 'w') + cwriter = csv.writer(fwrite) + cwriter.writerow(['Image Number', 'Center X', 'Center Y', 'StdDev Horizontal', 'Std Dev Vertical']) + for m in ms: + cwriter.writerow([str(m)]) + # Consistency Cycled + pv = 0 + pvs = 0 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + # print(g) + for i in range(startNP, startP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + for i in range(startP, endP): + img_name = ns.format(i) + fpath = offset + folder + imgfile = "%s_{0}.png" % img_name + # FOR NULL ROW OR COLUMN, DO NOT COUNT THE STDDEV + try: + x, y = center_detect(fpath + imgfile, 5, m=m) + # PUT IN CSV + cwriter.writerow([str(i), str(x), str(y)]) + # CONVERGENCE + # Record x, y, check rcount, refresh CONSISTENCY + cvx[rcount] = x + cvy[rcount] = y + rcount += 1 + if rcount == 4: + pv += np.var(cvx) + np.var(cvy) + pvs += 1 + rcount = 0 + cvx = np.zeros(4) + cvy = np.zeros(4) + except AttributeError: + print('No {0}'.format(fpath + imgfile)) + pass + # print(str(i), val) + msepv = sqrt(pv / pvs) + cvg = {'PicConsistency': msepv} + convergence[m] = cvg + variations.append(msepv) + print(convergence) + fwrite.close() +"""""" + + +def parameter_convert(method, padding, blur): + return method + 2 * padding + blur * 100 + + +def main(): + # TODO: HANDLE THE MAXI MINI LEFT AND RIGHT PROBLEM (2 PEAKS) + folder = "../calib4/" + img_name = "img_59_{0}.jpg" + ns = "img_%d_{0}.png" + # print("Center Detection yields: ") + # gaussian_kernel_expr('testpic', 'img_{0}') + #sobel_kernel_expr('testpic', 'img_{0}') + convergence_test('calib4/', 'img_{0}') + """for i in range(59, 193): + #if i in [29]: + try: + if i in [133, 134, 157, 158, 159, 160]: + print(i) + val = center_detect_test(folder, ns % i, 5, debug=True, hough=False) + print(str(i), val) + #val = center_detect_test(folder, ns % i, 5, hough=False) + #print(str(i), val) + except AttributeError: + print('No image {0}!'.format(i)) + print('------------------------------------------------------')""" + # convergence_test_final('calib4/', 'img_{0}') + + +def case_calc(): + hori_lower = 53.50 - 0.13 + hori_upper = 53.50 + 0.13 + verti_lower = 41.41 - 0.11 + verti_upper = 41.41 + 0.11 + height = 3 + width = 4 + print('hori_lower: {0}'.format(distance(width / 2, hori_lower / 2))) + print('hori_upper: {0}'.format(distance(width / 2, hori_upper / 2))) + print('verti_lower: {0}'.format(distance(height / 2, verti_lower / 2))) + print('verti_upper: {0}'.format(distance(height / 2, verti_upper / 2))) + + +def distance(h, angle): + return 2.54 * (h / tan(radians(angle))) + + +def deviation(): + serr = 1.017 + p_to_i = 1 / 166.1861 + fluc = serr * p_to_i + dev = 2 * fluc + print(fluc, dev) + mm_per_inch = 25.4 + mfluc, mdev = mm_per_inch * fluc, mm_per_inch * dev + print(mfluc, mdev) + + #print(center_detect(folder + img_name, 10, debug=True)) + + + + #print("Center Detection yields: ") + #print(center_detect("../new_test/img_3_{0}.png", 5)) + #2.5 + 13 = 15.5 / 2 = 7.75 + + """plt.figure() + plt.plot([1,2 ,3]) + plt.show()""" + + #print(atan(56 / 200) * 180 / 3.1415926535) + #print(atan(134 / 537) * 180 / 3.1415926535) + + #test() + #test_canny_detect() + #random_test() + + +if __name__ == '__main__': + #main() + #print(DEGREES) + #test_old() + #test('../bright/', 'img_193_{0}.png') + #deviation() + #test_interactive() + fourier_expr() + #test_record() + #test_canny_detect() + + + +# INSIGHT: +"""Might be able to solve the problem by auto-thresholding and converting to binary. +Alternative: + 1. Mark the maximum and minimum that are certain multitudes of standard deviation above + +=========================================== +========= THE FOLLOWING FUNCTIONS ========= +============== ARE DEPRECATED ============= +==========================================- + +def OMP(imDims, sparsity, measurements, A): + display = None + numPixels = 0 + r = measurements.copy() + indices = [] + + # Threshold to check error. If error is below this value, stop. + THRESHOLD = 0.1 + + # For iterating to recover all signal + i = 0 + + while i < sparsity and np.linalg.norm(r) > THRESHOLD: + # Calculate the correlations + print('%d - ' % i, end="", flush=True) + corrs = A.T.dot(r) + + # Choose highest-correlated pixel location and add to collection + # COMPLETE THE LINE BELOW + best_index = np.argmax(np.abs(corrs)) + indices.append(best_index) + + # Build the matrix made up of selected indices so far + # COMPLETE THE LINE BELOW + Atrunc = A[:, indices] + + # Find orthogonal projection of measurements to subspace + # spanned by recovered codewords + b = measurements + # COMPLETE THE LINE BELOW + xhat = np.linalg.lstsq(Atrunc, b)[0] + + # Find component orthogonal to subspace to use for next measurement + # COMPLETE THE LINE BELOW + r = b - Atrunc.dot(xhat) + + # This is for viewing the recovery process + if i % 10 == 0 or i == sparsity - 1 or np.linalg.norm(r) <= THRESHOLD: + recovered_signal = np.zeros(numPixels) + for j, x in zip(indices, xhat): + recovered_signal[j] = x + Ihat = recovered_signal.reshape(imDims) + plt.title('estimated image') + plt.imshow(Ihat, cmap=plt.cm.gray, interpolation='nearest') + display.clear_output(wait=True) + display.display(plt.gcf()) + + i = i + 1 + + display.clear_output(wait=True) + + # Fill in the recovered signal + recovered_signal = np.zeros(numPixels) + for i, x in zip(indices, xhat): + recovered_signal[i] = x + + return recovered_signal + +if ori == 'h': + x = np.array(range(img.shape[1])) + y = np.array([img_rec.rel_lumin(img, p, c) for c in x]) +else: + x = np.array(range(img.shape[0])) + y = np.array([img_rec.rel_lumin(img, r, p) for r in x]) +""" + +CALK = 166.1861 diff --git a/img_rec_module/~$log.docx b/img_rec_module/~$log.docx new file mode 100644 index 0000000..0430bb4 Binary files /dev/null and b/img_rec_module/~$log.docx differ diff --git a/ip_connected.txt b/ip_connected.txt new file mode 100644 index 0000000..90edc97 --- /dev/null +++ b/ip_connected.txt @@ -0,0 +1,10 @@ + +192.168.0.0 +192.168.0.1 +192.168.0.2 +192.168.0.3 +192.168.0.1 +192.168.0.13 +10.142.172.115 +10.142.172.116 +10.142.172.118 diff --git a/ip_test.sh b/ip_test.sh new file mode 100755 index 0000000..c90402d --- /dev/null +++ b/ip_test.sh @@ -0,0 +1,15 @@ +#!/bin/bash +touch ip_connected.txt +for ip in 192.168.3.{0..15} + do + s=`ping -c 1 $ip | grep 'icmp'` + check=`expr "$s" : '64 bytes'` + if [ "$check" -ge 5 ] + then + echo $ip + echo $ip >> ip_connected.txt + fi + done + + + diff --git a/socket_module/rpi_socket.py b/socket_module/rpi_socket.py new file mode 100644 index 0000000..985ab52 --- /dev/null +++ b/socket_module/rpi_socket.py @@ -0,0 +1,77 @@ +import socket + + +class SteadySocket: + + MAXMSGLEN = 128 + EOFChar = b'!' + + def __init__(self, sockt=None): + if sockt is None: + self.sock = socket.socket() + else: + self.sock = sockt + + def connect(self, host, port): + self.sock.connect((host, port)) + + def send(self, data, flags=0): + if data.find(self.EOFChar == -1): + data += self.EOFChar + data_sent = 0 + tot_len = len(data) + while data_sent < tot_len: + try: + sent = self.sock.send(data[data_sent:]) + assert sent != 0 + data_sent += sent + except: + raise RuntimeError("Connection Lost!") + + + def recv(self): + data_recv = [] + bytes_recv = 0 + count = 0 + while bytes_recv < self.MAXMSGLEN: + msg = self.sock.recv(self.MAXMSGLEN - bytes_recv) + end = msg.find(self.EOFChar) + if end != -1: + data_recv.append(msg[:end]) + break + data_recv.append(msg) + bytes_recv += len(msg) + print(count) + return b''.join(data_recv) + + def close(self): + self.sock.close() + + +def main(): + IP = '192.168.3.4' + port = 8000 + + rpisock = SteadySocket() + connected = False + while True: + if not connected: + try: + rpisock.connect(IP, port) + connected = True + msg = input("type a message\n") + rpisock.send(bytes(msg, 'utf-8')) + data = rpisock.recv() + print(data) + except: + pass + else: + print("already connected") + msg = input("type a message\n") + rpisock.send(bytes(msg, 'utf-8')) + data = rpisock.recv() + print(data) + + +if __name__ == "__main__": + main() diff --git a/socket_module/server_socket.py b/socket_module/server_socket.py new file mode 100644 index 0000000..49fddb7 --- /dev/null +++ b/socket_module/server_socket.py @@ -0,0 +1,85 @@ +import socket + + +class SteadySocket: + + MAXMSGLEN = 128 + EOFChar = b'!' + + def __init__(self, sockt=None): + if sockt is None: + self.sock = socket.socket() + else: + self.sock = sockt + + def connect(self, host, port): + self.sock.connect((host, port)) + + def send(self, data, flags=0): + if data.find(self.EOFChar == -1): + data += self.EOFChar + data_sent = 0 + tot_len = len(data) + while data_sent < tot_len: + try: + sent = self.sock.send(data[data_sent:]) + assert sent != 0 + data_sent += sent + except: + raise RuntimeError("Connection Lost!") + + + def recv(self): + data_recv = [] + bytes_recv = 0 + count = 0 + while bytes_recv < self.MAXMSGLEN: + msg = self.sock.recv(self.MAXMSGLEN - bytes_recv) + end = msg.find(self.EOFChar) + if end != -1: + data_recv.append(msg[:end]) + break + data_recv.append(msg) + bytes_recv += len(msg) + print(count) + return b''.join(data_recv) + + def close(self): + self.sock.close() + + +def main(): + ssock = socket.socket() + IP = "192.168.3.4" + port = 8000 + ssock.bind((IP, port)) + print("Now connected to " + IP + ":" + str(port)) + ssock.listen(1) + + conn = None + addr = None + sconn = None + while True: + if conn is None: + conn, addr = ssock.accept() + sconn = SteadySocket(conn) + print(addr) + else: + data = sconn.recv() + if data: + print(data) + if data == b"hi": + sconn.send(b"how are you!") + elif data == b'c': + sconn.close() + break + else: + sconn.send(b"It's good huh?!") + inp = input("value?\n") + if inp == 'e': + sconn.close() + break + + +if __name__ == "__main__": + main() diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..2af3756 --- /dev/null +++ b/test.sh @@ -0,0 +1,11 @@ +#!/bin/bash +for ip in 192.168.0.{0..255} + do + k=`ping -c 1 $ip | grep 'icmp'` + if [ "$k" > 5 ] + then echo $ip + fi + done + + + diff --git a/testpic/gray.txt b/testpic/gray.txt new file mode 100644 index 0000000..484b6f1 --- /dev/null +++ b/testpic/gray.txt @@ -0,0 +1,150 @@ +../testpic/img_1_1.png +(205.21480189651163, 300.9431873419749) +../testpic/img_1_2.png +(205.63638921004812, 300.7155445882073) +../testpic/img_1_3.png +(205.96730122081806, 300.9461855154958) +../testpic/img_2_1.png +(206.294705409402, 300.3672244728102) +../testpic/img_2_2.png +(206.89687869797643, 300.62957126862716) +../testpic/img_2_3.png +(206.03173965420586, 300.5376752697736) +../testpic/img_3_1.png +(200.84548583250404, 305.31250145945256) +../testpic/img_3_2.png +(200.8508617308734, 305.61891026952617) +../testpic/img_3_3.png +(201.11703696912699, 305.1685157754102) +../testpic/img_4_1.png +(208.61251671569937, 288.58145034959693) +../testpic/img_4_2.png +(206.7195131495757, 288.50535061792084) +../testpic/img_4_3.png +(203.9452244851535, 290.2052810653526) +../testpic/img_5_1.png +(205.40664153558757, 287.7623893599146) +../testpic/img_5_2.png +(204.9789788601677, 287.8715606914188) +../testpic/img_5_3.png +(211.7910055674488, 286.3685028850654) +../testpic/img_6_1.png +(217.0322629237196, 285.0367800566558) +../testpic/img_6_2.png +(214.88535502987406, 284.8828179469582) +../testpic/img_6_3.png +(215.76065051862108, 284.9932621778891) +../testpic/img_7_1.png +(217.37677626205667, 288.239680625496) +../testpic/img_7_2.png +(217.09738081018097, 288.7231164372432) +../testpic/img_7_3.png +(217.83758218152386, 288.4375218250161) +../testpic/img_8_1.png +(219.0315518772011, 286.608607067481) +../testpic/img_8_2.png +(219.2035209718933, 286.97894202924783) +../testpic/img_8_3.png +(218.95224028991848, 286.90592653956014) +../testpic/img_9_1.png +(217.64093013710516, 294.7222458158094) +../testpic/img_9_2.png +(217.54430830417542, 294.7696235004352) +../testpic/img_9_3.png +(217.5159267972094, 294.98671052542886) +../testpic/img_10_1.png +(219.01834291880346, 294.1889201606354) +../testpic/img_10_2.png +(220.11165575567446, 292.63926584110834) +../testpic/img_10_3.png +(222.8811302926324, 296.1182964266989) +../testpic/img_11_1.png +(219.69710306595923, 298.06577009042303) +../testpic/img_11_2.png +(219.77079226305807, 297.6972685864174) +../testpic/img_11_3.png +(219.72552517656615, 297.73284519911294) +../testpic/img_12_1.png +(218.0796259620671, 291.8496429144712) +../testpic/img_12_2.png +(218.11775264893598, 292.46013540240716) +../testpic/img_12_3.png +(218.6122214239511, 292.80915989964365) +../testpic/img_13_1.png +(218.4344154245471, 294.0818247758554) +../testpic/img_13_2.png +(218.17258930976334, 294.3701968572963) +../testpic/img_13_3.png +(217.4153885964598, 294.2661432761171) +../testpic/img_14_1.png +(208.30469342400863, 287.3509032893072) +../testpic/img_14_2.png +(206.8162120965767, 287.5793092707929) +../testpic/img_14_3.png +(207.9252711084856, 287.83037136055475) +../testpic/img_15_1.png +(206.81576078703893, 291.4096632718139) +../testpic/img_15_2.png +(207.79208272428122, 292.72957625568705) +../testpic/img_15_3.png +(207.54221099284027, 292.68348653085314) +../testpic/img_16_1.png +(210.11284670279136, 300.0715380971377) +../testpic/img_16_2.png +(209.52751389228695, 300.1969423451505) +../testpic/img_16_3.png +(209.40369008536234, 301.07097191446053) +../testpic/img_17_1.png +(218.93320872864754, 295.37952155647326) +../testpic/img_17_2.png +(218.9696659360369, 294.07045075136824) +../testpic/img_17_3.png +(219.12438095323773, 296.2608060055451) +../testpic/img_18_1.png +(213.41879050983465, 304.63372960145017) +../testpic/img_18_2.png +(213.13174989642516, 305.4446278908936) +../testpic/img_18_3.png +(217.90089511643342, 300.40415858460165) +../testpic/img_19_1.png +(226.7269214785641, 305.75699324219954) +../testpic/img_19_2.png +(226.34747351012416, 306.3059651266557) +../testpic/img_19_3.png +(226.28901165084417, 306.0126329735141) +../testpic/img_20_1.png +(219.65087039784123, 297.8033969960556) +../testpic/img_20_2.png +(219.2187889577143, 289.4087735896516) +../testpic/img_20_3.png +(219.9922950570292, 299.85077919874084) +../testpic/img_21_1.png +(219.63674348907952, 299.79682720488404) +../testpic/img_21_2.png +(219.2064998236914, 300.2619177584171) +../testpic/img_21_3.png +(218.8902855903587, 299.87321197209826) +../testpic/img_22_1.png +(205.54559205763047, 296.3571238704225) +../testpic/img_22_2.png +(209.48089510272197, 295.58371082468915) +../testpic/img_22_3.png +(222.26898057258506, 292.40915820234034) +../testpic/img_23_1.png +(217.34067539050167, 296.13485132000216) +../testpic/img_23_2.png +(217.7811059263327, 296.2544105728407) +../testpic/img_23_3.png +(217.51753530982677, 300.09854738205064) +../testpic/img_24_1.png +(218.07393217622632, 300.2997811875231) +../testpic/img_24_2.png +(211.2929535239784, 302.1473413252606) +../testpic/img_24_3.png +(208.50949807153992, 301.43124519988316) +../testpic/img_25_1.png +(210.19723323812133, 306.7113598893541) +../testpic/img_25_2.png +(207.70165150262, 307.3175263979337) +../testpic/img_25_3.png +(208.36875361369817, 303.0375261028656) \ No newline at end of file diff --git a/testpic/gray_large.txt b/testpic/gray_large.txt new file mode 100644 index 0000000..798fcc5 --- /dev/null +++ b/testpic/gray_large.txt @@ -0,0 +1,150 @@ +../testpic/img_1_1.png +(2060.00857421875, 3020.9592122395834) +../testpic/img_1_2.png +(2055.92142578125, 3006.5083984375) +../testpic/img_1_3.png +(2036.7973665364584, 2976.037431640625) +../testpic/img_2_1.png +(1994.5098600260417, 2904.026982421875) +../testpic/img_2_2.png +(1965.238154296875, 2855.570888671875) +../testpic/img_2_3.png +(1968.0356998697916, 2870.765810546875) +../testpic/img_3_1.png +(2631.8355729166665, 4000.7486295572917) +../testpic/img_3_2.png +(2572.3222233072916, 3914.09978515625) +../testpic/img_3_3.png +(2542.20052734375, 3857.4532194010417) +../testpic/img_4_1.png +(1955.0836393229167, 2704.5398860677083) +../testpic/img_4_2.png +(1977.513046875, 2759.889892578125) +../testpic/img_4_3.png +(1972.871962890625, 2807.31193359375) +../testpic/img_5_1.png +(1836.8890104166667, 2573.371370442708) +../testpic/img_5_2.png +(1804.554326171875, 2534.3080208333336) +../testpic/img_5_3.png +(1748.3726692708333, 2364.02326171875) +../testpic/img_6_1.png +(1833.804638671875, 2408.40583984375) +../testpic/img_6_2.png +(1794.8656022135417, 2379.531031901042) +../testpic/img_6_3.png +(1825.3344010416668, 2411.0420703125) +../testpic/img_7_1.png +(1956.28767578125, 2594.02013671875) +../testpic/img_7_2.png +(1957.131474609375, 2602.8370149739585) +../testpic/img_7_3.png +(1929.12623046875, 2554.3452311197916) +../testpic/img_8_1.png +(1921.8942057291667, 2514.8496484375) +../testpic/img_8_2.png +(1852.7399837239584, 2425.5876822916666) +../testpic/img_8_3.png +(1805.0545279947917, 2365.268522135417) +../testpic/img_9_1.png +(2637.453131510417, 3571.55296875) +../testpic/img_9_2.png +(2643.413323567708, 3581.7896419270833) +../testpic/img_9_3.png +(2626.104762369792, 3561.4219921875) +../testpic/img_10_1.png +(2563.569778645833, 3443.4276822916668) +../testpic/img_10_2.png +(2463.009303385417, 3274.5800390625) +../testpic/img_10_3.png +(2770.323935546875, 3680.632825520833) +../testpic/img_11_1.png +(2631.7345768229166, 3570.506767578125) +../testpic/img_11_2.png +(2536.99267578125, 3436.5612565104166) +../testpic/img_11_3.png +(2515.003251953125, 3407.8838736979164) +../testpic/img_12_1.png +(2538.5078971354164, 3397.2115462239585) +../testpic/img_12_2.png +(2556.02197265625, 3427.2062825520834) +../testpic/img_12_3.png +(2584.2490852864585, 3461.3426399739583) +../testpic/img_13_1.png +(2576.20923828125, 3468.3926171875) +../testpic/img_13_2.png +(2568.1598307291665, 3465.099430338542) +../testpic/img_13_3.png +(2507.983466796875, 3394.4911946614584) +../testpic/img_14_1.png +(1680.2696028645832, 2317.8881868489584) +../testpic/img_14_2.png +(1668.6466536458333, 2320.2641959635416) +../testpic/img_14_3.png +(1652.1645930989582, 2287.086826171875) +../testpic/img_15_1.png +(1884.2619075520834, 2654.9820279947917) +../testpic/img_15_2.png +(1908.3619466145833, 2688.427666015625) +../testpic/img_15_3.png +(1897.6742317708333, 2676.16841796875) +../testpic/img_16_1.png +(1975.1264192708334, 2820.76623046875) +../testpic/img_16_2.png +(2018.3365266927083, 2891.7369498697917) +../testpic/img_16_3.png +(1993.0766471354166, 2865.553720703125) +../testpic/img_17_1.png +(2075.0250065104165, 2799.5747981770833) +../testpic/img_17_2.png +(2049.05498046875, 2751.82646484375) +../testpic/img_17_3.png +(2061.5160416666668, 2787.213369140625) +../testpic/img_18_1.png +(2536.3010026041666, 3620.313056640625) +../testpic/img_18_2.png +(2582.2423958333334, 3700.678421223958) +../testpic/img_18_3.png +(2264.6719498697917, 3122.138948567708) +../testpic/img_19_1.png +(2962.3082682291665, 3994.8783463541668) +../testpic/img_19_2.png +(2908.7927083333334, 3936.3397526041667) +../testpic/img_19_3.png +(2914.5825813802085, 3941.415817057292) +../testpic/img_20_1.png +(2733.4142252604165, 3705.9723014322917) +../testpic/img_20_2.png +(2198.65669921875, 2902.627744140625) +../testpic/img_20_3.png +(2607.9814453125, 3554.693896484375) +../testpic/img_21_1.png +(2701.4876171875, 3687.44046875) +../testpic/img_21_2.png +(2739.979921875, 3753.1351790364583) +../testpic/img_21_3.png +(2667.824397786458, 3654.8404557291665) +../testpic/img_22_1.png +(1895.4133854166666, 2732.820751953125) +../testpic/img_22_2.png +(1825.6778255208333, 2576.085166015625) +../testpic/img_22_3.png +(1777.4883658854167, 2338.400416666667) +../testpic/img_23_1.png +(2012.2138346354166, 2741.7170930989582) +../testpic/img_23_2.png +(2002.2059016927083, 2723.66294921875) +../testpic/img_23_3.png +(2379.87974609375, 3283.4063411458333) +../testpic/img_24_1.png +(2104.8507291666665, 2898.495052083333) +../testpic/img_24_2.png +(2229.5265169270833, 3188.2062239583333) +../testpic/img_24_3.png +(2258.8827604166668, 3265.548330078125) +../testpic/img_25_1.png +(2449.8590169270833, 3574.7358756510416) +../testpic/img_25_2.png +(2467.9384733072916, 3651.5874641927085) +../testpic/img_25_3.png +(2274.6644173177083, 3308.1192154947917) \ No newline at end of file diff --git a/testpic/rel_lumin.txt b/testpic/rel_lumin.txt new file mode 100644 index 0000000..2151f3f --- /dev/null +++ b/testpic/rel_lumin.txt @@ -0,0 +1,150 @@ +../testpic/img_1_1.png +(206.04350300185553, 299.0540341998243) +../testpic/img_1_2.png +(206.4661876998688, 298.87869157975604) +../testpic/img_1_3.png +(206.539726576666, 299.3445028302692) +../testpic/img_2_1.png +(206.62574823965744, 298.364015333678) +../testpic/img_2_2.png +(207.15543076436487, 298.4790493172048) +../testpic/img_2_3.png +(206.42267550723432, 298.5091752433472) +../testpic/img_3_1.png +(201.97471732113223, 303.4166202623412) +../testpic/img_3_2.png +(201.8755908196089, 303.45606722221186) +../testpic/img_3_3.png +(202.04564115266442, 303.3166549610932) +../testpic/img_4_1.png +(208.76926943629095, 287.51138587988) +../testpic/img_4_2.png +(207.0018867758149, 287.656914170687) +../testpic/img_4_3.png +(204.44109724453457, 289.1925625342303) +../testpic/img_5_1.png +(205.77664478329535, 286.68530176937907) +../testpic/img_5_2.png +(205.6780512374802, 287.1001660889027) +../testpic/img_5_3.png +(211.82925866772135, 285.40585819828635) +../testpic/img_6_1.png +(216.1515787432525, 284.84917334617035) +../testpic/img_6_2.png +(214.52290017997893, 284.11390800672206) +../testpic/img_6_3.png +(215.3919833543449, 284.6765849105273) +../testpic/img_7_1.png +(217.22741430360932, 287.87844718888476) +../testpic/img_7_2.png +(217.00325638001345, 288.10503306376864) +../testpic/img_7_3.png +(217.29538500272267, 288.30482564333306) +../testpic/img_8_1.png +(218.10509847882844, 286.28394605240817) +../testpic/img_8_2.png +(218.3788797701322, 286.60001461430176) +../testpic/img_8_3.png +(218.2059111736144, 286.1172453033881) +../testpic/img_9_1.png +(217.08171004297984, 293.66398575147895) +../testpic/img_9_2.png +(216.98183698735136, 293.8811851742873) +../testpic/img_9_3.png +(216.9994269999031, 293.90584411028874) +../testpic/img_10_1.png +(218.4178268983069, 292.73218415360174) +../testpic/img_10_2.png +(219.4433578980413, 291.3678911350465) +../testpic/img_10_3.png +(222.06517427244975, 294.84198971641104) +../testpic/img_11_1.png +(219.0737726973493, 296.5752738260455) +../testpic/img_11_2.png +(219.15309034371694, 295.94924921149686) +../testpic/img_11_3.png +(218.92205064090555, 296.1111383515795) +../testpic/img_12_1.png +(217.31650922649175, 290.8263281533628) +../testpic/img_12_2.png +(217.43124337282256, 291.65437011556145) +../testpic/img_12_3.png +(217.94999730338108, 291.89445361132294) +../testpic/img_13_1.png +(217.7314953458256, 293.0030826815401) +../testpic/img_13_2.png +(217.66352922869572, 293.251933930113) +../testpic/img_13_3.png +(216.92528878379466, 293.0805113563251) +../testpic/img_14_1.png +(207.7580659152881, 286.60700596561094) +../testpic/img_14_2.png +(206.88115334127554, 286.2262269101382) +../testpic/img_14_3.png +(207.57769680927507, 287.02800557197895) +../testpic/img_15_1.png +(207.06218511814652, 290.6672864462294) +../testpic/img_15_2.png +(207.98098233293044, 291.99506585433636) +../testpic/img_15_3.png +(207.77505722866593, 292.006797659142) +../testpic/img_16_1.png +(210.40074913599636, 298.3601622520285) +../testpic/img_16_2.png +(209.78375083010266, 298.7840695237666) +../testpic/img_16_3.png +(209.641959443913, 299.44390843956813) +../testpic/img_17_1.png +(218.26568835261116, 294.7008282336055) +../testpic/img_17_2.png +(218.37299204011276, 293.384018922485) +../testpic/img_17_3.png +(218.66148315527113, 295.3027772591837) +../testpic/img_18_1.png +(213.38377251339844, 302.96352678722457) +../testpic/img_18_2.png +(213.07871090196872, 303.819533098452) +../testpic/img_18_3.png +(217.33723440473466, 299.1504826785637) +../testpic/img_19_1.png +(225.64353383755207, 304.42557061445035) +../testpic/img_19_2.png +(225.41128117140823, 304.8032542035086) +../testpic/img_19_3.png +(225.24899337338888, 304.69323068961785) +../testpic/img_20_1.png +(218.81571787606484, 296.93738661740343) +../testpic/img_20_2.png +(218.43314931707963, 288.85839063985725) +../testpic/img_20_3.png +(219.2706263099278, 298.8913892018587) +../testpic/img_21_1.png +(219.1711213895556, 298.91458567063023) +../testpic/img_21_2.png +(218.7321468018084, 299.1851711764027) +../testpic/img_21_3.png +(218.39759504201595, 298.5943724891208) +../testpic/img_22_1.png +(205.9262940567231, 295.15892353843077) +../testpic/img_22_2.png +(209.0387011317147, 294.75770055611173) +../testpic/img_22_3.png +(220.85123144981077, 291.1300724133201) +../testpic/img_23_1.png +(216.84730426577943, 295.15845622072544) +../testpic/img_23_2.png +(217.4184592783349, 295.1480815414764) +../testpic/img_23_3.png +(217.28838816509725, 299.02055198593763) +../testpic/img_24_1.png +(217.68334305616995, 299.1629854552312) +../testpic/img_24_2.png +(211.5709812570286, 300.6117397810366) +../testpic/img_24_3.png +(208.73136668809158, 300.86739838045446) +../testpic/img_25_1.png +(210.5961759781371, 305.25471559068825) +../testpic/img_25_2.png +(208.19015513423867, 305.68466521990763) +../testpic/img_25_3.png +(208.6434659680136, 301.30739718030026) diff --git a/testpic/rel_lumin_large.txt b/testpic/rel_lumin_large.txt new file mode 100644 index 0000000..30d34fa --- /dev/null +++ b/testpic/rel_lumin_large.txt @@ -0,0 +1,150 @@ +../testpic/img_1_1.png +(2157.319560885457, 3131.1597227852385) +../testpic/img_1_2.png +(2153.845215880276, 3117.8879561790022) +../testpic/img_1_3.png +(2119.147901084622, 3071.347509693332) +../testpic/img_2_1.png +(2119.2762954278173, 3060.198404566339) +../testpic/img_2_2.png +(2077.6439000678206, 2993.564657338488) +../testpic/img_2_3.png +(2090.1380134206984, 3022.5621918611105) +../testpic/img_3_1.png +(2500.3933865379954, 3756.2172173432277) +../testpic/img_3_2.png +(2444.073992806933, 3673.891820433198) +../testpic/img_3_3.png +(2429.1023810971974, 3646.637485417054) +../testpic/img_4_1.png +(2055.7335538458124, 2831.1005957049974) +../testpic/img_4_2.png +(2091.2184790769784, 2906.028847937455) +../testpic/img_4_3.png +(2085.2016014812198, 2949.6260911354293) +../testpic/img_5_1.png +(1975.5123306673688, 2752.257668808484) +../testpic/img_5_2.png +(1956.6913595834355, 2731.290047436797) +../testpic/img_5_3.png +(1889.0332441719518, 2545.1684890409497) +../testpic/img_6_1.png +(1918.7954031999095, 2528.6296200091383) +../testpic/img_6_2.png +(1870.5873508692757, 2477.403960498067) +../testpic/img_6_3.png +(1942.2617853464994, 2567.0242849523934) +../testpic/img_7_1.png +(2063.382415765099, 2734.476804926168) +../testpic/img_7_2.png +(2059.0865935522115, 2733.752575941349) +../testpic/img_7_3.png +(2019.4297569459177, 2679.3543911112342) +../testpic/img_8_1.png +(2037.3651209942493, 2674.2379268332115) +../testpic/img_8_2.png +(1963.2828938497344, 2576.60862928513) +../testpic/img_8_3.png +(1877.5070854903254, 2461.835944080701) +../testpic/img_9_1.png +(2738.1486253561347, 3704.1150944628794) +../testpic/img_9_2.png +(2757.1875320142717, 3734.3473117676517) +../testpic/img_9_3.png +(2730.8636854648853, 3698.704681957753) +../testpic/img_10_1.png +(2679.361416892579, 3590.985822183059) +../testpic/img_10_2.png +(2589.2803069981333, 3437.9402039503957) +../testpic/img_10_3.png +(2900.8176388014826, 3851.49471199546) +../testpic/img_11_1.png +(2766.039084427688, 3744.5778596737127) +../testpic/img_11_2.png +(2669.5522158918957, 3605.0231953607718) +../testpic/img_11_3.png +(2655.8969932304944, 3592.331972533938) +../testpic/img_12_1.png +(2594.027650903526, 3471.4874609655285) +../testpic/img_12_2.png +(2654.9036825136873, 3561.191341362665) +../testpic/img_12_3.png +(2695.1501438085506, 3609.5406669466897) +../testpic/img_13_1.png +(2666.374846697289, 3588.1627893380605) +../testpic/img_13_2.png +(2657.6071162415406, 3580.5191123470804) +../testpic/img_13_3.png +(2597.123502915347, 3508.8868087141295) +../testpic/img_14_1.png +(1804.1555150325169, 2488.8738166760354) +../testpic/img_14_2.png +(1818.0525948893292, 2515.3298217597335) +../testpic/img_14_3.png +(1777.0797201595474, 2457.256514838709) +../testpic/img_15_1.png +(2035.9442432975757, 2857.9935453567546) +../testpic/img_15_2.png +(2059.090047130236, 2890.8611122402826) +../testpic/img_15_3.png +(2045.9399136986385, 2875.36131800779) +../testpic/img_16_1.png +(2115.043809103625, 2999.251745279759) +../testpic/img_16_2.png +(2165.299873011056, 3083.9238274535805) +../testpic/img_16_3.png +(2133.3272369166634, 3047.156435178312) +../testpic/img_17_1.png +(2200.842028967558, 2971.561740387991) +../testpic/img_17_2.png +(2164.278240785303, 2907.7068662018496) +../testpic/img_17_3.png +(2176.967779031927, 2939.999408562449) +../testpic/img_18_1.png +(2629.9792025032802, 3734.0598358641137) +../testpic/img_18_2.png +(2675.6307109172553, 3815.063785085293) +../testpic/img_18_3.png +(2381.734804178486, 3278.3021199003847) +../testpic/img_19_1.png +(3068.005648860044, 4139.180744150981) +../testpic/img_19_2.png +(3005.5945333118875, 4064.19319303324) +../testpic/img_19_3.png +(3025.07070747263, 4091.9986061667178) +../testpic/img_20_1.png +(2843.908716079451, 3859.2420605241127) +../testpic/img_20_2.png +(2323.8894860359133, 3073.13692569066) +../testpic/img_20_3.png +(2734.9635923326778, 3728.073756552263) +../testpic/img_21_1.png +(2791.519919590555, 3807.18962820202) +../testpic/img_21_2.png +(2817.8960916876545, 3854.361313029992) +../testpic/img_21_3.png +(2737.9935515769216, 3743.399583933548) +../testpic/img_22_1.png +(2060.085794285838, 2952.7686506645473) +../testpic/img_22_2.png +(1949.920946809211, 2749.511030426506) +../testpic/img_22_3.png +(1923.704953940907, 2535.86253002149) +../testpic/img_23_1.png +(2035.5784462603976, 2770.697075293164) +../testpic/img_23_2.png +(2061.4682121301553, 2798.4670206407895) +../testpic/img_23_3.png +(2421.692887731753, 3332.6030449439595) +../testpic/img_24_1.png +(2194.6536882747673, 3016.12029752409) +../testpic/img_24_2.png +(2274.0128258624727, 3231.0430655725836) +../testpic/img_24_3.png +(2293.1907674783547, 3305.427215605218) +../testpic/img_25_1.png +(2515.6176692591093, 3646.3347570200845) +../testpic/img_25_2.png +(2510.7358431808866, 3686.5021075732457) +../testpic/img_25_3.png +(2322.6145823469774, 3354.1474745596156) diff --git a/timer.c b/timer.c new file mode 100644 index 0000000..e6b123a --- /dev/null +++ b/timer.c @@ -0,0 +1,101 @@ +// Global Variables +int timer = 0; +int on = 0; +int minInterval = 2; + + +void setup() { + // Setup pins for pin activated interrupts: p8, p7 + pinMode(3,INPUT);//digitalWrite(8,HIGH); + pinMode(2,INPUT);//digitalWrite(7,HIGH); + + // Setup pin for timer activated interrupts: p13 + pinMode(13,OUTPUT);//`******digitalWrite(13,LOW); + pinMode(12,OUTPUT); // Open the relay to shut of RPi + + + // Setup the timer interrupt configuration for 1 Hz + /* + cli(); + TCCR1A = 0;// set entire TCCR1A register to 0 + TCCR1B = 0;// same for TCCR1B + TCNT1 = 0;//initialize counter value to 0 + // set compare match register for 1hz increments + OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536) + // Set CS12 and CS10 bits for 1024 prescaler + TCCR1B |= (1 << CS12) | (1 << CS10); + // enable timer compare interrupt + TIMSK1 |= (1 << OCIE1A); + // Normally would turn on, but this is left for the p8 interrupt to do: + // turn on CTC mode + // TCCR1B |= (1 << WGM12); + // + sei(); + */ + + // Setup p3 and p2 interrupt code + attachInterrupt(digitalPinToInterrupt(2),ISR_p2,FALLING); + attachInterrupt(digitalPinToInterrupt(3),ISR_p3,RISING); + + // Turn on the RPi pin to start the flow of energy to the RPi so it + // can be configured to run the system and eventually activate p8 and + // p9 interrupt ISR's which will begin the total system operation. + digitalWrite(13,HIGH); // this flips a relay energizing the RPi + digitalWrite(12,LOW); + + Serial.begin(9600); + Serial.println("Running..."); +} + +// timer1 interrupt service routine +ISR(TIMER1_COMPA_vect){ + // turn on the RPi, as the time interval has elapsed + if(timer == 60*minInterval){ + //if(timer == 10){ + digitalWrite(12,LOW); + digitalWrite(13,HIGH); + timer = 1; + Serial.println(timer); + } else { + timer += 1; + Serial.println(timer); + } +} + +// pin2 interrupt service routine +void ISR_p2(){ + // turn off RPi, as the signal pin has lifted saying it is shutdown + if (timer > 5){ + digitalWrite(13,LOW); + digitalWrite(12,HIGH); + Serial.println("pin 2 lifted"); + } +} + +// pin3 interrup service routine +void ISR_p3(){ + // start the timer1, as the signal pin has been lifted saying the clocks are synchronized + cli(); + TCCR1A = 0;// set entire TCCR1A register to 0 + TCCR1B = 0;// same for TCCR1B + TCNT1 = 0;//initialize counter value to 0 + // set compare match register for 1hz increments + OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536) + // Set CS12 and CS10 bits for 1024 prescaler + TCCR1B |= (1 << CS12) | (1 << CS10); + // enable timer compare interrupt + TIMSK1 |= (1 << OCIE1A); + TCCR1B |= (1 << WGM12); + sei(); + Serial.println("pin 3 lifted"); + detachInterrupt(3); +} + + + +void loop() { + // put your main code here, to run repeatedly: + //delay(1000); + //Serial.println("yup, again"); + +}