├── LICENSE ├── README.md ├── Server.py ├── __pycache__ ├── camera_pi.cpython-35.pyc └── getHackRFData.cpython-35.pyc ├── camera_pi.py ├── data ├── dataJ.json └── dataRaw.csv ├── getHackRFData.py ├── static ├── boost.js ├── heatmap.js ├── highcharts.js ├── jquery-3.1.1.min.js ├── plotly-latest.min.js └── style.css └── templates └── index.html /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 HensonZl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HackRFPiBot 2 | ## Using a Raspberry Pi and a HackRF One to locate and graph RF signals on a Python3 Flask Web Server 3 | 4 | ###### @authors 5 | - Zachariah L. Henson https://www.linkedin.com/in/zachariah-henson-00a693165/ 6 | - Seth French https://www.linkedin.com/in/seth-french-59591017b/ 7 | 8 | ###### @contributors 9 | - Special thanks to the following people for their advising and contributions on this progect. 10 | 11 | - Scott Blough- https://www.linkedin.com/in/scottblough 12 | - Dr. Ali Yurekli- https://www.linkedin.com/in/yurekli 13 | - Nicholas Consolo- https://www.linkedin.com/in/nick-consolo-6432227 14 | 15 | # IMPORTANT NOTICE 16 | **This project possess the ability to break federal laws and FCC regulations by using this code and reading through this documentation you are agreeing to not use this code/project to break the law and if you chose to use or build this project you understand that all testing must be done in a faraday cage. Visit https://www.fcc.gov/general/jammer-enforcement and https://www.fcc.gov/ for all laws and regulations** 17 | 18 | ## File Structure 19 | - **Templates/** _contains the html files for the webserver_ 20 | - **Static/** _contains all static CDN's and css files **NOTE: The Font Awesome CDN was not included due to size. Independant download required**_ 21 | - **Data/** _contains the .csv and .json file used to store, update, parse, and display the data_ 22 | - **Pycache/** _contains the server cache files_ 23 | - **In The Parent Directory/** 24 | 1. **Server.py** _The Flask server_ 25 | 2. **getHackRFData.py** _The script that interfaces with the HackRf One_ 26 | 3. **camera_pi.py** _The script that interfaces with the Pi's camera_ 27 | 4. **MISSING** _The audio file used to transmit a signal was ommited due to file size_ 28 | 29 | 30 | ## Hardware Used 31 | - HackRf One [HackRf One](https://www.amazon.com/Great-Scott-Gadgets-peripheral-transmission/dp/B01COVX464/ref=sr_1_1_sspa?crid=1FN4F7O1GJSJT&keywords=hackrf+one&qid=1556739808&s=gateway&sprefix=hackrf+one%2Caps%2C152&sr=8-1-spons&psc=1) 32 | - Raspberry Pi 3B+ [RPi](https://www.amazon.com/ELEMENT-Element14-Raspberry-Pi-Motherboard/dp/B07BDR5PDW/ref=sr_1_3?crid=2ZMFKANCQR3DQ&keywords=raspberry+pi+3+b%2B&qid=1556739859&s=gateway&sprefix=raspb%2Caps%2C169&sr=8-3) 33 | - High Throughput Cooling Case [Pi Case](https://www.amazon.com/Smraza-Raspberry-Heatsinks-Supply-Black-Clear/dp/B07BT65FT1/ref=sr_1_1_sspa?keywords=raspberry+pi+case&qid=1556740244&s=hi&sr=1-1-spons&psc=1) 34 | - A Good Micro SD Card [SD Card](https://www.amazon.com/Samsung-MicroSD-Adapter-MB-ME32GA-AM/dp/B06XWN9Q99/ref=pd_bxgy_147_img_3/146-7873174-4246317?_encoding=UTF8&pd_rd_i=B06XWN9Q99&pd_rd_r=6bf70053-6c4a-11e9-b1cc-c9dd2e9ccfc7&pd_rd_w=m4afy&pd_rd_wg=A9Jjh&pf_rd_p=a2006322-0bc0-4db9-a08e-d168c18ce6f0&pf_rd_r=6K0DWW6HS49A8NQ5SAYV&psc=1&refRID=6K0DWW6HS49A8NQ5SAYV) 35 | - Mobile Power Supply [Power Supply](https://www.amazon.com/Battery-Pack-Raspberry-4000mAh-Suction/dp/B07BSG7V3J/ref=sr_1_3?keywords=raspberry+pi+3+b%2B+power+pack&qid=1556740353&s=electronics&sr=1-3) 36 | - DC Motor Controler [DC Controler](https://www.amazon.com/gp/product/B01M29YK5U/ref=ppx_yo_dt_b_asin_title_o09_s00?ie=UTF8&psc=1) 37 | - 4 DC Motors [Pi Motors](https://www.amazon.com/gp/product/B01M29YK5U/ref=ppx_yo_dt_b_asin_title_o09_s00?ie=UTF8&psc=1) 38 | - DC Power Supply For Motors [DC Power Supply](https://www.amazon.com/LAMPVPATH-Battery-Holder-Switch-Leads/dp/B076C7S2VN/ref=sr_1_6?keywords=dc+motor+power+supply+AA+batteries&qid=1556741377&s=gateway&sr=8-6) 39 | - Simple Robot Frame [Amazon Has Plenty Of Them](https://www.amazon.com/) 40 | - Raspberry Pi Camera [Pi Camera](https://www.amazon.com/Raspberry-Pi-Camera-Module-Megapixel/dp/B01ER2SKFS/ref=sr_1_3?crid=1QIIYT6VAP2VU&keywords=raspberry+pi+camera&qid=1556740642&s=electronics&sprefix=raspberry+pi+camer%2Celectronics%2C164&sr=1-3) 41 | 42 | ## Software/Libraries Used 43 | - HackRF Lib and Tools [HackRF GitHub](https://github.com/mossmann/hackrf/wiki/Operating-System-Tips) 44 | - Python3 Flask WebServer [Flask](http://flask.pocoo.org/) 45 | - Plotty.js [Plotty](https://plot.ly/javascript/) 46 | - HighCharts.js [HighCharts](https://www.highcharts.com/) 47 | - Font Awesome [FA](https://fontawesome.com/download) 48 | - Custom RPi Camera Script Created By [Ruchir Sharma](https://www.hackster.io/ruchir1674/video-streaming-on-flask-server-using-rpi-ef3d75) 49 | - Pthyon3 csv 50 | - Python3 json 51 | - Python3 subprocess 52 | - Python3 RPi.GPIO 53 | - Python3 RPi.Camera 54 | 55 | ## Getting Started 56 | - Ensure that your RaspberryPi is updated 57 | ``` 58 | sudo apt-get update 59 | sudo apt-get upgrade 60 | ``` 61 | - Ensure Python3 is installed on the PI 62 | ``` sudo python3 ``` 63 | 1. If there is an error follow the link to learn how to install python3 [Python3](https://gist.github.com/dschep/24aa61672a2092246eaca2824400d37f) 64 | - Install pip3 65 | ``` sudo apt-get install python3-pip ``` 66 | - Install Flask 67 | ``` sudo pip3 install Flask ``` 68 | 1. As a note, you are able to do this within a virtual python environment if you want. The offical Flask documention above shows you how to do that 69 | - Install Flask Bootstrap 70 | ``` pip3 install flask-bootstrap ``` 71 | - Install RPi.GPIO 72 | ``` sudo apt-get install python3-rpi.gpio ``` 73 | - Install RP.Camera 74 | ``` sudo apt-get install python3-picamera ``` 75 | - The rest of the libraries used are CDNs and are included in this repository excluding Font Awesome wich is linked in the Software section 76 | - If you wish to download your own CDNs all the links to download them are next to them in the **Software/Libraries Used** section 77 | 78 | ## Installing HackRf Lib Tools and Firmware 79 | - Clone The GitHub Repository 80 | ``` 81 | git clone https://github.com/mossmann/hackrf.git 82 | ``` 83 | - Install The Software 84 | ``` 85 | cd hackrf/host 86 | mkdir build 87 | cd build 88 | cmake .. 89 | make 90 | sudo make install 91 | sudo ldconfig 92 | ``` 93 | - If you detirmine the firmware need to be updated use the following link [Firmware](https://github.com/mossmann/hackrf/wiki/Updating-Firmware) 94 | - Make sure everything installed correctly 95 | ``` 96 | sudo hackrf_info 97 | ``` 98 | - If everything installed correctly you should get the following output 99 | ``` 100 | hackrf_info version: 2017.02.1 101 | libhackrf version: 2017.02.1 (0.5) 102 | Found HackRF 103 | Index: 0 104 | Serial number: 0000000000000000################ 105 | Board ID Number: 2 (HackRF One) 106 | Firmware Version: 2017.02.1 (API:1.02) 107 | Part ID Number: 0x######## 0x######## 108 | ``` 109 | 110 | ## Setting Up The Raspberry Pi As A Access Point 111 | - This **MUST** be done in order for you to be able to access the webserver in a headless configuration 112 | - Follow this link to learn how to do so [RPi Access Point](https://learn.sparkfun.com/tutorials/setting-up-a-raspberry-pi-3-as-an-access-point/all) 113 | 114 | ## Starting The Server 115 | - With all of the following steps completed and Font Awesome downloaded and in the **/static** folder everything should be good to go 116 | - Open a terminal and open the folder were the files are located and type the following command 117 | ``` sudo python3 Server.py ``` 118 | - This will start the server on port 80 on your raspberry pi 119 | - With the server started you should be able to connect to you Raspberry Pi's network on any WiFi compatible device and go to the IP address you set for your Pi in the **Setting Up The Raspberry Pi As A Access Point** section and see the website and control both the Pi Robot and HackRF One 120 | 121 | ## Additional Notes 122 | - With the Pi acting like an access point you are able to ssh into to via any terminal or ssh app on a mobile phone using the IP address set in the **Setting Up The Raspberry Pi As A Access Point** section. This allows the project to remain headless. 123 | - In the **Setting Up The Raspberry Pi As A Access Point** section, the network traffic was forwarded to the eht0 interface. This can be done with any interface on the Pi. I note this because if you want to, you can install a Verizon WiFi dongle and have it forwarded to that interface. In combination with that you can purchase a static IP address from Verizon for $500 USD and have your pi accessable from anywhere in the world. 124 | 125 | ## Pictures Of The Graphs 126 | ![Line Graph](https://i.imgur.com/xOsTxzf.png) 127 | ![Heat Map](https://i.imgur.com/C5ddMpp.png) 128 | ![Spectral Waterfall](https://i.imgur.com/knLPOKP.png) 129 | 130 | ## Pictures Of The Web Interface On A Mobile Phone 131 | ![Camera](https://i.imgur.com/YzEN4vs.jpg) 132 | ![Controls](https://i.imgur.com/D5Iupth.jpg) 133 | -------------------------------------------------------------------------------- /Server.py: -------------------------------------------------------------------------------- 1 | #@authors Zachariah L Henson and Seth French and copyrighted under the MIT lience 2 | from flask import Flask, render_template, Response #the framework for the webserver 3 | from flask_bootstrap import Bootstrap #a js libary for css, js and html 4 | import datetime #the date is important 5 | import RPi.GPIO as gpio #allows for the use of GPIO pins on the raspberry pi 6 | import time #for time stamps 7 | import json #json is the file format we used to minipulate the data 8 | from flask.json import jsonify #allows for the use of json in the webserver as a response to a $.get commoand is js 9 | from camera_pi import Camera # a script that allows for the brodcast of the camera interface on the website 10 | from getHackRFData import HackRF # a custom stript that interfaces with the hackrf one 11 | 12 | app = Flask(__name__) #init the web app 13 | Bootstrap(app) #let the ap know you will use bootstrap framework 14 | app.config['BOOTSTRAP_SERVE_LOCAL'] = True #the location for the static CDN of the bootstrap 15 | 16 | gpio.setmode(gpio.BCM) #setting the gpio mode on the pi to be able to access them 17 | gpio.setwarnings(False) #no need for warnings after development change to true if you need the warnings 18 | 19 | dcOne = 17 #sets the gpio pin number to a var for future use 20 | dcTwo = 22 21 | dcThree = 23 22 | dcFour = 24 23 | 24 | gpio.setup(dcOne,gpio.OUT) #setts the mode of the gpio pin to know it will be recieving info to send out 25 | gpio.setup(dcTwo,gpio.OUT) 26 | gpio.setup(dcThree,gpio.OUT) 27 | gpio.setup(dcFour,gpio.OUT) 28 | 29 | gpio.output(dcOne,gpio.LOW) # turn all of the gpio pins off, we dont need a run away robot 30 | gpio.output(dcTwo,gpio.LOW) 31 | gpio.output(dcThree,gpio.LOW) 32 | gpio.output(dcFour,gpio.LOW) 33 | 34 | 35 | 36 | @app.route("/") #home dir of the webserver 37 | def index(): 38 | 39 | templateData = { #if we needed to return data it would be done here 40 | 41 | } 42 | 43 | return render_template('index.html', **templateData) #return the template of the website in html format for the user to see 44 | 45 | def gen(camera): #define the camera function to be used 46 | 47 | """Video streaming generator function.""" 48 | 49 | while True: 50 | 51 | frame = camera.get_frame() #gets the current frame of the cammera from the script 52 | 53 | yield (b'--frame\r\n' 54 | 55 | b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') #sets the display format 56 | 57 | @app.route('/video_feed') #dir of the camera interface 58 | def video_feed(): 59 | 60 | """Video streaming route. Put this in the src attribute of an img tag.""" 61 | 62 | return Response(gen(Camera()), #displays the current frame of the camera to the /video_feed dir 63 | 64 | mimetype='multipart/x-mixed-replace; boundary=frame') 65 | 66 | @app.route('/gengraph/') #the dir were all the HackRF data is collected and formated and accepts a parm that allows for the user to choose a rf signal range 67 | def gengraph(range): 68 | RfRange = str(range) #converts the user input into a usable string 69 | HRF = HackRF("/home/pi/Documents/rpiWebServer/data/dataRaw.csv", RfRange, "100000") #3 parms. location of were to dump the CSV data, the range to scan and how many MHz between each hop, currently .1 Mhz 70 | 71 | HRF.getData() #calls the fuction to get the data from the HackRF with the above parms 72 | 73 | HRF.csvToJson("/home/pi/Documents/rpiWebServer/data/dataRaw.csv", "/home/pi/Documents/rpiWebServer/data/dataJ.json") #calls a function to convert the data from CSV to JSON with the file paths as parms 74 | 75 | jobj = HRF.load("/home/pi/Documents/rpiWebServer/data/dataJ.json") # calls a funtion that loads the JSON data into a object 76 | 77 | def extract_time(json): 78 | 79 | try: 80 | 81 | # Also convert to int since update_time will be string. When comparing 82 | 83 | # strings, "10" is smaller than "2". 84 | 85 | return int(json['hz_low']) 86 | 87 | except KeyError: 88 | 89 | return 0 90 | 91 | jobj.sort(key=extract_time, reverse=False) #sorts the json data to be ordered correctly 92 | 93 | y_cords = [] #y cords object 94 | x_cords = [] #x cords object 95 | 96 | bandwidth = 98039.22 #the exact MHz between hops in the scans 97 | spacer = 49019.61 #used to find the middle of the signal 98 | startingHz = 0.0 #sets a starting point 99 | 100 | for distro in jobj: #sets all of the y cords from the json object 101 | 102 | y_cords.append((float(distro['DB1']))) 103 | y_cords.append((float(distro['DB2']))) 104 | y_cords.append((float(distro['DB3']))) 105 | y_cords.append((float(distro['DB4']))) 106 | y_cords.append((float(distro['DB5']))) 107 | y_cords.append((float(distro['DB6']))) 108 | y_cords.append((float(distro['DB7']))) 109 | y_cords.append((float(distro['DB8']))) 110 | y_cords.append((float(distro['DB9']))) 111 | y_cords.append((float(distro['DB10']))) 112 | y_cords.append((float(distro['DB11']))) 113 | y_cords.append((float(distro['DB12']))) 114 | y_cords.append((float(distro['DB13']))) 115 | y_cords.append((float(distro['DB14']))) 116 | y_cords.append((float(distro['DB15']))) 117 | y_cords.append((float(distro['DB16']))) 118 | y_cords.append((float(distro['DB17']))) 119 | y_cords.append((float(distro['DB18']))) 120 | y_cords.append((float(distro['DB19']))) 121 | y_cords.append((float(distro['DB20']))) 122 | y_cords.append((float(distro['DB21']))) 123 | y_cords.append((float(distro['DB22']))) 124 | y_cords.append((float(distro['DB23']))) 125 | y_cords.append((float(distro['DB24']))) 126 | y_cords.append((float(distro['DB25']))) 127 | y_cords.append((float(distro['DB26']))) 128 | y_cords.append((float(distro['DB27']))) 129 | y_cords.append((float(distro['DB28']))) 130 | y_cords.append((float(distro['DB29']))) 131 | y_cords.append((float(distro['DB30']))) 132 | y_cords.append((float(distro['DB31']))) 133 | y_cords.append((float(distro['DB32']))) 134 | y_cords.append((float(distro['DB33']))) 135 | y_cords.append((float(distro['DB34']))) 136 | y_cords.append((float(distro['DB35']))) 137 | y_cords.append((float(distro['DB36']))) 138 | y_cords.append((float(distro['DB37']))) 139 | y_cords.append((float(distro['DB38']))) 140 | y_cords.append((float(distro['DB39']))) 141 | y_cords.append((float(distro['DB40']))) 142 | y_cords.append((float(distro['DB41']))) 143 | y_cords.append((float(distro['DB42']))) 144 | y_cords.append((float(distro['DB43']))) 145 | y_cords.append((float(distro['DB44']))) 146 | y_cords.append((float(distro['DB45']))) 147 | y_cords.append((float(distro['DB46']))) 148 | y_cords.append((float(distro['DB47']))) 149 | y_cords.append((float(distro['DB48']))) 150 | y_cords.append((float(distro['DB49']))) 151 | y_cords.append((float(distro['DB50']))) 152 | y_cords.append((float(distro['DB51']))) 153 | 154 | for distro in jobj: #sets all of the x cords for the RF signals based on the space between hops and the middle of the signal. as a note rf singals are read from the middle of the signal not the begining so thats why it is formated like this 155 | startingHz = float(distro['hz_low']) 156 | startingHz += spacer 157 | x_cords.append(startingHz) 158 | startingHz += bandwidth 159 | x_cords.append(startingHz) 160 | startingHz += bandwidth 161 | x_cords.append(startingHz) 162 | startingHz += bandwidth 163 | x_cords.append(startingHz) 164 | startingHz += bandwidth 165 | x_cords.append(startingHz) 166 | startingHz += bandwidth 167 | x_cords.append(startingHz) 168 | startingHz += bandwidth 169 | x_cords.append(startingHz) 170 | startingHz += bandwidth 171 | x_cords.append(startingHz) 172 | startingHz += bandwidth 173 | x_cords.append(startingHz) 174 | startingHz += bandwidth 175 | x_cords.append(startingHz) 176 | startingHz += bandwidth 177 | x_cords.append(startingHz) 178 | startingHz += bandwidth 179 | x_cords.append(startingHz) 180 | startingHz += bandwidth 181 | x_cords.append(startingHz) 182 | startingHz += bandwidth 183 | x_cords.append(startingHz) 184 | startingHz += bandwidth 185 | x_cords.append(startingHz) 186 | startingHz += bandwidth 187 | x_cords.append(startingHz) 188 | startingHz += bandwidth 189 | x_cords.append(startingHz) 190 | startingHz += bandwidth 191 | x_cords.append(startingHz) 192 | startingHz += bandwidth 193 | x_cords.append(startingHz) 194 | startingHz += bandwidth 195 | x_cords.append(startingHz) 196 | startingHz += bandwidth 197 | x_cords.append(startingHz) 198 | startingHz += bandwidth 199 | x_cords.append(startingHz) 200 | startingHz += bandwidth 201 | x_cords.append(startingHz) 202 | startingHz += bandwidth 203 | x_cords.append(startingHz) 204 | startingHz += bandwidth 205 | x_cords.append(startingHz) 206 | startingHz += bandwidth 207 | x_cords.append(startingHz) 208 | startingHz += bandwidth 209 | x_cords.append(startingHz) 210 | startingHz += bandwidth 211 | x_cords.append(startingHz) 212 | startingHz += bandwidth 213 | x_cords.append(startingHz) 214 | startingHz += bandwidth 215 | x_cords.append(startingHz) 216 | startingHz += bandwidth 217 | x_cords.append(startingHz) 218 | startingHz += bandwidth 219 | x_cords.append(startingHz) 220 | startingHz += bandwidth 221 | x_cords.append(startingHz) 222 | startingHz += bandwidth 223 | x_cords.append(startingHz) 224 | startingHz += bandwidth 225 | x_cords.append(startingHz) 226 | startingHz += bandwidth 227 | x_cords.append(startingHz) 228 | startingHz += bandwidth 229 | x_cords.append(startingHz) 230 | startingHz += bandwidth 231 | x_cords.append(startingHz) 232 | startingHz += bandwidth 233 | x_cords.append(startingHz) 234 | startingHz += bandwidth 235 | x_cords.append(startingHz) 236 | startingHz += bandwidth 237 | x_cords.append(startingHz) 238 | startingHz += bandwidth 239 | x_cords.append(startingHz) 240 | startingHz += bandwidth 241 | x_cords.append(startingHz) 242 | startingHz += bandwidth 243 | x_cords.append(startingHz) 244 | startingHz += bandwidth 245 | x_cords.append(startingHz) 246 | startingHz += bandwidth 247 | x_cords.append(startingHz) 248 | startingHz += bandwidth 249 | x_cords.append(startingHz) 250 | startingHz += bandwidth 251 | x_cords.append(startingHz) 252 | startingHz += bandwidth 253 | x_cords.append(startingHz) 254 | startingHz += bandwidth 255 | x_cords.append(startingHz) 256 | startingHz += bandwidth 257 | x_cords.append(startingHz) 258 | 259 | cords = [x_cords,y_cords] #puts the x and y cords in a parent object 260 | 261 | return jsonify(cords) #returns the parent object to the client 262 | 263 | @app.route('/block/') #warrning do not use this function outside of a fareaday cage as it is breaks FCC regulations 264 | def block(blockRange): #blocks a rf sgnial range 265 | RfRange = str(blockRange) #formats the user input into a string 266 | HRF = HackRF("/home/pi/Documents/rpiWebServer/data/dataRaw.csv", RfRange, "100000") #init the HackRF 267 | HRF.sendData(RfRange) #calls a funtion to block a RF signal based on the user input 268 | 269 | randomData = ['hello', 'hello'] #you need to return data for a funtion to be called by $.get in a flask server 270 | 271 | return jsonify(randomData) # read the above comment 272 | 273 | 274 | @app.route("//") #the dir that controls the robot 275 | def action(deviceName, action): 276 | if deviceName == 'robot': #inits the gpio pins read the code at the beggining of the file to understand better 277 | actuator1 = dcOne 278 | actuator2 = dcTwo 279 | actuator3 = dcThree 280 | actuator4 = dcFour 281 | 282 | if action == "backwards": #sets the pins to go a direction based on user input 283 | gpio.output(actuator1, False) 284 | gpio.output(actuator2, True) 285 | gpio.output(actuator3, False) 286 | gpio.output(actuator4, True) 287 | 288 | if action == "forwards": #sets the pins to go a direction based on user input 289 | gpio.output(actuator1, True) 290 | gpio.output(actuator2, False) 291 | gpio.output(actuator3, True) 292 | gpio.output(actuator4, False) 293 | 294 | if action == "left": #sets the pins to go a direction based on user input 295 | gpio.output(actuator1, False) 296 | gpio.output(actuator2, True) 297 | gpio.output(actuator3, True) 298 | gpio.output(actuator4, False) 299 | 300 | if action == "right": #sets the pins to go a direction based on user input 301 | gpio.output(actuator1, True) 302 | gpio.output(actuator2, False) 303 | gpio.output(actuator3, False) 304 | gpio.output(actuator4, True) 305 | 306 | if action == "off": #sets the pins to go a direction based on user input 307 | gpio.output(actuator1, gpio.LOW) 308 | gpio.output(actuator2, gpio.LOW) 309 | gpio.output(actuator3, gpio.LOW) 310 | gpio.output(actuator4, gpio.LOW) 311 | 312 | templateData = { 313 | 314 | } 315 | 316 | return jsonify(templateData) #agian you have to return something in a fuction 317 | 318 | 319 | 320 | if __name__ == "__main__": 321 | 322 | app.run(host='0.0.0.0', port=80, debug=True, threaded=True) #starts the app on a port on the local host 323 | -------------------------------------------------------------------------------- /__pycache__/camera_pi.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HensonZl/hackrfpibot/4eb730f5add931d0d26f2ec1177994dee5417012/__pycache__/camera_pi.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/getHackRFData.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HensonZl/hackrfpibot/4eb730f5add931d0d26f2ec1177994dee5417012/__pycache__/getHackRFData.cpython-35.pyc -------------------------------------------------------------------------------- /camera_pi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # camera_pi.py 5 | # 6 | # NOT MY SCRIPT this was used from https://www.hackster.io/ruchir1674/video-streaming-on-flask-server-using-rpi-ef3d75 7 | # Look at the above link to get the documentation for the following script. 8 | import time 9 | import io 10 | import threading 11 | import picamera 12 | 13 | 14 | class Camera(object): 15 | thread = None # background thread that reads frames from camera 16 | frame = None # current frame is stored here by background thread 17 | last_access = 0 # time of last client access to the camera 18 | 19 | def initialize(self): 20 | if Camera.thread is None: 21 | # start background frame thread 22 | Camera.thread = threading.Thread(target=self._thread) 23 | Camera.thread.start() 24 | 25 | # wait until frames start to be available 26 | while self.frame is None: 27 | time.sleep(0) 28 | 29 | def get_frame(self): 30 | Camera.last_access = time.time() 31 | self.initialize() 32 | return self.frame 33 | 34 | @classmethod 35 | def _thread(cls): 36 | with picamera.PiCamera() as camera: 37 | # camera setup 38 | camera.resolution = (320, 240) 39 | camera.hflip = True 40 | camera.vflip = True 41 | 42 | # let camera warm up 43 | camera.start_preview() 44 | time.sleep(2) 45 | 46 | stream = io.BytesIO() 47 | for foo in camera.capture_continuous(stream, 'jpeg', 48 | use_video_port=True): 49 | # store frame 50 | stream.seek(0) 51 | cls.frame = stream.read() 52 | 53 | # reset stream for next frame 54 | stream.seek(0) 55 | stream.truncate() 56 | 57 | # if there hasn't been any clients asking for frames in 58 | # the last 10 seconds stop the thread 59 | if time.time() - cls.last_access > 10: 60 | break 61 | cls.thread = None -------------------------------------------------------------------------------- /data/dataJ.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"run":"to get data"} 3 | ] -------------------------------------------------------------------------------- /data/dataRaw.csv: -------------------------------------------------------------------------------- 1 | 2019-04-23, 01:22:01.874030, 80000000, 85000000, 98039.22, 204, -58.89, -57.47, -60.69, -74.38, -67.06, -62.17, -67.63, -60.90, -64.32, -60.98, -61.31, -76.06, -62.70, -60.75, -67.61, -63.74, -62.13, -66.44, -70.70, -63.94, -67.85, -67.55, -71.59, -62.99, -58.10, -62.29, -75.70, -65.02, -58.01, -66.02, -67.69, -60.13, -60.40, -51.76, -56.73, -72.56, -61.46, -60.74, -61.93, -60.89, -65.01, -62.15, -58.78, -74.84, -64.60, -69.34, -62.76, -67.46, -65.21, -72.61, -61.52 2 | 2019-04-23, 01:22:01.874030, 90000000, 95000000, 98039.22, 204, -65.75, -66.84, -68.99, -67.65, -72.22, -71.24, -65.22, -64.26, -65.58, -74.62, -66.39, -67.78, -68.36, -69.12, -62.78, -64.13, -73.29, -64.91, -62.99, -80.15, -68.74, -63.23, -61.88, -70.07, -68.04, -65.31, -60.82, -61.35, -71.92, -62.94, -62.79, -65.36, -51.79, -44.91, -49.06, -69.13, -66.07, -61.26, -69.27, -73.67, -73.32, -66.85, -75.24, -67.22, -65.38, -65.88, -78.28, -64.96, -65.59, -62.85, -71.23 3 | 2019-04-23, 01:22:01.874030, 85000000, 90000000, 98039.22, 204, -69.69, -75.78, -76.40, -66.33, -74.70, -73.33, -70.55, -69.86, -71.06, -76.82, -74.41, -64.86, -68.17, -70.40, -74.03, -72.28, -70.84, -72.76, -69.89, -64.98, -72.03, -69.62, -76.13, -74.07, -77.32, -78.35, -72.43, -75.10, -69.48, -77.55, -76.94, -75.93, -72.58, -83.01, -68.23, -64.24, -62.52, -62.68, -63.93, -69.68, -78.98, -69.74, -70.99, -68.35, -65.64, -70.56, -73.43, -73.34, -69.15, -66.52, -53.03 4 | 2019-04-23, 01:22:01.874030, 95000000, 100000000, 98039.22, 204, -71.18, -79.22, -75.76, -69.09, -72.96, -64.64, -63.65, -67.03, -67.45, -71.67, -76.52, -73.62, -77.78, -77.80, -74.38, -71.03, -71.91, -69.11, -67.88, -72.54, -78.61, -78.25, -75.71, -75.90, -76.21, -80.99, -66.80, -63.08, -66.31, -74.24, -65.05, -72.32, -66.33, -66.11, -75.50, -73.39, -71.44, -66.77, -78.15, -71.18, -72.90, -64.81, -60.41, -59.48, -66.07, -75.21, -76.22, -72.60, -71.83, -63.54, -51.60 5 | 2019-04-23, 01:22:01.874030, 100000000, 105000000, 98039.22, 204, -54.64, -68.23, -71.78, -73.83, -67.09, -65.90, -67.43, -70.09, -68.66, -71.07, -72.63, -74.19, -77.10, -72.75, -71.26, -68.90, -70.20, -70.72, -70.60, -81.02, -66.26, -69.24, -66.87, -65.34, -67.60, -70.74, -75.56, -77.04, -76.93, -76.24, -66.82, -66.31, -51.70, -44.33, -47.63, -57.55, -35.01, -26.12, -29.47, -50.78, -60.42, -68.33, -74.23, -74.22, -70.35, -74.64, -71.41, -66.26, -61.73, -61.92, -69.22 6 | 2019-04-23, 01:22:01.874030, 110000000, 115000000, 98039.22, 204, -52.76, -77.13, -74.97, -67.60, -82.62, -78.56, -76.92, -64.47, -63.35, -66.88, -68.14, -67.99, -67.23, -69.77, -73.20, -64.47, -69.08, -84.60, -72.69, -68.92, -63.04, -67.06, -69.81, -74.41, -67.43, -64.28, -67.68, -68.21, -72.25, -71.74, -66.91, -70.63, -67.35, -63.11, -70.89, -67.08, -81.92, -63.93, -60.34, -61.61, -71.81, -84.74, -72.85, -70.18, -67.53, -64.91, -61.93, -63.99, -76.18, -64.58, -61.62 7 | 2019-04-23, 01:22:01.874030, 105000000, 110000000, 98039.22, 204, -71.89, -68.10, -75.95, -85.31, -79.30, -72.93, -71.37, -73.63, -72.80, -69.00, -67.47, -75.31, -75.03, -73.84, -67.13, -65.41, -75.90, -83.77, -71.18, -69.39, -80.17, -77.48, -68.22, -63.97, -64.70, -65.63, -61.85, -66.37, -67.09, -69.07, -89.27, -81.56, -79.56, -90.35, -80.92, -74.67, -74.24, -72.20, -68.05, -64.18, -62.22, -64.16, -64.75, -71.65, -68.34, -66.22, -72.73, -74.74, -70.27, -68.69, -51.98 8 | 2019-04-23, 01:22:01.874030, 115000000, 120000000, 98039.22, 204, -59.46, -70.13, -65.11, -67.25, -70.91, -67.37, -81.73, -72.91, -82.75, -72.11, -79.33, -72.44, -76.63, -65.56, -62.30, -59.80, -61.48, -67.27, -67.12, -69.49, -67.60, -75.95, -66.55, -63.53, -62.31, -73.58, -63.34, -61.92, -66.69, -61.57, -59.74, -61.92, -64.81, -65.81, -64.67, -75.08, -74.77, -63.61, -66.59, -68.94, -66.66, -80.13, -70.98, -68.14, -62.13, -57.70, -61.16, -73.66, -64.51, -57.75, -46.91 9 | 2019-04-23, 01:22:01.874030, 120000000, 125000000, 98039.22, 204, -49.34, -59.95, -59.36, -68.35, -78.92, -82.62, -72.83, -71.88, -73.19, -69.03, -61.84, -66.51, -67.11, -70.05, -73.00, -66.35, -67.02, -68.36, -72.97, -73.90, -107.87, -68.97, -63.01, -65.94, -68.24, -64.55, -67.00, -78.97, -67.55, -67.76, -65.13, -71.54, -73.70, -69.95, -69.15, -78.14, -68.37, -64.11, -64.16, -67.03, -64.47, -56.94, -61.18, -75.41, -76.27, -69.18, -60.11, -59.83, -61.31, -58.68, -59.24 10 | 2019-04-23, 01:22:01.874030, 130000000, 135000000, 98039.22, 204, -54.59, -66.44, -67.90, -64.88, -68.53, -72.22, -73.66, -74.39, -67.70, -64.21, -69.78, -73.97, -71.04, -67.25, -65.92, -63.27, -63.91, -65.07, -64.67, -67.60, -67.61, -68.58, -73.03, -72.39, -68.27, -65.24, -67.03, -79.58, -67.16, -62.54, -56.92, -57.88, -63.33, -69.91, -69.25, -75.51, -81.07, -74.65, -66.55, -69.78, -67.40, -70.61, -64.85, -69.09, -68.29, -65.42, -61.70, -60.27, -67.38, -69.09, -69.24 11 | 2019-04-23, 01:22:01.874030, 125000000, 130000000, 98039.22, 204, -61.27, -62.81, -58.50, -55.63, -59.77, -60.15, -58.97, -63.06, -63.17, -63.09, -70.26, -63.05, -67.83, -68.07, -63.00, -65.98, -65.46, -69.66, -70.12, -63.97, -69.79, -68.36, -66.38, -68.49, -72.46, -71.57, -74.43, -63.69, -65.60, -64.51, -66.89, -73.78, -67.45, -63.87, -57.67, -56.22, -61.82, -62.59, -66.01, -69.31, -67.86, -68.08, -72.31, -64.82, -67.19, -64.47, -78.10, -78.76, -65.15, -71.28, -61.32 12 | 2019-04-23, 01:22:01.874030, 135000000, 140000000, 98039.22, 204, -70.56, -70.89, -76.16, -59.16, -56.70, -61.60, -66.64, -76.45, -73.38, -70.74, -59.47, -64.57, -61.32, -62.49, -65.13, -63.89, -67.01, -68.53, -75.84, -74.29, -74.49, -74.80, -70.43, -78.23, -75.17, -66.41, -68.13, -68.28, -63.00, -63.47, -68.35, -76.89, -72.66, -77.09, -65.26, -63.96, -65.73, -68.48, -72.99, -69.94, -73.98, -72.67, -73.99, -69.93, -65.63, -68.41, -69.01, -66.44, -75.03, -65.52, -55.85 13 | 2019-04-23, 01:22:01.874030, 140000000, 145000000, 98039.22, 204, -54.51, -66.56, -66.65, -65.44, -73.25, -71.91, -65.13, -68.74, -75.82, -71.19, -72.03, -74.29, -66.45, -64.28, -70.44, -64.54, -63.45, -71.46, -68.06, -63.93, -64.94, -68.53, -69.20, -65.01, -66.32, -68.36, -75.80, -65.49, -66.24, -66.22, -66.34, -67.94, -66.84, -63.02, -65.79, -74.37, -70.92, -65.02, -63.92, -62.74, -68.88, -70.63, -77.08, -68.92, -68.80, -75.81, -62.38, -60.77, -65.77, -75.94, -71.63 14 | 2019-04-23, 01:22:01.874030, 150000000, 155000000, 98039.22, 204, -61.06, -75.54, -74.24, -74.44, -66.01, -69.46, -79.22, -69.66, -75.67, -73.83, -71.72, -67.53, -63.20, -66.60, -70.86, -65.63, -75.21, -78.09, -81.60, -70.15, -68.17, -69.22, -72.94, -71.13, -71.86, -75.56, -79.73, -72.81, -72.37, -76.50, -63.18, -59.55, -62.71, -69.14, -70.13, -70.04, -71.98, -77.09, -63.90, -61.47, -68.66, -74.18, -66.61, -65.17, -71.24, -76.56, -68.97, -63.48, -68.66, -64.14, -66.90 15 | 2019-04-23, 01:22:01.874030, 145000000, 150000000, 98039.22, 204, -60.47, -62.50, -67.10, -61.17, -60.57, -70.73, -66.40, -70.63, -64.57, -70.57, -68.87, -62.62, -62.49, -69.23, -72.41, -76.34, -73.74, -69.00, -71.47, -64.00, -78.46, -71.34, -80.84, -89.91, -69.66, -66.43, -67.67, -65.58, -75.76, -67.23, -75.89, -74.83, -75.57, -66.74, -67.26, -78.02, -72.20, -78.71, -71.20, -69.76, -72.76, -70.82, -75.53, -63.95, -69.25, -79.56, -70.93, -65.99, -66.69, -77.98, -67.05 16 | 2019-04-23, 01:22:01.874030, 155000000, 160000000, 98039.22, 204, -66.87, -72.18, -71.87, -60.71, -59.26, -67.03, -77.32, -66.65, -71.43, -71.35, -82.50, -77.75, -70.70, -72.29, -69.04, -66.99, -63.73, -70.96, -78.22, -61.75, -62.70, -72.61, -72.82, -74.59, -70.26, -64.39, -63.00, -63.06, -70.06, -74.06, -72.14, -86.36, -73.47, -72.86, -73.95, -72.15, -77.09, -74.09, -71.45, -68.92, -68.12, -65.54, -64.80, -77.09, -72.02, -69.91, -84.64, -75.91, -70.94, -68.16, -53.81 17 | -------------------------------------------------------------------------------- /getHackRFData.py: -------------------------------------------------------------------------------- 1 | import subprocess #allows for the use of terminal commands to be executed 2 | import csv #to enable the ability to read and write CSV files 3 | import json #to enable the ability to read and write JSON files 4 | 5 | class HackRF: #init function for the hackrf see the server file for explination 6 | def __init__(self, dataPath, range, bandwidth): 7 | self.dataPath = dataPath 8 | self.range = range 9 | self.bandwidth = bandwidth 10 | 11 | def getData(self): #calls the hackrf_sweep command to get the RF signal data in your area these parms can be explained in the HackRf One Documentaion 12 | subprocess.call(['hackrf_sweep', '-r', str(self.dataPath), '-f', str(self.range), '-w', str(self.bandwidth), '-1']) 13 | subprocess.call(['hackrf_spiflash','-R']) 14 | 15 | def sendData(self, rfRange): #send a blank audio file to block a RF signal parms can be explained in the HackRf One Documentaion 16 | subprocess.call(['hackrf_transfer', '-t', 'testFile2.wav', '-f', str(rfRange), '-p', '1', '-a', '1', '-x', '28', '-s', '1']) 17 | 18 | def csvToJson(self, csvPath, jsonPath): #converts the CSV file the HackRF One produces in the above fintion into a json file 19 | csvfile = open(str(csvPath), 'r') 20 | jsonfile = open(str(jsonPath), 'w') 21 | fieldnames = ("date","time","hz_low","hz_high","bandwidth","samples","DB1","DB2","DB3","DB4","DB5","DB6","DB7","DB8","DB9","DB10","DB11","DB12","DB13","DB14","DB15","DB16","DB17","DB18","DB19","DB20","DB21","DB22","DB23","DB24","DB25","DB26","DB27","DB28","DB29","DB30","DB31","DB32","DB33","DB34","DB35","DB36","DB37","DB38","DB39","DB40","DB41","DB42","DB43","DB44","DB45","DB46","DB47","DB48","DB49","DB50","DB51") 22 | reader = csv.DictReader(csvfile, fieldnames) 23 | jsonfile.write('[') 24 | jsonfile.write('\n') 25 | First = True 26 | for row in reader: 27 | if First == True: 28 | First = False 29 | else: 30 | jsonfile.write(',') 31 | jsonfile.write('\n') 32 | json.dump(row, jsonfile) 33 | jsonfile.write('\n') 34 | jsonfile.write(']') 35 | 36 | def load(self, jsonPath): #reads in the json file and returns it as an object 37 | with open(str(jsonPath), 'r') as f: 38 | distros_dict = json.load(f) 39 | return distros_dict 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /static/boost.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highcharts JS v7.0.3 (2019-02-06) 3 | Boost module 4 | 5 | (c) 2010-2019 Highsoft AS 6 | Author: Torstein Honsi 7 | 8 | License: www.highcharts.com/license 9 | */ 10 | (function(u){"object"===typeof module&&module.exports?(u["default"]=u,module.exports=u):"function"===typeof define&&define.amd?define(function(){return u}):u("undefined"!==typeof Highcharts?Highcharts:void 0)})(function(u){(function(l){function u(){var a=Array.prototype.slice.call(arguments),c=-Number.MAX_VALUE;a.forEach(function(a){if("undefined"!==typeof a&&null!==a&&"undefined"!==typeof a.length&&0=(b.options.boostThreshold||Number.MAX_VALUE)&&++c);a.boostForceChartBoost=f&&(d===a.series.length&&0g||0>c)c=0;if(!d||d>g)d=g;a.drawArrays(a[(e||"points").toUpperCase()],c/h,(d-c)/h);return!0},allocate:function(a){k=-1;m= 19 | new Float32Array(4*a)},push:function(a,b,c,d){m&&(m[++k]=a,m[++k]=b,m[++k]=c,m[++k]=d)}}}function qa(a){function c(a){var b,c;return a.isSeriesBoosting?(b=!!a.options.stacking,c=a.xData||a.options.xData||a.processedXData,b=(b?a.data:c||a.options.data).length,"treemap"===a.type?b*=12:"heatmap"===a.type?b*=6:fa[a.type]&&(b*=2),b):0}function d(){e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}function f(a,b){function c(a){a&&(b.colorData.push(a[0]),b.colorData.push(a[1]),b.colorData.push(a[2]),b.colorData.push(a[3]))} 20 | function e(a,b,e,d,w){c(w);q.usePreallocated?D.push(a,b,e?1:0,d||1):(B.push(a),B.push(b),B.push(e?1:0),B.push(d||1))}function d(){b.segments.length&&(b.segments[b.segments.length-1].to=B.length)}function w(){b.segments.length&&b.segments[b.segments.length-1].from===B.length||(d(),b.segments.push({from:B.length}))}function g(a,b,d,w,g){c(g);e(a+d,b);c(g);e(a,b);c(g);e(a,b+w);c(g);e(a,b+w);c(g);e(a+d,b+w);c(g);e(a+d,b)}function f(a,c){q.useGPUTranslations||(b.skipTranslation=!0,a.x=y.toPixels(a.x,!0), 21 | a.y=z.toPixels(a.y,!0));c?B=[a.x,a.y,0,2].concat(B):e(a.x,a.y,0,2)}var ha=a.pointArrayMap&&"low,high"===a.pointArrayMap.join(","),h=a.chart,O=a.options,m=!!O.stacking,k=O.data,S=a.xAxis.getExtremes(),N=S.min,S=S.max,p=a.yAxis.getExtremes(),v=p.min,p=p.max,n=a.xData||O.xData||a.processedXData,A=a.yData||O.yData||a.processedYData,u=a.zData||O.zData||a.processedZData,z=a.yAxis,y=a.xAxis,F=a.chart.plotHeight,I=a.chart.plotWidth,G=!n||0===n.length,H=O.connectNulls,r=a.points||!1,Q=!1,J=!1,x,T,U,k=m?a.data: 22 | n||k,n={x:Number.MAX_VALUE,y:0},K={x:-Number.MAX_VALUE,y:0},L=0,M=!1,t,ca,E=-1,Z=!1,aa=!1,ba,W="undefined"===typeof h.index,X=!1,da=!1,V=fa[a.type],ea=!1,P=!0,ga=!0,R=O.threshold;if(!(O.boostData&&0b.node.levelDynamic)return 1;if(a.node.levelDynamic< 23 | b.node.levelDynamic)return-1}return 0}),r.forEach(function(b){var c=b.plotY,e;"undefined"===typeof c||isNaN(c)||null===b.y||(c=b.shapeArgs,e=h.styledMode?b.series.colorAttribs(b):e=b.series.pointAttribs(b),b=e["stroke-width"]||0,T=l.color(e.fill).rgba,T[0]/=255,T[1]/=255,T[2]/=255,"treemap"===a.type&&(b=b||1,U=l.color(e.stroke).rgba,U[0]/=255,U[1]/=255,U[2]/=255,g(c.x,c.y,c.width,c.height,U),b/=2),"heatmap"===a.type&&h.inverted&&(c.x=y.len-c.x,c.y=z.len-c.y,c.width=-c.width,c.height=-c.height),g(c.x+ 24 | b,c.y+b,c.width-2*b,c.height-2*b,T))});else{for(;Eb.zMax&&(b.zMax=x[2]),x[2]b.zMax&&(b.zMax=u[E]),u[E]=N&&aa<=S&&(X=!0),Z&&Z>=N&&Z<=S&&(da=!0),ha?(G&&(t=x.slice(1,3)),ba=t[0],t=t[1]):m&&(r=x.x,t=x.stackY,ba=t-x.y), 25 | null!==v&&"undefined"!==typeof v&&null!==p&&"undefined"!==typeof p&&(P=t>=v&&t<=p),r>S&&K.xN&&(n.x=r,n.y=t),null!==t||!H)if(null!==t&&(P||X||da)){if(r>=N&&r<=S&&(ea=!0),ea||X||da){if(!q.useGPUTranslations&&(b.skipTranslation=!0,r=y.toPixels(r,!0),t=z.toPixels(t,!0),t>F&&(t=F),r>I&&"points"===b.drawMode))continue;if(V){x=ba;if(!1===ba||"undefined"===typeof ba)x=0>t?t:0;ha||m||(x=Math.max(R,v));q.useGPUTranslations||(x=z.toPixels(x,!0));e(r,x,0,0,!1)}b.hasMarkers&&ea&&!1!== 26 | Q&&(a.closestPointRangePx=Math.min(a.closestPointRangePx,Math.abs(r-Q)));!q.useGPUTranslations&&!q.usePreallocated&&Q&&1>Math.abs(r-Q)&&J&&1>Math.abs(t-J)?q.debug.showSkipSummary&&++L:(O.step&&!ga&&e(r,J,0,2,!1),e(r,t,0,"bubble"===a.type?ca||1:2,!1),Q=r,J=t,M=!0,ga=!1)}}else w()}else w()}q.debug.showSkipSummary&&console.log("skipped points:",L);M||!1===H||"line_strip"!==a.drawMode||(n.x-Number.MAX_VALUE&&f(K))}d()}}function b(){v=[];y.data=B=[];u=[];D&&D.destroy()}function k(a){g&& 27 | (g.setUniform("xAxisTrans",a.transA),g.setUniform("xAxisMin",a.min),g.setUniform("xAxisMinPad",a.minPixelPadding),g.setUniform("xAxisPointRange",a.pointRange),g.setUniform("xAxisLen",a.len),g.setUniform("xAxisPos",a.pos),g.setUniform("xAxisCVSCoord",!a.horiz))}function h(a){g&&(g.setUniform("yAxisTrans",a.transA),g.setUniform("yAxisMin",a.min),g.setUniform("yAxisMinPad",a.minPixelPadding),g.setUniform("yAxisPointRange",a.pointRange),g.setUniform("yAxisLen",a.len),g.setUniform("yAxisPos",a.pos),g.setUniform("yAxisCVSCoord", 28 | !a.horiz))}function m(a,b){g.setUniform("hasThreshold",a);g.setUniform("translatedThreshold",b)}function p(c){if(c)z=c.chartWidth||800,A=c.chartHeight||400;else return!1;if(!(e&&z&&A&&g))return!1;q.debug.timeRendering&&console.time("gl rendering");e.canvas.width=z;e.canvas.height=A;g.bind();e.viewport(0,0,z,A);g.setPMatrix([2/z,0,0,0,0,-(2/A),0,0,0,0,-2,0,-1,1,-1,1]);g.setPlotHeight(c.plotHeight);12*((d.marker?d.marker.radius:10)||10)),f=F[f&&f.symbol||a.series.symbol]||F.circle;if(!(0===a.segments.length||a.segmentslength&&a.segments[0].from===a.segments[0].to)){f.isReady&&(e.bindTexture(e.TEXTURE_2D,f.handle),g.setTexture(f.handle)); 30 | c.styledMode?f=a.series.markerGroup&&a.series.markerGroup.getStyle("fill"):(f=a.series.pointAttribs&&a.series.pointAttribs().fill||a.series.color,d.colorByPoint&&(f=a.series.chart.options.colors[b]));a.series.fillOpacity&&d.fillOpacity&&(f=(new ia(f)).setOpacity(G(d.fillOpacity,1)).get());f=l.color(f).rgba;q.useAlpha||(f[3]=1);"lines"===a.drawMode&&q.useAlpha&&1>f[3]&&(f[3]/=10);"add"===d.boostBlending?(e.blendFunc(e.SRC_ALPHA,e.ONE),e.blendEquation(e.FUNC_ADD)):"mult"===d.boostBlending||"multiply"=== 31 | d.boostBlending?e.blendFunc(e.DST_COLOR,e.ZERO):"darken"===d.boostBlending?(e.blendFunc(e.ONE,e.ONE),e.blendEquation(e.FUNC_MIN)):e.blendFuncSeparate(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);g.reset();0=(d.options.boostThreshold||Number.MAX_VALUE)}var d=this,f=this.options.data;P(this.chart)&&H[this.type]?(c(f)&&"heatmap"!==this.type&&"treemap"!==this.type&&!this.options.stacking&&this.hasExtremes&&this.hasExtremes(!0)||(a.apply(this,Array.prototype.slice.call(arguments,1)), 56 | f=this.processedXData),(this.isSeriesBoosting=c(f))?this.enterBoost():this.exitBoost&&this.exitBoost()):a.apply(this,Array.prototype.slice.call(arguments,1))});M(p,"hide",function(){this.canvas&&this.renderTarget&&(this.ogl&&this.ogl.clear(),this.boostClear())});p.prototype.enterBoost=function(){this.alteredByBoost=[];["allowDG","directTouch","stickyTracking"].forEach(function(a){this.alteredByBoost.push({prop:a,val:this[a],own:this.hasOwnProperty(a)})},this);this.directTouch=this.allowDG=!1;this.stickyTracking= 57 | !0;this.animate=null;this.labelBySeries&&(this.labelBySeries=this.labelBySeries.destroy())};p.prototype.exitBoost=function(){(this.alteredByBoost||[]).forEach(function(a){a.own?this[a.prop]=a.val:delete this[a.prop]},this);this.boostClear&&this.boostClear()};p.prototype.hasExtremes=function(a){var c=this.options,d=this.xAxis&&this.xAxis.options,f=this.yAxis&&this.yAxis.options;return c.data.length>(c.boostThreshold||Number.MAX_VALUE)&&J(f.min)&&J(f.max)&&(!a||J(d.min)&&J(d.max))};p.prototype.destroyGraphics= 58 | function(){var a=this,c=this.points,d,f;if(c)for(f=0;f=z&&d<=A),null!==d&&c>=u&&c<=e&&l))if(a=h.toPixels(c,!0),K){if(void 0===Y||a===y){G||(f=d);if(void 0===C||d>M)M=d,C=b;if(void 0===Y||fe?.5:c/(e-1))})},setTickPositions:function(){if(!this.dataClasses)return k.prototype.setTickPositions.call(this)},initStops:function(){this.stops=this.options.stops||[[0,this.options.minColor],[1,this.options.maxColor]];this.stops.forEach(function(a){a.color=l(a[1])})},setOptions:function(a){k.prototype.setOptions.call(this,a);this.options.crosshair= 12 | this.options.marker},setAxisSize:function(){var a=this.legendSymbol,d=this.chart,f=d.options.legend||{},g,m;a?(this.left=f=a.attr("x"),this.top=g=a.attr("y"),this.width=m=a.attr("width"),this.height=a=a.attr("height"),this.right=d.chartWidth-f-m,this.bottom=d.chartHeight-g-a,this.len=this.horiz?m:a,this.pos=this.horiz?f:g):this.len=(this.horiz?f.symbolWidth:f.symbolHeight)||this.defaultLegendLength},normalizedValue:function(a){this.isLog&&(a=this.val2lin(a));return 1-(this.max-a)/(this.max-this.min|| 13 | 1)},toColor:function(a,d){var f=this.stops,g,m,b=this.dataClasses,c,e;if(b)for(e=b.length;e--;){if(c=b[e],g=c.from,f=c.to,(void 0===g||a>=g)&&(void 0===f||a<=f)){m=c.color;d&&(d.dataClass=e,d.colorIndex=c.colorIndex);break}}else{a=this.normalizedValue(a);for(e=f.length;e--&&!(a>f[e][0]););g=f[e]||f[e+1];f=f[e+1]||g;a=1-(f[0]-a)/(f[0]-g[0]||1);m=g.color.tweenTo(f.color,a)}return m},getOffset:function(){var a=this.legendGroup,d=this.chart.axisOffset[this.side];a&&(this.axisParent=a,k.prototype.getOffset.call(this), 14 | this.added||(this.added=!0,this.labelLeft=0,this.labelRight=this.width),this.chart.axisOffset[this.side]=d)},setLegendColor:function(){var a,d=this.reversed;a=d?1:0;d=d?0:1;a=this.horiz?[a,0,d,0]:[0,d,0,a];this.legendColor={linearGradient:{x1:a[0],y1:a[1],x2:a[2],y2:a[3]},stops:this.stops}},drawLegendSymbol:function(a,d){var f=a.padding,g=a.options,e=this.horiz,c=t(g.symbolWidth,e?this.defaultLegendLength:12),b=t(g.symbolHeight,e?12:this.defaultLegendLength),l=t(g.labelPadding,e?16:30),g=t(g.itemDistance, 15 | 10);this.setLegendColor();d.legendSymbol=this.chart.renderer.rect(0,a.baseline-11,c,b).attr({zIndex:1}).add(d.legendGroup);this.legendItemWidth=c+f+(e?g:l);this.legendItemHeight=b+f+(e?l:0)},setState:function(a){this.series.forEach(function(d){d.setState(a)})},visible:!0,setVisible:v,getSeriesExtremes:function(){var a=this.series,d=a.length;this.dataMin=Infinity;for(this.dataMax=-Infinity;d--;)a[d].getExtremes(),void 0!==a[d].valueMin&&(this.dataMin=Math.min(this.dataMin,a[d].valueMin),this.dataMax= 16 | Math.max(this.dataMax,a[d].valueMax))},drawCrosshair:function(a,d){var f=d&&d.plotX,e=d&&d.plotY,c,b=this.pos,l=this.len;d&&(c=this.toPixels(d[d.series.colorKey]),cb+l&&(c=b+l+2),d.plotX=c,d.plotY=this.len-c,k.prototype.drawCrosshair.call(this,a,d),d.plotX=f,d.plotY=e,this.cross&&!this.cross.addedToColorAxis&&this.legendGroup&&(this.cross.addClass("highcharts-coloraxis-marker").add(this.legendGroup),this.cross.addedToColorAxis=!0,this.chart.styledMode||this.cross.attr({fill:this.crosshair.color})))}, 17 | getPlotLinePath:function(a,d,f,e,c){return p(c)?this.horiz?["M",c-4,this.top-6,"L",c+4,this.top-6,c,this.top,"Z"]:["M",this.left,c,"L",this.left-6,c+6,this.left-6,c-6,"Z"]:k.prototype.getPlotLinePath.call(this,a,d,f,e)},update:function(a,d){var c=this.chart,e=c.legend;this.series.forEach(function(a){a.isDirtyData=!0});a.dataClasses&&e.allItems&&(e.allItems.forEach(function(a){a.isDataClass&&a.legendGroup&&a.legendGroup.destroy()}),c.isDirtyLegend=!0);c.options[this.coll]=u(this.userOptions,a);k.prototype.update.call(this, 18 | a,d);this.legendItem&&(this.setLegendColor(),e.colorizeItem(this,!0))},remove:function(){this.legendItem&&this.chart.legend.destroyItem(this);k.prototype.remove.call(this)},getDataClassLegendSymbols:function(){var a=this,d=this.chart,e=this.legendItems,g=d.options.legend,l=g.valueDecimals,n=g.valueSuffix||"",h;e.length||this.dataClasses.forEach(function(f,g){var k=!0,m=f.from,p=f.to;h="";void 0===m?h="\x3c ":void 0===p&&(h="\x3e ");void 0!==m&&(h+=b.numberFormat(m,l)+n);void 0!==m&&void 0!==p&&(h+= 19 | " - ");void 0!==p&&(h+=b.numberFormat(p,l)+n);e.push(r({chart:d,name:h,options:{},drawLegendSymbol:c.drawRectangle,visible:!0,setState:v,isDataClass:!0,setVisible:function(){k=this.visible=!k;a.series.forEach(function(a){a.points.forEach(function(a){a.dataClass===g&&a.setVisible(k)})});d.legend.colorizeItem(this,k)}},f))});return e},name:""}),["fill","stroke"].forEach(function(a){b.Fx.prototype[a+"Setter"]=function(){this.elem.attr(a,l(this.start).tweenTo(l(this.end),this.pos),null,!0)}}),h(q,"afterGetAxes", 20 | function(){var a=this.options.colorAxis;this.colorAxis=[];a&&new n(this,a)}),h(e,"afterGetAllItems",function(a){var d=[],c=this.chart.colorAxis[0];c&&c.options&&c.options.showInLegend&&(c.options.dataClasses?d=c.getDataClassLegendSymbols():d.push(c),c.series.forEach(function(c){b.erase(a.allItems,c)}));for(c=d.length;c--;)a.allItems.unshift(d[c])}),h(e,"afterColorizeItem",function(a){a.visible&&a.item.legendColor&&a.item.legendSymbol.attr({fill:a.item.legendColor})}),h(e,"afterUpdate",function(a, 21 | c,e){this.chart.colorAxis[0]&&this.chart.colorAxis[0].update({},e)}))})(h);(function(b){var h=b.defined,k=b.noop,q=b.seriesTypes;b.colorPointMixin={isValid:function(){return null!==this.value&&Infinity!==this.value&&-Infinity!==this.value},setVisible:function(b){var l=this,h=b?"show":"hide";l.visible=!!b;["graphic","dataLabel"].forEach(function(b){if(l[b])l[b][h]()})},setState:function(l){b.Point.prototype.setState.call(this,l);this.graphic&&this.graphic.attr({zIndex:"hover"===l?1:0})}};b.colorSeriesMixin= 22 | {pointArrayMap:["value"],axisTypes:["xAxis","yAxis","colorAxis"],optionalAxis:"colorAxis",trackerGroups:["group","markerGroup","dataLabelsGroup"],getSymbol:k,parallelArrays:["x","y","value"],colorKey:"value",pointAttribs:q.column.prototype.pointAttribs,translateColors:function(){var b=this,h=this.options.nullColor,k=this.colorAxis,p=this.colorKey;this.data.forEach(function(e){var c=e[p];if(c=e.options.color||(e.isNull?h:k&&void 0!==c?k.toColor(c,e):e.color||b.color))e.color=c})},colorAttribs:function(b){var l= 23 | {};h(b.color)&&(l[this.colorProp||"fill"]=b.color);return l}}})(h);(function(b){var h=b.colorPointMixin,k=b.merge,q=b.noop,l=b.pick,n=b.Series,r=b.seriesType,p=b.seriesTypes;r("heatmap","scatter",{animation:!1,borderWidth:0,nullColor:"#f7f7f7",dataLabels:{formatter:function(){return this.point.value},inside:!0,verticalAlign:"middle",crop:!1,overflow:!1,padding:0},marker:null,pointRange:null,tooltip:{pointFormat:"{point.x}, {point.y}: {point.value}\x3cbr/\x3e"},states:{hover:{halo:!1,brightness:.2}}}, 24 | k(b.colorSeriesMixin,{pointArrayMap:["y","value"],hasPointSpecificOptions:!0,getExtremesFromAll:!0,directTouch:!0,init:function(){var e;p.scatter.prototype.init.apply(this,arguments);e=this.options;e.pointRange=l(e.pointRange,e.colsize||1);this.yAxis.axisPointRange=e.rowsize||1},translate:function(){var e=this.options,c=this.xAxis,b=this.yAxis,h=e.pointPadding||0,k=function(a,c,b){return Math.min(Math.max(c,a),b)},a=this.pointPlacementToXValue();this.generatePoints();this.points.forEach(function(d){var f= 25 | (e.colsize||1)/2,g=(e.rowsize||1)/2,m=k(Math.round(c.len-c.translate(d.x-f,0,1,0,1,-a)),-c.len,2*c.len),f=k(Math.round(c.len-c.translate(d.x+f,0,1,0,1,-a)),-c.len,2*c.len),p=k(Math.round(b.translate(d.y-g,0,1,0,1)),-b.len,2*b.len),g=k(Math.round(b.translate(d.y+g,0,1,0,1)),-b.len,2*b.len),n=l(d.pointPadding,h);d.plotX=d.clientX=(m+f)/2;d.plotY=(p+g)/2;d.shapeType="rect";d.shapeArgs={x:Math.min(m,f)+n,y:Math.min(p,g)+n,width:Math.abs(f-m)-2*n,height:Math.abs(g-p)-2*n}});this.translateColors()},drawPoints:function(){var b= 26 | this.chart.styledMode?"css":"attr";p.column.prototype.drawPoints.call(this);this.points.forEach(function(c){c.graphic[b](this.colorAttribs(c))},this)},getValidPoints:function(b,c){return n.prototype.getValidPoints.call(this,b,c,!0)},animate:q,getBox:q,drawLegendSymbol:b.LegendSymbolMixin.drawRectangle,alignDataLabel:p.column.prototype.alignDataLabel,getExtremes:function(){n.prototype.getExtremes.call(this,this.valueData);this.valueMin=this.dataMin;this.valueMax=this.dataMax;n.prototype.getExtremes.call(this)}}), 27 | b.extend({haloPath:function(b){if(!b)return[];var c=this.shapeArgs;return["M",c.x-b,c.y-b,"L",c.x-b,c.y+c.height+b,c.x+c.width+b,c.y+c.height+b,c.x+c.width+b,c.y-b,"Z"]}},h))})(h)}); 28 | //# sourceMappingURL=heatmap.js.map 29 | -------------------------------------------------------------------------------- /static/jquery-3.1.1.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */ 2 | !function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):C.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/[^\x20\t\r\n\f]+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R), 3 | a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,ka=/^$|\/(?:java|ecma)script/i,la={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};la.optgroup=la.option,la.tbody=la.tfoot=la.colgroup=la.caption=la.thead,la.th=la.td;function ma(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function na(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=ma(l.appendChild(f),"script"),j&&na(g),c){k=0;while(f=g[k++])ka.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var qa=d.documentElement,ra=/^key/,sa=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ta=/^([^.]*)(?:\.(.+)|)/;function ua(){return!0}function va(){return!1}function wa(){try{return d.activeElement}catch(a){}}function xa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)xa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=va;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(qa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,za=/\s*$/g;function Da(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Ea(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Fa(a){var b=Ba.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ga(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Aa.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ia(f,b,c,d)});if(m&&(e=pa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(ma(e,"script"),Ea),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=ma(h),f=ma(a),d=0,e=f.length;d0&&na(g,!i&&ma(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ja(this,a,!0)},remove:function(a){return Ja(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.appendChild(a)}})},prepend:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(ma(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!za.test(a)&&!la[(ja.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function Ya(a,b,c,d,e){return new Ya.prototype.init(a,b,c,d,e)}r.Tween=Ya,Ya.prototype={constructor:Ya,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Ya.propHooks[this.prop];return a&&a.get?a.get(this):Ya.propHooks._default.get(this)},run:function(a){var b,c=Ya.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ya.propHooks._default.set(this),this}},Ya.prototype.init.prototype=Ya.prototype,Ya.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Ya.propHooks.scrollTop=Ya.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Ya.prototype.init,r.fx.step={};var Za,$a,_a=/^(?:toggle|show|hide)$/,ab=/queueHooks$/;function bb(){$a&&(a.requestAnimationFrame(bb),r.fx.tick())}function cb(){return a.setTimeout(function(){Za=void 0}),Za=r.now()}function db(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ba[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function eb(a,b,c){for(var d,e=(hb.tweeners[b]||[]).concat(hb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?ib:void 0)), 4 | void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),ib={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=jb[b]||r.find.attr;jb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=jb[g],jb[g]=e,e=null!=c(a,b,d)?g:null,jb[g]=f),e}});var kb=/^(?:input|select|textarea|button)$/i,lb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):kb.test(a.nodeName)||lb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function mb(a){var b=a.match(K)||[];return b.join(" ")}function nb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,nb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,nb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,nb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=nb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(nb(c))+" ").indexOf(b)>-1)return!0;return!1}});var ob=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ob,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:mb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ia.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,"$1"),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("

Video Feed

Robot Controls

Commands

Select The RF Range To Scan:
Select The RF Range To Block:
{% endblock %} --------------------------------------------------------------------------------