diff --git a/content/js/meteorogram/package-lock.json b/content/js/meteorogram/package-lock.json
index 4f2b95b781f63ed5221c66f9090127e505eaf778..ee7832aa9f37ebf71a3d84e2d5c60bb3b48997ed 100644
--- a/content/js/meteorogram/package-lock.json
+++ b/content/js/meteorogram/package-lock.json
@@ -4372,6 +4372,12 @@
       "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
       "dev": true
     },
+    "infer-owner": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+      "dev": true
+    },
     "inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -6739,22 +6745,16 @@
       }
     },
     "terser": {
-      "version": "3.17.0",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
-      "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==",
+      "version": "4.6.3",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz",
+      "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==",
       "dev": true,
       "requires": {
-        "commander": "^2.19.0",
+        "commander": "^2.20.0",
         "source-map": "~0.6.1",
-        "source-map-support": "~0.5.10"
+        "source-map-support": "~0.5.12"
       },
       "dependencies": {
-        "commander": {
-          "version": "2.20.0",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
-          "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
-          "dev": true
-        },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -6762,9 +6762,9 @@
           "dev": true
         },
         "source-map-support": {
-          "version": "0.5.12",
-          "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
-          "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
+          "version": "0.5.16",
+          "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
+          "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
           "dev": true,
           "requires": {
             "buffer-from": "^1.0.0",
@@ -6774,44 +6774,40 @@
       }
     },
     "terser-webpack-plugin": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz",
-      "integrity": "sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA==",
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
+      "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
       "dev": true,
       "requires": {
-        "cacache": "^11.0.2",
-        "find-cache-dir": "^2.0.0",
+        "cacache": "^12.0.2",
+        "find-cache-dir": "^2.1.0",
+        "is-wsl": "^1.1.0",
         "schema-utils": "^1.0.0",
-        "serialize-javascript": "^1.4.0",
+        "serialize-javascript": "^2.1.2",
         "source-map": "^0.6.1",
-        "terser": "^3.16.1",
-        "webpack-sources": "^1.1.0",
-        "worker-farm": "^1.5.2"
+        "terser": "^4.1.2",
+        "webpack-sources": "^1.4.0",
+        "worker-farm": "^1.7.0"
       },
       "dependencies": {
-        "bluebird": {
-          "version": "3.5.4",
-          "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz",
-          "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==",
-          "dev": true
-        },
         "cacache": {
-          "version": "11.3.2",
-          "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz",
-          "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==",
+          "version": "12.0.3",
+          "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz",
+          "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==",
           "dev": true,
           "requires": {
-            "bluebird": "^3.5.3",
+            "bluebird": "^3.5.5",
             "chownr": "^1.1.1",
             "figgy-pudding": "^3.5.1",
-            "glob": "^7.1.3",
+            "glob": "^7.1.4",
             "graceful-fs": "^4.1.15",
+            "infer-owner": "^1.0.3",
             "lru-cache": "^5.1.1",
             "mississippi": "^3.0.0",
             "mkdirp": "^0.5.1",
             "move-concurrently": "^1.0.1",
             "promise-inflight": "^1.0.1",
-            "rimraf": "^2.6.2",
+            "rimraf": "^2.6.3",
             "ssri": "^6.0.1",
             "unique-filename": "^1.1.1",
             "y18n": "^4.0.0"
@@ -6837,10 +6833,24 @@
             "locate-path": "^3.0.0"
           }
         },
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
         "graceful-fs": {
-          "version": "4.1.15",
-          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
-          "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
           "dev": true
         },
         "locate-path": {
@@ -6872,28 +6882,10 @@
             "semver": "^5.6.0"
           }
         },
-        "mississippi": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
-          "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
-          "dev": true,
-          "requires": {
-            "concat-stream": "^1.5.0",
-            "duplexify": "^3.4.2",
-            "end-of-stream": "^1.1.0",
-            "flush-write-stream": "^1.0.0",
-            "from2": "^2.1.0",
-            "parallel-transform": "^1.1.0",
-            "pump": "^3.0.0",
-            "pumpify": "^1.3.3",
-            "stream-each": "^1.1.0",
-            "through2": "^2.0.0"
-          }
-        },
         "p-limit": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
-          "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+          "version": "2.2.2",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
+          "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
           "dev": true,
           "requires": {
             "p-try": "^2.0.0"
@@ -6923,31 +6915,16 @@
             "find-up": "^3.0.0"
           }
         },
-        "pump": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
-          "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-          "dev": true,
-          "requires": {
-            "end-of-stream": "^1.1.0",
-            "once": "^1.3.1"
-          }
-        },
-        "schema-utils": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
-          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
-          "dev": true,
-          "requires": {
-            "ajv": "^6.1.0",
-            "ajv-errors": "^1.0.0",
-            "ajv-keywords": "^3.1.0"
-          }
-        },
         "semver": {
-          "version": "5.7.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
-          "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        },
+        "serialize-javascript": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
+          "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
           "dev": true
         },
         "source-map": {
@@ -6956,13 +6933,14 @@
           "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
         },
-        "ssri": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
-          "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+        "webpack-sources": {
+          "version": "1.4.3",
+          "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+          "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
           "dev": true,
           "requires": {
-            "figgy-pudding": "^3.5.1"
+            "source-list-map": "^2.0.0",
+            "source-map": "~0.6.1"
           }
         },
         "y18n": {
@@ -6972,9 +6950,9 @@
           "dev": true
         },
         "yallist": {
-          "version": "3.0.3",
-          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
-          "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+          "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
           "dev": true
         }
       }
@@ -7899,9 +7877,9 @@
       }
     },
     "worker-farm": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
-      "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==",
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+      "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
       "dev": true,
       "requires": {
         "errno": "~0.1.7"
diff --git a/content/pages/instruments/aoss/cameras/hawkcam-flash.html b/content/pages/instruments/aoss/cameras/hawkcam-flash.html
index 1866e11980a3ab57329a35b5fe0d89d1ee41eda8..00afbb310d51c1c1b79045c80979b7f5cabb3a57 100644
--- a/content/pages/instruments/aoss/cameras/hawkcam-flash.html
+++ b/content/pages/instruments/aoss/cameras/hawkcam-flash.html
@@ -79,9 +79,9 @@ h3 + p {
 	<div id="resources" class="container">
 			<h3>Resources</h3>
 			<ul>
-				<li><a href="hawkcam/faq.html">Frequently Asked Questions</a></li>
+				<li><a href="{filename}hawkcam/faq.html">Frequently Asked Questions</a></li>
 				<li><a href="http://www.youtube.com/playlist?list=PL79FF32A040A90651&feature=mh_lol">SSEC Hawkcam Youtube Videos</a></li>
-				<li><a href="./hawkcam_images/">an assortment of hawkcam screenshots / pictures</a></li>
+				<li><a href="{static}hawkcam_images/">an assortment of hawkcam screenshots / pictures</a></li>
 				<li><a href="http://www.ssec.wisc.edu/news/topic/hawkcam">SSEC News articles on the hawkcam</a></li>
 				<li><a href="{filename}hawkcam/camera-details.html">Details about the HawkCam</a></li>
 				<li><a href="http://www.ssec.wisc.edu/news/topic/hawkcam/feed"><img src="http://www.ssec.wisc.edu/images/icon-rss.png" alt="RSS" border="0"> RSS</a></li>
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_0423_16.png b/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_0423_16.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e5a5438752086ac349300f6edd2c2883e488bb2
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_0423_16.png differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby1.png b/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby1.png
new file mode 100644
index 0000000000000000000000000000000000000000..a55f1842fa0f777a1ad282ce586efcc8eb8a1701
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby1.png differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby2.png b/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby2.png
new file mode 100644
index 0000000000000000000000000000000000000000..92196e8b7b0788b8fb6ab6a783282a1a486f4de1
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby2.png differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby5.png b/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby5.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae374be434f66bcd0acf4fd19207181ab9c07009
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby5.png differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/PastedGraphic-3.png b/content/pages/instruments/aoss/cameras/hawkcam_images/PastedGraphic-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..effc727db4e4b3422026f5fbda75da03003d83cd
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/PastedGraphic-3.png differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0000_Layer 21.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0000_Layer 21.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..899422dc38f9b8036bd6ca1d3285eba0a7beb548
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0000_Layer 21.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 10_2.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 10_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2975e5ce3372ac1ad96d6ff5a5cc2b2203c04169
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 10_2.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 20.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 20.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7fa2cddfa4fa6180d592e7a881df80200b0e7cc7
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 20.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0002_Layer 19.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0002_Layer 19.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..dcd24509094deb3af810cc53e0784294c45e1ed2
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0002_Layer 19.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0003_Layer 8_2.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0003_Layer 8_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..71cb1680abd5c5d448f6a2664ba4b5033a48df1c
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0003_Layer 8_2.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 16.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 16.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4924ac7ac764e4c17012be00fa9986e4d0e7f849
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 16.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 6_2.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 6_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e989c90a251105f9f7779af15448b21db3af375d
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 6_2.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0008_Layer 3_2.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0008_Layer 3_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..387c91a59a42bb71d66431d5a9685f6e61536476
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0008_Layer 3_2.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0010_Layer 11.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0010_Layer 11.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..16173e3b2ef312431484f09bcb7c503fb38a6a5e
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0010_Layer 11.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0011_Layer 10.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0011_Layer 10.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..82227c242aa46ade118cd17353d3d86352a53ee2
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0011_Layer 10.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0013_Layer 8.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0013_Layer 8.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..bb67b5fa13eb6e4a3146a19f56384e3c7ad972f3
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0013_Layer 8.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0019_Layer 2.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0019_Layer 2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1e4c0cb456e0f1aaa2c3673c5da8d19411ceebbc
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0019_Layer 2.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0020_Layer 1.jpg b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0020_Layer 1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5366831eb7eea22aaf4fda8e16f5e718fecf53b4
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0020_Layer 1.jpg differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m18s116.png b/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m18s116.png
new file mode 100644
index 0000000000000000000000000000000000000000..a988c0e854eca2f3a13f70f4f976b488e977d33d
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m18s116.png differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m23s171.png b/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m23s171.png
new file mode 100644
index 0000000000000000000000000000000000000000..5e2bbb6ada2cc753896537608f47fa97f54e00dc
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m23s171.png differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m20s143.png b/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m20s143.png
new file mode 100644
index 0000000000000000000000000000000000000000..0a51be3d6c696a151ebe52d73bc8af5f330a54b7
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m20s143.png differ
diff --git a/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m27s214.png b/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m27s214.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6a390d6526ca777b543617594c750b66d025736
Binary files /dev/null and b/content/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m27s214.png differ
diff --git a/htdocs/aoss/aeri/index.html b/htdocs/aoss/aeri/index.html
index 4e129c6ff64cd7f07edbdcf4edc8df2d64434137..06e2cf4e583b994192872a29f13aa2e0ee414197 100644
--- a/htdocs/aoss/aeri/index.html
+++ b/htdocs/aoss/aeri/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 
 
@@ -249,6 +248,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/cameras/hawkcam/details.html b/htdocs/aoss/cameras/hawkcam/details.html
index 83524e137f81666c5059dd2a600f9ba94a9c157e..ca28f27f122fd5c860a1ef97f8c43e39425e0a40 100644
--- a/htdocs/aoss/cameras/hawkcam/details.html
+++ b/htdocs/aoss/cameras/hawkcam/details.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <div class="container">
     <div class="row">
@@ -190,8 +189,8 @@ The flash applet that is used to display the video in the web page is
 <a href="http://www.longtailvideo.com/players/">JW Player</a>.
 <h3>Installation photos</h3>
 <table width="100%">
-<td><a href="/pages/instruments/aoss/cameras/hawkcam/hawkcam-install.jpg"><img src="/pages/instruments/aoss/cameras/hawkcam/hawkcam-install-thumb.jpg"></a><p>Nick Ciganovich installing the camera on the roof of Weeks Hall. <a href="/pages/instruments/aoss/cameras/hawkcam/hawkcam-install.jpg">Full size.</a></td>
-<td><a href="/pages/instruments/aoss/cameras/hawkcam/hawksnest_from_above.jpg"><img src="/pages/instruments/aoss/cameras/hawkcam/hawksnest_from_above-thumb.jpg"></a><p>View of the installed camera from the roof of the Atmospheric, Oceanic & Space Sciences Building next door. This is 12 stories above the nest. Photo by SSEC researcher Chris Schmidt. <a href="/pages/instruments/aoss/cameras/hawkcam/hawksnest_from_above.jpg">Full size.</a>
+<td><a href="https://metobs.ssec.wisc.edu/pages/instruments/aoss/cameras/hawkcam/hawkcam-install.jpg"><img src="https://metobs.ssec.wisc.edu/pages/instruments/aoss/cameras/hawkcam/hawkcam-install-thumb.jpg"></a><p>Nick Ciganovich installing the camera on the roof of Weeks Hall. <a href="https://metobs.ssec.wisc.edu/pages/instruments/aoss/cameras/hawkcam/hawkcam-install.jpg">Full size.</a></td>
+<td><a href="https://metobs.ssec.wisc.edu/pages/instruments/aoss/cameras/hawkcam/hawksnest_from_above.jpg"><img src="https://metobs.ssec.wisc.edu/pages/instruments/aoss/cameras/hawkcam/hawksnest_from_above-thumb.jpg"></a><p>View of the installed camera from the roof of the Atmospheric, Oceanic & Space Sciences Building next door. This is 12 stories above the nest. Photo by SSEC researcher Chris Schmidt. <a href="https://metobs.ssec.wisc.edu/pages/instruments/aoss/cameras/hawkcam/hawksnest_from_above.jpg">Full size.</a>
 </td>
 </table>
 <h3>Credits</h3>
@@ -242,6 +241,5 @@ Thanks to:
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/cameras/hawkcam/faq.html b/htdocs/aoss/cameras/hawkcam/faq.html
index 8b147dabfd8dc0558e3a6243333a7379d138e39f..5d1222127ab9e6cbe0794b5a59cb68a490dfae6a 100644
--- a/htdocs/aoss/cameras/hawkcam/faq.html
+++ b/htdocs/aoss/cameras/hawkcam/faq.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <div class="container">
     <div class="row">
@@ -255,6 +254,5 @@ Standing upright also employs the feet and legs as important heat dissipating st
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/cameras/hawkcam/index.html b/htdocs/aoss/cameras/hawkcam/index.html
index 2e902a96e4d1068bbd1947e25dce70b6c22638e7..2d75658268c919dbab6f6912dcc48d41a76ab92b 100644
--- a/htdocs/aoss/cameras/hawkcam/index.html
+++ b/htdocs/aoss/cameras/hawkcam/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <div id="content">
     <div class="container">
@@ -214,11 +213,11 @@
 	<div id="resources" class="container">
 			<h3>Resources</h3>
 			<ul>
-				<li><a href="hawkcam/faq.html">Frequently Asked Questions</a></li>
+				<li><a href="https://metobs.ssec.wisc.edu/aoss/cameras/hawkcam/faq/">Frequently Asked Questions</a></li>
 				<li><a href="http://www.youtube.com/playlist?list=PL79FF32A040A90651&amp;feature=mh_lol">SSEC Hawkcam Youtube Videos</a></li>
-				<li><a href="./hawkcam_images/">an assortment of hawkcam screenshots / pictures</a></li>
+				<li><a href="https://metobs.ssec.wisc.edu/pages/instruments/aoss/cameras/hawkcam_images">an assortment of hawkcam screenshots / pictures</a></li>
 				<li><a href="http://www.ssec.wisc.edu/news/topic/hawkcam">SSEC News articles on the hawkcam</a></li>
-				<li><a href="/aoss/cameras/hawkcam/details/">Details about the HawkCam</a></li>
+				<li><a href="https://metobs.ssec.wisc.edu/aoss/cameras/hawkcam/details/">Details about the HawkCam</a></li>
 				<li><a href="http://www.ssec.wisc.edu/news/topic/hawkcam/feed"><img src="http://www.ssec.wisc.edu/images/icon-rss.png" alt="RSS" border="0"> RSS</a></li>
 				<li><a href="http://www.facebook.com/pages/UW-Madison-Space-Science-and-Engineering-Center-SSEC/148860151841838">
 					<img src="http://www.ssec.wisc.edu/images/icon-facebook.png" alt="Facebook" border="0"> Facebook</a></li>
@@ -261,6 +260,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/cameras/index.html b/htdocs/aoss/cameras/index.html
index f135f69a8e0faf1a64cafc23ce31028483fc9438..eb8c466996dc66b8a9c746346d256d884e836bc6 100644
--- a/htdocs/aoss/cameras/index.html
+++ b/htdocs/aoss/cameras/index.html
@@ -201,8 +201,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     
 <div class="instrument">
@@ -240,7 +239,7 @@
                               <li><a href="/pub/cameras/north/mov/">North</a></li>
                               <li><a href="http://roofvid.ssec.wisc.edu/east">East</a></li>
                               <li><a href="http://roofvid.ssec.wisc.edu/south">South</a></li>
-                              <li><a href="/aoss/cameras/hawkcam">Hawk's Nest Camera</a>
+                              <li><a href="https://metobs.ssec.wisc.edu/aoss/cameras/hawkcam">Hawk's Nest Camera</a>
                            </ul>
                         </li>
                      </ul>
@@ -252,20 +251,20 @@
                <p>You can also view these images via an auto-updating smartphone friendly
                   format:</p>
                <ul>
-                  <li><a href="/aoss/cameras/m-west/">West</a></li>
-                  <li><a href="/aoss/cameras/m-northwest/">Northwest</a></li>
-                  <li><a href="/aoss/cameras/m-north/">North</a></li>
-                  <li><a href="/aoss/cameras/m-east/">East</a></li>
+                  <li><a href="https://metobs.ssec.wisc.edu/aoss/cameras/m-west/">West</a></li>
+                  <li><a href="https://metobs.ssec.wisc.edu/aoss/cameras/m-northwest/">Northwest</a></li>
+                  <li><a href="https://metobs.ssec.wisc.edu/aoss/cameras/m-north/">North</a></li>
+                  <li><a href="https://metobs.ssec.wisc.edu/aoss/cameras/m-east/">East</a></li>
                </ul>
                <h3>Live Video</h3>
                <p>These streams provide a live video feed from the rooftop cameras and require the free <a href="http://www.videolan.org/vlc/">VLC Player</a> to play.</p>
                 <ul>
-                  <li> <a href="/camera_feeds/ssec-roof-north-web.xspf">North</a>
-                  <li> <a href="/camera_feeds/ssec-roof-south-web.xspf">South</a>
-                  <li> <a href="/camera_feeds/ssec-roof-east-web.xspf">East</a>
-                  <li> <a href="/camera_feeds/ssec-roof-west-web.xspf">West</a>
-                  <li> <a href="/camera_feeds/ssec-roof-northwest-web.xspf">Northwest</a>
-                  <li>Alternate multicast feeds:  <a href="/camera_feeds/ssec-roof-north.xspf">North</a> |  <a href="/camera_feeds/ssec-roof-south.xspf">South</a> |  <a href="/camera_feeds/ssec-roof-east.xspf">East</a> |  <a href="/camera_feeds/ssec-roof-west.xspf">West</a> | <a href="/camera_feeds/ssec-roof-northwest.xspf">Northwest</a>
+                  <li> <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-north-web.xspf">North</a>
+                  <li> <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-south-web.xspf">South</a>
+                  <li> <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-east-web.xspf">East</a>
+                  <li> <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-west-web.xspf">West</a>
+                  <li> <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-northwest-web.xspf">Northwest</a>
+                  <li>Alternate multicast feeds:  <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-north.xspf">North</a> |  <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-south.xspf">South</a> |  <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-east.xspf">East</a> |  <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-west.xspf">West</a> | <a href="https://metobs.ssec.wisc.edu/camera_feeds/ssec-roof-northwest.xspf">Northwest</a>
       <ul>
       <li>
       Multicast streams require a wired connection to the campus network to play.
@@ -343,6 +342,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/cameras/m-east.html b/htdocs/aoss/cameras/m-east.html
index 791f9bc10ed4faa94e46cda85995ab9e05f0689a..90a4dff021196738a1925eb74ea83170fda5ed77 100644
--- a/htdocs/aoss/cameras/m-east.html
+++ b/htdocs/aoss/cameras/m-east.html
@@ -178,8 +178,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <img src="/pub/cache/aoss/cameras/east/latest_small.jpg">
 
@@ -217,6 +216,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/cameras/m-north.html b/htdocs/aoss/cameras/m-north.html
index 6cd73495ced5688bfeacab5df0b1213b2c6d2387..fb3caa6c7fcc466435a08cbd8fcab1dae701156b 100644
--- a/htdocs/aoss/cameras/m-north.html
+++ b/htdocs/aoss/cameras/m-north.html
@@ -178,8 +178,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <img src="/pub/cache/aoss/cameras/north/latest_small.jpg">
 
@@ -217,6 +216,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/cameras/m-northwest.html b/htdocs/aoss/cameras/m-northwest.html
index ec469cb5205e5c49f9627c0190150f035c996a69..1da01b1add8d7749d6b887ef72bfa593384fe394 100644
--- a/htdocs/aoss/cameras/m-northwest.html
+++ b/htdocs/aoss/cameras/m-northwest.html
@@ -178,8 +178,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <img src="/pub/cache/aoss/cameras/northwest/latest_small.jpg">
 
@@ -217,6 +216,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/cameras/m-west.html b/htdocs/aoss/cameras/m-west.html
index fcb3527230574065c5e96e9696683ab0705cb16b..f218c6fbfc2ba205a6e4b6c38c3782e9988314ce 100644
--- a/htdocs/aoss/cameras/m-west.html
+++ b/htdocs/aoss/cameras/m-west.html
@@ -178,8 +178,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <img src="/pub/cache/aoss/cameras/west/latest_small.jpg">
 
@@ -217,6 +216,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/ceil/index.html b/htdocs/aoss/ceil/index.html
index e59058b5fdecbe07abbbd68fc20b2adc750d89b3..a3a94a28538038ad59735e080eb01f354361105c 100644
--- a/htdocs/aoss/ceil/index.html
+++ b/htdocs/aoss/ceil/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     
 
@@ -211,8 +210,8 @@
     </div>
 </div>
 
-<script src="/js/quicklooks.js"></script>
-<script src="/js/moment.min.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/quicklooks.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
 <script>
     $('#quicklooks-link').attr('src',get_quicklook_url('ceilo','aoss','',moment.utc())[0]);
 </script>
@@ -252,6 +251,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/doppler/index.html b/htdocs/aoss/doppler/index.html
index e26dba5d1a4ff41ca8a704f1e722656d817d00c6..a8374910687399b307c963aeec95862e3c00c29b 100644
--- a/htdocs/aoss/doppler/index.html
+++ b/htdocs/aoss/doppler/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     
 
@@ -227,6 +226,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/gps/index.html b/htdocs/aoss/gps/index.html
index 84b43e545bc7a1b26e4dc75bf7fdfd393e21406c..5236eee1dc3ea287f2dc4db6243f8b2093489fda 100644
--- a/htdocs/aoss/gps/index.html
+++ b/htdocs/aoss/gps/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     
 
@@ -188,7 +187,7 @@
             </div>
             <div class="col-sm-4 text-center">
                 <a href="/quicklooks">
-                    <img src="/images/gpsexample.png" width="480px">
+                    <img src="https://metobs.ssec.wisc.edu/images/gpsexample.png" width="480px">
                 </a>
                 <h3 style="margin-top:10px">Quicklook Browser</h3>
             </div>
@@ -230,6 +229,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/index.html b/htdocs/aoss/index.html
index d32dd5df8284a0a2ff582817f6178a21ee4e4238..8a0f2ce2a15b0b5af425689130619c2e9b9710aa 100644
--- a/htdocs/aoss/index.html
+++ b/htdocs/aoss/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     <!-- The circle icons use Font Awesome's stacked icon classes. For more information, visit http://fontawesome.io/examples/ -->
     <section id="instruments" class="services bg-primary" style="padding:5px 0">
         <div class="container">
@@ -307,6 +306,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/lidar/index.html b/htdocs/aoss/lidar/index.html
index 4d3df8049a57e8f6ca11e690641bcb8b58cced09..ac82d9474528756c7c7baa81fb1e917e46f9207a 100644
--- a/htdocs/aoss/lidar/index.html
+++ b/htdocs/aoss/lidar/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     
 
@@ -190,7 +189,7 @@
             </div>
             <div class="col-sm-4 text-center">
                 <a href="http://lidar.ssec.wisc.edu/">
-                    <img src="/images/lidarexample.png" width="480px">
+                    <img src="https://metobs.ssec.wisc.edu/images/lidarexample.png" width="480px">
                 </a>
 <!--                <h3 style="margin-top:10px">Quicklook Browser</h3>-->
             </div>
@@ -233,6 +232,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/tower/index.html b/htdocs/aoss/tower/index.html
index 84f277d5fb8b4dc5f8c59caca3fc09a64a8c945e..f8e4b3a8ca466a681a8483283ca5e40ddbabf257 100644
--- a/htdocs/aoss/tower/index.html
+++ b/htdocs/aoss/tower/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     
 
@@ -229,20 +228,22 @@
                 </a>
             </div>
             <div class="col-sm-4 text-center">
-                <img src="/images/SSEC_from_ERB.png" width="100%">
+                <img src="https://metobs.ssec.wisc.edu/images/SSEC_from_ERB.png" width="100%">
                 <h3 style="margin-top:10px">Tower Location</h3>
             </div>
             <div class="col-sm-4 text-center">
-                <img width="100%" src="/images/Tower_Layout.png" alt="Tower Layout" align="center">
+                <img width="100%" src="https://metobs.ssec.wisc.edu/images/Tower_Layout.png" alt="Tower Layout" align="center">
                 <h3 style="margin-top:10px">Tower Layout</h3>
             </div>
         </div>
     </div>
 </div>
-<script src="/js/quicklooks.js"></script>
-<script src="/js/moment.min.js"></script>
-<script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
-<script type="text/javascript" src="/js/meteorogram/site_configs.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/quicklooks.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
+<!--TODO: LOAD PLOTLY DYNAMICALLY-->
+<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/meteorogram.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/site_configs.js"></script>
 <script type="text/javascript">
     $(document).ready(function(){
         //initialize the meteorogram table
@@ -293,6 +294,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/tower/lobby/index.html b/htdocs/aoss/tower/lobby/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..dd242353f724480a63422a7c2abe8a9e23ca6d76
--- /dev/null
+++ b/htdocs/aoss/tower/lobby/index.html
@@ -0,0 +1,166 @@
+<!--Calls lobby_page.html instead of page.html for lobby display. Called by content/pages/lobby_meteorogram.html-->
+<!--Calls lobby_base.html instead of base.html for lobby display-->
+<!--Used to remove Footer and Navbar from lobby display.-->
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <!--Page title-->
+    <title>AOSS Tower Lobby Display - RAIN | SSEC @ UW-Madison</title>
+    <!--Javascript includes -->
+
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    <title> - RAIN | SSEC @ UW-Madison</title>
+
+    <!-- Favicon -->
+    <link rel="shortcut icon" href="https://www.ssec.wisc.edu/favicon.ico" type="image/x-icon">
+    
+     <!-- Bootstrap Core CSS -->
+    <link rel="stylesheet"
+          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
+          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
+          crossorigin="anonymous">
+
+    <!-- Custom CSS -->
+    <link href="/theme/css/stylish-portfolio.css" rel="stylesheet">
+
+    <!-- Custom Fonts -->
+    <link href="/theme/css/font-awesome.min.css" rel="stylesheet" type="text/css">
+    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">
+
+    <!-- jQuery -->
+    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
+    <!-- Bootstrap Core JavaScript -->
+    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
+            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
+            crossorigin="anonymous"></script>
+
+    <!-- Custom Theme JavaScript -->
+    <script>
+    // Closes the sidebar menu
+    $("#menu-close").click(function(e) {
+        e.preventDefault();
+        $("#sidebar-wrapper").toggleClass("active");
+    });
+    // Opens the sidebar menu
+    $("#menu-toggle").click(function(e) {
+        e.preventDefault();
+        $("#sidebar-wrapper").toggleClass("active");
+    });
+    // Scrolls to the selected menu item on the page
+    $(function() {
+        $('a[href*=\\#]:not([href=\\#],[data-toggle],[data-target],[data-slide])').click(function() {
+            if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {
+                var target = $(this.hash);
+                target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
+                if (target.length) {
+                    $('html,body').animate({
+                        scrollTop: target.offset().top
+                    }, 1000);
+                    return false;
+                }
+            }
+        });
+    });
+    //#to-top button appears after scrolling
+    var fixed = false;
+    $(document).scroll(function() {
+        if ($(this).scrollTop() > 250) {
+            if (!fixed) {
+                fixed = true;
+                // $('#to-top').css({position:'fixed', display:'block'});
+                $('#to-top').show("slow", function() {
+                    $('#to-top').css({
+                        position: 'fixed',
+                        display: 'block'
+                    });
+                });
+            }
+        } else {
+            if (fixed) {
+                fixed = false;
+                $('#to-top').hide("slow", function() {
+                    $('#to-top').css({
+                        display: 'none'
+                    });
+                });
+            }
+        }
+    });
+    // Disable Google Maps scrolling
+    // See http://stackoverflow.com/a/25904582/1607849
+    // Disable scroll zooming and bind back the click event
+    var onMapMouseleaveHandler = function(event) {
+        var that = $(this);
+        that.on('click', onMapClickHandler);
+        that.off('mouseleave', onMapMouseleaveHandler);
+        that.find('iframe').css("pointer-events", "none");
+    }
+    var onMapClickHandler = function(event) {
+            var that = $(this);
+            // Disable the click handler until the user leaves the map area
+            that.off('click', onMapClickHandler);
+            // Enable scrolling zoom
+            that.find('iframe').css("pointer-events", "auto");
+            // Handle the mouse leave event
+            that.on('mouseleave', onMapMouseleaveHandler);
+        }
+        // Enable map zooming with mouse scroll when the user clicks the map
+    $('.map').on('click', onMapClickHandler);
+    </script>
+
+    <!-- Custom Fonts -->
+    <!--link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"-->
+    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">    <!-- Populate javascript environment variables from conf-->
+    <script>
+         var METOBS_API_URL = 'https://metobs-test.ssec.wisc.edu';
+         var QUICKLOOKS_FORMAT = 'new';
+    </script>
+    <!--Page Header-->
+    
+
+    <!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">-->
+    <link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" type="text/css">
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.8.10/jquery.timepicker.min.css" type="text/css">
+    <link rel="stylesheet" href="/theme/css/meteorogram_style.css">
+    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.js"></script>
+    <!--<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>-->
+
+</head>
+
+<body>
+    <!--Page Content-->
+    
+
+<!----starting-hue is what hsl color the background will start at.-->
+<div id="color" style="z-index: 1; position: absolute; top: 0px; left: 0px; height: 100%; width: 100%; --starting-hue: 0;">
+    <div id="header" style="height: 7%; width: 100%; background-color: grey"></div>
+    <div id="row1" style="height: calc(93%/3); width: 100%"></div>
+    <div id="row2" style="height: calc(93%/3); width: 100%"></div>
+    <div id="row3" style="height: calc(93%/3); width: 100%">
+        <div id="col1" style="float: left; height: 100%; width: calc(100%/3)"></div>
+        <div id="col2" style="float: left; height: 100%; width: calc(100%/3); position: relative">
+            <img id="roofCam" src="http://metobs.ssec.wisc.edu/pub/cache/aoss/cameras/west/latest_orig.jpg" alt="west" style="Cache-Control: no-store; height: 100%; width: 100%;">
+            <div id="dirText" style="position: absolute; bottom: 0%; right: 0%; font-size: .5vh; background-color: black; color: white">west</div>
+        </div>
+        <div id="col3" style="float: left; height: 100%; width: calc(100%/3)"></div>
+    </div>
+</div>
+<div id="graph" style="z-index: 2; position: absolute; top: 0px; left: 0px; height: 100%; width: 100%;"></div>
+<!--opacity: 1 makes the screen black until graph loads, which only takes a fraction of a second. Also blacks out screen between 1 and 5 am.-->
+<div id="overlay" style="z-index: 3; position: absolute; top: 0px; left: 0px; height: 100%; width: 100%; background-color: black; opacity: 1"></div>
+<script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
+<script type="text/javascript" src="/js/meteorogram/site_configs_lobby.js"></script>
+<script type="text/javascript">
+    var met = MeteorogramController('graph', 'control-container', siteConfigs);
+    met.initMeteorogram();
+    met.initMeteorogramControls();
+    met.displayRealTime();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/htdocs/aoss/tower/lobby24-7/index.html b/htdocs/aoss/tower/lobby24-7/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..cf278898dfdb2c67ae52f31a9c82db485f91502b
--- /dev/null
+++ b/htdocs/aoss/tower/lobby24-7/index.html
@@ -0,0 +1,166 @@
+<!--Calls lobby_page.html instead of page.html for lobby display. Called by content/pages/lobby_meteorogram.html-->
+<!--Calls lobby_base.html instead of base.html for lobby display-->
+<!--Used to remove Footer and Navbar from lobby display.-->
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <!--Page title-->
+    <title>AOSS Tower Lobby Display - RAIN | SSEC @ UW-Madison</title>
+    <!--Javascript includes -->
+
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    <title> - RAIN | SSEC @ UW-Madison</title>
+
+    <!-- Favicon -->
+    <link rel="shortcut icon" href="https://www.ssec.wisc.edu/favicon.ico" type="image/x-icon">
+    
+     <!-- Bootstrap Core CSS -->
+    <link rel="stylesheet"
+          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
+          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
+          crossorigin="anonymous">
+
+    <!-- Custom CSS -->
+    <link href="/theme/css/stylish-portfolio.css" rel="stylesheet">
+
+    <!-- Custom Fonts -->
+    <link href="/theme/css/font-awesome.min.css" rel="stylesheet" type="text/css">
+    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">
+
+    <!-- jQuery -->
+    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
+    <!-- Bootstrap Core JavaScript -->
+    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
+            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
+            crossorigin="anonymous"></script>
+
+    <!-- Custom Theme JavaScript -->
+    <script>
+    // Closes the sidebar menu
+    $("#menu-close").click(function(e) {
+        e.preventDefault();
+        $("#sidebar-wrapper").toggleClass("active");
+    });
+    // Opens the sidebar menu
+    $("#menu-toggle").click(function(e) {
+        e.preventDefault();
+        $("#sidebar-wrapper").toggleClass("active");
+    });
+    // Scrolls to the selected menu item on the page
+    $(function() {
+        $('a[href*=\\#]:not([href=\\#],[data-toggle],[data-target],[data-slide])').click(function() {
+            if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {
+                var target = $(this.hash);
+                target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
+                if (target.length) {
+                    $('html,body').animate({
+                        scrollTop: target.offset().top
+                    }, 1000);
+                    return false;
+                }
+            }
+        });
+    });
+    //#to-top button appears after scrolling
+    var fixed = false;
+    $(document).scroll(function() {
+        if ($(this).scrollTop() > 250) {
+            if (!fixed) {
+                fixed = true;
+                // $('#to-top').css({position:'fixed', display:'block'});
+                $('#to-top').show("slow", function() {
+                    $('#to-top').css({
+                        position: 'fixed',
+                        display: 'block'
+                    });
+                });
+            }
+        } else {
+            if (fixed) {
+                fixed = false;
+                $('#to-top').hide("slow", function() {
+                    $('#to-top').css({
+                        display: 'none'
+                    });
+                });
+            }
+        }
+    });
+    // Disable Google Maps scrolling
+    // See http://stackoverflow.com/a/25904582/1607849
+    // Disable scroll zooming and bind back the click event
+    var onMapMouseleaveHandler = function(event) {
+        var that = $(this);
+        that.on('click', onMapClickHandler);
+        that.off('mouseleave', onMapMouseleaveHandler);
+        that.find('iframe').css("pointer-events", "none");
+    }
+    var onMapClickHandler = function(event) {
+            var that = $(this);
+            // Disable the click handler until the user leaves the map area
+            that.off('click', onMapClickHandler);
+            // Enable scrolling zoom
+            that.find('iframe').css("pointer-events", "auto");
+            // Handle the mouse leave event
+            that.on('mouseleave', onMapMouseleaveHandler);
+        }
+        // Enable map zooming with mouse scroll when the user clicks the map
+    $('.map').on('click', onMapClickHandler);
+    </script>
+
+    <!-- Custom Fonts -->
+    <!--link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"-->
+    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">    <!-- Populate javascript environment variables from conf-->
+    <script>
+         var METOBS_API_URL = 'https://metobs-test.ssec.wisc.edu';
+         var QUICKLOOKS_FORMAT = 'new';
+    </script>
+    <!--Page Header-->
+    
+
+    <!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">-->
+    <link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" type="text/css">
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.8.10/jquery.timepicker.min.css" type="text/css">
+    <link rel="stylesheet" href="/theme/css/meteorogram_style.css">
+    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.js"></script>
+    <!--<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>-->
+
+</head>
+
+<body>
+    <!--Page Content-->
+    
+
+<!----starting-hue is what hsl color the background will start at.-->
+<div id="color" style="z-index: 1; position: absolute; top: 0px; left: 0px; height: 100%; width: 100%; --starting-hue: 0;">
+    <div id="header" style="height: 7%; width: 100%; background-color: grey"></div>
+    <div id="row1" style="height: calc(93%/3); width: 100%"></div>
+    <div id="row2" style="height: calc(93%/3); width: 100%"></div>
+    <div id="row3" style="height: calc(93%/3); width: 100%">
+        <div id="col1" style="float: left; height: 100%; width: calc(100%/3)"></div>
+        <div id="col2" style="float: left; height: 100%; width: calc(100%/3); position: relative">
+            <img id="roofCam" src="http://metobs.ssec.wisc.edu/pub/cache/aoss/cameras/west/latest_orig.jpg" alt="west" style="Cache-Control: no-store; height: 100%; width: 100%;">
+            <div id="dirText" style="position: absolute; bottom: 0%; right: 0%; font-size: .5vh; background-color: black; color: white">west</div>
+        </div>
+        <div id="col3" style="float: left; height: 100%; width: calc(100%/3)"></div>
+    </div>
+</div>
+<div id="graph" style="z-index: 2; position: absolute; top: 0px; left: 0px; height: 100%; width: 100%;"></div>
+<!--Needs to exists for code to run, but does nothing. Used to make screen black between 1 and 5 am normally.-->
+<div id="overlay"></div>
+<script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
+<script type="text/javascript" src="/js/meteorogram/site_configs_lobby.js"></script>
+<script type="text/javascript">
+    var met = MeteorogramController('graph', 'control-container', siteConfigs);
+    met.initMeteorogram();
+    met.initMeteorogramControls();
+    met.displayRealTime();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/htdocs/aoss/tower/meteorogram/index.html b/htdocs/aoss/tower/meteorogram/index.html
index 1f015a7d33ce67ba148d6361b3fc4562ae789a92..5718a53e83286b8d4c51216be031b7df413f541d 100644
--- a/htdocs/aoss/tower/meteorogram/index.html
+++ b/htdocs/aoss/tower/meteorogram/index.html
@@ -185,8 +185,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <div id="content">
     <div class="container">
@@ -206,8 +205,8 @@
         </div>
     </div>
 </div>
-<script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
-<script type="text/javascript" src="/js/meteorogram/site_configs.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/meteorogram.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/site_configs.js"></script>
 <script type="text/javascript">
     var met = MeteorogramController('graph', 'control-container', siteConfigs['aoss.tower']);
     met.initMeteorogram();
@@ -249,6 +248,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/aoss/tower/text_popup/index.html b/htdocs/aoss/tower/text_popup/index.html
index 03717fca08e66876b2997390faadac2561e5f43b..7e51a26e7d95307000d8cd72ff8583d40e0618ab 100644
--- a/htdocs/aoss/tower/text_popup/index.html
+++ b/htdocs/aoss/tower/text_popup/index.html
@@ -175,15 +175,16 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <div class="instrument" style="text-align:center">
     <div id="graph" style="display:inline-block;text-align:left"></div>
 </div>
-<script src="/js/moment.min.js"></script>
-<script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
-<script type="text/javascript" src="/js/meteorogram/site_configs.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
+<!--TODO: LOAD PLOTLY DYNAMICALLY-->
+<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/meteorogram.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/site_configs.js"></script>
 <script type="text/javascript">
     $(document).ready(function(){
         //initialize the meteorogram table
@@ -230,6 +231,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/archives.html b/htdocs/archives.html
index 0f55db31f83a676a098ca65accce823aab562bcd..a464205a6f0b5b9ebf9f589638d11da02c43a3e7 100644
--- a/htdocs/archives.html
+++ b/htdocs/archives.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
 <h1>Archives for RAIN | SSEC @ UW-Madison</h1>
 
 <dl>
@@ -215,6 +214,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/authors.html b/htdocs/authors.html
index 2a1bcff40a7f530e2b22e2664778e8c3cc382dc4..19f23046b0701452702a32f0276da9d4161004f8 100644
--- a/htdocs/authors.html
+++ b/htdocs/authors.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     <h1>Authors on RAIN | SSEC @ UW-Madison</h1>
 
     <ul>    </ul>
@@ -214,6 +213,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/categories.html b/htdocs/categories.html
index 94ed2f55afb84452353ba53308293ec5f0ba9686..764ba4a01b24f2bffe2cdb5b804c7683bf74f545 100644
--- a/htdocs/categories.html
+++ b/htdocs/categories.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
 <ul>
 </ul>
     <!-- Footer -->
@@ -213,6 +212,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/data_download/index.html b/htdocs/data_download/index.html
index 4b758575f5d4e1c61eed94528238d94579b7de0d..ade189e48ab91c3c46e651dcff583f50d116e3e8 100644
--- a/htdocs/data_download/index.html
+++ b/htdocs/data_download/index.html
@@ -182,8 +182,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
 
     
 
@@ -362,15 +361,15 @@
     </div>
             
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.js"></script>
-    <script type="text/javascript" src="/js/data_api_info.js"></script>
-    <script type="text/javascript" src="/js/underscore-min.js"></script>
-    <script type="text/javascript" src="/js/moment.min.js"></script>
-    <script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
-    <script type="text/javascript" src="/js/meteorogram/site_configs.js"></script>
-    <script type="text/javascript" src="/js/quicklooks.js"></script>
-    <script type="text/javascript" src="/js/quicklooks-util.js"></script>
-    <script type="text/javascript" src="/js/form_util.js"></script>
-    <script type="text/javascript" src="/js/data_download.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/data_api_info.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/underscore-min.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/meteorogram.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/site_configs.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/quicklooks.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/quicklooks-util.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/form_util.js"></script>
+    <script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/data_download.js"></script>
   </div>
   </div>
 </div>
@@ -411,6 +410,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/disclaimer/index.html b/htdocs/disclaimer/index.html
index ff29063fcb013f554355e296874fe0673917d9b5..73df5ee9ac7302e85fdb20b91e51f51720400cfb 100644
--- a/htdocs/disclaimer/index.html
+++ b/htdocs/disclaimer/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     
 <p>
@@ -238,6 +237,5 @@ For all other data and imagery on this website please acknowledge:
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/feeds/all.atom.xml b/htdocs/feeds/all.atom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5e73569753f6262f2ba6530ff219c14e1ff1039f
--- /dev/null
+++ b/htdocs/feeds/all.atom.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom"><title>RAIN | SSEC @ UW-Madison</title><link href="https://metobs.ssec.wisc.edu/" rel="alternate"></link><link href="https://metobs.ssec.wisc.edu/feeds/all.atom.xml" rel="self"></link><id>https://metobs.ssec.wisc.edu/</id><updated>2020-02-21T13:55:22Z</updated></feed>
\ No newline at end of file
diff --git a/htdocs/file_download/index.html b/htdocs/file_download/index.html
index c29f8d6625d8ef34c3e575dfa1728d3959fb7632..6ca68b3880df8c300b06d68d5d808585b99cf7c7 100644
--- a/htdocs/file_download/index.html
+++ b/htdocs/file_download/index.html
@@ -181,8 +181,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
 
     
 
@@ -339,12 +338,12 @@
   <div class="row">
       <!--Preview table goes here-->
   </div>
-    <script src="/js/underscore-min.js"></script>
-    <script src="/js/moment.min.js"></script>
-    <script src="/js/quicklooks.js"></script>
-    <script src="/js/quicklooks-util.js"></script>
-    <script src="/js/form_util.js"></script>
-    <script src="/js/file_download.js"></script>
+    <script src="https://metobs.ssec.wisc.edu/js/underscore-min.js"></script>
+    <script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
+    <script src="https://metobs.ssec.wisc.edu/js/quicklooks.js"></script>
+    <script src="https://metobs.ssec.wisc.edu/js/quicklooks-util.js"></script>
+    <script src="https://metobs.ssec.wisc.edu/js/form_util.js"></script>
+    <script src="https://metobs.ssec.wisc.edu/js/file_download.js"></script>
   </div>
 </div>
 
@@ -384,6 +383,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/index.html b/htdocs/index.html
index 09fdef3725218977a19ee24d73fbf9f1e229a27a..a8721a848a49762b1a41b48266ed7bd7f54d1f3b 100644
--- a/htdocs/index.html
+++ b/htdocs/index.html
@@ -193,8 +193,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 
     <!-- Header -->
@@ -360,7 +359,7 @@
                         <div class="col-md-6">
                             <div class="portfolio-item">
                                 <a href="/aoss/tower/meteorogram">
-                                    <img class="img-portfolio img-responsive" src="/images/aossinteractive.png">
+                                    <img class="img-portfolio img-responsive" src="https://metobs.ssec.wisc.edu/images/aossinteractive.png">
                                     Realtime Tower Data
                                 </a>
                             </div>
@@ -368,7 +367,7 @@
                         <div class="col-md-6">
                             <div class="portfolio-item">
                                 <a href="/mendota/buoy/meteorogram">
-                                    <img class="img-portfolio img-responsive" src="/images/buoyinteractive.png">
+                                    <img class="img-portfolio img-responsive" src="https://metobs.ssec.wisc.edu/images/buoyinteractive.png">
                                     Realtime Buoy Data
                                 </a>
                             </div>
@@ -376,7 +375,7 @@
                         <div class="col-md-6">
                             <div class="portfolio-item">
                                 <a href="./quicklooks/">
-                                    <img class="img-portfolio img-responsive" src="/images/rigexample.png">
+                                    <img class="img-portfolio img-responsive" src="https://metobs.ssec.wisc.edu/images/rigexample.png">
                                     Quicklook Browser
                                 </a>
                             </div>
@@ -384,7 +383,7 @@
                         <div class="col-md-6">
                             <div class="portfolio-item">
                                 <a href="./file_download/">
-                                    <img class="img-portfolio img-responsive" src="/images/portfolio-4.png">
+                                    <img class="img-portfolio img-responsive" src="https://metobs.ssec.wisc.edu/images/portfolio-4.png">
                                     Data Download Form
                                 </a>
                             </div>
@@ -487,6 +486,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/instruments/index.html b/htdocs/instruments/index.html
index f5b83dfaef72a7f12bf7a9a939c90829706caa0d..6592b3a0f74a744804077eec94d7b24c338f8ac9 100644
--- a/htdocs/instruments/index.html
+++ b/htdocs/instruments/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     
 <div>
@@ -185,10 +184,10 @@
     <table>
         <tr>
             <td class="instruments">
-                <a href="/aoss/"><img src="/images/SSEC_from_ERB.png" alt="AOSS Bldg" height="224px"><br>Atmospheric, Oceanic, and Space Sciences Building (AOSS)</a><br>UW-Madison: RIG Tower, HSRL, Ceilometer, GPS
+                <a href="/aoss/"><img src="https://metobs.ssec.wisc.edu/images/SSEC_from_ERB.png" alt="AOSS Bldg" height="224px"><br>Atmospheric, Oceanic, and Space Sciences Building (AOSS)</a><br>UW-Madison: RIG Tower, HSRL, Ceilometer, GPS
             </td>
             <td class="instruments">
-                <a href="/mendota/"><img src="/images/buoy_small.png" alt="Buoy"><br>Lake Mendota</a><br>Madison, WI
+                <a href="/mendota/"><img src="https://metobs.ssec.wisc.edu/images/buoy_small.png" alt="Buoy"><br>Lake Mendota</a><br>Madison, WI
             </td>
         </tr>
     </table>
@@ -230,6 +229,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/js/meteorogram/dispatcher.js b/htdocs/js/meteorogram/dispatcher.js
index 85a8458db4376832049cf02e96ebebe9a309ec04..ad558a82740992ee77f241d03fa2b2e64ded84b7 100644
--- a/htdocs/js/meteorogram/dispatcher.js
+++ b/htdocs/js/meteorogram/dispatcher.js
@@ -7,6 +7,8 @@ var Plot = require('./plot/init.js');
 var Table = require('./plot/table.js');
 var dataAccess = require('./plot/data.js');
 var loading = require('./ui/loading.js');
+var updatePlot = require('./plot/update.js');
+var hue;
 
 function getDispatcher() {
     var myDispatcher = new Flux.Dispatcher();
@@ -26,6 +28,32 @@ function getDispatcher() {
         }
     }
 
+    function dispatchChangeUnits(unitCount) {
+        return function() {
+            unitCount = (unitCount + 1) % 2
+            //dispatch update message to plotStore
+            myDispatcher.dispatch({'status': 'changeUnits', 'emit': 'plotEmitter', 'unitCount': unitCount});
+        }
+    }
+
+    function changeBackgroundColor() {
+        // Moves faster between Red, Green, and Blue. This is purely aesthetic to avoid "ugly" colors (I'm looking at
+        // you brown-green).
+        var skip_jump = 120;
+        var acceleration = 2;
+        var rate = .2;
+        // Exactly rate times faster at skip_jump / 2, and normal speed at skip_jump.
+        hue += (acceleration * Math.min(skip_jump - hue % skip_jump, hue % skip_jump) / (skip_jump / 2) + 1) * rate
+        // Loops around the color circle.
+        if (hue > 360) {
+            hue = 0
+        }
+        // Make the brighter colors more grey to match the darker colors above them.
+        document.getElementById('row1').style.backgroundColor = 'hsl(' + hue + ',' + 100 + '%,' + 15 + '%)';
+        document.getElementById('row2').style.backgroundColor = 'hsl(' + hue + ',' + 75 + '%,' + 30 + '%)';
+        document.getElementById('row3').style.backgroundColor = 'hsl(' + hue + ',' + 50 + '%,' + 45 + '%)';
+    }
+
     //creates checkbox store
     var checkboxEmitter = ee({
         visible: {},
@@ -49,7 +77,7 @@ function getDispatcher() {
             if(action.emit == 'checkboxEmitter')
             {
                 this.emit(action.status, action.location);
-            }    
+            }
         }
     });
 
@@ -82,6 +110,9 @@ function getDispatcher() {
                 }
 
                 if (action.status == 'get_since_now') {
+                    if (this.plotsInfo['isLobbyDisplay']) {
+                        action.time = '-6:00:00'
+                    }
                     this.emit(
                         action.status,
                         action.time,
@@ -118,12 +149,14 @@ function getDispatcher() {
                         this.plotsInfo);
                 } else if (action.status == 'update') {
                     this.emit(action.status, this.div, this.plotsInfo, this.dataCache, action.startTime);
+                } else if (action.status == 'changeUnits') {
+                    this.emit(action.status, this.div, this.plotsInfo, this.dataCache, action.unitCount);
                 } else {
                     //adds parameter for user information in custom plot
                     // console.debug("Emitting user information message: {action.status} : {action.userInfo}");
                     this.emit(action.status, action.userInfo);
                 }
-            }    
+            }
         }
     });
 
@@ -134,8 +167,11 @@ function getDispatcher() {
         if(plotsInfo.progress.validID){
             var id = plotsInfo.progress.id[0];
             clearInterval(id);
+            if (plotsInfo['isLobbyDisplay']) {
+                clearInterval(plotsInfo.progress.colorID);
+                clearInterval(plotsInfo.progress.lobbyID);
+            }
             plotsInfo.progress.validID = false;
-
         }
     }
 
@@ -163,6 +199,11 @@ function getDispatcher() {
 
         // every 30 seconds, rings update alarm
         var intervalID = setInterval(dispatchUpdate(startTime), updateInterval[interval]);
+        if (plotsInfo['isLobbyDisplay']) {
+            hue = Number(getComputedStyle(document.getElementById("color")).getPropertyValue('--starting-hue'))
+            plotsInfo.progress.colorID = setInterval(changeBackgroundColor, 1000)
+            plotsInfo.progress.lobbyID = setInterval(dispatchChangeUnits(0), 5000);
+        }
         // save alarm id
         plotsInfo.progress.id = [intervalID, startTime, interval];
         plotsInfo.progress.validID = true;
@@ -201,6 +242,10 @@ function getDispatcher() {
         dataAccess.requestPlotUpdate(dataCache, div, plotsInfo, startTime, undefined, undefined, true);
     });
 
+    plotEmitter.on('changeUnits', function(div, plotsInfo, dataCache, unitCount) {
+        updatePlot.changeUnits(dataCache, document.getElementById(div), plotsInfo, unitCount)
+    });
+
     plotEmitter.on("checking_custom", function()
     {
         //before components were plots. Here, it's the user prompt paragraph
diff --git a/htdocs/js/meteorogram/meteorogram.js b/htdocs/js/meteorogram/meteorogram.js
index 7510a62e744035c136a5150978f2b31d639c62be..784e6cdb68006735d141241f5c33081cc81db94f 100644
--- a/htdocs/js/meteorogram/meteorogram.js
+++ b/htdocs/js/meteorogram/meteorogram.js
@@ -1 +1 @@
-!function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=6)}([function(t,e,n){(function(t,n){var r;!function(){var i="object"==typeof self&&self.self===self&&self||"object"==typeof t&&t.global===t&&t||this||{},o=i._,a=Array.prototype,s=Object.prototype,c="undefined"!=typeof Symbol?Symbol.prototype:null,l=a.push,u=a.slice,p=s.toString,f=s.hasOwnProperty,d=Array.isArray,h=Object.keys,v=Object.create,y=function(){},m=function(t){return t instanceof m?t:this instanceof m?void(this._wrapped=t):new m(t)};e.nodeType?i._=m:(!n.nodeType&&n.exports&&(e=n.exports=m),e._=m),m.VERSION="1.9.1";var g,b=function(t,e,n){if(void 0===e)return t;switch(null==n?3:n){case 1:return function(n){return t.call(e,n)};case 3:return function(n,r,i){return t.call(e,n,r,i)};case 4:return function(n,r,i,o){return t.call(e,n,r,i,o)}}return function(){return t.apply(e,arguments)}},_=function(t,e,n){return m.iteratee!==g?m.iteratee(t,e):null==t?m.identity:m.isFunction(t)?b(t,e,n):m.isObject(t)&&!m.isArray(t)?m.matcher(t):m.property(t)};m.iteratee=g=function(t,e){return _(t,e,1/0)};var x=function(t,e){return e=null==e?t.length-1:+e,function(){for(var n=Math.max(arguments.length-e,0),r=Array(n),i=0;i<n;i++)r[i]=arguments[i+e];switch(e){case 0:return t.call(this,r);case 1:return t.call(this,arguments[0],r);case 2:return t.call(this,arguments[0],arguments[1],r)}var o=Array(e+1);for(i=0;i<e;i++)o[i]=arguments[i];return o[e]=r,t.apply(this,o)}},k=function(t){if(!m.isObject(t))return{};if(v)return v(t);y.prototype=t;var e=new y;return y.prototype=null,e},w=function(t){return function(e){return null==e?void 0:e[t]}},j=function(t,e){return null!=t&&f.call(t,e)},O=function(t,e){for(var n=e.length,r=0;r<n;r++){if(null==t)return;t=t[e[r]]}return n?t:void 0},T=Math.pow(2,53)-1,P=w("length"),S=function(t){var e=P(t);return"number"==typeof e&&e>=0&&e<=T};m.each=m.forEach=function(t,e,n){var r,i;if(e=b(e,n),S(t))for(r=0,i=t.length;r<i;r++)e(t[r],r,t);else{var o=m.keys(t);for(r=0,i=o.length;r<i;r++)e(t[o[r]],o[r],t)}return t},m.map=m.collect=function(t,e,n){e=_(e,n);for(var r=!S(t)&&m.keys(t),i=(r||t).length,o=Array(i),a=0;a<i;a++){var s=r?r[a]:a;o[a]=e(t[s],s,t)}return o};var $=function(t){return function(e,n,r,i){var o=arguments.length>=3;return function(e,n,r,i){var o=!S(e)&&m.keys(e),a=(o||e).length,s=t>0?0:a-1;for(i||(r=e[o?o[s]:s],s+=t);s>=0&&s<a;s+=t){var c=o?o[s]:s;r=n(r,e[c],c,e)}return r}(e,b(n,i,4),r,o)}};m.reduce=m.foldl=m.inject=$(1),m.reduceRight=m.foldr=$(-1),m.find=m.detect=function(t,e,n){var r=(S(t)?m.findIndex:m.findKey)(t,e,n);if(void 0!==r&&-1!==r)return t[r]},m.filter=m.select=function(t,e,n){var r=[];return e=_(e,n),m.each(t,function(t,n,i){e(t,n,i)&&r.push(t)}),r},m.reject=function(t,e,n){return m.filter(t,m.negate(_(e)),n)},m.every=m.all=function(t,e,n){e=_(e,n);for(var r=!S(t)&&m.keys(t),i=(r||t).length,o=0;o<i;o++){var a=r?r[o]:o;if(!e(t[a],a,t))return!1}return!0},m.some=m.any=function(t,e,n){e=_(e,n);for(var r=!S(t)&&m.keys(t),i=(r||t).length,o=0;o<i;o++){var a=r?r[o]:o;if(e(t[a],a,t))return!0}return!1},m.contains=m.includes=m.include=function(t,e,n,r){return S(t)||(t=m.values(t)),("number"!=typeof n||r)&&(n=0),m.indexOf(t,e,n)>=0},m.invoke=x(function(t,e,n){var r,i;return m.isFunction(e)?i=e:m.isArray(e)&&(r=e.slice(0,-1),e=e[e.length-1]),m.map(t,function(t){var o=i;if(!o){if(r&&r.length&&(t=O(t,r)),null==t)return;o=t[e]}return null==o?o:o.apply(t,n)})}),m.pluck=function(t,e){return m.map(t,m.property(e))},m.where=function(t,e){return m.filter(t,m.matcher(e))},m.findWhere=function(t,e){return m.find(t,m.matcher(e))},m.max=function(t,e,n){var r,i,o=-1/0,a=-1/0;if(null==e||"number"==typeof e&&"object"!=typeof t[0]&&null!=t)for(var s=0,c=(t=S(t)?t:m.values(t)).length;s<c;s++)null!=(r=t[s])&&r>o&&(o=r);else e=_(e,n),m.each(t,function(t,n,r){((i=e(t,n,r))>a||i===-1/0&&o===-1/0)&&(o=t,a=i)});return o},m.min=function(t,e,n){var r,i,o=1/0,a=1/0;if(null==e||"number"==typeof e&&"object"!=typeof t[0]&&null!=t)for(var s=0,c=(t=S(t)?t:m.values(t)).length;s<c;s++)null!=(r=t[s])&&r<o&&(o=r);else e=_(e,n),m.each(t,function(t,n,r){((i=e(t,n,r))<a||i===1/0&&o===1/0)&&(o=t,a=i)});return o},m.shuffle=function(t){return m.sample(t,1/0)},m.sample=function(t,e,n){if(null==e||n)return S(t)||(t=m.values(t)),t[m.random(t.length-1)];var r=S(t)?m.clone(t):m.values(t),i=P(r);e=Math.max(Math.min(e,i),0);for(var o=i-1,a=0;a<e;a++){var s=m.random(a,o),c=r[a];r[a]=r[s],r[s]=c}return r.slice(0,e)},m.sortBy=function(t,e,n){var r=0;return e=_(e,n),m.pluck(m.map(t,function(t,n,i){return{value:t,index:r++,criteria:e(t,n,i)}}).sort(function(t,e){var n=t.criteria,r=e.criteria;if(n!==r){if(n>r||void 0===n)return 1;if(n<r||void 0===r)return-1}return t.index-e.index}),"value")};var A=function(t,e){return function(n,r,i){var o=e?[[],[]]:{};return r=_(r,i),m.each(n,function(e,i){var a=r(e,i,n);t(o,e,a)}),o}};m.groupBy=A(function(t,e,n){j(t,n)?t[n].push(e):t[n]=[e]}),m.indexBy=A(function(t,e,n){t[n]=e}),m.countBy=A(function(t,e,n){j(t,n)?t[n]++:t[n]=1});var E=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;m.toArray=function(t){return t?m.isArray(t)?u.call(t):m.isString(t)?t.match(E):S(t)?m.map(t,m.identity):m.values(t):[]},m.size=function(t){return null==t?0:S(t)?t.length:m.keys(t).length},m.partition=A(function(t,e,n){t[n?0:1].push(e)},!0),m.first=m.head=m.take=function(t,e,n){return null==t||t.length<1?null==e?void 0:[]:null==e||n?t[0]:m.initial(t,t.length-e)},m.initial=function(t,e,n){return u.call(t,0,Math.max(0,t.length-(null==e||n?1:e)))},m.last=function(t,e,n){return null==t||t.length<1?null==e?void 0:[]:null==e||n?t[t.length-1]:m.rest(t,Math.max(0,t.length-e))},m.rest=m.tail=m.drop=function(t,e,n){return u.call(t,null==e||n?1:e)},m.compact=function(t){return m.filter(t,Boolean)};var D=function(t,e,n,r){for(var i=(r=r||[]).length,o=0,a=P(t);o<a;o++){var s=t[o];if(S(s)&&(m.isArray(s)||m.isArguments(s)))if(e)for(var c=0,l=s.length;c<l;)r[i++]=s[c++];else D(s,e,n,r),i=r.length;else n||(r[i++]=s)}return r};m.flatten=function(t,e){return D(t,e,!1)},m.without=x(function(t,e){return m.difference(t,e)}),m.uniq=m.unique=function(t,e,n,r){m.isBoolean(e)||(r=n,n=e,e=!1),null!=n&&(n=_(n,r));for(var i=[],o=[],a=0,s=P(t);a<s;a++){var c=t[a],l=n?n(c,a,t):c;e&&!n?(a&&o===l||i.push(c),o=l):n?m.contains(o,l)||(o.push(l),i.push(c)):m.contains(i,c)||i.push(c)}return i},m.union=x(function(t){return m.uniq(D(t,!0,!0))}),m.intersection=function(t){for(var e=[],n=arguments.length,r=0,i=P(t);r<i;r++){var o=t[r];if(!m.contains(e,o)){var a;for(a=1;a<n&&m.contains(arguments[a],o);a++);a===n&&e.push(o)}}return e},m.difference=x(function(t,e){return e=D(e,!0,!0),m.filter(t,function(t){return!m.contains(e,t)})}),m.unzip=function(t){for(var e=t&&m.max(t,P).length||0,n=Array(e),r=0;r<e;r++)n[r]=m.pluck(t,r);return n},m.zip=x(m.unzip),m.object=function(t,e){for(var n={},r=0,i=P(t);r<i;r++)e?n[t[r]]=e[r]:n[t[r][0]]=t[r][1];return n};var M=function(t){return function(e,n,r){n=_(n,r);for(var i=P(e),o=t>0?0:i-1;o>=0&&o<i;o+=t)if(n(e[o],o,e))return o;return-1}};m.findIndex=M(1),m.findLastIndex=M(-1),m.sortedIndex=function(t,e,n,r){for(var i=(n=_(n,r,1))(e),o=0,a=P(t);o<a;){var s=Math.floor((o+a)/2);n(t[s])<i?o=s+1:a=s}return o};var I=function(t,e,n){return function(r,i,o){var a=0,s=P(r);if("number"==typeof o)t>0?a=o>=0?o:Math.max(o+s,a):s=o>=0?Math.min(o+1,s):o+s+1;else if(n&&o&&s)return r[o=n(r,i)]===i?o:-1;if(i!=i)return(o=e(u.call(r,a,s),m.isNaN))>=0?o+a:-1;for(o=t>0?a:s-1;o>=0&&o<s;o+=t)if(r[o]===i)return o;return-1}};m.indexOf=I(1,m.findIndex,m.sortedIndex),m.lastIndexOf=I(-1,m.findLastIndex),m.range=function(t,e,n){null==e&&(e=t||0,t=0),n||(n=e<t?-1:1);for(var r=Math.max(Math.ceil((e-t)/n),0),i=Array(r),o=0;o<r;o++,t+=n)i[o]=t;return i},m.chunk=function(t,e){if(null==e||e<1)return[];for(var n=[],r=0,i=t.length;r<i;)n.push(u.call(t,r,r+=e));return n};var F=function(t,e,n,r,i){if(!(r instanceof e))return t.apply(n,i);var o=k(t.prototype),a=t.apply(o,i);return m.isObject(a)?a:o};m.bind=x(function(t,e,n){if(!m.isFunction(t))throw new TypeError("Bind must be called on a function");var r=x(function(i){return F(t,r,e,this,n.concat(i))});return r}),m.partial=x(function(t,e){var n=m.partial.placeholder,r=function(){for(var i=0,o=e.length,a=Array(o),s=0;s<o;s++)a[s]=e[s]===n?arguments[i++]:e[s];for(;i<arguments.length;)a.push(arguments[i++]);return F(t,r,this,this,a)};return r}),m.partial.placeholder=m,m.bindAll=x(function(t,e){var n=(e=D(e,!1,!1)).length;if(n<1)throw new Error("bindAll must be passed function names");for(;n--;){var r=e[n];t[r]=m.bind(t[r],t)}}),m.memoize=function(t,e){var n=function(r){var i=n.cache,o=""+(e?e.apply(this,arguments):r);return j(i,o)||(i[o]=t.apply(this,arguments)),i[o]};return n.cache={},n},m.delay=x(function(t,e,n){return setTimeout(function(){return t.apply(null,n)},e)}),m.defer=m.partial(m.delay,m,1),m.throttle=function(t,e,n){var r,i,o,a,s=0;n||(n={});var c=function(){s=!1===n.leading?0:m.now(),r=null,a=t.apply(i,o),r||(i=o=null)},l=function(){var l=m.now();s||!1!==n.leading||(s=l);var u=e-(l-s);return i=this,o=arguments,u<=0||u>e?(r&&(clearTimeout(r),r=null),s=l,a=t.apply(i,o),r||(i=o=null)):r||!1===n.trailing||(r=setTimeout(c,u)),a};return l.cancel=function(){clearTimeout(r),s=0,r=i=o=null},l},m.debounce=function(t,e,n){var r,i,o=function(e,n){r=null,n&&(i=t.apply(e,n))},a=x(function(a){if(r&&clearTimeout(r),n){var s=!r;r=setTimeout(o,e),s&&(i=t.apply(this,a))}else r=m.delay(o,e,this,a);return i});return a.cancel=function(){clearTimeout(r),r=null},a},m.wrap=function(t,e){return m.partial(e,t)},m.negate=function(t){return function(){return!t.apply(this,arguments)}},m.compose=function(){var t=arguments,e=t.length-1;return function(){for(var n=e,r=t[e].apply(this,arguments);n--;)r=t[n].call(this,r);return r}},m.after=function(t,e){return function(){if(--t<1)return e.apply(this,arguments)}},m.before=function(t,e){var n;return function(){return--t>0&&(n=e.apply(this,arguments)),t<=1&&(e=null),n}},m.once=m.partial(m.before,2),m.restArguments=x;var z=!{toString:null}.propertyIsEnumerable("toString"),N=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],H=function(t,e){var n=N.length,r=t.constructor,i=m.isFunction(r)&&r.prototype||s,o="constructor";for(j(t,o)&&!m.contains(e,o)&&e.push(o);n--;)(o=N[n])in t&&t[o]!==i[o]&&!m.contains(e,o)&&e.push(o)};m.keys=function(t){if(!m.isObject(t))return[];if(h)return h(t);var e=[];for(var n in t)j(t,n)&&e.push(n);return z&&H(t,e),e},m.allKeys=function(t){if(!m.isObject(t))return[];var e=[];for(var n in t)e.push(n);return z&&H(t,e),e},m.values=function(t){for(var e=m.keys(t),n=e.length,r=Array(n),i=0;i<n;i++)r[i]=t[e[i]];return r},m.mapObject=function(t,e,n){e=_(e,n);for(var r=m.keys(t),i=r.length,o={},a=0;a<i;a++){var s=r[a];o[s]=e(t[s],s,t)}return o},m.pairs=function(t){for(var e=m.keys(t),n=e.length,r=Array(n),i=0;i<n;i++)r[i]=[e[i],t[e[i]]];return r},m.invert=function(t){for(var e={},n=m.keys(t),r=0,i=n.length;r<i;r++)e[t[n[r]]]=n[r];return e},m.functions=m.methods=function(t){var e=[];for(var n in t)m.isFunction(t[n])&&e.push(n);return e.sort()};var C=function(t,e){return function(n){var r=arguments.length;if(e&&(n=Object(n)),r<2||null==n)return n;for(var i=1;i<r;i++)for(var o=arguments[i],a=t(o),s=a.length,c=0;c<s;c++){var l=a[c];e&&void 0!==n[l]||(n[l]=o[l])}return n}};m.extend=C(m.allKeys),m.extendOwn=m.assign=C(m.keys),m.findKey=function(t,e,n){e=_(e,n);for(var r,i=m.keys(t),o=0,a=i.length;o<a;o++)if(e(t[r=i[o]],r,t))return r};var R,q,W=function(t,e,n){return e in n};m.pick=x(function(t,e){var n={},r=e[0];if(null==t)return n;m.isFunction(r)?(e.length>1&&(r=b(r,e[1])),e=m.allKeys(t)):(r=W,e=D(e,!1,!1),t=Object(t));for(var i=0,o=e.length;i<o;i++){var a=e[i],s=t[a];r(s,a,t)&&(n[a]=s)}return n}),m.omit=x(function(t,e){var n,r=e[0];return m.isFunction(r)?(r=m.negate(r),e.length>1&&(n=e[1])):(e=m.map(D(e,!1,!1),String),r=function(t,n){return!m.contains(e,n)}),m.pick(t,r,n)}),m.defaults=C(m.allKeys,!0),m.create=function(t,e){var n=k(t);return e&&m.extendOwn(n,e),n},m.clone=function(t){return m.isObject(t)?m.isArray(t)?t.slice():m.extend({},t):t},m.tap=function(t,e){return e(t),t},m.isMatch=function(t,e){var n=m.keys(e),r=n.length;if(null==t)return!r;for(var i=Object(t),o=0;o<r;o++){var a=n[o];if(e[a]!==i[a]||!(a in i))return!1}return!0},R=function(t,e,n,r){if(t===e)return 0!==t||1/t==1/e;if(null==t||null==e)return!1;if(t!=t)return e!=e;var i=typeof t;return("function"===i||"object"===i||"object"==typeof e)&&q(t,e,n,r)},q=function(t,e,n,r){t instanceof m&&(t=t._wrapped),e instanceof m&&(e=e._wrapped);var i=p.call(t);if(i!==p.call(e))return!1;switch(i){case"[object RegExp]":case"[object String]":return""+t==""+e;case"[object Number]":return+t!=+t?+e!=+e:0==+t?1/+t==1/e:+t==+e;case"[object Date]":case"[object Boolean]":return+t==+e;case"[object Symbol]":return c.valueOf.call(t)===c.valueOf.call(e)}var o="[object Array]"===i;if(!o){if("object"!=typeof t||"object"!=typeof e)return!1;var a=t.constructor,s=e.constructor;if(a!==s&&!(m.isFunction(a)&&a instanceof a&&m.isFunction(s)&&s instanceof s)&&"constructor"in t&&"constructor"in e)return!1}n=n||[],r=r||[];for(var l=n.length;l--;)if(n[l]===t)return r[l]===e;if(n.push(t),r.push(e),o){if((l=t.length)!==e.length)return!1;for(;l--;)if(!R(t[l],e[l],n,r))return!1}else{var u,f=m.keys(t);if(l=f.length,m.keys(e).length!==l)return!1;for(;l--;)if(u=f[l],!j(e,u)||!R(t[u],e[u],n,r))return!1}return n.pop(),r.pop(),!0},m.isEqual=function(t,e){return R(t,e)},m.isEmpty=function(t){return null==t||(S(t)&&(m.isArray(t)||m.isString(t)||m.isArguments(t))?0===t.length:0===m.keys(t).length)},m.isElement=function(t){return!(!t||1!==t.nodeType)},m.isArray=d||function(t){return"[object Array]"===p.call(t)},m.isObject=function(t){var e=typeof t;return"function"===e||"object"===e&&!!t},m.each(["Arguments","Function","String","Number","Date","RegExp","Error","Symbol","Map","WeakMap","Set","WeakSet"],function(t){m["is"+t]=function(e){return p.call(e)==="[object "+t+"]"}}),m.isArguments(arguments)||(m.isArguments=function(t){return j(t,"callee")});var L=i.document&&i.document.childNodes;"object"!=typeof Int8Array&&"function"!=typeof L&&(m.isFunction=function(t){return"function"==typeof t||!1}),m.isFinite=function(t){return!m.isSymbol(t)&&isFinite(t)&&!isNaN(parseFloat(t))},m.isNaN=function(t){return m.isNumber(t)&&isNaN(t)},m.isBoolean=function(t){return!0===t||!1===t||"[object Boolean]"===p.call(t)},m.isNull=function(t){return null===t},m.isUndefined=function(t){return void 0===t},m.has=function(t,e){if(!m.isArray(e))return j(t,e);for(var n=e.length,r=0;r<n;r++){var i=e[r];if(null==t||!f.call(t,i))return!1;t=t[i]}return!!n},m.noConflict=function(){return i._=o,this},m.identity=function(t){return t},m.constant=function(t){return function(){return t}},m.noop=function(){},m.property=function(t){return m.isArray(t)?function(e){return O(e,t)}:w(t)},m.propertyOf=function(t){return null==t?function(){}:function(e){return m.isArray(e)?O(t,e):t[e]}},m.matcher=m.matches=function(t){return t=m.extendOwn({},t),function(e){return m.isMatch(e,t)}},m.times=function(t,e,n){var r=Array(Math.max(0,t));e=b(e,n,1);for(var i=0;i<t;i++)r[i]=e(i);return r},m.random=function(t,e){return null==e&&(e=t,t=0),t+Math.floor(Math.random()*(e-t+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},U=m.invert(B),Y=function(t){var e=function(e){return t[e]},n="(?:"+m.keys(t).join("|")+")",r=RegExp(n),i=RegExp(n,"g");return function(t){return t=null==t?"":""+t,r.test(t)?t.replace(i,e):t}};m.escape=Y(B),m.unescape=Y(U),m.result=function(t,e,n){m.isArray(e)||(e=[e]);var r=e.length;if(!r)return m.isFunction(n)?n.call(t):n;for(var i=0;i<r;i++){var o=null==t?void 0:t[e[i]];void 0===o&&(o=n,i=r),t=m.isFunction(o)?o.call(t):o}return t};var K=0;m.uniqueId=function(t){var e=++K+"";return t?t+e:e},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var G=/(.)^/,V={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},J=/\\|'|\r|\n|\u2028|\u2029/g,Z=function(t){return"\\"+V[t]};m.template=function(t,e,n){!e&&n&&(e=n),e=m.defaults({},e,m.templateSettings);var r,i=RegExp([(e.escape||G).source,(e.interpolate||G).source,(e.evaluate||G).source].join("|")+"|$","g"),o=0,a="__p+='";t.replace(i,function(e,n,r,i,s){return a+=t.slice(o,s).replace(J,Z),o=s+e.length,n?a+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'":r?a+="'+\n((__t=("+r+"))==null?'':__t)+\n'":i&&(a+="';\n"+i+"\n__p+='"),e}),a+="';\n",e.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{r=new Function(e.variable||"obj","_",a)}catch(t){throw t.source=a,t}var s=function(t){return r.call(this,t,m)},c=e.variable||"obj";return s.source="function("+c+"){\n"+a+"}",s},m.chain=function(t){var e=m(t);return e._chain=!0,e};var Q=function(t,e){return t._chain?m(e).chain():e};m.mixin=function(t){return m.each(m.functions(t),function(e){var n=m[e]=t[e];m.prototype[e]=function(){var t=[this._wrapped];return l.apply(t,arguments),Q(this,n.apply(m,t))}}),m},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(t){var e=a[t];m.prototype[t]=function(){var n=this._wrapped;return e.apply(n,arguments),"shift"!==t&&"splice"!==t||0!==n.length||delete n[0],Q(this,n)}}),m.each(["concat","join","slice"],function(t){var e=a[t];m.prototype[t]=function(){return Q(this,e.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return String(this._wrapped)},void 0===(r=function(){return m}.apply(e,[]))||(n.exports=r)}()}).call(this,n(31),n(32)(t))},function(t,e,n){"use strict";function r(t,e){var n=parseInt(t.substring(6,10)),r=parseInt(t.substring(0,3)),i=parseInt(t.substring(3,5)),o=parseInt(e.substring(0,2)),a=parseInt(e.substring(3,5)),s=parseInt(e.substring(6,8));return new Date(n,r,i,o,a,s)}function i(){$("#Plot").prop("disabled",!0)}function o(t,e,n,o,a){if("--"==(s=$("#interval option:selected")).text());else{var s,c=r(t,n),l=(r(e,o)-c)/1e3,u=(s=$("#interval option:selected")).data("seconds");l=Math.floor(l/u);l>=0&&l<60?($("#prompt_user").html("a "+s.text()+" interval would plot about "+l.toString()+" data points; that's too few - please try again"),$("#default").attr("selected","selected"),i()):l<0?($("#prompt_user").html("The end date is before the start date. Please choose a later end date."),$("#default").attr("selected","selected")):l>1e3?($("#prompt_user").html("a "+s.text()+" interval would plot about "+l.toString()+" data points; that's too many - please try again"),$("#default").attr("selected","selected"),i()):($("#prompt_user").html("a "+s.text()+" interval would plot about "+l.toString()+" data points."),$("#Plot").prop("disabled",!1))}}t.exports.loading=function(){},t.exports.disable=function(){$("#Start-date-picker").prop("disabled",!0),$("#Start-time-picker").prop("disabled",!0),$("#End-date-picker").prop("disabled",!0),$("#End-time-picker").prop("disabled",!0),$("#interval").prop("disabled",!0),$("#Plot").prop("disabled",!0)},t.exports.enable=function(){$("#Start-date-picker").prop("disabled",!1),$("#Start-time-picker").prop("disabled",!1),$("#End-date-picker").prop("disabled",!1),$("#End-time-picker").prop("disabled",!1),$("#interval").prop("disabled",!1)},t.exports.checkInterval=function(){var t=$("#Start-date-picker").val(),e=$("#End-date-picker").val(),n=$("#Start-time-picker").val(),r=$("#End-time-picker").val(),i=$("#interval"),a=$("#interval option:selected");t&&e&&n&&r||"--"==a.text()||($("#prompt_user").html("Please fill out all other fields before filling out the interval field"),$("#default").attr("selected","selected")),o(t,e,n,r,i)}},function(t,e,n){"use strict";var r=n(18)();t.exports=function(t){return t!==r&&null!==t}},function(t,e){t.exports=Plotly},function(t,e,n){"use strict";var r=n(0);function i(t){return 1.8*t+32}function o(t){return t}String.prototype.format||(String.prototype.format=function(){var t=arguments;return this.replace(/{(\d+)}/g,function(e,n){return void 0!==t[n]?t[n]:e})});var a={null:o,undefined:o,getF:i,getPresInHg:function(t){return.02952998751*t},getSpeedMPH:function(t){return 3600*t/1608},getAccumMillimeter:function(t){return 25.4*t},cardinalWDir:function(t){return["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"][Math.floor((t+11.25)%360/22.5)]},getSpeedKTS:function(t){return 1.94384*t}};function s(t,e,n){var r;return null===t?(t="",r=""):(r="yaxis2"in e&&"convert_value"in e.yaxis2?(r=a[e.yaxis2.convert_value](t)).toFixed?r.toFixed(e.yaxis2.precision):r:void 0,t=(t=a[e.yaxis.convert_value](t)).toFixed?t.toFixed(e.yaxis.precision):t),"yaxis2"in e&&void 0!==r?"{0}: {1}{2} ({3}{4})".format(n.name,t,e.yaxis.units,r,e.yaxis2.units):"{0}: {1}{2}".format(n.name,t,e.yaxis.units)}function c(t,e,n,r){for(var i=[],o=0;o<t.length;o++)i.push(s(t[o],e,n));return i}var l={undefined:c,null:c,dewpoint:function(t,e,n,r){var i,o=[],a=void 0;"anc_variables"in n&&1==n.anc_variables.length&&(a=r[n.anc_variables[0]]);var c=n.anc_info[n.anc_variables[0]];c||(c={name:n.anc_variables[0],units:"",precision:2});for(var l=0;l<t.length;l++)i=s(t[l],e,n),void 0!==a&&(i+="<br>{0}: {1}{2}".format(c.name,a[l]?a[l].toFixed(c.precision):"",c.units)),o.push(i);return o},water_temp:function(t,e,n,r){for(var o,a,s,c,l,u=[],p=0;p<t.length;p++){a=t[p],c=[],l=n.y[p];for(var f=0;f<a.length;f++)s=a[f],o="Depth: {0}m<br>{1}: {2} °C ({3} °F)".format(l.toFixed(1),n.name,null!==s?s.toFixed(3):"N/A",null!==s?i(s).toFixed(3):"N/A"),c.push(o);u.push(c)}return u}};t.exports.getTickVals=function(t,e,n){var i=.02*(e-t),o=((e+=i)-(t-=i))/4;return r.range(t,e+o,o)},t.exports.getProbeText=function(t,e,n,r){return"probe_text"in n?l[n.probe_text](t,e,n,r):c(t,e,n)},t.exports.getTickText=function(t,e){for(var n=[],r=0;r<t.length;r++){var i=a[e.convert_value](t[r]);i=i.toFixed?i.toFixed(e.precision):i,n.push(i)}return n}},function(t,e,n){"use strict";t.exports.buildRequestUrl=function(t,e,n,r,i,o,a){var s=METOBS_API_URL+"/api/data."+t+"?";return s+="interval="+e,s+="&epoch="+n,s+="&sep="+r||!1,s+="&order="+i,s+=o,s+="&symbols="+a}},function(t,e,n){"use strict";var r=n(7),i=n(9);n(0);window.MeteorogramController=function(t,e,n){var o=i.getDispatcher();return{plotDiv:t,controlDiv:e,dataCache:[],initMeteorogram:function(t,e){this.hasGraph=!0,this.plotDiv=t||this.plotDiv,o.dispatch({status:"initPlot",emit:"plotEmitter",location:this.plotDiv,dataCache:this.dataCache,plotsInfo:n,plotOrder:e})},initMeteorogramTable:function(t,e){this.hasTable=!0,this.tableDiv=t||this.plotDiv,o.dispatch({status:"initTable",emit:"plotEmitter",location:this.tableDiv,plotsInfo:n,plotOrder:e})},initMeteorogramControls:function(t){r(this.controlDiv,this.plotDiv,o)},displayRealTime:function(){this.hasTable&&o.dispatch({status:"update_table",emit:"plotEmitter",time:"-3:00:00",location:this.tableDiv}),this.hasGraph&&o.dispatch({status:"get_since_now",emit:"plotEmitter",time:"-3:00:00",location:this.plotDiv})},showPlot:function(t){o.dispatch({status:"show"+t,emit:"checkboxEmitter",location:this.div})},hidePlot:function(t){o.dispatch({status:"hide"+t,emit:"checkboxEmitter",location:this.div})},displayRecent:function(t){o.dispatch({status:"get_since_now",emit:"plotEmitter",time:t})},displayTimeRange:function(t,e,n){o.dispatch({status:"get_between_dates",emit:"plotEmitter",start:t,end:e,interval:n||"auto"})}}}},function(t,e,n){"use strict";n(1);var r=n(8);var i=function(t,e){$(t+" #plot-btn").click(function(){!function(t){t.dispatch({status:"get_between_dates",emit:"plotEmitter",start:$("#Start-date-picker").val().split(" ").join("T")+":00",end:$("#End-date-picker").val().split(" ").join("T")+":00",interval:"auto"})}(e)}),$(t+" #dropDownId").change(function(){!function(t,e){"realtime"==t?e.dispatch({status:"get_since_now",emit:"plotEmitter",time:"-3:00:00"}):e.dispatch({status:"get_since_now",emit:"plotEmitter",time:t})}($(this).val(),e)})},o=function(t,e){$(e+" #dropDownId").prop("disabled","recent"!=t),$(e+" #interval").prop("disabled","range"!=t),$(e+" #Start-date-picker").prop("disabled","range"!=t),$(e+" #End-date-picker").prop("disabled","range"!=t),$(e+" #Start-time-picker").prop("disabled","range"!=t),$(e+" #End-time-picker").prop("disabled","range"!=t),$(e+" #plot-btn").prop("disabled","range"!=t)},a=function(t,e,n){var r="#"+t;!function(t){$(t+" #Start-date-picker").datetimepicker({changeMonth:!0,changeYear:!0,dateFormat:"yy-mm-dd",timeFormat:"HH:mm",showSecond:!1,showMillisec:!1,showMicrosec:!1}),$(t+" #End-date-picker").datetimepicker({changeMonth:!0,changeYear:!0,dateFormat:"yy-mm-dd",timeFormat:"HH:mm",showSecond:!1,showMillisec:!1,showMicrosec:!1}),$(t+" [type=text]").prop("disabled",!0),$(t+" select").prop("disabled",!0),$(t+" #last_x_days").click(function(){o("recent",t)}),$(t+" #date_range").click(function(){o("range",t)}),$(t+" #last_x_days").trigger("click")}(r),i(r,n)};$(document).ready(function(){}),t.exports=function(t,e,n){$("#"+t).append(r.controlPanelTemplate),a(t,e,n)}},function(t,e,n){"use strict";t.exports={controlPanelTemplate:'<div class="row" id="control-panel-row"><div id="show-hide-boxes" class="col-md-12"></div><div class = "col-md-9"><div class="row" style="padding: 0 1em;"><div class="form-group"><table style="width:100%"><tr><td><div class="radio"><label><input type="radio" id="last_x_days" name="time_select">Recent Data:</label></div></td><td><select class="form-control" id="dropDownId"><option selected value="realtime">Realtime Update</option><option value="-1:00:00">Past 1 Hour</option><option value="-2:00:00">Past 2 Hours</option><option value="-3:00:00">Past 3 Hours</option><option value="-6:00:00">Past 6 Hours</option><option value="-12:00:00">Past 12 Hours</option><option value="-18:00:00">Past 18 Hours</option><option value="-24:00:00">Past 24 Hours</option><option value="-96:00:00">Past 4 Days</option></select></td><td style="padding-left:.5em"><div class="radio"><label><input type="radio" id="date_range" name="time_select">Date Range:</label></div></td><td><input class="form-control" style="padding 0.5em 0;" id="Start-date-picker" type="text" placeholder="YYYY-MM-DD"/></td><td>to </td><td><input class="form-control" style="padding 0.5em 0;" id="End-date-picker" type="text" placeholder="YYYY-MM-DD"/></td><td><button class="btn btn-primary btn-block" id="plot-btn">Plot</button></td></tr></table></div></div></div></div>',checkboxTemplates:{"aoss.tower":'<div class="form-group"><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="temp">Temperature + Dewpoint</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="pres">Pressure</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="wS">Wind Speed</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="wD">Wind Direction</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="aP">Precipitation</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="sF">Solar Flux</label></div>',"mendota.buoy":'<div class="form-group"><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="temp">Temperature + Dewpoint</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="rh">Relative Humidity</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="wS">Wind Speed</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="wD">Wind Direction</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="chlor">Chlorophyll</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="phyco">Phycocyanin</label></div>'}}},function(t,e,n){"use strict";var r=n(10),i=n(26),o=n(29),a=n(30),s=n(33),c=n(1);t.exports.getDispatcher=function(){var t=new i.Dispatcher;t.GRAPH_HEIGHT=170;var e=r({visible:{},setPlots:function(t){for(var e in t)this.visible[e]=!0},setShowing:function(t,e){this.showing[t]=void 0===e?!this.showing[t]:e},getShowing:function(t){return this.showing[t]},handleActions:function(t){"checkboxEmitter"==t.emit&&this.emit(t.status,t.location)}});e.dispatchToken=t.register(e.handleActions.bind(e));var n=r({handleActions:function(n){"plotEmitter"==n.emit&&(t.waitFor([e.dispatchToken]),void 0!==n.location&&(this.div=n.location),void 0!==n.plotsInfo&&(this.plotsInfo=n.plotsInfo,this.plotOrder=this.plotsInfo.defaultPlots),void 0!==n.plotOrder&&(this.plotOrder=n.plotOrder),void 0!==n.dataCache&&(this.dataCache=n.dataCache),"get_since_now"==n.status?this.emit(n.status,n.time,this.plotsInfo,this.dataCache,this.div):"update_table"==n.status?this.emit(n.status,n.time,this.plotsInfo,this.div):"get_between_dates"==n.status?this.emit(n.status,n.start,n.end,n.interval,this.plotsInfo,this.dataCache,this.div):"initPlot"==n.status?this.emit(n.status,n.location,n.plotOrder?n.plotOrder:this.plotOrder,this.plotsInfo,this.dataCache):"initTable"==n.status?this.emit(n.status,n.location,n.plotOrder?n.plotOrder:this.plotOrder,this.plotsInfo):"update"==n.status?this.emit(n.status,this.div,this.plotsInfo,this.dataCache,n.startTime):this.emit(n.status,n.userInfo))}});function l(t){if(t.progress||(t.progress={}),t.progress.validID){var e=t.progress.id[0];clearInterval(e),t.progress.validID=!1}}var u={"1m":3e4,"5m":15e4,"1h":18e5};function p(e,n,r){r.progress||(r.progress={}),l(r),void 0===e&&(e=r.progress.id[1]),void 0===n&&(n=r.progress.id[2]);var i=setInterval(function(e){return function(){t.dispatch({status:"update",emit:"plotEmitter",startTime:e})}}(e),u[n]);r.progress.id=[i,e,n],r.progress.validID=!0}return n.on("initTable",function(t,n,r){e.setPlots(r),a.initTable(t,n,r)}),n.on("update_table",function(t,e,n){a.requestTableUpdate(n,e),setInterval(function(){a.requestTableUpdate(n,e)},u["1m"])}),n.on("initPlot",function(t,n,r,i){e.setPlots(r),o.initPlot(i,t,n,r)}),n.on("get_since_now",function(t,e,n,r){p(t,s.requestPlotUpdate(n,r,e,t,void 0,void 0,void 0,l),e)}),n.on("get_between_dates",function(t,e,n,r,i,o){l(r),s.requestPlotUpdate(i,o,r,t,e,n)}),n.on("update",function(t,e,n,r){s.requestPlotUpdate(n,t,e,r,void 0,void 0,!0)}),n.on("checking_custom",function(){c.checkInterval()}),n.dispatchToken=t.register(n.handleActions.bind(n)),t}},function(t,e,n){"use strict";var r,i,o,a,s,c,l,u=n(11),p=n(25),f=Function.prototype.apply,d=Function.prototype.call,h=Object.create,v=Object.defineProperty,y=Object.defineProperties,m=Object.prototype.hasOwnProperty,g={configurable:!0,enumerable:!1,writable:!0};s={on:r=function(t,e){var n;return p(e),m.call(this,"__ee__")?n=this.__ee__:(n=g.value=h(null),v(this,"__ee__",g),g.value=null),n[t]?"object"==typeof n[t]?n[t].push(e):n[t]=[n[t],e]:n[t]=e,this},once:i=function(t,e){var n,i;return p(e),i=this,r.call(this,t,n=function(){o.call(i,t,n),f.call(e,this,arguments)}),n.__eeOnceListener__=e,this},off:o=function(t,e){var n,r,i,o;if(p(e),!m.call(this,"__ee__"))return this;if(!(n=this.__ee__)[t])return this;if("object"==typeof(r=n[t]))for(o=0;i=r[o];++o)i!==e&&i.__eeOnceListener__!==e||(2===r.length?n[t]=r[o?0:1]:r.splice(o,1));else r!==e&&r.__eeOnceListener__!==e||delete n[t];return this},emit:a=function(t){var e,n,r,i,o;if(m.call(this,"__ee__")&&(i=this.__ee__[t]))if("object"==typeof i){for(n=arguments.length,o=new Array(n-1),e=1;e<n;++e)o[e-1]=arguments[e];for(i=i.slice(),e=0;r=i[e];++e)f.call(r,this,o)}else switch(arguments.length){case 1:d.call(i,this);break;case 2:d.call(i,this,arguments[1]);break;case 3:d.call(i,this,arguments[1],arguments[2]);break;default:for(n=arguments.length,o=new Array(n-1),e=1;e<n;++e)o[e-1]=arguments[e];f.call(i,this,o)}}},c={on:u(r),once:u(i),off:u(o),emit:u(a)},l=y({},c),t.exports=e=function(t){return null==t?h(l):y(Object(t),c)},e.methods=s},function(t,e,n){"use strict";var r=n(12),i=n(20),o=n(21),a=n(22);(t.exports=function(t,e){var n,o,s,c,l;return arguments.length<2||"string"!=typeof t?(c=e,e=t,t=null):c=arguments[2],null==t?(n=s=!0,o=!1):(n=a.call(t,"c"),o=a.call(t,"e"),s=a.call(t,"w")),l={value:e,configurable:n,enumerable:o,writable:s},c?r(i(c),l):l}).gs=function(t,e,n){var s,c,l,u;return"string"!=typeof t?(l=n,n=e,e=t,t=null):l=arguments[3],null==e?e=void 0:o(e)?null==n?n=void 0:o(n)||(l=n,n=void 0):(l=e,e=n=void 0),null==t?(s=!0,c=!1):(s=a.call(t,"c"),c=a.call(t,"e")),u={get:e,set:n,configurable:s,enumerable:c},l?r(i(l),u):u}},function(t,e,n){"use strict";t.exports=n(13)()?Object.assign:n(14)},function(t,e,n){"use strict";t.exports=function(){var t,e=Object.assign;return"function"==typeof e&&(e(t={foo:"raz"},{bar:"dwa"},{trzy:"trzy"}),t.foo+t.bar+t.trzy==="razdwatrzy")}},function(t,e,n){"use strict";var r=n(15),i=n(19),o=Math.max;t.exports=function(t,e){var n,a,s,c=o(arguments.length,2);for(t=Object(i(t)),s=function(r){try{t[r]=e[r]}catch(t){n||(n=t)}},a=1;a<c;++a)e=arguments[a],r(e).forEach(s);if(void 0!==n)throw n;return t}},function(t,e,n){"use strict";t.exports=n(16)()?Object.keys:n(17)},function(t,e,n){"use strict";t.exports=function(){try{return Object.keys("primitive"),!0}catch(t){return!1}}},function(t,e,n){"use strict";var r=n(2),i=Object.keys;t.exports=function(t){return i(r(t)?Object(t):t)}},function(t,e,n){"use strict";t.exports=function(){}},function(t,e,n){"use strict";var r=n(2);t.exports=function(t){if(!r(t))throw new TypeError("Cannot use null or undefined");return t}},function(t,e,n){"use strict";var r=n(2),i=Array.prototype.forEach,o=Object.create;t.exports=function(t){var e=o(null);return i.call(arguments,function(t){r(t)&&function(t,e){var n;for(n in t)e[n]=t[n]}(Object(t),e)}),e}},function(t,e,n){"use strict";t.exports=function(t){return"function"==typeof t}},function(t,e,n){"use strict";t.exports=n(23)()?String.prototype.contains:n(24)},function(t,e,n){"use strict";var r="razdwatrzy";t.exports=function(){return"function"==typeof r.contains&&(!0===r.contains("dwa")&&!1===r.contains("foo"))}},function(t,e,n){"use strict";var r=String.prototype.indexOf;t.exports=function(t){return r.call(this,t,arguments[1])>-1}},function(t,e,n){"use strict";t.exports=function(t){if("function"!=typeof t)throw new TypeError(t+" is not a function");return t}},function(t,e,n){t.exports.Dispatcher=n(27)},function(t,e,n){"use strict";e.__esModule=!0;var r=n(28),i=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this._callbacks={},this._isDispatching=!1,this._isHandled={},this._isPending={},this._lastID=1}return t.prototype.register=function(t){var e="ID_"+this._lastID++;return this._callbacks[e]=t,e},t.prototype.unregister=function(t){this._callbacks[t]||r(!1),delete this._callbacks[t]},t.prototype.waitFor=function(t){this._isDispatching||r(!1);for(var e=0;e<t.length;e++){var n=t[e];this._isPending[n]?this._isHandled[n]||r(!1):(this._callbacks[n]||r(!1),this._invokeCallback(n))}},t.prototype.dispatch=function(t){this._isDispatching&&r(!1),this._startDispatching(t);try{for(var e in this._callbacks)this._isPending[e]||this._invokeCallback(e)}finally{this._stopDispatching()}},t.prototype.isDispatching=function(){return this._isDispatching},t.prototype._invokeCallback=function(t){this._isPending[t]=!0,this._callbacks[t](this._pendingPayload),this._isHandled[t]=!0},t.prototype._startDispatching=function(t){for(var e in this._callbacks)this._isPending[e]=!1,this._isHandled[e]=!1;this._pendingPayload=t,this._isDispatching=!0},t.prototype._stopDispatching=function(){delete this._pendingPayload,this._isDispatching=!1},t}();t.exports=i},function(t,e,n){"use strict";var r=function(t){};t.exports=function(t,e,n,i,o,a,s,c){if(r(e),!t){var l;if(void 0===e)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,i,o,a,s,c],p=0;(l=new Error(e.replace(/%s/g,function(){return u[p++]}))).name="Invariant Violation"}throw l.framesToPop=1,l}}},function(t,e,n){"use strict";var r=n(3),i=n(1);function o(t,e,n,r){for(var i,o={gridcolor:"#777777",titlefont:{size:12},title:n.title,zeroline:!1,overlaying:"y"+(t-1).toString(),side:"right",anchor:"x"},a=0;a<r.length;a++)(i=r[a])in n&&(o[i]=n[i]);return o}t.exports.initPlot=function(t,e,n,a){var s=n.length,c={title:a.title,showlegend:!1,height:170*s+180};c.xaxis={domain:[0,1],showline:!1,zeroline:!1,showticklabels:s>0,gridcolor:"#777777",showgrid:!1,tickformat:"%Y-%m-%d %H:%MZ"};for(var l,u,p,f,d,h,v,y,m=0,g=1/s,b=m,_=["color","mode","zmin","zmax","y","contours","line","colorscale","showscale","colorbar","tick0","dtick","hovermode"],x=["nticks","range","autorange","zeroline","showgrid","tickmode","ticktext","tickvals"],k=0;k<n.length;k++){h=n[k],b=m+=1,l=(u=a.plots[h]).yaxis,y=[(n.length-1-k)*g*1.03,1-k*g*1.05];for(var w=0;w<u.traces.length;w++){f={name:(p=u.traces[w]).name,x:[],y:[],text:[],type:p.type?p.type:"scatter",xaxis:"x1",yaxis:"y"+m,hoverinfo:"x+text",hovermode:"closest",var_names:p.var_names,anc_variables:p.anc_variables,anc_data:[],plot_name:h,trace_index:w},p.isSecondAxis&&(f.yaxis="y"+(m+w));for(var j=0;j<_.length;j++)(v=_[j])in p&&(f[v]=p[v]);"colorbar"in f&&(f.colorbar.len=y[1]-y[0],f.colorbar.y=(y[1]-y[0])/2+y[0],f.z=[]),t.push(f)}for(d={gridcolor:"#777777",titlefont:{size:12},title:l.title,zeroline:!1,domain:[(n.length-1-k)*g*1.03,1-k*g*1.05]},j=0;j<x.length;j++)(v=x[j])in l&&(d[v]=l[v]);c["yaxis"+m]=d,"yaxis2"in u&&!u.yaxis2.skip&&(d=o(m+=1,0,l=u.yaxis2,x),c["yaxis"+m]=d)}c.xaxis.anchor="y"+b,r.plot(e,t,c,{showLink:!1,displaylogo:!1,displayModeBar:!0,responsive:!0}),i.loading()}},function(t,e,n){"use strict";var r=n(4),i=n(5);function o(t,e,n,r){for(var i=0;i<r.anc_variables.length;i++){var o=r.anc_info[r.anc_variables[i]],a=$("<td>N/A</td>");a.addClass("met_data"),a.data("info",{key:e,idx:n,anc_idx:i});var s=$("<tr></tr>"),c=o.short_name||o.name;s.append("<td>"+c+"</td>"),s.append(a),s.append('<td class="convert"></td>'),t.append(s)}}function a(t,e,n,r,i){var o='<tr><td colspan="2">'+(l=r.short_name||r.name)+"</td><td></td>";t.append(o);for(var a=0;a<r.y_highlight.length;a++){var s=r.y_highlight[a],c=$("<tr></tr>"),l=r.y[s]+i.yaxis.units;c.append('<td class="subtitle text-center">'+l+"</td>");var u=$("<td>N/A</td>");u.addClass("met_data"),u.data("info",{key:e,idx:n,hl_idx:s}),c.append(u),c.append('<td class="convert"></td>'),t.append(c)}}function s(t,e,n,i,o){for(var a=0;a<i.y_highlight.length;a++){var s=i.y_highlight[a],c=t[i.var_names[s]][0],l=i.zprobe.units,u=r.getTickText([c],i.zprobe),p="";if(i.zprobe2&&i.zprobe2.convert_value){var f=i.zprobe2.units;p=r.getTickText([c],i.zprobe2)+f}e[o].innerHTML=u+l,n[o].innerHTML=p,o+=1}return o}function c(t,e,n,i){for(var o=0;o<n.anc_variables.length;o++){var a=n.anc_variables[o],s=n.anc_info[a],c=t[a][0],l=r.getTickText([c],s);e[i].innerHTML=c||0==c?l+s.units:"N/A",i+=1}return i}t.exports.initTable=function(t,e,n){for(var r,i,s=$("#"+t),c=$('<table class="met_table"><tbody></tbody></table>'),l=c.children("tbody"),u=0;u<e.length;u++){i=e[u],r=n.plots[i];for(var p=0;p<r.traces.length;p++){var f=r.traces[p];if("contour"==f.type)a(l,i,p,f,r);else{var d=$("<td>N/A</td>");d.addClass("met_data"),d.data("info",{key:i,idx:p});var h=$("<tr></tr>"),v=f.short_name||f.name;h.append("<td>"+v+"</td>"),h.append(d),h.append('<td class="convert"></td>'),l.append(h),f.anc_variables&&o(l,i,p,f)}}}s.append("<h3>"+n.title+"</h3>"),s.append(c),s.append('<span id="timestamp"></span>')},t.exports.requestTableUpdate=function(t,e){$("#"+t);var n=[],o=[],a=$("#"+t+" .met_data"),l=$("#"+t+" .convert");a.each(function(){var t=$(this).data("info").key,r=$(this).data("info").idx,i=$(this).data("info").anc_idx,a=$(this).data("info").hl_idx,s=e.plots[t].traces[r];-1==o.indexOf(t)&&o.push(t),void 0!==i?n.push(s.anc_variables[0]):void 0!==a?n.push(s.var_names[a]):n.push(s.var_names[0])});var u=n.join(":"),p=i.buildRequestUrl("json","1m","","","column","&begin=-00:04:00",u);$.ajax({type:"GET",url:p,jsonp:"callback",dataType:"jsonp",success:function(n){n.div_id=t,n.plotOrder=o,n.data_cells=a,n.convert_cells=l,function(t,e){var n,i,o=t.results.data,a=0,l=t.div_id,u=t.plotOrder,p=t.data_cells,f=t.convert_cells;if(0!=t.num_results){$("#"+l+" #timestamp").html("Last updated: "+t.results.timestamps[0]);for(var d=0;d<u.length;d++){i=u[d],n=e.plots[i];for(var h=0;h<n.traces.length;h++){var v=n.traces[h];if("contour"==v.type)a=s(o,p,f,v,a);else{var y=o[v.var_names[0]][0];if(y||0==y){var m=n.yaxis.units,g="",b=n.yaxis.precision;n.yaxis.precision=Math.min(b,1);var _=r.getTickText([y],n.yaxis);if(n.yaxis.precision=b,n.yaxis2&&n.yaxis2.convert_value){var x=n.yaxis2.units,b=n.yaxis2.precision;n.yaxis2.precision=Math.min(b,1);var k=r.getTickText([y],n.yaxis2);n.yaxis2.precision=b,g=k+x}p[a].innerHTML=_+m,f[a].innerHTML=g}else p[a].innerHTML="N/A",f[a].innerHTML="";a+=1,v.anc_variables&&(a=c(o,p,v,a))}}}}else $("#"+l+" #timestamp").html("No recent data")}(n,e)}})}},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e,n){"use strict";var r=n(34),i=n(5),o=n(0);function a(t,e,n,i,a,s,c,l){$.ajax({type:"GET",url:e,jsonp:"callback",dataType:"jsonp",success:function(e){if(200!=e.code)return console.error("Invalid data API query. Code: {0} | Message: {1}".format(e.code,e.message)),void(void 0!==l&&l(i));var u=document.getElementById(a),p=function(t){var e={dates:o.map(t.timestamps,function(t){return t.replace("T"," ").substring(0,t.length-1)})};return o.extend(e,t.data),e}(e.results),f=t[0].x||[],d=p.dates;if(0!=(e={dates:d}).dates.length){if(s){for(var h=0;h<d.length&&d[h]<=f[f.length-1];)h++;if(h>=d.length)return void console.info("No new data downloaded");for(var v=0;v<n.length;v++)e[n[v]]=p[n[v]].slice(h);d=d.slice(h),e.dates=d}else for(v=0;v<n.length;v++)e[n[v]]=p[n[v]];r.updatePlot(t,u,i,e,s,c)}else console.warn("No data available from API")}})}var s=[[864e5,"5m","-00:10:00"],[2592e6,"1h","-02:00:00"]],c={"1m":60,"5m":300,"1h":3600};t.exports.requestPlotUpdate=function(t,e,n,r,l,u,p,f){var d,h,v,y,m=function(t){var e=[];return o.each(t,function(t){Array.prototype.push.apply(e,t.var_names),"anc_variables"in t&&Array.prototype.push.apply(e,t.anc_variables)}),o.uniq(e)}(t),g="";for(var b in m)g+=m[b],b<m.length-1&&(g+=":");if(l){if(y="&begin="+r+"&end="+l,"auto"==u)for(var b in u="1m",d=new Date(l)-new Date(r),s)d>=s[b][0]&&(u=s[b][1])}else{for(var b in u="1m",d=-36e5*(h=o.map(r.split(":"),Number))[0]+6e4*h[1]+1e3*h[2],s)d>=s[b][0]&&(u=s[b][1],p&&(r=s[b][2]));y="&begin="+r}return v=p?c.hasOwnProperty(u)?d/1e3/c[u]:250:0,a(t,i.buildRequestUrl("json",u,"","","column",y,g),m,n,e,p,v,f),u}},function(t,e,n){"use strict";function r(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e<t.length;e++)n[e]=t[e];return n}return Array.from(t)}var i=n(3),o=n(4),a=n(0);t.exports.updatePlot=function(t,e,n,s,c,l){!function(t,e,n,s,c,l){var u,p,f,d,h,v=s.dates,y=[],m=!1,g=[],b={x:[],y:[],text:[]},_=[],x={x:[],z:[],text:[]},k=0;for(f=0;f<t.length;f++)u=t[f].plot_name,y[y.length-1]!=u&&(p=n.plots[u],a.each(p.traces,function(e,n){if("contour"==t[k+n].type){var i;x.x.push(v),_.push(k+n),h=a.map(e.var_names,function(t){return s[t]}),(i=t[f].text).push.apply(i,r(o.getProbeText(h,p,e,s)));for(var c=0;c<e.var_names.length;c++){for(var l;c>=t[f].z.length;)t[f].z.push([]);(l=t[f].z[c]).push.apply(l,r(s[e.var_names[c]]))}x.z.push(t[f].z),x.text.push(t[f].text)}else b.x.push(v),g.push(k+n),a.each(e.var_names,function(t){b.y.push(s[t]),d="probe_text"in e&&null===e.probe_text?[void 0]:o.getProbeText(s[t],p,e,s),b.text.push(d)})}),k+=p.traces.length,y.push(u));if(g.length>0&&i.extendTraces(e,b,g),_.length>0)for(i.extendTraces(e,x,_),f=0;f<_.length;f++)t[_[f]].z.splice(0,t[_[f]].y.length),t[_[f]].text.splice(0,t[_[f]].y.length);0!=l||c||(l=s.dates.length,m=!0),l>0&&t[0].x.length>l&&function(t,e){for(var n=0;n<t.length;n++){if(t[n].x.splice(0,e),t[n].hasOwnProperty("z"))for(var r=0;r<t[n].z.length;r++)t[n].z[r].splice(0,e);else t[n].hasOwnProperty("y")&&t[n].y.splice(0,e);t[n].hasOwnProperty("text")&&t[n].text.splice(0,e)}}(t,t[0].x.length-l),m&&i.redraw(e)}(t,e,n,s,c,l)}}]);
\ No newline at end of file
+!function(n){var r={};function i(t){if(r[t])return r[t].exports;var e=r[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,i),e.l=!0,e.exports}i.m=n,i.c=r,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=7)}([function(t,Q,e){(function(V,Z){var J;!function(){function n(){}var t="object"==typeof self&&self.self===self&&self||"object"==typeof V&&V.global===V&&V||this||{},e=t._,r=Array.prototype,a=Object.prototype,p="undefined"!=typeof Symbol?Symbol.prototype:null,i=r.push,l=r.slice,f=a.toString,o=a.hasOwnProperty,s=Array.isArray,c=Object.keys,u=Object.create,d=function(t){return t instanceof d?t:this instanceof d?void(this._wrapped=t):new d(t)};Q.nodeType?t._=d:(!Z.nodeType&&Z.exports&&(Q=Z.exports=d),Q._=d),d.VERSION="1.9.1";function h(i,o,t){if(void 0===o)return i;switch(null==t?3:t){case 1:return function(t){return i.call(o,t)};case 3:return function(t,e,n){return i.call(o,t,e,n)};case 4:return function(t,e,n,r){return i.call(o,t,e,n,r)}}return function(){return i.apply(o,arguments)}}function v(t,e,n){return d.iteratee!==y?d.iteratee(t,e):null==t?d.identity:d.isFunction(t)?h(t,e,n):d.isObject(t)&&!d.isArray(t)?d.matcher(t):d.property(t)}var y;d.iteratee=y=function(t,e){return v(t,e,1/0)};function m(a,s){return s=null==s?a.length-1:+s,function(t,e){for(var n=Math.max(arguments.length-s,0),r=Array(n),i=0;i<n;i++)r[i]=arguments[i+s];switch(s){case 0:return a.call(this,r);case 1:return a.call(this,t,r);case 2:return a.call(this,t,e,r)}var o=Array(s+1);for(i=0;i<s;i++)o[i]=arguments[i];return o[s]=r,a.apply(this,o)}}function g(t){if(!d.isObject(t))return{};if(u)return u(t);n.prototype=t;var e=new n;return n.prototype=null,e}function b(e){return function(t){return null==t?void 0:t[e]}}function x(t,e){return null!=t&&o.call(t,e)}function _(t,e){for(var n=e.length,r=0;r<n;r++){if(null==t)return;t=t[e[r]]}return n?t:void 0}function k(t){var e=j(t);return"number"==typeof e&&0<=e&&e<=w}var w=Math.pow(2,53)-1,j=b("length");d.each=d.forEach=function(t,e,n){var r,i;if(e=h(e,n),k(t))for(r=0,i=t.length;r<i;r++)e(t[r],r,t);else{var o=d.keys(t);for(r=0,i=o.length;r<i;r++)e(t[o[r]],o[r],t)}return t},d.map=d.collect=function(t,e,n){e=v(e,n);for(var r=!k(t)&&d.keys(t),i=(r||t).length,o=Array(i),a=0;a<i;a++){var s=r?r[a]:a;o[a]=e(t[s],s,t)}return o};function T(l){return function(t,e,n,r){var i=3<=arguments.length;return function(t,e,n,r){var i=!k(t)&&d.keys(t),o=(i||t).length,a=0<l?0:o-1;for(r||(n=t[i?i[a]:a],a+=l);0<=a&&a<o;a+=l){var s=i?i[a]:a;n=e(n,t[s],s,t)}return n}(t,h(e,r,4),n,i)}}d.reduce=d.foldl=d.inject=T(1),d.reduceRight=d.foldr=T(-1),d.find=d.detect=function(t,e,n){var r=(k(t)?d.findIndex:d.findKey)(t,e,n);if(void 0!==r&&-1!==r)return t[r]},d.filter=d.select=function(t,r,e){var i=[];return r=v(r,e),d.each(t,function(t,e,n){r(t,e,n)&&i.push(t)}),i},d.reject=function(t,e,n){return d.filter(t,d.negate(v(e)),n)},d.every=d.all=function(t,e,n){e=v(e,n);for(var r=!k(t)&&d.keys(t),i=(r||t).length,o=0;o<i;o++){var a=r?r[o]:o;if(!e(t[a],a,t))return!1}return!0},d.some=d.any=function(t,e,n){e=v(e,n);for(var r=!k(t)&&d.keys(t),i=(r||t).length,o=0;o<i;o++){var a=r?r[o]:o;if(e(t[a],a,t))return!0}return!1},d.contains=d.includes=d.include=function(t,e,n,r){return k(t)||(t=d.values(t)),"number"==typeof n&&!r||(n=0),0<=d.indexOf(t,e,n)},d.invoke=m(function(t,n,r){var i,o;return d.isFunction(n)?o=n:d.isArray(n)&&(i=n.slice(0,-1),n=n[n.length-1]),d.map(t,function(t){var e=o;if(!e){if(i&&i.length&&(t=_(t,i)),null==t)return;e=t[n]}return null==e?e:e.apply(t,r)})}),d.pluck=function(t,e){return d.map(t,d.property(e))},d.where=function(t,e){return d.filter(t,d.matcher(e))},d.findWhere=function(t,e){return d.find(t,d.matcher(e))},d.max=function(t,r,e){var n,i,o=-1/0,a=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof t[0]&&null!=t)for(var s=0,l=(t=k(t)?t:d.values(t)).length;s<l;s++)null!=(n=t[s])&&o<n&&(o=n);else r=v(r,e),d.each(t,function(t,e,n){i=r(t,e,n),(a<i||i===-1/0&&o===-1/0)&&(o=t,a=i)});return o},d.min=function(t,r,e){var n,i,o=1/0,a=1/0;if(null==r||"number"==typeof r&&"object"!=typeof t[0]&&null!=t)for(var s=0,l=(t=k(t)?t:d.values(t)).length;s<l;s++)null!=(n=t[s])&&n<o&&(o=n);else r=v(r,e),d.each(t,function(t,e,n){((i=r(t,e,n))<a||i===1/0&&o===1/0)&&(o=t,a=i)});return o},d.shuffle=function(t){return d.sample(t,1/0)},d.sample=function(t,e,n){if(null==e||n)return k(t)||(t=d.values(t)),t[d.random(t.length-1)];var r=k(t)?d.clone(t):d.values(t),i=j(r);e=Math.max(Math.min(e,i),0);for(var o=i-1,a=0;a<e;a++){var s=d.random(a,o),l=r[a];r[a]=r[s],r[s]=l}return r.slice(0,e)},d.sortBy=function(t,r,e){var i=0;return r=v(r,e),d.pluck(d.map(t,function(t,e,n){return{value:t,index:i++,criteria:r(t,e,n)}}).sort(function(t,e){var n=t.criteria,r=e.criteria;if(n!==r){if(r<n||void 0===n)return 1;if(n<r||void 0===r)return-1}return t.index-e.index}),"value")};function M(a,e){return function(r,i,t){var o=e?[[],[]]:{};return i=v(i,t),d.each(r,function(t,e){var n=i(t,e,r);a(o,t,n)}),o}}d.groupBy=M(function(t,e,n){x(t,n)?t[n].push(e):t[n]=[e]}),d.indexBy=M(function(t,e,n){t[n]=e}),d.countBy=M(function(t,e,n){x(t,n)?t[n]++:t[n]=1});var O=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;d.toArray=function(t){return t?d.isArray(t)?l.call(t):d.isString(t)?t.match(O):k(t)?d.map(t,d.identity):d.values(t):[]},d.size=function(t){return null==t?0:k(t)?t.length:d.keys(t).length},d.partition=M(function(t,e,n){t[n?0:1].push(e)},!0),d.first=d.head=d.take=function(t,e,n){return null==t||t.length<1?null==e?void 0:[]:null==e||n?t[0]:d.initial(t,t.length-e)},d.initial=function(t,e,n){return l.call(t,0,Math.max(0,t.length-(null==e||n?1:e)))},d.last=function(t,e,n){return null==t||t.length<1?null==e?void 0:[]:null==e||n?t[t.length-1]:d.rest(t,Math.max(0,t.length-e))},d.rest=d.tail=d.drop=function(t,e,n){return l.call(t,null==e||n?1:e)},d.compact=function(t){return d.filter(t,Boolean)};var P=function(t,e,n,r){for(var i=(r=r||[]).length,o=0,a=j(t);o<a;o++){var s=t[o];if(k(s)&&(d.isArray(s)||d.isArguments(s)))if(e)for(var l=0,c=s.length;l<c;)r[i++]=s[l++];else P(s,e,n,r),i=r.length;else n||(r[i++]=s)}return r};d.flatten=function(t,e){return P(t,e,!1)},d.without=m(function(t,e){return d.difference(t,e)}),d.uniq=d.unique=function(t,e,n,r){d.isBoolean(e)||(r=n,n=e,e=!1),null!=n&&(n=v(n,r));for(var i=[],o=[],a=0,s=j(t);a<s;a++){var l=t[a],c=n?n(l,a,t):l;e&&!n?(a&&o===c||i.push(l),o=c):n?d.contains(o,c)||(o.push(c),i.push(l)):d.contains(i,l)||i.push(l)}return i},d.union=m(function(t){return d.uniq(P(t,!0,!0))}),d.intersection=function(t){for(var e=[],n=arguments.length,r=0,i=j(t);r<i;r++){var o=t[r];if(!d.contains(e,o)){var a;for(a=1;a<n&&d.contains(arguments[a],o);a++);a===n&&e.push(o)}}return e},d.difference=m(function(t,e){return e=P(e,!0,!0),d.filter(t,function(t){return!d.contains(e,t)})}),d.unzip=function(t){for(var e=t&&d.max(t,j).length||0,n=Array(e),r=0;r<e;r++)n[r]=d.pluck(t,r);return n},d.zip=m(d.unzip),d.object=function(t,e){for(var n={},r=0,i=j(t);r<i;r++)e?n[t[r]]=e[r]:n[t[r][0]]=t[r][1];return n};function S(o){return function(t,e,n){e=v(e,n);for(var r=j(t),i=0<o?0:r-1;0<=i&&i<r;i+=o)if(e(t[i],i,t))return i;return-1}}d.findIndex=S(1),d.findLastIndex=S(-1),d.sortedIndex=function(t,e,n,r){for(var i=(n=v(n,r,1))(e),o=0,a=j(t);o<a;){var s=Math.floor((o+a)/2);n(t[s])<i?o=s+1:a=s}return o};function D(o,a,s){return function(t,e,n){var r=0,i=j(t);if("number"==typeof n)0<o?r=0<=n?n:Math.max(n+i,r):i=0<=n?Math.min(n+1,i):n+i+1;else if(s&&n&&i)return t[n=s(t,e)]===e?n:-1;if(e!=e)return 0<=(n=a(l.call(t,r,i),d.isNaN))?n+r:-1;for(n=0<o?r:i-1;0<=n&&n<i;n+=o)if(t[n]===e)return n;return-1}}d.indexOf=D(1,d.findIndex,d.sortedIndex),d.lastIndexOf=D(-1,d.findLastIndex),d.range=function(t,e,n){null==e&&(e=t||0,t=0),n||(n=e<t?-1:1);for(var r=Math.max(Math.ceil((e-t)/n),0),i=Array(r),o=0;o<r;o++,t+=n)i[o]=t;return i},d.chunk=function(t,e){if(null==e||e<1)return[];for(var n=[],r=0,i=t.length;r<i;)n.push(l.call(t,r,r+=e));return n};function I(t,e,n,r,i){if(!(r instanceof e))return t.apply(n,i);var o=g(t.prototype),a=t.apply(o,i);return d.isObject(a)?a:o}d.bind=m(function(e,n,r){if(!d.isFunction(e))throw new TypeError("Bind must be called on a function");var i=m(function(t){return I(e,i,n,this,r.concat(t))});return i}),d.partial=m(function(i,o){var a=d.partial.placeholder,s=function(){for(var t=0,e=o.length,n=Array(e),r=0;r<e;r++)n[r]=o[r]===a?arguments[t++]:o[r];for(;t<arguments.length;)n.push(arguments[t++]);return I(i,s,this,this,n)};return s}),(d.partial.placeholder=d).bindAll=m(function(t,e){var n=(e=P(e,!1,!1)).length;if(n<1)throw new Error("bindAll must be passed function names");for(;n--;){var r=e[n];t[r]=d.bind(t[r],t)}}),d.memoize=function(r,i){var o=function(t){var e=o.cache,n=""+(i?i.apply(this,arguments):t);return x(e,n)||(e[n]=r.apply(this,arguments)),e[n]};return o.cache={},o},d.delay=m(function(t,e,n){return setTimeout(function(){return t.apply(null,n)},e)}),d.defer=d.partial(d.delay,d,1),d.throttle=function(n,r,i){var o,a,s,l,c=0;i||(i={});function u(){c=!1===i.leading?0:d.now(),o=null,l=n.apply(a,s),o||(a=s=null)}function t(){var t=d.now();c||!1!==i.leading||(c=t);var e=r-(t-c);return a=this,s=arguments,e<=0||r<e?(o&&(clearTimeout(o),o=null),c=t,l=n.apply(a,s),o||(a=s=null)):o||!1===i.trailing||(o=setTimeout(u,e)),l}return t.cancel=function(){clearTimeout(o),c=0,o=a=s=null},t},d.debounce=function(n,r,i){function o(t,e){a=null,e&&(s=n.apply(t,e))}var a,s,t=m(function(t){if(a&&clearTimeout(a),i){var e=!a;a=setTimeout(o,r),e&&(s=n.apply(this,t))}else a=d.delay(o,r,this,t);return s});return t.cancel=function(){clearTimeout(a),a=null},t},d.wrap=function(t,e){return d.partial(e,t)},d.negate=function(t){return function(){return!t.apply(this,arguments)}},d.compose=function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},d.after=function(t,e){return function(){if(--t<1)return e.apply(this,arguments)}},d.before=function(t,e){var n;return function(){return 0<--t&&(n=e.apply(this,arguments)),t<=1&&(e=null),n}},d.once=d.partial(d.before,2),d.restArguments=m;function E(t,e){var n=A.length,r=t.constructor,i=d.isFunction(r)&&r.prototype||a,o="constructor";for(x(t,o)&&!d.contains(e,o)&&e.push(o);n--;)(o=A[n])in t&&t[o]!==i[o]&&!d.contains(e,o)&&e.push(o)}var $=!{toString:null}.propertyIsEnumerable("toString"),A=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];d.keys=function(t){if(!d.isObject(t))return[];if(c)return c(t);var e=[];for(var n in t)x(t,n)&&e.push(n);return $&&E(t,e),e},d.allKeys=function(t){if(!d.isObject(t))return[];var e=[];for(var n in t)e.push(n);return $&&E(t,e),e},d.values=function(t){for(var e=d.keys(t),n=e.length,r=Array(n),i=0;i<n;i++)r[i]=t[e[i]];return r},d.mapObject=function(t,e,n){e=v(e,n);for(var r=d.keys(t),i=r.length,o={},a=0;a<i;a++){var s=r[a];o[s]=e(t[s],s,t)}return o},d.pairs=function(t){for(var e=d.keys(t),n=e.length,r=Array(n),i=0;i<n;i++)r[i]=[e[i],t[e[i]]];return r},d.invert=function(t){for(var e={},n=d.keys(t),r=0,i=n.length;r<i;r++)e[t[n[r]]]=n[r];return e},d.functions=d.methods=function(t){var e=[];for(var n in t)d.isFunction(t[n])&&e.push(n);return e.sort()};function z(l,c){return function(t){var e=arguments.length;if(c&&(t=Object(t)),e<2||null==t)return t;for(var n=1;n<e;n++)for(var r=arguments[n],i=l(r),o=i.length,a=0;a<o;a++){var s=i[a];c&&void 0!==t[s]||(t[s]=r[s])}return t}}d.extend=z(d.allKeys),d.extendOwn=d.assign=z(d.keys),d.findKey=function(t,e,n){e=v(e,n);for(var r,i=d.keys(t),o=0,a=i.length;o<a;o++)if(e(t[r=i[o]],r,t))return r};function F(t,e,n){return e in n}var C,N;d.pick=m(function(t,e){var n={},r=e[0];if(null==t)return n;d.isFunction(r)?(1<e.length&&(r=h(r,e[1])),e=d.allKeys(t)):(r=F,e=P(e,!1,!1),t=Object(t));for(var i=0,o=e.length;i<o;i++){var a=e[i],s=t[a];r(s,a,t)&&(n[a]=s)}return n}),d.omit=m(function(t,n){var e,r=n[0];return d.isFunction(r)?(r=d.negate(r),1<n.length&&(e=n[1])):(n=d.map(P(n,!1,!1),String),r=function(t,e){return!d.contains(n,e)}),d.pick(t,r,e)}),d.defaults=z(d.allKeys,!0),d.create=function(t,e){var n=g(t);return e&&d.extendOwn(n,e),n},d.clone=function(t){return d.isObject(t)?d.isArray(t)?t.slice():d.extend({},t):t},d.tap=function(t,e){return e(t),t},d.isMatch=function(t,e){var n=d.keys(e),r=n.length;if(null==t)return!r;for(var i=Object(t),o=0;o<r;o++){var a=n[o];if(e[a]!==i[a]||!(a in i))return!1}return!0},C=function(t,e,n,r){if(t===e)return 0!==t||1/t==1/e;if(null==t||null==e)return!1;if(t!=t)return e!=e;var i=typeof t;return("function"==i||"object"==i||"object"==typeof e)&&N(t,e,n,r)},N=function(t,e,n,r){t instanceof d&&(t=t._wrapped),e instanceof d&&(e=e._wrapped);var i=f.call(t);if(i!==f.call(e))return!1;switch(i){case"[object RegExp]":case"[object String]":return""+t==""+e;case"[object Number]":return+t!=+t?+e!=+e:0==+t?1/+t==1/e:+t==+e;case"[object Date]":case"[object Boolean]":return+t==+e;case"[object Symbol]":return p.valueOf.call(t)===p.valueOf.call(e)}var o="[object Array]"===i;if(!o){if("object"!=typeof t||"object"!=typeof e)return!1;var a=t.constructor,s=e.constructor;if(a!==s&&!(d.isFunction(a)&&a instanceof a&&d.isFunction(s)&&s instanceof s)&&"constructor"in t&&"constructor"in e)return!1}r=r||[];for(var l=(n=n||[]).length;l--;)if(n[l]===t)return r[l]===e;if(n.push(t),r.push(e),o){if((l=t.length)!==e.length)return!1;for(;l--;)if(!C(t[l],e[l],n,r))return!1}else{var c,u=d.keys(t);if(l=u.length,d.keys(e).length!==l)return!1;for(;l--;)if(c=u[l],!x(e,c)||!C(t[c],e[c],n,r))return!1}return n.pop(),r.pop(),!0},d.isEqual=function(t,e){return C(t,e)},d.isEmpty=function(t){return null==t||(k(t)&&(d.isArray(t)||d.isString(t)||d.isArguments(t))?0===t.length:0===d.keys(t).length)},d.isElement=function(t){return!(!t||1!==t.nodeType)},d.isArray=s||function(t){return"[object Array]"===f.call(t)},d.isObject=function(t){var e=typeof t;return"function"==e||"object"==e&&!!t},d.each(["Arguments","Function","String","Number","Date","RegExp","Error","Symbol","Map","WeakMap","Set","WeakSet"],function(e){d["is"+e]=function(t){return f.call(t)==="[object "+e+"]"}}),d.isArguments(arguments)||(d.isArguments=function(t){return x(t,"callee")});var H=t.document&&t.document.childNodes;"object"!=typeof Int8Array&&"function"!=typeof H&&(d.isFunction=function(t){return"function"==typeof t||!1}),d.isFinite=function(t){return!d.isSymbol(t)&&isFinite(t)&&!isNaN(parseFloat(t))},d.isNaN=function(t){return d.isNumber(t)&&isNaN(t)},d.isBoolean=function(t){return!0===t||!1===t||"[object Boolean]"===f.call(t)},d.isNull=function(t){return null===t},d.isUndefined=function(t){return void 0===t},d.has=function(t,e){if(!d.isArray(e))return x(t,e);for(var n=e.length,r=0;r<n;r++){var i=e[r];if(null==t||!o.call(t,i))return!1;t=t[i]}return!!n},d.noConflict=function(){return t._=e,this},d.identity=function(t){return t},d.constant=function(t){return function(){return t}},d.noop=function(){},d.property=function(e){return d.isArray(e)?function(t){return _(t,e)}:b(e)},d.propertyOf=function(e){return null==e?function(){}:function(t){return d.isArray(t)?_(e,t):e[t]}},d.matcher=d.matches=function(e){return e=d.extendOwn({},e),function(t){return d.isMatch(t,e)}},d.times=function(t,e,n){var r=Array(Math.max(0,t));e=h(e,n,1);for(var i=0;i<t;i++)r[i]=e(i);return r},d.random=function(t,e){return null==e&&(e=t,t=0),t+Math.floor(Math.random()*(e-t+1))},d.now=Date.now||function(){return(new Date).getTime()};function L(e){function n(t){return e[t]}var t="(?:"+d.keys(e).join("|")+")",r=RegExp(t),i=RegExp(t,"g");return function(t){return t=null==t?"":""+t,r.test(t)?t.replace(i,n):t}}var B={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},R=d.invert(B);d.escape=L(B),d.unescape=L(R),d.result=function(t,e,n){d.isArray(e)||(e=[e]);var r=e.length;if(!r)return d.isFunction(n)?n.call(t):n;for(var i=0;i<r;i++){var o=null==t?void 0:t[e[i]];void 0===o&&(o=n,i=r),t=d.isFunction(o)?o.call(t):o}return t};var U=0;d.uniqueId=function(t){var e=++U+"";return t?t+e:e},d.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};function W(t){return"\\"+Y[t]}var q=/(.)^/,Y={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},G=/\\|'|\r|\n|\u2028|\u2029/g;d.template=function(o,t,e){!t&&e&&(t=e),t=d.defaults({},t,d.templateSettings);var n,r=RegExp([(t.escape||q).source,(t.interpolate||q).source,(t.evaluate||q).source].join("|")+"|$","g"),a=0,s="__p+='";o.replace(r,function(t,e,n,r,i){return s+=o.slice(a,i).replace(G,W),a=i+t.length,e?s+="'+\n((__t=("+e+"))==null?'':_.escape(__t))+\n'":n?s+="'+\n((__t=("+n+"))==null?'':__t)+\n'":r&&(s+="';\n"+r+"\n__p+='"),t}),s+="';\n",t.variable||(s="with(obj||{}){\n"+s+"}\n"),s="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+s+"return __p;\n";try{n=new Function(t.variable||"obj","_",s)}catch(t){throw t.source=s,t}function i(t){return n.call(this,t,d)}var l=t.variable||"obj";return i.source="function("+l+"){\n"+s+"}",i},d.chain=function(t){var e=d(t);return e._chain=!0,e};function K(t,e){return t._chain?d(e).chain():e}d.mixin=function(n){return d.each(d.functions(n),function(t){var e=d[t]=n[t];d.prototype[t]=function(){var t=[this._wrapped];return i.apply(t,arguments),K(this,e.apply(d,t))}}),d},d.mixin(d),d.each(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var n=r[e];d.prototype[e]=function(){var t=this._wrapped;return n.apply(t,arguments),"shift"!==e&&"splice"!==e||0!==t.length||delete t[0],K(this,t)}}),d.each(["concat","join","slice"],function(t){var e=r[t];d.prototype[t]=function(){return K(this,e.apply(this._wrapped,arguments))}}),d.prototype.value=function(){return this._wrapped},d.prototype.valueOf=d.prototype.toJSON=d.prototype.value,d.prototype.toString=function(){return String(this._wrapped)},void 0===(J=function(){return d}.apply(Q,[]))||(Z.exports=J)}()}).call(this,e(32),e(33)(t))},function(t){"use strict";function l(t,e){var n=parseInt(t.substring(6,10)),r=parseInt(t.substring(0,3)),i=parseInt(t.substring(3,5)),o=parseInt(e.substring(0,2)),a=parseInt(e.substring(3,5)),s=parseInt(e.substring(6,8));return new Date(n,r,i,o,a,s)}function c(){$("#Plot").prop("disabled",!0)}function a(t,e,n,r){if("--"==(i=$("#interval option:selected")).text());else{var i,o=l(t,n),a=(l(e,r)-o)/1e3,s=(i=$("#interval option:selected")).data("seconds");a=Math.floor(a/s);0<=a&&a<60?($("#prompt_user").html("a "+i.text()+" interval would plot about "+a.toString()+" data points; that's too few - please try again"),$("#default").attr("selected","selected"),c()):a<0?($("#prompt_user").html("The end date is before the start date. Please choose a later end date."),$("#default").attr("selected","selected")):1e3<a?($("#prompt_user").html("a "+i.text()+" interval would plot about "+a.toString()+" data points; that's too many - please try again"),$("#default").attr("selected","selected"),c()):($("#prompt_user").html("a "+i.text()+" interval would plot about "+a.toString()+" data points."),$("#Plot").prop("disabled",!1))}}t.exports.loading=function(){},t.exports.disable=function(){$("#Start-date-picker").prop("disabled",!0),$("#Start-time-picker").prop("disabled",!0),$("#End-date-picker").prop("disabled",!0),$("#End-time-picker").prop("disabled",!0),$("#interval").prop("disabled",!0),$("#Plot").prop("disabled",!0)},t.exports.enable=function(){$("#Start-date-picker").prop("disabled",!1),$("#Start-time-picker").prop("disabled",!1),$("#End-date-picker").prop("disabled",!1),$("#End-time-picker").prop("disabled",!1),$("#interval").prop("disabled",!1)},t.exports.checkInterval=function(){var t=$("#Start-date-picker").val(),e=$("#End-date-picker").val(),n=$("#Start-time-picker").val(),r=$("#End-time-picker").val(),i=$("#interval"),o=$("#interval option:selected");t&&e&&n&&r||"--"==o.text()||($("#prompt_user").html("Please fill out all other fields before filling out the interval field"),$("#default").attr("selected","selected")),a(t,e,n,r,i)}},function(t,e,n){"use strict";var r=n(19)();t.exports=function(t){return t!==r&&null!==t}},function(t){t.exports=Plotly},function(t,e,n){"use strict";var i=n(0);function p(t){return 1.8*t+32}function r(t){return t}String.prototype.format||(String.prototype.format=function(){var n=arguments;return this.replace(/{(\d+)}/g,function(t,e){return void 0!==n[e]?n[e]:t})});var o={null:r,undefined:r,getF:p,getPresInHg:function(t){return.02952998751*t},getSpeedMPH:function(t){return 3600*t/1608},getAccumMillimeter:function(t){return 25.4*t},cardinalWDir:function(t){return["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"][Math.floor((t+11.25)%360/22.5)]},getSpeedKTS:function(t){return 1.94384*t}};function c(t,e,n){var r;return null===t?r=t="":(r="yaxis2"in e&&"convert_value"in e.yaxis2?(r=o[e.yaxis2.convert_value](t)).toFixed?r.toFixed(e.yaxis2.precision):r:void 0,t=(t=o[e.yaxis.convert_value](t)).toFixed?t.toFixed(e.yaxis.precision):t),"yaxis2"in e&&void 0!==r?"{0}: {1}{2} ({3}{4})".format(n.name,t,e.yaxis.units,r,e.yaxis2.units):"{0}: {1}{2}".format(n.name,t,e.yaxis.units)}function a(t,e,n,r){for(var i=[],o=0;o<t.length;o++)i.push(c(t[o],e,n));return i}var s={undefined:a,null:a,dewpoint:function(t,e,n,r){var i,o=[],a=void 0;"anc_variables"in n&&1==n.anc_variables.length&&(a=r[n.anc_variables[0]]);var s=n.anc_info[n.anc_variables[0]];s||(s={name:n.anc_variables[0],units:"",precision:2});for(var l=0;l<t.length;l++)i=c(t[l],e,n),void 0!==a&&(i+="<br>{0}: {1}{2}".format(s.name,a[l]?a[l].toFixed(s.precision):"",s.units)),o.push(i);return o},water_temp:function(t,e,n){for(var r,i,o,a,s,l=[],c=0;c<t.length;c++){i=t[c],a=[],s=n.y[c];for(var u=0;u<i.length;u++)o=i[u],r="Depth: {0}m<br>{1}: {2} °C ({3} °F)".format(s.toFixed(1),n.name,null!==o?o.toFixed(3):"N/A",null!==o?p(o).toFixed(3):"N/A"),a.push(r);l.push(a)}return l}};t.exports.getTickVals=function(t,e){var n=.02*(e-t),r=((e+=n)-(t-=n))/4;return i.range(t,e+r,r)},t.exports.getProbeText=function(t,e,n,r){return"probe_text"in n?s[n.probe_text](t,e,n,r):a(t,e,n)},t.exports.getTickText=function(t,e){for(var n=[],r=0;r<t.length;r++){var i=o[e.convert_value](t[r]);i=i.toFixed?i.toFixed(e.precision):i,n.push(i)}return n}},function(t){"use strict";t.exports.buildRequestUrl=function(t,e,n,r,i,o,a){var s=METOBS_API_URL+"/api/data."+t+"?";return s+="interval="+e,s+="&epoch="+n,s+="&sep="+r||!1,s+="&order="+i,s+=o,s+="&symbols="+a}},function(t,e,n){"use strict";function _(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e<t.length;e++)n[e]=t[e];return n}return Array.from(t)}var k=n(3),w=n(4),j=n(0);function v(t,e,n){var r=(t=new Date(t)).toLocaleString(void 0,{hour:"numeric",minute:"numeric",second:"numeric",hour12:n}),i=t.getMonth()+1;i=i<10?"0"+i:i;var o={day_name:(t=t.toString().split(" "))[0],month_name:t[1],month:i,day:t[2],year:t[3],time:r};return e.replace(/\{([^}]*)\}/g,function(t,e){return o[e]||t})}function T(t,e,n,r){var i,o,a,s,l,c,u,p=0==r?"yaxis":"yaxis2",f={};!function(t,e,n){var r=t[0].x[t[0].x.length-1],i=Number(v(r+" UTC","{time}",!1).split(":")[0]);document.getElementById("overlay").style.opacity=0<i&&i<5?1:0;var o=v(r+" UTC","{day_name}, {month_name} {day}, {year} {time}",!0),a=v(r,"{year}-{month}-{day} {time}Z",!1),s=0==e?"327.5 meters":"1074.5 feet";n["annotations.1.text"]="Data last recorded at: "+a+" ["+o+" Local]          RIG Elevation = "+s}(t,r,f);for(var d=0;d<t.length;d++)if(l=0==d?"":d+1,s=t[d].x,f["xaxis"+l+".tickvals"]=[s[0],s[Math.round(s.length/2)],s[s.length-1]],i=t[d].plot_name,o=n.plots[i],a=w.getTickText([t[d].y[t[d].y.length-1]],o[p])[0],f["annotations["+(3+2*d)+"].text"]=a+""+o[p].units,null!=(u=e.layout["yaxis"+l].tickvals)){if("wind_direction"==i||"rel_hum"==i)c=o[p].ticktext;else{c=[];for(var h=0;h<u.length;h++)c.push(w.getTickText([u[h]],o[p]))}f["yaxis"+l+".ticktext"]=c}k.relayout(e,f),function(){var t={north:"east",east:"south",south:"west",west:"north"}[document.getElementById("roofCam").src.split("/")[7]];document.getElementById("roofCam").alt=document.getElementById("dirText").innerHTML=t,document.getElementById("roofCam").src="http://metobs.ssec.wisc.edu/pub/cache/aoss/cameras/"+t+"/latest_orig.jpg?t="+(new Date).getTime()}()}function M(t,e,n,r,i,o){if("aoss.tower.rel_hum"!=n&&"aoss.tower.wind_direction"!=n){0==t.y.length?(t.yMin=Math.min.apply(Math,_(e)),t.yMax=Math.max.apply(Math,_(e))):(t.yMin=Math.min.apply(Math,_(e).concat([t.yMin])),t.yMax=Math.max.apply(Math,_(e).concat([t.yMax])));var a=t.yMax-t.yMin,s=t.yMin-a,l="aoss.tower.solar_flux"==n?t.yMax:t.yMax+a;0==a&&(0<l?(l*=1.1,s*=.9):l<0?(l*=.9,s*=1.1):s=-(l=.1));var c=s;"aoss.tower.air_temp"!=n&&"aoss.tower.dewpoint"!=n&&s<=0&&(c=s=0),s-=.075*a+.001,r[i+".tickvals"]=[c,c+(l-c)/4,c+2*(l-c)/4,c+3*(l-c)/4,l],r[i+".range"]=[s,l]}else r[i+".tickvals"]=o}t.exports.updatePlot=function(t,e,n,r,i,o){!function(o,t,a,s,e,n){var r,l,c,u,p,f,d=s.dates,i=[],h=!1,v=[],y={x:[],y:[],text:[]},m=[],g={x:[],z:[],text:[]},b=0,x={};for(c=0;c<o.length;c++)r=o[c].plot_name,i[i.length-1]!=r&&(l=a.plots[r],j.each(l.traces,function(e,t){if("contour"==o[b+t].type){var n;g.x.push(d),m.push(b+t),p=j.map(e.var_names,function(t){return s[t]}),(n=o[c].text).push.apply(n,_(w.getProbeText(p,l,e,s)));for(var r=0;r<e.var_names.length;r++){for(var i;r>=o[c].z.length;)o[c].z.push([]);(i=o[c].z[r]).push.apply(i,_(s[e.var_names[r]]))}g.z.push(o[c].z),g.text.push(o[c].text)}else y.x.push(d),v.push(b+t),j.each(e.var_names,function(t){a.isLobbyDisplay&&(f=0==c?"":c+1,M(o[c],s[t],t,x,"yaxis"+f,l.yaxis2.tickvals)),y.y.push(s[t]),u="probe_text"in e&&null===e.probe_text?[void 0]:w.getProbeText(s[t],l,e,s),y.text.push(u)})}),b+=l.traces.length,i.push(r));if(0<v.length&&k.extendTraces(t,y,v),0<m.length)for(k.extendTraces(t,g,m),c=0;c<m.length;c++)o[m[c]].z.splice(0,o[m[c]].y.length),o[m[c]].text.splice(0,o[m[c]].y.length);0!=n||e||(n=s.dates.length,h=!0),0<n&&o[0].x.length>n&&function(t,e){for(var n=0;n<t.length;n++){if(t[n].x.splice(0,e),t[n].hasOwnProperty("z"))for(var r=0;r<t[n].z.length;r++)t[n].z[r].splice(0,e);else t[n].hasOwnProperty("y")&&t[n].y.splice(0,e);t[n].hasOwnProperty("text")&&t[n].text.splice(0,e)}}(o,o[0].x.length-n),0!=Object.keys(x).length&&(k.relayout(t,x),e||T(o,t,a,0)),h&&k.redraw(t)}(t,e,n,r,i,o)},t.exports.changeUnits=T},function(t,e,n){"use strict";var i=n(8),o=n(10);n(0);window.MeteorogramController=function(t,e,n){var r=o.getDispatcher();return{plotDiv:t,controlDiv:e,dataCache:[],initMeteorogram:function(t,e){this.hasGraph=!0,this.plotDiv=t||this.plotDiv,r.dispatch({status:"initPlot",emit:"plotEmitter",location:this.plotDiv,dataCache:this.dataCache,plotsInfo:n,plotOrder:e})},initMeteorogramTable:function(t,e){this.hasTable=!0,this.tableDiv=t||this.plotDiv,r.dispatch({status:"initTable",emit:"plotEmitter",location:this.tableDiv,plotsInfo:n,plotOrder:e})},initMeteorogramControls:function(){i(this.controlDiv,this.plotDiv,r)},displayRealTime:function(){this.hasTable&&r.dispatch({status:"update_table",emit:"plotEmitter",time:"-3:00:00",location:this.tableDiv}),this.hasGraph&&r.dispatch({status:"get_since_now",emit:"plotEmitter",time:"-3:00:00",location:this.plotDiv})},showPlot:function(t){r.dispatch({status:"show"+t,emit:"checkboxEmitter",location:this.div})},hidePlot:function(t){r.dispatch({status:"hide"+t,emit:"checkboxEmitter",location:this.div})},displayRecent:function(t){r.dispatch({status:"get_since_now",emit:"plotEmitter",time:t})},displayTimeRange:function(t,e,n){r.dispatch({status:"get_between_dates",emit:"plotEmitter",start:t,end:e,interval:n||"auto"})}}}},function(t,e,n){"use strict";n(1);var r=n(9);function i(t,e){$(t+" #plot-btn").click(function(){!function(t){t.dispatch({status:"get_between_dates",emit:"plotEmitter",start:$("#Start-date-picker").val().split(" ").join("T")+":00",end:$("#End-date-picker").val().split(" ").join("T")+":00",interval:"auto"})}(e)}),$(t+" #dropDownId").change(function(){!function(t,e){if("realtime"==t)e.dispatch({status:"get_since_now",emit:"plotEmitter",time:"-3:00:00"});else{e.dispatch({status:"get_since_now",emit:"plotEmitter",time:t})}}($(this).val(),e)})}function o(t,e){$(e+" #dropDownId").prop("disabled","recent"!=t),$(e+" #interval").prop("disabled","range"!=t),$(e+" #Start-date-picker").prop("disabled","range"!=t),$(e+" #End-date-picker").prop("disabled","range"!=t),$(e+" #Start-time-picker").prop("disabled","range"!=t),$(e+" #End-time-picker").prop("disabled","range"!=t),$(e+" #plot-btn").prop("disabled","range"!=t)}function a(t,e,n){var r="#"+t;!function(t){$(t+" #Start-date-picker").datetimepicker({changeMonth:!0,changeYear:!0,dateFormat:"yy-mm-dd",timeFormat:"HH:mm",showSecond:!1,showMillisec:!1,showMicrosec:!1}),$(t+" #End-date-picker").datetimepicker({changeMonth:!0,changeYear:!0,dateFormat:"yy-mm-dd",timeFormat:"HH:mm",showSecond:!1,showMillisec:!1,showMicrosec:!1}),$(t+" [type=text]").prop("disabled",!0),$(t+" select").prop("disabled",!0),$(t+" #last_x_days").click(function(){o("recent",t)}),$(t+" #date_range").click(function(){o("range",t)}),$(t+" #last_x_days").trigger("click")}(r),i(r,n)}$(document).ready(function(){}),t.exports=function(t,e,n){$("#"+t).append(r.controlPanelTemplate),a(t,0,n)}},function(t){"use strict";t.exports={controlPanelTemplate:'<div class="row" id="control-panel-row"><div id="show-hide-boxes" class="col-md-12"></div><div class = "col-md-9"><div class="row" style="padding: 0 1em;"><div class="form-group"><table style="width:100%"><tr><td><div class="radio"><label><input type="radio" id="last_x_days" name="time_select">Recent Data:</label></div></td><td><select class="form-control" id="dropDownId"><option selected value="realtime">Realtime Update</option><option value="-1:00:00">Past 1 Hour</option><option value="-2:00:00">Past 2 Hours</option><option value="-3:00:00">Past 3 Hours</option><option value="-6:00:00">Past 6 Hours</option><option value="-12:00:00">Past 12 Hours</option><option value="-18:00:00">Past 18 Hours</option><option value="-24:00:00">Past 24 Hours</option><option value="-96:00:00">Past 4 Days</option></select></td><td style="padding-left:.5em"><div class="radio"><label><input type="radio" id="date_range" name="time_select">Date Range:</label></div></td><td><input class="form-control" style="padding 0.5em 0;" id="Start-date-picker" type="text" placeholder="YYYY-MM-DD"/></td><td>to </td><td><input class="form-control" style="padding 0.5em 0;" id="End-date-picker" type="text" placeholder="YYYY-MM-DD"/></td><td><button class="btn btn-primary btn-block" id="plot-btn">Plot</button></td></tr></table></div></div></div></div>',checkboxTemplates:{"aoss.tower":'<div class="form-group"><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="temp">Temperature + Dewpoint</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="pres">Pressure</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="wS">Wind Speed</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="wD">Wind Direction</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="aP">Precipitation</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="sF">Solar Flux</label></div>',"mendota.buoy":'<div class="form-group"><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="temp">Temperature + Dewpoint</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="rh">Relative Humidity</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="wS">Wind Speed</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="wD">Wind Direction</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="chlor">Chlorophyll</label><label class="form-check-label"><input type="checkbox" class="form-check-input" checked id="phyco">Phycocyanin</label></div>'}}},function(t,e,n){"use strict";var u,r=n(11),p=n(27),f=n(30),d=n(31),h=n(34),v=n(1),y=n(6);t.exports.getDispatcher=function(){var i=new p.Dispatcher;function o(){360<(u+=.2*(2*Math.min(120-u%120,u%120)/60+1))&&(u=0),document.getElementById("row1").style.backgroundColor="hsl("+u+",100%,15%)",document.getElementById("row2").style.backgroundColor="hsl("+u+",75%,30%)",document.getElementById("row3").style.backgroundColor="hsl("+u+",50%,45%)"}i.GRAPH_HEIGHT=170;var a=r({visible:{},setPlots:function(t){for(var e in t)this.visible[e]=!0},setShowing:function(t,e){this.showing[t]=void 0===e?!this.showing[t]:e},getShowing:function(t){return this.showing[t]},handleActions:function(t){"checkboxEmitter"==t.emit&&this.emit(t.status,t.location)}});a.dispatchToken=i.register(a.handleActions.bind(a));var t=r({handleActions:function(t){"plotEmitter"==t.emit&&(i.waitFor([a.dispatchToken]),void 0!==t.location&&(this.div=t.location),void 0!==t.plotsInfo&&(this.plotsInfo=t.plotsInfo,this.plotOrder=this.plotsInfo.defaultPlots),void 0!==t.plotOrder&&(this.plotOrder=t.plotOrder),void 0!==t.dataCache&&(this.dataCache=t.dataCache),"get_since_now"==t.status?(this.plotsInfo.isLobbyDisplay&&(t.time="-6:00:00"),this.emit(t.status,t.time,this.plotsInfo,this.dataCache,this.div)):"update_table"==t.status?this.emit(t.status,t.time,this.plotsInfo,this.div):"get_between_dates"==t.status?this.emit(t.status,t.start,t.end,t.interval,this.plotsInfo,this.dataCache,this.div):"initPlot"==t.status?this.emit(t.status,t.location,t.plotOrder?t.plotOrder:this.plotOrder,this.plotsInfo,this.dataCache):"initTable"==t.status?this.emit(t.status,t.location,t.plotOrder?t.plotOrder:this.plotOrder,this.plotsInfo):"update"==t.status?this.emit(t.status,this.div,this.plotsInfo,this.dataCache,t.startTime):"changeUnits"==t.status?this.emit(t.status,this.div,this.plotsInfo,this.dataCache,t.unitCount):this.emit(t.status,t.userInfo))}});function s(t){if(t.progress||(t.progress={}),t.progress.validID){var e=t.progress.id[0];clearInterval(e),t.isLobbyDisplay&&(clearInterval(t.progress.colorID),clearInterval(t.progress.lobbyID)),t.progress.validID=!1}}var l={"1m":3e4,"5m":15e4,"1h":18e5};function c(t,e,n){n.progress||(n.progress={}),s(n),void 0===t&&(t=n.progress.id[1]),void 0===e&&(e=n.progress.id[2]);var r=setInterval(function(t){return function(){i.dispatch({status:"update",emit:"plotEmitter",startTime:t})}}(t),l[e]);n.isLobbyDisplay&&(u=Number(getComputedStyle(document.getElementById("color")).getPropertyValue("--starting-hue")),n.progress.colorID=setInterval(o,1e3),n.progress.lobbyID=setInterval(function(t){return function(){t=(t+1)%2,i.dispatch({status:"changeUnits",emit:"plotEmitter",unitCount:t})}}(0),5e3)),n.progress.id=[r,t,e],n.progress.validID=!0}return t.on("initTable",function(t,e,n){a.setPlots(n),d.initTable(t,e,n)}),t.on("update_table",function(t,e,n){d.requestTableUpdate(n,e),setInterval(function(){d.requestTableUpdate(n,e)},l["1m"])}),t.on("initPlot",function(t,e,n,r){a.setPlots(n),f.initPlot(r,t,e,n)}),t.on("get_since_now",function(t,e,n,r){c(t,h.requestPlotUpdate(n,r,e,t,void 0,void 0,void 0,s),e)}),t.on("get_between_dates",function(t,e,n,r,i,o){s(r),h.requestPlotUpdate(i,o,r,t,e,n)}),t.on("update",function(t,e,n,r){h.requestPlotUpdate(n,t,e,r,void 0,void 0,!0)}),t.on("changeUnits",function(t,e,n,r){y.changeUnits(n,document.getElementById(t),e,r)}),t.on("checking_custom",function(){v.checkInterval()}),t.dispatchToken=i.register(t.handleActions.bind(t)),i}},function(t,e,n){"use strict";var i,r,o,a,s,l,c,u=n(12),p=n(26),f=Function.prototype.apply,d=Function.prototype.call,h=Object.create,v=Object.defineProperty,y=Object.defineProperties,m=Object.prototype.hasOwnProperty,g={configurable:!0,enumerable:!1,writable:!0};r=function(t,e){var n,r;return p(e),i.call(r=this,t,n=function(){o.call(r,t,n),f.call(e,this,arguments)}),n.__eeOnceListener__=e,this},s={on:i=function(t,e){var n;return p(e),m.call(this,"__ee__")?n=this.__ee__:(n=g.value=h(null),v(this,"__ee__",g),g.value=null),n[t]?"object"==typeof n[t]?n[t].push(e):n[t]=[n[t],e]:n[t]=e,this},once:r,off:o=function(t,e){var n,r,i,o;if(p(e),!m.call(this,"__ee__"))return this;if(!(n=this.__ee__)[t])return this;if("object"==typeof(r=n[t]))for(o=0;i=r[o];++o)i!==e&&i.__eeOnceListener__!==e||(2===r.length?n[t]=r[o?0:1]:r.splice(o,1));else r!==e&&r.__eeOnceListener__!==e||delete n[t];return this},emit:a=function(t,e,n){var r,i,o,a,s;if(m.call(this,"__ee__")&&(a=this.__ee__[t]))if("object"==typeof a){for(i=arguments.length,s=new Array(i-1),r=1;r<i;++r)s[r-1]=arguments[r];for(a=a.slice(),r=0;o=a[r];++r)f.call(o,this,s)}else switch(arguments.length){case 1:d.call(a,this);break;case 2:d.call(a,this,e);break;case 3:d.call(a,this,e,n);break;default:for(i=arguments.length,s=new Array(i-1),r=1;r<i;++r)s[r-1]=arguments[r];f.call(a,this,s)}}},l={on:u(i),once:u(r),off:u(o),emit:u(a)},c=y({},l),t.exports=e=function(t){return null==t?h(c):y(Object(t),l)},e.methods=s},function(t,e,n){"use strict";var l=n(13),c=n(21),u=n(22),p=n(23);(t.exports=function(t,e,n){var r,i,o,a,s;return arguments.length<2||"string"!=typeof t?(a=e,e=t,t=null):a=n,null==t?(r=o=!0,i=!1):(r=p.call(t,"c"),i=p.call(t,"e"),o=p.call(t,"w")),s={value:e,configurable:r,enumerable:i,writable:o},a?l(c(a),s):s}).gs=function(t,e,n,r){var i,o,a,s;return"string"!=typeof t?(a=n,n=e,e=t,t=null):a=r,null==e?e=void 0:u(e)?null==n?n=void 0:u(n)||(a=n,n=void 0):(a=e,e=n=void 0),o=null==t?!(i=!0):(i=p.call(t,"c"),p.call(t,"e")),s={get:e,set:n,configurable:i,enumerable:o},a?l(c(a),s):s}},function(t,e,n){"use strict";t.exports=n(14)()?Object.assign:n(15)},function(t){"use strict";t.exports=function(){var t,e=Object.assign;return"function"==typeof e&&(e(t={foo:"raz"},{bar:"dwa"},{trzy:"trzy"}),t.foo+t.bar+t.trzy==="razdwatrzy")}},function(t,e,n){"use strict";var a=n(16),s=n(20),l=Math.max;t.exports=function(e,n){var r,t,i,o=l(arguments.length,2);for(e=Object(s(e)),i=function(t){try{e[t]=n[t]}catch(t){r||(r=t)}},t=1;t<o;++t)a(n=arguments[t]).forEach(i);if(void 0!==r)throw r;return e}},function(t,e,n){"use strict";t.exports=n(17)()?Object.keys:n(18)},function(t){"use strict";t.exports=function(){try{return Object.keys("primitive"),!0}catch(t){return!1}}},function(t,e,n){"use strict";var r=n(2),i=Object.keys;t.exports=function(t){return i(r(t)?Object(t):t)}},function(t){"use strict";t.exports=function(){}},function(t,e,n){"use strict";var r=n(2);t.exports=function(t){if(!r(t))throw new TypeError("Cannot use null or undefined");return t}},function(t,e,n){"use strict";var r=n(2),i=Array.prototype.forEach,o=Object.create;t.exports=function(){var e=o(null);return i.call(arguments,function(t){r(t)&&function(t,e){var n;for(n in t)e[n]=t[n]}(Object(t),e)}),e}},function(t){"use strict";t.exports=function(t){return"function"==typeof t}},function(t,e,n){"use strict";t.exports=n(24)()?String.prototype.contains:n(25)},function(t){"use strict";var e="razdwatrzy";t.exports=function(){return"function"==typeof e.contains&&(!0===e.contains("dwa")&&!1===e.contains("foo"))}},function(t){"use strict";var n=String.prototype.indexOf;t.exports=function(t,e){return-1<n.call(this,t,e)}},function(t){"use strict";t.exports=function(t){if("function"!=typeof t)throw new TypeError(t+" is not a function");return t}},function(t,e,n){t.exports.Dispatcher=n(28)},function(t,e,n){"use strict";e.__esModule=!0;var r=n(29),i=(o.prototype.register=function(t){var e="ID_"+this._lastID++;return this._callbacks[e]=t,e},o.prototype.unregister=function(t){this._callbacks[t]||r(!1),delete this._callbacks[t]},o.prototype.waitFor=function(t){this._isDispatching||r(!1);for(var e=0;e<t.length;e++){var n=t[e];this._isPending[n]?this._isHandled[n]||r(!1):(this._callbacks[n]||r(!1),this._invokeCallback(n))}},o.prototype.dispatch=function(t){this._isDispatching&&r(!1),this._startDispatching(t);try{for(var e in this._callbacks)this._isPending[e]||this._invokeCallback(e)}finally{this._stopDispatching()}},o.prototype.isDispatching=function(){return this._isDispatching},o.prototype._invokeCallback=function(t){this._isPending[t]=!0,this._callbacks[t](this._pendingPayload),this._isHandled[t]=!0},o.prototype._startDispatching=function(t){for(var e in this._callbacks)this._isPending[e]=!1,this._isHandled[e]=!1;this._pendingPayload=t,this._isDispatching=!0},o.prototype._stopDispatching=function(){delete this._pendingPayload,this._isDispatching=!1},o);function o(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,o),this._callbacks={},this._isDispatching=!1,this._isHandled={},this._isPending={},this._lastID=1}t.exports=i},function(t){"use strict";t.exports=function(t,e,n,r,i,o,a,s){if(!t){var l;if(void 0===e)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,i,o,a,s],u=0;(l=new Error(e.replace(/%s/g,function(){return c[u++]}))).name="Invariant Violation"}throw l.framesToPop=1,l}}},function(t,e,n){"use strict";function E(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var $=n(3),A=n(1);function z(t,e,n,r){for(var i,o={gridcolor:"#777777",titlefont:{size:12},title:n.title,zeroline:!1,overlaying:"y"+(t-1).toString(),side:"right",anchor:"x"},a=0;a<r.length;a++)(i=r[a])in n&&(o[i]=n[i]);return o}t.exports.initPlot=function(t,e,n,r){var i=n.length,o={title:r.title,showlegend:!1,height:170*i+180};Object.assign(o,r.layout),o.xaxis={domain:[0,1],showline:!1,zeroline:!1,showticklabels:0<i,gridcolor:"#777777",showgrid:!1,tickformat:"%Y-%m-%d %H:%MZ"};for(var a,s,l,c,u,p,f,d,h,v,y,m,g,b,x,_,k,w=0,j=1/i,T=w,M=["marker","color","mode","zmin","zmax","y","contours","line","colorscale","showscale","colorbar","tick0","dtick","hovermode"],O=["nticks","range","autorange","zeroline","showgrid","tickmode","ticktext","tickvals"],P=0;P<n.length;P++){p=n[P],T=w+=1,a=(s=r.plots[p]).yaxis,d=[(n.length-1-P)*j*1.03,1-P*j*1.05],r.isLobbyDisplay&&(d=[.82-8/75-(.2+8/75)*Math.floor(P/3),.82-(.2+8/75)*Math.floor(P/3)]);for(var S=0;S<s.traces.length;S++){c={name:(l=s.traces[S]).name,x:[],y:[],text:[],type:l.type?l.type:"scatter",xaxis:r.isLobbyDisplay?"x"+w:"x1",yaxis:"y"+w,hoverinfo:"x+text",hovermode:"closest",var_names:l.var_names,anc_variables:l.anc_variables,anc_data:[],plot_name:p,trace_index:S},l.isSecondAxis&&(c.yaxis="y"+(w+S));for(var D=0;D<M.length;D++)(f=M[D])in l&&(c[f]=l[f]);"colorbar"in c&&(c.colorbar.len=d[1]-d[0],c.colorbar.y=(d[1]-d[0])/2+d[0],c.z=[]),t.push(c)}for(u={gridcolor:"#777777",titlefont:{size:12},title:a.title,zeroline:!1,domain:d},r.isLobbyDisplay&&(h=o,v=u,y=w,m=P,g=d[1],b=l.name,x=r.rowTextSize,k=_=void 0,h["xaxis"+y]={ticktext:["-6h","-3h","Now"],tickfont:{size:x/5},showline:!0,linecolor:"white",anchor:"y"+y,domain:[.1+1/3*(m%3)*(1+Math.floor(m/6)),14/60+1/3*(m%3)*(1+Math.floor(m/6))],zeroline:!1,showgrid:!1},h.annotations.push((E(_={font:{size:x/2},showarrow:!1,align:"center",x:1/6+1/3*(m%3)*(1+Math.floor(m/6)),y:g+.04,xref:"paper",yref:"paper"},"showarrow",!0),E(_,"arrowhead",0),E(_,"ax",0),E(_,"ay",0),_)),h.annotations.push((E(k={text:b,font:{size:x/4},showarrow:!1,align:"center",x:1/6+1/3*(m%3)*(1+Math.floor(m/6)),y:g+.085,xref:"paper",yref:"paper"},"showarrow",!0),E(k,"arrowhead",0),E(k,"ax",0),E(k,"ay",0),k)),delete v.title,v.tickfont={size:x/5},v.showgrid=!1,v.showticklabels=!0,v.anchor="x"+y,v.showline=!0,v.linecolor="white"),D=0;D<O.length;D++)(f=O[D])in a&&(u[f]=a[f]);o["yaxis"+w]=u,!r.isLobbyDisplay&&"yaxis2"in s&&!s.yaxis2.skip&&(u=z(w+=1,0,a=s.yaxis2,O),o["yaxis"+w]=u)}o.xaxis.anchor="y"+T;var I={showLink:!1,displaylogo:!1,displayModeBar:!0,responsive:!0};r.isLobbyDisplay&&(delete o.xaxis,I={responsive:!0}),$.plot(e,t,o,I),A.loading()}},function(t,e,n){"use strict";var x=n(4),c=n(5);function h(t,e,n,r){for(var i=0;i<r.anc_variables.length;i++){var o=r.anc_info[r.anc_variables[i]],a=$("<td>N/A</td>");a.addClass("met_data"),a.data("info",{key:e,idx:n,anc_idx:i});var s=$("<tr></tr>"),l=o.short_name||o.name;s.append("<td>"+l+"</td>"),s.append(a),s.append('<td class="convert"></td>'),t.append(s)}}function v(t,e,n,r,i){var o='<tr><td colspan="2">'+(c=r.short_name||r.name)+"</td><td></td>";t.append(o);for(var a=0;a<r.y_highlight.length;a++){var s=r.y_highlight[a],l=$("<tr></tr>"),c=r.y[s]+i.yaxis.units;l.append('<td class="subtitle text-center">'+c+"</td>");var u=$("<td>N/A</td>");u.addClass("met_data"),u.data("info",{key:e,idx:n,hl_idx:s}),l.append(u),l.append('<td class="convert"></td>'),t.append(l)}}function _(t,e,n,r,i){for(var o=0;o<r.y_highlight.length;o++){var a=r.y_highlight[o],s=t[r.var_names[a]][0],l=r.zprobe.units,c=x.getTickText([s],r.zprobe),u="";if(r.zprobe2&&r.zprobe2.convert_value){var p=r.zprobe2.units;u=x.getTickText([s],r.zprobe2)+p}e[i].innerHTML=c+l,n[i].innerHTML=u,i+=1}return i}function k(t,e,n,r){for(var i=0;i<n.anc_variables.length;i++){var o=n.anc_variables[i],a=n.anc_info[o],s=t[o][0],l=x.getTickText([s],a);e[r].innerHTML=s||0==s?l+a.units:"N/A",r+=1}return r}t.exports.initTable=function(t,e,n){for(var r,i,o=$("#"+t),a=$('<table class="met_table"><tbody></tbody></table>'),s=a.children("tbody"),l=0;l<e.length;l++){i=e[l],r=n.plots[i];for(var c=0;c<r.traces.length;c++){var u=r.traces[c];if("contour"==u.type)v(s,i,c,u,r);else{var p=$("<td>N/A</td>");p.addClass("met_data"),p.data("info",{key:i,idx:c});var f=$("<tr></tr>"),d=u.short_name||u.name;if("Wind Direction Card"==d)continue;f.append("<td>"+d+"</td>"),f.append(p),f.append('<td class="convert"></td>'),s.append(f),u.anc_variables&&h(s,i,c,u)}}}o.append("<h3>"+n.title+"</h3>"),o.append(a),o.append('<span id="timestamp"></span>')},t.exports.requestTableUpdate=function(e,o){$("#"+e);var a,s=[],l=[],n=$("#"+e+" .met_data"),r=$("#"+e+" .convert");n.each(function(){var t=$(this).data("info").key,e=$(this).data("info").idx,n=$(this).data("info").anc_idx,r=$(this).data("info").hl_idx,i=o.plots[t].traces[e];-1==l.indexOf(t)&&l.push(t),a=void 0!==n?i.anc_variables[0]:void 0!==r?i.var_names[r]:i.var_names[0],s.includes(a)||s.push(a)});var t=s.join(":"),i=c.buildRequestUrl("json","1m","","","column","&begin=-00:04:00",t);$.ajax({type:"GET",url:i,jsonp:"callback",dataType:"jsonp",success:function(t){t.div_id=e,t.plotOrder=l,t.data_cells=n,t.convert_cells=r,function(t,e){var n,r,i=t.results.data,o=0,a=t.div_id,s=t.plotOrder,l=t.data_cells,c=t.convert_cells;if(0==t.num_results)return $("#"+a+" #timestamp").html("No recent data");$("#"+a+" #timestamp").html("Last updated: "+t.results.timestamps[0]);for(var u=0;u<s.length;u++){r=s[u],n=e.plots[r];for(var p=0;p<n.traces.length;p++){var f=n.traces[p];if("Wind Direction Card"!=f.name)if("contour"==f.type)o=_(i,l,c,f,o);else{var d=i[f.var_names[0]][0];if(d||0==d){var h=n.yaxis.units,v="",y=n.yaxis.precision;n.yaxis.precision=Math.min(y,1);var m=x.getTickText([d],n.yaxis);if(n.yaxis.precision=y,n.yaxis2&&n.yaxis2.convert_value!=n.yaxis.convert_value){var g=n.yaxis2.units;y=n.yaxis2.precision;n.yaxis2.precision=Math.min(y,1);var b=x.getTickText([d],n.yaxis2);n.yaxis2.precision=y,v=b+g}l[o].innerHTML=m+h,c[o].innerHTML=v}else l[o].innerHTML="N/A",c[o].innerHTML="";o+=1,f.anc_variables&&(o=k(i,l,f,o))}}}}(t,o)}})}},function(t){var e;e=function(){return this}();try{e=e||new Function("return this")()}catch(t){"object"==typeof window&&(e=window)}t.exports=e},function(t){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e,n){"use strict";var h=n(6),v=n(5),y=n(0);function m(s,t,l,c,u,p,f,d){$.ajax({type:"GET",url:t,jsonp:"callback",dataType:"jsonp",success:function(t){if(200!=t.code)return console.error("Invalid data API query. Code: {0} | Message: {1}".format(t.code,t.message)),void(void 0!==d&&d(c));var e=document.getElementById(u),n=function(t){var e={dates:y.map(t.timestamps,function(t){return t.replace("T"," ").substring(0,t.length-1)})};return y.extend(e,t.data),e}(t.results),r=s[0].x||[],i=n.dates;if(0!=(t={dates:i}).dates.length){if(p){for(var o=0;o<i.length&&i[o]<=r[r.length-1];)o++;if(o>=i.length)return void console.info("No new data downloaded");for(var a=0;a<l.length;a++)t[l[a]]=n[l[a]].slice(o);i=i.slice(o),t.dates=i}else for(a=0;a<l.length;a++)t[l[a]]=n[l[a]];h.updatePlot(s,e,c,t,p,f)}else console.warn("No data available from API")}})}var g=[[864e5,"5m","-00:10:00"],[2592e6,"1h","-02:00:00"]],b={"1m":60,"5m":300,"1h":3600};t.exports.requestPlotUpdate=function(t,e,n,r,i,o,a,s){var l,c,u,p,f=function(t){var e=[];return y.each(t,function(t){Array.prototype.push.apply(e,t.var_names),"anc_variables"in t&&Array.prototype.push.apply(e,t.anc_variables)}),y.uniq(e)}(t),d="";for(var h in f)d+=f[h],h<f.length-1&&(d+=":");if(i){if(p="&begin="+r+"&end="+i,"auto"==o)for(var h in o="1m",l=new Date(i)-new Date(r),g)l>=g[h][0]&&(o=g[h][1])}else{for(var h in o="1m",l=-36e5*(c=y.map(r.split(":"),Number))[0]+6e4*c[1]+1e3*c[2],g)l>=g[h][0]&&(o=g[h][1],a&&(r=g[h][2]));p="&begin="+r}return u=a?b.hasOwnProperty(o)?l/1e3/b[o]:250:0,m(t,v.buildRequestUrl("json",o,"","","column",p,d),f,n,e,a,u,s),o}}]);
\ No newline at end of file
diff --git a/htdocs/js/meteorogram/meteorogram.js.map b/htdocs/js/meteorogram/meteorogram.js.map
index 60dc21a79ee7575e41367a014d12e513d540f259..2e52ed72683f9aa0221be615bc062865fe1b82fd 100644
--- a/htdocs/js/meteorogram/meteorogram.js.map
+++ b/htdocs/js/meteorogram/meteorogram.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./controller.js","webpack:///./dispatcher.js","webpack:///./node_modules/d/index.js","webpack:///./node_modules/es5-ext/function/noop.js","webpack:///./node_modules/es5-ext/object/assign/index.js","webpack:///./node_modules/es5-ext/object/assign/is-implemented.js","webpack:///./node_modules/es5-ext/object/assign/shim.js","webpack:///./node_modules/es5-ext/object/is-callable.js","webpack:///./node_modules/es5-ext/object/is-value.js","webpack:///./node_modules/es5-ext/object/keys/index.js","webpack:///./node_modules/es5-ext/object/keys/is-implemented.js","webpack:///./node_modules/es5-ext/object/keys/shim.js","webpack:///./node_modules/es5-ext/object/normalize-options.js","webpack:///./node_modules/es5-ext/object/valid-callable.js","webpack:///./node_modules/es5-ext/object/valid-value.js","webpack:///./node_modules/es5-ext/string/#/contains/index.js","webpack:///./node_modules/es5-ext/string/#/contains/is-implemented.js","webpack:///./node_modules/es5-ext/string/#/contains/shim.js","webpack:///./node_modules/event-emitter/index.js","webpack:///./node_modules/fbjs/lib/invariant.js","webpack:///./node_modules/flux/index.js","webpack:///./node_modules/flux/lib/Dispatcher.js","webpack:///./node_modules/underscore/underscore.js","webpack:///(webpack)/buildin/global.js","webpack:///(webpack)/buildin/module.js","webpack:///./plot/data.js","webpack:///./plot/init.js","webpack:///./plot/table.js","webpack:///./plot/ticks.js","webpack:///./plot/update.js","webpack:///./plot/utils.js","webpack:///./ui/button_template.js","webpack:///./ui/buttons.js","webpack:///./ui/loading.js","webpack:///external \"Plotly\""],"names":["buildFormInDiv","require","Dispatcher","_","API","div","controlDiv","plotsInfo","myDispatcher","getDispatcher","plotDiv","dataCache","initMeteorogram","plot_div","plotOrder","hasGraph","dispatch","initMeteorogramTable","table_div","hasTable","tableDiv","initMeteorogramControls","displayRealTime","showPlot","varName","status","hidePlot","displayRecent","start_time","displayTimeRange","stop_time","interval","window","MeteorogramController","ee","Flux","Plot","Table","dataAccess","loading","GRAPH_HEIGHT","dispatchUpdate","startTime","checkboxEmitter","visible","setPlots","plot_key","setShowing","plotName","undefined","showing","getShowing","handleActions","action","emit","location","dispatchToken","register","bind","plotEmitter","waitFor","defaultPlots","time","start","end","userInfo","stopUpdate","progress","validID","id","clearInterval","updateInterval","startUpdate","intervalID","setInterval","on","initTable","requestTableUpdate","initPlot","requestPlotUpdate","checkInterval","module","exports","updatePlot","utils","processData","dataObj","dates","map","timestamps","date","replace","substring","length","allData","extend","data","plotting","url","var_names","update","maxPoints","err_callback","$","ajax","type","jsonp","dataType","success","code","console","error","format","message","graphDiv","document","getElementById","existingDates","warn","startIndex","info","i","slice","intervalLookUp","intervalToSeconds","varNamesForDiv","varNames","each","trace_data","Array","prototype","push","apply","anc_variables","uniq","endTime","stream_string","dt_in_ms","time_parts","split","Number","Date","hasOwnProperty","buildRequestUrl","Plotly","getSecondAxisConfig","axis_number","plot_info","axis_info","axis_kwargs","key","axis_config","gridcolor","titlefont","title","zeroline","overlaying","toString","side","anchor","idx","div_id","DEFAULT_PLOT_HEIGHT","nshowing","layout","showlegend","height","domain","showline","showticklabels","showgrid","tickformat","trace_info","trace_config","step","x_anchor","trace_kwargs","plot_idx","plots","yaxis","trace_info_idx","traces","name","x","y","text","xaxis","hoverinfo","hovermode","anc_data","plot_name","trace_index","isSecondAxis","colorbar","len","z","yaxis2","skip","toolbar","plot","ticktext","table","tbody","children","add_contour_rows","info_td","addClass","row","short_name","append","add_anc_rows","anc_info_idx","anc_info","anc_idx","title_row","hightlight_idx","y_highlight","hightlight_idx_idx","units","hl_idx","data_cells","convert_cells","trace_idx","trace","indexOf","join","updateTable","results","td_idx","num_results","html","update_contour_cells","update_val","convert","old_precision","precision","Math","min","orig_val","getTickText","convert_value","convert_units","convert_val","innerHTML","update_anc_cells","zprobe","zprobe2","anc_key","String","args","arguments","match","number","getWaterTempProbe","plotInfo","traceInfo","allProbeText","probeText","col","rowText","depth","j","toFixed","getF","getSpeedMPH","val","getSpeedKTS","getPresInHg","getAccumMillimeter","cardinalWDir","degrees","floor","getVal","CONVERSION_FUNCTIONS","null","formatValue","val2","getDewpointProbe","relHum","rh_info","defaultProbeText","PROBE_TEXT_FUNCTIONS","dewpoint","water_temp","getProbeText","probe_text","values","tickText","getTickVals","max","bump","extra","range","removeOldPoints","removeCount","splice","replaceData","plotHandled","forceRedraw","tracesToExtend","extendData","newContourData","contourTracesToExtend","contourExtendData","traceIndex","index","var_name","extendTraces","redraw","epoch","sep","order","streams","request_url","METOBS_API_URL","checkboxTemplates","controlPanelTemplate","dispatchCustom","dispatcher","getUserInfo","startDate","endDate","intervalVal","setTimeout","dropDown","selectedText","timeDelta","bind_daterange_actions","jQ_div","click","change","set_active_form","which_block","prop","set_form_datepickers","datetimepicker","changeMonth","changeYear","dateFormat","timeFormat","showSecond","showMillisec","showMicrosec","trigger","setup_all_forms","ready","disable","enable","getDate","dateString","timeString","year","parseInt","month","day","hour","minute","seconds","enablePlot","disablePlot","checkFields","selected","diff","points","attr"],"mappings":"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EtD;AACA;AACA;AACA;AACA,kBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE;;AAEF;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,aAAa,4BAA4B;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;;AAEpB;AACA,aAAa,2BAA2B;AACxC;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,0BAA0B;;AAE1B;AACA;AACA;AACA;;;;;;;;;;;;;ACnIA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAI,IAAqC;AACzC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,qDAAqD;AACrD,KAAK;AACL;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA,0BAA0B;AAC1B;AACA;AACA;;AAEA,2B;;;;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4BAA4B,mBAAO,CAAC,+DAAkB;;;;;;;;;;;;;ACTtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEa;;AAEb;;AAEA,iDAAiD,0CAA0C,0DAA0D,EAAE;;AAEvJ,gBAAgB,mBAAO,CAAC,gEAAoB;;AAE5C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,sBAAsB;AACtB;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,2BAA2B,KAAqC,qGAAqG,SAAgB;AACrL;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B,KAAqC,qFAAqF,SAAgB;AACrK,oBAAoB,iBAAiB;AACrC;AACA;AACA,+BAA+B,KAAqC,gHAAgH,SAAgB;AACpM;AACA;AACA,6BAA6B,KAAqC,kGAAkG,SAAgB;AACpL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,4BAA4B,KAAqC,8FAA8F,SAAgB;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED,4B;;;;;;;;;;;ACtOA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM,KAA6B;AACnC,QAAQ,KAA4B;AACpC;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,oBAAoB;AACzC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,YAAY;AAClD;AACA;AACA,KAAK;AACL;AACA,uCAAuC,YAAY;AACnD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,8BAA8B;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,YAAY;AACtD;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,YAAY;AACtD;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,WAAW;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,kDAAkD;AAClD,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,wCAAwC;AACxC,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA,iBAAiB,gBAAgB;AACjC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,6CAA6C,YAAY;AACzD;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,8BAA8B;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD;AACtD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qBAAqB,cAAc;AACnC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO,eAAe;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,qBAAqB,eAAe;AACpC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yCAAyC,YAAY;AACrD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yCAAyC,YAAY;AACrD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,yCAAyC,YAAY;AACrD;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qDAAqD;AACrD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM,KAAwB;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe;AACf,cAAc;AACd,cAAc;AACd,gBAAgB;AAChB,gBAAgB;AAChB,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP,qBAAqB;AACrB;;AAEA;AACA;AACA,KAAK;AACL,iBAAiB;;AAEjB;AACA,kDAAkD,EAAE,iBAAiB;;AAErE;AACA,wBAAwB,8BAA8B;AACtD,2BAA2B;;AAE3B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,kDAAkD,iBAAiB;;AAEnE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;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","file":"meteorogram.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./controller.js\");\n","var buildFormInDiv = require('./ui/buttons.js');\nvar Dispatcher = require('./dispatcher.js');\nvar _ = require('underscore');\n\nfunction API(div, controlDiv, plotsInfo) {\n    var myDispatcher = Dispatcher.getDispatcher();\n    return {\n        plotDiv: div,\n        controlDiv: controlDiv,\n        // Our storage of the plotly data/traces being plotted right now\n        dataCache: [],\n\n        initMeteorogram: function(plot_div, plotOrder) {\n            this.hasGraph = true;\n            this.plotDiv = plot_div || this.plotDiv;\n            //start with only the selected plots showing, reveal others only if their data is requested\n            myDispatcher.dispatch({\n                'status': 'initPlot',\n                'emit': 'plotEmitter',\n                'location': this.plotDiv,\n                'dataCache': this.dataCache,\n                'plotsInfo': plotsInfo,\n                'plotOrder': plotOrder\n            });\n        },\n        initMeteorogramTable: function(table_div,plotOrder) {\n            this.hasTable = true;\n            this.tableDiv = table_div || this.plotDiv;\n            //start with only the selected plots showing, reveal others only if their data is requested\n            myDispatcher.dispatch({\n                'status': 'initTable',\n                'emit': 'plotEmitter',\n                'location': this.tableDiv,\n                'plotsInfo': plotsInfo,\n                'plotOrder': plotOrder,\n            });\n        },\n\n        initMeteorogramControls:function(plotOrder){\n            buildFormInDiv(this.controlDiv, this.plotDiv,myDispatcher);\n        },\n\n        displayRealTime: function() {\n            if (this.hasTable) {\n                myDispatcher.dispatch({\n                    'status':'update_table',\n                    'emit':'plotEmitter',\n                    'time':'-3:00:00',\n                    'location':this.tableDiv\n                });\n            }\n            if (this.hasGraph) {\n                myDispatcher.dispatch({\n                    'status':'get_since_now',\n                    'emit':'plotEmitter',\n                    'time':'-3:00:00',\n                    'location':this.plotDiv\n                });\n            }\n        },\n\n        showPlot:function(varName){\n            myDispatcher.dispatch({status: ('show' + varName), 'emit': 'checkboxEmitter','location':this.div});\n        },\n\n        hidePlot:function(varName){\n            myDispatcher.dispatch({status: ('hide' + varName), 'emit': 'checkboxEmitter','location':this.div});\n        },\n\n        displayRecent: function(start_time) {\n            // interval, if not provided, will be determined based on start time\n            myDispatcher.dispatch({\n                'status': 'get_since_now',\n                'emit': 'plotEmitter',\n                'time': start_time,\n            });\n        },\n\n        displayTimeRange: function(start_time, stop_time, interval) {\n            myDispatcher.dispatch({\n                'status':'get_between_dates',\n                'emit':'plotEmitter',\n                'start':start_time,\n                'end':stop_time,\n                'interval':interval||'auto',\n            });\n\n        },\n    }\n}\n\n//expose the API to other scripts\nwindow.MeteorogramController = API;\n","\"use strict\";\n\n//var $ = require('jquery');\nvar ee = require('event-emitter');\nvar Flux = require('flux');\nvar Plot = require('./plot/init.js');\nvar Table = require('./plot/table.js');\nvar dataAccess = require('./plot/data.js');\nvar loading = require('./ui/loading.js');\n\nfunction getDispatcher() {\n    var myDispatcher = new Flux.Dispatcher();\n    //not sure where else to stick globals\n    myDispatcher.GRAPH_HEIGHT = 170;\n    /**\n    * The purpose of this method is to dispatch an update message to plotStore\n    *\n    * no parameters\n    * no returns\n    */\n\n    function dispatchUpdate(startTime) {\n        return function() {\n            //dispatch update message to plotStore\n            myDispatcher.dispatch({'status': 'update', 'emit': 'plotEmitter', 'startTime': startTime});\n        }\n    }\n\n    //creates checkbox store\n    var checkboxEmitter = ee({\n        visible: {},\n        setPlots: function (plotsInfo) {\n            for (var plot_key in plotsInfo) {\n                this.visible[plot_key] = true;\n            }\n        },\n        setShowing: function(plotName, visible) {\n            if (visible === undefined) {\n                this.showing[plotName] = !this.showing[plotName];\n            } else {\n                this.showing[plotName] = visible;\n            }\n        },\n        getShowing: function(plotName) {\n            return this.showing[plotName];\n        },\n        handleActions: function(action) {\n            //only handels if action is for checkbox emitter\n            if(action.emit == 'checkboxEmitter')\n            {\n                this.emit(action.status, action.location);\n            }    \n        }\n    });\n\n    //register store with dispatcher\n    checkboxEmitter.dispatchToken = myDispatcher.register(checkboxEmitter.handleActions.bind(checkboxEmitter));\n\n    //create plotStore\n    // FIXME: Event emitter should be added to a class prototype, not the other way around\n    // See https://github.com/medikoo/event-emitter#usage\n    // The below works...but only because event-emitter allows it. Should probably stick with advertised features\n    var plotEmitter = ee({\n        handleActions: function(action) {\n            if (action.emit == 'plotEmitter') {\n                myDispatcher.waitFor([checkboxEmitter.dispatchToken]);\n\n                if (action.location !== undefined) {\n                    this.div = action.location;\n                }\n\n                if (action.plotsInfo !== undefined) {\n                    this.plotsInfo = action.plotsInfo;\n                    this.plotOrder = this.plotsInfo.defaultPlots;\n                }\n                if (action.plotOrder !== undefined) {\n                    this.plotOrder = action.plotOrder;\n                }\n\n                if (action.dataCache !== undefined) {\n                    this.dataCache = action.dataCache;\n                }\n\n                if (action.status == 'get_since_now') {\n                    this.emit(\n                        action.status,\n                        action.time,\n                        this.plotsInfo,\n                        this.dataCache,\n                        this.div);\n                }else if (action.status == 'update_table') {\n                    this.emit(\n                        action.status,\n                        action.time,\n                        this.plotsInfo,\n                        this.div);\n                } else if (action.status == 'get_between_dates') {\n                    this.emit(\n                        action.status,\n                        action.start,\n                        action.end,\n                        action.interval,\n                        this.plotsInfo,\n                        this.dataCache,\n                        this.div);\n                } else if (action.status == 'initPlot') {\n                    this.emit(\n                        action.status,\n                        action.location,\n                        action.plotOrder ? action.plotOrder : this.plotOrder,\n                        this.plotsInfo,\n                        this.dataCache);\n                } else if (action.status == 'initTable') {\n                    this.emit(\n                        action.status,\n                        action.location,\n                        action.plotOrder ? action.plotOrder : this.plotOrder,\n                        this.plotsInfo);\n                } else if (action.status == 'update') {\n                    this.emit(action.status, this.div, this.plotsInfo, this.dataCache, action.startTime);\n                } else {\n                    //adds parameter for user information in custom plot\n                    // console.debug(\"Emitting user information message: {action.status} : {action.userInfo}\");\n                    this.emit(action.status, action.userInfo);\n                }\n            }    \n        }\n    });\n\n\n    function stopUpdate(plotsInfo) {\n        if(!plotsInfo.progress)\n            plotsInfo.progress = {};\n        if(plotsInfo.progress.validID){\n            var id = plotsInfo.progress.id[0];\n            clearInterval(id);\n            plotsInfo.progress.validID = false;\n\n        }\n    }\n\n    // update every N/2 milliseconds\n    const updateInterval = {\n        '1m': 30 * 1000,\n        '5m': 2.5 * 60 * 1000,\n        '1h': 30 * 60 * 1000,\n    };\n\n\n    function startUpdate(startTime, interval, plotsInfo) {\n        // stop any previous updates\n        if(!plotsInfo.progress)\n            plotsInfo.progress = {};\n        stopUpdate(plotsInfo);\n\n        // resume update operations\n        if (startTime === undefined) {\n            startTime = plotsInfo.progress.id[1];\n        }\n        if (interval === undefined) {\n            interval = plotsInfo.progress.id[2];\n        }\n\n        // every 30 seconds, rings update alarm\n        var intervalID = setInterval(dispatchUpdate(startTime), updateInterval[interval]);\n        // save alarm id\n        plotsInfo.progress.id = [intervalID, startTime, interval];\n        plotsInfo.progress.validID = true;\n    }\n\n    plotEmitter.on('initTable', function(div, plotOrder, plotsInfo) {\n        //initialize checkbox store\n        checkboxEmitter.setPlots(plotsInfo);\n        Table.initTable(div, plotOrder, plotsInfo);\n    });\n\n    plotEmitter.on('update_table',function(time, plotsInfo, div){\n        Table.requestTableUpdate(div, plotsInfo);\n        setInterval(function(){Table.requestTableUpdate(div,plotsInfo)},updateInterval['1m']);\n    });\n\n    plotEmitter.on('initPlot', function(div, plotOrder, plotsInfo, dataCache) {\n        //initialize checkbox store\n        checkboxEmitter.setPlots(plotsInfo);\n        Plot.initPlot(dataCache, div, plotOrder, plotsInfo);\n    });\n\n    plotEmitter.on(\"get_since_now\", function(time, plotsInfo, dataCache, div) {\n        var interval = dataAccess.requestPlotUpdate(dataCache, div, plotsInfo, time,\n            undefined, undefined, undefined, stopUpdate);\n        startUpdate(time, interval, plotsInfo);\n    });\n\n    plotEmitter.on(\"get_between_dates\",function(start, end, interval, plotsInfo, dataCache, div) {\n        stopUpdate(plotsInfo);\n        dataAccess.requestPlotUpdate(dataCache, div, plotsInfo, start, end, interval);\n    });\n\n    //when store recieves signal, update component\n    plotEmitter.on('update', function(div, plotsInfo, dataCache, startTime) {\n        dataAccess.requestPlotUpdate(dataCache, div, plotsInfo, startTime, undefined, undefined, true);\n    });\n\n    plotEmitter.on(\"checking_custom\", function()\n    {\n        //before components were plots. Here, it's the user prompt paragraph\n        loading.checkInterval();\n    });\n\n    //register plotStore with dispatcher\n    plotEmitter.dispatchToken = myDispatcher.register(plotEmitter.handleActions.bind(plotEmitter));\n\n    return myDispatcher;\n}\n\n//exports dispatchers and stores\nmodule.exports.getDispatcher = getDispatcher;\n","'use strict';\n\nvar assign        = require('es5-ext/object/assign')\n  , normalizeOpts = require('es5-ext/object/normalize-options')\n  , isCallable    = require('es5-ext/object/is-callable')\n  , contains      = require('es5-ext/string/#/contains')\n\n  , d;\n\nd = module.exports = function (dscr, value/*, options*/) {\n\tvar c, e, w, options, desc;\n\tif ((arguments.length < 2) || (typeof dscr !== 'string')) {\n\t\toptions = value;\n\t\tvalue = dscr;\n\t\tdscr = null;\n\t} else {\n\t\toptions = arguments[2];\n\t}\n\tif (dscr == null) {\n\t\tc = w = true;\n\t\te = false;\n\t} else {\n\t\tc = contains.call(dscr, 'c');\n\t\te = contains.call(dscr, 'e');\n\t\tw = contains.call(dscr, 'w');\n\t}\n\n\tdesc = { value: value, configurable: c, enumerable: e, writable: w };\n\treturn !options ? desc : assign(normalizeOpts(options), desc);\n};\n\nd.gs = function (dscr, get, set/*, options*/) {\n\tvar c, e, options, desc;\n\tif (typeof dscr !== 'string') {\n\t\toptions = set;\n\t\tset = get;\n\t\tget = dscr;\n\t\tdscr = null;\n\t} else {\n\t\toptions = arguments[3];\n\t}\n\tif (get == null) {\n\t\tget = undefined;\n\t} else if (!isCallable(get)) {\n\t\toptions = get;\n\t\tget = set = undefined;\n\t} else if (set == null) {\n\t\tset = undefined;\n\t} else if (!isCallable(set)) {\n\t\toptions = set;\n\t\tset = undefined;\n\t}\n\tif (dscr == null) {\n\t\tc = true;\n\t\te = false;\n\t} else {\n\t\tc = contains.call(dscr, 'c');\n\t\te = contains.call(dscr, 'e');\n\t}\n\n\tdesc = { get: get, set: set, configurable: c, enumerable: e };\n\treturn !options ? desc : assign(normalizeOpts(options), desc);\n};\n","\"use strict\";\n\n// eslint-disable-next-line no-empty-function\nmodule.exports = function () {};\n","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")()\n\t? Object.assign\n\t: require(\"./shim\");\n","\"use strict\";\n\nmodule.exports = function () {\n\tvar assign = Object.assign, obj;\n\tif (typeof assign !== \"function\") return false;\n\tobj = { foo: \"raz\" };\n\tassign(obj, { bar: \"dwa\" }, { trzy: \"trzy\" });\n\treturn (obj.foo + obj.bar + obj.trzy) === \"razdwatrzy\";\n};\n","\"use strict\";\n\nvar keys  = require(\"../keys\")\n  , value = require(\"../valid-value\")\n  , max   = Math.max;\n\nmodule.exports = function (dest, src /*, …srcn*/) {\n\tvar error, i, length = max(arguments.length, 2), assign;\n\tdest = Object(value(dest));\n\tassign = function (key) {\n\t\ttry {\n\t\t\tdest[key] = src[key];\n\t\t} catch (e) {\n\t\t\tif (!error) error = e;\n\t\t}\n\t};\n\tfor (i = 1; i < length; ++i) {\n\t\tsrc = arguments[i];\n\t\tkeys(src).forEach(assign);\n\t}\n\tif (error !== undefined) throw error;\n\treturn dest;\n};\n","// Deprecated\n\n\"use strict\";\n\nmodule.exports = function (obj) {\n return typeof obj === \"function\";\n};\n","\"use strict\";\n\nvar _undefined = require(\"../function/noop\")(); // Support ES3 engines\n\nmodule.exports = function (val) {\n return (val !== _undefined) && (val !== null);\n};\n","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")()\n\t? Object.keys\n\t: require(\"./shim\");\n","\"use strict\";\n\nmodule.exports = function () {\n\ttry {\n\t\tObject.keys(\"primitive\");\n\t\treturn true;\n\t} catch (e) {\n return false;\n}\n};\n","\"use strict\";\n\nvar isValue = require(\"../is-value\");\n\nvar keys = Object.keys;\n\nmodule.exports = function (object) {\n\treturn keys(isValue(object) ? Object(object) : object);\n};\n","\"use strict\";\n\nvar isValue = require(\"./is-value\");\n\nvar forEach = Array.prototype.forEach, create = Object.create;\n\nvar process = function (src, obj) {\n\tvar key;\n\tfor (key in src) obj[key] = src[key];\n};\n\n// eslint-disable-next-line no-unused-vars\nmodule.exports = function (opts1 /*, …options*/) {\n\tvar result = create(null);\n\tforEach.call(arguments, function (options) {\n\t\tif (!isValue(options)) return;\n\t\tprocess(Object(options), result);\n\t});\n\treturn result;\n};\n","\"use strict\";\n\nmodule.exports = function (fn) {\n\tif (typeof fn !== \"function\") throw new TypeError(fn + \" is not a function\");\n\treturn fn;\n};\n","\"use strict\";\n\nvar isValue = require(\"./is-value\");\n\nmodule.exports = function (value) {\n\tif (!isValue(value)) throw new TypeError(\"Cannot use null or undefined\");\n\treturn value;\n};\n","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")()\n\t? String.prototype.contains\n\t: require(\"./shim\");\n","\"use strict\";\n\nvar str = \"razdwatrzy\";\n\nmodule.exports = function () {\n\tif (typeof str.contains !== \"function\") return false;\n\treturn (str.contains(\"dwa\") === true) && (str.contains(\"foo\") === false);\n};\n","\"use strict\";\n\nvar indexOf = String.prototype.indexOf;\n\nmodule.exports = function (searchString/*, position*/) {\n\treturn indexOf.call(this, searchString, arguments[1]) > -1;\n};\n","'use strict';\n\nvar d        = require('d')\n  , callable = require('es5-ext/object/valid-callable')\n\n  , apply = Function.prototype.apply, call = Function.prototype.call\n  , create = Object.create, defineProperty = Object.defineProperty\n  , defineProperties = Object.defineProperties\n  , hasOwnProperty = Object.prototype.hasOwnProperty\n  , descriptor = { configurable: true, enumerable: false, writable: true }\n\n  , on, once, off, emit, methods, descriptors, base;\n\non = function (type, listener) {\n\tvar data;\n\n\tcallable(listener);\n\n\tif (!hasOwnProperty.call(this, '__ee__')) {\n\t\tdata = descriptor.value = create(null);\n\t\tdefineProperty(this, '__ee__', descriptor);\n\t\tdescriptor.value = null;\n\t} else {\n\t\tdata = this.__ee__;\n\t}\n\tif (!data[type]) data[type] = listener;\n\telse if (typeof data[type] === 'object') data[type].push(listener);\n\telse data[type] = [data[type], listener];\n\n\treturn this;\n};\n\nonce = function (type, listener) {\n\tvar once, self;\n\n\tcallable(listener);\n\tself = this;\n\ton.call(this, type, once = function () {\n\t\toff.call(self, type, once);\n\t\tapply.call(listener, this, arguments);\n\t});\n\n\tonce.__eeOnceListener__ = listener;\n\treturn this;\n};\n\noff = function (type, listener) {\n\tvar data, listeners, candidate, i;\n\n\tcallable(listener);\n\n\tif (!hasOwnProperty.call(this, '__ee__')) return this;\n\tdata = this.__ee__;\n\tif (!data[type]) return this;\n\tlisteners = data[type];\n\n\tif (typeof listeners === 'object') {\n\t\tfor (i = 0; (candidate = listeners[i]); ++i) {\n\t\t\tif ((candidate === listener) ||\n\t\t\t\t\t(candidate.__eeOnceListener__ === listener)) {\n\t\t\t\tif (listeners.length === 2) data[type] = listeners[i ? 0 : 1];\n\t\t\t\telse listeners.splice(i, 1);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif ((listeners === listener) ||\n\t\t\t\t(listeners.__eeOnceListener__ === listener)) {\n\t\t\tdelete data[type];\n\t\t}\n\t}\n\n\treturn this;\n};\n\nemit = function (type) {\n\tvar i, l, listener, listeners, args;\n\n\tif (!hasOwnProperty.call(this, '__ee__')) return;\n\tlisteners = this.__ee__[type];\n\tif (!listeners) return;\n\n\tif (typeof listeners === 'object') {\n\t\tl = arguments.length;\n\t\targs = new Array(l - 1);\n\t\tfor (i = 1; i < l; ++i) args[i - 1] = arguments[i];\n\n\t\tlisteners = listeners.slice();\n\t\tfor (i = 0; (listener = listeners[i]); ++i) {\n\t\t\tapply.call(listener, this, args);\n\t\t}\n\t} else {\n\t\tswitch (arguments.length) {\n\t\tcase 1:\n\t\t\tcall.call(listeners, this);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tcall.call(listeners, this, arguments[1]);\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tcall.call(listeners, this, arguments[1], arguments[2]);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tl = arguments.length;\n\t\t\targs = new Array(l - 1);\n\t\t\tfor (i = 1; i < l; ++i) {\n\t\t\t\targs[i - 1] = arguments[i];\n\t\t\t}\n\t\t\tapply.call(listeners, this, args);\n\t\t}\n\t}\n};\n\nmethods = {\n\ton: on,\n\tonce: once,\n\toff: off,\n\temit: emit\n};\n\ndescriptors = {\n\ton: d(on),\n\tonce: d(once),\n\toff: d(off),\n\temit: d(emit)\n};\n\nbase = defineProperties({}, descriptors);\n\nmodule.exports = exports = function (o) {\n\treturn (o == null) ? create(base) : defineProperties(Object(o), descriptors);\n};\nexports.methods = methods;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\n/**\n * Use invariant() to assert state which your program assumes to be true.\n *\n * Provide sprintf-style format (only %s is supported) and arguments\n * to provide information about what broke and what you were\n * expecting.\n *\n * The invariant message will be stripped in production, but the invariant\n * will remain to ensure logic does not differ in production.\n */\n\nvar validateFormat = function validateFormat(format) {};\n\nif (process.env.NODE_ENV !== 'production') {\n  validateFormat = function validateFormat(format) {\n    if (format === undefined) {\n      throw new Error('invariant requires an error message argument');\n    }\n  };\n}\n\nfunction invariant(condition, format, a, b, c, d, e, f) {\n  validateFormat(format);\n\n  if (!condition) {\n    var error;\n    if (format === undefined) {\n      error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');\n    } else {\n      var args = [a, b, c, d, e, f];\n      var argIndex = 0;\n      error = new Error(format.replace(/%s/g, function () {\n        return args[argIndex++];\n      }));\n      error.name = 'Invariant Violation';\n    }\n\n    error.framesToPop = 1; // we don't care about invariant's own frame\n    throw error;\n  }\n}\n\nmodule.exports = invariant;","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\nmodule.exports.Dispatcher = require('./lib/Dispatcher');\n","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule Dispatcher\n * \n * @preventMunge\n */\n\n'use strict';\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nvar invariant = require('fbjs/lib/invariant');\n\nvar _prefix = 'ID_';\n\n/**\n * Dispatcher is used to broadcast payloads to registered callbacks. This is\n * different from generic pub-sub systems in two ways:\n *\n *   1) Callbacks are not subscribed to particular events. Every payload is\n *      dispatched to every registered callback.\n *   2) Callbacks can be deferred in whole or part until other callbacks have\n *      been executed.\n *\n * For example, consider this hypothetical flight destination form, which\n * selects a default city when a country is selected:\n *\n *   var flightDispatcher = new Dispatcher();\n *\n *   // Keeps track of which country is selected\n *   var CountryStore = {country: null};\n *\n *   // Keeps track of which city is selected\n *   var CityStore = {city: null};\n *\n *   // Keeps track of the base flight price of the selected city\n *   var FlightPriceStore = {price: null}\n *\n * When a user changes the selected city, we dispatch the payload:\n *\n *   flightDispatcher.dispatch({\n *     actionType: 'city-update',\n *     selectedCity: 'paris'\n *   });\n *\n * This payload is digested by `CityStore`:\n *\n *   flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'city-update') {\n *       CityStore.city = payload.selectedCity;\n *     }\n *   });\n *\n * When the user selects a country, we dispatch the payload:\n *\n *   flightDispatcher.dispatch({\n *     actionType: 'country-update',\n *     selectedCountry: 'australia'\n *   });\n *\n * This payload is digested by both stores:\n *\n *   CountryStore.dispatchToken = flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'country-update') {\n *       CountryStore.country = payload.selectedCountry;\n *     }\n *   });\n *\n * When the callback to update `CountryStore` is registered, we save a reference\n * to the returned token. Using this token with `waitFor()`, we can guarantee\n * that `CountryStore` is updated before the callback that updates `CityStore`\n * needs to query its data.\n *\n *   CityStore.dispatchToken = flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'country-update') {\n *       // `CountryStore.country` may not be updated.\n *       flightDispatcher.waitFor([CountryStore.dispatchToken]);\n *       // `CountryStore.country` is now guaranteed to be updated.\n *\n *       // Select the default city for the new country\n *       CityStore.city = getDefaultCityForCountry(CountryStore.country);\n *     }\n *   });\n *\n * The usage of `waitFor()` can be chained, for example:\n *\n *   FlightPriceStore.dispatchToken =\n *     flightDispatcher.register(function(payload) {\n *       switch (payload.actionType) {\n *         case 'country-update':\n *         case 'city-update':\n *           flightDispatcher.waitFor([CityStore.dispatchToken]);\n *           FlightPriceStore.price =\n *             getFlightPriceStore(CountryStore.country, CityStore.city);\n *           break;\n *     }\n *   });\n *\n * The `country-update` payload will be guaranteed to invoke the stores'\n * registered callbacks in order: `CountryStore`, `CityStore`, then\n * `FlightPriceStore`.\n */\n\nvar Dispatcher = (function () {\n  function Dispatcher() {\n    _classCallCheck(this, Dispatcher);\n\n    this._callbacks = {};\n    this._isDispatching = false;\n    this._isHandled = {};\n    this._isPending = {};\n    this._lastID = 1;\n  }\n\n  /**\n   * Registers a callback to be invoked with every dispatched payload. Returns\n   * a token that can be used with `waitFor()`.\n   */\n\n  Dispatcher.prototype.register = function register(callback) {\n    var id = _prefix + this._lastID++;\n    this._callbacks[id] = callback;\n    return id;\n  };\n\n  /**\n   * Removes a callback based on its token.\n   */\n\n  Dispatcher.prototype.unregister = function unregister(id) {\n    !this._callbacks[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.unregister(...): `%s` does not map to a registered callback.', id) : invariant(false) : undefined;\n    delete this._callbacks[id];\n  };\n\n  /**\n   * Waits for the callbacks specified to be invoked before continuing execution\n   * of the current callback. This method should only be used by a callback in\n   * response to a dispatched payload.\n   */\n\n  Dispatcher.prototype.waitFor = function waitFor(ids) {\n    !this._isDispatching ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): Must be invoked while dispatching.') : invariant(false) : undefined;\n    for (var ii = 0; ii < ids.length; ii++) {\n      var id = ids[ii];\n      if (this._isPending[id]) {\n        !this._isHandled[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): Circular dependency detected while ' + 'waiting for `%s`.', id) : invariant(false) : undefined;\n        continue;\n      }\n      !this._callbacks[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): `%s` does not map to a registered callback.', id) : invariant(false) : undefined;\n      this._invokeCallback(id);\n    }\n  };\n\n  /**\n   * Dispatches a payload to all registered callbacks.\n   */\n\n  Dispatcher.prototype.dispatch = function dispatch(payload) {\n    !!this._isDispatching ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.') : invariant(false) : undefined;\n    this._startDispatching(payload);\n    try {\n      for (var id in this._callbacks) {\n        if (this._isPending[id]) {\n          continue;\n        }\n        this._invokeCallback(id);\n      }\n    } finally {\n      this._stopDispatching();\n    }\n  };\n\n  /**\n   * Is this Dispatcher currently dispatching.\n   */\n\n  Dispatcher.prototype.isDispatching = function isDispatching() {\n    return this._isDispatching;\n  };\n\n  /**\n   * Call the callback stored with the given id. Also do some internal\n   * bookkeeping.\n   *\n   * @internal\n   */\n\n  Dispatcher.prototype._invokeCallback = function _invokeCallback(id) {\n    this._isPending[id] = true;\n    this._callbacks[id](this._pendingPayload);\n    this._isHandled[id] = true;\n  };\n\n  /**\n   * Set up bookkeeping needed when dispatching.\n   *\n   * @internal\n   */\n\n  Dispatcher.prototype._startDispatching = function _startDispatching(payload) {\n    for (var id in this._callbacks) {\n      this._isPending[id] = false;\n      this._isHandled[id] = false;\n    }\n    this._pendingPayload = payload;\n    this._isDispatching = true;\n  };\n\n  /**\n   * Clear bookkeeping used for dispatching.\n   *\n   * @internal\n   */\n\n  Dispatcher.prototype._stopDispatching = function _stopDispatching() {\n    delete this._pendingPayload;\n    this._isDispatching = false;\n  };\n\n  return Dispatcher;\n})();\n\nmodule.exports = Dispatcher;","//     Underscore.js 1.9.1\n//     http://underscorejs.org\n//     (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n//     Underscore may be freely distributed under the MIT license.\n\n(function() {\n\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` (`self`) in the browser, `global`\n  // on the server, or `this` in some virtual machines. We use `self`\n  // instead of `window` for `WebWorker` support.\n  var root = typeof self == 'object' && self.self === self && self ||\n            typeof global == 'object' && global.global === global && global ||\n            this ||\n            {};\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype;\n  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var push = ArrayProto.push,\n      slice = ArrayProto.slice,\n      toString = ObjProto.toString,\n      hasOwnProperty = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var nativeIsArray = Array.isArray,\n      nativeKeys = Object.keys,\n      nativeCreate = Object.create;\n\n  // Naked function reference for surrogate-prototype-swapping.\n  var Ctor = function(){};\n\n  // Create a safe reference to the Underscore object for use below.\n  var _ = function(obj) {\n    if (obj instanceof _) return obj;\n    if (!(this instanceof _)) return new _(obj);\n    this._wrapped = obj;\n  };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for their old module API. If we're in\n  // the browser, add `_` as a global object.\n  // (`nodeType` is checked to ensure that `module`\n  // and `exports` are not HTML elements.)\n  if (typeof exports != 'undefined' && !exports.nodeType) {\n    if (typeof module != 'undefined' && !module.nodeType && module.exports) {\n      exports = module.exports = _;\n    }\n    exports._ = _;\n  } else {\n    root._ = _;\n  }\n\n  // Current version.\n  _.VERSION = '1.9.1';\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  var optimizeCb = function(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1: return function(value) {\n        return func.call(context, value);\n      };\n      // The 2-argument case is omitted because we’re not using it.\n      case 3: return function(value, index, collection) {\n        return func.call(context, value, index, collection);\n      };\n      case 4: return function(accumulator, value, index, collection) {\n        return func.call(context, accumulator, value, index, collection);\n      };\n    }\n    return function() {\n      return func.apply(context, arguments);\n    };\n  };\n\n  var builtinIteratee;\n\n  // An internal function to generate callbacks that can be applied to each\n  // element in a collection, returning the desired result — either `identity`,\n  // an arbitrary callback, a property matcher, or a property accessor.\n  var cb = function(value, context, argCount) {\n    if (_.iteratee !== builtinIteratee) return _.iteratee(value, context);\n    if (value == null) return _.identity;\n    if (_.isFunction(value)) return optimizeCb(value, context, argCount);\n    if (_.isObject(value) && !_.isArray(value)) return _.matcher(value);\n    return _.property(value);\n  };\n\n  // External wrapper for our callback generator. Users may customize\n  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.\n  // This abstraction hides the internal-only argCount argument.\n  _.iteratee = builtinIteratee = function(value, context) {\n    return cb(value, context, Infinity);\n  };\n\n  // Some functions take a variable number of arguments, or a few expected\n  // arguments at the beginning and then a variable number of values to operate\n  // on. This helper accumulates all remaining arguments past the function’s\n  // argument length (or an explicit `startIndex`), into an array that becomes\n  // the last argument. Similar to ES6’s \"rest parameter\".\n  var restArguments = function(func, startIndex) {\n    startIndex = startIndex == null ? func.length - 1 : +startIndex;\n    return function() {\n      var length = Math.max(arguments.length - startIndex, 0),\n          rest = Array(length),\n          index = 0;\n      for (; index < length; index++) {\n        rest[index] = arguments[index + startIndex];\n      }\n      switch (startIndex) {\n        case 0: return func.call(this, rest);\n        case 1: return func.call(this, arguments[0], rest);\n        case 2: return func.call(this, arguments[0], arguments[1], rest);\n      }\n      var args = Array(startIndex + 1);\n      for (index = 0; index < startIndex; index++) {\n        args[index] = arguments[index];\n      }\n      args[startIndex] = rest;\n      return func.apply(this, args);\n    };\n  };\n\n  // An internal function for creating a new object that inherits from another.\n  var baseCreate = function(prototype) {\n    if (!_.isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    Ctor.prototype = prototype;\n    var result = new Ctor;\n    Ctor.prototype = null;\n    return result;\n  };\n\n  var shallowProperty = function(key) {\n    return function(obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  };\n\n  var has = function(obj, path) {\n    return obj != null && hasOwnProperty.call(obj, path);\n  }\n\n  var deepGet = function(obj, path) {\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      if (obj == null) return void 0;\n      obj = obj[path[i]];\n    }\n    return length ? obj : void 0;\n  };\n\n  // Helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object.\n  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n  var getLength = shallowProperty('length');\n  var isArrayLike = function(collection) {\n    var length = getLength(collection);\n    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;\n  };\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  _.each = _.forEach = function(obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var keys = _.keys(obj);\n      for (i = 0, length = keys.length; i < length; i++) {\n        iteratee(obj[keys[i]], keys[i], obj);\n      }\n    }\n    return obj;\n  };\n\n  // Return the results of applying the iteratee to each element.\n  _.map = _.collect = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length,\n        results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  };\n\n  // Create a reducing function iterating left or right.\n  var createReduce = function(dir) {\n    // Wrap code that reassigns argument variables in a separate function than\n    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)\n    var reducer = function(obj, iteratee, memo, initial) {\n      var keys = !isArrayLike(obj) && _.keys(obj),\n          length = (keys || obj).length,\n          index = dir > 0 ? 0 : length - 1;\n      if (!initial) {\n        memo = obj[keys ? keys[index] : index];\n        index += dir;\n      }\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = keys ? keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    };\n\n    return function(obj, iteratee, memo, context) {\n      var initial = arguments.length >= 3;\n      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);\n    };\n  };\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  _.reduce = _.foldl = _.inject = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  _.reduceRight = _.foldr = createReduce(-1);\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _.find = _.detect = function(obj, predicate, context) {\n    var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey;\n    var key = keyFinder(obj, predicate, context);\n    if (key !== void 0 && key !== -1) return obj[key];\n  };\n\n  // Return all the elements that pass a truth test.\n  // Aliased as `select`.\n  _.filter = _.select = function(obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    _.each(obj, function(value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _.reject = function(obj, predicate, context) {\n    return _.filter(obj, _.negate(cb(predicate)), context);\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Aliased as `all`.\n  _.every = _.all = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Aliased as `any`.\n  _.some = _.any = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  };\n\n  // Determine if the array or object contains a given item (using `===`).\n  // Aliased as `includes` and `include`.\n  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = _.values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return _.indexOf(obj, item, fromIndex) >= 0;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _.invoke = restArguments(function(obj, path, args) {\n    var contextPath, func;\n    if (_.isFunction(path)) {\n      func = path;\n    } else if (_.isArray(path)) {\n      contextPath = path.slice(0, -1);\n      path = path[path.length - 1];\n    }\n    return _.map(obj, function(context) {\n      var method = func;\n      if (!method) {\n        if (contextPath && contextPath.length) {\n          context = deepGet(context, contextPath);\n        }\n        if (context == null) return void 0;\n        method = context[path];\n      }\n      return method == null ? method : method.apply(context, args);\n    });\n  });\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _.pluck = function(obj, key) {\n    return _.map(obj, _.property(key));\n  };\n\n  // Convenience version of a common use case of `filter`: selecting only objects\n  // containing specific `key:value` pairs.\n  _.where = function(obj, attrs) {\n    return _.filter(obj, _.matcher(attrs));\n  };\n\n  // Convenience version of a common use case of `find`: getting the first object\n  // containing specific `key:value` pairs.\n  _.findWhere = function(obj, attrs) {\n    return _.find(obj, _.matcher(attrs));\n  };\n\n  // Return the maximum element (or element-based computation).\n  _.max = function(obj, iteratee, context) {\n    var result = -Infinity, lastComputed = -Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : _.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _.min = function(obj, iteratee, context) {\n    var result = Infinity, lastComputed = Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : _.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Shuffle a collection.\n  _.shuffle = function(obj) {\n    return _.sample(obj, Infinity);\n  };\n\n  // Sample **n** random values from a collection using the modern version of the\n  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `map`.\n  _.sample = function(obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = _.values(obj);\n      return obj[_.random(obj.length - 1)];\n    }\n    var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj);\n    var length = getLength(sample);\n    n = Math.max(Math.min(n, length), 0);\n    var last = length - 1;\n    for (var index = 0; index < n; index++) {\n      var rand = _.random(index, last);\n      var temp = sample[index];\n      sample[index] = sample[rand];\n      sample[rand] = temp;\n    }\n    return sample.slice(0, n);\n  };\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  _.sortBy = function(obj, iteratee, context) {\n    var index = 0;\n    iteratee = cb(iteratee, context);\n    return _.pluck(_.map(obj, function(value, key, list) {\n      return {\n        value: value,\n        index: index++,\n        criteria: iteratee(value, key, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  };\n\n  // An internal function used for aggregate \"group by\" operations.\n  var group = function(behavior, partition) {\n    return function(obj, iteratee, context) {\n      var result = partition ? [[], []] : {};\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _.groupBy = group(function(result, value, key) {\n    if (has(result, key)) result[key].push(value); else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `groupBy`, but for\n  // when you know that your index values will be unique.\n  _.indexBy = group(function(result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  _.countBy = group(function(result, value, key) {\n    if (has(result, key)) result[key]++; else result[key] = 1;\n  });\n\n  var reStrSymbol = /[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff]/g;\n  // Safely create a real, live array from anything iterable.\n  _.toArray = function(obj) {\n    if (!obj) return [];\n    if (_.isArray(obj)) return slice.call(obj);\n    if (_.isString(obj)) {\n      // Keep surrogate pair characters together\n      return obj.match(reStrSymbol);\n    }\n    if (isArrayLike(obj)) return _.map(obj, _.identity);\n    return _.values(obj);\n  };\n\n  // Return the number of elements in an object.\n  _.size = function(obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : _.keys(obj).length;\n  };\n\n  // Split a collection into two arrays: one whose elements all satisfy the given\n  // predicate, and one whose elements all do not satisfy the predicate.\n  _.partition = group(function(result, value, pass) {\n    result[pass ? 0 : 1].push(value);\n  }, true);\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head` and `take`. The **guard** check\n  // allows it to work with `_.map`.\n  _.first = _.head = _.take = function(array, n, guard) {\n    if (array == null || array.length < 1) return n == null ? void 0 : [];\n    if (n == null || guard) return array[0];\n    return _.initial(array, array.length - n);\n  };\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  _.initial = function(array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  _.last = function(array, n, guard) {\n    if (array == null || array.length < 1) return n == null ? void 0 : [];\n    if (n == null || guard) return array[array.length - 1];\n    return _.rest(array, Math.max(0, array.length - n));\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.\n  // Especially useful on the arguments object. Passing an **n** will return\n  // the rest N values in the array.\n  _.rest = _.tail = _.drop = function(array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  };\n\n  // Trim out all falsy values from an array.\n  _.compact = function(array) {\n    return _.filter(array, Boolean);\n  };\n\n  // Internal implementation of a recursive `flatten` function.\n  var flatten = function(input, shallow, strict, output) {\n    output = output || [];\n    var idx = output.length;\n    for (var i = 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {\n        // Flatten current level of array or arguments object.\n        if (shallow) {\n          var j = 0, len = value.length;\n          while (j < len) output[idx++] = value[j++];\n        } else {\n          flatten(value, shallow, strict, output);\n          idx = output.length;\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  };\n\n  // Flatten out an array, either recursively (by default), or just one level.\n  _.flatten = function(array, shallow) {\n    return flatten(array, shallow, false);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _.without = restArguments(function(array, otherArrays) {\n    return _.difference(array, otherArrays);\n  });\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // The faster algorithm will not work with an iteratee if the iteratee\n  // is not a one-to-one function, so providing an iteratee will disable\n  // the faster algorithm.\n  // Aliased as `unique`.\n  _.uniq = _.unique = function(array, isSorted, iteratee, context) {\n    if (!_.isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n          computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted && !iteratee) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!_.contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!_.contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _.union = restArguments(function(arrays) {\n    return _.uniq(flatten(arrays, true, true));\n  });\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  _.intersection = function(array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (_.contains(result, item)) continue;\n      var j;\n      for (j = 1; j < argsLength; j++) {\n        if (!_.contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _.difference = restArguments(function(array, rest) {\n    rest = flatten(rest, true, true);\n    return _.filter(array, function(value){\n      return !_.contains(rest, value);\n    });\n  });\n\n  // Complement of _.zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices.\n  _.unzip = function(array) {\n    var length = array && _.max(array, getLength).length || 0;\n    var result = Array(length);\n\n    for (var index = 0; index < length; index++) {\n      result[index] = _.pluck(array, index);\n    }\n    return result;\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _.zip = restArguments(_.unzip);\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values. Passing by pairs is the reverse of _.pairs.\n  _.object = function(list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  };\n\n  // Generator function to create the findIndex and findLastIndex functions.\n  var createPredicateIndexFinder = function(dir) {\n    return function(array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  };\n\n  // Returns the first index on an array-like that passes a predicate test.\n  _.findIndex = createPredicateIndexFinder(1);\n  _.findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  _.sortedIndex = function(array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0, high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\n    }\n    return low;\n  };\n\n  // Generator function to create the indexOf and lastIndexOf functions.\n  var createIndexFinder = function(dir, predicateFind, sortedIndex) {\n    return function(array, item, idx) {\n      var i = 0, length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n          i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), _.isNaN);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  };\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);\n  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _.range = function(start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    if (!step) {\n      step = stop < start ? -1 : 1;\n    }\n\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n\n    return range;\n  };\n\n  // Chunk a single array into multiple arrays, each containing `count` or fewer\n  // items.\n  _.chunk = function(array, count) {\n    if (count == null || count < 1) return [];\n    var result = [];\n    var i = 0, length = array.length;\n    while (i < length) {\n      result.push(slice.call(array, i, i += count));\n    }\n    return result;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Determines whether to execute a function as a constructor\n  // or a normal function with the provided arguments.\n  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (_.isObject(result)) return result;\n    return self;\n  };\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if\n  // available.\n  _.bind = restArguments(function(func, context, args) {\n    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');\n    var bound = restArguments(function(callArgs) {\n      return executeBound(func, bound, context, this, args.concat(callArgs));\n    });\n    return bound;\n  });\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. _ acts\n  // as a placeholder by default, allowing any combination of arguments to be\n  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.\n  _.partial = restArguments(function(func, boundArgs) {\n    var placeholder = _.partial.placeholder;\n    var bound = function() {\n      var position = 0, length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length; i++) {\n        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, bound, this, this, args);\n    };\n    return bound;\n  });\n\n  _.partial.placeholder = _;\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  _.bindAll = restArguments(function(obj, keys) {\n    keys = flatten(keys, false, false);\n    var index = keys.length;\n    if (index < 1) throw new Error('bindAll must be passed function names');\n    while (index--) {\n      var key = keys[index];\n      obj[key] = _.bind(obj[key], obj);\n    }\n  });\n\n  // Memoize an expensive function by storing its results.\n  _.memoize = function(func, hasher) {\n    var memoize = function(key) {\n      var cache = memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!has(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    memoize.cache = {};\n    return memoize;\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _.delay = restArguments(function(func, wait, args) {\n    return setTimeout(function() {\n      return func.apply(null, args);\n    }, wait);\n  });\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _.defer = _.partial(_.delay, _, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  _.throttle = function(func, wait, options) {\n    var timeout, context, args, result;\n    var previous = 0;\n    if (!options) options = {};\n\n    var later = function() {\n      previous = options.leading === false ? 0 : _.now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n\n    var throttled = function() {\n      var now = _.now();\n      if (!previous && options.leading === false) previous = now;\n      var remaining = wait - (now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n\n    throttled.cancel = function() {\n      clearTimeout(timeout);\n      previous = 0;\n      timeout = context = args = null;\n    };\n\n    return throttled;\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds. If `immediate` is passed, trigger the function on the\n  // leading edge, instead of the trailing.\n  _.debounce = function(func, wait, immediate) {\n    var timeout, result;\n\n    var later = function(context, args) {\n      timeout = null;\n      if (args) result = func.apply(context, args);\n    };\n\n    var debounced = restArguments(function(args) {\n      if (timeout) clearTimeout(timeout);\n      if (immediate) {\n        var callNow = !timeout;\n        timeout = setTimeout(later, wait);\n        if (callNow) result = func.apply(this, args);\n      } else {\n        timeout = _.delay(later, wait, this, args);\n      }\n\n      return result;\n    });\n\n    debounced.cancel = function() {\n      clearTimeout(timeout);\n      timeout = null;\n    };\n\n    return debounced;\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _.wrap = function(func, wrapper) {\n    return _.partial(wrapper, func);\n  };\n\n  // Returns a negated version of the passed-in predicate.\n  _.negate = function(predicate) {\n    return function() {\n      return !predicate.apply(this, arguments);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _.compose = function() {\n    var args = arguments;\n    var start = args.length - 1;\n    return function() {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  };\n\n  // Returns a function that will only be executed on and after the Nth call.\n  _.after = function(times, func) {\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  };\n\n  // Returns a function that will only be executed up to (but not including) the Nth call.\n  _.before = function(times, func) {\n    var memo;\n    return function() {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _.once = _.partial(_.before, 2);\n\n  _.restArguments = restArguments;\n\n  // Object Functions\n  // ----------------\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n\n  var collectNonEnumProps = function(obj, keys) {\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = _.isFunction(constructor) && constructor.prototype || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';\n    if (has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);\n\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {\n        keys.push(prop);\n      }\n    }\n  };\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`.\n  _.keys = function(obj) {\n    if (!_.isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (has(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve all the property names of an object.\n  _.allKeys = function(obj) {\n    if (!_.isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _.values = function(obj) {\n    var keys = _.keys(obj);\n    var length = keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[keys[i]];\n    }\n    return values;\n  };\n\n  // Returns the results of applying the iteratee to each element of the object.\n  // In contrast to _.map it returns an object.\n  _.mapObject = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys = _.keys(obj),\n        length = keys.length,\n        results = {};\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys[index];\n      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  };\n\n  // Convert an object into a list of `[key, value]` pairs.\n  // The opposite of _.object.\n  _.pairs = function(obj) {\n    var keys = _.keys(obj);\n    var length = keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [keys[i], obj[keys[i]]];\n    }\n    return pairs;\n  };\n\n  // Invert the keys and values of an object. The values must be serializable.\n  _.invert = function(obj) {\n    var result = {};\n    var keys = _.keys(obj);\n    for (var i = 0, length = keys.length; i < length; i++) {\n      result[obj[keys[i]]] = keys[i];\n    }\n    return result;\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`.\n  _.functions = _.methods = function(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // An internal function for creating assigner functions.\n  var createAssigner = function(keysFunc, defaults) {\n    return function(obj) {\n      var length = arguments.length;\n      if (defaults) obj = Object(obj);\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n            keys = keysFunc(source),\n            l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!defaults || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _.extend = createAssigner(_.allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in object(s).\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  _.extendOwn = _.assign = createAssigner(_.keys);\n\n  // Returns the first key on an object that passes a predicate test.\n  _.findKey = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = _.keys(obj), key;\n    for (var i = 0, length = keys.length; i < length; i++) {\n      key = keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  };\n\n  // Internal pick helper function to determine if `obj` has key `key`.\n  var keyInObj = function(value, key, obj) {\n    return key in obj;\n  };\n\n  // Return a copy of the object only containing the whitelisted properties.\n  _.pick = restArguments(function(obj, keys) {\n    var result = {}, iteratee = keys[0];\n    if (obj == null) return result;\n    if (_.isFunction(iteratee)) {\n      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);\n      keys = _.allKeys(obj);\n    } else {\n      iteratee = keyInObj;\n      keys = flatten(keys, false, false);\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  });\n\n  // Return a copy of the object without the blacklisted properties.\n  _.omit = restArguments(function(obj, keys) {\n    var iteratee = keys[0], context;\n    if (_.isFunction(iteratee)) {\n      iteratee = _.negate(iteratee);\n      if (keys.length > 1) context = keys[1];\n    } else {\n      keys = _.map(flatten(keys, false, false), String);\n      iteratee = function(value, key) {\n        return !_.contains(keys, key);\n      };\n    }\n    return _.pick(obj, iteratee, context);\n  });\n\n  // Fill in a given object with default properties.\n  _.defaults = createAssigner(_.allKeys, true);\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  _.create = function(prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) _.extendOwn(result, props);\n    return result;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _.clone = function(obj) {\n    if (!_.isObject(obj)) return obj;\n    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _.tap = function(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  _.isMatch = function(object, attrs) {\n    var keys = _.keys(attrs), length = keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  };\n\n\n  // Internal recursive comparison function for `isEqual`.\n  var eq, deepEq;\n  eq = function(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // `null` or `undefined` only equal to itself (strict comparison).\n    if (a == null || b == null) return false;\n    // `NaN`s are equivalent, but non-reflexive.\n    if (a !== a) return b !== b;\n    // Exhaust primitive checks\n    var type = typeof a;\n    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;\n    return deepEq(a, b, aStack, bStack);\n  };\n\n  // Internal recursive comparison function for `isEqual`.\n  deepEq = function(a, b, aStack, bStack) {\n    // Unwrap any wrapped objects.\n    if (a instanceof _) a = a._wrapped;\n    if (b instanceof _) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, regular expressions, dates, and booleans are compared by value.\n      case '[object RegExp]':\n      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN.\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n      case '[object Symbol]':\n        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);\n    }\n\n    var areArrays = className === '[object Array]';\n    if (!areArrays) {\n      if (typeof a != 'object' || typeof b != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&\n                               _.isFunction(bCtor) && bCtor instanceof bCtor)\n                          && ('constructor' in a && 'constructor' in b)) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var keys = _.keys(a), key;\n      length = keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (_.keys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = keys[length];\n        if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  };\n\n  // Perform a deep comparison to check if two objects are equal.\n  _.isEqual = function(a, b) {\n    return eq(a, b);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _.isEmpty = function(obj) {\n    if (obj == null) return true;\n    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;\n    return _.keys(obj).length === 0;\n  };\n\n  // Is a given value a DOM element?\n  _.isElement = function(obj) {\n    return !!(obj && obj.nodeType === 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _.isArray = nativeIsArray || function(obj) {\n    return toString.call(obj) === '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _.isObject = function(obj) {\n    var type = typeof obj;\n    return type === 'function' || type === 'object' && !!obj;\n  };\n\n  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet.\n  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name) {\n    _['is' + name] = function(obj) {\n      return toString.call(obj) === '[object ' + name + ']';\n    };\n  });\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  if (!_.isArguments(arguments)) {\n    _.isArguments = function(obj) {\n      return has(obj, 'callee');\n    };\n  }\n\n  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,\n  // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).\n  var nodelist = root.document && root.document.childNodes;\n  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {\n    _.isFunction = function(obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  // Is a given object a finite number?\n  _.isFinite = function(obj) {\n    return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj));\n  };\n\n  // Is the given value `NaN`?\n  _.isNaN = function(obj) {\n    return _.isNumber(obj) && isNaN(obj);\n  };\n\n  // Is a given value a boolean?\n  _.isBoolean = function(obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  };\n\n  // Is a given value equal to null?\n  _.isNull = function(obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  // Shortcut function for checking if an object has a given property directly\n  // on itself (in other words, not on a prototype).\n  _.has = function(obj, path) {\n    if (!_.isArray(path)) {\n      return has(obj, path);\n    }\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      var key = path[i];\n      if (obj == null || !hasOwnProperty.call(obj, key)) {\n        return false;\n      }\n      obj = obj[key];\n    }\n    return !!length;\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _.noConflict = function() {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iteratees.\n  _.identity = function(value) {\n    return value;\n  };\n\n  // Predicate-generating functions. Often useful outside of Underscore.\n  _.constant = function(value) {\n    return function() {\n      return value;\n    };\n  };\n\n  _.noop = function(){};\n\n  // Creates a function that, when passed an object, will traverse that object’s\n  // properties down the given `path`, specified as an array of keys or indexes.\n  _.property = function(path) {\n    if (!_.isArray(path)) {\n      return shallowProperty(path);\n    }\n    return function(obj) {\n      return deepGet(obj, path);\n    };\n  };\n\n  // Generates a function for a given object that returns a given property.\n  _.propertyOf = function(obj) {\n    if (obj == null) {\n      return function(){};\n    }\n    return function(path) {\n      return !_.isArray(path) ? obj[path] : deepGet(obj, path);\n    };\n  };\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  _.matcher = _.matches = function(attrs) {\n    attrs = _.extendOwn({}, attrs);\n    return function(obj) {\n      return _.isMatch(obj, attrs);\n    };\n  };\n\n  // Run a function **n** times.\n  _.times = function(n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  };\n\n  // Return a random integer between min and max (inclusive).\n  _.random = function(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  };\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  _.now = Date.now || function() {\n    return new Date().getTime();\n  };\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  var unescapeMap = _.invert(escapeMap);\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + _.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n  _.escape = createEscaper(escapeMap);\n  _.unescape = createEscaper(unescapeMap);\n\n  // Traverses the children of `obj` along `path`. If a child is a function, it\n  // is invoked with its parent as context. Returns the value of the final\n  // child, or `fallback` if any child is undefined.\n  _.result = function(obj, path, fallback) {\n    if (!_.isArray(path)) path = [path];\n    var length = path.length;\n    if (!length) {\n      return _.isFunction(fallback) ? fallback.call(obj) : fallback;\n    }\n    for (var i = 0; i < length; i++) {\n      var prop = obj == null ? void 0 : obj[path[i]];\n      if (prop === void 0) {\n        prop = fallback;\n        i = length; // Ensure we don't continue iterating.\n      }\n      obj = _.isFunction(prop) ? prop.call(obj) : prop;\n    }\n    return obj;\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _.uniqueId = function(prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _.templateSettings = {\n    evaluate: /<%([\\s\\S]+?)%>/g,\n    interpolate: /<%=([\\s\\S]+?)%>/g,\n    escape: /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\": \"'\",\n    '\\\\': '\\\\',\n    '\\r': 'r',\n    '\\n': 'n',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escapeRegExp = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n\n  var escapeChar = function(match) {\n    return '\\\\' + escapes[match];\n  };\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  _.template = function(text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = _.defaults({}, settings, _.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);\n      index = offset + match.length;\n\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offset.\n      return match;\n    });\n    source += \"';\\n\";\n\n    // If a variable is not specified, place data values in local scope.\n    if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + 'return __p;\\n';\n\n    var render;\n    try {\n      render = new Function(settings.variable || 'obj', '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    var template = function(data) {\n      return render.call(this, data, _);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    var argument = settings.variable || 'obj';\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n\n    return template;\n  };\n\n  // Add a \"chain\" function. Start chaining a wrapped Underscore object.\n  _.chain = function(obj) {\n    var instance = _(obj);\n    instance._chain = true;\n    return instance;\n  };\n\n  // OOP\n  // ---------------\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n\n  // Helper function to continue chaining intermediate results.\n  var chainResult = function(instance, obj) {\n    return instance._chain ? _(obj).chain() : obj;\n  };\n\n  // Add your own custom functions to the Underscore object.\n  _.mixin = function(obj) {\n    _.each(_.functions(obj), function(name) {\n      var func = _[name] = obj[name];\n      _.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return chainResult(this, func.apply(_, args));\n      };\n    });\n    return _;\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _.mixin(_);\n\n  // Add all mutator Array functions to the wrapper.\n  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      var obj = this._wrapped;\n      method.apply(obj, arguments);\n      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];\n      return chainResult(this, obj);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  _.each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      return chainResult(this, method.apply(this._wrapped, arguments));\n    };\n  });\n\n  // Extracts the result from a wrapped and chained object.\n  _.prototype.value = function() {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxy for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;\n\n  _.prototype.toString = function() {\n    return String(this._wrapped);\n  };\n\n  // AMD registration happens at the end for compatibility with AMD loaders\n  // that may not enforce next-turn semantics on modules. Even though general\n  // practice for AMD registration is to be anonymous, underscore registers\n  // as a named module because, like jQuery, it is a base library that is\n  // popular enough to be bundled in a third party lib, but not be part of\n  // an AMD load request. Those cases could generate an error when an\n  // anonymous define() is called outside of a loader request.\n  if (typeof define == 'function' && define.amd) {\n    define('underscore', [], function() {\n      return _;\n    });\n  }\n}());\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","\"use strict\";\nvar updatePlot = require('./update.js');\nvar utils = require('./utils.js');\nvar _ = require('underscore');\n\n\nfunction processData(dataObj) {\n    // plotly doesn't support the 'T' date/time separator or the 'Z' at the end\n    // https://help.plot.ly/date-format-and-time-series/#step-2-entering-dates-and-times-in-plotly-s-grid\n    var dates = _.map(dataObj.timestamps, function(date){return date.replace(\"T\",' ').substring(0, date.length-1)});\n    var allData = {\n        dates: dates,\n    };\n    _.extend(allData, dataObj.data);\n    return allData;\n}\n\n\nfunction plotting(dataCache, url, var_names, plotsInfo, div, update, maxPoints, err_callback) {\n    //gets information and updates component\n    $.ajax({\n            type: 'GET',\n            url: url,\n            jsonp: \"callback\",\n            dataType: \"jsonp\",\n\n            success: function(dataObj) {\n                if (dataObj.code != 200) {\n                    console.error(\"Invalid data API query. Code: {0} | Message: {1}\".format(\n                        dataObj.code, dataObj.message));\n                    if (err_callback !== undefined) {\n                        // stop the update timer if specified\n                        err_callback(plotsInfo);\n                    }\n                    return;\n                }\n\n                var graphDiv = document.getElementById(div);\n                var allData = processData(dataObj['results']);\n                // var existingDates = graphDiv.data[0]['x'];\n                var existingDates = dataCache[0]['x'] || [];\n                var dates = allData['dates'];\n                dataObj = {\n                    dates: dates\n                };\n\n                if (dataObj.dates.length == 0) {\n                    console.warn(\"No data available from API\");\n                    return;\n                }\n\n                if (update) {\n                    // first index in the new data that is actually new\n                    var startIndex = 0;\n                    // update only dates that aren't already included\n                    // assume that we don't have any missing dates in the middle\n                    while (startIndex < dates.length && dates[startIndex] <= existingDates[existingDates.length - 1]) {\n                        startIndex++;\n                    }\n\n                    // subset the data if needed\n                    if (startIndex >= dates.length) {\n                        console.info(\"No new data downloaded\");\n                        return;\n                    } else {\n                        for (var i = 0; i < var_names.length; i++) {\n                            dataObj[var_names[i]] = allData[var_names[i]].slice(startIndex);\n                        }\n                        dates = dates.slice(startIndex);\n                        dataObj.dates = dates;\n                    }\n                } else {\n                    // replace the entire data array\n                    for (var i = 0; i < var_names.length; i++) {\n                        dataObj[var_names[i]] = allData[var_names[i]];\n                    }\n                }\n\n                // Update data with\n                updatePlot.updatePlot(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints);\n            }\n    });\n}\n\n\n// 1. the minimum time period (in milliseconds) that a request must cover in order to use\n// 2. MetObs Data API interval specifier\n// 3. reasonable update interval for API given this data interval\nconst intervalLookUp = [\n    // 1 day for 5 minutes\n    [1000*60*60*24, '5m', '-00:10:00'],\n    // 1 month for 1 hour\n    [1000*60*60*24*30*1, '1h', '-02:00:00'],\n    // anything else is 1 minute\n];\n\nconst intervalToSeconds = {\n    '1m': 60,\n    '5m': 60 * 5,\n    '1h': 60 * 60,\n};\n\n\nfunction varNamesForDiv(dataCache) {\n    var varNames = [];\n    _.each(dataCache, function(trace_data) {\n        Array.prototype.push.apply(varNames, trace_data.var_names);\n        if ('anc_variables' in trace_data) {\n            Array.prototype.push.apply(varNames, trace_data.anc_variables);\n        }\n    });\n    return _.uniq(varNames);\n}\n\n\n//poorly ordered function parameters\nfunction requestPlotUpdate(dataCache, div, plotsInfo, startTime, endTime, interval, update, err_callback) {\n    var varNames = varNamesForDiv(dataCache);\n    var stream_string = '';\n    var dt_in_ms;\n    var time_parts;\n    var maxPoints;\n    var time;\n    for (var i in varNames) {\n        stream_string += varNames[i];\n        if (i < varNames.length - 1) stream_string += ':';\n    }\n\n    if (!endTime) {\n        interval = '1m';\n        // hours, minutes, seconds\n        time_parts = _.map(startTime.split(':'), Number);\n        dt_in_ms = -1000 * 60 * 60 * time_parts[0] + 1000 * 60 * time_parts[1] + 1000 * time_parts[2];\n        for (var i in intervalLookUp) {\n            if (dt_in_ms >= intervalLookUp[i][0]) {\n                interval = intervalLookUp[i][1];\n\n                if (update) {\n                    // we only want new data, the passed startTime was only\n                    // used to determine the interval\n                    startTime = intervalLookUp[i][2];\n                }\n            }\n        }\n        time = '&begin=' + startTime;\n    } else {\n        time = '&begin=' + startTime + '&end=' + endTime;\n        if (interval == 'auto') {\n            interval = '1m';\n            dt_in_ms = (new Date(endTime)) - (new Date(startTime));\n            for (var i in intervalLookUp) {\n                if (dt_in_ms >= intervalLookUp[i][0])\n                    interval = intervalLookUp[i][1];\n            }\n        }\n    }\n\n\n    // Maximum number of points (fallback to arbitrary 250)\n    if (update) {\n        maxPoints = intervalToSeconds.hasOwnProperty(interval) ? dt_in_ms / 1000 / intervalToSeconds[interval] : 250;\n    } else {\n        maxPoints = 0; // delete all previous data\n    }\n    var url = utils.buildRequestUrl('json', interval, '', '', 'column', time, stream_string);\n    plotting(dataCache, url, varNames, plotsInfo, div, update, maxPoints, err_callback);\n    return interval;\n}\n\n\n//export functions\nmodule.exports.requestPlotUpdate = requestPlotUpdate;\n","\"use strict\";\nvar Plotly = require('Plotly');\nvar loading = require('../ui/loading.js');\n\n\nfunction getSecondAxisConfig(axis_number, plot_info, axis_info, axis_kwargs) {\n    var key;\n    var axis_config = {\n        gridcolor: '#777777',\n        titlefont: {'size' : 12},\n        title: axis_info['title'],\n        zeroline: false,\n        overlaying: 'y' + (axis_number - 1).toString(),\n        side: 'right',\n        anchor: 'x',\n    };\n\n    for (var idx=0; idx < axis_kwargs.length; idx++) {\n        key = axis_kwargs[idx];\n        if (key in axis_info) {\n            axis_config[key] = axis_info[key];\n        }\n    }\n    return axis_config;\n}\n\n\nfunction initPlot(dataCache, div_id, plotOrder, plotsInfo) {\n    var DEFAULT_PLOT_HEIGHT = 170;\n    var nshowing = plotOrder.length;\n    var layout = {\n        title: plotsInfo.title,\n        showlegend: false,\n        height: DEFAULT_PLOT_HEIGHT * nshowing + 180,\n    };\n\n    layout['xaxis'] = {\n        //domain affects size of x axis\n        //this made room for the legend\n        //1 is the far right of the plot, 0 is the far left\n        domain: [0, 1],\n\n        //xaxis doesn't show its lines\n        showline: false,\n        zeroline: false,\n\n        //values of the tick labels show up\n        //show right away if we have any starting streams\n        showticklabels: nshowing > 0,\n\n        //its grid is a little darker than default\n        gridcolor : \"#777777\",\n\n        //hide grid\n        showgrid: false,\n        tickformat: '%Y-%m-%d %H:%MZ'\n    };\n\n    var axis_number = 0;\n    var axis_info;\n    var plot_info;\n    var trace_info;\n    var trace_config;\n    var axis_config;\n    var plot_key;\n    var key;\n    var step = 1 / nshowing;\n    var domain;\n    var x_anchor = axis_number;\n    var trace_kwargs = ['color', 'mode', 'zmin', 'zmax', 'y',\n        'contours', 'line', 'colorscale', 'showscale', 'colorbar', 'tick0', 'dtick', 'hovermode'];\n    var axis_kwargs = ['nticks', 'range', 'autorange', 'zeroline', 'showgrid',\n        'tickmode', 'ticktext', 'tickvals'];\n    for (var plot_idx=0; plot_idx < plotOrder.length; plot_idx++) {\n        plot_key = plotOrder[plot_idx];\n        plot_info = plotsInfo.plots[plot_key];\n        axis_number += 1;\n        x_anchor = axis_number;\n        axis_info = plot_info.yaxis;\n        domain = [(plotOrder.length - 1 - plot_idx) * step * 1.03,\n            1 - plot_idx * step * 1.05];\n\n        // Create the necessary traces (lines)\n        for (var trace_info_idx=0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {\n            trace_info = plot_info.traces[trace_info_idx];\n            trace_config = {\n                name: trace_info['name'],\n                x: [],\n                y: [],\n                text: [],\n                type: trace_info.type ? trace_info.type : 'scatter',\n                xaxis: 'x1',\n                yaxis: 'y' + axis_number,\n                hoverinfo: 'x+text',\n                hovermode: 'closest',\n                // meteorogram custom data flags\n                var_names: trace_info['var_names'],\n                anc_variables: trace_info['anc_variables'],\n                anc_data: [],\n                plot_name: plot_key,\n                trace_index: trace_info_idx,\n            };\n\n            // when we have a second trace that is purely there to make the\n            // second y-axis appear, we do this to point the trace to the\n            // correct axis\n            if (trace_info.isSecondAxis) {\n                trace_config.yaxis = 'y' + (axis_number + trace_info_idx);\n            }\n\n            for (var idx=0; idx < trace_kwargs.length; idx++) {\n                key = trace_kwargs[idx];\n                if (key in trace_info) {\n                    trace_config[key] = trace_info[key];\n                }\n            }\n            if ('colorbar' in trace_config) {\n                trace_config.colorbar.len = domain[1] - domain[0];\n                trace_config.colorbar.y = (domain[1] - domain[0]) / 2 + domain[0];\n                trace_config.z = [];\n            }\n            dataCache.push(trace_config);\n        }\n\n        // Create Y-axis configuration object\n        axis_config = {\n            gridcolor: '#777777',\n            titlefont: {'size' : 12},\n            title: axis_info['title'],\n            zeroline: false,\n            // where on the canvas does this axis belong\n            domain: [\n                (plotOrder.length - 1 - plot_idx) * step * 1.03,\n                1 - plot_idx * step * 1.05\n            ],\n        };\n\n        for (idx=0; idx < axis_kwargs.length; idx++) {\n            key = axis_kwargs[idx];\n            if (key in axis_info) {\n                axis_config[key] = axis_info[key];\n            }\n        }\n\n        layout['yaxis' + axis_number] = axis_config;\n\n        // Process second y-axis config\n        // Skip if specified meaning this configuration is only parsed\n        // for additional hover/probe information (custom MetObs thing, not Plotly)\n        if ('yaxis2' in plot_info && !plot_info.yaxis2.skip) {\n            axis_number += 1;\n            axis_info = plot_info.yaxis2;\n            axis_config = getSecondAxisConfig(axis_number, plot_info, axis_info, axis_kwargs);\n            layout['yaxis' + axis_number] = axis_config;\n        }\n        // MetObs custom way of saying \"I want more probe information\n        // if ('probe2' in plot_info) {\n        //     axis_number += 1;\n        //     axis_info = plot_info.probe2;\n        //     axis_config = getSecondAxisConfig(axis_number, plot_info, axis_info, axis_kwargs);\n        //     layout['probe' + axis_number] = axis_config;\n        // }\n    }\n    // xaxis only shows on the bottom most plot\n    layout['xaxis']['anchor'] = 'y' + x_anchor;\n\n    // Toolbar configuration\n    var toolbar = {\n        // Disable link to plotly\n        'showLink': false,\n        // Don't show plotly logo\n        'displaylogo': false,\n        'displayModeBar': true,\n        'responsive': true\n    };\n\n    //creates new graph\n    Plotly.plot(div_id, dataCache, layout, toolbar);\n    loading.loading();\n}\n\nmodule.exports.initPlot = initPlot;\n","\"use strict\";\nvar ticktext = require('./ticks.js');\nvar utils = require('./utils.js');\n\n/* \n * Build a table in the specified div with a row for each trace in plotsInfo\n * Stores metadata for each trace using $.data, which is retrieved\n * and used by requestTableUpdate\n */\nfunction initTable(div_id, plotOrder, plotsInfo) {\n    var div = $('#'+div_id);\n    var table = $('<table class=\"met_table\"><tbody></tbody></table>');\n    var tbody = table.children('tbody');\n\n    var plot_info;\n    var plot_key;\n    for (var plot_idx=0; plot_idx < plotOrder.length; plot_idx++) {\n        plot_key = plotOrder[plot_idx];\n        plot_info = plotsInfo.plots[plot_key];\n        //extract the necessary variables\n        for (var trace_info_idx=0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {\n            var trace_info = plot_info.traces[trace_info_idx];\n            if(trace_info.type=='contour'){\n                add_contour_rows(tbody,plot_key,trace_info_idx,trace_info,plot_info);\n            }else{\n                var info_td = $('<td>N/A</td>');\n                info_td.addClass('met_data');\n                info_td.data('info', {key:plot_key,idx:trace_info_idx});\n                var row = $('<tr></tr>');\n                var name = trace_info.short_name || trace_info.name;\n                row.append('<td>'+name+'</td>');\n                row.append(info_td);\n                row.append('<td class=\"convert\"></td>');\n                tbody.append(row);\n                //add rows for our ancillary variables that normally only show up in tags\n                if(trace_info.anc_variables)\n                    add_anc_rows(tbody,plot_key,trace_info_idx,trace_info);\n            }\n        };\n    }\n    div.append('<h3>'+plotsInfo.title+'</h3>');\n    div.append(table);\n    div.append('<span id=\"timestamp\"></span>');\n};\n\nfunction add_anc_rows(tbody,plot_key,idx,trace_info){\n    for(var anc_info_idx = 0; anc_info_idx < trace_info.anc_variables.length; anc_info_idx++){\n        var anc_info = trace_info.anc_info[trace_info.anc_variables[anc_info_idx]];\n        var info_td = $('<td>N/A</td>');\n        info_td.addClass('met_data');\n        info_td.data('info', {key:plot_key,idx:idx,anc_idx:anc_info_idx});\n        var row = $('<tr></tr>');\n        var name = anc_info.short_name || anc_info.name;\n        row.append('<td>'+name+'</td>');\n        row.append(info_td);\n        row.append('<td class=\"convert\"></td>');\n        tbody.append(row);\n    }\n\n}\n\nfunction add_contour_rows(tbody,plot_key,idx,trace_info,plot_info){\n    var name = trace_info.short_name||trace_info.name;\n    var title_row=('<tr><td colspan=\"2\">'+name+'</td><td></td>');\n    tbody.append(title_row);\n    for(var hightlight_idx = 0;hightlight_idx< trace_info.y_highlight.length;hightlight_idx++){\n        var hightlight_idx_idx = trace_info.y_highlight[hightlight_idx];\n        var row = $('<tr></tr>');\n        var name = trace_info.y[hightlight_idx_idx] + plot_info.yaxis.units;\n        row.append('<td class=\"subtitle text-center\">'+name+'</td>');\n        var info_td = $('<td>N/A</td>');\n        info_td.addClass('met_data');\n        info_td.data('info', {key:plot_key,idx:idx,hl_idx:hightlight_idx_idx});\n        row.append(info_td);\n        row.append('<td class=\"convert\"></td>');\n        tbody.append(row);\n    }\n\n}\n\n/* \n * Build a datastream request from the data tags in div_id's existing meteorogram table,\n * then add labels and alternate units based on the axes objects in plotsInfo\n */\nfunction requestTableUpdate(div_id,plotsInfo) {\n    var div = $('#'+div_id);\n    var varNames = [];\n    var plotOrder = [];\n    var data_cells = $('#'+div_id+' .met_data');\n    var convert_cells = $('#'+div_id+' .convert');\n    data_cells.each(function(){\n            var key = $(this).data('info').key;\n            var trace_idx = $(this).data('info').idx;\n            var anc_idx = $(this).data('info').anc_idx;\n            var hl_idx = $(this).data('info').hl_idx;\n            var trace = plotsInfo.plots[key].traces[trace_idx];\n            if(plotOrder.indexOf(key)==-1)\n                plotOrder.push(key);\n            if(anc_idx !== undefined)\n                varNames.push(trace.anc_variables[0]);\n            else if(hl_idx !== undefined)\n                varNames.push(trace.var_names[hl_idx]);\n            else\n                varNames.push(trace.var_names[0]);\n    });\n    var stream_string = varNames.join(':'); \n    //Use a set time that has both buoy and tower records for testing\n    var url = utils.buildRequestUrl('json', '1m', '', '', 'column', '&begin=-00:04:00', stream_string);\n    $.ajax({\n            type: 'GET',\n            url: url,\n            jsonp: \"callback\",\n            dataType: \"jsonp\",\n            success: function(dataObj){\n                dataObj.div_id = div_id;\n                dataObj.plotOrder = plotOrder;\n                dataObj.data_cells = data_cells;\n                dataObj.convert_cells = convert_cells;\n                updateTable(dataObj,plotsInfo);\n            }\n    });\n}\n\nfunction updateTable(dataObj,plotsInfo) {\n    var data = dataObj.results.data;\n    var plot_info;\n    var plot_key;\n    var td_idx = 0;\n    var div_id = dataObj.div_id;\n    var plotOrder = dataObj.plotOrder;\n    var data_cells = dataObj.data_cells;\n    var convert_cells = dataObj.convert_cells;\n    if(dataObj.num_results==0){\n        $('#'+div_id+' #timestamp').html('No recent data');\n        return;\n    }\n    $('#'+div_id+' #timestamp').html('Last updated: '+ dataObj.results.timestamps[0]);\n    for (var plot_idx=0; plot_idx < plotOrder.length; plot_idx++) {\n        plot_key = plotOrder[plot_idx];\n        plot_info = plotsInfo.plots[plot_key];\n        //Fill in a row for each trace in the plot\n        for (var trace_info_idx=0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {\n            var trace_info = plot_info.traces[trace_info_idx];\n            if (trace_info.type=='contour') {\n                td_idx=update_contour_cells(data,data_cells,convert_cells,trace_info,td_idx);\n            } else {\n                var update_val = data[trace_info['var_names'][0]][0]; \n                if(update_val || update_val==0){\n                    var units = plot_info.yaxis.units;\n                    var convert = '';\n                    var old_precision = plot_info.yaxis.precision;\n                    plot_info.yaxis.precision=Math.min(old_precision,1);\n                    var orig_val = ticktext.getTickText([update_val],plot_info.yaxis);\n                    plot_info.yaxis.precision = old_precision;\n                    if(plot_info.yaxis2 && plot_info.yaxis2.convert_value){\n                        var convert_units = plot_info.yaxis2.units;\n                        var old_precision = plot_info.yaxis2.precision;\n                        plot_info.yaxis2.precision= Math.min(old_precision,1);\n                        var convert_val = ticktext.getTickText([update_val],plot_info.yaxis2);\n                        plot_info.yaxis2.precision = old_precision;\n                        convert = convert_val+convert_units;\n                    }\n                    data_cells[td_idx].innerHTML=orig_val+units;\n                    convert_cells[td_idx].innerHTML=convert;\n                } else {\n                    data_cells[td_idx].innerHTML='N/A';\n                    convert_cells[td_idx].innerHTML='';\n                }\n                td_idx+=1;\n                //Fill in a row for each anc_var in the plot\n                if (trace_info.anc_variables) {\n                    td_idx=update_anc_cells(data,data_cells,trace_info,td_idx);\n                }\n            }\n        }\n    }\n}\n\n\nfunction update_contour_cells(data,data_cells,convert_cells,trace_info,td_idx){\n    for(var hightlight_idx = 0;hightlight_idx< trace_info.y_highlight.length;hightlight_idx++){\n        var hightlight_idx_idx = trace_info.y_highlight[hightlight_idx];\n        var update_val = data[trace_info['var_names'][hightlight_idx_idx]][0];\n        var units = trace_info.zprobe.units;\n        var orig_val = ticktext.getTickText([update_val],trace_info.zprobe);\n        var convert = '';\n        if(trace_info.zprobe2 && trace_info.zprobe2.convert_value){\n            var convert_units = trace_info.zprobe2.units;\n            var convert_val = ticktext.getTickText([update_val],trace_info.zprobe2);\n            convert = convert_val+convert_units;\n        }\n        data_cells[td_idx].innerHTML=orig_val+units;\n        convert_cells[td_idx].innerHTML=convert;\n        td_idx+=1;\n    }\n    return td_idx;\n}\n\nfunction update_anc_cells(data,data_cells,trace_info,td_idx){\n    for(var anc_info_idx = 0; anc_info_idx < trace_info.anc_variables.length; anc_info_idx++){\n        var anc_key = trace_info.anc_variables[anc_info_idx];\n        var anc_info = trace_info.anc_info[anc_key];\n        var update_val = data[anc_key][0];\n        var orig_val = ticktext.getTickText([update_val],anc_info);\n        if(update_val || update_val==0)\n            data_cells[td_idx].innerHTML=orig_val+anc_info.units;\n        else\n            data_cells[td_idx].innerHTML='N/A';\n        td_idx+=1;\n    }\n    return td_idx;\n}\nmodule.exports.initTable = initTable; \nmodule.exports.requestTableUpdate = requestTableUpdate; \n","var _ = require('underscore');\n\n// Add string formatting if it doesn't exist\nif (!String.prototype.format) {\n  String.prototype.format = function() {\n    var args = arguments;\n    return this.replace(/{(\\d+)}/g, function(match, number) {\n      return typeof args[number] != 'undefined'\n        ? args[number]\n        : match\n      ;\n    });\n  };\n}\n\nfunction getWaterTempProbe(data, plotInfo, traceInfo, allData) {\n    var allProbeText = [];\n    var probeText;\n    var row, col;\n    var rowText;\n    var depth;\n    for (var j=0; j < data.length; j++) {\n        row = data[j];\n        rowText = [];\n        depth = traceInfo.y[j];\n        for (var i=0; i < row.length; i++) {\n            col = row[i];\n\n            probeText = \"Depth: {0}m<br>{1}: {2} °C ({3} °F)\".format(\n                depth.toFixed(1),\n                traceInfo.name,\n                col !== null ? col.toFixed(3) : \"N/A\",\n                col !== null ? getF(col).toFixed(3) : \"N/A\");\n            rowText.push(probeText);\n        }\n        allProbeText.push(rowText);\n    }\n    return allProbeText;\n}\n\nfunction getSpeedMPH(val) {\n    // convert m/s to mph\n    return val * 3600 / 1608;\n}\nfunction getSpeedKTS(val) {\n    //m/s to knots\n    return val * 1.94384;\n}\n\n\nfunction getPresInHg(val) {\n    // hPa to InHg\n    return val * 0.02952998751;\n}\n\n\nfunction getAccumMillimeter(val) {\n    // convert inches to millimeters\n    return val * 25.4;\n}\n\n\nfunction cardinalWDir(degrees){\n    \n    return ['N','NNE','NE','ENE',\n            'E','ESE','SE','SSE',\n            'S','SSW','SW','WSW',\n            'W','WNW','NW','NNW'][Math.floor(((degrees+11.25)%360)/22.5)];\n}\n// Convert C to F degrees\nfunction getF(val) {\n    return val * 1.8 + 32;\n}\n\nfunction getVal(val) {\n    return val;\n}\n\n\nvar CONVERSION_FUNCTIONS = {\n    null: getVal,\n    undefined: getVal,\n    getF: getF,\n    getPresInHg: getPresInHg,\n    getSpeedMPH: getSpeedMPH,\n    getAccumMillimeter: getAccumMillimeter,\n    cardinalWDir: cardinalWDir,\n    getSpeedKTS:getSpeedKTS\n};\n\n\n\nfunction formatValue(val, plotInfo, traceInfo) {\n    var val2;\n    if (val === null) {\n        val = \"\";\n        val2 = \"\";\n    } else {\n        if ('yaxis2' in plotInfo && 'convert_value' in plotInfo.yaxis2) {\n            val2 = CONVERSION_FUNCTIONS[plotInfo.yaxis2.convert_value](val);\n            val2 = (val2.toFixed)?val2.toFixed(plotInfo.yaxis2.precision):val2;\n        } else {\n            val2 = undefined;\n        }\n        val = CONVERSION_FUNCTIONS[plotInfo.yaxis.convert_value](val);\n        val=(val.toFixed)?val.toFixed(plotInfo.yaxis.precision):val;\n    }\n\n    if ('yaxis2' in plotInfo && val2 !== undefined) {\n        return \"{0}: {1}{2} ({3}{4})\".format(\n            traceInfo.name,\n            val, plotInfo.yaxis.units,\n            val2, plotInfo.yaxis2.units);\n    } else {\n        return \"{0}: {1}{2}\".format(\n            traceInfo.name,\n            val, plotInfo.yaxis.units);\n    }\n}\n\nfunction getDewpointProbe(data, plotInfo, traceInfo, allData) {\n    var allProbeText = [];\n    var probeText;\n    var relHum = undefined;\n    if ('anc_variables' in traceInfo && traceInfo.anc_variables.length == 1) {\n        relHum = allData[traceInfo.anc_variables[0]];\n    }\n    var rh_info = traceInfo.anc_info[traceInfo.anc_variables[0]];\n    if(!rh_info)\n        rh_info={ name: traceInfo.anc_variables[0], units: '', precision: 2};\n\n    for (var i=0; i < data.length; i++) {\n        probeText = formatValue(data[i], plotInfo, traceInfo);\n        if (relHum !== undefined) {\n            probeText += \"<br>{0}: {1}{2}\".format(rh_info.name,\n                    relHum[i] ? relHum[i].toFixed(rh_info.precision) : \"\",\n                    rh_info.units);\n        }\n        allProbeText.push(probeText);\n    }\n    return allProbeText;\n}\n\n\nfunction defaultProbeText(data, plotInfo, traceInfo, allData) {\n    // assume traces share the same 'x'\n    var allProbeText = [];\n    for (var i=0; i < data.length; i++) {\n        allProbeText.push(formatValue(data[i], plotInfo, traceInfo));\n    }\n    return allProbeText;\n}\n\n\nvar PROBE_TEXT_FUNCTIONS = {\n    undefined: defaultProbeText,\n    null: defaultProbeText,\n    dewpoint: getDewpointProbe,\n    water_temp: getWaterTempProbe,\n};\n\n\nfunction getProbeText(data, plotInfo, traceInfo, allData) {\n    if ('probe_text' in traceInfo) {\n        return PROBE_TEXT_FUNCTIONS[traceInfo.probe_text](data, plotInfo, traceInfo, allData);\n    }\n    return defaultProbeText(data, plotInfo, traceInfo, allData);\n}\n\n\nfunction getTickText(values, axis_info) {\n    var tickText = [];\n    for (var i=0; i < values.length; i++) {\n        var val = CONVERSION_FUNCTIONS[axis_info.convert_value](values[i]);\n        val = (val.toFixed)?val.toFixed(axis_info.precision):val;\n        tickText.push(val);\n    }\n    return tickText;\n}\n\n\n/**\n* the purpose of this method is to get the spacing for the y axis\n* For deg F and deg C\n* @param min - minimum of the temp or dew point array\n* @param max - maximum of the temp or dew point array\n* @return array of 4 tick values for the y axis\n*/\n\nfunction getTickVals(min, max, bump) {\n    var extra = (max - min) * 0.02;\n    min = min - extra;\n    max = max + extra;\n    var step = (max - min) / 4.;\n    //create 4 tick values for the y axis\n    return _.range(min, max + step, step);\n}\n\n\nmodule.exports.getTickVals = getTickVals;\nmodule.exports.getProbeText = getProbeText;\nmodule.exports.getTickText = getTickText;\n\n\n\n\n","var Plotly = require('Plotly');\nvar ticktext = require('./ticks.js');\nvar _ = require('underscore');\n\n\nfunction removeOldPoints(dataCache, removeCount) {\n    for (var i = 0; i < dataCache.length; i++) {\n        dataCache[i].x.splice(0, removeCount);\n\n        if (dataCache[i].hasOwnProperty('z')) {\n            for (var j = 0; j < dataCache[i].z.length; j++) {\n                dataCache[i].z[j].splice(0, removeCount);\n            }\n        } else if (dataCache[i].hasOwnProperty('y')) {\n            // delete things from y *only* if we don't have a Z\n            dataCache[i].y.splice(0, removeCount);\n        }\n        if (dataCache[i].hasOwnProperty('text')) {\n            dataCache[i].text.splice(0, removeCount);\n        }\n    }\n}\n\n\nfunction replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints) {\n    var dates = dataObj.dates;\n    var plotName;\n    var plotInfo;\n    var i;\n    var probeText;\n    var plotHandled = [];\n    var forceRedraw = false;\n\n    // scatter updates\n    var tracesToExtend = [];\n    var extendData = {\n        x: [],\n        y: [],\n        text: [],\n    };\n\n    // contour updates\n    var newContourData;\n    var contourTracesToExtend = [];\n    var contourExtendData = {\n        x: [],\n        z: [],\n        text: [],\n    };\n\n    var traceIndex = 0;\n    /**\n     *\n     * If we are updating the plots instead of replacing them, then try\n     * to use plotly's extendTraces to update the x and y coordinates as well\n     * the hovering probe text. This should only add new trace points instead\n     * of updating all points.\n     *\n     * Since we passed 'dataCache' to plotly's 'plot' function during\n     * initialization any changes to 'dataCache' should be mirrored in Plotly's\n     * plot and vice versa. See the below stackoverflow question for details.\n     * https://stackoverflow.com/questions/45759582/plotly-how-to-discard-older-points\n     * This is important since we use `.shift()` on the data arrays to remove\n     * \"old\" elements.\n     *\n     * We have to operate per-plot because some of our plots hover/probe labels\n     * use the trace values to come up with one probe box\n     * (air temp + dewpoint -> relative humidity).\n     *\n     */\n    for (i = 0; i < dataCache.length; i++) {\n        plotName = dataCache[i].plot_name;\n        if (plotHandled[plotHandled.length - 1] == plotName) {\n            // this happens when there are more than one trace in a plot\n            continue;\n        }\n        plotInfo = plotsInfo.plots[plotName];\n        _.each(plotInfo.traces, function(traceInfo, index) {\n\n            if (dataCache[traceIndex + index].type == 'contour') {\n                // push new dates for each trace to be extended\n                contourExtendData.x.push(dates);\n                contourTracesToExtend.push(traceIndex + index);\n                // update the Z data instead of the traditional 'y' data\n                // assumes Y doesn't update between calls\n                newContourData = _.map(traceInfo.var_names, function(var_name) {return dataObj[var_name];});\n                dataCache[i].text.push(...ticktext.getProbeText(newContourData, plotInfo, traceInfo, dataObj));\n                for (var j = 0; j < traceInfo.var_names.length; j++) {\n                    while (j >= dataCache[i].z.length) {\n                        dataCache[i].z.push([]);\n                    }\n                    dataCache[i].z[j].push(...dataObj[traceInfo.var_names[j]]);  // ES6-style push\n                }\n                contourExtendData.z.push(dataCache[i].z);\n                contourExtendData.text.push(dataCache[i].text);\n                // If plotly could handle extendTraces in the x-dimension we'd\n                // probably do something like this:\n                // newContourData = _.map(traceInfo.var_names, function(var_name) {return dataObj[var_name];});\n                // contourExtendData.z.push(newContourData);\n                // contourExtendData.text.push(\n                //     [ticktext.getProbeText(newContourData, plotInfo, traceInfo, dataObj)]\n                // );\n            } else {\n                // push new dates for each trace to be extended\n                extendData['x'].push(dates);\n                tracesToExtend.push(traceIndex + index);\n                // scatter plots, assume the y data is the data being updated\n                _.each(traceInfo.var_names, function (var_name) {\n                    // push the entire new data array as one element to update\n                    extendData.y.push(dataObj[var_name]);\n\n                    // Get new probe text shown when hovering over the traces\n                    if ('probe_text' in traceInfo && traceInfo['probe_text'] === null) {\n                        // we don't want probe text for this trace\n                        probeText = [undefined];\n                    } else {\n                        probeText = ticktext.getProbeText(dataObj[var_name], plotInfo, traceInfo, dataObj);\n                    }\n                    extendData.text.push(probeText);\n                });\n            }\n        });\n        traceIndex += plotInfo.traces.length;\n        plotHandled.push(plotName);\n    }\n\n    // Have plotly update the graph with the new points in extendData\n    // This will add data to 'dataCache' because of how we originally\n    // created the plots.\n    if (tracesToExtend.length > 0) {\n        Plotly.extendTraces(graphDiv, extendData, tracesToExtend);\n    }\n    if (contourTracesToExtend.length > 0) {\n        Plotly.extendTraces(graphDiv, contourExtendData, contourTracesToExtend);\n        // we are currently cheating and re-adding every \"row\" of data because\n        // plotly doesn't support extendTrace'ing in the x-dimension\n        // we want to remove the previous \"depth\" amount of rows\n        for (i = 0; i < contourTracesToExtend.length; i++) {\n            dataCache[contourTracesToExtend[i]].z.splice(0, dataCache[contourTracesToExtend[i]].y.length);\n            dataCache[contourTracesToExtend[i]].text.splice(0, dataCache[contourTracesToExtend[i]].y.length);\n        }\n    }\n\n    if (maxPoints == 0 && !update) {\n        // we aren't doing realtime updates and the caller wants us to remove\n        // all previous points and keep all new points\n        maxPoints = dataObj.dates.length;\n        // we have to force a redraw of the plot because the removed plots\n        // will still exist on the the graph otherwise (until the next update)\n        forceRedraw = true;\n    }\n    // If adding these new points gave us more points than we need\n    // remove the points at the beginning of our data\n    if (maxPoints > 0 && dataCache[0]['x'].length > maxPoints) {\n        removeOldPoints(dataCache, dataCache[0].x.length - maxPoints);\n    }\n\n    if (forceRedraw) {\n        Plotly.redraw(graphDiv);\n    }\n}\n\n\n\nfunction updatePlot(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints) {\n    replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints);\n}\n\nmodule.exports.updatePlot = updatePlot;\n","\"use strict\";\n\nfunction buildRequestUrl(format, interval, epoch, sep, order, time, streams) {\n    var request_url = METOBS_API_URL+'/api/data.'+format+'?';\n    request_url += 'interval='+interval;\n    request_url += '&epoch='+epoch;\n    request_url +='&sep='+sep || ',';\n    request_url += '&order='+order;\n    request_url+=time;\n    request_url+='&symbols='+streams;\n    return request_url;\n}\n\nmodule.exports.buildRequestUrl = buildRequestUrl;\n","const checkboxTemplates = {\n    'aoss.tower': '<div class=\"form-group\">'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"temp\">Temperature + Dewpoint'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"pres\">Pressure'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"wS\">Wind Speed'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"wD\">Wind Direction'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"aP\">Precipitation'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"sF\">Solar Flux'+\n        '</label>'+\n        '</div>',\n    'mendota.buoy': '<div class=\"form-group\">'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"temp\">Temperature + Dewpoint'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"rh\">Relative Humidity'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"wS\">Wind Speed'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"wD\">Wind Direction'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"chlor\">Chlorophyll'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"phyco\">Phycocyanin'+\n        '</label>'+\n        '</div>'\n};\n\nconst controlPanelTemplate = '<div class=\"row\" id=\"control-panel-row\">'+\n'<div id=\"show-hide-boxes\" class=\"col-md-12\">'+\n'</div>'+\n'<div class = \"col-md-9\">'+\n'<div class=\"row\" style=\"padding: 0 1em;\">'+\n'<div class=\"form-group\">'+\n'<table style=\"width:100%\">'+\n'<tr>'+\n'<td>'+\n'<div class=\"radio\">'+\n'<label><input type=\"radio\" id=\"last_x_days\" name=\"time_select\">'+\n'Recent Data:'+\n'</label>'+\n'</div>'+\n'</td>'+\n'<td>'+\n'<select class=\"form-control\" id=\"dropDownId\">'+\n'<option selected value=\"realtime\">Realtime Update</option>'+\n'<option value=\"-1:00:00\">Past 1 Hour</option>'+\n'<option value=\"-2:00:00\">Past 2 Hours</option>'+\n'<option value=\"-3:00:00\">Past 3 Hours</option>'+\n'<option value=\"-6:00:00\">Past 6 Hours</option>'+\n'<option value=\"-12:00:00\">Past 12 Hours</option>'+\n'<option value=\"-18:00:00\">Past 18 Hours</option>'+\n'<option value=\"-24:00:00\">Past 24 Hours</option>'+\n'<option value=\"-96:00:00\">Past 4 Days</option>'+\n'</select>'+\n'</td>'+\n'<td style=\"padding-left:.5em\">'+\n'<div class=\"radio\">'+\n'<label><input type=\"radio\" id=\"date_range\" name=\"time_select\">'+\n'Date Range:'+\n'</label>'+\n'</div>'+\n'</td>'+\n'<td>'+\n'<input class=\"form-control\" style=\"padding 0.5em 0;\" id=\"Start-date-picker\" type=\"text\" placeholder=\"YYYY-MM-DD\"/>'+\n'</td>'+\n'<td>to </td>'+\n'<td>'+\n'<input class=\"form-control\" style=\"padding 0.5em 0;\" id=\"End-date-picker\" type=\"text\" placeholder=\"YYYY-MM-DD\"/>'+\n'</td>'+\n'<td>'+\n'<button class=\"btn btn-primary btn-block\" id=\"plot-btn\">Plot</button>'+\n'</td>'+\n'</tr>'+\n'</table>'+\n'</div>'+\n'</div>'+\n'</div>'+\n'</div>'\n;\nmodule.exports = {\n    controlPanelTemplate:controlPanelTemplate,\n    checkboxTemplates:checkboxTemplates\n}\n","\"use strict\";\n\n//var $ = require('jquery');\n//var jQuery = require('jquery');\n\nvar loading = require('./loading.js');\nconst controlPanelTemplate = require('./button_template.js');\n\n/**\n* The purpose of this method is to tell dispatcher\n* Oh, please check if user's entering stuff correctly\n*\n* no params\n* no returns\n*/\n\nfunction dispatchCustom(dispatcher)\n{\n    dispatcher.dispatch({\n        status:'get_between_dates',\n        'emit':'plotEmitter',\n        'start':$('#Start-date-picker').val().split(' ').join('T')+':00',\n        'end':$('#End-date-picker').val().split(' ').join('T')+':00',\n        'interval':'auto',\n    });\n}\n\n\n/**\n* The purpose of this method is to send dispatcher user information\n*\n* no params\n* no returns\n*/\n\nfunction getUserInfo(dispatcher)\n{\n    //show gif\n    loading.loading();\n\n    //get the information from the text boxes\n    var startDate = $('#Start-date-picker').val();\n    var endDate = $('#End-date-picker').val();\n    var startTime = $('#Start-time-picker').val();\n    var endTime = $('#End-time-picker').val();\n    var interval = $('#interval option:selected');\n    var intervalVal = interval.data(\"name\");\n\n    //store in user info\n    var userInfo = {'startDate' : startDate,\n                    'startTime' : startTime,\n                    'endDate': endDate,\n                    'endTime': endTime,\n                    'interval': intervalVal};\n\n    //send to dispatcher\n    setTimeout(function() {dispatch.dispatch({status: 'plot_custom', 'emit': 'plotEmitter', 'userInfo': userInfo});}, 200);                 \n}\n\n\n/**\n* The purpose of this method is to tell dispatcher, time to check if we need to update\n*\n* no params\n* no returns\n*/\n\nfunction dispatchUpdate(dispatcher)\n{\n    dispatcher.dispatch({'status': 'update', 'emit': 'plotEmitter'});\n}\n\n/**\n* The purpose of this method is to figure out what the user wants to do based upon\n* what the user selects on the task dropdown\n*\n* no params\n* no returns\n*/\n\nfunction dropDown(selectedText, dispatcher) {\n    if (selectedText == 'realtime') {\n        dispatcher.dispatch({\n            status:'get_since_now',\n            'emit':'plotEmitter',\n            'time':'-3:00:00'\n        });\n\n    } else {\n        var timeDelta = selectedText;\n        dispatcher.dispatch({\n            status:'get_since_now',\n            'emit':'plotEmitter',\n            'time':selectedText\n        });\n    }\n}\n\nvar bind_daterange_actions = function(jQ_div,dispatcher){\n    //bind to custom buttons and dropdowns\n    $(jQ_div+' #plot-btn').click(function(){dispatchCustom(dispatcher)});\n    $(jQ_div+' #dropDownId').change(function(){dropDown($(this).val(),dispatcher)});\n}\nvar set_active_form = function(which_block,jQ_div){\n    $(jQ_div+\" #dropDownId\").prop(\"disabled\",which_block!=\"recent\");\n\n    $(jQ_div+\" #interval\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #Start-date-picker\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #End-date-picker\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #Start-time-picker\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #End-time-picker\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #plot-btn\").prop(\"disabled\",which_block!=\"range\");\n}\n\nvar set_form_datepickers = function(jQ_div){\n    $(jQ_div+' #Start-date-picker').datetimepicker({\n        changeMonth: true, \n        changeYear: true,\n        dateFormat:'yy-mm-dd',\n        timeFormat:'HH:mm',\n        showSecond:false,\n        showMillisec:false,\n        showMicrosec:false\n    });\n\n    $(jQ_div+' #End-date-picker').datetimepicker({\n        changeMonth: true, \n        changeYear: true,\n        dateFormat:'yy-mm-dd',\n        timeFormat:'HH:mm',\n        showSecond:false,\n        showMillisec:false,\n        showMicrosec:false\n    });\n\n    //bind the enabling/disabling of forms to radio buttons\n    $(jQ_div+' [type=text]').prop(\"disabled\",true);\n    $(jQ_div+' select').prop(\"disabled\",true);\n    $(jQ_div+\" #last_x_days\").click(function(){\n        set_active_form(\"recent\",jQ_div);\n    });\n    $(jQ_div+\" #date_range\").click(function(){\n        set_active_form(\"range\",jQ_div);\n    });\n    //$('#Start-time-picker').editableSelect();\n    //$('#End-time-picker').editableSelect();\n    //add placeholder values for the order forms    \n    //$('#Start-date-picker').attr('placeholder',moment.utc().subtract(5,'days').format('YYYY-MM-DD'));\n    //$('#End-date-picker').attr('placeholder',moment.utc().format('YYYY-MM-DD'));\n    //Firefox (+others maybe) keep buttons selected on page reload\n    //enable the currrently selected one's field\n    $(jQ_div+\" #last_x_days\").trigger('click');\n\n};\n\nvar setup_all_forms = function(div,plot_div,dispatcher){\n    var jQ_div = '#'+div;\n    set_form_datepickers(jQ_div,plot_div);\n    bind_daterange_actions(jQ_div,dispatcher);\n}\n\nfunction buildFormInDiv(div, plot_div,dispatcher) {\n    $('#'+div).append(controlPanelTemplate.controlPanelTemplate);\n    //$('#'+div+ \" #show-hide-boxes\").append(controlPanelTemplate.checkboxTemplates[site]);\n    setup_all_forms(div,plot_div,dispatcher);\n}\n$(document).ready(function(){\n    //Hide all form errors initially\n    //Set up the date range inputs as datepicker objects\n});\n\nmodule.exports = buildFormInDiv;\n","\"use strict\";\n//var $ = require('jquery');\n\n/**\n* The purpose of this function is to either hide the graph and show the loading\n* spinner or to hide the loading spinner and show the graph\n* no parameters or returns\n*/\n\nfunction loading()\n{\n    return;\n    //$(\"#progress\").toggle();\n    //$(\"#graph\").toggle();\n}\n\n/**\n* The point of this method is to disable the custom area of the meteorogram\n* header\n*\n* no params\n* no returns\n*/\n\nfunction disable()\n{\n\t//disable custom rows\n\t$('#Start-date-picker').prop(\"disabled\", true);\n\t$('#Start-time-picker').prop(\"disabled\", true);\n\t$('#End-date-picker').prop(\"disabled\", true);\n\t$('#End-time-picker').prop(\"disabled\", true);\n\t$('#interval').prop(\"disabled\", true);\n\t$('#Plot').prop(\"disabled\", true);\n}\n\n/**\n* The purpose of this method is to enable the custom area of the meteorogram\n* header\n*\n* no params\n* no returns\n*/\n\nfunction enable()\n{\n\t//enable custom rows\n\t$('#Start-date-picker').prop(\"disabled\", false);\n\t$('#Start-time-picker').prop(\"disabled\", false);\n\t$('#End-date-picker').prop(\"disabled\", false);\n\t$('#End-time-picker').prop(\"disabled\", false);\n\t$('#interval').prop(\"disabled\", false);\n}\n\n/**\n* The purpose of this function is to take a date string and a time string and turn that\n* into a date JS object\n*\n* @param dateString - \"MM/DD/YYYY\"\n* @param timeString - \"HH-MM-SS\"\n* @return date object\n*/\n\nfunction getDate(dateString, timeString)\n{\n\t//get date string\n\tvar year = parseInt(dateString.substring(6,10));\n\tvar month = parseInt(dateString.substring(0,3));\n\tvar day = parseInt(dateString.substring(3,5));\n\tvar hour = parseInt(timeString.substring(0,2));\n\tvar minute = parseInt(timeString.substring(3,5));\n\tvar seconds = parseInt(timeString.substring(6,8));\n\n    //return date variable\n    var date = new Date(year, month, day, hour, minute, seconds);\n\n    return date;\n}\n\n/**\n* The purpose of this method is to make sure each field is valid and does\n* not result in too much or too less data points being plotted\n* @param start date - the date the user wants to start at\n* @param time user wants to start at\n* @param end Date - the date user wants to stop at\n* @param end Time - the time the user wants to stop at\n* @param interval - how many seconds averaged does the user want\n* no returns\n*/\n\n/**\n* The purpsoe of this method is to enable the plot button\n*\n* no params\n* no returns\n*/\n\nfunction enablePlot()\n{\n\t//enable plot button\n\t$('#Plot').prop(\"disabled\", false);\n}\n\n/**\n* The purpose of this method is to disable the plot button\n*\n* no params\n* no returns\n*/\n\nfunction disablePlot()\n{\n\t//disable plot button\n\t$('#Plot').prop(\"disabled\", true);\n}\n\nfunction checkFields(startDate, endDate, startTime, endTime, interval)\n{\n\t//get user information from selected drop down\n\tvar selected = $('#interval option:selected');\n\n    //give user time to fill out other fields\n\tif(selected.text() == '--');\n\n\telse\n\t{\n\t\t//get information to create a message to the user saying approx how many pts\n\t\t//they are plotting\n        var start = getDate(startDate, startTime);\n        var end = getDate(endDate, endTime);\n        var selected = $('#interval option:selected');\n        var diff = (end - start)/1000;\n        var intervalVal = selected.data(\"seconds\");\n        diff = Math.floor(diff/intervalVal);\n        var points = diff/interval;\n\n        //if too few points, tell user\n        if(diff >= 0 && diff < 60)\n        {\n        \t$('#prompt_user').html('a ' + selected.text() + ' interval would plot about ' + diff.toString() \n        \t\t + ' data points; that\\'s too few - please try again');\n\t\t\t$('#default').attr('selected', 'selected');\n\t\t\tdisablePlot();\n        }\n\n        //if the user accidentally mixed up start and end dates, politely tell them\n        else if(diff < 0)\n        {\n        \t$('#prompt_user').html('The end date is before the start date. Please choose a later end date.');\n\t\t\t$('#default').attr('selected', 'selected');\n        }\n\n        //if too many points, tell user\n        else if(diff > 1000)\n        {\n        \t$('#prompt_user').html('a ' + selected.text() + ' interval would plot about '\n        \t\t+ diff.toString() + ' data points; that\\'s too many - please try again');\n\t\t\t$('#default').attr('selected', 'selected');\n\t\t\tdisablePlot();\n        }\n\n        //else we enable the plot button and tell user how many points they're plotting\n        else\n        {\n        \t$('#prompt_user').html('a ' + selected.text() + ' interval would plot about '\n        \t\t+ diff.toString() + ' data points.');\n\n\t\t\tenablePlot();\n        }\n\n\t}\n}\n\n/**\n* The purpose of this method is to make sure all the fields and intervals selected are valid\n*\n* No parameters\n* No returns\n*/\n\nfunction checkInterval()\n{\n\tvar startDate = $('#Start-date-picker').val();\n\tvar endDate = $('#End-date-picker').val();\n\tvar startTime = $('#Start-time-picker').val();\n\tvar endTime = $('#End-time-picker').val();\n\tvar interval = $('#interval');\n\n\t//get user information from selected drop down\n\tvar selected = $('#interval option:selected');\n\n    //check if any fields are not filled out\n\tif((!startDate || !endDate || !startTime || !endTime) && selected.text() != '--')\n\t{\n\t\t$('#prompt_user').html('Please fill out all other fields before filling out the interval field');\n\t\t$('#default').attr('selected', 'selected');\n\t}\n\n    //check to see if fields are ok\n\tcheckFields(startDate, endDate, startTime, endTime, interval);\n}\n\nmodule.exports.loading = loading;\nmodule.exports.disable = disable;\nmodule.exports.enable = enable;\nmodule.exports.checkInterval = checkInterval;\n","module.exports = Plotly;"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./controller.js","webpack:///./dispatcher.js","webpack:///./node_modules/d/index.js","webpack:///./node_modules/es5-ext/function/noop.js","webpack:///./node_modules/es5-ext/object/assign/index.js","webpack:///./node_modules/es5-ext/object/assign/is-implemented.js","webpack:///./node_modules/es5-ext/object/assign/shim.js","webpack:///./node_modules/es5-ext/object/is-callable.js","webpack:///./node_modules/es5-ext/object/is-value.js","webpack:///./node_modules/es5-ext/object/keys/index.js","webpack:///./node_modules/es5-ext/object/keys/is-implemented.js","webpack:///./node_modules/es5-ext/object/keys/shim.js","webpack:///./node_modules/es5-ext/object/normalize-options.js","webpack:///./node_modules/es5-ext/object/valid-callable.js","webpack:///./node_modules/es5-ext/object/valid-value.js","webpack:///./node_modules/es5-ext/string/#/contains/index.js","webpack:///./node_modules/es5-ext/string/#/contains/is-implemented.js","webpack:///./node_modules/es5-ext/string/#/contains/shim.js","webpack:///./node_modules/event-emitter/index.js","webpack:///./node_modules/fbjs/lib/invariant.js","webpack:///./node_modules/flux/index.js","webpack:///./node_modules/flux/lib/Dispatcher.js","webpack:///./node_modules/underscore/underscore.js","webpack:///(webpack)/buildin/global.js","webpack:///(webpack)/buildin/module.js","webpack:///./plot/data.js","webpack:///./plot/init.js","webpack:///./plot/table.js","webpack:///./plot/ticks.js","webpack:///./plot/update.js","webpack:///./plot/utils.js","webpack:///./ui/button_template.js","webpack:///./ui/buttons.js","webpack:///./ui/loading.js","webpack:///external \"Plotly\""],"names":["buildFormInDiv","require","Dispatcher","_","API","div","controlDiv","plotsInfo","myDispatcher","getDispatcher","plotDiv","dataCache","initMeteorogram","plot_div","plotOrder","hasGraph","dispatch","initMeteorogramTable","table_div","hasTable","tableDiv","initMeteorogramControls","displayRealTime","showPlot","varName","status","hidePlot","displayRecent","start_time","displayTimeRange","stop_time","interval","window","MeteorogramController","ee","Flux","Plot","Table","dataAccess","loading","updatePlot","hue","GRAPH_HEIGHT","dispatchUpdate","startTime","dispatchChangeUnits","unitCount","changeBackgroundColor","skip_jump","acceleration","rate","Math","min","document","getElementById","style","backgroundColor","checkboxEmitter","visible","setPlots","plot_key","setShowing","plotName","undefined","showing","getShowing","handleActions","action","emit","location","dispatchToken","register","bind","plotEmitter","waitFor","defaultPlots","time","start","end","userInfo","stopUpdate","progress","validID","id","clearInterval","colorID","lobbyID","updateInterval","startUpdate","intervalID","setInterval","Number","getComputedStyle","getPropertyValue","on","initTable","requestTableUpdate","initPlot","requestPlotUpdate","changeUnits","checkInterval","module","exports","utils","processData","dataObj","dates","map","timestamps","date","replace","substring","length","allData","extend","data","plotting","url","var_names","update","maxPoints","err_callback","$","ajax","type","jsonp","dataType","success","code","console","error","format","message","graphDiv","existingDates","warn","startIndex","info","i","slice","intervalLookUp","intervalToSeconds","varNamesForDiv","varNames","each","trace_data","Array","prototype","push","apply","anc_variables","uniq","endTime","stream_string","dt_in_ms","time_parts","split","Date","hasOwnProperty","buildRequestUrl","Plotly","getSecondAxisConfig","axis_number","plot_info","axis_info","axis_kwargs","key","axis_config","gridcolor","titlefont","title","zeroline","overlaying","toString","side","anchor","idx","coreLobbyLayout","layout","plot_idx","topOfGraph","graphName","textSize","ticktext","tickfont","size","showline","linecolor","domain","floor","showgrid","font","showarrow","align","x","y","xref","yref","text","div_id","DEFAULT_PLOT_HEIGHT","nshowing","showlegend","height","Object","assign","showticklabels","tickformat","trace_info","trace_config","step","x_anchor","trace_kwargs","plots","yaxis","trace_info_idx","traces","name","xaxis","hoverinfo","hovermode","anc_data","plot_name","trace_index","isSecondAxis","colorbar","len","z","yaxis2","skip","toolbar","responsive","plot","table","tbody","children","add_contour_rows","info_td","addClass","row","short_name","append","add_anc_rows","anc_info_idx","anc_info","anc_idx","title_row","hightlight_idx","y_highlight","hightlight_idx_idx","units","hl_idx","data_cells","convert_cells","trace_idx","trace","indexOf","includes","join","updateTable","results","td_idx","num_results","html","update_contour_cells","update_val","convert","old_precision","precision","orig_val","getTickText","convert_value","convert_units","convert_val","innerHTML","update_anc_cells","zprobe","zprobe2","anc_key","String","args","arguments","match","number","getWaterTempProbe","plotInfo","traceInfo","allProbeText","probeText","col","rowText","depth","j","toFixed","getF","getSpeedMPH","val","getSpeedKTS","getPresInHg","getAccumMillimeter","cardinalWDir","degrees","getVal","CONVERSION_FUNCTIONS","null","formatValue","val2","getDewpointProbe","relHum","rh_info","defaultProbeText","PROBE_TEXT_FUNCTIONS","dewpoint","water_temp","getProbeText","probe_text","values","tickText","getTickVals","max","bump","extra","range","removeOldPoints","removeCount","splice","formatDate","formatString","hour12","toLocaleString","hour","minute","second","month","getMonth","dateInfo","day_name","month_name","day","year","$0","$1","updateHeader","layoutUpdates","curr_date","opacity","date_local","date_utc","elevation","changeCamera","directions","newDirection","src","alt","getTime","currData","tick_dates","converted_tickvals","tickvals","round","relayout","fitGraphs","var_name","defaultTickVals","yMin","yMax","spread","bottom","top","tick0","replaceData","plotHandled","forceRedraw","tracesToExtend","extendData","newContourData","contourTracesToExtend","contourExtendData","traceIndex","index","extendTraces","keys","redraw","epoch","sep","order","streams","request_url","METOBS_API_URL","checkboxTemplates","controlPanelTemplate","dispatchCustom","dispatcher","getUserInfo","startDate","endDate","intervalVal","setTimeout","dropDown","selectedText","timeDelta","bind_daterange_actions","jQ_div","click","change","set_active_form","which_block","prop","set_form_datepickers","datetimepicker","changeMonth","changeYear","dateFormat","timeFormat","showSecond","showMillisec","showMicrosec","trigger","setup_all_forms","ready","disable","enable","getDate","dateString","timeString","parseInt","seconds","enablePlot","disablePlot","checkFields","selected","diff","points","attr"],"mappings":"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CAAC,0DAAQ;;;;;;;;;;;;;ACJN;;AAEb;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;;;;;;;;;;;;;ACTa;;AAEb,cAAc,mBAAO,CAAC,8DAAa;;AAEnC;;AAEA;AACA;AACA;;;;;;;;;;;;;ACRa;;AAEb,cAAc,mBAAO,CAAC,6DAAY;;AAElC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;;;;;;;;;;;;;ACnBa;;AAEb;AACA;AACA;AACA;;;;;;;;;;;;;ACLa;;AAEb,cAAc,mBAAO,CAAC,6DAAY;;AAElC;AACA;AACA;AACA;;;;;;;;;;;;;ACPa;;AAEb,iBAAiB,mBAAO,CAAC,oFAAkB;AAC3C;AACA,GAAG,mBAAO,CAAC,gEAAQ;;;;;;;;;;;;;ACJN;;AAEb;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;ACPa;;AAEb;;AAEA;AACA;AACA;;;;;;;;;;;;;ACNa;;AAEb,eAAe,mBAAO,CAAC,oCAAG;AAC1B,eAAe,mBAAO,CAAC,sFAA+B;;AAEtD;AACA;AACA;AACA;AACA,kBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE;;AAEF;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,aAAa,4BAA4B;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;;AAEpB;AACA,aAAa,2BAA2B;AACxC;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,0BAA0B;;AAE1B;AACA;AACA;AACA;;;;;;;;;;;;;ACnIA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAI,IAAqC;AACzC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,qDAAqD;AACrD,KAAK;AACL;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA,0BAA0B;AAC1B;AACA;AACA;;AAEA,2B;;;;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4BAA4B,mBAAO,CAAC,+DAAkB;;;;;;;;;;;;;ACTtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEa;;AAEb;;AAEA,iDAAiD,0CAA0C,0DAA0D,EAAE;;AAEvJ,gBAAgB,mBAAO,CAAC,gEAAoB;;AAE5C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,sBAAsB;AACtB;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,2BAA2B,KAAqC,qGAAqG,SAAgB;AACrL;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B,KAAqC,qFAAqF,SAAgB;AACrK,oBAAoB,iBAAiB;AACrC;AACA;AACA,+BAA+B,KAAqC,gHAAgH,SAAgB;AACpM;AACA;AACA,6BAA6B,KAAqC,kGAAkG,SAAgB;AACpL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,4BAA4B,KAAqC,8FAA8F,SAAgB;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED,4B;;;;;;;;;;;ACtOA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM,KAA6B;AACnC,QAAQ,KAA4B;AACpC;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,oBAAoB;AACzC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,YAAY;AAClD;AACA;AACA,KAAK;AACL;AACA,uCAAuC,YAAY;AACnD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,8BAA8B;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,YAAY;AACtD;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,YAAY;AACtD;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,WAAW;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,kDAAkD;AAClD,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,wCAAwC;AACxC,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA,iBAAiB,gBAAgB;AACjC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,6CAA6C,YAAY;AACzD;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,8BAA8B;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD;AACtD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qBAAqB,cAAc;AACnC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO,eAAe;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,qBAAqB,eAAe;AACpC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yCAAyC,YAAY;AACrD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yCAAyC,YAAY;AACrD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,yCAAyC,YAAY;AACrD;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qDAAqD;AACrD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM,KAAwB;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe;AACf,cAAc;AACd,cAAc;AACd,gBAAgB;AAChB,gBAAgB;AAChB,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP,qBAAqB;AACrB;;AAEA;AACA;AACA,KAAK;AACL,iBAAiB;;AAEjB;AACA,kDAAkD,EAAE,iBAAiB;;AAErE;AACA,wBAAwB,8BAA8B;AACtD,2BAA2B;;AAE3B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,kDAAkD,iBAAiB;;AAEnE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,IAAyC;AAC/C,IAAI,iCAAqB,EAAE,mCAAE;AAC7B;AACA,KAAK;AAAA,oGAAC;AACN;AACA,CAAC;;;;;;;;;;;;;AC3pDD;;AAEA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;;;;;;;;;;;;ACrBa;;AACb,IAAI+B,aAAavC,mBAAOA,CAAC,qCAAR,CAAjB;AACA,IAAIsG,QAAQtG,mBAAOA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","file":"meteorogram.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./controller.js\");\n","var buildFormInDiv = require('./ui/buttons.js');\nvar Dispatcher = require('./dispatcher.js');\nvar _ = require('underscore');\n\nfunction API(div, controlDiv, plotsInfo) {\n    var myDispatcher = Dispatcher.getDispatcher();\n    return {\n        plotDiv: div,\n        controlDiv: controlDiv,\n        // Our storage of the plotly data/traces being plotted right now\n        dataCache: [],\n\n        initMeteorogram: function(plot_div, plotOrder) {\n            this.hasGraph = true;\n            this.plotDiv = plot_div || this.plotDiv;\n            //start with only the selected plots showing, reveal others only if their data is requested\n            myDispatcher.dispatch({\n                'status': 'initPlot',\n                'emit': 'plotEmitter',\n                'location': this.plotDiv,\n                'dataCache': this.dataCache,\n                'plotsInfo': plotsInfo,\n                'plotOrder': plotOrder\n            });\n        },\n        initMeteorogramTable: function(table_div,plotOrder) {\n            this.hasTable = true;\n            this.tableDiv = table_div || this.plotDiv;\n            //start with only the selected plots showing, reveal others only if their data is requested\n            myDispatcher.dispatch({\n                'status': 'initTable',\n                'emit': 'plotEmitter',\n                'location': this.tableDiv,\n                'plotsInfo': plotsInfo,\n                'plotOrder': plotOrder,\n            });\n        },\n\n        initMeteorogramControls:function(plotOrder){\n            buildFormInDiv(this.controlDiv, this.plotDiv,myDispatcher);\n        },\n\n        displayRealTime: function() {\n            if (this.hasTable) {\n                myDispatcher.dispatch({\n                    'status':'update_table',\n                    'emit':'plotEmitter',\n                    'time':'-3:00:00',\n                    'location':this.tableDiv\n                });\n            }\n            if (this.hasGraph) {\n                myDispatcher.dispatch({\n                    'status':'get_since_now',\n                    'emit':'plotEmitter',\n                    'time':'-3:00:00',\n                    'location':this.plotDiv\n                });\n            }\n        },\n\n        showPlot:function(varName){\n            myDispatcher.dispatch({status: ('show' + varName), 'emit': 'checkboxEmitter','location':this.div});\n        },\n\n        hidePlot:function(varName){\n            myDispatcher.dispatch({status: ('hide' + varName), 'emit': 'checkboxEmitter','location':this.div});\n        },\n\n        displayRecent: function(start_time) {\n            // interval, if not provided, will be determined based on start time\n            myDispatcher.dispatch({\n                'status': 'get_since_now',\n                'emit': 'plotEmitter',\n                'time': start_time,\n            });\n        },\n\n        displayTimeRange: function(start_time, stop_time, interval) {\n            myDispatcher.dispatch({\n                'status':'get_between_dates',\n                'emit':'plotEmitter',\n                'start':start_time,\n                'end':stop_time,\n                'interval':interval||'auto',\n            });\n\n        },\n    }\n}\n\n//expose the API to other scripts\nwindow.MeteorogramController = API;\n","\"use strict\";\n\n//var $ = require('jquery');\nvar ee = require('event-emitter');\nvar Flux = require('flux');\nvar Plot = require('./plot/init.js');\nvar Table = require('./plot/table.js');\nvar dataAccess = require('./plot/data.js');\nvar loading = require('./ui/loading.js');\nvar updatePlot = require('./plot/update.js');\nvar hue;\n\nfunction getDispatcher() {\n    var myDispatcher = new Flux.Dispatcher();\n    //not sure where else to stick globals\n    myDispatcher.GRAPH_HEIGHT = 170;\n    /**\n    * The purpose of this method is to dispatch an update message to plotStore\n    *\n    * no parameters\n    * no returns\n    */\n\n    function dispatchUpdate(startTime) {\n        return function() {\n            //dispatch update message to plotStore\n            myDispatcher.dispatch({'status': 'update', 'emit': 'plotEmitter', 'startTime': startTime});\n        }\n    }\n\n    function dispatchChangeUnits(unitCount) {\n        return function() {\n            unitCount = (unitCount + 1) % 2\n            //dispatch update message to plotStore\n            myDispatcher.dispatch({'status': 'changeUnits', 'emit': 'plotEmitter', 'unitCount': unitCount});\n        }\n    }\n\n    function changeBackgroundColor() {\n        // Moves faster between Red, Green, and Blue. This is purely aesthetic to avoid \"ugly\" colors (I'm looking at\n        // you brown-green).\n        var skip_jump = 120;\n        var acceleration = 2;\n        var rate = .2;\n        // Exactly rate times faster at skip_jump / 2, and normal speed at skip_jump.\n        hue += (acceleration * Math.min(skip_jump - hue % skip_jump, hue % skip_jump) / (skip_jump / 2) + 1) * rate\n        // Loops around the color circle.\n        if (hue > 360) {\n            hue = 0\n        }\n        // Make the brighter colors more grey to match the darker colors above them.\n        document.getElementById('row1').style.backgroundColor = 'hsl(' + hue + ',' + 100 + '%,' + 15 + '%)';\n        document.getElementById('row2').style.backgroundColor = 'hsl(' + hue + ',' + 75 + '%,' + 30 + '%)';\n        document.getElementById('row3').style.backgroundColor = 'hsl(' + hue + ',' + 50 + '%,' + 45 + '%)';\n    }\n\n    //creates checkbox store\n    var checkboxEmitter = ee({\n        visible: {},\n        setPlots: function (plotsInfo) {\n            for (var plot_key in plotsInfo) {\n                this.visible[plot_key] = true;\n            }\n        },\n        setShowing: function(plotName, visible) {\n            if (visible === undefined) {\n                this.showing[plotName] = !this.showing[plotName];\n            } else {\n                this.showing[plotName] = visible;\n            }\n        },\n        getShowing: function(plotName) {\n            return this.showing[plotName];\n        },\n        handleActions: function(action) {\n            //only handels if action is for checkbox emitter\n            if(action.emit == 'checkboxEmitter')\n            {\n                this.emit(action.status, action.location);\n            }\n        }\n    });\n\n    //register store with dispatcher\n    checkboxEmitter.dispatchToken = myDispatcher.register(checkboxEmitter.handleActions.bind(checkboxEmitter));\n\n    //create plotStore\n    // FIXME: Event emitter should be added to a class prototype, not the other way around\n    // See https://github.com/medikoo/event-emitter#usage\n    // The below works...but only because event-emitter allows it. Should probably stick with advertised features\n    var plotEmitter = ee({\n        handleActions: function(action) {\n            if (action.emit == 'plotEmitter') {\n                myDispatcher.waitFor([checkboxEmitter.dispatchToken]);\n\n                if (action.location !== undefined) {\n                    this.div = action.location;\n                }\n\n                if (action.plotsInfo !== undefined) {\n                    this.plotsInfo = action.plotsInfo;\n                    this.plotOrder = this.plotsInfo.defaultPlots;\n                }\n                if (action.plotOrder !== undefined) {\n                    this.plotOrder = action.plotOrder;\n                }\n\n                if (action.dataCache !== undefined) {\n                    this.dataCache = action.dataCache;\n                }\n\n                if (action.status == 'get_since_now') {\n                    if (this.plotsInfo['isLobbyDisplay']) {\n                        action.time = '-6:00:00'\n                    }\n                    this.emit(\n                        action.status,\n                        action.time,\n                        this.plotsInfo,\n                        this.dataCache,\n                        this.div);\n                }else if (action.status == 'update_table') {\n                    this.emit(\n                        action.status,\n                        action.time,\n                        this.plotsInfo,\n                        this.div);\n                } else if (action.status == 'get_between_dates') {\n                    this.emit(\n                        action.status,\n                        action.start,\n                        action.end,\n                        action.interval,\n                        this.plotsInfo,\n                        this.dataCache,\n                        this.div);\n                } else if (action.status == 'initPlot') {\n                    this.emit(\n                        action.status,\n                        action.location,\n                        action.plotOrder ? action.plotOrder : this.plotOrder,\n                        this.plotsInfo,\n                        this.dataCache);\n                } else if (action.status == 'initTable') {\n                    this.emit(\n                        action.status,\n                        action.location,\n                        action.plotOrder ? action.plotOrder : this.plotOrder,\n                        this.plotsInfo);\n                } else if (action.status == 'update') {\n                    this.emit(action.status, this.div, this.plotsInfo, this.dataCache, action.startTime);\n                } else if (action.status == 'changeUnits') {\n                    this.emit(action.status, this.div, this.plotsInfo, this.dataCache, action.unitCount);\n                } else {\n                    //adds parameter for user information in custom plot\n                    // console.debug(\"Emitting user information message: {action.status} : {action.userInfo}\");\n                    this.emit(action.status, action.userInfo);\n                }\n            }\n        }\n    });\n\n\n    function stopUpdate(plotsInfo) {\n        if(!plotsInfo.progress)\n            plotsInfo.progress = {};\n        if(plotsInfo.progress.validID){\n            var id = plotsInfo.progress.id[0];\n            clearInterval(id);\n            if (plotsInfo['isLobbyDisplay']) {\n                clearInterval(plotsInfo.progress.colorID);\n                clearInterval(plotsInfo.progress.lobbyID);\n            }\n            plotsInfo.progress.validID = false;\n        }\n    }\n\n    // update every N/2 milliseconds\n    const updateInterval = {\n        '1m': 30 * 1000,\n        '5m': 2.5 * 60 * 1000,\n        '1h': 30 * 60 * 1000,\n    };\n\n\n    function startUpdate(startTime, interval, plotsInfo) {\n        // stop any previous updates\n        if(!plotsInfo.progress)\n            plotsInfo.progress = {};\n        stopUpdate(plotsInfo);\n\n        // resume update operations\n        if (startTime === undefined) {\n            startTime = plotsInfo.progress.id[1];\n        }\n        if (interval === undefined) {\n            interval = plotsInfo.progress.id[2];\n        }\n\n        // every 30 seconds, rings update alarm\n        var intervalID = setInterval(dispatchUpdate(startTime), updateInterval[interval]);\n        if (plotsInfo['isLobbyDisplay']) {\n            hue = Number(getComputedStyle(document.getElementById(\"color\")).getPropertyValue('--starting-hue'))\n            plotsInfo.progress.colorID = setInterval(changeBackgroundColor, 1000)\n            plotsInfo.progress.lobbyID = setInterval(dispatchChangeUnits(0), 5000);\n        }\n        // save alarm id\n        plotsInfo.progress.id = [intervalID, startTime, interval];\n        plotsInfo.progress.validID = true;\n    }\n\n    plotEmitter.on('initTable', function(div, plotOrder, plotsInfo) {\n        //initialize checkbox store\n        checkboxEmitter.setPlots(plotsInfo);\n        Table.initTable(div, plotOrder, plotsInfo);\n    });\n\n    plotEmitter.on('update_table',function(time, plotsInfo, div){\n        Table.requestTableUpdate(div, plotsInfo);\n        setInterval(function(){Table.requestTableUpdate(div,plotsInfo)},updateInterval['1m']);\n    });\n\n    plotEmitter.on('initPlot', function(div, plotOrder, plotsInfo, dataCache) {\n        //initialize checkbox store\n        checkboxEmitter.setPlots(plotsInfo);\n        Plot.initPlot(dataCache, div, plotOrder, plotsInfo);\n    });\n\n    plotEmitter.on(\"get_since_now\", function(time, plotsInfo, dataCache, div) {\n        var interval = dataAccess.requestPlotUpdate(dataCache, div, plotsInfo, time,\n            undefined, undefined, undefined, stopUpdate);\n        startUpdate(time, interval, plotsInfo);\n    });\n\n    plotEmitter.on(\"get_between_dates\",function(start, end, interval, plotsInfo, dataCache, div) {\n        stopUpdate(plotsInfo);\n        dataAccess.requestPlotUpdate(dataCache, div, plotsInfo, start, end, interval);\n    });\n\n    //when store recieves signal, update component\n    plotEmitter.on('update', function(div, plotsInfo, dataCache, startTime) {\n        dataAccess.requestPlotUpdate(dataCache, div, plotsInfo, startTime, undefined, undefined, true);\n    });\n\n    plotEmitter.on('changeUnits', function(div, plotsInfo, dataCache, unitCount) {\n        updatePlot.changeUnits(dataCache, document.getElementById(div), plotsInfo, unitCount)\n    });\n\n    plotEmitter.on(\"checking_custom\", function()\n    {\n        //before components were plots. Here, it's the user prompt paragraph\n        loading.checkInterval();\n    });\n\n    //register plotStore with dispatcher\n    plotEmitter.dispatchToken = myDispatcher.register(plotEmitter.handleActions.bind(plotEmitter));\n\n    return myDispatcher;\n}\n\n//exports dispatchers and stores\nmodule.exports.getDispatcher = getDispatcher;\n","'use strict';\n\nvar assign        = require('es5-ext/object/assign')\n  , normalizeOpts = require('es5-ext/object/normalize-options')\n  , isCallable    = require('es5-ext/object/is-callable')\n  , contains      = require('es5-ext/string/#/contains')\n\n  , d;\n\nd = module.exports = function (dscr, value/*, options*/) {\n\tvar c, e, w, options, desc;\n\tif ((arguments.length < 2) || (typeof dscr !== 'string')) {\n\t\toptions = value;\n\t\tvalue = dscr;\n\t\tdscr = null;\n\t} else {\n\t\toptions = arguments[2];\n\t}\n\tif (dscr == null) {\n\t\tc = w = true;\n\t\te = false;\n\t} else {\n\t\tc = contains.call(dscr, 'c');\n\t\te = contains.call(dscr, 'e');\n\t\tw = contains.call(dscr, 'w');\n\t}\n\n\tdesc = { value: value, configurable: c, enumerable: e, writable: w };\n\treturn !options ? desc : assign(normalizeOpts(options), desc);\n};\n\nd.gs = function (dscr, get, set/*, options*/) {\n\tvar c, e, options, desc;\n\tif (typeof dscr !== 'string') {\n\t\toptions = set;\n\t\tset = get;\n\t\tget = dscr;\n\t\tdscr = null;\n\t} else {\n\t\toptions = arguments[3];\n\t}\n\tif (get == null) {\n\t\tget = undefined;\n\t} else if (!isCallable(get)) {\n\t\toptions = get;\n\t\tget = set = undefined;\n\t} else if (set == null) {\n\t\tset = undefined;\n\t} else if (!isCallable(set)) {\n\t\toptions = set;\n\t\tset = undefined;\n\t}\n\tif (dscr == null) {\n\t\tc = true;\n\t\te = false;\n\t} else {\n\t\tc = contains.call(dscr, 'c');\n\t\te = contains.call(dscr, 'e');\n\t}\n\n\tdesc = { get: get, set: set, configurable: c, enumerable: e };\n\treturn !options ? desc : assign(normalizeOpts(options), desc);\n};\n","\"use strict\";\n\n// eslint-disable-next-line no-empty-function\nmodule.exports = function () {};\n","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")()\n\t? Object.assign\n\t: require(\"./shim\");\n","\"use strict\";\n\nmodule.exports = function () {\n\tvar assign = Object.assign, obj;\n\tif (typeof assign !== \"function\") return false;\n\tobj = { foo: \"raz\" };\n\tassign(obj, { bar: \"dwa\" }, { trzy: \"trzy\" });\n\treturn (obj.foo + obj.bar + obj.trzy) === \"razdwatrzy\";\n};\n","\"use strict\";\n\nvar keys  = require(\"../keys\")\n  , value = require(\"../valid-value\")\n  , max   = Math.max;\n\nmodule.exports = function (dest, src /*, …srcn*/) {\n\tvar error, i, length = max(arguments.length, 2), assign;\n\tdest = Object(value(dest));\n\tassign = function (key) {\n\t\ttry {\n\t\t\tdest[key] = src[key];\n\t\t} catch (e) {\n\t\t\tif (!error) error = e;\n\t\t}\n\t};\n\tfor (i = 1; i < length; ++i) {\n\t\tsrc = arguments[i];\n\t\tkeys(src).forEach(assign);\n\t}\n\tif (error !== undefined) throw error;\n\treturn dest;\n};\n","// Deprecated\n\n\"use strict\";\n\nmodule.exports = function (obj) {\n return typeof obj === \"function\";\n};\n","\"use strict\";\n\nvar _undefined = require(\"../function/noop\")(); // Support ES3 engines\n\nmodule.exports = function (val) {\n return (val !== _undefined) && (val !== null);\n};\n","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")()\n\t? Object.keys\n\t: require(\"./shim\");\n","\"use strict\";\n\nmodule.exports = function () {\n\ttry {\n\t\tObject.keys(\"primitive\");\n\t\treturn true;\n\t} catch (e) {\n return false;\n}\n};\n","\"use strict\";\n\nvar isValue = require(\"../is-value\");\n\nvar keys = Object.keys;\n\nmodule.exports = function (object) {\n\treturn keys(isValue(object) ? Object(object) : object);\n};\n","\"use strict\";\n\nvar isValue = require(\"./is-value\");\n\nvar forEach = Array.prototype.forEach, create = Object.create;\n\nvar process = function (src, obj) {\n\tvar key;\n\tfor (key in src) obj[key] = src[key];\n};\n\n// eslint-disable-next-line no-unused-vars\nmodule.exports = function (opts1 /*, …options*/) {\n\tvar result = create(null);\n\tforEach.call(arguments, function (options) {\n\t\tif (!isValue(options)) return;\n\t\tprocess(Object(options), result);\n\t});\n\treturn result;\n};\n","\"use strict\";\n\nmodule.exports = function (fn) {\n\tif (typeof fn !== \"function\") throw new TypeError(fn + \" is not a function\");\n\treturn fn;\n};\n","\"use strict\";\n\nvar isValue = require(\"./is-value\");\n\nmodule.exports = function (value) {\n\tif (!isValue(value)) throw new TypeError(\"Cannot use null or undefined\");\n\treturn value;\n};\n","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")()\n\t? String.prototype.contains\n\t: require(\"./shim\");\n","\"use strict\";\n\nvar str = \"razdwatrzy\";\n\nmodule.exports = function () {\n\tif (typeof str.contains !== \"function\") return false;\n\treturn (str.contains(\"dwa\") === true) && (str.contains(\"foo\") === false);\n};\n","\"use strict\";\n\nvar indexOf = String.prototype.indexOf;\n\nmodule.exports = function (searchString/*, position*/) {\n\treturn indexOf.call(this, searchString, arguments[1]) > -1;\n};\n","'use strict';\n\nvar d        = require('d')\n  , callable = require('es5-ext/object/valid-callable')\n\n  , apply = Function.prototype.apply, call = Function.prototype.call\n  , create = Object.create, defineProperty = Object.defineProperty\n  , defineProperties = Object.defineProperties\n  , hasOwnProperty = Object.prototype.hasOwnProperty\n  , descriptor = { configurable: true, enumerable: false, writable: true }\n\n  , on, once, off, emit, methods, descriptors, base;\n\non = function (type, listener) {\n\tvar data;\n\n\tcallable(listener);\n\n\tif (!hasOwnProperty.call(this, '__ee__')) {\n\t\tdata = descriptor.value = create(null);\n\t\tdefineProperty(this, '__ee__', descriptor);\n\t\tdescriptor.value = null;\n\t} else {\n\t\tdata = this.__ee__;\n\t}\n\tif (!data[type]) data[type] = listener;\n\telse if (typeof data[type] === 'object') data[type].push(listener);\n\telse data[type] = [data[type], listener];\n\n\treturn this;\n};\n\nonce = function (type, listener) {\n\tvar once, self;\n\n\tcallable(listener);\n\tself = this;\n\ton.call(this, type, once = function () {\n\t\toff.call(self, type, once);\n\t\tapply.call(listener, this, arguments);\n\t});\n\n\tonce.__eeOnceListener__ = listener;\n\treturn this;\n};\n\noff = function (type, listener) {\n\tvar data, listeners, candidate, i;\n\n\tcallable(listener);\n\n\tif (!hasOwnProperty.call(this, '__ee__')) return this;\n\tdata = this.__ee__;\n\tif (!data[type]) return this;\n\tlisteners = data[type];\n\n\tif (typeof listeners === 'object') {\n\t\tfor (i = 0; (candidate = listeners[i]); ++i) {\n\t\t\tif ((candidate === listener) ||\n\t\t\t\t\t(candidate.__eeOnceListener__ === listener)) {\n\t\t\t\tif (listeners.length === 2) data[type] = listeners[i ? 0 : 1];\n\t\t\t\telse listeners.splice(i, 1);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif ((listeners === listener) ||\n\t\t\t\t(listeners.__eeOnceListener__ === listener)) {\n\t\t\tdelete data[type];\n\t\t}\n\t}\n\n\treturn this;\n};\n\nemit = function (type) {\n\tvar i, l, listener, listeners, args;\n\n\tif (!hasOwnProperty.call(this, '__ee__')) return;\n\tlisteners = this.__ee__[type];\n\tif (!listeners) return;\n\n\tif (typeof listeners === 'object') {\n\t\tl = arguments.length;\n\t\targs = new Array(l - 1);\n\t\tfor (i = 1; i < l; ++i) args[i - 1] = arguments[i];\n\n\t\tlisteners = listeners.slice();\n\t\tfor (i = 0; (listener = listeners[i]); ++i) {\n\t\t\tapply.call(listener, this, args);\n\t\t}\n\t} else {\n\t\tswitch (arguments.length) {\n\t\tcase 1:\n\t\t\tcall.call(listeners, this);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tcall.call(listeners, this, arguments[1]);\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tcall.call(listeners, this, arguments[1], arguments[2]);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tl = arguments.length;\n\t\t\targs = new Array(l - 1);\n\t\t\tfor (i = 1; i < l; ++i) {\n\t\t\t\targs[i - 1] = arguments[i];\n\t\t\t}\n\t\t\tapply.call(listeners, this, args);\n\t\t}\n\t}\n};\n\nmethods = {\n\ton: on,\n\tonce: once,\n\toff: off,\n\temit: emit\n};\n\ndescriptors = {\n\ton: d(on),\n\tonce: d(once),\n\toff: d(off),\n\temit: d(emit)\n};\n\nbase = defineProperties({}, descriptors);\n\nmodule.exports = exports = function (o) {\n\treturn (o == null) ? create(base) : defineProperties(Object(o), descriptors);\n};\nexports.methods = methods;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\n/**\n * Use invariant() to assert state which your program assumes to be true.\n *\n * Provide sprintf-style format (only %s is supported) and arguments\n * to provide information about what broke and what you were\n * expecting.\n *\n * The invariant message will be stripped in production, but the invariant\n * will remain to ensure logic does not differ in production.\n */\n\nvar validateFormat = function validateFormat(format) {};\n\nif (process.env.NODE_ENV !== 'production') {\n  validateFormat = function validateFormat(format) {\n    if (format === undefined) {\n      throw new Error('invariant requires an error message argument');\n    }\n  };\n}\n\nfunction invariant(condition, format, a, b, c, d, e, f) {\n  validateFormat(format);\n\n  if (!condition) {\n    var error;\n    if (format === undefined) {\n      error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');\n    } else {\n      var args = [a, b, c, d, e, f];\n      var argIndex = 0;\n      error = new Error(format.replace(/%s/g, function () {\n        return args[argIndex++];\n      }));\n      error.name = 'Invariant Violation';\n    }\n\n    error.framesToPop = 1; // we don't care about invariant's own frame\n    throw error;\n  }\n}\n\nmodule.exports = invariant;","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\nmodule.exports.Dispatcher = require('./lib/Dispatcher');\n","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule Dispatcher\n * \n * @preventMunge\n */\n\n'use strict';\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nvar invariant = require('fbjs/lib/invariant');\n\nvar _prefix = 'ID_';\n\n/**\n * Dispatcher is used to broadcast payloads to registered callbacks. This is\n * different from generic pub-sub systems in two ways:\n *\n *   1) Callbacks are not subscribed to particular events. Every payload is\n *      dispatched to every registered callback.\n *   2) Callbacks can be deferred in whole or part until other callbacks have\n *      been executed.\n *\n * For example, consider this hypothetical flight destination form, which\n * selects a default city when a country is selected:\n *\n *   var flightDispatcher = new Dispatcher();\n *\n *   // Keeps track of which country is selected\n *   var CountryStore = {country: null};\n *\n *   // Keeps track of which city is selected\n *   var CityStore = {city: null};\n *\n *   // Keeps track of the base flight price of the selected city\n *   var FlightPriceStore = {price: null}\n *\n * When a user changes the selected city, we dispatch the payload:\n *\n *   flightDispatcher.dispatch({\n *     actionType: 'city-update',\n *     selectedCity: 'paris'\n *   });\n *\n * This payload is digested by `CityStore`:\n *\n *   flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'city-update') {\n *       CityStore.city = payload.selectedCity;\n *     }\n *   });\n *\n * When the user selects a country, we dispatch the payload:\n *\n *   flightDispatcher.dispatch({\n *     actionType: 'country-update',\n *     selectedCountry: 'australia'\n *   });\n *\n * This payload is digested by both stores:\n *\n *   CountryStore.dispatchToken = flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'country-update') {\n *       CountryStore.country = payload.selectedCountry;\n *     }\n *   });\n *\n * When the callback to update `CountryStore` is registered, we save a reference\n * to the returned token. Using this token with `waitFor()`, we can guarantee\n * that `CountryStore` is updated before the callback that updates `CityStore`\n * needs to query its data.\n *\n *   CityStore.dispatchToken = flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'country-update') {\n *       // `CountryStore.country` may not be updated.\n *       flightDispatcher.waitFor([CountryStore.dispatchToken]);\n *       // `CountryStore.country` is now guaranteed to be updated.\n *\n *       // Select the default city for the new country\n *       CityStore.city = getDefaultCityForCountry(CountryStore.country);\n *     }\n *   });\n *\n * The usage of `waitFor()` can be chained, for example:\n *\n *   FlightPriceStore.dispatchToken =\n *     flightDispatcher.register(function(payload) {\n *       switch (payload.actionType) {\n *         case 'country-update':\n *         case 'city-update':\n *           flightDispatcher.waitFor([CityStore.dispatchToken]);\n *           FlightPriceStore.price =\n *             getFlightPriceStore(CountryStore.country, CityStore.city);\n *           break;\n *     }\n *   });\n *\n * The `country-update` payload will be guaranteed to invoke the stores'\n * registered callbacks in order: `CountryStore`, `CityStore`, then\n * `FlightPriceStore`.\n */\n\nvar Dispatcher = (function () {\n  function Dispatcher() {\n    _classCallCheck(this, Dispatcher);\n\n    this._callbacks = {};\n    this._isDispatching = false;\n    this._isHandled = {};\n    this._isPending = {};\n    this._lastID = 1;\n  }\n\n  /**\n   * Registers a callback to be invoked with every dispatched payload. Returns\n   * a token that can be used with `waitFor()`.\n   */\n\n  Dispatcher.prototype.register = function register(callback) {\n    var id = _prefix + this._lastID++;\n    this._callbacks[id] = callback;\n    return id;\n  };\n\n  /**\n   * Removes a callback based on its token.\n   */\n\n  Dispatcher.prototype.unregister = function unregister(id) {\n    !this._callbacks[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.unregister(...): `%s` does not map to a registered callback.', id) : invariant(false) : undefined;\n    delete this._callbacks[id];\n  };\n\n  /**\n   * Waits for the callbacks specified to be invoked before continuing execution\n   * of the current callback. This method should only be used by a callback in\n   * response to a dispatched payload.\n   */\n\n  Dispatcher.prototype.waitFor = function waitFor(ids) {\n    !this._isDispatching ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): Must be invoked while dispatching.') : invariant(false) : undefined;\n    for (var ii = 0; ii < ids.length; ii++) {\n      var id = ids[ii];\n      if (this._isPending[id]) {\n        !this._isHandled[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): Circular dependency detected while ' + 'waiting for `%s`.', id) : invariant(false) : undefined;\n        continue;\n      }\n      !this._callbacks[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): `%s` does not map to a registered callback.', id) : invariant(false) : undefined;\n      this._invokeCallback(id);\n    }\n  };\n\n  /**\n   * Dispatches a payload to all registered callbacks.\n   */\n\n  Dispatcher.prototype.dispatch = function dispatch(payload) {\n    !!this._isDispatching ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.') : invariant(false) : undefined;\n    this._startDispatching(payload);\n    try {\n      for (var id in this._callbacks) {\n        if (this._isPending[id]) {\n          continue;\n        }\n        this._invokeCallback(id);\n      }\n    } finally {\n      this._stopDispatching();\n    }\n  };\n\n  /**\n   * Is this Dispatcher currently dispatching.\n   */\n\n  Dispatcher.prototype.isDispatching = function isDispatching() {\n    return this._isDispatching;\n  };\n\n  /**\n   * Call the callback stored with the given id. Also do some internal\n   * bookkeeping.\n   *\n   * @internal\n   */\n\n  Dispatcher.prototype._invokeCallback = function _invokeCallback(id) {\n    this._isPending[id] = true;\n    this._callbacks[id](this._pendingPayload);\n    this._isHandled[id] = true;\n  };\n\n  /**\n   * Set up bookkeeping needed when dispatching.\n   *\n   * @internal\n   */\n\n  Dispatcher.prototype._startDispatching = function _startDispatching(payload) {\n    for (var id in this._callbacks) {\n      this._isPending[id] = false;\n      this._isHandled[id] = false;\n    }\n    this._pendingPayload = payload;\n    this._isDispatching = true;\n  };\n\n  /**\n   * Clear bookkeeping used for dispatching.\n   *\n   * @internal\n   */\n\n  Dispatcher.prototype._stopDispatching = function _stopDispatching() {\n    delete this._pendingPayload;\n    this._isDispatching = false;\n  };\n\n  return Dispatcher;\n})();\n\nmodule.exports = Dispatcher;","//     Underscore.js 1.9.1\n//     http://underscorejs.org\n//     (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n//     Underscore may be freely distributed under the MIT license.\n\n(function() {\n\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` (`self`) in the browser, `global`\n  // on the server, or `this` in some virtual machines. We use `self`\n  // instead of `window` for `WebWorker` support.\n  var root = typeof self == 'object' && self.self === self && self ||\n            typeof global == 'object' && global.global === global && global ||\n            this ||\n            {};\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype;\n  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var push = ArrayProto.push,\n      slice = ArrayProto.slice,\n      toString = ObjProto.toString,\n      hasOwnProperty = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var nativeIsArray = Array.isArray,\n      nativeKeys = Object.keys,\n      nativeCreate = Object.create;\n\n  // Naked function reference for surrogate-prototype-swapping.\n  var Ctor = function(){};\n\n  // Create a safe reference to the Underscore object for use below.\n  var _ = function(obj) {\n    if (obj instanceof _) return obj;\n    if (!(this instanceof _)) return new _(obj);\n    this._wrapped = obj;\n  };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for their old module API. If we're in\n  // the browser, add `_` as a global object.\n  // (`nodeType` is checked to ensure that `module`\n  // and `exports` are not HTML elements.)\n  if (typeof exports != 'undefined' && !exports.nodeType) {\n    if (typeof module != 'undefined' && !module.nodeType && module.exports) {\n      exports = module.exports = _;\n    }\n    exports._ = _;\n  } else {\n    root._ = _;\n  }\n\n  // Current version.\n  _.VERSION = '1.9.1';\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  var optimizeCb = function(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1: return function(value) {\n        return func.call(context, value);\n      };\n      // The 2-argument case is omitted because we’re not using it.\n      case 3: return function(value, index, collection) {\n        return func.call(context, value, index, collection);\n      };\n      case 4: return function(accumulator, value, index, collection) {\n        return func.call(context, accumulator, value, index, collection);\n      };\n    }\n    return function() {\n      return func.apply(context, arguments);\n    };\n  };\n\n  var builtinIteratee;\n\n  // An internal function to generate callbacks that can be applied to each\n  // element in a collection, returning the desired result — either `identity`,\n  // an arbitrary callback, a property matcher, or a property accessor.\n  var cb = function(value, context, argCount) {\n    if (_.iteratee !== builtinIteratee) return _.iteratee(value, context);\n    if (value == null) return _.identity;\n    if (_.isFunction(value)) return optimizeCb(value, context, argCount);\n    if (_.isObject(value) && !_.isArray(value)) return _.matcher(value);\n    return _.property(value);\n  };\n\n  // External wrapper for our callback generator. Users may customize\n  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.\n  // This abstraction hides the internal-only argCount argument.\n  _.iteratee = builtinIteratee = function(value, context) {\n    return cb(value, context, Infinity);\n  };\n\n  // Some functions take a variable number of arguments, or a few expected\n  // arguments at the beginning and then a variable number of values to operate\n  // on. This helper accumulates all remaining arguments past the function’s\n  // argument length (or an explicit `startIndex`), into an array that becomes\n  // the last argument. Similar to ES6’s \"rest parameter\".\n  var restArguments = function(func, startIndex) {\n    startIndex = startIndex == null ? func.length - 1 : +startIndex;\n    return function() {\n      var length = Math.max(arguments.length - startIndex, 0),\n          rest = Array(length),\n          index = 0;\n      for (; index < length; index++) {\n        rest[index] = arguments[index + startIndex];\n      }\n      switch (startIndex) {\n        case 0: return func.call(this, rest);\n        case 1: return func.call(this, arguments[0], rest);\n        case 2: return func.call(this, arguments[0], arguments[1], rest);\n      }\n      var args = Array(startIndex + 1);\n      for (index = 0; index < startIndex; index++) {\n        args[index] = arguments[index];\n      }\n      args[startIndex] = rest;\n      return func.apply(this, args);\n    };\n  };\n\n  // An internal function for creating a new object that inherits from another.\n  var baseCreate = function(prototype) {\n    if (!_.isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    Ctor.prototype = prototype;\n    var result = new Ctor;\n    Ctor.prototype = null;\n    return result;\n  };\n\n  var shallowProperty = function(key) {\n    return function(obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  };\n\n  var has = function(obj, path) {\n    return obj != null && hasOwnProperty.call(obj, path);\n  }\n\n  var deepGet = function(obj, path) {\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      if (obj == null) return void 0;\n      obj = obj[path[i]];\n    }\n    return length ? obj : void 0;\n  };\n\n  // Helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object.\n  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n  var getLength = shallowProperty('length');\n  var isArrayLike = function(collection) {\n    var length = getLength(collection);\n    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;\n  };\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  _.each = _.forEach = function(obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var keys = _.keys(obj);\n      for (i = 0, length = keys.length; i < length; i++) {\n        iteratee(obj[keys[i]], keys[i], obj);\n      }\n    }\n    return obj;\n  };\n\n  // Return the results of applying the iteratee to each element.\n  _.map = _.collect = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length,\n        results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  };\n\n  // Create a reducing function iterating left or right.\n  var createReduce = function(dir) {\n    // Wrap code that reassigns argument variables in a separate function than\n    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)\n    var reducer = function(obj, iteratee, memo, initial) {\n      var keys = !isArrayLike(obj) && _.keys(obj),\n          length = (keys || obj).length,\n          index = dir > 0 ? 0 : length - 1;\n      if (!initial) {\n        memo = obj[keys ? keys[index] : index];\n        index += dir;\n      }\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = keys ? keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    };\n\n    return function(obj, iteratee, memo, context) {\n      var initial = arguments.length >= 3;\n      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);\n    };\n  };\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  _.reduce = _.foldl = _.inject = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  _.reduceRight = _.foldr = createReduce(-1);\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _.find = _.detect = function(obj, predicate, context) {\n    var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey;\n    var key = keyFinder(obj, predicate, context);\n    if (key !== void 0 && key !== -1) return obj[key];\n  };\n\n  // Return all the elements that pass a truth test.\n  // Aliased as `select`.\n  _.filter = _.select = function(obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    _.each(obj, function(value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _.reject = function(obj, predicate, context) {\n    return _.filter(obj, _.negate(cb(predicate)), context);\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Aliased as `all`.\n  _.every = _.all = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Aliased as `any`.\n  _.some = _.any = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  };\n\n  // Determine if the array or object contains a given item (using `===`).\n  // Aliased as `includes` and `include`.\n  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = _.values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return _.indexOf(obj, item, fromIndex) >= 0;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _.invoke = restArguments(function(obj, path, args) {\n    var contextPath, func;\n    if (_.isFunction(path)) {\n      func = path;\n    } else if (_.isArray(path)) {\n      contextPath = path.slice(0, -1);\n      path = path[path.length - 1];\n    }\n    return _.map(obj, function(context) {\n      var method = func;\n      if (!method) {\n        if (contextPath && contextPath.length) {\n          context = deepGet(context, contextPath);\n        }\n        if (context == null) return void 0;\n        method = context[path];\n      }\n      return method == null ? method : method.apply(context, args);\n    });\n  });\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _.pluck = function(obj, key) {\n    return _.map(obj, _.property(key));\n  };\n\n  // Convenience version of a common use case of `filter`: selecting only objects\n  // containing specific `key:value` pairs.\n  _.where = function(obj, attrs) {\n    return _.filter(obj, _.matcher(attrs));\n  };\n\n  // Convenience version of a common use case of `find`: getting the first object\n  // containing specific `key:value` pairs.\n  _.findWhere = function(obj, attrs) {\n    return _.find(obj, _.matcher(attrs));\n  };\n\n  // Return the maximum element (or element-based computation).\n  _.max = function(obj, iteratee, context) {\n    var result = -Infinity, lastComputed = -Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : _.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _.min = function(obj, iteratee, context) {\n    var result = Infinity, lastComputed = Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : _.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Shuffle a collection.\n  _.shuffle = function(obj) {\n    return _.sample(obj, Infinity);\n  };\n\n  // Sample **n** random values from a collection using the modern version of the\n  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `map`.\n  _.sample = function(obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = _.values(obj);\n      return obj[_.random(obj.length - 1)];\n    }\n    var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj);\n    var length = getLength(sample);\n    n = Math.max(Math.min(n, length), 0);\n    var last = length - 1;\n    for (var index = 0; index < n; index++) {\n      var rand = _.random(index, last);\n      var temp = sample[index];\n      sample[index] = sample[rand];\n      sample[rand] = temp;\n    }\n    return sample.slice(0, n);\n  };\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  _.sortBy = function(obj, iteratee, context) {\n    var index = 0;\n    iteratee = cb(iteratee, context);\n    return _.pluck(_.map(obj, function(value, key, list) {\n      return {\n        value: value,\n        index: index++,\n        criteria: iteratee(value, key, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  };\n\n  // An internal function used for aggregate \"group by\" operations.\n  var group = function(behavior, partition) {\n    return function(obj, iteratee, context) {\n      var result = partition ? [[], []] : {};\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _.groupBy = group(function(result, value, key) {\n    if (has(result, key)) result[key].push(value); else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `groupBy`, but for\n  // when you know that your index values will be unique.\n  _.indexBy = group(function(result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  _.countBy = group(function(result, value, key) {\n    if (has(result, key)) result[key]++; else result[key] = 1;\n  });\n\n  var reStrSymbol = /[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff]/g;\n  // Safely create a real, live array from anything iterable.\n  _.toArray = function(obj) {\n    if (!obj) return [];\n    if (_.isArray(obj)) return slice.call(obj);\n    if (_.isString(obj)) {\n      // Keep surrogate pair characters together\n      return obj.match(reStrSymbol);\n    }\n    if (isArrayLike(obj)) return _.map(obj, _.identity);\n    return _.values(obj);\n  };\n\n  // Return the number of elements in an object.\n  _.size = function(obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : _.keys(obj).length;\n  };\n\n  // Split a collection into two arrays: one whose elements all satisfy the given\n  // predicate, and one whose elements all do not satisfy the predicate.\n  _.partition = group(function(result, value, pass) {\n    result[pass ? 0 : 1].push(value);\n  }, true);\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head` and `take`. The **guard** check\n  // allows it to work with `_.map`.\n  _.first = _.head = _.take = function(array, n, guard) {\n    if (array == null || array.length < 1) return n == null ? void 0 : [];\n    if (n == null || guard) return array[0];\n    return _.initial(array, array.length - n);\n  };\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  _.initial = function(array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  _.last = function(array, n, guard) {\n    if (array == null || array.length < 1) return n == null ? void 0 : [];\n    if (n == null || guard) return array[array.length - 1];\n    return _.rest(array, Math.max(0, array.length - n));\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.\n  // Especially useful on the arguments object. Passing an **n** will return\n  // the rest N values in the array.\n  _.rest = _.tail = _.drop = function(array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  };\n\n  // Trim out all falsy values from an array.\n  _.compact = function(array) {\n    return _.filter(array, Boolean);\n  };\n\n  // Internal implementation of a recursive `flatten` function.\n  var flatten = function(input, shallow, strict, output) {\n    output = output || [];\n    var idx = output.length;\n    for (var i = 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {\n        // Flatten current level of array or arguments object.\n        if (shallow) {\n          var j = 0, len = value.length;\n          while (j < len) output[idx++] = value[j++];\n        } else {\n          flatten(value, shallow, strict, output);\n          idx = output.length;\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  };\n\n  // Flatten out an array, either recursively (by default), or just one level.\n  _.flatten = function(array, shallow) {\n    return flatten(array, shallow, false);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _.without = restArguments(function(array, otherArrays) {\n    return _.difference(array, otherArrays);\n  });\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // The faster algorithm will not work with an iteratee if the iteratee\n  // is not a one-to-one function, so providing an iteratee will disable\n  // the faster algorithm.\n  // Aliased as `unique`.\n  _.uniq = _.unique = function(array, isSorted, iteratee, context) {\n    if (!_.isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n          computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted && !iteratee) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!_.contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!_.contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _.union = restArguments(function(arrays) {\n    return _.uniq(flatten(arrays, true, true));\n  });\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  _.intersection = function(array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (_.contains(result, item)) continue;\n      var j;\n      for (j = 1; j < argsLength; j++) {\n        if (!_.contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _.difference = restArguments(function(array, rest) {\n    rest = flatten(rest, true, true);\n    return _.filter(array, function(value){\n      return !_.contains(rest, value);\n    });\n  });\n\n  // Complement of _.zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices.\n  _.unzip = function(array) {\n    var length = array && _.max(array, getLength).length || 0;\n    var result = Array(length);\n\n    for (var index = 0; index < length; index++) {\n      result[index] = _.pluck(array, index);\n    }\n    return result;\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _.zip = restArguments(_.unzip);\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values. Passing by pairs is the reverse of _.pairs.\n  _.object = function(list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  };\n\n  // Generator function to create the findIndex and findLastIndex functions.\n  var createPredicateIndexFinder = function(dir) {\n    return function(array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  };\n\n  // Returns the first index on an array-like that passes a predicate test.\n  _.findIndex = createPredicateIndexFinder(1);\n  _.findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  _.sortedIndex = function(array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0, high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\n    }\n    return low;\n  };\n\n  // Generator function to create the indexOf and lastIndexOf functions.\n  var createIndexFinder = function(dir, predicateFind, sortedIndex) {\n    return function(array, item, idx) {\n      var i = 0, length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n          i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), _.isNaN);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  };\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);\n  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _.range = function(start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    if (!step) {\n      step = stop < start ? -1 : 1;\n    }\n\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n\n    return range;\n  };\n\n  // Chunk a single array into multiple arrays, each containing `count` or fewer\n  // items.\n  _.chunk = function(array, count) {\n    if (count == null || count < 1) return [];\n    var result = [];\n    var i = 0, length = array.length;\n    while (i < length) {\n      result.push(slice.call(array, i, i += count));\n    }\n    return result;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Determines whether to execute a function as a constructor\n  // or a normal function with the provided arguments.\n  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (_.isObject(result)) return result;\n    return self;\n  };\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if\n  // available.\n  _.bind = restArguments(function(func, context, args) {\n    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');\n    var bound = restArguments(function(callArgs) {\n      return executeBound(func, bound, context, this, args.concat(callArgs));\n    });\n    return bound;\n  });\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. _ acts\n  // as a placeholder by default, allowing any combination of arguments to be\n  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.\n  _.partial = restArguments(function(func, boundArgs) {\n    var placeholder = _.partial.placeholder;\n    var bound = function() {\n      var position = 0, length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length; i++) {\n        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, bound, this, this, args);\n    };\n    return bound;\n  });\n\n  _.partial.placeholder = _;\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  _.bindAll = restArguments(function(obj, keys) {\n    keys = flatten(keys, false, false);\n    var index = keys.length;\n    if (index < 1) throw new Error('bindAll must be passed function names');\n    while (index--) {\n      var key = keys[index];\n      obj[key] = _.bind(obj[key], obj);\n    }\n  });\n\n  // Memoize an expensive function by storing its results.\n  _.memoize = function(func, hasher) {\n    var memoize = function(key) {\n      var cache = memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!has(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    memoize.cache = {};\n    return memoize;\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _.delay = restArguments(function(func, wait, args) {\n    return setTimeout(function() {\n      return func.apply(null, args);\n    }, wait);\n  });\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _.defer = _.partial(_.delay, _, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  _.throttle = function(func, wait, options) {\n    var timeout, context, args, result;\n    var previous = 0;\n    if (!options) options = {};\n\n    var later = function() {\n      previous = options.leading === false ? 0 : _.now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n\n    var throttled = function() {\n      var now = _.now();\n      if (!previous && options.leading === false) previous = now;\n      var remaining = wait - (now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n\n    throttled.cancel = function() {\n      clearTimeout(timeout);\n      previous = 0;\n      timeout = context = args = null;\n    };\n\n    return throttled;\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds. If `immediate` is passed, trigger the function on the\n  // leading edge, instead of the trailing.\n  _.debounce = function(func, wait, immediate) {\n    var timeout, result;\n\n    var later = function(context, args) {\n      timeout = null;\n      if (args) result = func.apply(context, args);\n    };\n\n    var debounced = restArguments(function(args) {\n      if (timeout) clearTimeout(timeout);\n      if (immediate) {\n        var callNow = !timeout;\n        timeout = setTimeout(later, wait);\n        if (callNow) result = func.apply(this, args);\n      } else {\n        timeout = _.delay(later, wait, this, args);\n      }\n\n      return result;\n    });\n\n    debounced.cancel = function() {\n      clearTimeout(timeout);\n      timeout = null;\n    };\n\n    return debounced;\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _.wrap = function(func, wrapper) {\n    return _.partial(wrapper, func);\n  };\n\n  // Returns a negated version of the passed-in predicate.\n  _.negate = function(predicate) {\n    return function() {\n      return !predicate.apply(this, arguments);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _.compose = function() {\n    var args = arguments;\n    var start = args.length - 1;\n    return function() {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  };\n\n  // Returns a function that will only be executed on and after the Nth call.\n  _.after = function(times, func) {\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  };\n\n  // Returns a function that will only be executed up to (but not including) the Nth call.\n  _.before = function(times, func) {\n    var memo;\n    return function() {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _.once = _.partial(_.before, 2);\n\n  _.restArguments = restArguments;\n\n  // Object Functions\n  // ----------------\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n\n  var collectNonEnumProps = function(obj, keys) {\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = _.isFunction(constructor) && constructor.prototype || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';\n    if (has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);\n\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {\n        keys.push(prop);\n      }\n    }\n  };\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`.\n  _.keys = function(obj) {\n    if (!_.isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (has(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve all the property names of an object.\n  _.allKeys = function(obj) {\n    if (!_.isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _.values = function(obj) {\n    var keys = _.keys(obj);\n    var length = keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[keys[i]];\n    }\n    return values;\n  };\n\n  // Returns the results of applying the iteratee to each element of the object.\n  // In contrast to _.map it returns an object.\n  _.mapObject = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys = _.keys(obj),\n        length = keys.length,\n        results = {};\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys[index];\n      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  };\n\n  // Convert an object into a list of `[key, value]` pairs.\n  // The opposite of _.object.\n  _.pairs = function(obj) {\n    var keys = _.keys(obj);\n    var length = keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [keys[i], obj[keys[i]]];\n    }\n    return pairs;\n  };\n\n  // Invert the keys and values of an object. The values must be serializable.\n  _.invert = function(obj) {\n    var result = {};\n    var keys = _.keys(obj);\n    for (var i = 0, length = keys.length; i < length; i++) {\n      result[obj[keys[i]]] = keys[i];\n    }\n    return result;\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`.\n  _.functions = _.methods = function(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // An internal function for creating assigner functions.\n  var createAssigner = function(keysFunc, defaults) {\n    return function(obj) {\n      var length = arguments.length;\n      if (defaults) obj = Object(obj);\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n            keys = keysFunc(source),\n            l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!defaults || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _.extend = createAssigner(_.allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in object(s).\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  _.extendOwn = _.assign = createAssigner(_.keys);\n\n  // Returns the first key on an object that passes a predicate test.\n  _.findKey = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = _.keys(obj), key;\n    for (var i = 0, length = keys.length; i < length; i++) {\n      key = keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  };\n\n  // Internal pick helper function to determine if `obj` has key `key`.\n  var keyInObj = function(value, key, obj) {\n    return key in obj;\n  };\n\n  // Return a copy of the object only containing the whitelisted properties.\n  _.pick = restArguments(function(obj, keys) {\n    var result = {}, iteratee = keys[0];\n    if (obj == null) return result;\n    if (_.isFunction(iteratee)) {\n      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);\n      keys = _.allKeys(obj);\n    } else {\n      iteratee = keyInObj;\n      keys = flatten(keys, false, false);\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  });\n\n  // Return a copy of the object without the blacklisted properties.\n  _.omit = restArguments(function(obj, keys) {\n    var iteratee = keys[0], context;\n    if (_.isFunction(iteratee)) {\n      iteratee = _.negate(iteratee);\n      if (keys.length > 1) context = keys[1];\n    } else {\n      keys = _.map(flatten(keys, false, false), String);\n      iteratee = function(value, key) {\n        return !_.contains(keys, key);\n      };\n    }\n    return _.pick(obj, iteratee, context);\n  });\n\n  // Fill in a given object with default properties.\n  _.defaults = createAssigner(_.allKeys, true);\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  _.create = function(prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) _.extendOwn(result, props);\n    return result;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _.clone = function(obj) {\n    if (!_.isObject(obj)) return obj;\n    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _.tap = function(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  _.isMatch = function(object, attrs) {\n    var keys = _.keys(attrs), length = keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  };\n\n\n  // Internal recursive comparison function for `isEqual`.\n  var eq, deepEq;\n  eq = function(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // `null` or `undefined` only equal to itself (strict comparison).\n    if (a == null || b == null) return false;\n    // `NaN`s are equivalent, but non-reflexive.\n    if (a !== a) return b !== b;\n    // Exhaust primitive checks\n    var type = typeof a;\n    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;\n    return deepEq(a, b, aStack, bStack);\n  };\n\n  // Internal recursive comparison function for `isEqual`.\n  deepEq = function(a, b, aStack, bStack) {\n    // Unwrap any wrapped objects.\n    if (a instanceof _) a = a._wrapped;\n    if (b instanceof _) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, regular expressions, dates, and booleans are compared by value.\n      case '[object RegExp]':\n      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN.\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n      case '[object Symbol]':\n        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);\n    }\n\n    var areArrays = className === '[object Array]';\n    if (!areArrays) {\n      if (typeof a != 'object' || typeof b != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&\n                               _.isFunction(bCtor) && bCtor instanceof bCtor)\n                          && ('constructor' in a && 'constructor' in b)) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var keys = _.keys(a), key;\n      length = keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (_.keys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = keys[length];\n        if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  };\n\n  // Perform a deep comparison to check if two objects are equal.\n  _.isEqual = function(a, b) {\n    return eq(a, b);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _.isEmpty = function(obj) {\n    if (obj == null) return true;\n    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;\n    return _.keys(obj).length === 0;\n  };\n\n  // Is a given value a DOM element?\n  _.isElement = function(obj) {\n    return !!(obj && obj.nodeType === 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _.isArray = nativeIsArray || function(obj) {\n    return toString.call(obj) === '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _.isObject = function(obj) {\n    var type = typeof obj;\n    return type === 'function' || type === 'object' && !!obj;\n  };\n\n  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet.\n  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name) {\n    _['is' + name] = function(obj) {\n      return toString.call(obj) === '[object ' + name + ']';\n    };\n  });\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  if (!_.isArguments(arguments)) {\n    _.isArguments = function(obj) {\n      return has(obj, 'callee');\n    };\n  }\n\n  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,\n  // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).\n  var nodelist = root.document && root.document.childNodes;\n  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {\n    _.isFunction = function(obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  // Is a given object a finite number?\n  _.isFinite = function(obj) {\n    return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj));\n  };\n\n  // Is the given value `NaN`?\n  _.isNaN = function(obj) {\n    return _.isNumber(obj) && isNaN(obj);\n  };\n\n  // Is a given value a boolean?\n  _.isBoolean = function(obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  };\n\n  // Is a given value equal to null?\n  _.isNull = function(obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  // Shortcut function for checking if an object has a given property directly\n  // on itself (in other words, not on a prototype).\n  _.has = function(obj, path) {\n    if (!_.isArray(path)) {\n      return has(obj, path);\n    }\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      var key = path[i];\n      if (obj == null || !hasOwnProperty.call(obj, key)) {\n        return false;\n      }\n      obj = obj[key];\n    }\n    return !!length;\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _.noConflict = function() {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iteratees.\n  _.identity = function(value) {\n    return value;\n  };\n\n  // Predicate-generating functions. Often useful outside of Underscore.\n  _.constant = function(value) {\n    return function() {\n      return value;\n    };\n  };\n\n  _.noop = function(){};\n\n  // Creates a function that, when passed an object, will traverse that object’s\n  // properties down the given `path`, specified as an array of keys or indexes.\n  _.property = function(path) {\n    if (!_.isArray(path)) {\n      return shallowProperty(path);\n    }\n    return function(obj) {\n      return deepGet(obj, path);\n    };\n  };\n\n  // Generates a function for a given object that returns a given property.\n  _.propertyOf = function(obj) {\n    if (obj == null) {\n      return function(){};\n    }\n    return function(path) {\n      return !_.isArray(path) ? obj[path] : deepGet(obj, path);\n    };\n  };\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  _.matcher = _.matches = function(attrs) {\n    attrs = _.extendOwn({}, attrs);\n    return function(obj) {\n      return _.isMatch(obj, attrs);\n    };\n  };\n\n  // Run a function **n** times.\n  _.times = function(n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  };\n\n  // Return a random integer between min and max (inclusive).\n  _.random = function(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  };\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  _.now = Date.now || function() {\n    return new Date().getTime();\n  };\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  var unescapeMap = _.invert(escapeMap);\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + _.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n  _.escape = createEscaper(escapeMap);\n  _.unescape = createEscaper(unescapeMap);\n\n  // Traverses the children of `obj` along `path`. If a child is a function, it\n  // is invoked with its parent as context. Returns the value of the final\n  // child, or `fallback` if any child is undefined.\n  _.result = function(obj, path, fallback) {\n    if (!_.isArray(path)) path = [path];\n    var length = path.length;\n    if (!length) {\n      return _.isFunction(fallback) ? fallback.call(obj) : fallback;\n    }\n    for (var i = 0; i < length; i++) {\n      var prop = obj == null ? void 0 : obj[path[i]];\n      if (prop === void 0) {\n        prop = fallback;\n        i = length; // Ensure we don't continue iterating.\n      }\n      obj = _.isFunction(prop) ? prop.call(obj) : prop;\n    }\n    return obj;\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _.uniqueId = function(prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _.templateSettings = {\n    evaluate: /<%([\\s\\S]+?)%>/g,\n    interpolate: /<%=([\\s\\S]+?)%>/g,\n    escape: /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\": \"'\",\n    '\\\\': '\\\\',\n    '\\r': 'r',\n    '\\n': 'n',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escapeRegExp = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n\n  var escapeChar = function(match) {\n    return '\\\\' + escapes[match];\n  };\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  _.template = function(text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = _.defaults({}, settings, _.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);\n      index = offset + match.length;\n\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offset.\n      return match;\n    });\n    source += \"';\\n\";\n\n    // If a variable is not specified, place data values in local scope.\n    if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + 'return __p;\\n';\n\n    var render;\n    try {\n      render = new Function(settings.variable || 'obj', '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    var template = function(data) {\n      return render.call(this, data, _);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    var argument = settings.variable || 'obj';\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n\n    return template;\n  };\n\n  // Add a \"chain\" function. Start chaining a wrapped Underscore object.\n  _.chain = function(obj) {\n    var instance = _(obj);\n    instance._chain = true;\n    return instance;\n  };\n\n  // OOP\n  // ---------------\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n\n  // Helper function to continue chaining intermediate results.\n  var chainResult = function(instance, obj) {\n    return instance._chain ? _(obj).chain() : obj;\n  };\n\n  // Add your own custom functions to the Underscore object.\n  _.mixin = function(obj) {\n    _.each(_.functions(obj), function(name) {\n      var func = _[name] = obj[name];\n      _.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return chainResult(this, func.apply(_, args));\n      };\n    });\n    return _;\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _.mixin(_);\n\n  // Add all mutator Array functions to the wrapper.\n  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      var obj = this._wrapped;\n      method.apply(obj, arguments);\n      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];\n      return chainResult(this, obj);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  _.each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      return chainResult(this, method.apply(this._wrapped, arguments));\n    };\n  });\n\n  // Extracts the result from a wrapped and chained object.\n  _.prototype.value = function() {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxy for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;\n\n  _.prototype.toString = function() {\n    return String(this._wrapped);\n  };\n\n  // AMD registration happens at the end for compatibility with AMD loaders\n  // that may not enforce next-turn semantics on modules. Even though general\n  // practice for AMD registration is to be anonymous, underscore registers\n  // as a named module because, like jQuery, it is a base library that is\n  // popular enough to be bundled in a third party lib, but not be part of\n  // an AMD load request. Those cases could generate an error when an\n  // anonymous define() is called outside of a loader request.\n  if (typeof define == 'function' && define.amd) {\n    define('underscore', [], function() {\n      return _;\n    });\n  }\n}());\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","\"use strict\";\nvar updatePlot = require('./update.js');\nvar utils = require('./utils.js');\nvar _ = require('underscore');\n\n\nfunction processData(dataObj) {\n    // plotly doesn't support the 'T' date/time separator or the 'Z' at the end\n    // https://help.plot.ly/date-format-and-time-series/#step-2-entering-dates-and-times-in-plotly-s-grid\n    var dates = _.map(dataObj.timestamps, function(date){return date.replace(\"T\",' ').substring(0, date.length-1)});\n    var allData = {\n        dates: dates,\n    };\n    _.extend(allData, dataObj.data);\n    return allData;\n}\n\n\nfunction plotting(dataCache, url, var_names, plotsInfo, div, update, maxPoints, err_callback) {\n    //gets information and updates component\n    $.ajax({\n            type: 'GET',\n            url: url,\n            jsonp: \"callback\",\n            dataType: \"jsonp\",\n\n            success: function(dataObj) {\n                if (dataObj.code != 200) {\n                    console.error(\"Invalid data API query. Code: {0} | Message: {1}\".format(\n                        dataObj.code, dataObj.message));\n                    if (err_callback !== undefined) {\n                        // stop the update timer if specified\n                        err_callback(plotsInfo);\n                    }\n                    return;\n                }\n\n                var graphDiv = document.getElementById(div);\n                var allData = processData(dataObj['results']);\n                // var existingDates = graphDiv.data[0]['x'];\n                var existingDates = dataCache[0]['x'] || [];\n                var dates = allData['dates'];\n                dataObj = {\n                    dates: dates\n                };\n\n                if (dataObj.dates.length == 0) {\n                    console.warn(\"No data available from API\");\n                    return;\n                }\n\n                if (update) {\n                    // first index in the new data that is actually new\n                    var startIndex = 0;\n                    // update only dates that aren't already included\n                    // assume that we don't have any missing dates in the middle\n                    while (startIndex < dates.length && dates[startIndex] <= existingDates[existingDates.length - 1]) {\n                        startIndex++;\n                    }\n\n                    // subset the data if needed\n                    if (startIndex >= dates.length) {\n                        console.info(\"No new data downloaded\");\n                        return;\n                    } else {\n                        for (var i = 0; i < var_names.length; i++) {\n                            dataObj[var_names[i]] = allData[var_names[i]].slice(startIndex);\n                        }\n                        dates = dates.slice(startIndex);\n                        dataObj.dates = dates;\n                    }\n                } else {\n                    // replace the entire data array\n                    for (var i = 0; i < var_names.length; i++) {\n                        dataObj[var_names[i]] = allData[var_names[i]];\n                    }\n                }\n\n                // Update data with\n                updatePlot.updatePlot(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints);\n            }\n    });\n}\n\n\n// 1. the minimum time period (in milliseconds) that a request must cover in order to use\n// 2. MetObs Data API interval specifier\n// 3. reasonable update interval for API given this data interval\nconst intervalLookUp = [\n    // 1 day for 5 minutes\n    [1000*60*60*24, '5m', '-00:10:00'],\n    // 1 month for 1 hour\n    [1000*60*60*24*30*1, '1h', '-02:00:00'],\n    // anything else is 1 minute\n];\n\nconst intervalToSeconds = {\n    '1m': 60,\n    '5m': 60 * 5,\n    '1h': 60 * 60,\n};\n\n\nfunction varNamesForDiv(dataCache) {\n    var varNames = [];\n    _.each(dataCache, function(trace_data) {\n        Array.prototype.push.apply(varNames, trace_data.var_names);\n        if ('anc_variables' in trace_data) {\n            Array.prototype.push.apply(varNames, trace_data.anc_variables);\n        }\n    });\n    return _.uniq(varNames);\n}\n\n\n//poorly ordered function parameters\nfunction requestPlotUpdate(dataCache, div, plotsInfo, startTime, endTime, interval, update, err_callback) {\n    var varNames = varNamesForDiv(dataCache);\n    var stream_string = '';\n    var dt_in_ms;\n    var time_parts;\n    var maxPoints;\n    var time;\n    for (var i in varNames) {\n        stream_string += varNames[i];\n        if (i < varNames.length - 1) stream_string += ':';\n    }\n\n    if (!endTime) {\n        interval = '1m';\n        // hours, minutes, seconds\n        time_parts = _.map(startTime.split(':'), Number);\n        dt_in_ms = -1000 * 60 * 60 * time_parts[0] + 1000 * 60 * time_parts[1] + 1000 * time_parts[2];\n        for (var i in intervalLookUp) {\n            if (dt_in_ms >= intervalLookUp[i][0]) {\n                interval = intervalLookUp[i][1];\n\n                if (update) {\n                    // we only want new data, the passed startTime was only\n                    // used to determine the interval\n                    startTime = intervalLookUp[i][2];\n                }\n            }\n        }\n        time = '&begin=' + startTime;\n    } else {\n        time = '&begin=' + startTime + '&end=' + endTime;\n        if (interval == 'auto') {\n            interval = '1m';\n            dt_in_ms = (new Date(endTime)) - (new Date(startTime));\n            for (var i in intervalLookUp) {\n                if (dt_in_ms >= intervalLookUp[i][0])\n                    interval = intervalLookUp[i][1];\n            }\n        }\n    }\n\n\n    // Maximum number of points (fallback to arbitrary 250)\n    if (update) {\n        maxPoints = intervalToSeconds.hasOwnProperty(interval) ? dt_in_ms / 1000 / intervalToSeconds[interval] : 250;\n    } else {\n        maxPoints = 0; // delete all previous data\n    }\n    var url = utils.buildRequestUrl('json', interval, '', '', 'column', time, stream_string);\n    plotting(dataCache, url, varNames, plotsInfo, div, update, maxPoints, err_callback);\n    return interval;\n}\n\n\n//export functions\nmodule.exports.requestPlotUpdate = requestPlotUpdate;\n","\"use strict\";\nvar Plotly = require('Plotly');\nvar loading = require('../ui/loading.js');\n\n\nfunction getSecondAxisConfig(axis_number, plot_info, axis_info, axis_kwargs) {\n    var key;\n    var axis_config = {\n        gridcolor: '#777777',\n        titlefont: {'size' : 12},\n        title: axis_info['title'],\n        zeroline: false,\n        overlaying: 'y' + (axis_number - 1).toString(),\n        side: 'right',\n        anchor: 'x',\n    };\n\n    for (var idx=0; idx < axis_kwargs.length; idx++) {\n        key = axis_kwargs[idx];\n        if (key in axis_info) {\n            axis_config[key] = axis_info[key];\n        }\n    }\n    return axis_config;\n}\n\n\nfunction coreLobbyLayout(layout, axis_config, axis_number, plot_idx, topOfGraph, graphName, textSize) {\n    layout['xaxis' + axis_number] = {\n        ticktext: ['-6h', '-3h', 'Now'],\n        tickfont: {\n            size: textSize / 5\n        },\n        showline: true,\n        linecolor: 'white',\n        anchor: 'y' + axis_number,\n         // 1 is the far right of the plot, 0 is the far left.\n        // Space the x-axis with the 10% of window width on each side. The bottom row has no middle graph,\n        // which is why we multiply by (1 + Math.floor(plot_idx / 6)).\n        domain: [.1 + 1 / 3 * (plot_idx % 3) * (1 + Math.floor(plot_idx / 6)), 14 / 60 + 1 / 3 * (plot_idx % 3) * (1 + Math.floor(plot_idx / 6))],\n        // xaxis doesn't show its lines.\n        zeroline: false,\n        // hide grid.\n        showgrid: false\n    };\n    // This is the text for the current value above each graph.\n    layout['annotations'].push({\n        font: {\n            size: textSize / 2\n        },\n        showarrow: false,\n        align: 'center',\n        // Middle of each x-axis domain.\n        x: 1/6 + 1 / 3 * (plot_idx % 3) * (1 + Math.floor(plot_idx / 6)), //position in x domain\n        y: topOfGraph + .04, //position in y domain\n        xref: 'paper',\n        yref: 'paper',\n        //Makes text centered\n        showarrow: true,\n        arrowhead: 0,\n        ax: 0,\n        ay: 0,\n      });\n    // This is the text for the name of each graph.\n    layout['annotations'].push({\n        text: graphName,\n        font: {\n            size: textSize / 4\n        },\n        showarrow: false,\n        align: 'center',\n        x: 1/6 + 1 / 3 * (plot_idx % 3) * (1 + Math.floor(plot_idx / 6)), //position in x domain\n        y: topOfGraph + .085, //position in y domain\n        xref: 'paper',\n        yref: 'paper',\n        //Makes text centered\n        showarrow: true,\n        arrowhead: 0,\n        ax: 0,\n        ay: 0,\n      });\n    // Removes title from yaxis.\n    delete axis_config['title']\n    axis_config['tickfont'] = { size: textSize / 5 }\n    axis_config['showgrid'] = false;\n    axis_config['showticklabels'] = true;\n    // Give each subgraph its own y-axis.\n    axis_config['anchor'] = 'x' + axis_number;\n    axis_config['showline'] =  true;\n    axis_config['linecolor'] = 'white';\n    // axis_config are both modified without having to be returned.\n}\n\n\nfunction initPlot(dataCache, div_id, plotOrder, plotsInfo) {\n    var DEFAULT_PLOT_HEIGHT = 170;\n    var nshowing = plotOrder.length;\n    var layout = {\n        title: plotsInfo.title,\n        showlegend: false,\n        height: DEFAULT_PLOT_HEIGHT * nshowing + 180,\n    }\n    // Updates layout with plotsInfo.layout, which is defined for lobby display.\n    Object.assign(layout, plotsInfo.layout)\n    layout['xaxis'] = {\n        //domain affects size of x axis\n        //this made room for the legend\n        //1 is the far right of the plot, 0 is the far left\n        domain: [0, 1],\n\n        //xaxis doesn't show its lines\n        showline: false,\n        zeroline: false,\n\n        //values of the tick labels show up\n        //show right away if we have any starting streams\n        showticklabels: nshowing > 0,\n\n        //its grid is a little darker than default\n        gridcolor: \"#777777\",\n\n        //hide grid\n        showgrid: false,\n        tickformat: '%Y-%m-%d %H:%MZ'\n    };\n    var axis_number = 0;\n    var axis_info;\n    var plot_info;\n    var trace_info;\n    var trace_config;\n    var axis_config;\n    var plot_key;\n    var key;\n    var step = 1 / nshowing;\n    var domain;\n    var x_anchor = axis_number;\n    var trace_kwargs = ['marker', 'color', 'mode', 'zmin', 'zmax', 'y',\n        'contours', 'line', 'colorscale', 'showscale', 'colorbar', 'tick0', 'dtick', 'hovermode'];\n    var axis_kwargs = ['nticks', 'range', 'autorange', 'zeroline', 'showgrid',\n        'tickmode', 'ticktext', 'tickvals'];\n    for (var plot_idx = 0; plot_idx < plotOrder.length; plot_idx++) {\n        plot_key = plotOrder[plot_idx];\n        plot_info = plotsInfo.plots[plot_key];\n        axis_number += 1;\n        x_anchor = axis_number;\n        axis_info = plot_info.yaxis;\n        domain = [(plotOrder.length - 1 - plot_idx) * step * 1.03, 1 - plot_idx * step * 1.05];\n        if (plotsInfo['isLobbyDisplay']) {\n            // Leaves 8% for the header, then divides the rest into thirds with 10% height above and below each graph.\n            domain = [.82 - 8 / 75 - (.2 + 8 / 75) * Math.floor(plot_idx / 3), .82 - (.2 + 8 / 75) * Math.floor(plot_idx / 3)];\n        }\n\n        // Create the necessary traces (lines)\n        for (var trace_info_idx = 0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {\n            trace_info = plot_info.traces[trace_info_idx];\n            trace_config = {\n                name: trace_info['name'],\n                x: [],\n                y: [],\n                text: [],\n                type: trace_info.type ? trace_info.type : 'scatter',\n                // Gives each graph its own x-axis if plotsInfo['isLobbyDisplay'].\n                xaxis: plotsInfo['isLobbyDisplay'] ? 'x' + axis_number : 'x1',\n                yaxis: 'y' + axis_number,\n                hoverinfo: 'x+text',\n                hovermode: 'closest',\n                // meteorogram custom data flags\n                var_names: trace_info['var_names'],\n                anc_variables: trace_info['anc_variables'],\n                anc_data: [],\n                plot_name: plot_key,\n                trace_index: trace_info_idx\n            };\n            // when we have a second trace that is purely there to make the\n            // second y-axis appear, we do this to point the trace to the\n            // correct axis\n            if (trace_info.isSecondAxis) {\n                trace_config.yaxis = 'y' + (axis_number + trace_info_idx);\n            }\n\n            for (var idx = 0; idx < trace_kwargs.length; idx++) {\n                key = trace_kwargs[idx];\n                if (key in trace_info) {\n                    trace_config[key] = trace_info[key];\n                }\n            }\n            if ('colorbar' in trace_config) {\n                trace_config.colorbar.len = domain[1] - domain[0];\n                trace_config.colorbar.y = (domain[1] - domain[0]) / 2 + domain[0];\n                trace_config.z = [];\n            }\n            dataCache.push(trace_config);\n        }\n\n        // Create Y-axis configuration object\n        axis_config = {\n            gridcolor: '#777777',\n            titlefont: { 'size': 12 },\n            title: axis_info['title'],\n            zeroline: false,\n            // where on the canvas does this axis belong\n            domain: domain\n        };\n        if (plotsInfo['isLobbyDisplay']) {\n            coreLobbyLayout(layout, axis_config, axis_number, plot_idx, domain[1], trace_info['name'], plotsInfo['rowTextSize'])\n        }\n\n        for (idx = 0; idx < axis_kwargs.length; idx++) {\n            key = axis_kwargs[idx];\n            if (key in axis_info) {\n                axis_config[key] = axis_info[key];\n            }\n        }\n\n        layout['yaxis' + axis_number] = axis_config;\n\n        // Process second y-axis config\n        // Skip if specified meaning this configuration is only parsed\n        // for additional hover/probe information (custom MetObs thing, not Plotly)\n        if (!plotsInfo['isLobbyDisplay'] && 'yaxis2' in plot_info && !plot_info.yaxis2.skip) {\n            axis_number += 1;\n            axis_info = plot_info.yaxis2;\n            axis_config = getSecondAxisConfig(axis_number, plot_info, axis_info, axis_kwargs);\n            layout['yaxis' + axis_number] = axis_config;\n        }\n        // MetObs custom way of saying \"I want more probe information\n        // if ('probe2' in plot_info) {\n        //     axis_number += 1;\n        //     axis_info = plot_info.probe2;\n        //     axis_config = getSecondAxisConfig(axis_number, plot_info, axis_info, axis_kwargs);\n        //     layout['probe' + axis_number] = axis_config;\n        // }\n    }\n    // xaxis only shows on the bottom most plot\n    layout['xaxis']['anchor'] = 'y' + x_anchor;\n\n    // Toolbar configuration\n    var toolbar = {\n        // Disable link to plotly\n        'showLink': false,\n        // Don't show plotly logo\n        'displaylogo': false,\n        'displayModeBar': true,\n        'responsive': true\n    };\n    if (plotsInfo['isLobbyDisplay']) {\n        // Prevents first graph from taking up entire width, and other layout problems.\n        delete layout['xaxis'];\n        // Adjusts graph sizes every time window size is changed.\n        toolbar = {responsive: true};\n    }\n    //creates new graph\n    Plotly.plot(div_id, dataCache, layout, toolbar);\n    loading.loading();\n}\n\nmodule.exports.initPlot = initPlot;\n","\"use strict\";\nvar ticktext = require('./ticks.js');\nvar utils = require('./utils.js');\n\n/* \n * Build a table in the specified div with a row for each trace in plotsInfo\n * Stores metadata for each trace using $.data, which is retrieved\n * and used by requestTableUpdate\n */\nfunction initTable(div_id, plotOrder, plotsInfo) {\n    var div = $('#'+div_id);\n    var table = $('<table class=\"met_table\"><tbody></tbody></table>');\n    var tbody = table.children('tbody');\n\n    var plot_info;\n    var plot_key;\n    for (var plot_idx=0; plot_idx < plotOrder.length; plot_idx++) {\n        plot_key = plotOrder[plot_idx];\n        plot_info = plotsInfo.plots[plot_key];\n        //extract the necessary variables\n        for (var trace_info_idx=0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {\n            var trace_info = plot_info.traces[trace_info_idx];\n            if(trace_info.type=='contour'){\n                add_contour_rows(tbody,plot_key,trace_info_idx,trace_info,plot_info);\n            }else{\n                var info_td = $('<td>N/A</td>');\n                info_td.addClass('met_data');\n                info_td.data('info', {key:plot_key,idx:trace_info_idx});\n                var row = $('<tr></tr>');\n                var name = trace_info.short_name || trace_info.name;\n                if (name == 'Wind Direction Card') {\n                    continue\n                }\n                row.append('<td>'+name+'</td>');\n                row.append(info_td);\n                row.append('<td class=\"convert\"></td>');\n                tbody.append(row);\n                //add rows for our ancillary variables that normally only show up in tags\n                if(trace_info.anc_variables)\n                    add_anc_rows(tbody,plot_key,trace_info_idx,trace_info);\n            }\n        };\n    }\n    div.append('<h3>'+plotsInfo.title+'</h3>');\n    div.append(table);\n    div.append('<span id=\"timestamp\"></span>');\n};\n\nfunction add_anc_rows(tbody,plot_key,idx,trace_info){\n    for(var anc_info_idx = 0; anc_info_idx < trace_info.anc_variables.length; anc_info_idx++){\n        var anc_info = trace_info.anc_info[trace_info.anc_variables[anc_info_idx]];\n        var info_td = $('<td>N/A</td>');\n        info_td.addClass('met_data');\n        info_td.data('info', {key:plot_key,idx:idx,anc_idx:anc_info_idx});\n        var row = $('<tr></tr>');\n        var name = anc_info.short_name || anc_info.name;\n        row.append('<td>'+name+'</td>');\n        row.append(info_td);\n        row.append('<td class=\"convert\"></td>');\n        tbody.append(row);\n    }\n\n}\n\nfunction add_contour_rows(tbody,plot_key,idx,trace_info,plot_info){\n    var name = trace_info.short_name||trace_info.name;\n    var title_row=('<tr><td colspan=\"2\">'+name+'</td><td></td>');\n    tbody.append(title_row);\n    for(var hightlight_idx = 0;hightlight_idx< trace_info.y_highlight.length;hightlight_idx++){\n        var hightlight_idx_idx = trace_info.y_highlight[hightlight_idx];\n        var row = $('<tr></tr>');\n        var name = trace_info.y[hightlight_idx_idx] + plot_info.yaxis.units;\n        row.append('<td class=\"subtitle text-center\">'+name+'</td>');\n        var info_td = $('<td>N/A</td>');\n        info_td.addClass('met_data');\n        info_td.data('info', {key:plot_key,idx:idx,hl_idx:hightlight_idx_idx});\n        row.append(info_td);\n        row.append('<td class=\"convert\"></td>');\n        tbody.append(row);\n    }\n\n}\n\n/*\n * Build a datastream request from the data tags in div_id's existing meteorogram table,\n * then add labels and alternate units based on the axes objects in plotsInfo\n */\nfunction requestTableUpdate(div_id,plotsInfo) {\n    var div = $('#'+div_id);\n    var varNames = [];\n    var plotOrder = [];\n    var data_cells = $('#'+div_id+' .met_data');\n    var convert_cells = $('#'+div_id+' .convert');\n    var varName;\n    data_cells.each(function(){\n            var key = $(this).data('info').key;\n            var trace_idx = $(this).data('info').idx;\n            var anc_idx = $(this).data('info').anc_idx;\n            var hl_idx = $(this).data('info').hl_idx;\n            var trace = plotsInfo.plots[key].traces[trace_idx];\n            if(plotOrder.indexOf(key)==-1)\n                plotOrder.push(key);\n            if(anc_idx !== undefined)\n                varName = trace.anc_variables[0];\n            else if(hl_idx !== undefined)\n                varName = trace.var_names[hl_idx];\n            else\n                varName = trace.var_names[0];\n            if (!varNames.includes(varName))\n                varNames.push(varName);\n    });\n    var stream_string = varNames.join(':'); \n    //Use a set time that has both buoy and tower records for testing\n    var url = utils.buildRequestUrl('json', '1m', '', '', 'column', '&begin=-00:04:00', stream_string);\n    $.ajax({\n            type: 'GET',\n            url: url,\n            jsonp: \"callback\",\n            dataType: \"jsonp\",\n            success: function(dataObj){\n                dataObj.div_id = div_id;\n                dataObj.plotOrder = plotOrder;\n                dataObj.data_cells = data_cells;\n                dataObj.convert_cells = convert_cells;\n                updateTable(dataObj,plotsInfo);\n            }\n    });\n}\n\nfunction updateTable(dataObj,plotsInfo) {\n    var data = dataObj.results.data;\n    var plot_info;\n    var plot_key;\n    var td_idx = 0;\n    var div_id = dataObj.div_id;\n    var plotOrder = dataObj.plotOrder;\n    var data_cells = dataObj.data_cells;\n    var convert_cells = dataObj.convert_cells;\n    if(dataObj.num_results==0){\n        $('#'+div_id+' #timestamp').html('No recent data');\n        return;\n    }\n    $('#'+div_id+' #timestamp').html('Last updated: '+ dataObj.results.timestamps[0]);\n    for (var plot_idx=0; plot_idx < plotOrder.length; plot_idx++) {\n        plot_key = plotOrder[plot_idx];\n        plot_info = plotsInfo.plots[plot_key];\n        //Fill in a row for each trace in the plot\n        for (var trace_info_idx=0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {\n            var trace_info = plot_info.traces[trace_info_idx];\n            if (trace_info.name == 'Wind Direction Card') {\n                continue\n            }\n            if (trace_info.type=='contour') {\n                td_idx=update_contour_cells(data,data_cells,convert_cells,trace_info,td_idx);\n            } else {\n                var update_val = data[trace_info['var_names'][0]][0];\n                if(update_val || update_val==0){\n                    var units = plot_info.yaxis.units;\n                    var convert = '';\n                    var old_precision = plot_info.yaxis.precision;\n                    plot_info.yaxis.precision=Math.min(old_precision,1);\n                    var orig_val = ticktext.getTickText([update_val],plot_info.yaxis);\n                    plot_info.yaxis.precision = old_precision;\n                    if(plot_info.yaxis2 && plot_info.yaxis2.convert_value != plot_info.yaxis.convert_value){\n                        var convert_units = plot_info.yaxis2.units;\n                        var old_precision = plot_info.yaxis2.precision;\n                        plot_info.yaxis2.precision= Math.min(old_precision,1);\n                        var convert_val = ticktext.getTickText([update_val],plot_info.yaxis2);\n                        plot_info.yaxis2.precision = old_precision;\n                        convert = convert_val+convert_units;\n                    }\n                    data_cells[td_idx].innerHTML=orig_val+units;\n                    convert_cells[td_idx].innerHTML=convert;\n                } else {\n                    data_cells[td_idx].innerHTML='N/A';\n                    convert_cells[td_idx].innerHTML='';\n                }\n                td_idx+=1;\n                //Fill in a row for each anc_var in the plot\n                if (trace_info.anc_variables) {\n                    td_idx=update_anc_cells(data,data_cells,trace_info,td_idx);\n                }\n            }\n        }\n    }\n}\n\n\nfunction update_contour_cells(data,data_cells,convert_cells,trace_info,td_idx){\n    for(var hightlight_idx = 0;hightlight_idx< trace_info.y_highlight.length;hightlight_idx++){\n        var hightlight_idx_idx = trace_info.y_highlight[hightlight_idx];\n        var update_val = data[trace_info['var_names'][hightlight_idx_idx]][0];\n        var units = trace_info.zprobe.units;\n        var orig_val = ticktext.getTickText([update_val],trace_info.zprobe);\n        var convert = '';\n        if(trace_info.zprobe2 && trace_info.zprobe2.convert_value){\n            var convert_units = trace_info.zprobe2.units;\n            var convert_val = ticktext.getTickText([update_val],trace_info.zprobe2);\n            convert = convert_val+convert_units;\n        }\n        data_cells[td_idx].innerHTML=orig_val+units;\n        convert_cells[td_idx].innerHTML=convert;\n        td_idx+=1;\n    }\n    return td_idx;\n}\n\nfunction update_anc_cells(data,data_cells,trace_info,td_idx){\n    for(var anc_info_idx = 0; anc_info_idx < trace_info.anc_variables.length; anc_info_idx++){\n        var anc_key = trace_info.anc_variables[anc_info_idx];\n        var anc_info = trace_info.anc_info[anc_key];\n        var update_val = data[anc_key][0];\n        var orig_val = ticktext.getTickText([update_val],anc_info);\n        if(update_val || update_val==0)\n            data_cells[td_idx].innerHTML=orig_val+anc_info.units;\n        else\n            data_cells[td_idx].innerHTML='N/A';\n        td_idx+=1;\n    }\n    return td_idx;\n}\nmodule.exports.initTable = initTable; \nmodule.exports.requestTableUpdate = requestTableUpdate; \n","var _ = require('underscore');\n\n// Add string formatting if it doesn't exist\nif (!String.prototype.format) {\n  String.prototype.format = function() {\n    var args = arguments;\n    return this.replace(/{(\\d+)}/g, function(match, number) {\n      return typeof args[number] != 'undefined'\n        ? args[number]\n        : match\n      ;\n    });\n  };\n}\n\nfunction getWaterTempProbe(data, plotInfo, traceInfo, allData) {\n    var allProbeText = [];\n    var probeText;\n    var row, col;\n    var rowText;\n    var depth;\n    for (var j=0; j < data.length; j++) {\n        row = data[j];\n        rowText = [];\n        depth = traceInfo.y[j];\n        for (var i=0; i < row.length; i++) {\n            col = row[i];\n\n            probeText = \"Depth: {0}m<br>{1}: {2} °C ({3} °F)\".format(\n                depth.toFixed(1),\n                traceInfo.name,\n                col !== null ? col.toFixed(3) : \"N/A\",\n                col !== null ? getF(col).toFixed(3) : \"N/A\");\n            rowText.push(probeText);\n        }\n        allProbeText.push(rowText);\n    }\n    return allProbeText;\n}\n\nfunction getSpeedMPH(val) {\n    // convert m/s to mph\n    return val * 3600 / 1608;\n}\nfunction getSpeedKTS(val) {\n    //m/s to knots\n    return val * 1.94384;\n}\n\n\nfunction getPresInHg(val) {\n    // hPa to InHg\n    return val * 0.02952998751;\n}\n\n\nfunction getAccumMillimeter(val) {\n    // convert inches to millimeters\n    return val * 25.4;\n}\n\n\nfunction cardinalWDir(degrees){\n    \n    return ['N','NNE','NE','ENE',\n            'E','ESE','SE','SSE',\n            'S','SSW','SW','WSW',\n            'W','WNW','NW','NNW'][Math.floor(((degrees+11.25)%360)/22.5)];\n}\n// Convert C to F degrees\nfunction getF(val) {\n    return val * 1.8 + 32;\n}\n\nfunction getVal(val) {\n    return val;\n}\n\n\nvar CONVERSION_FUNCTIONS = {\n    null: getVal,\n    undefined: getVal,\n    getF: getF,\n    getPresInHg: getPresInHg,\n    getSpeedMPH: getSpeedMPH,\n    getAccumMillimeter: getAccumMillimeter,\n    cardinalWDir: cardinalWDir,\n    getSpeedKTS:getSpeedKTS\n};\n\n\n\nfunction formatValue(val, plotInfo, traceInfo) {\n    var val2;\n    if (val === null) {\n        val = \"\";\n        val2 = \"\";\n    } else {\n        if ('yaxis2' in plotInfo && 'convert_value' in plotInfo.yaxis2) {\n            val2 = CONVERSION_FUNCTIONS[plotInfo.yaxis2.convert_value](val);\n            val2 = (val2.toFixed)?val2.toFixed(plotInfo.yaxis2.precision):val2;\n        } else {\n            val2 = undefined;\n        }\n        val = CONVERSION_FUNCTIONS[plotInfo.yaxis.convert_value](val);\n        val=(val.toFixed)?val.toFixed(plotInfo.yaxis.precision):val;\n    }\n\n    if ('yaxis2' in plotInfo && val2 !== undefined) {\n        return \"{0}: {1}{2} ({3}{4})\".format(\n            traceInfo.name,\n            val, plotInfo.yaxis.units,\n            val2, plotInfo.yaxis2.units);\n    } else {\n        return \"{0}: {1}{2}\".format(\n            traceInfo.name,\n            val, plotInfo.yaxis.units);\n    }\n}\n\nfunction getDewpointProbe(data, plotInfo, traceInfo, allData) {\n    var allProbeText = [];\n    var probeText;\n    var relHum = undefined;\n    if ('anc_variables' in traceInfo && traceInfo.anc_variables.length == 1) {\n        relHum = allData[traceInfo.anc_variables[0]];\n    }\n    var rh_info = traceInfo.anc_info[traceInfo.anc_variables[0]];\n    if(!rh_info)\n        rh_info={ name: traceInfo.anc_variables[0], units: '', precision: 2};\n\n    for (var i=0; i < data.length; i++) {\n        probeText = formatValue(data[i], plotInfo, traceInfo);\n        if (relHum !== undefined) {\n            probeText += \"<br>{0}: {1}{2}\".format(rh_info.name,\n                    relHum[i] ? relHum[i].toFixed(rh_info.precision) : \"\",\n                    rh_info.units);\n        }\n        allProbeText.push(probeText);\n    }\n    return allProbeText;\n}\n\n\nfunction defaultProbeText(data, plotInfo, traceInfo, allData) {\n    // assume traces share the same 'x'\n    var allProbeText = [];\n    for (var i=0; i < data.length; i++) {\n        allProbeText.push(formatValue(data[i], plotInfo, traceInfo));\n    }\n    return allProbeText;\n}\n\n\nvar PROBE_TEXT_FUNCTIONS = {\n    undefined: defaultProbeText,\n    null: defaultProbeText,\n    dewpoint: getDewpointProbe,\n    water_temp: getWaterTempProbe,\n};\n\n\nfunction getProbeText(data, plotInfo, traceInfo, allData) {\n    if ('probe_text' in traceInfo) {\n        return PROBE_TEXT_FUNCTIONS[traceInfo.probe_text](data, plotInfo, traceInfo, allData);\n    }\n    return defaultProbeText(data, plotInfo, traceInfo, allData);\n}\n\n\nfunction getTickText(values, axis_info) {\n    var tickText = [];\n    for (var i=0; i < values.length; i++) {\n        var val = CONVERSION_FUNCTIONS[axis_info.convert_value](values[i]);\n        val = (val.toFixed)?val.toFixed(axis_info.precision):val;\n        tickText.push(val);\n    }\n    return tickText;\n}\n\n\n/**\n* the purpose of this method is to get the spacing for the y axis\n* For deg F and deg C\n* @param min - minimum of the temp or dew point array\n* @param max - maximum of the temp or dew point array\n* @return array of 4 tick values for the y axis\n*/\n\nfunction getTickVals(min, max, bump) {\n    var extra = (max - min) * 0.02;\n    min = min - extra;\n    max = max + extra;\n    var step = (max - min) / 4.;\n    //create 4 tick values for the y axis\n    return _.range(min, max + step, step);\n}\n\n\nmodule.exports.getTickVals = getTickVals;\nmodule.exports.getProbeText = getProbeText;\nmodule.exports.getTickText = getTickText;\n\n\n\n\n","var Plotly = require('Plotly');\nvar ticktext = require('./ticks.js');\nvar _ = require('underscore');\n\n\nfunction removeOldPoints(dataCache, removeCount) {\n    for (var i = 0; i < dataCache.length; i++) {\n        dataCache[i].x.splice(0, removeCount);\n\n        if (dataCache[i].hasOwnProperty('z')) {\n            for (var j = 0; j < dataCache[i].z.length; j++) {\n                dataCache[i].z[j].splice(0, removeCount);\n            }\n        } else if (dataCache[i].hasOwnProperty('y')) {\n            // delete things from y *only* if we don't have a Z\n            dataCache[i].y.splice(0, removeCount);\n        }\n        if (dataCache[i].hasOwnProperty('text')) {\n            dataCache[i].text.splice(0, removeCount);\n        }\n    }\n}\n\n\nfunction formatDate(date, formatString, hour12) {\n    var date = new Date(date);\n    var time = date.toLocaleString(undefined, { hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: hour12 });\n    var month = date.getMonth() + 1;\n    month = month < 10 ? '0' + month : month;\n    date = date.toString().split(' ');\n    var dateInfo = {\n        day_name: date[0],\n        month_name: date[1],\n        month: month,\n        day: date[2],\n        year: date[3],\n        time: time,\n    }\n    // https://stackoverflow.com/questions/36529417/javascript-insert-variables-at-a-specific-place-in-a-string\n    return formatString.replace(/\\{([^}]*)\\}/g, function($0, $1) {\n        return dateInfo[$1] || $0;\n    });\n}\n\n\nfunction updateHeader(dataCache, unitCount, layoutUpdates) {\n    // Note: curr_date is 2 minutes behind the current time.\n    var curr_date = dataCache[0]['x'][dataCache[0]['x'].length - 1];\n    // Date() takes + ' UTC' as a way to know the given date is UTC and converts it to local time.\n    var hour = Number(formatDate(curr_date + ' UTC', '{time}', false).split(':')[0]);\n    // Make the screen go black between 1 and 5 am.\n    if (0 < hour && hour < 5) {\n        document.getElementById(\"overlay\").style.opacity = 1;\n    } else {\n        document.getElementById(\"overlay\").style.opacity = 0;\n    }\n    var date_local = formatDate(curr_date + ' UTC', '{day_name}, {month_name} {day}, {year} {time}', true);\n    var date_utc = formatDate(curr_date, '{year}-{month}-{day} {time}Z', false);\n    var elevation = unitCount == 0 ? '327.5 meters' : '1074.5 feet';\n    layoutUpdates['annotations.1.text'] = 'Data last recorded at: ' + date_utc + ' [' + date_local + ' Local]          RIG Elevation = ' + elevation;\n}\n\n\nfunction changeCamera() {\n    var directions = {'north': 'east', 'east': 'south', 'south': 'west', 'west': 'north',};\n    // Gets witch direction the current camera is showing.\n    var newDirection = directions[document.getElementById('roofCam').src.split('/')[7]];\n    // Makes image update. Image updates every (about) 2 minutes and 15 seconds.\n    document.getElementById('roofCam').alt = document.getElementById('dirText').innerHTML = newDirection;\n    document.getElementById('roofCam').src = 'http://metobs.ssec.wisc.edu/pub/cache/aoss/cameras/' + newDirection +\n                                             '/latest_orig.jpg?t=' + new Date().getTime();\n}\n\n\nfunction changeUnits(dataCache, graphDiv, plotsInfo, unitCount) {\n    // Note: unitCount alternates between 0 and 1.\n    var plotName;\n    var plotInfo;\n    var currData;\n    var tick_dates;\n    // This changes the graphDiv y-axis we are getting.\n    var axis_number;\n    // This changes the plotInfo y-axis we are getting, which switches between units every time changeUnits is called.\n    var yaxis = unitCount == 0 ? 'yaxis' : 'yaxis2';\n    var converted_tickvals;\n    var tickvals;\n    var layoutUpdates = {};\n    updateHeader(dataCache, unitCount, layoutUpdates);\n    // Update  each subgraph's displayed y-axis and current data values.\n    for (var i = 0; i < dataCache.length; i++) {\n        axis_number = i == 0 ? '' : i + 1;\n        tick_dates = dataCache[i]['x'];\n        // Prevents '-6h' from falling off x-axis.\n        layoutUpdates['xaxis' + axis_number + '.tickvals'] = [ tick_dates[0], tick_dates[Math.round(tick_dates.length / 2)], tick_dates[tick_dates.length - 1]]\n        plotName = dataCache[i].plot_name;\n        plotInfo = plotsInfo.plots[plotName];\n        // Convert data to the correct units.\n        currData = ticktext.getTickText([dataCache[i]['y'][dataCache[i]['y'].length - 1]], plotInfo[yaxis])[0];\n        layoutUpdates['annotations[' + (3 + 2 * i) + '].text'] = currData + '' + plotInfo[yaxis]['units']\n        tickvals = graphDiv.layout['yaxis' + axis_number]['tickvals']\n        if (tickvals != undefined) {\n            // Relative Humidity and Wind Direction ticktext and tickvals are static from site_configs_lobby.js.\n            if (plotName == 'wind_direction' || plotName == 'rel_hum') {\n                converted_tickvals = plotInfo[yaxis]['ticktext'];\n            } else {\n                converted_tickvals = [];\n                for (var j = 0; j < tickvals.length; j++) {\n                    converted_tickvals.push(ticktext.getTickText([tickvals[j]], plotInfo[yaxis]))\n                }\n            }\n            layoutUpdates['yaxis' + axis_number + '.ticktext'] = converted_tickvals;\n        }\n    }\n    // Updates everything at once to save time.\n    Plotly.relayout(graphDiv, layoutUpdates);\n    changeCamera();\n}\n\n\nfunction fitGraphs(dataCache, data, var_name, layoutUpdates, yaxis, defaultTickVals) {\n    // Set the range of each graph if applicable.\n    if (var_name != 'aoss.tower.rel_hum' && var_name != 'aoss.tower.wind_direction') {\n        // data only contains new data. Thus we must keep track of old mins/maxs.\n        if (dataCache['y'].length == 0) {\n            // dataCache['y'] gets overridden somewhere.\n            dataCache.yMin = Math.min(...data)\n            dataCache.yMax = Math.max(...data)\n        } else {\n            dataCache.yMin = Math.min(...data, dataCache.yMin)\n            dataCache.yMax = Math.max(...data, dataCache.yMax)\n        }\n\n        var spread = dataCache.yMax - dataCache.yMin;\n        var bottom = dataCache.yMin - spread;\n        var top = var_name == 'aoss.tower.solar_flux' ? dataCache.yMax : dataCache.yMax + spread;\n        // Make graph visible if flat line: Add a margin equal to 10% of the value if non-zero, else scale from 0 to 1.\n        if (spread == 0) {\n            // Note: top == bottom since spread == 0.\n            if (top > 0) {\n                top = top * 1.1\n                bottom = bottom * .9\n            } else if (top < 0) { // Only applies to air_temp and dewpoint.\n                top = top * .9\n                bottom = bottom * 1.1\n            } else { // Mainly for precipitation.\n                top = .1\n                bottom = -.1\n            }\n        }\n        // Used to lower bottom so that the graph can be seen if it is 0.\n        var tick0 = bottom\n        // If bottom < 0: Make the bottom 0 since values cannot be negative,\n        // and lower the bottom to see 0.\n        if (var_name != 'aoss.tower.air_temp' && var_name != 'aoss.tower.dewpoint' && bottom <= 0) {\n            bottom = 0;\n            tick0 = 0;\n        }\n        // Shifts the bottom down so that tick0 doesn't overlap xaxis ticks, and graphs near zero can be seen.\n        bottom -= .075 * spread + .001;\n        layoutUpdates[yaxis + '.tickvals'] = [tick0, tick0 + (top - tick0) / 4, tick0 + 2 * (top - tick0) / 4,\n                                              tick0 + 3 * (top - tick0) / 4, top]\n        layoutUpdates[yaxis + '.range'] = [bottom, top]\n    } else {\n        layoutUpdates[yaxis + '.tickvals'] = defaultTickVals\n    }\n    // layoutUpdates is changed without having to return it.\n}\n\n\nfunction replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints) {\n    var dates = dataObj.dates;\n    var plotName;\n    var plotInfo;\n    var i;\n    var probeText;\n    var plotHandled = [];\n    var forceRedraw = false;\n\n    // scatter updates\n    var tracesToExtend = [];\n    var extendData = {\n        x: [],\n        y: [],\n        text: [],\n    };\n\n    // contour updates\n    var newContourData;\n    var contourTracesToExtend = [];\n    var contourExtendData = {\n        x: [],\n        z: [],\n        text: [],\n    };\n\n    var traceIndex = 0;\n\n    // Variables used for lobby display.\n    var layoutUpdates = {};\n    var axis_number;\n    /**\n     *\n     * If we are updating the plots instead of replacing them, then try\n     * to use plotly's extendTraces to update the x and y coordinates as well\n     * the hovering probe text. This should only add new trace points instead\n     * of updating all points.\n     *\n     * Since we passed 'dataCache' to plotly's 'plot' function during\n     * initialization any changes to 'dataCache' should be mirrored in Plotly's\n     * plot and vice versa. See the below stackoverflow question for details.\n     * https://stackoverflow.com/questions/45759582/plotly-how-to-discard-older-points\n     * This is important since we use `.shift()` on the data arrays to remove\n     * \"old\" elements.\n     *\n     * We have to operate per-plot because some of our plots hover/probe labels\n     * use the trace values to come up with one probe box\n     * (air temp + dewpoint -> relative humidity).\n     *\n     */\n    for (i = 0; i < dataCache.length; i++) {\n        plotName = dataCache[i].plot_name;\n        if (plotHandled[plotHandled.length - 1] == plotName) {\n            // this happens when there are more than one trace in a plot\n            continue;\n        }\n        plotInfo = plotsInfo.plots[plotName];\n        _.each(plotInfo.traces, function (traceInfo, index) {\n\n            if (dataCache[traceIndex + index].type == 'contour') {\n                // push new dates for each trace to be extended\n                contourExtendData.x.push(dates);\n                contourTracesToExtend.push(traceIndex + index);\n                // update the Z data instead of the traditional 'y' data\n                // assumes Y doesn't update between calls\n                newContourData = _.map(traceInfo.var_names, function(var_name) {return dataObj[var_name];});\n                dataCache[i].text.push(...ticktext.getProbeText(newContourData, plotInfo, traceInfo, dataObj));\n                for (var j = 0; j < traceInfo.var_names.length; j++) {\n                    while (j >= dataCache[i].z.length) {\n                        dataCache[i].z.push([]);\n                    }\n                    dataCache[i].z[j].push(...dataObj[traceInfo.var_names[j]]);  // ES6-style push\n                }\n                contourExtendData.z.push(dataCache[i].z);\n                contourExtendData.text.push(dataCache[i].text);\n                // If plotly could handle extendTraces in the x-dimension we'd\n                // probably do something like this:\n                // newContourData = _.map(traceInfo.var_names, function(var_name) {return dataObj[var_name];});\n                // contourExtendData.z.push(newContourData);\n                // contourExtendData.text.push(\n                //     [ticktext.getProbeText(newContourData, plotInfo, traceInfo, dataObj)]\n                // );\n            } else {\n                // push new dates for each trace to be extended\n                extendData['x'].push(dates);\n                tracesToExtend.push(traceIndex + index);\n                // scatter plots, assume the y data is the data being updated\n                _.each(traceInfo.var_names, function (var_name) {\n                    if (plotsInfo['isLobbyDisplay']) {\n                        axis_number = i == 0 ? '': i + 1;\n                        fitGraphs(dataCache[i], dataObj[var_name], var_name, layoutUpdates, 'yaxis' + axis_number, plotInfo['yaxis2']['tickvals'])\n                    }\n                    // push the entire new data array as one element to update\n                    extendData.y.push(dataObj[var_name]);\n\n                    // Get new probe text shown when hovering over the traces\n                    if ('probe_text' in traceInfo && traceInfo['probe_text'] === null) {\n                        // we don't want probe text for this trace\n                        probeText = [undefined];\n                    } else {\n                        probeText = ticktext.getProbeText(dataObj[var_name], plotInfo, traceInfo, dataObj);\n                    }\n                    extendData.text.push(probeText);\n                });\n            }\n        });\n        traceIndex += plotInfo.traces.length;\n        plotHandled.push(plotName);\n    }\n\n    // Have plotly update the graph with the new points in extendData\n    // This will add data to 'dataCache' because of how we originally\n    // created the plots.\n    if (tracesToExtend.length > 0) {\n        Plotly.extendTraces(graphDiv, extendData, tracesToExtend);\n    }\n    if (contourTracesToExtend.length > 0) {\n        Plotly.extendTraces(graphDiv, contourExtendData, contourTracesToExtend);\n        // we are currently cheating and re-adding every \"row\" of data because\n        // plotly doesn't support extendTrace'ing in the x-dimension\n        // we want to remove the previous \"depth\" amount of rows\n        for (i = 0; i < contourTracesToExtend.length; i++) {\n            dataCache[contourTracesToExtend[i]].z.splice(0, dataCache[contourTracesToExtend[i]].y.length);\n            dataCache[contourTracesToExtend[i]].text.splice(0, dataCache[contourTracesToExtend[i]].y.length);\n        }\n    }\n\n    if (maxPoints == 0 && !update) {\n        // we aren't doing realtime updates and the caller wants us to remove\n        // all previous points and keep all new points\n        maxPoints = dataObj.dates.length;\n        // we have to force a redraw of the plot because the removed plots\n        // will still exist on the the graph otherwise (until the next update)\n        forceRedraw = true;\n    }\n    // If adding these new points gave us more points than we need\n    // remove the points at the beginning of our data\n    if (maxPoints > 0 && dataCache[0]['x'].length > maxPoints) {\n        removeOldPoints(dataCache, dataCache[0].x.length - maxPoints);\n    }\n\n    // If lobby display and data to update.\n    if (Object.keys(layoutUpdates).length != 0) {\n        // Updates everything at once to save time. Should be done after all dataCache manipulations.\n        Plotly.relayout(graphDiv, layoutUpdates);\n        // The first time through, call changeUnits to display current data.\n        if (!update) {\n            changeUnits(dataCache, graphDiv, plotsInfo, 0);\n        }\n    }\n    if (forceRedraw) {\n        Plotly.redraw(graphDiv);\n    }\n}\n\n\nfunction updatePlot(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints) {\n    replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints);\n}\n\nmodule.exports.updatePlot = updatePlot;\nmodule.exports.changeUnits = changeUnits;\n","\"use strict\";\n\nfunction buildRequestUrl(format, interval, epoch, sep, order, time, streams) {\n    var request_url = METOBS_API_URL+'/api/data.'+format+'?';\n    request_url += 'interval='+interval;\n    request_url += '&epoch='+epoch;\n    request_url +='&sep='+sep || ',';\n    request_url += '&order='+order;\n    request_url+=time;\n    request_url+='&symbols='+streams;\n    return request_url;\n}\n\nmodule.exports.buildRequestUrl = buildRequestUrl;\n","const checkboxTemplates = {\n    'aoss.tower': '<div class=\"form-group\">'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"temp\">Temperature + Dewpoint'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"pres\">Pressure'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"wS\">Wind Speed'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"wD\">Wind Direction'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"aP\">Precipitation'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"sF\">Solar Flux'+\n        '</label>'+\n        '</div>',\n    'mendota.buoy': '<div class=\"form-group\">'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"temp\">Temperature + Dewpoint'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"rh\">Relative Humidity'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"wS\">Wind Speed'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"wD\">Wind Direction'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"chlor\">Chlorophyll'+\n        '</label>'+\n        '<label class=\"form-check-label\">'+\n        '<input type=\"checkbox\" class=\"form-check-input\" checked id=\"phyco\">Phycocyanin'+\n        '</label>'+\n        '</div>'\n};\n\nconst controlPanelTemplate = '<div class=\"row\" id=\"control-panel-row\">'+\n'<div id=\"show-hide-boxes\" class=\"col-md-12\">'+\n'</div>'+\n'<div class = \"col-md-9\">'+\n'<div class=\"row\" style=\"padding: 0 1em;\">'+\n'<div class=\"form-group\">'+\n'<table style=\"width:100%\">'+\n'<tr>'+\n'<td>'+\n'<div class=\"radio\">'+\n'<label><input type=\"radio\" id=\"last_x_days\" name=\"time_select\">'+\n'Recent Data:'+\n'</label>'+\n'</div>'+\n'</td>'+\n'<td>'+\n'<select class=\"form-control\" id=\"dropDownId\">'+\n'<option selected value=\"realtime\">Realtime Update</option>'+\n'<option value=\"-1:00:00\">Past 1 Hour</option>'+\n'<option value=\"-2:00:00\">Past 2 Hours</option>'+\n'<option value=\"-3:00:00\">Past 3 Hours</option>'+\n'<option value=\"-6:00:00\">Past 6 Hours</option>'+\n'<option value=\"-12:00:00\">Past 12 Hours</option>'+\n'<option value=\"-18:00:00\">Past 18 Hours</option>'+\n'<option value=\"-24:00:00\">Past 24 Hours</option>'+\n'<option value=\"-96:00:00\">Past 4 Days</option>'+\n'</select>'+\n'</td>'+\n'<td style=\"padding-left:.5em\">'+\n'<div class=\"radio\">'+\n'<label><input type=\"radio\" id=\"date_range\" name=\"time_select\">'+\n'Date Range:'+\n'</label>'+\n'</div>'+\n'</td>'+\n'<td>'+\n'<input class=\"form-control\" style=\"padding 0.5em 0;\" id=\"Start-date-picker\" type=\"text\" placeholder=\"YYYY-MM-DD\"/>'+\n'</td>'+\n'<td>to </td>'+\n'<td>'+\n'<input class=\"form-control\" style=\"padding 0.5em 0;\" id=\"End-date-picker\" type=\"text\" placeholder=\"YYYY-MM-DD\"/>'+\n'</td>'+\n'<td>'+\n'<button class=\"btn btn-primary btn-block\" id=\"plot-btn\">Plot</button>'+\n'</td>'+\n'</tr>'+\n'</table>'+\n'</div>'+\n'</div>'+\n'</div>'+\n'</div>'\n;\nmodule.exports = {\n    controlPanelTemplate:controlPanelTemplate,\n    checkboxTemplates:checkboxTemplates\n}\n","\"use strict\";\n\n//var $ = require('jquery');\n//var jQuery = require('jquery');\n\nvar loading = require('./loading.js');\nconst controlPanelTemplate = require('./button_template.js');\n\n/**\n* The purpose of this method is to tell dispatcher\n* Oh, please check if user's entering stuff correctly\n*\n* no params\n* no returns\n*/\n\nfunction dispatchCustom(dispatcher)\n{\n    dispatcher.dispatch({\n        status:'get_between_dates',\n        'emit':'plotEmitter',\n        'start':$('#Start-date-picker').val().split(' ').join('T')+':00',\n        'end':$('#End-date-picker').val().split(' ').join('T')+':00',\n        'interval':'auto',\n    });\n}\n\n\n/**\n* The purpose of this method is to send dispatcher user information\n*\n* no params\n* no returns\n*/\n\nfunction getUserInfo(dispatcher)\n{\n    //show gif\n    loading.loading();\n\n    //get the information from the text boxes\n    var startDate = $('#Start-date-picker').val();\n    var endDate = $('#End-date-picker').val();\n    var startTime = $('#Start-time-picker').val();\n    var endTime = $('#End-time-picker').val();\n    var interval = $('#interval option:selected');\n    var intervalVal = interval.data(\"name\");\n\n    //store in user info\n    var userInfo = {'startDate' : startDate,\n                    'startTime' : startTime,\n                    'endDate': endDate,\n                    'endTime': endTime,\n                    'interval': intervalVal};\n\n    //send to dispatcher\n    setTimeout(function() {dispatch.dispatch({status: 'plot_custom', 'emit': 'plotEmitter', 'userInfo': userInfo});}, 200);                 \n}\n\n\n/**\n* The purpose of this method is to tell dispatcher, time to check if we need to update\n*\n* no params\n* no returns\n*/\n\nfunction dispatchUpdate(dispatcher)\n{\n    dispatcher.dispatch({'status': 'update', 'emit': 'plotEmitter'});\n}\n\n/**\n* The purpose of this method is to figure out what the user wants to do based upon\n* what the user selects on the task dropdown\n*\n* no params\n* no returns\n*/\n\nfunction dropDown(selectedText, dispatcher) {\n    if (selectedText == 'realtime') {\n        dispatcher.dispatch({\n            status:'get_since_now',\n            'emit':'plotEmitter',\n            'time':'-3:00:00'\n        });\n\n    } else {\n        var timeDelta = selectedText;\n        dispatcher.dispatch({\n            status:'get_since_now',\n            'emit':'plotEmitter',\n            'time':selectedText\n        });\n    }\n}\n\nvar bind_daterange_actions = function(jQ_div,dispatcher){\n    //bind to custom buttons and dropdowns\n    $(jQ_div+' #plot-btn').click(function(){dispatchCustom(dispatcher)});\n    $(jQ_div+' #dropDownId').change(function(){dropDown($(this).val(),dispatcher)});\n}\nvar set_active_form = function(which_block,jQ_div){\n    $(jQ_div+\" #dropDownId\").prop(\"disabled\",which_block!=\"recent\");\n\n    $(jQ_div+\" #interval\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #Start-date-picker\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #End-date-picker\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #Start-time-picker\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #End-time-picker\").prop(\"disabled\",which_block!=\"range\");\n    $(jQ_div+\" #plot-btn\").prop(\"disabled\",which_block!=\"range\");\n}\n\nvar set_form_datepickers = function(jQ_div){\n    $(jQ_div+' #Start-date-picker').datetimepicker({\n        changeMonth: true, \n        changeYear: true,\n        dateFormat:'yy-mm-dd',\n        timeFormat:'HH:mm',\n        showSecond:false,\n        showMillisec:false,\n        showMicrosec:false\n    });\n\n    $(jQ_div+' #End-date-picker').datetimepicker({\n        changeMonth: true, \n        changeYear: true,\n        dateFormat:'yy-mm-dd',\n        timeFormat:'HH:mm',\n        showSecond:false,\n        showMillisec:false,\n        showMicrosec:false\n    });\n\n    //bind the enabling/disabling of forms to radio buttons\n    $(jQ_div+' [type=text]').prop(\"disabled\",true);\n    $(jQ_div+' select').prop(\"disabled\",true);\n    $(jQ_div+\" #last_x_days\").click(function(){\n        set_active_form(\"recent\",jQ_div);\n    });\n    $(jQ_div+\" #date_range\").click(function(){\n        set_active_form(\"range\",jQ_div);\n    });\n    //$('#Start-time-picker').editableSelect();\n    //$('#End-time-picker').editableSelect();\n    //add placeholder values for the order forms    \n    //$('#Start-date-picker').attr('placeholder',moment.utc().subtract(5,'days').format('YYYY-MM-DD'));\n    //$('#End-date-picker').attr('placeholder',moment.utc().format('YYYY-MM-DD'));\n    //Firefox (+others maybe) keep buttons selected on page reload\n    //enable the currrently selected one's field\n    $(jQ_div+\" #last_x_days\").trigger('click');\n\n};\n\nvar setup_all_forms = function(div,plot_div,dispatcher){\n    var jQ_div = '#'+div;\n    set_form_datepickers(jQ_div,plot_div);\n    bind_daterange_actions(jQ_div,dispatcher);\n}\n\nfunction buildFormInDiv(div, plot_div,dispatcher) {\n    $('#'+div).append(controlPanelTemplate.controlPanelTemplate);\n    //$('#'+div+ \" #show-hide-boxes\").append(controlPanelTemplate.checkboxTemplates[site]);\n    setup_all_forms(div,plot_div,dispatcher);\n}\n$(document).ready(function(){\n    //Hide all form errors initially\n    //Set up the date range inputs as datepicker objects\n});\n\nmodule.exports = buildFormInDiv;\n","\"use strict\";\n//var $ = require('jquery');\n\n/**\n* The purpose of this function is to either hide the graph and show the loading\n* spinner or to hide the loading spinner and show the graph\n* no parameters or returns\n*/\n\nfunction loading()\n{\n    return;\n    //$(\"#progress\").toggle();\n    //$(\"#graph\").toggle();\n}\n\n/**\n* The point of this method is to disable the custom area of the meteorogram\n* header\n*\n* no params\n* no returns\n*/\n\nfunction disable()\n{\n\t//disable custom rows\n\t$('#Start-date-picker').prop(\"disabled\", true);\n\t$('#Start-time-picker').prop(\"disabled\", true);\n\t$('#End-date-picker').prop(\"disabled\", true);\n\t$('#End-time-picker').prop(\"disabled\", true);\n\t$('#interval').prop(\"disabled\", true);\n\t$('#Plot').prop(\"disabled\", true);\n}\n\n/**\n* The purpose of this method is to enable the custom area of the meteorogram\n* header\n*\n* no params\n* no returns\n*/\n\nfunction enable()\n{\n\t//enable custom rows\n\t$('#Start-date-picker').prop(\"disabled\", false);\n\t$('#Start-time-picker').prop(\"disabled\", false);\n\t$('#End-date-picker').prop(\"disabled\", false);\n\t$('#End-time-picker').prop(\"disabled\", false);\n\t$('#interval').prop(\"disabled\", false);\n}\n\n/**\n* The purpose of this function is to take a date string and a time string and turn that\n* into a date JS object\n*\n* @param dateString - \"MM/DD/YYYY\"\n* @param timeString - \"HH-MM-SS\"\n* @return date object\n*/\n\nfunction getDate(dateString, timeString)\n{\n\t//get date string\n\tvar year = parseInt(dateString.substring(6,10));\n\tvar month = parseInt(dateString.substring(0,3));\n\tvar day = parseInt(dateString.substring(3,5));\n\tvar hour = parseInt(timeString.substring(0,2));\n\tvar minute = parseInt(timeString.substring(3,5));\n\tvar seconds = parseInt(timeString.substring(6,8));\n\n    //return date variable\n    var date = new Date(year, month, day, hour, minute, seconds);\n\n    return date;\n}\n\n/**\n* The purpose of this method is to make sure each field is valid and does\n* not result in too much or too less data points being plotted\n* @param start date - the date the user wants to start at\n* @param time user wants to start at\n* @param end Date - the date user wants to stop at\n* @param end Time - the time the user wants to stop at\n* @param interval - how many seconds averaged does the user want\n* no returns\n*/\n\n/**\n* The purpsoe of this method is to enable the plot button\n*\n* no params\n* no returns\n*/\n\nfunction enablePlot()\n{\n\t//enable plot button\n\t$('#Plot').prop(\"disabled\", false);\n}\n\n/**\n* The purpose of this method is to disable the plot button\n*\n* no params\n* no returns\n*/\n\nfunction disablePlot()\n{\n\t//disable plot button\n\t$('#Plot').prop(\"disabled\", true);\n}\n\nfunction checkFields(startDate, endDate, startTime, endTime, interval)\n{\n\t//get user information from selected drop down\n\tvar selected = $('#interval option:selected');\n\n    //give user time to fill out other fields\n\tif(selected.text() == '--');\n\n\telse\n\t{\n\t\t//get information to create a message to the user saying approx how many pts\n\t\t//they are plotting\n        var start = getDate(startDate, startTime);\n        var end = getDate(endDate, endTime);\n        var selected = $('#interval option:selected');\n        var diff = (end - start)/1000;\n        var intervalVal = selected.data(\"seconds\");\n        diff = Math.floor(diff/intervalVal);\n        var points = diff/interval;\n\n        //if too few points, tell user\n        if(diff >= 0 && diff < 60)\n        {\n        \t$('#prompt_user').html('a ' + selected.text() + ' interval would plot about ' + diff.toString() \n        \t\t + ' data points; that\\'s too few - please try again');\n\t\t\t$('#default').attr('selected', 'selected');\n\t\t\tdisablePlot();\n        }\n\n        //if the user accidentally mixed up start and end dates, politely tell them\n        else if(diff < 0)\n        {\n        \t$('#prompt_user').html('The end date is before the start date. Please choose a later end date.');\n\t\t\t$('#default').attr('selected', 'selected');\n        }\n\n        //if too many points, tell user\n        else if(diff > 1000)\n        {\n        \t$('#prompt_user').html('a ' + selected.text() + ' interval would plot about '\n        \t\t+ diff.toString() + ' data points; that\\'s too many - please try again');\n\t\t\t$('#default').attr('selected', 'selected');\n\t\t\tdisablePlot();\n        }\n\n        //else we enable the plot button and tell user how many points they're plotting\n        else\n        {\n        \t$('#prompt_user').html('a ' + selected.text() + ' interval would plot about '\n        \t\t+ diff.toString() + ' data points.');\n\n\t\t\tenablePlot();\n        }\n\n\t}\n}\n\n/**\n* The purpose of this method is to make sure all the fields and intervals selected are valid\n*\n* No parameters\n* No returns\n*/\n\nfunction checkInterval()\n{\n\tvar startDate = $('#Start-date-picker').val();\n\tvar endDate = $('#End-date-picker').val();\n\tvar startTime = $('#Start-time-picker').val();\n\tvar endTime = $('#End-time-picker').val();\n\tvar interval = $('#interval');\n\n\t//get user information from selected drop down\n\tvar selected = $('#interval option:selected');\n\n    //check if any fields are not filled out\n\tif((!startDate || !endDate || !startTime || !endTime) && selected.text() != '--')\n\t{\n\t\t$('#prompt_user').html('Please fill out all other fields before filling out the interval field');\n\t\t$('#default').attr('selected', 'selected');\n\t}\n\n    //check to see if fields are ok\n\tcheckFields(startDate, endDate, startTime, endTime, interval);\n}\n\nmodule.exports.loading = loading;\nmodule.exports.disable = disable;\nmodule.exports.enable = enable;\nmodule.exports.checkInterval = checkInterval;\n","module.exports = Plotly;"],"sourceRoot":""}
\ No newline at end of file
diff --git a/htdocs/js/meteorogram/plot/init.js b/htdocs/js/meteorogram/plot/init.js
index 4a44e0b4d94b4fe3c7b13d62ea4dbd16222db2e3..da800b73150533b59d407a8d2e02eee0f53862b9 100644
--- a/htdocs/js/meteorogram/plot/init.js
+++ b/htdocs/js/meteorogram/plot/init.js
@@ -25,6 +25,73 @@ function getSecondAxisConfig(axis_number, plot_info, axis_info, axis_kwargs) {
 }
 
 
+function coreLobbyLayout(layout, axis_config, axis_number, plot_idx, topOfGraph, graphName, textSize) {
+    layout['xaxis' + axis_number] = {
+        ticktext: ['-6h', '-3h', 'Now'],
+        tickfont: {
+            size: textSize / 5
+        },
+        showline: true,
+        linecolor: 'white',
+        anchor: 'y' + axis_number,
+         // 1 is the far right of the plot, 0 is the far left.
+        // Space the x-axis with the 10% of window width on each side. The bottom row has no middle graph,
+        // which is why we multiply by (1 + Math.floor(plot_idx / 6)).
+        domain: [.1 + 1 / 3 * (plot_idx % 3) * (1 + Math.floor(plot_idx / 6)), 14 / 60 + 1 / 3 * (plot_idx % 3) * (1 + Math.floor(plot_idx / 6))],
+        // xaxis doesn't show its lines.
+        zeroline: false,
+        // hide grid.
+        showgrid: false
+    };
+    // This is the text for the current value above each graph.
+    layout['annotations'].push({
+        font: {
+            size: textSize / 2
+        },
+        showarrow: false,
+        align: 'center',
+        // Middle of each x-axis domain.
+        x: 1/6 + 1 / 3 * (plot_idx % 3) * (1 + Math.floor(plot_idx / 6)), //position in x domain
+        y: topOfGraph + .04, //position in y domain
+        xref: 'paper',
+        yref: 'paper',
+        //Makes text centered
+        showarrow: true,
+        arrowhead: 0,
+        ax: 0,
+        ay: 0,
+      });
+    // This is the text for the name of each graph.
+    layout['annotations'].push({
+        text: graphName,
+        font: {
+            size: textSize / 4
+        },
+        showarrow: false,
+        align: 'center',
+        x: 1/6 + 1 / 3 * (plot_idx % 3) * (1 + Math.floor(plot_idx / 6)), //position in x domain
+        y: topOfGraph + .085, //position in y domain
+        xref: 'paper',
+        yref: 'paper',
+        //Makes text centered
+        showarrow: true,
+        arrowhead: 0,
+        ax: 0,
+        ay: 0,
+      });
+    // Removes title from yaxis.
+    delete axis_config['title']
+    axis_config['tickfont'] = { size: textSize / 5 }
+    axis_config['showgrid'] = false;
+    axis_config['showticklabels'] = true;
+    // Give each subgraph its own y-axis.
+    axis_config['anchor'] = 'x' + axis_number;
+    axis_config['showline'] =  true;
+    axis_config['linecolor'] = 'white';
+    // axis_config are both modified without having to be returned.
+}
+
+
 function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
     var DEFAULT_PLOT_HEIGHT = 170;
     var nshowing = plotOrder.length;
@@ -32,8 +99,9 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
         title: plotsInfo.title,
         showlegend: false,
         height: DEFAULT_PLOT_HEIGHT * nshowing + 180,
-    };
-
+    }
+    // Updates layout with plotsInfo.layout, which is defined for lobby display.
+    Object.assign(layout, plotsInfo.layout)
     layout['xaxis'] = {
         //domain affects size of x axis
         //this made room for the legend
@@ -49,13 +117,12 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
         showticklabels: nshowing > 0,
 
         //its grid is a little darker than default
-        gridcolor : "#777777",
+        gridcolor: "#777777",
 
         //hide grid
         showgrid: false,
         tickformat: '%Y-%m-%d %H:%MZ'
     };
-
     var axis_number = 0;
     var axis_info;
     var plot_info;
@@ -67,21 +134,24 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
     var step = 1 / nshowing;
     var domain;
     var x_anchor = axis_number;
-    var trace_kwargs = ['color', 'mode', 'zmin', 'zmax', 'y',
+    var trace_kwargs = ['marker', 'color', 'mode', 'zmin', 'zmax', 'y',
         'contours', 'line', 'colorscale', 'showscale', 'colorbar', 'tick0', 'dtick', 'hovermode'];
     var axis_kwargs = ['nticks', 'range', 'autorange', 'zeroline', 'showgrid',
         'tickmode', 'ticktext', 'tickvals'];
-    for (var plot_idx=0; plot_idx < plotOrder.length; plot_idx++) {
+    for (var plot_idx = 0; plot_idx < plotOrder.length; plot_idx++) {
         plot_key = plotOrder[plot_idx];
         plot_info = plotsInfo.plots[plot_key];
         axis_number += 1;
         x_anchor = axis_number;
         axis_info = plot_info.yaxis;
-        domain = [(plotOrder.length - 1 - plot_idx) * step * 1.03,
-            1 - plot_idx * step * 1.05];
+        domain = [(plotOrder.length - 1 - plot_idx) * step * 1.03, 1 - plot_idx * step * 1.05];
+        if (plotsInfo['isLobbyDisplay']) {
+            // Leaves 8% for the header, then divides the rest into thirds with 10% height above and below each graph.
+            domain = [.82 - 8 / 75 - (.2 + 8 / 75) * Math.floor(plot_idx / 3), .82 - (.2 + 8 / 75) * Math.floor(plot_idx / 3)];
+        }
 
         // Create the necessary traces (lines)
-        for (var trace_info_idx=0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {
+        for (var trace_info_idx = 0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {
             trace_info = plot_info.traces[trace_info_idx];
             trace_config = {
                 name: trace_info['name'],
@@ -89,7 +159,8 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
                 y: [],
                 text: [],
                 type: trace_info.type ? trace_info.type : 'scatter',
-                xaxis: 'x1',
+                // Gives each graph its own x-axis if plotsInfo['isLobbyDisplay'].
+                xaxis: plotsInfo['isLobbyDisplay'] ? 'x' + axis_number : 'x1',
                 yaxis: 'y' + axis_number,
                 hoverinfo: 'x+text',
                 hovermode: 'closest',
@@ -98,9 +169,8 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
                 anc_variables: trace_info['anc_variables'],
                 anc_data: [],
                 plot_name: plot_key,
-                trace_index: trace_info_idx,
+                trace_index: trace_info_idx
             };
-
             // when we have a second trace that is purely there to make the
             // second y-axis appear, we do this to point the trace to the
             // correct axis
@@ -108,7 +178,7 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
                 trace_config.yaxis = 'y' + (axis_number + trace_info_idx);
             }
 
-            for (var idx=0; idx < trace_kwargs.length; idx++) {
+            for (var idx = 0; idx < trace_kwargs.length; idx++) {
                 key = trace_kwargs[idx];
                 if (key in trace_info) {
                     trace_config[key] = trace_info[key];
@@ -125,17 +195,17 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
         // Create Y-axis configuration object
         axis_config = {
             gridcolor: '#777777',
-            titlefont: {'size' : 12},
+            titlefont: { 'size': 12 },
             title: axis_info['title'],
             zeroline: false,
             // where on the canvas does this axis belong
-            domain: [
-                (plotOrder.length - 1 - plot_idx) * step * 1.03,
-                1 - plot_idx * step * 1.05
-            ],
+            domain: domain
         };
+        if (plotsInfo['isLobbyDisplay']) {
+            coreLobbyLayout(layout, axis_config, axis_number, plot_idx, domain[1], trace_info['name'], plotsInfo['rowTextSize'])
+        }
 
-        for (idx=0; idx < axis_kwargs.length; idx++) {
+        for (idx = 0; idx < axis_kwargs.length; idx++) {
             key = axis_kwargs[idx];
             if (key in axis_info) {
                 axis_config[key] = axis_info[key];
@@ -147,7 +217,7 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
         // Process second y-axis config
         // Skip if specified meaning this configuration is only parsed
         // for additional hover/probe information (custom MetObs thing, not Plotly)
-        if ('yaxis2' in plot_info && !plot_info.yaxis2.skip) {
+        if (!plotsInfo['isLobbyDisplay'] && 'yaxis2' in plot_info && !plot_info.yaxis2.skip) {
             axis_number += 1;
             axis_info = plot_info.yaxis2;
             axis_config = getSecondAxisConfig(axis_number, plot_info, axis_info, axis_kwargs);
@@ -173,7 +243,12 @@ function initPlot(dataCache, div_id, plotOrder, plotsInfo) {
         'displayModeBar': true,
         'responsive': true
     };
-
+    if (plotsInfo['isLobbyDisplay']) {
+        // Prevents first graph from taking up entire width, and other layout problems.
+        delete layout['xaxis'];
+        // Adjusts graph sizes every time window size is changed.
+        toolbar = {responsive: true};
+    }
     //creates new graph
     Plotly.plot(div_id, dataCache, layout, toolbar);
     loading.loading();
diff --git a/htdocs/js/meteorogram/plot/table.js b/htdocs/js/meteorogram/plot/table.js
index 524266c30556796ac058765009763eb74cd0556e..4cbf7ffa7a091dd22ec685e30b61aad75e645b7b 100644
--- a/htdocs/js/meteorogram/plot/table.js
+++ b/htdocs/js/meteorogram/plot/table.js
@@ -28,6 +28,9 @@ function initTable(div_id, plotOrder, plotsInfo) {
                 info_td.data('info', {key:plot_key,idx:trace_info_idx});
                 var row = $('<tr></tr>');
                 var name = trace_info.short_name || trace_info.name;
+                if (name == 'Wind Direction Card') {
+                    continue
+                }
                 row.append('<td>'+name+'</td>');
                 row.append(info_td);
                 row.append('<td class="convert"></td>');
@@ -78,7 +81,7 @@ function add_contour_rows(tbody,plot_key,idx,trace_info,plot_info){
 
 }
 
-/* 
+/*
  * Build a datastream request from the data tags in div_id's existing meteorogram table,
  * then add labels and alternate units based on the axes objects in plotsInfo
  */
@@ -88,6 +91,7 @@ function requestTableUpdate(div_id,plotsInfo) {
     var plotOrder = [];
     var data_cells = $('#'+div_id+' .met_data');
     var convert_cells = $('#'+div_id+' .convert');
+    var varName;
     data_cells.each(function(){
             var key = $(this).data('info').key;
             var trace_idx = $(this).data('info').idx;
@@ -97,11 +101,13 @@ function requestTableUpdate(div_id,plotsInfo) {
             if(plotOrder.indexOf(key)==-1)
                 plotOrder.push(key);
             if(anc_idx !== undefined)
-                varNames.push(trace.anc_variables[0]);
+                varName = trace.anc_variables[0];
             else if(hl_idx !== undefined)
-                varNames.push(trace.var_names[hl_idx]);
+                varName = trace.var_names[hl_idx];
             else
-                varNames.push(trace.var_names[0]);
+                varName = trace.var_names[0];
+            if (!varNames.includes(varName))
+                varNames.push(varName);
     });
     var stream_string = varNames.join(':'); 
     //Use a set time that has both buoy and tower records for testing
@@ -141,10 +147,13 @@ function updateTable(dataObj,plotsInfo) {
         //Fill in a row for each trace in the plot
         for (var trace_info_idx=0; trace_info_idx < plot_info.traces.length; trace_info_idx++) {
             var trace_info = plot_info.traces[trace_info_idx];
+            if (trace_info.name == 'Wind Direction Card') {
+                continue
+            }
             if (trace_info.type=='contour') {
                 td_idx=update_contour_cells(data,data_cells,convert_cells,trace_info,td_idx);
             } else {
-                var update_val = data[trace_info['var_names'][0]][0]; 
+                var update_val = data[trace_info['var_names'][0]][0];
                 if(update_val || update_val==0){
                     var units = plot_info.yaxis.units;
                     var convert = '';
@@ -152,7 +161,7 @@ function updateTable(dataObj,plotsInfo) {
                     plot_info.yaxis.precision=Math.min(old_precision,1);
                     var orig_val = ticktext.getTickText([update_val],plot_info.yaxis);
                     plot_info.yaxis.precision = old_precision;
-                    if(plot_info.yaxis2 && plot_info.yaxis2.convert_value){
+                    if(plot_info.yaxis2 && plot_info.yaxis2.convert_value != plot_info.yaxis.convert_value){
                         var convert_units = plot_info.yaxis2.units;
                         var old_precision = plot_info.yaxis2.precision;
                         plot_info.yaxis2.precision= Math.min(old_precision,1);
diff --git a/htdocs/js/meteorogram/plot/update.js b/htdocs/js/meteorogram/plot/update.js
index 648032822a3342e4183753325dfbcc5838ab453e..0a303029d3baf993ff972ee2808e0e8819220ae2 100644
--- a/htdocs/js/meteorogram/plot/update.js
+++ b/htdocs/js/meteorogram/plot/update.js
@@ -22,6 +22,151 @@ function removeOldPoints(dataCache, removeCount) {
 }
 
 
+function formatDate(date, formatString, hour12) {
+    var date = new Date(date);
+    var time = date.toLocaleString(undefined, { hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: hour12 });
+    var month = date.getMonth() + 1;
+    month = month < 10 ? '0' + month : month;
+    date = date.toString().split(' ');
+    var dateInfo = {
+        day_name: date[0],
+        month_name: date[1],
+        month: month,
+        day: date[2],
+        year: date[3],
+        time: time,
+    }
+    // https://stackoverflow.com/questions/36529417/javascript-insert-variables-at-a-specific-place-in-a-string
+    return formatString.replace(/\{([^}]*)\}/g, function($0, $1) {
+        return dateInfo[$1] || $0;
+    });
+}
+
+
+function updateHeader(dataCache, unitCount, layoutUpdates) {
+    // Note: curr_date is 2 minutes behind the current time.
+    var curr_date = dataCache[0]['x'][dataCache[0]['x'].length - 1];
+    // Date() takes + ' UTC' as a way to know the given date is UTC and converts it to local time.
+    var hour = Number(formatDate(curr_date + ' UTC', '{time}', false).split(':')[0]);
+    // Make the screen go black between 1 and 5 am.
+    if (0 < hour && hour < 5) {
+        document.getElementById("overlay").style.opacity = 1;
+    } else {
+        document.getElementById("overlay").style.opacity = 0;
+    }
+    var date_local = formatDate(curr_date + ' UTC', '{day_name}, {month_name} {day}, {year} {time}', true);
+    var date_utc = formatDate(curr_date, '{year}-{month}-{day} {time}Z', false);
+    var elevation = unitCount == 0 ? '327.5 meters' : '1074.5 feet';
+    layoutUpdates['annotations.1.text'] = 'Data last recorded at: ' + date_utc + ' [' + date_local + ' Local]          RIG Elevation = ' + elevation;
+}
+
+
+function changeCamera() {
+    var directions = {'north': 'east', 'east': 'south', 'south': 'west', 'west': 'north',};
+    // Gets witch direction the current camera is showing.
+    var newDirection = directions[document.getElementById('roofCam').src.split('/')[7]];
+    // Makes image update. Image updates every (about) 2 minutes and 15 seconds.
+    document.getElementById('roofCam').alt = document.getElementById('dirText').innerHTML = newDirection;
+    document.getElementById('roofCam').src = 'http://metobs.ssec.wisc.edu/pub/cache/aoss/cameras/' + newDirection +
+                                             '/latest_orig.jpg?t=' + new Date().getTime();
+}
+
+
+function changeUnits(dataCache, graphDiv, plotsInfo, unitCount) {
+    // Note: unitCount alternates between 0 and 1.
+    var plotName;
+    var plotInfo;
+    var currData;
+    var tick_dates;
+    // This changes the graphDiv y-axis we are getting.
+    var axis_number;
+    // This changes the plotInfo y-axis we are getting, which switches between units every time changeUnits is called.
+    var yaxis = unitCount == 0 ? 'yaxis' : 'yaxis2';
+    var converted_tickvals;
+    var tickvals;
+    var layoutUpdates = {};
+    updateHeader(dataCache, unitCount, layoutUpdates);
+    // Update  each subgraph's displayed y-axis and current data values.
+    for (var i = 0; i < dataCache.length; i++) {
+        axis_number = i == 0 ? '' : i + 1;
+        tick_dates = dataCache[i]['x'];
+        // Prevents '-6h' from falling off x-axis.
+        layoutUpdates['xaxis' + axis_number + '.tickvals'] = [ tick_dates[0], tick_dates[Math.round(tick_dates.length / 2)], tick_dates[tick_dates.length - 1]]
+        plotName = dataCache[i].plot_name;
+        plotInfo = plotsInfo.plots[plotName];
+        // Convert data to the correct units.
+        currData = ticktext.getTickText([dataCache[i]['y'][dataCache[i]['y'].length - 1]], plotInfo[yaxis])[0];
+        layoutUpdates['annotations[' + (3 + 2 * i) + '].text'] = currData + '' + plotInfo[yaxis]['units']
+        tickvals = graphDiv.layout['yaxis' + axis_number]['tickvals']
+        if (tickvals != undefined) {
+            // Relative Humidity and Wind Direction ticktext and tickvals are static from site_configs_lobby.js.
+            if (plotName == 'wind_direction' || plotName == 'rel_hum') {
+                converted_tickvals = plotInfo[yaxis]['ticktext'];
+            } else {
+                converted_tickvals = [];
+                for (var j = 0; j < tickvals.length; j++) {
+                    converted_tickvals.push(ticktext.getTickText([tickvals[j]], plotInfo[yaxis]))
+                }
+            }
+            layoutUpdates['yaxis' + axis_number + '.ticktext'] = converted_tickvals;
+        }
+    }
+    // Updates everything at once to save time.
+    Plotly.relayout(graphDiv, layoutUpdates);
+    changeCamera();
+}
+
+
+function fitGraphs(dataCache, data, var_name, layoutUpdates, yaxis, defaultTickVals) {
+    // Set the range of each graph if applicable.
+    if (var_name != 'aoss.tower.rel_hum' && var_name != 'aoss.tower.wind_direction') {
+        // data only contains new data. Thus we must keep track of old mins/maxs.
+        if (dataCache['y'].length == 0) {
+            // dataCache['y'] gets overridden somewhere.
+            dataCache.yMin = Math.min(...data)
+            dataCache.yMax = Math.max(...data)
+        } else {
+            dataCache.yMin = Math.min(...data, dataCache.yMin)
+            dataCache.yMax = Math.max(...data, dataCache.yMax)
+        }
+
+        var spread = dataCache.yMax - dataCache.yMin;
+        var bottom = dataCache.yMin - spread;
+        var top = var_name == 'aoss.tower.solar_flux' ? dataCache.yMax : dataCache.yMax + spread;
+        // Make graph visible if flat line: Add a margin equal to 10% of the value if non-zero, else scale from 0 to 1.
+        if (spread == 0) {
+            // Note: top == bottom since spread == 0.
+            if (top > 0) {
+                top = top * 1.1
+                bottom = bottom * .9
+            } else if (top < 0) { // Only applies to air_temp and dewpoint.
+                top = top * .9
+                bottom = bottom * 1.1
+            } else { // Mainly for precipitation.
+                top = .1
+                bottom = -.1
+            }
+        }
+        // Used to lower bottom so that the graph can be seen if it is 0.
+        var tick0 = bottom
+        // If bottom < 0: Make the bottom 0 since values cannot be negative,
+        // and lower the bottom to see 0.
+        if (var_name != 'aoss.tower.air_temp' && var_name != 'aoss.tower.dewpoint' && bottom <= 0) {
+            bottom = 0;
+            tick0 = 0;
+        }
+        // Shifts the bottom down so that tick0 doesn't overlap xaxis ticks, and graphs near zero can be seen.
+        bottom -= .075 * spread + .001;
+        layoutUpdates[yaxis + '.tickvals'] = [tick0, tick0 + (top - tick0) / 4, tick0 + 2 * (top - tick0) / 4,
+                                              tick0 + 3 * (top - tick0) / 4, top]
+        layoutUpdates[yaxis + '.range'] = [bottom, top]
+    } else {
+        layoutUpdates[yaxis + '.tickvals'] = defaultTickVals
+    }
+    // layoutUpdates is changed without having to return it.
+}
+
+
 function replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints) {
     var dates = dataObj.dates;
     var plotName;
@@ -49,6 +194,10 @@ function replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints)
     };
 
     var traceIndex = 0;
+
+    // Variables used for lobby display.
+    var layoutUpdates = {};
+    var axis_number;
     /**
      *
      * If we are updating the plots instead of replacing them, then try
@@ -75,7 +224,7 @@ function replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints)
             continue;
         }
         plotInfo = plotsInfo.plots[plotName];
-        _.each(plotInfo.traces, function(traceInfo, index) {
+        _.each(plotInfo.traces, function (traceInfo, index) {
 
             if (dataCache[traceIndex + index].type == 'contour') {
                 // push new dates for each trace to be extended
@@ -106,6 +255,10 @@ function replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints)
                 tracesToExtend.push(traceIndex + index);
                 // scatter plots, assume the y data is the data being updated
                 _.each(traceInfo.var_names, function (var_name) {
+                    if (plotsInfo['isLobbyDisplay']) {
+                        axis_number = i == 0 ? '': i + 1;
+                        fitGraphs(dataCache[i], dataObj[var_name], var_name, layoutUpdates, 'yaxis' + axis_number, plotInfo['yaxis2']['tickvals'])
+                    }
                     // push the entire new data array as one element to update
                     extendData.y.push(dataObj[var_name]);
 
@@ -155,15 +308,24 @@ function replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints)
         removeOldPoints(dataCache, dataCache[0].x.length - maxPoints);
     }
 
+    // If lobby display and data to update.
+    if (Object.keys(layoutUpdates).length != 0) {
+        // Updates everything at once to save time. Should be done after all dataCache manipulations.
+        Plotly.relayout(graphDiv, layoutUpdates);
+        // The first time through, call changeUnits to display current data.
+        if (!update) {
+            changeUnits(dataCache, graphDiv, plotsInfo, 0);
+        }
+    }
     if (forceRedraw) {
         Plotly.redraw(graphDiv);
     }
 }
 
 
-
 function updatePlot(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints) {
     replaceData(dataCache, graphDiv, plotsInfo, dataObj, update, maxPoints);
 }
 
 module.exports.updatePlot = updatePlot;
+module.exports.changeUnits = changeUnits;
diff --git a/htdocs/js/meteorogram/site_configs_lobby.js b/htdocs/js/meteorogram/site_configs_lobby.js
new file mode 100644
index 0000000000000000000000000000000000000000..cf21e44147dec79179af1c103a3fc982ef2b24c8
--- /dev/null
+++ b/htdocs/js/meteorogram/site_configs_lobby.js
@@ -0,0 +1,287 @@
+/*Config options for different sites*/
+
+// Note: Do exponential decay scaling to allow smaller windows to have larger text
+// without making text in bigger windows too big.
+// Note: units are in px. pt = 3 / 4 * px (about).
+// Note: divide by the a ratio for width and height that allows all text to be "nice" sized. 3:1 and 20:1 do this job.
+// Note: The dimensions of the rows 1 through 3 are the same.
+var rowTextSize = Math.pow(Math.min(document.getElementById("row1").scrollWidth / 3,
+                                    document.getElementById("row1").scrollHeight) * 3 / 4, .8);
+var headerTextSize = Math.pow(Math.min(document.getElementById("header").scrollWidth / 22,
+                                       document.getElementById("header").scrollHeight) * 3 / 4, .8);
+var siteConfigs = {
+    rowTextSize: rowTextSize,
+    isLobbyDisplay: true,
+    layout: {
+        showlegend: false,
+        margin: {t:0, l:0, r:0, b:0},
+        font: { color: 'white' },
+        paper_bgcolor: 'rgba(0,0,0,0)',
+        plot_bgcolor: 'rgba(0,0,0,0)',
+        height: undefined,
+        // Header text providing data about the display.
+        annotations: [
+            {
+                text: 'Reliable Automated Instrumentation Network (RAIN) - Current Readings',
+                font: {
+                    size: headerTextSize
+                },
+                showarrow: false,
+                align: 'center',
+                x: .5,
+                y: .985,
+                xref: 'paper',
+                yref: 'paper',
+                // Makes text centered.
+                showarrow: true,
+                arrowhead: 0,
+                ax: 0,
+                ay: 0,
+            },
+            // text added in update.js:
+            // 'Data last recorded at: ' + date_utc + ' [' + date_local + ' Local]          RIG Elevation = ' + elevation
+            {
+                font: {
+                    size: headerTextSize / 1.25
+                },
+                showarrow: false,
+                align: 'center',
+                x: .5,
+                y: .96,
+                xref: 'paper',
+                yref: 'paper',
+                // Makes text centered.
+                showarrow: true,
+                arrowhead: 0,
+                ax: 0,
+                ay: 0,
+            },
+            {
+                text: 'Data values updated every 2 minutes      --      Trend graphs show 6 hour history [2 minute average]',
+                font: {
+                    size: headerTextSize / 1.5
+                },
+                showarrow: false,
+                align: 'center',
+                x: .5,
+                y: .94,
+                xref: 'paper',
+                yref: 'paper',
+                // Makes text centered.
+                showarrow: true,
+                arrowhead: 0,
+                ax: 0,
+                ay: 0,
+            },
+        ],
+    },
+    defaultPlots: ['air_temp', 'dewpoint', 'rel_hum', 'wind_direction', 'wind_speed', 'accum_precip', 'solar_flux', 'pressure'],
+    plots: {
+        air_temp: {
+            traces: [
+                {
+                    name: 'Temperature',
+                    var_names: ['aoss.tower.air_temp'],
+                    line: {
+                        color: 'white',
+                        width: rowTextSize / 50
+                    },
+                },
+            ],
+            yaxis: {
+                title: 'Temp (°C)',
+                convert_value: null,
+                units: ' °C',
+                precision: 0,
+            },
+            yaxis2: {
+                title: 'Temp (°F)',
+                convert_value: 'getF',
+                units: ' °F',
+                precision: 0,
+            },
+        },
+        dewpoint: {
+            traces: [
+                {
+                    // Dewpoint
+                    name: 'Dew Point',
+                    var_names: ['aoss.tower.dewpoint'],
+                    line: {
+                        color: 'white',
+                        width: rowTextSize / 50
+                    },
+                },
+            ],
+            yaxis: {
+                title: 'Dew Point (°C)',
+                convert_value: null,
+                units: ' °C',
+                precision: 0,
+            },
+            yaxis2: {
+                title: 'Dew Point (°F)',
+                convert_value: 'getF',
+                units: ' °F',
+                precision: 0,
+            },
+        },
+        pressure: {
+            traces: [
+                {
+                    name: 'Pressure',
+                    var_names: ['aoss.tower.pressure'],
+                    line: {
+                        color: 'white',
+                        width: rowTextSize / 50
+                    },
+                },
+            ],
+            yaxis: {
+                title: 'Pressure (hpa)',
+                convert_value: null,
+                units: ' hPa',
+                precision: 1,
+            },
+            yaxis2: {
+                title: 'Pressure (inHg)',
+                convert_value: 'getPresInHg',
+                units: ' inHg',
+                precision: 2,
+            },
+        },
+        rel_hum: {
+            traces: [
+                {
+                    name: 'Relative Humidity',
+                    var_names: ['aoss.tower.rel_hum'],
+                    line: {
+                        color: 'white',
+                        width: rowTextSize / 50
+                    },
+                },
+            ],
+            yaxis: {
+                title: 'Relative Humidity (%)',
+                range: [-0.5, 105.0],
+                tickvals: [0, 20, 40, 60, 80, 100],
+                ticktext: ['0', '20', '40', '60', '80', '100'],
+                convert_value: null,
+                units: '%',
+                precision: 0,
+            },
+            yaxis2: {
+                title: 'Relative Humidity (%)',
+                range: [-0.5, 105.0],
+                tickvals: [0, 20, 40, 60, 80, 100],
+                ticktext: ['0', '20', '40', '60', '80', '100'],
+                convert_value: null,
+                units: '%',
+                precision: 0,
+            },
+        },
+        wind_speed: {
+            traces: [
+                {
+                    name: 'Wind Speed',
+                    var_names: ['aoss.tower.wind_speed'],
+                    line: {
+                        color: 'white',
+                        width: rowTextSize / 50
+                    },
+                },
+            ],
+            yaxis: {
+                title: 'Wind Speed (m/s)',
+                convert_value: null,
+                units: ' m/s',
+                precision: 1,
+            },
+            yaxis2: {
+                title: 'Wind Speed (mph)',
+                convert_value: 'getSpeedMPH',
+                units: ' mph',
+                precision: 1,
+            }
+        },
+        wind_direction: {
+            traces: [
+                {
+                    name: 'Wind Direction',
+                    var_names: ['aoss.tower.wind_direction'],
+                    line: {
+                        color: 'white'
+                    },
+                    mode: 'markers',
+                    marker: {size: rowTextSize / 25}
+                },
+            ],
+            yaxis: {
+                title: 'Wind Direction (°)',
+                range: [-20, 380],
+                tickvals: ['0', '90', '180', '270', '360'],
+                convert_value: null,
+                units: '°',
+                precision: 0,
+            },
+            yaxis2: {
+                title: 'Wind Direction',
+                range: [-20, 380],
+                tickvals: ['0', '90', '180', '270', '360'],
+                ticktext: ['N', 'E', 'S', 'W', 'N'],
+                convert_value: 'cardinalWDir',
+                units:'',
+                precision: 0,
+            },
+        },
+        accum_precip: {
+            traces: [
+                {
+                    name: 'Accumulated Precipitation',
+                    short_name:'Accum. Precip.',
+                    var_names: ['aoss.tower.accum_precip'],
+                    line: {
+                        color: 'white',
+                        width: rowTextSize / 50
+                    },
+                },
+            ],
+            yaxis: {
+                title: 'Accum Precip (mm)',
+                convert_value: 'getAccumMillimeter',
+                units: ' mm',
+                precision: 1,
+            },
+            yaxis2: {
+                title: 'Accum Precip (inches)',
+                convert_value: null,
+                units: ' in',
+                precision: 2,
+            },
+        },
+        solar_flux: {
+            traces: [
+                {
+                    name: 'Solar Flux',
+                    var_names: ['aoss.tower.solar_flux'],
+                    line: {
+                        color: 'white',
+                        width: rowTextSize / 50
+                    },
+                },
+            ],
+            yaxis: {
+                title: 'Solar Flux (W/m^2)',
+                convert_value: null,
+                units: ' W/m^2',
+                precision: 0,
+            },
+            yaxis2: {
+                title: 'Solar Flux (W/m^2)',
+                convert_value: null,
+                units: ' W/m^2',
+                precision: 0,
+            },
+        },
+    },
+};
\ No newline at end of file
diff --git a/htdocs/mendota/buoy/index.html b/htdocs/mendota/buoy/index.html
index 1b34c3b3d437868285f4097e597e664dcfc6d2ae..78eb937dab013dc34c3c2a66faaabdd386d9bf3b 100644
--- a/htdocs/mendota/buoy/index.html
+++ b/htdocs/mendota/buoy/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <div class="instrument">
     <div class="container">
@@ -191,7 +190,7 @@
                 </p>
             </div>
             <div class="col-sm-4 text-center">
-                <a href="../quicklooks#buoy"><img class="img-responsive img-center" src="/images/buoyexample.png" alt="QuickLook Example"></a>
+                <a href="../quicklooks#buoy"><img class="img-responsive img-center" src="https://metobs.ssec.wisc.edu/images/buoyexample.png" alt="QuickLook Example"></a>
                 <h3 style="margin-top:10px">Quicklook Browser</h3>
             </div>
         </div>
@@ -210,7 +209,7 @@
                 <h2>Buoy Location</h2>
             </div>
             <div class="col-sm-4">
-                <img class="img-responsive img-center" src="/images/buoywatertempexample.png" alt="Buoy Water Temp Profile">
+                <img class="img-responsive img-center" src="https://metobs.ssec.wisc.edu/images/buoywatertempexample.png" alt="Buoy Water Temp Profile">
                 <h2>Water Temp Profile Example</h2>
             </div>
         </div>
@@ -219,10 +218,12 @@
     </div>
     <!-- /.container -->
 </div>    
-<script src="/js/quicklooks.js"></script>
-<script src="/js/moment.min.js"></script>
-<script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
-<script type="text/javascript" src="/js/meteorogram/site_configs.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/quicklooks.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
+<!--TODO: LOAD PLOTLY DYNAMICALLY-->
+<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/meteorogram.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/site_configs.js"></script>
 <script type="text/javascript">
     var myConfig = siteConfigs['mendota.buoy'];
     myConfig.title = "Current Conditions";
@@ -266,6 +267,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/mendota/buoy/meteorogram/index.html b/htdocs/mendota/buoy/meteorogram/index.html
index 3fc82ece9ad27f32f1d3b8bc56d3ec5b50be6cf3..1a96ace75d6ae895ab6ad86a7f5b6ab1244ab6d8 100644
--- a/htdocs/mendota/buoy/meteorogram/index.html
+++ b/htdocs/mendota/buoy/meteorogram/index.html
@@ -185,8 +185,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <div id="content">
     <div class="container">
@@ -206,8 +205,8 @@
         </div>
     </div>
 </div>
-<script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
-<script type="text/javascript" src="/js/meteorogram/site_configs.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/meteorogram.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/site_configs.js"></script>
 <script type="text/javascript">
     var met = MeteorogramController('graph', 'control-container', siteConfigs['mendota.buoy']);
     met.initMeteorogram();
@@ -249,6 +248,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/mendota/buoy/text_popup/index.html b/htdocs/mendota/buoy/text_popup/index.html
index 4a98bc4552d87e7036372ac32b55f9ad2ccd549d..2ca2a1faf245433da5fae5d07fd32f17b5d8965e 100644
--- a/htdocs/mendota/buoy/text_popup/index.html
+++ b/htdocs/mendota/buoy/text_popup/index.html
@@ -175,15 +175,16 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <div class="instrument" style="text-align:center">
     <div id="graph" style="display:inline-block;text-align:left"></div>
 </div>
-<script src="/js/moment.min.js"></script>
-<script type="text/javascript" src="/js/meteorogram/meteorogram.js"></script>
-<script type="text/javascript" src="/js/meteorogram/site_configs.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
+<!--TODO: LOAD PLOTLY DYNAMICALLY-->
+<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/meteorogram.js"></script>
+<script type="text/javascript" src="https://metobs.ssec.wisc.edu/js/meteorogram/site_configs.js"></script>
 <script type="text/javascript">
     $(document).ready(function(){
         var myConfig = siteConfigs['mendota.buoy'];
@@ -228,6 +229,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/mendota/index.html b/htdocs/mendota/index.html
index 83b3fb860f65f6e50ce3db5bc64c52d4836d8ef0..cf065c69b36ebfe3e84e48ce7c1c214ab45a0737 100644
--- a/htdocs/mendota/index.html
+++ b/htdocs/mendota/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
 <!-- The circle icons use Font Awesome's stacked icon classes. For more information, visit http://fontawesome.io/examples/ -->
 <section id="instruments" class="services bg-primary" style="padding:5px 0">
     <div class="container">
@@ -242,6 +241,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_0423_16.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_0423_16.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e5a5438752086ac349300f6edd2c2883e488bb2
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_0423_16.png differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby1.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby1.png
new file mode 100644
index 0000000000000000000000000000000000000000..a55f1842fa0f777a1ad282ce586efcc8eb8a1701
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby1.png differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby2.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby2.png
new file mode 100644
index 0000000000000000000000000000000000000000..92196e8b7b0788b8fb6ab6a783282a1a486f4de1
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby2.png differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby5.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby5.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae374be434f66bcd0acf4fd19207181ab9c07009
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/Hawk_baby5.png differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/PastedGraphic-3.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/PastedGraphic-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..effc727db4e4b3422026f5fbda75da03003d83cd
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/PastedGraphic-3.png differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0000_Layer 21.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0000_Layer 21.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..899422dc38f9b8036bd6ca1d3285eba0a7beb548
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0000_Layer 21.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 10_2.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 10_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2975e5ce3372ac1ad96d6ff5a5cc2b2203c04169
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 10_2.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 20.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 20.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7fa2cddfa4fa6180d592e7a881df80200b0e7cc7
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0001_Layer 20.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0002_Layer 19.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0002_Layer 19.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..dcd24509094deb3af810cc53e0784294c45e1ed2
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0002_Layer 19.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0003_Layer 8_2.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0003_Layer 8_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..71cb1680abd5c5d448f6a2664ba4b5033a48df1c
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0003_Layer 8_2.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 16.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 16.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4924ac7ac764e4c17012be00fa9986e4d0e7f849
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 16.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 6_2.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 6_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e989c90a251105f9f7779af15448b21db3af375d
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0005_Layer 6_2.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0008_Layer 3_2.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0008_Layer 3_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..387c91a59a42bb71d66431d5a9685f6e61536476
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0008_Layer 3_2.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0010_Layer 11.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0010_Layer 11.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..16173e3b2ef312431484f09bcb7c503fb38a6a5e
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0010_Layer 11.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0011_Layer 10.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0011_Layer 10.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..82227c242aa46ade118cd17353d3d86352a53ee2
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0011_Layer 10.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0013_Layer 8.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0013_Layer 8.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..bb67b5fa13eb6e4a3146a19f56384e3c7ad972f3
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0013_Layer 8.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0019_Layer 2.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0019_Layer 2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1e4c0cb456e0f1aaa2c3673c5da8d19411ceebbc
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0019_Layer 2.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0020_Layer 1.jpg b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0020_Layer 1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5366831eb7eea22aaf4fda8e16f5e718fecf53b4
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/hawkcam_0020_Layer 1.jpg differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m18s116.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m18s116.png
new file mode 100644
index 0000000000000000000000000000000000000000..a988c0e854eca2f3a13f70f4f976b488e977d33d
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m18s116.png differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m23s171.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m23s171.png
new file mode 100644
index 0000000000000000000000000000000000000000..5e2bbb6ada2cc753896537608f47fa97f54e00dc
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h24m23s171.png differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m20s143.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m20s143.png
new file mode 100644
index 0000000000000000000000000000000000000000..0a51be3d6c696a151ebe52d73bc8af5f330a54b7
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m20s143.png differ
diff --git a/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m27s214.png b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m27s214.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6a390d6526ca777b543617594c750b66d025736
Binary files /dev/null and b/htdocs/pages/instruments/aoss/cameras/hawkcam_images/vlcsnap-2012-04-20-15h27m27s214.png differ
diff --git a/htdocs/quicklooks/detail.html b/htdocs/quicklooks/detail.html
index 7e87e0932fb3e4a3c43f16e13070eb1858230385..c40477bda4860a2976a2a782645d6692b62b2241 100644
--- a/htdocs/quicklooks/detail.html
+++ b/htdocs/quicklooks/detail.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
     <div class="container">
         <br>
@@ -190,9 +189,9 @@
         </div>
     </div>
         <hr>
-<script src="/js/moment.min.js"></script>
-<script src="/js/underscore-min.js"></script>
-<script src="/js/quicklooks.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/underscore-min.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/quicklooks.js"></script>
 <script>
 //parses the GET parameters from a function
 //from http://stackoverflow.com/a/831060/6884806
@@ -246,6 +245,5 @@ $(document).ready(function(){
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/quicklooks/index.html b/htdocs/quicklooks/index.html
index b486693bc974a544f59362bf910f628c689977d6..d7eb84e9fd89dd5430007d3dd1dfca3f4723d132 100644
--- a/htdocs/quicklooks/index.html
+++ b/htdocs/quicklooks/index.html
@@ -181,8 +181,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
 
     
     
@@ -341,12 +340,12 @@
 </div>
 -->
 </div>
-<script src="/js/moment.min.js"></script>
-<script src="/js/underscore-min.js"></script>
-<script src="/js/quicklookorder.js"></script>
-<script src="/js/quicklooks.js"></script>
-<script src="/js/quicklooks-util.js"></script>
-<script src="/js/quicklooks-interactive.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/underscore-min.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/quicklookorder.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/quicklooks.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/quicklooks-util.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/quicklooks-interactive.js"></script>
 
 
     <!-- Footer -->
@@ -383,6 +382,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/realtime/index.html b/htdocs/realtime/index.html
index ac3f1c62870a8aa40fd9b793011c14bbf648aed8..b6b863768aad5fd94b2b4a672c437d97b053063e 100644
--- a/htdocs/realtime/index.html
+++ b/htdocs/realtime/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 
 <div>
@@ -185,10 +184,10 @@
     <table>
         <tr>
             <td class="instruments">
-                <a href="/aoss/tower/meteorogram"><img src="/images/aossinteractive.png" alt="AOSS Interactive Data" height="256px"><br>Atmospheric, Oceanic, and Space Sciences Building (AOSS)</a><br>RIG Tower Real-time Interactive Data
+                <a href="/aoss/tower/meteorogram"><img src="https://metobs.ssec.wisc.edu/images/aossinteractive.png" alt="AOSS Interactive Data" height="256px"><br>Atmospheric, Oceanic, and Space Sciences Building (AOSS)</a><br>RIG Tower Real-time Interactive Data
             </td>
             <td class="instruments">
-                <a href="/mendota/buoy/meteorogram"><img src="/images/buoyinteractive.png" alt="Buoy Interactive Data" height="256px"><br>Lake Mendota</a><br>Buoy Real-time Interactive Data
+                <a href="/mendota/buoy/meteorogram"><img src="https://metobs.ssec.wisc.edu/images/buoyinteractive.png" alt="Buoy Interactive Data" height="256px"><br>Lake Mendota</a><br>Buoy Real-time Interactive Data
             </td>
         </tr>
     </table>
@@ -230,6 +229,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/sparc/aeri/realtime_quicklooks/index.html b/htdocs/sparc/aeri/realtime_quicklooks/index.html
index f433101dfb7ec690914afe20ebc490a5c4dd9b58..3a3d596ab6ee4b6a9727d43ba916b1909cf8460f 100644
--- a/htdocs/sparc/aeri/realtime_quicklooks/index.html
+++ b/htdocs/sparc/aeri/realtime_quicklooks/index.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     
 <style>
 
@@ -357,7 +356,7 @@ nav {
             </div>
         </div>
 </div>
-<script src="/js/moment.min.js"></script>
+<script src="https://metobs.ssec.wisc.edu/js/moment.min.js"></script>
 <script>
     setInterval(function(){
         //cache-break the images with a new url every 10 minutes
@@ -418,6 +417,5 @@ nav {
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file
diff --git a/htdocs/tags.html b/htdocs/tags.html
index 9c886f35094665dbc93770007626ab04ef9a7b20..ec0810292e17341707e47682b7d12bfe00b15791 100644
--- a/htdocs/tags.html
+++ b/htdocs/tags.html
@@ -175,8 +175,7 @@
                     </ol> -->
                 </div>
       </div>
-    </nav>    
-    <!--Page Content-->    
+    </nav>    <!--Page Content-->    
     <h1>Tags for RAIN | SSEC @ UW-Madison</h1>    <!-- Footer -->
     <section id="contact">
     <footer>
@@ -211,6 +210,5 @@
         </div>
         <a id="to-top" href="#top" class="btn btn-dark btn-lg"><i class="fa fa-chevron-up fa-fw fa-1x"></i></a>
     </footer>
-    </section> 
-</body>
+    </section></body>
 </html>
\ No newline at end of file