aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Loomans <noahloomans@gmail.com>2017-01-08 11:48:13 +0100
committerNoah Loomans <noahloomans@gmail.com>2017-01-08 11:48:13 +0100
commit320c18af3ee9cbeaaae3d4796dd7f15a5ac90889 (patch)
treed63339d425a2a6a20c883d896b9ed492272d6085
parent4e8da42863406764a659a7337e774ad216d356c9 (diff)
parentdea89e1ec600b302a8db33dd48080b901aee7c7e (diff)
Merge branch 'master' of github.com:nloomans/rooster-mml
-rw-r--r--package.json7
-rw-r--r--public/javascripts/analytics.js35
-rw-r--r--public/javascripts/autocomplete.js87
-rw-r--r--public/javascripts/browserFixToolkit.js12
-rw-r--r--public/javascripts/bundle.js869
-rw-r--r--public/javascripts/easterEggs.js91
-rw-r--r--public/javascripts/favorite.js79
-rw-r--r--public/javascripts/featureDetect.js29
-rw-r--r--public/javascripts/frontpage.js23
-rw-r--r--public/javascripts/getURLOfUser.js9
-rw-r--r--public/javascripts/getUsers.js7
-rw-r--r--public/javascripts/getWeek.js33
-rw-r--r--public/javascripts/main.bak.js244
-rw-r--r--public/javascripts/main.js272
-rw-r--r--public/javascripts/schedule.js71
-rw-r--r--public/javascripts/scrollSnap.js55
-rw-r--r--public/javascripts/search.js87
-rw-r--r--public/javascripts/weekSelector.js95
-rw-r--r--public/stylesheets/style.css49
-rw-r--r--routes/meetingpointProxy.js17
-rw-r--r--views/index.jade4
21 files changed, 907 insertions, 1268 deletions
diff --git a/package.json b/package.json
index 7ad833f..26f274b 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"start": "node ./bin/www",
"setup": "npm install && bower install",
"build-dev": "browserify -d -t [ babelify --presets [ es2015 ] ] -e ./public/javascripts/main.js > ./public/javascripts/bundle.js",
+ "watch": "watchify -v -d -t [ babelify --presets [ es2015 ] ] -e ./public/javascripts/main.js -o ./public/javascripts/bundle.js",
"build": "browserify -t [ babelify --presets [ es2015 ] ] -e ./public/javascripts/main.js | uglifyjs -cm > ./public/javascripts/bundle.js"
},
"dependencies": {
@@ -26,14 +27,16 @@
"lodash": "^4.15.0",
"morgan": "~1.7.0",
"request": "^2.74.0",
+ "smoothscroll-polyfill": "^0.3.4",
"then-yield": "0.0.1"
},
"devDependencies": {
- "babel-preset-es2015": "^6.14.0",
+ "babel-preset-es2016": "^6.16.0",
"babelify": "^7.3.0",
"bower": "^1.7.9",
"browserify": "^13.1.0",
- "gulp": "^3.9.1"
+ "gulp": "^3.9.1",
+ "watchify": "^3.7.0"
},
"author": "Noah Loomans <noahloomans@gmail.com>",
"license": "MIT",
diff --git a/public/javascripts/analytics.js b/public/javascripts/analytics.js
new file mode 100644
index 0000000..a93c8a4
--- /dev/null
+++ b/public/javascripts/analytics.js
@@ -0,0 +1,35 @@
+/* global ga */
+
+const self = {}
+
+self.send = {}
+
+self.send.search = function (selectedUser, favorite) {
+ const hitType = 'event'
+
+ const eventCategory = favorite ? 'search fav' : 'search'
+
+ let eventAction
+ switch (selectedUser.type) {
+ case 'c':
+ eventAction = 'Class'
+ break
+ case 't':
+ eventAction = 'Teacher'
+ break
+ case 'r':
+ eventAction = 'Room'
+ break
+ case 's':
+ eventAction = 'Student'
+ break
+ }
+
+ const eventLabel = selectedUser.value
+
+ ga(function () {
+ ga('send', { hitType, eventCategory, eventAction, eventLabel })
+ })
+}
+
+module.exports = self
diff --git a/public/javascripts/autocomplete.js b/public/javascripts/autocomplete.js
new file mode 100644
index 0000000..71fb17d
--- /dev/null
+++ b/public/javascripts/autocomplete.js
@@ -0,0 +1,87 @@
+const EventEmitter = require('events')
+
+const self = new EventEmitter()
+
+self._items = []
+self._selectedItemIndex = -1
+
+self._nodes = {
+ search: document.querySelector('#search'),
+ input: document.querySelector('input[type="search"]'),
+ autocomplete: document.querySelector('.autocomplete')
+}
+
+self.getSelectedItem = function () {
+ if (self.getItems() === []) return
+
+ if (self.getSelectedItemIndex() === -1) {
+ return self.getItems()[0]
+ } else {
+ return self.getItems()[self.getSelectedItemIndex()]
+ }
+}
+
+self.getSelectedItemIndex = function () {
+ return self._selectedItemIndex
+}
+
+self.getItems = function () {
+ return self._items
+}
+
+self.removeAllItems = function () {
+ while (self._nodes.autocomplete.firstChild) {
+ self._nodes.autocomplete.removeChild(self._nodes.autocomplete.firstChild)
+ }
+ self._items = []
+ self._selectedItemIndex = -1
+}
+
+self.addItem = function (item) {
+ const listItem = document.createElement('li')
+ listItem.textContent = item.value
+ self._nodes.autocomplete.appendChild(listItem)
+ self._items.push(item)
+}
+
+self._moveSelected = function (shift) {
+ if (self._selectedItemIndex + shift >= self.getItems().length) {
+ self._selectedItemIndex = -1
+ } else if (self._selectedItemIndex + shift < -1) {
+ self._selectedItemIndex = self.getItems().length - 1
+ } else {
+ self._selectedItemIndex += shift
+ }
+
+ for (let i = 0; i < self.getItems().length; i++) {
+ self._nodes.autocomplete.children[i].classList.remove('selected')
+ }
+ if (self._selectedItemIndex >= 0) {
+ self._nodes.autocomplete
+ .children[self._selectedItemIndex].classList.add('selected')
+ }
+}
+
+self._handleItemClick = function (event) {
+ if (!self._nodes.autocomplete.contains(event.target)) return
+ const itemIndex = Array.prototype.indexOf
+ .call(self._nodes.autocomplete.children, event.target)
+ self._selectedItemIndex = itemIndex
+ self.emit('select', self.getSelectedItem())
+}
+
+self._handleKeydown = function (event) {
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
+ event.preventDefault()
+ if (event.key === 'ArrowDown') {
+ self._moveSelected(1)
+ } else if (event.key === 'ArrowUp') {
+ self._moveSelected(-1)
+ }
+ }
+}
+
+self._nodes.autocomplete.addEventListener('click', self._handleItemClick)
+self._nodes.input.addEventListener('keydown', self._handleKeydown)
+
+module.exports = self
diff --git a/public/javascripts/browserFixToolkit.js b/public/javascripts/browserFixToolkit.js
new file mode 100644
index 0000000..fbeab74
--- /dev/null
+++ b/public/javascripts/browserFixToolkit.js
@@ -0,0 +1,12 @@
+const self = {}
+
+self.isIE = navigator.userAgent.indexOf('MSIE') !== -1 ||
+ navigator.appVersion.indexOf('Trident/') > 0
+
+if (self.isIE) {
+ self.inputEvent = 'textinput'
+} else {
+ self.inputEvent = 'input'
+}
+
+module.exports = self
diff --git a/public/javascripts/bundle.js b/public/javascripts/bundle.js
index 55ef8c7..1b43c65 100644
--- a/public/javascripts/bundle.js
+++ b/public/javascripts/bundle.js
@@ -1,868 +1 @@
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-exports.remove = removeDiacritics;
-
-var replacementList = [
- {
- base: ' ',
- chars: "\u00A0",
- }, {
- base: '0',
- chars: "\u07C0",
- }, {
- base: 'A',
- chars: "\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F",
- }, {
- base: 'AA',
- chars: "\uA732",
- }, {
- base: 'AE',
- chars: "\u00C6\u01FC\u01E2",
- }, {
- base: 'AO',
- chars: "\uA734",
- }, {
- base: 'AU',
- chars: "\uA736",
- }, {
- base: 'AV',
- chars: "\uA738\uA73A",
- }, {
- base: 'AY',
- chars: "\uA73C",
- }, {
- base: 'B',
- chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
- }, {
- base: 'C',
- chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
- }, {
- base: 'D',
- chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
- }, {
- base: 'Dh',
- chars: "\u00D0",
- }, {
- base: 'DZ',
- chars: "\u01F1\u01C4",
- }, {
- base: 'Dz',
- chars: "\u01F2\u01C5",
- }, {
- base: 'E',
- chars: "\u025B\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E\u1D07",
- }, {
- base: 'F',
- chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
- }, {
- base: 'G',
- chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
- }, {
- base: 'H',
- chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
- }, {
- base: 'I',
- chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
- }, {
- base: 'J',
- chars: "\u24BF\uFF2A\u0134\u0248\u0237",
- }, {
- base: 'K',
- chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
- }, {
- base: 'L',
- chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
- }, {
- base: 'LJ',
- chars: "\u01C7",
- }, {
- base: 'Lj',
- chars: "\u01C8",
- }, {
- base: 'M',
- chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
- }, {
- base: 'N',
- chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
- }, {
- base: 'NJ',
- chars: "\u01CA",
- }, {
- base: 'Nj',
- chars: "\u01CB",
- }, {
- base: 'O',
- chars: "\u24C4\uFF2F\xD2\xD3\xD4\u1ED2\u1ED0\u1ED6\u1ED4\xD5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\xD6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\xD8\u01FE\u0186\u019F\uA74A\uA74C",
- }, {
- base: 'OE',
- chars: "\u0152",
- }, {
- base: 'OI',
- chars: "\u01A2",
- }, {
- base: 'OO',
- chars: "\uA74E",
- }, {
- base: 'OU',
- chars: "\u0222",
- }, {
- base: 'P',
- chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
- }, {
- base: 'Q',
- chars: "\u24C6\uFF31\uA756\uA758\u024A",
- }, {
- base: 'R',
- chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
- }, {
- base: 'S',
- chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
- }, {
- base: 'T',
- chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
- }, {
- base: 'Th',
- chars: "\u00DE",
- }, {
- base: 'TZ',
- chars: "\uA728",
- }, {
- base: 'U',
- chars: "\u24CA\uFF35\xD9\xDA\xDB\u0168\u1E78\u016A\u1E7A\u016C\xDC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244",
- }, {
- base: 'V',
- chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
- }, {
- base: 'VY',
- chars: "\uA760",
- }, {
- base: 'W',
- chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
- }, {
- base: 'X',
- chars: "\u24CD\uFF38\u1E8A\u1E8C",
- }, {
- base: 'Y',
- chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
- }, {
- base: 'Z',
- chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
- }, {
- base: 'a',
- chars: "\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0251",
- }, {
- base: 'aa',
- chars: "\uA733",
- }, {
- base: 'ae',
- chars: "\u00E6\u01FD\u01E3",
- }, {
- base: 'ao',
- chars: "\uA735",
- }, {
- base: 'au',
- chars: "\uA737",
- }, {
- base: 'av',
- chars: "\uA739\uA73B",
- }, {
- base: 'ay',
- chars: "\uA73D",
- }, {
- base: 'b',
- chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
- }, {
- base: 'c',
- chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
- }, {
- base: 'd',
- chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
- }, {
- base: 'dh',
- chars: "\u00F0",
- }, {
- base: 'dz',
- chars: "\u01F3\u01C6",
- }, {
- base: 'e',
- chars: "\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u01DD",
- }, {
- base: 'f',
- chars: "\u24D5\uFF46\u1E1F\u0192",
- }, {
- base: 'ff',
- chars: "\uFB00",
- }, {
- base: 'fi',
- chars: "\uFB01",
- }, {
- base: 'fl',
- chars: "\uFB02",
- }, {
- base: 'ffi',
- chars: "\uFB03",
- }, {
- base: 'ffl',
- chars: "\uFB04",
- }, {
- base: 'g',
- chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
- }, {
- base: 'h',
- chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
- }, {
- base: 'hv',
- chars: "\u0195",
- }, {
- base: 'i',
- chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
- }, {
- base: 'j',
- chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
- }, {
- base: 'k',
- chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
- }, {
- base: 'l',
- chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
- }, {
- base: 'lj',
- chars: "\u01C9",
- }, {
- base: 'm',
- chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
- }, {
- base: 'n',
- chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
- }, {
- base: 'nj',
- chars: "\u01CC",
- }, {
- base: 'o',
- chars: "\u24DE\uFF4F\xF2\xF3\xF4\u1ED3\u1ED1\u1ED7\u1ED5\xF5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\xF6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\xF8\u01FF\uA74B\uA74D\u0275\u0254\u1D11",
- }, {
- base: 'oe',
- chars: "\u0153",
- }, {
- base: 'oi',
- chars: "\u01A3",
- }, {
- base: 'oo',
- chars: "\uA74F",
- }, {
- base: 'ou',
- chars: "\u0223",
- }, {
- base: 'p',
- chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
- }, {
- base: 'q',
- chars: "\u24E0\uFF51\u024B\uA757\uA759",
- }, {
- base: 'r',
- chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
- }, {
- base: 's',
- chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
- }, {
- base: 'ss',
- chars: "\xDF",
- }, {
- base: 't',
- chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
- }, {
- base: 'th',
- chars: "\u00FE",
- }, {
- base: 'tz',
- chars: "\uA729",
- }, {
- base: 'u',
- chars: "\u24E4\uFF55\xF9\xFA\xFB\u0169\u1E79\u016B\u1E7B\u016D\xFC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289",
- }, {
- base: 'v',
- chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
- }, {
- base: 'vy',
- chars: "\uA761",
- }, {
- base: 'w',
- chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
- }, {
- base: 'x',
- chars: "\u24E7\uFF58\u1E8B\u1E8D",
- }, {
- base: 'y',
- chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
- }, {
- base: 'z',
- chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
- }
-];
-
-var diacriticsMap = {};
-for (var i = 0; i < replacementList.length; i += 1) {
- var chars = replacementList[i].chars;
- for (var j = 0; j < chars.length; j += 1) {
- diacriticsMap[chars[j]] = replacementList[i].base;
- }
-}
-
-function removeDiacritics(str) {
- return str.replace(/[^\u0000-\u007e]/g, function(c) {
- return diacriticsMap[c] || c;
- });
-}
-
-},{}],2:[function(require,module,exports){
-(function (global){
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.flexibility=e()}}(function(){return function e(t,r,l){function n(f,i){if(!r[f]){if(!t[f]){var s="function"==typeof require&&require;if(!i&&s)return s(f,!0);if(o)return o(f,!0);var a=new Error("Cannot find module '"+f+"'");throw a.code="MODULE_NOT_FOUND",a}var c=r[f]={exports:{}};t[f][0].call(c.exports,function(e){var r=t[f][1][e];return n(r?r:e)},c,c.exports,e,t,r,l)}return r[f].exports}for(var o="function"==typeof require&&require,f=0;f<l.length;f++)n(l[f]);return n}({1:[function(e,t,r){t.exports=function(e){var t,r,l,n=-1;if(e.lines.length>1&&"flex-start"===e.style.alignContent)for(t=0;l=e.lines[++n];)l.crossStart=t,t+=l.cross;else if(e.lines.length>1&&"flex-end"===e.style.alignContent)for(t=e.flexStyle.crossSpace;l=e.lines[++n];)l.crossStart=t,t+=l.cross;else if(e.lines.length>1&&"center"===e.style.alignContent)for(t=e.flexStyle.crossSpace/2;l=e.lines[++n];)l.crossStart=t,t+=l.cross;else if(e.lines.length>1&&"space-between"===e.style.alignContent)for(r=e.flexStyle.crossSpace/(e.lines.length-1),t=0;l=e.lines[++n];)l.crossStart=t,t+=l.cross+r;else if(e.lines.length>1&&"space-around"===e.style.alignContent)for(r=2*e.flexStyle.crossSpace/(2*e.lines.length),t=r/2;l=e.lines[++n];)l.crossStart=t,t+=l.cross+r;else for(r=e.flexStyle.crossSpace/e.lines.length,t=e.flexStyle.crossInnerBefore;l=e.lines[++n];)l.crossStart=t,l.cross+=r,t+=l.cross}},{}],2:[function(e,t,r){t.exports=function(e){for(var t,r=-1;line=e.lines[++r];)for(t=-1;child=line.children[++t];){var l=child.style.alignSelf;"auto"===l&&(l=e.style.alignItems),"flex-start"===l?child.flexStyle.crossStart=line.crossStart:"flex-end"===l?child.flexStyle.crossStart=line.crossStart+line.cross-child.flexStyle.crossOuter:"center"===l?child.flexStyle.crossStart=line.crossStart+(line.cross-child.flexStyle.crossOuter)/2:(child.flexStyle.crossStart=line.crossStart,child.flexStyle.crossOuter=line.cross,child.flexStyle.cross=child.flexStyle.crossOuter-child.flexStyle.crossBefore-child.flexStyle.crossAfter)}}},{}],3:[function(e,t,r){t.exports=function l(e,l){var t="row"===l||"row-reverse"===l,r=e.mainAxis;if(r){var n=t&&"inline"===r||!t&&"block"===r;n||(e.flexStyle={main:e.flexStyle.cross,cross:e.flexStyle.main,mainOffset:e.flexStyle.crossOffset,crossOffset:e.flexStyle.mainOffset,mainBefore:e.flexStyle.crossBefore,mainAfter:e.flexStyle.crossAfter,crossBefore:e.flexStyle.mainBefore,crossAfter:e.flexStyle.mainAfter,mainInnerBefore:e.flexStyle.crossInnerBefore,mainInnerAfter:e.flexStyle.crossInnerAfter,crossInnerBefore:e.flexStyle.mainInnerBefore,crossInnerAfter:e.flexStyle.mainInnerAfter,mainBorderBefore:e.flexStyle.crossBorderBefore,mainBorderAfter:e.flexStyle.crossBorderAfter,crossBorderBefore:e.flexStyle.mainBorderBefore,crossBorderAfter:e.flexStyle.mainBorderAfter})}else t?e.flexStyle={main:e.style.width,cross:e.style.height,mainOffset:e.style.offsetWidth,crossOffset:e.style.offsetHeight,mainBefore:e.style.marginLeft,mainAfter:e.style.marginRight,crossBefore:e.style.marginTop,crossAfter:e.style.marginBottom,mainInnerBefore:e.style.paddingLeft,mainInnerAfter:e.style.paddingRight,crossInnerBefore:e.style.paddingTop,crossInnerAfter:e.style.paddingBottom,mainBorderBefore:e.style.borderLeftWidth,mainBorderAfter:e.style.borderRightWidth,crossBorderBefore:e.style.borderTopWidth,crossBorderAfter:e.style.borderBottomWidth}:e.flexStyle={main:e.style.height,cross:e.style.width,mainOffset:e.style.offsetHeight,crossOffset:e.style.offsetWidth,mainBefore:e.style.marginTop,mainAfter:e.style.marginBottom,crossBefore:e.style.marginLeft,crossAfter:e.style.marginRight,mainInnerBefore:e.style.paddingTop,mainInnerAfter:e.style.paddingBottom,crossInnerBefore:e.style.paddingLeft,crossInnerAfter:e.style.paddingRight,mainBorderBefore:e.style.borderTopWidth,mainBorderAfter:e.style.borderBottomWidth,crossBorderBefore:e.style.borderLeftWidth,crossBorderAfter:e.style.borderRightWidth},"content-box"===e.style.boxSizing&&("number"==typeof e.flexStyle.main&&(e.flexStyle.main+=e.flexStyle.mainInnerBefore+e.flexStyle.mainInnerAfter+e.flexStyle.mainBorderBefore+e.flexStyle.mainBorderAfter),"number"==typeof e.flexStyle.cross&&(e.flexStyle.cross+=e.flexStyle.crossInnerBefore+e.flexStyle.crossInnerAfter+e.flexStyle.crossBorderBefore+e.flexStyle.crossBorderAfter));e.mainAxis=t?"inline":"block",e.crossAxis=t?"block":"inline","number"==typeof e.style.flexBasis&&(e.flexStyle.main=e.style.flexBasis+e.flexStyle.mainInnerBefore+e.flexStyle.mainInnerAfter+e.flexStyle.mainBorderBefore+e.flexStyle.mainBorderAfter),e.flexStyle.mainOuter=e.flexStyle.main,e.flexStyle.crossOuter=e.flexStyle.cross,"auto"===e.flexStyle.mainOuter&&(e.flexStyle.mainOuter=e.flexStyle.mainOffset),"auto"===e.flexStyle.crossOuter&&(e.flexStyle.crossOuter=e.flexStyle.crossOffset),"number"==typeof e.flexStyle.mainBefore&&(e.flexStyle.mainOuter+=e.flexStyle.mainBefore),"number"==typeof e.flexStyle.mainAfter&&(e.flexStyle.mainOuter+=e.flexStyle.mainAfter),"number"==typeof e.flexStyle.crossBefore&&(e.flexStyle.crossOuter+=e.flexStyle.crossBefore),"number"==typeof e.flexStyle.crossAfter&&(e.flexStyle.crossOuter+=e.flexStyle.crossAfter)}},{}],4:[function(e,t,r){var l=e("../reduce");t.exports=function(e){if(e.mainSpace>0){var t=l(e.children,function(e,t){return e+parseFloat(t.style.flexGrow)},0);t>0&&(e.main=l(e.children,function(r,l){return"auto"===l.flexStyle.main?l.flexStyle.main=l.flexStyle.mainOffset+parseFloat(l.style.flexGrow)/t*e.mainSpace:l.flexStyle.main+=parseFloat(l.style.flexGrow)/t*e.mainSpace,l.flexStyle.mainOuter=l.flexStyle.main+l.flexStyle.mainBefore+l.flexStyle.mainAfter,r+l.flexStyle.mainOuter},0),e.mainSpace=0)}}},{"../reduce":12}],5:[function(e,t,r){var l=e("../reduce");t.exports=function(e){if(e.mainSpace<0){var t=l(e.children,function(e,t){return e+parseFloat(t.style.flexShrink)},0);t>0&&(e.main=l(e.children,function(r,l){return l.flexStyle.main+=parseFloat(l.style.flexShrink)/t*e.mainSpace,l.flexStyle.mainOuter=l.flexStyle.main+l.flexStyle.mainBefore+l.flexStyle.mainAfter,r+l.flexStyle.mainOuter},0),e.mainSpace=0)}}},{"../reduce":12}],6:[function(e,t,r){var l=e("../reduce");t.exports=function(e){var t;e.lines=[t={main:0,cross:0,children:[]}];for(var r,n=-1;r=e.children[++n];)"nowrap"===e.style.flexWrap||0===t.children.length||"auto"===e.flexStyle.main||e.flexStyle.main-e.flexStyle.mainInnerBefore-e.flexStyle.mainInnerAfter-e.flexStyle.mainBorderBefore-e.flexStyle.mainBorderAfter>=t.main+r.flexStyle.mainOuter?(t.main+=r.flexStyle.mainOuter,t.cross=Math.max(t.cross,r.flexStyle.crossOuter)):e.lines.push(t={main:r.flexStyle.mainOuter,cross:r.flexStyle.crossOuter,children:[]}),t.children.push(r);e.flexStyle.mainLines=l(e.lines,function(e,t){return Math.max(e,t.main)},0),e.flexStyle.crossLines=l(e.lines,function(e,t){return e+t.cross},0),"auto"===e.flexStyle.main&&(e.flexStyle.main=Math.max(e.flexStyle.mainOffset,e.flexStyle.mainLines+e.flexStyle.mainInnerBefore+e.flexStyle.mainInnerAfter+e.flexStyle.mainBorderBefore+e.flexStyle.mainBorderAfter)),"auto"===e.flexStyle.cross&&(e.flexStyle.cross=Math.max(e.flexStyle.crossOffset,e.flexStyle.crossLines+e.flexStyle.crossInnerBefore+e.flexStyle.crossInnerAfter+e.flexStyle.crossBorderBefore+e.flexStyle.crossBorderAfter)),e.flexStyle.crossSpace=e.flexStyle.cross-e.flexStyle.crossInnerBefore-e.flexStyle.crossInnerAfter-e.flexStyle.crossBorderBefore-e.flexStyle.crossBorderAfter-e.flexStyle.crossLines,e.flexStyle.mainOuter=e.flexStyle.main+e.flexStyle.mainBefore+e.flexStyle.mainAfter,e.flexStyle.crossOuter=e.flexStyle.cross+e.flexStyle.crossBefore+e.flexStyle.crossAfter}},{"../reduce":12}],7:[function(e,t,r){function l(t){for(var r,l=-1;r=t.children[++l];)e("./flex-direction")(r,t.style.flexDirection);e("./flex-direction")(t,t.style.flexDirection),e("./order")(t),e("./flexbox-lines")(t),e("./align-content")(t),l=-1;for(var n;n=t.lines[++l];)n.mainSpace=t.flexStyle.main-t.flexStyle.mainInnerBefore-t.flexStyle.mainInnerAfter-t.flexStyle.mainBorderBefore-t.flexStyle.mainBorderAfter-n.main,e("./flex-grow")(n),e("./flex-shrink")(n),e("./margin-main")(n),e("./margin-cross")(n),e("./justify-content")(n,t.style.justifyContent,t);e("./align-items")(t)}t.exports=l},{"./align-content":1,"./align-items":2,"./flex-direction":3,"./flex-grow":4,"./flex-shrink":5,"./flexbox-lines":6,"./justify-content":8,"./margin-cross":9,"./margin-main":10,"./order":11}],8:[function(e,t,r){t.exports=function(e,t,r){var l,n,o,f=r.flexStyle.mainInnerBefore,i=-1;if("flex-end"===t)for(l=e.mainSpace,l+=f;o=e.children[++i];)o.flexStyle.mainStart=l,l+=o.flexStyle.mainOuter;else if("center"===t)for(l=e.mainSpace/2,l+=f;o=e.children[++i];)o.flexStyle.mainStart=l,l+=o.flexStyle.mainOuter;else if("space-between"===t)for(n=e.mainSpace/(e.children.length-1),l=0,l+=f;o=e.children[++i];)o.flexStyle.mainStart=l,l+=o.flexStyle.mainOuter+n;else if("space-around"===t)for(n=2*e.mainSpace/(2*e.children.length),l=n/2,l+=f;o=e.children[++i];)o.flexStyle.mainStart=l,l+=o.flexStyle.mainOuter+n;else for(l=0,l+=f;o=e.children[++i];)o.flexStyle.mainStart=l,l+=o.flexStyle.mainOuter}},{}],9:[function(e,t,r){t.exports=function(e){for(var t,r=-1;t=e.children[++r];){var l=0;"auto"===t.flexStyle.crossBefore&&++l,"auto"===t.flexStyle.crossAfter&&++l;var n=e.cross-t.flexStyle.crossOuter;"auto"===t.flexStyle.crossBefore&&(t.flexStyle.crossBefore=n/l),"auto"===t.flexStyle.crossAfter&&(t.flexStyle.crossAfter=n/l),"auto"===t.flexStyle.cross?t.flexStyle.crossOuter=t.flexStyle.crossOffset+t.flexStyle.crossBefore+t.flexStyle.crossAfter:t.flexStyle.crossOuter=t.flexStyle.cross+t.flexStyle.crossBefore+t.flexStyle.crossAfter}}},{}],10:[function(e,t,r){t.exports=function(e){for(var t,r=0,l=-1;t=e.children[++l];)"auto"===t.flexStyle.mainBefore&&++r,"auto"===t.flexStyle.mainAfter&&++r;if(r>0){for(l=-1;t=e.children[++l];)"auto"===t.flexStyle.mainBefore&&(t.flexStyle.mainBefore=e.mainSpace/r),"auto"===t.flexStyle.mainAfter&&(t.flexStyle.mainAfter=e.mainSpace/r),"auto"===t.flexStyle.main?t.flexStyle.mainOuter=t.flexStyle.mainOffset+t.flexStyle.mainBefore+t.flexStyle.mainAfter:t.flexStyle.mainOuter=t.flexStyle.main+t.flexStyle.mainBefore+t.flexStyle.mainAfter;e.mainSpace=0}}},{}],11:[function(e,t,r){var l=/^(column|row)-reverse$/;t.exports=function(e){e.children.sort(function(e,t){return e.style.order-t.style.order||e.index-t.index}),l.test(e.style.flexDirection)&&e.children.reverse()}},{}],12:[function(e,t,r){function l(e,t,r){for(var l=e.length,n=-1;++n<l;)n in e&&(r=t(r,e[n],n));return r}t.exports=l},{}],13:[function(e,t,r){function l(e){i(f(e))}var n=e("./read"),o=e("./write"),f=e("./readAll"),i=e("./writeAll");t.exports=l,t.exports.read=n,t.exports.write=o,t.exports.readAll=f,t.exports.writeAll=i},{"./read":15,"./readAll":16,"./write":17,"./writeAll":18}],14:[function(e,t,r){function l(e,t,r){var l=e[t],f=String(l).match(o);if(!f){var a=t.match(s);if(a){var c=e["border"+a[1]+"Style"];return"none"===c?0:i[l]||0}return l}var y=f[1],x=f[2];return"px"===x?1*y:"cm"===x?.3937*y*96:"in"===x?96*y:"mm"===x?.3937*y*96/10:"pc"===x?12*y*96/72:"pt"===x?96*y/72:"rem"===x?16*y:n(l,r)}function n(e,t){f.style.cssText="border:none!important;clip:rect(0 0 0 0)!important;display:block!important;font-size:1em!important;height:0!important;margin:0!important;padding:0!important;position:relative!important;width:"+e+"!important",t.parentNode.insertBefore(f,t.nextSibling);var r=f.offsetWidth;return t.parentNode.removeChild(f),r}t.exports=l;var o=/^([-+]?\d*\.?\d+)(%|[a-z]+)$/,f=document.createElement("div"),i={medium:4,none:0,thick:6,thin:2},s=/^border(Bottom|Left|Right|Top)Width$/},{}],15:[function(e,t,r){function l(e){var t={alignContent:"stretch",alignItems:"stretch",alignSelf:"auto",borderBottomStyle:"none",borderBottomWidth:0,borderLeftStyle:"none",borderLeftWidth:0,borderRightStyle:"none",borderRightWidth:0,borderTopStyle:"none",borderTopWidth:0,boxSizing:"content-box",display:"inline",flexBasis:"auto",flexDirection:"row",flexGrow:0,flexShrink:1,flexWrap:"nowrap",justifyContent:"flex-start",height:"auto",marginTop:0,marginRight:0,marginLeft:0,marginBottom:0,paddingTop:0,paddingRight:0,paddingLeft:0,paddingBottom:0,maxHeight:"none",maxWidth:"none",minHeight:0,minWidth:0,order:0,position:"static",width:"auto"},r=e instanceof Element;if(r){var l=e.hasAttribute("data-style"),i=l?e.getAttribute("data-style"):e.getAttribute("style")||"";l||e.setAttribute("data-style",i);var s=window.getComputedStyle&&getComputedStyle(e)||{};f(t,s);var c=e.currentStyle||{};n(t,c),o(t,i);for(var y in t)t[y]=a(t,y,e);var x=e.getBoundingClientRect();t.offsetHeight=x.height||e.offsetHeight,t.offsetWidth=x.width||e.offsetWidth}var S={element:e,style:t};return S}function n(e,t){for(var r in e){var l=r in t;if(l)e[r]=t[r];else{var n=r.replace(/[A-Z]/g,"-$&").toLowerCase(),o=n in t;o&&(e[r]=t[n])}}var f="-js-display"in t;f&&(e.display=t["-js-display"])}function o(e,t){for(var r;r=i.exec(t);){var l=r[1].toLowerCase().replace(/-[a-z]/g,function(e){return e.slice(1).toUpperCase()});e[l]=r[2]}}function f(e,t){for(var r in e){var l=r in t;l&&!s.test(r)&&(e[r]=t[r])}}t.exports=l;var i=/([^\s:;]+)\s*:\s*([^;]+?)\s*(;|$)/g,s=/^(alignSelf|height|width)$/,a=e("./getComputedLength")},{"./getComputedLength":14}],16:[function(e,t,r){function l(e){var t=[];return n(e,t),t}function n(e,t){for(var r,l=o(e),i=[],s=-1;r=e.childNodes[++s];){var a=3===r.nodeType&&!/^\s*$/.test(r.nodeValue);if(l&&a){var c=r;r=e.insertBefore(document.createElement("flex-item"),c),r.appendChild(c)}var y=r instanceof Element;if(y){var x=n(r,t);if(l){var S=r.style;S.display="inline-block",S.position="absolute",x.style=f(r).style,i.push(x)}}}var m={element:e,children:i};return l&&(m.style=f(e).style,t.push(m)),m}function o(e){var t=e instanceof Element,r=t&&e.getAttribute("data-style"),l=t&&e.currentStyle&&e.currentStyle["-js-display"],n=i.test(r)||s.test(l);return n}t.exports=l;var f=e("../read"),i=/(^|;)\s*display\s*:\s*(inline-)?flex\s*(;|$)/i,s=/^(inline-)?flex$/i},{"../read":15}],17:[function(e,t,r){function l(e){o(e);var t=e.element.style,r="inline"===e.mainAxis?["main","cross"]:["cross","main"];t.boxSizing="content-box",t.display="block",t.position="relative",t.width=n(e.flexStyle[r[0]]-e.flexStyle[r[0]+"InnerBefore"]-e.flexStyle[r[0]+"InnerAfter"]-e.flexStyle[r[0]+"BorderBefore"]-e.flexStyle[r[0]+"BorderAfter"]),t.height=n(e.flexStyle[r[1]]-e.flexStyle[r[1]+"InnerBefore"]-e.flexStyle[r[1]+"InnerAfter"]-e.flexStyle[r[1]+"BorderBefore"]-e.flexStyle[r[1]+"BorderAfter"]);for(var l,f=-1;l=e.children[++f];){var i=l.element.style,s="inline"===l.mainAxis?["main","cross"]:["cross","main"];i.boxSizing="content-box",i.display="block",i.position="absolute","auto"!==l.flexStyle[s[0]]&&(i.width=n(l.flexStyle[s[0]]-l.flexStyle[s[0]+"InnerBefore"]-l.flexStyle[s[0]+"InnerAfter"]-l.flexStyle[s[0]+"BorderBefore"]-l.flexStyle[s[0]+"BorderAfter"])),"auto"!==l.flexStyle[s[1]]&&(i.height=n(l.flexStyle[s[1]]-l.flexStyle[s[1]+"InnerBefore"]-l.flexStyle[s[1]+"InnerAfter"]-l.flexStyle[s[1]+"BorderBefore"]-l.flexStyle[s[1]+"BorderAfter"])),i.top=n(l.flexStyle[s[1]+"Start"]),i.left=n(l.flexStyle[s[0]+"Start"]),i.marginTop=n(l.flexStyle[s[1]+"Before"]),i.marginRight=n(l.flexStyle[s[0]+"After"]),i.marginBottom=n(l.flexStyle[s[1]+"After"]),i.marginLeft=n(l.flexStyle[s[0]+"Before"])}}function n(e){return"string"==typeof e?e:Math.max(e,0)+"px"}t.exports=l;var o=e("../flexbox")},{"../flexbox":7}],18:[function(e,t,r){function l(e){for(var t,r=-1;t=e[++r];)n(t)}t.exports=l;var n=e("../write")},{"../write":17}]},{},[13])(13)});
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-
-},{}],3:[function(require,module,exports){
-/*
- * Fuzzy
- * https://github.com/myork/fuzzy
- *
- * Copyright (c) 2012 Matt York
- * Licensed under the MIT license.
- */
-
-(function() {
-
-var root = this;
-
-var fuzzy = {};
-
-// Use in node or in browser
-if (typeof exports !== 'undefined') {
- module.exports = fuzzy;
-} else {
- root.fuzzy = fuzzy;
-}
-
-// Return all elements of `array` that have a fuzzy
-// match against `pattern`.
-fuzzy.simpleFilter = function(pattern, array) {
- return array.filter(function(string) {
- return fuzzy.test(pattern, string);
- });
-};
-
-// Does `pattern` fuzzy match `string`?
-fuzzy.test = function(pattern, string) {
- return fuzzy.match(pattern, string) !== null;
-};
-
-// If `pattern` matches `string`, wrap each matching character
-// in `opts.pre` and `opts.post`. If no match, return null
-fuzzy.match = function(pattern, string, opts) {
- opts = opts || {};
- var patternIdx = 0
- , result = []
- , len = string.length
- , totalScore = 0
- , currScore = 0
- // prefix
- , pre = opts.pre || ''
- // suffix
- , post = opts.post || ''
- // String to compare against. This might be a lowercase version of the
- // raw string
- , compareString = opts.caseSensitive && string || string.toLowerCase()
- , ch, compareChar;
-
- pattern = opts.caseSensitive && pattern || pattern.toLowerCase();
-
- // For each character in the string, either add it to the result
- // or wrap in template if it's the next string in the pattern
- for(var idx = 0; idx < len; idx++) {
- ch = string[idx];
- if(compareString[idx] === pattern[patternIdx]) {
- ch = pre + ch + post;
- patternIdx += 1;
-
- // consecutive characters should increase the score more than linearly
- currScore += 1 + currScore;
- } else {
- currScore = 0;
- }
- totalScore += currScore;
- result[result.length] = ch;
- }
-
- // return rendered string if we have a match for every char
- if(patternIdx === pattern.length) {
- return {rendered: result.join(''), score: totalScore};
- }
-
- return null;
-};
-
-// The normal entry point. Filters `arr` for matches against `pattern`.
-// It returns an array with matching values of the type:
-//
-// [{
-// string: '<b>lah' // The rendered string
-// , index: 2 // The index of the element in `arr`
-// , original: 'blah' // The original element in `arr`
-// }]
-//
-// `opts` is an optional argument bag. Details:
-//
-// opts = {
-// // string to put before a matching character
-// pre: '<b>'
-//
-// // string to put after matching character
-// , post: '</b>'
-//
-// // Optional function. Input is an entry in the given arr`,
-// // output should be the string to test `pattern` against.
-// // In this example, if `arr = [{crying: 'koala'}]` we would return
-// // 'koala'.
-// , extract: function(arg) { return arg.crying; }
-// }
-fuzzy.filter = function(pattern, arr, opts) {
- opts = opts || {};
- return arr
- .reduce(function(prev, element, idx, arr) {
- var str = element;
- if(opts.extract) {
- str = opts.extract(element);
- }
- var rendered = fuzzy.match(pattern, str, opts);
- if(rendered != null) {
- prev[prev.length] = {
- string: rendered.rendered
- , score: rendered.score
- , index: idx
- , original: element
- };
- }
- return prev;
- }, [])
-
- // Sort by score. Browsers are inconsistent wrt stable/unstable
- // sorting, so force stable by using the index in the case of tie.
- // See http://ofb.net/~sethml/is-sort-stable.html
- .sort(function(a,b) {
- var compare = b.score - a.score;
- if(compare) return compare;
- return a.index - b.index;
- });
-};
-
-
-}());
-
-
-},{}],4:[function(require,module,exports){
-'use strict';
-module.exports = leftPad;
-
-var cache = [
- '',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' '
-];
-
-function leftPad (str, len, ch) {
- // convert `str` to `string`
- str = str + '';
- // `len` is the `pad`'s length now
- len = len - str.length;
- // doesn't need to pad
- if (len <= 0) return str;
- // `ch` defaults to `' '`
- if (!ch && ch !== 0) ch = ' ';
- // convert `ch` to `string`
- ch = ch + '';
- // cache common use cases
- if (ch === ' ' && len < 10) return cache[len] + str;
- // `pad` starts with an empty string
- var pad = '';
- // loop
- while (true) {
- // add `ch` to `pad` if `len` is odd
- if (len & 1) pad += ch;
- // devide `len` by 2, ditch the fraction
- len >>= 1;
- // "double" the `ch` so this operation count grows logarithmically on `len`
- // each time `ch` is "doubled", the `len` would need to be "doubled" too
- // similar to finding a value in binary search tree, hence O(log(n))
- if (len) ch += ch;
- // `len` is 0, exit the loop
- else break;
- }
- // pad `str`!
- return pad + str;
-}
-
-},{}],5:[function(require,module,exports){
-'use strict';
-
-var sinterklaas = function sinterklaas() {
- console.log('sinterklaas easter egg activated');
- var searchNode = document.querySelector('#search');
- var inputNode = searchNode.querySelector('input[type="search"]');
- var autocompleteNode = document.querySelector('.autocomplete');
- var autocomplete = false;
- var lyrics = [[{ woord: 'Hoor ', time: 0 }, { woord: 'wie ', time: 0.3 }, { woord: 'klopt ', time: 0.6 }, { woord: 'daar ', time: 0.9 }, { woord: 'kind', time: 1.2 }, { woord: '\'ren', time: 1.5 }], [{ woord: 'Hoor ', time: 1.8 }, { woord: 'wie ', time: 2.1 }, { woord: 'klopt ', time: 2.5 }, { woord: 'daar ', time: 2.8 }, { woord: 'kind', time: 3.1 }, { woord: '\'ren', time: 3.4 }], [{ woord: 'Hoor ', time: 3.7 }, { woord: 'wie ', time: 4 }, { woord: 'tikt ', time: 4.3 }, { woord: 'daar ', time: 4.6 }, { woord: 'zacht', time: 4.8 }, { woord: 'jes ', time: 5.3 }, { woord: 'tegen ', time: 5.5 }, { woord: '\'t ', time: 6.1 }, { woord: 'raam ', time: 6.2 }]];
-
- var originalValue = inputNode.value;
-
- inputNode.value = '';
- inputNode.placeholder = '';
-
- lyrics.forEach(function (row, rowIndex) {
- row.forEach(function (word, wordIndex) {
- setTimeout(function () {
- if (wordIndex === 0) inputNode.placeholder = '';
- inputNode.placeholder += word.woord;
- }, word.time * 1000);
- if (lyrics.length === rowIndex + 1 && lyrics[rowIndex].length === wordIndex + 1) {
- setTimeout(function () {
- if (inputNode.value === '') {
- inputNode.value = originalValue;
- }
- inputNode.placeholder = 'Zoeken';
- autocomplete = true;
- }, word.time * 1000 + 1000);
- }
- });
- });
-
- inputNode.addEventListener('focus', function () {
- if (!autocomplete) return;
-
- autocompleteNode.innerHTML = '';
-
- var autocompleteLyrics = ['\'t Is een vreemd\'ling zeker,', 'die verdwaalt is zeker.', '\'k Zal eens even vragen naar zijn naam:'];
-
- autocompleteLyrics.forEach(function (row) {
- var resultNode = document.createElement('li');
- resultNode.innerHTML = row;
- autocompleteNode.appendChild(resultNode);
- });
- });
-
- inputNode.addEventListener('input', function () {
- if (!autocomplete) return;
- if (inputNode.value.toLowerCase() === 'sint nicolaas' || inputNode.value.toLowerCase() === 'sintnicolaas' || inputNode.value.toLowerCase() === 'sint nikolaas' || inputNode.value.toLowerCase() === 'sintnikolaas') {
- inputNode.value = '';
- window.location.href = 'https://www.youtube-nocookie.com/embed/jsOiKJ3kKXM?start=30';
- }
- });
-};
-
-module.exports = { sinterklaas: sinterklaas };
-
-},{}],6:[function(require,module,exports){
-'use strict';
-
-var leftPad = require('left-pad');
-var getWeek = require('./getWeek');
-
-function getURLOfUsers(weekOffset, type, id) {
- return '//' + window.location.host + '/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F' + (getWeek() + weekOffset + '%2F' + type + '%2F' + type + leftPad(id, 5, '0') + '.htm');
-}
-
-module.exports = getURLOfUsers;
-
-},{"./getWeek":7,"left-pad":4}],7:[function(require,module,exports){
-"use strict";
-
-// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js,
-// were using the same code as they do to be sure that we always get the same
-// week number.
-function getWeek() {
- // Create a copy of this date object
- var target = new Date();
-
- // ISO week date weeks start on monday
- // so correct the day number
- var dayNr = (target.getDay() + 6) % 7;
-
- // ISO 8601 states that week 1 is the week
- // with the first thursday of that year.
- // Set the target date to the thursday in the target week
- target.setDate(target.getDate() - dayNr + 3);
-
- // Store the millisecond value of the target date
- var firstThursday = target.valueOf();
-
- // Set the target to the first thursday of the year
- // First set the target to january first
- target.setMonth(0, 1);
- // Not a thursday? Correct the date to the next thursday
- if (target.getDay() !== 4) {
- target.setMonth(0, 1 + (4 - target.getDay() + 7) % 7);
- }
-
- // The weeknumber is the number of weeks between the
- // first thursday of the year and the thursday in the target week
- return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000
-}
-
-module.exports = getWeek;
-
-},{}],8:[function(require,module,exports){
-'use strict';
-
-/* global ga FLAGS USERS */
-
-require('flexibility');
-
-var fuzzy = require('fuzzy');
-// const getUsers = require('./getUsers')
-var getURLOfUser = require('./getURLOfUser');
-var removeDiacritics = require('diacritics').remove;
-var getWeek = require('./getWeek');
-var easterEggs = require('./easterEggs');
-
-var searchNode = document.querySelector('#search');
-var inputNode = searchNode.querySelector('input[type="search"]');
-var autocompleteNode = document.querySelector('.autocomplete');
-var scheduleIframe = document.querySelector('#schedule');
-var prevButton = document.querySelectorAll('#week-selector button')[0];
-var nextButton = document.querySelectorAll('#week-selector button')[1];
-var currentWeekNode = document.querySelector('.current');
-var favNode = document.querySelector('.fav');
-
-if (FLAGS.indexOf('NO_FEATURE_DETECT') === -1) {
- if (document.querySelector('#schedule').getClientRects()[0].bottom !== document.body.getClientRects()[0].bottom) {
- window.location = 'http://www.meetingpointmco.nl/Roosters-AL/doc/';
- } else {
- window.onerror = function () {
- window.location = 'http://www.meetingpointmco.nl/Roosters-AL/doc/';
- };
- }
-} else {
- console.log('feature detection is OFF');
-}
-
-var selectedResult = -1;
-var selectedUser = void 0;
-var results = [];
-var offset = 0;
-
-function getCurrentFav() {
- if (!window.localStorage.getItem('fav')) return;
- var favCode = window.localStorage.getItem('fav').split(':');
- var fav = USERS.filter(function (user) {
- return user.type === favCode[0] && user.index === Number(favCode[1]);
- });
- return fav[0];
-}
-
-function changeFav(isFav) {
- if (!selectedUser) return;
- if (isFav) {
- window.localStorage.setItem('fav', selectedUser.type + ':' + selectedUser.index);
- } else {
- window.localStorage.removeItem('fav');
- }
- updateFavNode();
-}
-
-function usersEqual(user1, user2) {
- if (user1 == null || user2 == null) return false;
- return user1.type === user2.type && user1.index === user2.index;
-}
-
-function updateFavNode() {
- if (usersEqual(getCurrentFav(), selectedUser)) {
- favNode.innerHTML = '&#xE838;';
- } else {
- favNode.innerHTML = '&#xE83A';
- }
-}
-
-function updateWeekText() {
- if (offset === 0) currentWeekNode.innerHTML = 'Week ' + (getWeek() + offset);else currentWeekNode.innerHTML = '<strong>Week ' + (getWeek() + offset) + '</strong>';
-}
-
-updateWeekText();
-
-searchNode.addEventListener('keydown', function (e) {
- if (results.length !== 0 && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
- e.preventDefault();
-
- if (document.querySelector('.selected')) document.querySelector('.selected').classList.remove('selected');
-
- var change = e.key === 'ArrowDown' ? 1 : -1;
- selectedResult += change;
- if (selectedResult < -1) selectedResult = results.length - 1;else if (selectedResult > results.length - 1) selectedResult = -1;
-
- if (selectedResult !== -1) autocompleteNode.children[selectedResult].classList.add('selected');
- }
-});
-
-var inputEventStr = void 0;
-if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) {
- inputEventStr = 'textinput'; // IE 6-11
-} else {
- inputEventStr = 'input'; // normal browsers
-}
-
-searchNode.addEventListener(inputEventStr, function (e) {
- document.body.classList.remove('no-input');
- autocompleteNode.innerHTML = '';
- if (inputNode.value.trim() === '') return;
-
- selectedResult = -1;
- results = fuzzy.filter(removeDiacritics(inputNode.value), USERS, {
- extract: function extract(el) {
- return removeDiacritics(el.value);
- }
- }).slice(0, 7);
-
- results.forEach(function (result) {
- var resultNode = document.createElement('li');
- resultNode.innerHTML = '' + result.original.value;
- autocompleteNode.appendChild(resultNode);
- });
-});
-
-searchNode.addEventListener('submit', submitForm);
-
-function submitForm(e) {
- if (e) e.preventDefault();
- if (results.length !== 0) {
- var indexInResult = selectedResult === -1 ? 0 : selectedResult;
- selectedUser = USERS[results[indexInResult].index];
- }
- if (selectedUser == null) return;
-
- document.body.classList.add('searched');
-
- updateFavNode();
-
- inputNode.value = selectedUser.value;
- autocompleteNode.innerHTML = '';
-
- inputNode.blur();
-
- scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1);
-
- var eventAction = void 0;
- switch (selectedUser.type) {
- case 'c':
- eventAction = 'Class';
- break;
- case 't':
- eventAction = 'Teacher';
- break;
- case 'r':
- eventAction = 'Room';
- break;
- case 's':
- eventAction = 'Student';
- break;
- }
- var eventLabel = selectedUser.value;
-
- ga(function () {
- ga('send', { hitType: 'event', eventCategory: 'search', eventAction: eventAction, eventLabel: eventLabel });
- });
-}
-
-autocompleteNode.addEventListener('click', function (e) {
- if (autocompleteNode.contains(e.target)) {
- selectedResult = Array.prototype.indexOf.call(e.target.parentElement.childNodes, e.target);
- submitForm();
- }
-});
-
-prevButton.addEventListener('click', function () {
- offset--;
- updateWeekText();
- submitForm();
-});
-
-nextButton.addEventListener('click', function () {
- offset++;
- updateWeekText();
- submitForm();
-});
-
-inputNode.addEventListener('click', function () {
- inputNode.select();
-});
-
-window.addEventListener('blur', function () {
- // this will removed the selection without drawing focus on it (safari)
- // this will removed selection even when focusing an iframe (chrome)
- var oldValue = inputNode.value;
- inputNode.value = '';
- inputNode.value = oldValue;
-
- // this will hide the keyboard (iOS safari)
- document.activeElement.blur();
-});
-
-searchNode.addEventListener('blur', function (e) {
- autocompleteNode.innerHTML = '';
-});
-
-favNode.addEventListener('click', function () {
- if (usersEqual(getCurrentFav(), selectedUser)) {
- changeFav(false);
- } else {
- changeFav(true);
- }
-});
-
-var currentFav = getCurrentFav();
-
-if (currentFav) {
- (function () {
- selectedUser = currentFav;
- inputNode.value = selectedUser.value;
- scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1);
- updateFavNode();
-
- var eventAction = void 0;
- switch (selectedUser.type) {
- case 'c':
- eventAction = 'Class';
- break;
- case 't':
- eventAction = 'Teacher';
- break;
- case 'r':
- eventAction = 'Room';
- break;
- case 's':
- eventAction = 'Student';
- break;
- }
- var eventLabel = selectedUser.value;
-
- ga(function () {
- ga('send', { hitType: 'event', eventCategory: 'search fav', eventAction: eventAction, eventLabel: eventLabel });
- });
- })();
-} else if (inputNode.value === '') {
- document.body.classList.add('no-input');
- inputNode.focus();
-}
-
-if (inputNode.value !== '') {
- document.body.classList.remove('no-input');
- document.body.classList.add('searched');
-}
-
-document.body.style.opacity = '1';
-
-window.easterEggs = easterEggs;
-
-},{"./easterEggs":5,"./getURLOfUser":6,"./getWeek":7,"diacritics":1,"flexibility":2,"fuzzy":3}]},{},[8])
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvZGlhY3JpdGljcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9mbGV4aWJpbGl0eS9mbGV4aWJpbGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9mdXp6eS9saWIvZnV6enkuanMiLCJub2RlX21vZHVsZXMvbGVmdC1wYWQvaW5kZXguanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvZWFzdGVyRWdncy5qcyIsInB1YmxpYy9qYXZhc2NyaXB0cy9nZXRVUkxPZlVzZXIuanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvZ2V0V2Vlay5qcyIsInB1YmxpYy9qYXZhc2NyaXB0cy9tYWluLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDelRBOzs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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RCxNQTBCTyxJQUFJLFVBQVUsS0FBVixLQUFvQixFQUF4QixFQUE0QjtBQUNqQyxXQUFTLElBQVQsQ0FBYyxTQUFkLENBQXdCLEdBQXhCLENBQTRCLFVBQTVCO0FBQ0EsWUFBVSxLQUFWO0FBQ0Q7O0FBRUQsSUFBSSxVQUFVLEtBQVYsS0FBb0IsRUFBeEIsRUFBNEI7QUFDMUIsV0FBUyxJQUFULENBQWMsU0FBZCxDQUF3QixNQUF4QixDQUErQixVQUEvQjtBQUNBLFdBQVMsSUFBVCxDQUFjLFNBQWQsQ0FBd0IsR0FBeEIsQ0FBNEIsVUFBNUI7QUFDRDs7QUFFRCxTQUFTLElBQVQsQ0FBYyxLQUFkLENBQW9CLE9BQXBCLEdBQThCLEdBQTlCOztBQUVBLE9BQU8sVUFBUCxHQUFvQixVQUFwQiIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJleHBvcnRzLnJlbW92ZSA9IHJlbW92ZURpYWNyaXRpY3M7XG5cbnZhciByZXBsYWNlbWVudExpc3QgPSBbXG4gIHtcbiAgICBiYXNlOiAnICcsXG4gICAgY2hhcnM6IFwiXFx1MDBBMFwiLFxuICB9LCB7XG4gICAgYmFzZTogJzAnLFxuICAgIGNoYXJzOiBcIlxcdTA3QzBcIixcbiAgfSwge1xuICAgIGJhc2U6ICdBJyxcbiAgICBjaGFyczogXCJcXHUyNEI2XFx1RkYyMVxcdTAwQzBcXHUwMEMxXFx1MDBDMlxcdTFFQTZcXHUxRUE0XFx1MUVBQVxcdTFFQThcXHUwMEMzXFx1MDEwMFxcdTAxMDJcXHUxRUIwXFx1MUVBRVxcdTFFQjRcXHUxRUIyXFx1MDIyNlxcdTAxRTBcXHUwMEM0XFx1MDFERVxcdTFFQTJcXHUwMEM1XFx1MDFGQVxcdTAxQ0RcXHUwMjAwXFx1MDIwMlxcdTFFQTBcXHUxRUFDXFx1MUVCNlxcdTFFMDBcXHUwMTA0XFx1MDIzQVxcdTJDNkZcIixcbiAgfSwge1xuICAgIGJhc2U6ICdBQScsXG4gICAgY2hhcnM6IFwiXFx1QTczMlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0FFJyxcbiAgICBjaGFyczogXCJcXHUwMEM2XFx1MDFGQ1xcdTAxRTJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdBTycsXG4gICAgY2hhcnM6IFwiXFx1QTczNFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0FVJyxcbiAgICBjaGFyczogXCJcXHVBNzM2XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnQVYnLFxuICAgIGNoYXJzOiBcIlxcdUE3MzhcXHVBNzNBXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnQVknLFxuICAgIGNoYXJzOiBcIlxcdUE3M0NcIixcbiAgfSwge1xuICAgIGJhc2U6ICdCJyxcbiAgICBjaGFyczogXCJcXHUyNEI3XFx1RkYyMlxcdTFFMDJcXHUxRTA0XFx1MUUwNlxcdTAyNDNcXHUwMTgxXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnQycsXG4gICAgY2hhcnM6IFwiXFx1MjRiOFxcdWZmMjNcXHVBNzNFXFx1MUUwOFxcdTAxMDZcXHUwMDQzXFx1MDEwOFxcdTAxMEFcXHUwMTBDXFx1MDBDN1xcdTAxODdcXHUwMjNCXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnRCcsXG4gICAgY2hhcnM6IFwiXFx1MjRCOVxcdUZGMjRcXHUxRTBBXFx1MDEwRVxcdTFFMENcXHUxRTEwXFx1MUUxMlxcdTFFMEVcXHUwMTEwXFx1MDE4QVxcdTAxODlcXHUxRDA1XFx1QTc3OVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0RoJyxcbiAgICBjaGFyczogXCJcXHUwMEQwXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnRFonLFxuICAgIGNoYXJzOiBcIlxcdTAxRjFcXHUwMUM0XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnRHonLFxuICAgIGNoYXJzOiBcIlxcdTAxRjJcXHUwMUM1XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnRScsXG4gICAgY2hhcnM6IFwiXFx1MDI1QlxcdTI0QkFcXHVGRjI1XFx1MDBDOFxcdTAwQzlcXHUwMENBXFx1MUVDMFxcdTFFQkVcXHUxRUM0XFx1MUVDMlxcdTFFQkNcXHUwMTEyXFx1MUUxNFxcdTFFMTZcXHUwMTE0XFx1MDExNlxcdTAwQ0JcXHUxRUJBXFx1MDExQVxcdTAyMDRcXHUwMjA2XFx1MUVCOFxcdTFFQzZcXHUwMjI4XFx1MUUxQ1xcdTAxMThcXHUxRTE4XFx1MUUxQVxcdTAxOTBcXHUwMThFXFx1MUQwN1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ0YnLFxuICAgIGNoYXJzOiBcIlxcdUE3N0NcXHUyNEJCXFx1RkYyNlxcdTFFMUVcXHUwMTkxXFx1QTc3QlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0cnLFxuICAgIGNoYXJzOiBcIlxcdTI0QkNcXHVGRjI3XFx1MDFGNFxcdTAxMUNcXHUxRTIwXFx1MDExRVxcdTAxMjBcXHUwMUU2XFx1MDEyMlxcdTAxRTRcXHUwMTkzXFx1QTdBMFxcdUE3N0RcXHVBNzdFXFx1MDI2MlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0gnLFxuICAgIGNoYXJzOiBcIlxcdTI0QkRcXHVGRjI4XFx1MDEyNFxcdTFFMjJcXHUxRTI2XFx1MDIxRVxcdTFFMjRcXHUxRTI4XFx1MUUyQVxcdTAxMjZcXHUyQzY3XFx1MkM3NVxcdUE3OERcIixcbiAgfSwge1xuICAgIGJhc2U6ICdJJyxcbiAgICBjaGFyczogXCJcXHUyNEJFXFx1RkYyOVxceENDXFx4Q0RcXHhDRVxcdTAxMjhcXHUwMTJBXFx1MDEyQ1xcdTAxMzBcXHhDRlxcdTFFMkVcXHUxRUM4XFx1MDFDRlxcdTAyMDhcXHUwMjBBXFx1MUVDQVxcdTAxMkVcXHUxRTJDXFx1MDE5N1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ0onLFxuICAgIGNoYXJzOiBcIlxcdTI0QkZcXHVGRjJBXFx1MDEzNFxcdTAyNDhcXHUwMjM3XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnSycsXG4gICAgY2hhcnM6IFwiXFx1MjRDMFxcdUZGMkJcXHUxRTMwXFx1MDFFOFxcdTFFMzJcXHUwMTM2XFx1MUUzNFxcdTAxOThcXHUyQzY5XFx1QTc0MFxcdUE3NDJcXHVBNzQ0XFx1QTdBMlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ0wnLFxuICAgIGNoYXJzOiBcIlxcdTI0QzFcXHVGRjJDXFx1MDEzRlxcdTAxMzlcXHUwMTNEXFx1MUUzNlxcdTFFMzhcXHUwMTNCXFx1MUUzQ1xcdTFFM0FcXHUwMTQxXFx1MDIzRFxcdTJDNjJcXHUyQzYwXFx1QTc0OFxcdUE3NDZcXHVBNzgwXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnTEonLFxuICAgIGNoYXJzOiBcIlxcdTAxQzdcIixcbiAgfSwge1xuICAgIGJhc2U6ICdMaicsXG4gICAgY2hhcnM6IFwiXFx1MDFDOFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ00nLFxuICAgIGNoYXJzOiBcIlxcdTI0QzJcXHVGRjJEXFx1MUUzRVxcdTFFNDBcXHUxRTQyXFx1MkM2RVxcdTAxOUNcXHUwM0ZCXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnTicsXG4gICAgY2hhcnM6IFwiXFx1QTdBNFxcdTAyMjBcXHUyNEMzXFx1RkYyRVxcdTAxRjhcXHUwMTQzXFx4RDFcXHUxRTQ0XFx1MDE0N1xcdTFFNDZcXHUwMTQ1XFx1MUU0QVxcdTFFNDhcXHUwMTlEXFx1QTc5MFxcdTFEMEVcIixcbiAgfSwge1xuICAgIGJhc2U6ICdOSicsXG4gICAgY2hhcnM6IFwiXFx1MDFDQVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ05qJyxcbiAgICBjaGFyczogXCJcXHUwMUNCXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnTycsXG4gICAgY2hhcnM6IFwiXFx1MjRDNFxcdUZGMkZcXHhEMlxceEQzXFx4RDRcXHUxRUQyXFx1MUVEMFxcdTFFRDZcXHUxRUQ0XFx4RDVcXHUxRTRDXFx1MDIyQ1xcdTFFNEVcXHUwMTRDXFx1MUU1MFxcdTFFNTJcXHUwMTRFXFx1MDIyRVxcdTAyMzBcXHhENlxcdTAyMkFcXHUxRUNFXFx1MDE1MFxcdTAxRDFcXHUwMjBDXFx1MDIwRVxcdTAxQTBcXHUxRURDXFx1MUVEQVxcdTFFRTBcXHUxRURFXFx1MUVFMlxcdTFFQ0NcXHUxRUQ4XFx1MDFFQVxcdTAxRUNcXHhEOFxcdTAxRkVcXHUwMTg2XFx1MDE5RlxcdUE3NEFcXHVBNzRDXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnT0UnLFxuICAgIGNoYXJzOiBcIlxcdTAxNTJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdPSScsXG4gICAgY2hhcnM6IFwiXFx1MDFBMlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ09PJyxcbiAgICBjaGFyczogXCJcXHVBNzRFXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnT1UnLFxuICAgIGNoYXJzOiBcIlxcdTAyMjJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdQJyxcbiAgICBjaGFyczogXCJcXHUyNEM1XFx1RkYzMFxcdTFFNTRcXHUxRTU2XFx1MDFBNFxcdTJDNjNcXHVBNzUwXFx1QTc1MlxcdUE3NTRcIixcbiAgfSwge1xuICAgIGJhc2U6ICdRJyxcbiAgICBjaGFyczogXCJcXHUyNEM2XFx1RkYzMVxcdUE3NTZcXHVBNzU4XFx1MDI0QVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1InLFxuICAgIGNoYXJzOiBcIlxcdTI0QzdcXHVGRjMyXFx1MDE1NFxcdTFFNThcXHUwMTU4XFx1MDIxMFxcdTAyMTJcXHUxRTVBXFx1MUU1Q1xcdTAxNTZcXHUxRTVFXFx1MDI0Q1xcdTJDNjRcXHVBNzVBXFx1QTdBNlxcdUE3ODJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdTJyxcbiAgICBjaGFyczogXCJcXHUyNEM4XFx1RkYzM1xcdTFFOUVcXHUwMTVBXFx1MUU2NFxcdTAxNUNcXHUxRTYwXFx1MDE2MFxcdTFFNjZcXHUxRTYyXFx1MUU2OFxcdTAyMThcXHUwMTVFXFx1MkM3RVxcdUE3QThcXHVBNzg0XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnVCcsXG4gICAgY2hhcnM6IFwiXFx1MjRDOVxcdUZGMzRcXHUxRTZBXFx1MDE2NFxcdTFFNkNcXHUwMjFBXFx1MDE2MlxcdTFFNzBcXHUxRTZFXFx1MDE2NlxcdTAxQUNcXHUwMUFFXFx1MDIzRVxcdUE3ODZcIixcbiAgfSwge1xuICAgIGJhc2U6ICdUaCcsXG4gICAgY2hhcnM6IFwiXFx1MDBERVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1RaJyxcbiAgICBjaGFyczogXCJcXHVBNzI4XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnVScsXG4gICAgY2hhcnM6IFwiXFx1MjRDQVxcdUZGMzVcXHhEOVxceERBXFx4REJcXHUwMTY4XFx1MUU3OFxcdTAxNkFcXHUxRTdBXFx1MDE2Q1xceERDXFx1MDFEQlxcdTAxRDdcXHUwMUQ1XFx1MDFEOVxcdTFFRTZcXHUwMTZFXFx1MDE3MFxcdTAxRDNcXHUwMjE0XFx1MDIxNlxcdTAxQUZcXHUxRUVBXFx1MUVFOFxcdTFFRUVcXHUxRUVDXFx1MUVGMFxcdTFFRTRcXHUxRTcyXFx1MDE3MlxcdTFFNzZcXHUxRTc0XFx1MDI0NFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1YnLFxuICAgIGNoYXJzOiBcIlxcdTI0Q0JcXHVGRjM2XFx1MUU3Q1xcdTFFN0VcXHUwMUIyXFx1QTc1RVxcdTAyNDVcIixcbiAgfSwge1xuICAgIGJhc2U6ICdWWScsXG4gICAgY2hhcnM6IFwiXFx1QTc2MFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1cnLFxuICAgIGNoYXJzOiBcIlxcdTI0Q0NcXHVGRjM3XFx1MUU4MFxcdTFFODJcXHUwMTc0XFx1MUU4NlxcdTFFODRcXHUxRTg4XFx1MkM3MlwiLFxuICB9LCB7XG4gICAgYmFzZTogJ1gnLFxuICAgIGNoYXJzOiBcIlxcdTI0Q0RcXHVGRjM4XFx1MUU4QVxcdTFFOENcIixcbiAgfSwge1xuICAgIGJhc2U6ICdZJyxcbiAgICBjaGFyczogXCJcXHUyNENFXFx1RkYzOVxcdTFFRjJcXHhERFxcdTAxNzZcXHUxRUY4XFx1MDIzMlxcdTFFOEVcXHUwMTc4XFx1MUVGNlxcdTFFRjRcXHUwMUIzXFx1MDI0RVxcdTFFRkVcIixcbiAgfSwge1xuICAgIGJhc2U6ICdaJyxcbiAgICBjaGFyczogXCJcXHUyNENGXFx1RkYzQVxcdTAxNzlcXHUxRTkwXFx1MDE3QlxcdTAxN0RcXHUxRTkyXFx1MUU5NFxcdTAxQjVcXHUwMjI0XFx1MkM3RlxcdTJDNkJcXHVBNzYyXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnYScsXG4gICAgY2hhcnM6IFwiXFx1MjREMFxcdUZGNDFcXHUxRTlBXFx1MDBFMFxcdTAwRTFcXHUwMEUyXFx1MUVBN1xcdTFFQTVcXHUxRUFCXFx1MUVBOVxcdTAwRTNcXHUwMTAxXFx1MDEwM1xcdTFFQjFcXHUxRUFGXFx1MUVCNVxcdTFFQjNcXHUwMjI3XFx1MDFFMVxcdTAwRTRcXHUwMURGXFx1MUVBM1xcdTAwRTVcXHUwMUZCXFx1MDFDRVxcdTAyMDFcXHUwMjAzXFx1MUVBMVxcdTFFQURcXHUxRUI3XFx1MUUwMVxcdTAxMDVcXHUyQzY1XFx1MDI1MFxcdTAyNTFcIixcbiAgfSwge1xuICAgIGJhc2U6ICdhYScsXG4gICAgY2hhcnM6IFwiXFx1QTczM1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ2FlJyxcbiAgICBjaGFyczogXCJcXHUwMEU2XFx1MDFGRFxcdTAxRTNcIixcbiAgfSwge1xuICAgIGJhc2U6ICdhbycsXG4gICAgY2hhcnM6IFwiXFx1QTczNVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2F1JyxcbiAgICBjaGFyczogXCJcXHVBNzM3XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnYXYnLFxuICAgIGNoYXJzOiBcIlxcdUE3MzlcXHVBNzNCXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnYXknLFxuICAgIGNoYXJzOiBcIlxcdUE3M0RcIixcbiAgfSwge1xuICAgIGJhc2U6ICdiJyxcbiAgICBjaGFyczogXCJcXHUyNEQxXFx1RkY0MlxcdTFFMDNcXHUxRTA1XFx1MUUwN1xcdTAxODBcXHUwMTgzXFx1MDI1M1xcdTAxODJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdjJyxcbiAgICBjaGFyczogXCJcXHVGRjQzXFx1MjREMlxcdTAxMDdcXHUwMTA5XFx1MDEwQlxcdTAxMERcXHUwMEU3XFx1MUUwOVxcdTAxODhcXHUwMjNDXFx1QTczRlxcdTIxODRcIixcbiAgfSwge1xuICAgIGJhc2U6ICdkJyxcbiAgICBjaGFyczogXCJcXHUyNEQzXFx1RkY0NFxcdTFFMEJcXHUwMTBGXFx1MUUwRFxcdTFFMTFcXHUxRTEzXFx1MUUwRlxcdTAxMTFcXHUwMThDXFx1MDI1NlxcdTAyNTdcXHUwMThCXFx1MTNFN1xcdTA1MDFcXHVBN0FBXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnZGgnLFxuICAgIGNoYXJzOiBcIlxcdTAwRjBcIixcbiAgfSwge1xuICAgIGJhc2U6ICdkeicsXG4gICAgY2hhcnM6IFwiXFx1MDFGM1xcdTAxQzZcIixcbiAgfSwge1xuICAgIGJhc2U6ICdlJyxcbiAgICBjaGFyczogXCJcXHUyNEQ0XFx1RkY0NVxcdTAwRThcXHUwMEU5XFx1MDBFQVxcdTFFQzFcXHUxRUJGXFx1MUVDNVxcdTFFQzNcXHUxRUJEXFx1MDExM1xcdTFFMTVcXHUxRTE3XFx1MDExNVxcdTAxMTdcXHUwMEVCXFx1MUVCQlxcdTAxMUJcXHUwMjA1XFx1MDIwN1xcdTFFQjlcXHUxRUM3XFx1MDIyOVxcdTFFMURcXHUwMTE5XFx1MUUxOVxcdTFFMUJcXHUwMjQ3XFx1MDFERFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2YnLFxuICAgIGNoYXJzOiBcIlxcdTI0RDVcXHVGRjQ2XFx1MUUxRlxcdTAxOTJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdmZicsXG4gICAgY2hhcnM6IFwiXFx1RkIwMFwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2ZpJyxcbiAgICBjaGFyczogXCJcXHVGQjAxXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnZmwnLFxuICAgIGNoYXJzOiBcIlxcdUZCMDJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdmZmknLFxuICAgIGNoYXJzOiBcIlxcdUZCMDNcIixcbiAgfSwge1xuICAgIGJhc2U6ICdmZmwnLFxuICAgIGNoYXJzOiBcIlxcdUZCMDRcIixcbiAgfSwge1xuICAgIGJhc2U6ICdnJyxcbiAgICBjaGFyczogXCJcXHUyNEQ2XFx1RkY0N1xcdTAxRjVcXHUwMTFEXFx1MUUyMVxcdTAxMUZcXHUwMTIxXFx1MDFFN1xcdTAxMjNcXHUwMUU1XFx1MDI2MFxcdUE3QTFcXHVBNzdGXFx1MUQ3OVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2gnLFxuICAgIGNoYXJzOiBcIlxcdTI0RDdcXHVGRjQ4XFx1MDEyNVxcdTFFMjNcXHUxRTI3XFx1MDIxRlxcdTFFMjVcXHUxRTI5XFx1MUUyQlxcdTFFOTZcXHUwMTI3XFx1MkM2OFxcdTJDNzZcXHUwMjY1XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnaHYnLFxuICAgIGNoYXJzOiBcIlxcdTAxOTVcIixcbiAgfSwge1xuICAgIGJhc2U6ICdpJyxcbiAgICBjaGFyczogXCJcXHUyNEQ4XFx1RkY0OVxceEVDXFx4RURcXHhFRVxcdTAxMjlcXHUwMTJCXFx1MDEyRFxceEVGXFx1MUUyRlxcdTFFQzlcXHUwMUQwXFx1MDIwOVxcdTAyMEJcXHUxRUNCXFx1MDEyRlxcdTFFMkRcXHUwMjY4XFx1MDEzMVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ2onLFxuICAgIGNoYXJzOiBcIlxcdTI0RDlcXHVGRjRBXFx1MDEzNVxcdTAxRjBcXHUwMjQ5XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnaycsXG4gICAgY2hhcnM6IFwiXFx1MjREQVxcdUZGNEJcXHUxRTMxXFx1MDFFOVxcdTFFMzNcXHUwMTM3XFx1MUUzNVxcdTAxOTlcXHUyQzZBXFx1QTc0MVxcdUE3NDNcXHVBNzQ1XFx1QTdBM1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ2wnLFxuICAgIGNoYXJzOiBcIlxcdTI0REJcXHVGRjRDXFx1MDE0MFxcdTAxM0FcXHUwMTNFXFx1MUUzN1xcdTFFMzlcXHUwMTNDXFx1MUUzRFxcdTFFM0JcXHUwMTdGXFx1MDE0MlxcdTAxOUFcXHUwMjZCXFx1MkM2MVxcdUE3NDlcXHVBNzgxXFx1QTc0N1xcdTAyNkRcIixcbiAgfSwge1xuICAgIGJhc2U6ICdsaicsXG4gICAgY2hhcnM6IFwiXFx1MDFDOVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ20nLFxuICAgIGNoYXJzOiBcIlxcdTI0RENcXHVGRjREXFx1MUUzRlxcdTFFNDFcXHUxRTQzXFx1MDI3MVxcdTAyNkZcIixcbiAgfSwge1xuICAgIGJhc2U6ICduJyxcbiAgICBjaGFyczogXCJcXHUyNEREXFx1RkY0RVxcdTAxRjlcXHUwMTQ0XFx4RjFcXHUxRTQ1XFx1MDE0OFxcdTFFNDdcXHUwMTQ2XFx1MUU0QlxcdTFFNDlcXHUwMTlFXFx1MDI3MlxcdTAxNDlcXHVBNzkxXFx1QTdBNVxcdTA0M0JcXHUwNTA5XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnbmonLFxuICAgIGNoYXJzOiBcIlxcdTAxQ0NcIixcbiAgfSwge1xuICAgIGJhc2U6ICdvJyxcbiAgICBjaGFyczogXCJcXHUyNERFXFx1RkY0RlxceEYyXFx4RjNcXHhGNFxcdTFFRDNcXHUxRUQxXFx1MUVEN1xcdTFFRDVcXHhGNVxcdTFFNERcXHUwMjJEXFx1MUU0RlxcdTAxNERcXHUxRTUxXFx1MUU1M1xcdTAxNEZcXHUwMjJGXFx1MDIzMVxceEY2XFx1MDIyQlxcdTFFQ0ZcXHUwMTUxXFx1MDFEMlxcdTAyMERcXHUwMjBGXFx1MDFBMVxcdTFFRERcXHUxRURCXFx1MUVFMVxcdTFFREZcXHUxRUUzXFx1MUVDRFxcdTFFRDlcXHUwMUVCXFx1MDFFRFxceEY4XFx1MDFGRlxcdUE3NEJcXHVBNzREXFx1MDI3NVxcdTAyNTRcXHUxRDExXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnb2UnLFxuICAgIGNoYXJzOiBcIlxcdTAxNTNcIixcbiAgfSwge1xuICAgIGJhc2U6ICdvaScsXG4gICAgY2hhcnM6IFwiXFx1MDFBM1wiLFxuICB9LCB7XG4gICAgYmFzZTogJ29vJyxcbiAgICBjaGFyczogXCJcXHVBNzRGXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAnb3UnLFxuICAgIGNoYXJzOiBcIlxcdTAyMjNcIixcbiAgfSwge1xuICAgIGJhc2U6ICdwJyxcbiAgICBjaGFyczogXCJcXHUyNERGXFx1RkY1MFxcdTFFNTVcXHUxRTU3XFx1MDFBNVxcdTFEN0RcXHVBNzUxXFx1QTc1M1xcdUE3NTVcXHUwM0MxXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAncScsXG4gICAgY2hhcnM6IFwiXFx1MjRFMFxcdUZGNTFcXHUwMjRCXFx1QTc1N1xcdUE3NTlcIixcbiAgfSwge1xuICAgIGJhc2U6ICdyJyxcbiAgICBjaGFyczogXCJcXHUyNEUxXFx1RkY1MlxcdTAxNTVcXHUxRTU5XFx1MDE1OVxcdTAyMTFcXHUwMjEzXFx1MUU1QlxcdTFFNURcXHUwMTU3XFx1MUU1RlxcdTAyNERcXHUwMjdEXFx1QTc1QlxcdUE3QTdcXHVBNzgzXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAncycsXG4gICAgY2hhcnM6IFwiXFx1MjRFMlxcdUZGNTNcXHUwMTVCXFx1MUU2NVxcdTAxNURcXHUxRTYxXFx1MDE2MVxcdTFFNjdcXHUxRTYzXFx1MUU2OVxcdTAyMTlcXHUwMTVGXFx1MDIzRlxcdUE3QTlcXHVBNzg1XFx1MUU5QlxcdTAyODJcIixcbiAgfSwge1xuICAgIGJhc2U6ICdzcycsXG4gICAgY2hhcnM6IFwiXFx4REZcIixcbiAgfSwge1xuICAgIGJhc2U6ICd0JyxcbiAgICBjaGFyczogXCJcXHUyNEUzXFx1RkY1NFxcdTFFNkJcXHUxRTk3XFx1MDE2NVxcdTFFNkRcXHUwMjFCXFx1MDE2M1xcdTFFNzFcXHUxRTZGXFx1MDE2N1xcdTAxQURcXHUwMjg4XFx1MkM2NlxcdUE3ODdcIixcbiAgfSwge1xuICAgIGJhc2U6ICd0aCcsXG4gICAgY2hhcnM6IFwiXFx1MDBGRVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ3R6JyxcbiAgICBjaGFyczogXCJcXHVBNzI5XCIsXG4gIH0sIHtcbiAgICBiYXNlOiAndScsXG4gICAgY2hhcnM6IFwiXFx1MjRFNFxcdUZGNTVcXHhGOVxceEZBXFx4RkJcXHUwMTY5XFx1MUU3OVxcdTAxNkJcXHUxRTdCXFx1MDE2RFxceEZDXFx1MDFEQ1xcdTAxRDhcXHUwMUQ2XFx1MDFEQVxcdTFFRTdcXHUwMTZGXFx1MDE3MVxcdTAxRDRcXHUwMjE1XFx1MDIxN1xcdTAxQjBcXHUxRUVCXFx1MUVFOVxcdTFFRUZcXHUxRUVEXFx1MUVGMVxcdTFFRTVcXHUxRTczXFx1MDE3M1xcdTFFNzdcXHUxRTc1XFx1MDI4OVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ3YnLFxuICAgIGNoYXJzOiBcIlxcdTI0RTVcXHVGRjU2XFx1MUU3RFxcdTFFN0ZcXHUwMjhCXFx1QTc1RlxcdTAyOENcIixcbiAgfSwge1xuICAgIGJhc2U6ICd2eScsXG4gICAgY2hhcnM6IFwiXFx1QTc2MVwiLFxuICB9LCB7XG4gICAgYmFzZTogJ3cnLFxuICAgIGNoYXJzOiBcIlxcdTI0RTZcXHVGRjU3XFx1MUU4MVxcdTFFODNcXHUwMTc1XFx1MUU4N1xcdTFFODVcXHUxRTk4XFx1MUU4OVxcdTJDNzNcIixcbiAgfSwge1xuICAgIGJhc2U6ICd4JyxcbiAgICBjaGFyczogXCJcXHUyNEU3XFx1RkY1OFxcdTFFOEJcXHUxRThEXCIsXG4gIH0sIHtcbiAgICBiYXNlOiAneScsXG4gICAgY2hhcnM6IFwiXFx1MjRFOFxcdUZGNTlcXHUxRUYzXFx4RkRcXHUwMTc3XFx1MUVGOVxcdTAyMzNcXHUxRThGXFx4RkZcXHUxRUY3XFx1MUU5OVxcdTFFRjVcXHUwMUI0XFx1MDI0RlxcdTFFRkZcIixcbiAgfSwge1xuICAgIGJhc2U6ICd6JyxcbiAgICBjaGFyczogXCJcXHUyNEU5XFx1RkY1QVxcdTAxN0FcXHUxRTkxXFx1MDE3Q1xcdTAxN0VcXHUxRTkzXFx1MUU5NVxcdTAxQjZcXHUwMjI1XFx1MDI0MFxcdTJDNkNcXHVBNzYzXCIsXG4gIH1cbl07XG5cbnZhciBkaWFjcml0aWNzTWFwID0ge307XG5mb3IgKHZhciBpID0gMDsgaSA8IHJlcGxhY2VtZW50TGlzdC5sZW5ndGg7IGkgKz0gMSkge1xuICB2YXIgY2hhcnMgPSByZXBsYWNlbWVudExpc3RbaV0uY2hhcnM7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgY2hhcnMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICBkaWFjcml0aWNzTWFwW2NoYXJzW2pdXSA9IHJlcGxhY2VtZW50TGlzdFtpXS5iYXNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZURpYWNyaXRpY3Moc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvW15cXHUwMDAwLVxcdTAwN2VdL2csIGZ1bmN0aW9uKGMpIHtcbiAgICByZXR1cm4gZGlhY3JpdGljc01hcFtjXSB8fCBjO1xuICB9KTtcbn1cbiIsIiFmdW5jdGlvbihlKXtpZihcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZSltb2R1bGUuZXhwb3J0cz1lKCk7ZWxzZSBpZihcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQpZGVmaW5lKFtdLGUpO2Vsc2V7dmFyIHQ7dD1cInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93P3dpbmRvdzpcInVuZGVmaW5lZFwiIT10eXBlb2YgZ2xvYmFsP2dsb2JhbDpcInVuZGVmaW5lZFwiIT10eXBlb2Ygc2VsZj9zZWxmOnRoaXMsdC5mbGV4aWJpbGl0eT1lKCl9fShmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbiBlKHQscixsKXtmdW5jdGlvbiBuKGYsaSl7aWYoIXJbZl0pe2lmKCF0W2ZdKXt2YXIgcz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFpJiZzKXJldHVybiBzKGYsITApO2lmKG8pcmV0dXJuIG8oZiwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitmK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgYz1yW2ZdPXtleHBvcnRzOnt9fTt0W2ZdWzBdLmNhbGwoYy5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciByPXRbZl1bMV1bZV07cmV0dXJuIG4ocj9yOmUpfSxjLGMuZXhwb3J0cyxlLHQscixsKX1yZXR1cm4gcltmXS5leHBvcnRzfWZvcih2YXIgbz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGY9MDtmPGwubGVuZ3RoO2YrKyluKGxbZl0pO3JldHVybiBufSh7MTpbZnVuY3Rpb24oZSx0LHIpe3QuZXhwb3J0cz1mdW5jdGlvbihlKXt2YXIgdCxyLGwsbj0tMTtpZihlLmxpbmVzLmxlbmd0aD4xJiZcImZsZXgtc3RhcnRcIj09PWUuc3R5bGUuYWxpZ25Db250ZW50KWZvcih0PTA7bD1lLmxpbmVzWysrbl07KWwuY3Jvc3NTdGFydD10LHQrPWwuY3Jvc3M7ZWxzZSBpZihlLmxpbmVzLmxlbmd0aD4xJiZcImZsZXgtZW5kXCI9PT1lLnN0eWxlLmFsaWduQ29udGVudClmb3IodD1lLmZsZXhTdHlsZS5jcm9zc1NwYWNlO2w9ZS5saW5lc1srK25dOylsLmNyb3NzU3RhcnQ9dCx0Kz1sLmNyb3NzO2Vsc2UgaWYoZS5saW5lcy5sZW5ndGg+MSYmXCJjZW50ZXJcIj09PWUuc3R5bGUuYWxpZ25Db250ZW50KWZvcih0PWUuZmxleFN0eWxlLmNyb3NzU3BhY2UvMjtsPWUubGluZXNbKytuXTspbC5jcm9zc1N0YXJ0PXQsdCs9bC5jcm9zcztlbHNlIGlmKGUubGluZXMubGVuZ3RoPjEmJlwic3BhY2UtYmV0d2VlblwiPT09ZS5zdHlsZS5hbGlnbkNvbnRlbnQpZm9yKHI9ZS5mbGV4U3R5bGUuY3Jvc3NTcGFjZS8oZS5saW5lcy5sZW5ndGgtMSksdD0wO2w9ZS5saW5lc1srK25dOylsLmNyb3NzU3RhcnQ9dCx0Kz1sLmNyb3NzK3I7ZWxzZSBpZihlLmxpbmVzLmxlbmd0aD4xJiZcInNwYWNlLWFyb3VuZFwiPT09ZS5zdHlsZS5hbGlnbkNvbnRlbnQpZm9yKHI9MiplLmZsZXhTdHlsZS5jcm9zc1NwYWNlLygyKmUubGluZXMubGVuZ3RoKSx0PXIvMjtsPWUubGluZXNbKytuXTspbC5jcm9zc1N0YXJ0PXQsdCs9bC5jcm9zcytyO2Vsc2UgZm9yKHI9ZS5mbGV4U3R5bGUuY3Jvc3NTcGFjZS9lLmxpbmVzLmxlbmd0aCx0PWUuZmxleFN0eWxlLmNyb3NzSW5uZXJCZWZvcmU7bD1lLmxpbmVzWysrbl07KWwuY3Jvc3NTdGFydD10LGwuY3Jvc3MrPXIsdCs9bC5jcm9zc319LHt9XSwyOltmdW5jdGlvbihlLHQscil7dC5leHBvcnRzPWZ1bmN0aW9uKGUpe2Zvcih2YXIgdCxyPS0xO2xpbmU9ZS5saW5lc1srK3JdOylmb3IodD0tMTtjaGlsZD1saW5lLmNoaWxkcmVuWysrdF07KXt2YXIgbD1jaGlsZC5zdHlsZS5hbGlnblNlbGY7XCJhdXRvXCI9PT1sJiYobD1lLnN0eWxlLmFsaWduSXRlbXMpLFwiZmxleC1zdGFydFwiPT09bD9jaGlsZC5mbGV4U3R5bGUuY3Jvc3NTdGFydD1saW5lLmNyb3NzU3RhcnQ6XCJmbGV4LWVuZFwiPT09bD9jaGlsZC5mbGV4U3R5bGUuY3Jvc3NTdGFydD1saW5lLmNyb3NzU3RhcnQrbGluZS5jcm9zcy1jaGlsZC5mbGV4U3R5bGUuY3Jvc3NPdXRlcjpcImNlbnRlclwiPT09bD9jaGlsZC5mbGV4U3R5bGUuY3Jvc3NTdGFydD1saW5lLmNyb3NzU3RhcnQrKGxpbmUuY3Jvc3MtY2hpbGQuZmxleFN0eWxlLmNyb3NzT3V0ZXIpLzI6KGNoaWxkLmZsZXhTdHlsZS5jcm9zc1N0YXJ0PWxpbmUuY3Jvc3NTdGFydCxjaGlsZC5mbGV4U3R5bGUuY3Jvc3NPdXRlcj1saW5lLmNyb3NzLGNoaWxkLmZsZXhTdHlsZS5jcm9zcz1jaGlsZC5mbGV4U3R5bGUuY3Jvc3NPdXRlci1jaGlsZC5mbGV4U3R5bGUuY3Jvc3NCZWZvcmUtY2hpbGQuZmxleFN0eWxlLmNyb3NzQWZ0ZXIpfX19LHt9XSwzOltmdW5jdGlvbihlLHQscil7dC5leHBvcnRzPWZ1bmN0aW9uIGwoZSxsKXt2YXIgdD1cInJvd1wiPT09bHx8XCJyb3ctcmV2ZXJzZVwiPT09bCxyPWUubWFpbkF4aXM7aWYocil7dmFyIG49dCYmXCJpbmxpbmVcIj09PXJ8fCF0JiZcImJsb2NrXCI9PT1yO258fChlLmZsZXhTdHlsZT17bWFpbjplLmZsZXhTdHlsZS5jcm9zcyxjcm9zczplLmZsZXhTdHlsZS5tYWluLG1haW5PZmZzZXQ6ZS5mbGV4U3R5bGUuY3Jvc3NPZmZzZXQsY3Jvc3NPZmZzZXQ6ZS5mbGV4U3R5bGUubWFpbk9mZnNldCxtYWluQmVmb3JlOmUuZmxleFN0eWxlLmNyb3NzQmVmb3JlLG1haW5BZnRlcjplLmZsZXhTdHlsZS5jcm9zc0FmdGVyLGNyb3NzQmVmb3JlOmUuZmxleFN0eWxlLm1haW5CZWZvcmUsY3Jvc3NBZnRlcjplLmZsZXhTdHlsZS5tYWluQWZ0ZXIsbWFpbklubmVyQmVmb3JlOmUuZmxleFN0eWxlLmNyb3NzSW5uZXJCZWZvcmUsbWFpbklubmVyQWZ0ZXI6ZS5mbGV4U3R5bGUuY3Jvc3NJbm5lckFmdGVyLGNyb3NzSW5uZXJCZWZvcmU6ZS5mbGV4U3R5bGUubWFpbklubmVyQmVmb3JlLGNyb3NzSW5uZXJBZnRlcjplLmZsZXhTdHlsZS5tYWluSW5uZXJBZnRlcixtYWluQm9yZGVyQmVmb3JlOmUuZmxleFN0eWxlLmNyb3NzQm9yZGVyQmVmb3JlLG1haW5Cb3JkZXJBZnRlcjplLmZsZXhTdHlsZS5jcm9zc0JvcmRlckFmdGVyLGNyb3NzQm9yZGVyQmVmb3JlOmUuZmxleFN0eWxlLm1haW5Cb3JkZXJCZWZvcmUsY3Jvc3NCb3JkZXJBZnRlcjplLmZsZXhTdHlsZS5tYWluQm9yZGVyQWZ0ZXJ9KX1lbHNlIHQ/ZS5mbGV4U3R5bGU9e21haW46ZS5zdHlsZS53aWR0aCxjcm9zczplLnN0eWxlLmhlaWdodCxtYWluT2Zmc2V0OmUuc3R5bGUub2Zmc2V0V2lkdGgsY3Jvc3NPZmZzZXQ6ZS5zdHlsZS5vZmZzZXRIZWlnaHQsbWFpbkJlZm9yZTplLnN0eWxlLm1hcmdpbkxlZnQsbWFpbkFmdGVyOmUuc3R5bGUubWFyZ2luUmlnaHQsY3Jvc3NCZWZvcmU6ZS5zdHlsZS5tYXJnaW5Ub3AsY3Jvc3NBZnRlcjplLnN0eWxlLm1hcmdpbkJvdHRvbSxtYWluSW5uZXJCZWZvcmU6ZS5zdHlsZS5wYWRkaW5nTGVmdCxtYWluSW5uZXJBZnRlcjplLnN0eWxlLnBhZGRpbmdSaWdodCxjcm9zc0lubmVyQmVmb3JlOmUuc3R5bGUucGFkZGluZ1RvcCxjcm9zc0lubmVyQWZ0ZXI6ZS5zdHlsZS5wYWRkaW5nQm90dG9tLG1haW5Cb3JkZXJCZWZvcmU6ZS5zdHlsZS5ib3JkZXJMZWZ0V2lkdGgsbWFpbkJvcmRlckFmdGVyOmUuc3R5bGUuYm9yZGVyUmlnaHRXaWR0aCxjcm9zc0JvcmRlckJlZm9yZTplLnN0eWxlLmJvcmRlclRvcFdpZHRoLGNyb3NzQm9yZGVyQWZ0ZXI6ZS5zdHlsZS5ib3JkZXJCb3R0b21XaWR0aH06ZS5mbGV4U3R5bGU9e21haW46ZS5zdHlsZS5oZWlnaHQsY3Jvc3M6ZS5zdHlsZS53aWR0aCxtYWluT2Zmc2V0OmUuc3R5bGUub2Zmc2V0SGVpZ2h0LGNyb3NzT2Zmc2V0OmUuc3R5bGUub2Zmc2V0V2lkdGgsbWFpbkJlZm9yZTplLnN0eWxlLm1hcmdpblRvcCxtYWluQWZ0ZXI6ZS5zdHlsZS5tYXJnaW5Cb3R0b20sY3Jvc3NCZWZvcmU6ZS5zdHlsZS5tYXJnaW5MZWZ0LGNyb3NzQWZ0ZXI6ZS5zdHlsZS5tYXJnaW5SaWdodCxtYWluSW5uZXJCZWZvcmU6ZS5zdHlsZS5wYWRkaW5nVG9wLG1haW5Jbm5lckFmdGVyOmUuc3R5bGUucGFkZGluZ0JvdHRvbSxjcm9zc0lubmVyQmVmb3JlOmUuc3R5bGUucGFkZGluZ0xlZnQsY3Jvc3NJbm5lckFmdGVyOmUuc3R5bGUucGFkZGluZ1JpZ2h0LG1haW5Cb3JkZXJCZWZvcmU6ZS5zdHlsZS5ib3JkZXJUb3BXaWR0aCxtYWluQm9yZGVyQWZ0ZXI6ZS5zdHlsZS5ib3JkZXJCb3R0b21XaWR0aCxjcm9zc0JvcmRlckJlZm9yZTplLnN0eWxlLmJvcmRlckxlZnRXaWR0aCxjcm9zc0JvcmRlckFmdGVyOmUuc3R5bGUuYm9yZGVyUmlnaHRXaWR0aH0sXCJjb250ZW50LWJveFwiPT09ZS5zdHlsZS5ib3hTaXppbmcmJihcIm51bWJlclwiPT10eXBlb2YgZS5mbGV4U3R5bGUubWFpbiYmKGUuZmxleFN0eWxlLm1haW4rPWUuZmxleFN0eWxlLm1haW5Jbm5lckJlZm9yZStlLmZsZXhTdHlsZS5tYWluSW5uZXJBZnRlcitlLmZsZXhTdHlsZS5tYWluQm9yZGVyQmVmb3JlK2UuZmxleFN0eWxlLm1haW5Cb3JkZXJBZnRlciksXCJudW1iZXJcIj09dHlwZW9mIGUuZmxleFN0eWxlLmNyb3NzJiYoZS5mbGV4U3R5bGUuY3Jvc3MrPWUuZmxleFN0eWxlLmNyb3NzSW5uZXJCZWZvcmUrZS5mbGV4U3R5bGUuY3Jvc3NJbm5lckFmdGVyK2UuZmxleFN0eWxlLmNyb3NzQm9yZGVyQmVmb3JlK2UuZmxleFN0eWxlLmNyb3NzQm9yZGVyQWZ0ZXIpKTtlLm1haW5BeGlzPXQ/XCJpbmxpbmVcIjpcImJsb2NrXCIsZS5jcm9zc0F4aXM9dD9cImJsb2NrXCI6XCJpbmxpbmVcIixcIm51bWJlclwiPT10eXBlb2YgZS5zdHlsZS5mbGV4QmFzaXMmJihlLmZsZXhTdHlsZS5tYWluPWUuc3R5bGUuZmxleEJhc2lzK2UuZmxleFN0eWxlLm1haW5Jbm5lckJlZm9yZStlLmZsZXhTdHlsZS5tYWluSW5uZXJBZnRlcitlLmZsZXhTdHlsZS5tYWluQm9yZGVyQmVmb3JlK2UuZmxleFN0eWxlLm1haW5Cb3JkZXJBZnRlciksZS5mbGV4U3R5bGUubWFpbk91dGVyPWUuZmxleFN0eWxlLm1haW4sZS5mbGV4U3R5bGUuY3Jvc3NPdXRlcj1lLmZsZXhTdHlsZS5jcm9zcyxcImF1dG9cIj09PWUuZmxleFN0eWxlLm1haW5PdXRlciYmKGUuZmxleFN0eWxlLm1haW5PdXRlcj1lLmZsZXhTdHlsZS5tYWluT2Zmc2V0KSxcImF1dG9cIj09PWUuZmxleFN0eWxlLmNyb3NzT3V0ZXImJihlLmZsZXhTdHlsZS5jcm9zc091dGVyPWUuZmxleFN0eWxlLmNyb3NzT2Zmc2V0KSxcIm51bWJlclwiPT10eXBlb2YgZS5mbGV4U3R5bGUubWFpbkJlZm9yZSYmKGUuZmxleFN0eWxlLm1haW5PdXRlcis9ZS5mbGV4U3R5bGUubWFpbkJlZm9yZSksXCJudW1iZXJcIj09dHlwZW9mIGUuZmxleFN0eWxlLm1haW5BZnRlciYmKGUuZmxleFN0eWxlLm1haW5PdXRlcis9ZS5mbGV4U3R5bGUubWFpbkFmdGVyKSxcIm51bWJlclwiPT10eXBlb2YgZS5mbGV4U3R5bGUuY3Jvc3NCZWZvcmUmJihlLmZsZXhTdHlsZS5jcm9zc091dGVyKz1lLmZsZXhTdHlsZS5jcm9zc0JlZm9yZSksXCJudW1iZXJcIj09dHlwZW9mIGUuZmxleFN0eWxlLmNyb3NzQWZ0ZXImJihlLmZsZXhTdHlsZS5jcm9zc091dGVyKz1lLmZsZXhTdHlsZS5jcm9zc0FmdGVyKX19LHt9XSw0OltmdW5jdGlvbihlLHQscil7dmFyIGw9ZShcIi4uL3JlZHVjZVwiKTt0LmV4cG9ydHM9ZnVuY3Rpb24oZSl7aWYoZS5tYWluU3BhY2U+MCl7dmFyIHQ9bChlLmNoaWxkcmVuLGZ1bmN0aW9uKGUsdCl7cmV0dXJuIGUrcGFyc2VGbG9hdCh0LnN0eWxlLmZsZXhHcm93KX0sMCk7dD4wJiYoZS5tYWluPWwoZS5jaGlsZHJlbixmdW5jdGlvbihyLGwpe3JldHVyblwiYXV0b1wiPT09bC5mbGV4U3R5bGUubWFpbj9sLmZsZXhTdHlsZS5tYWluPWwuZmxleFN0eWxlLm1haW5PZmZzZXQrcGFyc2VGbG9hdChsLnN0eWxlLmZsZXhHcm93KS90KmUubWFpblNwYWNlOmwuZmxleFN0eWxlLm1haW4rPXBhcnNlRmxvYXQobC5zdHlsZS5mbGV4R3JvdykvdCplLm1haW5TcGFjZSxsLmZsZXhTdHlsZS5tYWluT3V0ZXI9bC5mbGV4U3R5bGUubWFpbitsLmZsZXhTdHlsZS5tYWluQmVmb3JlK2wuZmxleFN0eWxlLm1haW5BZnRlcixyK2wuZmxleFN0eWxlLm1haW5PdXRlcn0sMCksZS5tYWluU3BhY2U9MCl9fX0se1wiLi4vcmVkdWNlXCI6MTJ9XSw1OltmdW5jdGlvbihlLHQscil7dmFyIGw9ZShcIi4uL3JlZHVjZVwiKTt0LmV4cG9ydHM9ZnVuY3Rpb24oZSl7aWYoZS5tYWluU3BhY2U8MCl7dmFyIHQ9bChlLmNoaWxkcmVuLGZ1bmN0aW9uKGUsdCl7cmV0dXJuIGUrcGFyc2VGbG9hdCh0LnN0eWxlLmZsZXhTaHJpbmspfSwwKTt0PjAmJihlLm1haW49bChlLmNoaWxkcmVuLGZ1bmN0aW9uKHIsbCl7cmV0dXJuIGwuZmxleFN0eWxlLm1haW4rPXBhcnNlRmxvYXQobC5zdHlsZS5mbGV4U2hyaW5rKS90KmUubWFpblNwYWNlLGwuZmxleFN0eWxlLm1haW5PdXRlcj1sLmZsZXhTdHlsZS5tYWluK2wuZmxleFN0eWxlLm1haW5CZWZvcmUrbC5mbGV4U3R5bGUubWFpbkFmdGVyLHIrbC5mbGV4U3R5bGUubWFpbk91dGVyfSwwKSxlLm1haW5TcGFjZT0wKX19fSx7XCIuLi9yZWR1Y2VcIjoxMn1dLDY6W2Z1bmN0aW9uKGUsdCxyKXt2YXIgbD1lKFwiLi4vcmVkdWNlXCIpO3QuZXhwb3J0cz1mdW5jdGlvbihlKXt2YXIgdDtlLmxpbmVzPVt0PXttYWluOjAsY3Jvc3M6MCxjaGlsZHJlbjpbXX1dO2Zvcih2YXIgcixuPS0xO3I9ZS5jaGlsZHJlblsrK25dOylcIm5vd3JhcFwiPT09ZS5zdHlsZS5mbGV4V3JhcHx8MD09PXQuY2hpbGRyZW4ubGVuZ3RofHxcImF1dG9cIj09PWUuZmxleFN0eWxlLm1haW58fGUuZmxleFN0eWxlLm1haW4tZS5mbGV4U3R5bGUubWFpbklubmVyQmVmb3JlLWUuZmxleFN0eWxlLm1haW5Jbm5lckFmdGVyLWUuZmxleFN0eWxlLm1haW5Cb3JkZXJCZWZvcmUtZS5mbGV4U3R5bGUubWFpbkJvcmRlckFmdGVyPj10Lm1haW4rci5mbGV4U3R5bGUubWFpbk91dGVyPyh0Lm1haW4rPXIuZmxleFN0eWxlLm1haW5PdXRlcix0LmNyb3NzPU1hdGgubWF4KHQuY3Jvc3Msci5mbGV4U3R5bGUuY3Jvc3NPdXRlcikpOmUubGluZXMucHVzaCh0PXttYWluOnIuZmxleFN0eWxlLm1haW5PdXRlcixjcm9zczpyLmZsZXhTdHlsZS5jcm9zc091dGVyLGNoaWxkcmVuOltdfSksdC5jaGlsZHJlbi5wdXNoKHIpO2UuZmxleFN0eWxlLm1haW5MaW5lcz1sKGUubGluZXMsZnVuY3Rpb24oZSx0KXtyZXR1cm4gTWF0aC5tYXgoZSx0Lm1haW4pfSwwKSxlLmZsZXhTdHlsZS5jcm9zc0xpbmVzPWwoZS5saW5lcyxmdW5jdGlvbihlLHQpe3JldHVybiBlK3QuY3Jvc3N9LDApLFwiYXV0b1wiPT09ZS5mbGV4U3R5bGUubWFpbiYmKGUuZmxleFN0eWxlLm1haW49TWF0aC5tYXgoZS5mbGV4U3R5bGUubWFpbk9mZnNldCxlLmZsZXhTdHlsZS5tYWluTGluZXMrZS5mbGV4U3R5bGUubWFpbklubmVyQmVmb3JlK2UuZmxleFN0eWxlLm1haW5Jbm5lckFmdGVyK2UuZmxleFN0eWxlLm1haW5Cb3JkZXJCZWZvcmUrZS5mbGV4U3R5bGUubWFpbkJvcmRlckFmdGVyKSksXCJhdXRvXCI9PT1lLmZsZXhTdHlsZS5jcm9zcyYmKGUuZmxleFN0eWxlLmNyb3NzPU1hdGgubWF4KGUuZmxleFN0eWxlLmNyb3NzT2Zmc2V0LGUuZmxleFN0eWxlLmNyb3NzTGluZXMrZS5mbGV4U3R5bGUuY3Jvc3NJbm5lckJlZm9yZStlLmZsZXhTdHlsZS5jcm9zc0lubmVyQWZ0ZXIrZS5mbGV4U3R5bGUuY3Jvc3NCb3JkZXJCZWZvcmUrZS5mbGV4U3R5bGUuY3Jvc3NCb3JkZXJBZnRlcikpLGUuZmxleFN0eWxlLmNyb3NzU3BhY2U9ZS5mbGV4U3R5bGUuY3Jvc3MtZS5mbGV4U3R5bGUuY3Jvc3NJbm5lckJlZm9yZS1lLmZsZXhTdHlsZS5jcm9zc0lubmVyQWZ0ZXItZS5mbGV4U3R5bGUuY3Jvc3NCb3JkZXJCZWZvcmUtZS5mbGV4U3R5bGUuY3Jvc3NCb3JkZXJBZnRlci1lLmZsZXhTdHlsZS5jcm9zc0xpbmVzLGUuZmxleFN0eWxlLm1haW5PdXRlcj1lLmZsZXhTdHlsZS5tYWluK2UuZmxleFN0eWxlLm1haW5CZWZvcmUrZS5mbGV4U3R5bGUubWFpbkFmdGVyLGUuZmxleFN0eWxlLmNyb3NzT3V0ZXI9ZS5mbGV4U3R5bGUuY3Jvc3MrZS5mbGV4U3R5bGUuY3Jvc3NCZWZvcmUrZS5mbGV4U3R5bGUuY3Jvc3NBZnRlcn19LHtcIi4uL3JlZHVjZVwiOjEyfV0sNzpbZnVuY3Rpb24oZSx0LHIpe2Z1bmN0aW9uIGwodCl7Zm9yKHZhciByLGw9LTE7cj10LmNoaWxkcmVuWysrbF07KWUoXCIuL2ZsZXgtZGlyZWN0aW9uXCIpKHIsdC5zdHlsZS5mbGV4RGlyZWN0aW9uKTtlKFwiLi9mbGV4LWRpcmVjdGlvblwiKSh0LHQuc3R5bGUuZmxleERpcmVjdGlvbiksZShcIi4vb3JkZXJcIikodCksZShcIi4vZmxleGJveC1saW5lc1wiKSh0KSxlKFwiLi9hbGlnbi1jb250ZW50XCIpKHQpLGw9LTE7Zm9yKHZhciBuO249dC5saW5lc1srK2xdOyluLm1haW5TcGFjZT10LmZsZXhTdHlsZS5tYWluLXQuZmxleFN0eWxlLm1haW5Jbm5lckJlZm9yZS10LmZsZXhTdHlsZS5tYWluSW5uZXJBZnRlci10LmZsZXhTdHlsZS5tYWluQm9yZGVyQmVmb3JlLXQuZmxleFN0eWxlLm1haW5Cb3JkZXJBZnRlci1uLm1haW4sZShcIi4vZmxleC1ncm93XCIpKG4pLGUoXCIuL2ZsZXgtc2hyaW5rXCIpKG4pLGUoXCIuL21hcmdpbi1tYWluXCIpKG4pLGUoXCIuL21hcmdpbi1jcm9zc1wiKShuKSxlKFwiLi9qdXN0aWZ5LWNvbnRlbnRcIikobix0LnN0eWxlLmp1c3RpZnlDb250ZW50LHQpO2UoXCIuL2FsaWduLWl0ZW1zXCIpKHQpfXQuZXhwb3J0cz1sfSx7XCIuL2FsaWduLWNvbnRlbnRcIjoxLFwiLi9hbGlnbi1pdGVtc1wiOjIsXCIuL2ZsZXgtZGlyZWN0aW9uXCI6MyxcIi4vZmxleC1ncm93XCI6NCxcIi4vZmxleC1zaHJpbmtcIjo1LFwiLi9mbGV4Ym94LWxpbmVzXCI6NixcIi4vanVzdGlmeS1jb250ZW50XCI6OCxcIi4vbWFyZ2luLWNyb3NzXCI6OSxcIi4vbWFyZ2luLW1haW5cIjoxMCxcIi4vb3JkZXJcIjoxMX1dLDg6W2Z1bmN0aW9uKGUsdCxyKXt0LmV4cG9ydHM9ZnVuY3Rpb24oZSx0LHIpe3ZhciBsLG4sbyxmPXIuZmxleFN0eWxlLm1haW5Jbm5lckJlZm9yZSxpPS0xO2lmKFwiZmxleC1lbmRcIj09PXQpZm9yKGw9ZS5tYWluU3BhY2UsbCs9ZjtvPWUuY2hpbGRyZW5bKytpXTspby5mbGV4U3R5bGUubWFpblN0YXJ0PWwsbCs9by5mbGV4U3R5bGUubWFpbk91dGVyO2Vsc2UgaWYoXCJjZW50ZXJcIj09PXQpZm9yKGw9ZS5tYWluU3BhY2UvMixsKz1mO289ZS5jaGlsZHJlblsrK2ldOylvLmZsZXhTdHlsZS5tYWluU3RhcnQ9bCxsKz1vLmZsZXhTdHlsZS5tYWluT3V0ZXI7ZWxzZSBpZihcInNwYWNlLWJldHdlZW5cIj09PXQpZm9yKG49ZS5tYWluU3BhY2UvKGUuY2hpbGRyZW4ubGVuZ3RoLTEpLGw9MCxsKz1mO289ZS5jaGlsZHJlblsrK2ldOylvLmZsZXhTdHlsZS5tYWluU3RhcnQ9bCxsKz1vLmZsZXhTdHlsZS5tYWluT3V0ZXIrbjtlbHNlIGlmKFwic3BhY2UtYXJvdW5kXCI9PT10KWZvcihuPTIqZS5tYWluU3BhY2UvKDIqZS5jaGlsZHJlbi5sZW5ndGgpLGw9bi8yLGwrPWY7bz1lLmNoaWxkcmVuWysraV07KW8uZmxleFN0eWxlLm1haW5TdGFydD1sLGwrPW8uZmxleFN0eWxlLm1haW5PdXRlcituO2Vsc2UgZm9yKGw9MCxsKz1mO289ZS5jaGlsZHJlblsrK2ldOylvLmZsZXhTdHlsZS5tYWluU3RhcnQ9bCxsKz1vLmZsZXhTdHlsZS5tYWluT3V0ZXJ9fSx7fV0sOTpbZnVuY3Rpb24oZSx0LHIpe3QuZXhwb3J0cz1mdW5jdGlvbihlKXtmb3IodmFyIHQscj0tMTt0PWUuY2hpbGRyZW5bKytyXTspe3ZhciBsPTA7XCJhdXRvXCI9PT10LmZsZXhTdHlsZS5jcm9zc0JlZm9yZSYmKytsLFwiYXV0b1wiPT09dC5mbGV4U3R5bGUuY3Jvc3NBZnRlciYmKytsO3ZhciBuPWUuY3Jvc3MtdC5mbGV4U3R5bGUuY3Jvc3NPdXRlcjtcImF1dG9cIj09PXQuZmxleFN0eWxlLmNyb3NzQmVmb3JlJiYodC5mbGV4U3R5bGUuY3Jvc3NCZWZvcmU9bi9sKSxcImF1dG9cIj09PXQuZmxleFN0eWxlLmNyb3NzQWZ0ZXImJih0LmZsZXhTdHlsZS5jcm9zc0FmdGVyPW4vbCksXCJhdXRvXCI9PT10LmZsZXhTdHlsZS5jcm9zcz90LmZsZXhTdHlsZS5jcm9zc091dGVyPXQuZmxleFN0eWxlLmNyb3NzT2Zmc2V0K3QuZmxleFN0eWxlLmNyb3NzQmVmb3JlK3QuZmxleFN0eWxlLmNyb3NzQWZ0ZXI6dC5mbGV4U3R5bGUuY3Jvc3NPdXRlcj10LmZsZXhTdHlsZS5jcm9zcyt0LmZsZXhTdHlsZS5jcm9zc0JlZm9yZSt0LmZsZXhTdHlsZS5jcm9zc0FmdGVyfX19LHt9XSwxMDpbZnVuY3Rpb24oZSx0LHIpe3QuZXhwb3J0cz1mdW5jdGlvbihlKXtmb3IodmFyIHQscj0wLGw9LTE7dD1lLmNoaWxkcmVuWysrbF07KVwiYXV0b1wiPT09dC5mbGV4U3R5bGUubWFpbkJlZm9yZSYmKytyLFwiYXV0b1wiPT09dC5mbGV4U3R5bGUubWFpbkFmdGVyJiYrK3I7aWYocj4wKXtmb3IobD0tMTt0PWUuY2hpbGRyZW5bKytsXTspXCJhdXRvXCI9PT10LmZsZXhTdHlsZS5tYWluQmVmb3JlJiYodC5mbGV4U3R5bGUubWFpbkJlZm9yZT1lLm1haW5TcGFjZS9yKSxcImF1dG9cIj09PXQuZmxleFN0eWxlLm1haW5BZnRlciYmKHQuZmxleFN0eWxlLm1haW5BZnRlcj1lLm1haW5TcGFjZS9yKSxcImF1dG9cIj09PXQuZmxleFN0eWxlLm1haW4/dC5mbGV4U3R5bGUubWFpbk91dGVyPXQuZmxleFN0eWxlLm1haW5PZmZzZXQrdC5mbGV4U3R5bGUubWFpbkJlZm9yZSt0LmZsZXhTdHlsZS5tYWluQWZ0ZXI6dC5mbGV4U3R5bGUubWFpbk91dGVyPXQuZmxleFN0eWxlLm1haW4rdC5mbGV4U3R5bGUubWFpbkJlZm9yZSt0LmZsZXhTdHlsZS5tYWluQWZ0ZXI7ZS5tYWluU3BhY2U9MH19fSx7fV0sMTE6W2Z1bmN0aW9uKGUsdCxyKXt2YXIgbD0vXihjb2x1bW58cm93KS1yZXZlcnNlJC87dC5leHBvcnRzPWZ1bmN0aW9uKGUpe2UuY2hpbGRyZW4uc29ydChmdW5jdGlvbihlLHQpe3JldHVybiBlLnN0eWxlLm9yZGVyLXQuc3R5bGUub3JkZXJ8fGUuaW5kZXgtdC5pbmRleH0pLGwudGVzdChlLnN0eWxlLmZsZXhEaXJlY3Rpb24pJiZlLmNoaWxkcmVuLnJldmVyc2UoKX19LHt9XSwxMjpbZnVuY3Rpb24oZSx0LHIpe2Z1bmN0aW9uIGwoZSx0LHIpe2Zvcih2YXIgbD1lLmxlbmd0aCxuPS0xOysrbjxsOyluIGluIGUmJihyPXQocixlW25dLG4pKTtyZXR1cm4gcn10LmV4cG9ydHM9bH0se31dLDEzOltmdW5jdGlvbihlLHQscil7ZnVuY3Rpb24gbChlKXtpKGYoZSkpfXZhciBuPWUoXCIuL3JlYWRcIiksbz1lKFwiLi93cml0ZVwiKSxmPWUoXCIuL3JlYWRBbGxcIiksaT1lKFwiLi93cml0ZUFsbFwiKTt0LmV4cG9ydHM9bCx0LmV4cG9ydHMucmVhZD1uLHQuZXhwb3J0cy53cml0ZT1vLHQuZXhwb3J0cy5yZWFkQWxsPWYsdC5leHBvcnRzLndyaXRlQWxsPWl9LHtcIi4vcmVhZFwiOjE1LFwiLi9yZWFkQWxsXCI6MTYsXCIuL3dyaXRlXCI6MTcsXCIuL3dyaXRlQWxsXCI6MTh9XSwxNDpbZnVuY3Rpb24oZSx0LHIpe2Z1bmN0aW9uIGwoZSx0LHIpe3ZhciBsPWVbdF0sZj1TdHJpbmcobCkubWF0Y2gobyk7aWYoIWYpe3ZhciBhPXQubWF0Y2gocyk7aWYoYSl7dmFyIGM9ZVtcImJvcmRlclwiK2FbMV0rXCJTdHlsZVwiXTtyZXR1cm5cIm5vbmVcIj09PWM/MDppW2xdfHwwfXJldHVybiBsfXZhciB5PWZbMV0seD1mWzJdO3JldHVyblwicHhcIj09PXg/MSp5OlwiY21cIj09PXg/LjM5MzcqeSo5NjpcImluXCI9PT14Pzk2Knk6XCJtbVwiPT09eD8uMzkzNyp5Kjk2LzEwOlwicGNcIj09PXg/MTIqeSo5Ni83MjpcInB0XCI9PT14Pzk2KnkvNzI6XCJyZW1cIj09PXg/MTYqeTpuKGwscil9ZnVuY3Rpb24gbihlLHQpe2Yuc3R5bGUuY3NzVGV4dD1cImJvcmRlcjpub25lIWltcG9ydGFudDtjbGlwOnJlY3QoMCAwIDAgMCkhaW1wb3J0YW50O2Rpc3BsYXk6YmxvY2shaW1wb3J0YW50O2ZvbnQtc2l6ZToxZW0haW1wb3J0YW50O2hlaWdodDowIWltcG9ydGFudDttYXJnaW46MCFpbXBvcnRhbnQ7cGFkZGluZzowIWltcG9ydGFudDtwb3NpdGlvbjpyZWxhdGl2ZSFpbXBvcnRhbnQ7d2lkdGg6XCIrZStcIiFpbXBvcnRhbnRcIix0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGYsdC5uZXh0U2libGluZyk7dmFyIHI9Zi5vZmZzZXRXaWR0aDtyZXR1cm4gdC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGYpLHJ9dC5leHBvcnRzPWw7dmFyIG89L14oWy0rXT9cXGQqXFwuP1xcZCspKCV8W2Etel0rKSQvLGY9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSxpPXttZWRpdW06NCxub25lOjAsdGhpY2s6Nix0aGluOjJ9LHM9L15ib3JkZXIoQm90dG9tfExlZnR8UmlnaHR8VG9wKVdpZHRoJC99LHt9XSwxNTpbZnVuY3Rpb24oZSx0LHIpe2Z1bmN0aW9uIGwoZSl7dmFyIHQ9e2FsaWduQ29udGVudDpcInN0cmV0Y2hcIixhbGlnbkl0ZW1zOlwic3RyZXRjaFwiLGFsaWduU2VsZjpcImF1dG9cIixib3JkZXJCb3R0b21TdHlsZTpcIm5vbmVcIixib3JkZXJCb3R0b21XaWR0aDowLGJvcmRlckxlZnRTdHlsZTpcIm5vbmVcIixib3JkZXJMZWZ0V2lkdGg6MCxib3JkZXJSaWdodFN0eWxlOlwibm9uZVwiLGJvcmRlclJpZ2h0V2lkdGg6MCxib3JkZXJUb3BTdHlsZTpcIm5vbmVcIixib3JkZXJUb3BXaWR0aDowLGJveFNpemluZzpcImNvbnRlbnQtYm94XCIsZGlzcGxheTpcImlubGluZVwiLGZsZXhCYXNpczpcImF1dG9cIixmbGV4RGlyZWN0aW9uOlwicm93XCIsZmxleEdyb3c6MCxmbGV4U2hyaW5rOjEsZmxleFdyYXA6XCJub3dyYXBcIixqdXN0aWZ5Q29udGVudDpcImZsZXgtc3RhcnRcIixoZWlnaHQ6XCJhdXRvXCIsbWFyZ2luVG9wOjAsbWFyZ2luUmlnaHQ6MCxtYXJnaW5MZWZ0OjAsbWFyZ2luQm90dG9tOjAscGFkZGluZ1RvcDowLHBhZGRpbmdSaWdodDowLHBhZGRpbmdMZWZ0OjAscGFkZGluZ0JvdHRvbTowLG1heEhlaWdodDpcIm5vbmVcIixtYXhXaWR0aDpcIm5vbmVcIixtaW5IZWlnaHQ6MCxtaW5XaWR0aDowLG9yZGVyOjAscG9zaXRpb246XCJzdGF0aWNcIix3aWR0aDpcImF1dG9cIn0scj1lIGluc3RhbmNlb2YgRWxlbWVudDtpZihyKXt2YXIgbD1lLmhhc0F0dHJpYnV0ZShcImRhdGEtc3R5bGVcIiksaT1sP2UuZ2V0QXR0cmlidXRlKFwiZGF0YS1zdHlsZVwiKTplLmdldEF0dHJpYnV0ZShcInN0eWxlXCIpfHxcIlwiO2x8fGUuc2V0QXR0cmlidXRlKFwiZGF0YS1zdHlsZVwiLGkpO3ZhciBzPXdpbmRvdy5nZXRDb21wdXRlZFN0eWxlJiZnZXRDb21wdXRlZFN0eWxlKGUpfHx7fTtmKHQscyk7dmFyIGM9ZS5jdXJyZW50U3R5bGV8fHt9O24odCxjKSxvKHQsaSk7Zm9yKHZhciB5IGluIHQpdFt5XT1hKHQseSxlKTt2YXIgeD1lLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO3Qub2Zmc2V0SGVpZ2h0PXguaGVpZ2h0fHxlLm9mZnNldEhlaWdodCx0Lm9mZnNldFdpZHRoPXgud2lkdGh8fGUub2Zmc2V0V2lkdGh9dmFyIFM9e2VsZW1lbnQ6ZSxzdHlsZTp0fTtyZXR1cm4gU31mdW5jdGlvbiBuKGUsdCl7Zm9yKHZhciByIGluIGUpe3ZhciBsPXIgaW4gdDtpZihsKWVbcl09dFtyXTtlbHNle3ZhciBuPXIucmVwbGFjZSgvW0EtWl0vZyxcIi0kJlwiKS50b0xvd2VyQ2FzZSgpLG89biBpbiB0O28mJihlW3JdPXRbbl0pfX12YXIgZj1cIi1qcy1kaXNwbGF5XCJpbiB0O2YmJihlLmRpc3BsYXk9dFtcIi1qcy1kaXNwbGF5XCJdKX1mdW5jdGlvbiBvKGUsdCl7Zm9yKHZhciByO3I9aS5leGVjKHQpOyl7dmFyIGw9clsxXS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoLy1bYS16XS9nLGZ1bmN0aW9uKGUpe3JldHVybiBlLnNsaWNlKDEpLnRvVXBwZXJDYXNlKCl9KTtlW2xdPXJbMl19fWZ1bmN0aW9uIGYoZSx0KXtmb3IodmFyIHIgaW4gZSl7dmFyIGw9ciBpbiB0O2wmJiFzLnRlc3QocikmJihlW3JdPXRbcl0pfX10LmV4cG9ydHM9bDt2YXIgaT0vKFteXFxzOjtdKylcXHMqOlxccyooW147XSs/KVxccyooO3wkKS9nLHM9L14oYWxpZ25TZWxmfGhlaWdodHx3aWR0aCkkLyxhPWUoXCIuL2dldENvbXB1dGVkTGVuZ3RoXCIpfSx7XCIuL2dldENvbXB1dGVkTGVuZ3RoXCI6MTR9XSwxNjpbZnVuY3Rpb24oZSx0LHIpe2Z1bmN0aW9uIGwoZSl7dmFyIHQ9W107cmV0dXJuIG4oZSx0KSx0fWZ1bmN0aW9uIG4oZSx0KXtmb3IodmFyIHIsbD1vKGUpLGk9W10scz0tMTtyPWUuY2hpbGROb2Rlc1srK3NdOyl7dmFyIGE9Mz09PXIubm9kZVR5cGUmJiEvXlxccyokLy50ZXN0KHIubm9kZVZhbHVlKTtpZihsJiZhKXt2YXIgYz1yO3I9ZS5pbnNlcnRCZWZvcmUoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImZsZXgtaXRlbVwiKSxjKSxyLmFwcGVuZENoaWxkKGMpfXZhciB5PXIgaW5zdGFuY2VvZiBFbGVtZW50O2lmKHkpe3ZhciB4PW4ocix0KTtpZihsKXt2YXIgUz1yLnN0eWxlO1MuZGlzcGxheT1cImlubGluZS1ibG9ja1wiLFMucG9zaXRpb249XCJhYnNvbHV0ZVwiLHguc3R5bGU9ZihyKS5zdHlsZSxpLnB1c2goeCl9fX12YXIgbT17ZWxlbWVudDplLGNoaWxkcmVuOml9O3JldHVybiBsJiYobS5zdHlsZT1mKGUpLnN0eWxlLHQucHVzaChtKSksbX1mdW5jdGlvbiBvKGUpe3ZhciB0PWUgaW5zdGFuY2VvZiBFbGVtZW50LHI9dCYmZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXN0eWxlXCIpLGw9dCYmZS5jdXJyZW50U3R5bGUmJmUuY3VycmVudFN0eWxlW1wiLWpzLWRpc3BsYXlcIl0sbj1pLnRlc3Qocil8fHMudGVzdChsKTtyZXR1cm4gbn10LmV4cG9ydHM9bDt2YXIgZj1lKFwiLi4vcmVhZFwiKSxpPS8oXnw7KVxccypkaXNwbGF5XFxzKjpcXHMqKGlubGluZS0pP2ZsZXhcXHMqKDt8JCkvaSxzPS9eKGlubGluZS0pP2ZsZXgkL2l9LHtcIi4uL3JlYWRcIjoxNX1dLDE3OltmdW5jdGlvbihlLHQscil7ZnVuY3Rpb24gbChlKXtvKGUpO3ZhciB0PWUuZWxlbWVudC5zdHlsZSxyPVwiaW5saW5lXCI9PT1lLm1haW5BeGlzP1tcIm1haW5cIixcImNyb3NzXCJdOltcImNyb3NzXCIsXCJtYWluXCJdO3QuYm94U2l6aW5nPVwiY29udGVudC1ib3hcIix0LmRpc3BsYXk9XCJibG9ja1wiLHQucG9zaXRpb249XCJyZWxhdGl2ZVwiLHQud2lkdGg9bihlLmZsZXhTdHlsZVtyWzBdXS1lLmZsZXhTdHlsZVtyWzBdK1wiSW5uZXJCZWZvcmVcIl0tZS5mbGV4U3R5bGVbclswXStcIklubmVyQWZ0ZXJcIl0tZS5mbGV4U3R5bGVbclswXStcIkJvcmRlckJlZm9yZVwiXS1lLmZsZXhTdHlsZVtyWzBdK1wiQm9yZGVyQWZ0ZXJcIl0pLHQuaGVpZ2h0PW4oZS5mbGV4U3R5bGVbclsxXV0tZS5mbGV4U3R5bGVbclsxXStcIklubmVyQmVmb3JlXCJdLWUuZmxleFN0eWxlW3JbMV0rXCJJbm5lckFmdGVyXCJdLWUuZmxleFN0eWxlW3JbMV0rXCJCb3JkZXJCZWZvcmVcIl0tZS5mbGV4U3R5bGVbclsxXStcIkJvcmRlckFmdGVyXCJdKTtmb3IodmFyIGwsZj0tMTtsPWUuY2hpbGRyZW5bKytmXTspe3ZhciBpPWwuZWxlbWVudC5zdHlsZSxzPVwiaW5saW5lXCI9PT1sLm1haW5BeGlzP1tcIm1haW5cIixcImNyb3NzXCJdOltcImNyb3NzXCIsXCJtYWluXCJdO2kuYm94U2l6aW5nPVwiY29udGVudC1ib3hcIixpLmRpc3BsYXk9XCJibG9ja1wiLGkucG9zaXRpb249XCJhYnNvbHV0ZVwiLFwiYXV0b1wiIT09bC5mbGV4U3R5bGVbc1swXV0mJihpLndpZHRoPW4obC5mbGV4U3R5bGVbc1swXV0tbC5mbGV4U3R5bGVbc1swXStcIklubmVyQmVmb3JlXCJdLWwuZmxleFN0eWxlW3NbMF0rXCJJbm5lckFmdGVyXCJdLWwuZmxleFN0eWxlW3NbMF0rXCJCb3JkZXJCZWZvcmVcIl0tbC5mbGV4U3R5bGVbc1swXStcIkJvcmRlckFmdGVyXCJdKSksXCJhdXRvXCIhPT1sLmZsZXhTdHlsZVtzWzFdXSYmKGkuaGVpZ2h0PW4obC5mbGV4U3R5bGVbc1sxXV0tbC5mbGV4U3R5bGVbc1sxXStcIklubmVyQmVmb3JlXCJdLWwuZmxleFN0eWxlW3NbMV0rXCJJbm5lckFmdGVyXCJdLWwuZmxleFN0eWxlW3NbMV0rXCJCb3JkZXJCZWZvcmVcIl0tbC5mbGV4U3R5bGVbc1sxXStcIkJvcmRlckFmdGVyXCJdKSksaS50b3A9bihsLmZsZXhTdHlsZVtzWzFdK1wiU3RhcnRcIl0pLGkubGVmdD1uKGwuZmxleFN0eWxlW3NbMF0rXCJTdGFydFwiXSksaS5tYXJnaW5Ub3A9bihsLmZsZXhTdHlsZVtzWzFdK1wiQmVmb3JlXCJdKSxpLm1hcmdpblJpZ2h0PW4obC5mbGV4U3R5bGVbc1swXStcIkFmdGVyXCJdKSxpLm1hcmdpbkJvdHRvbT1uKGwuZmxleFN0eWxlW3NbMV0rXCJBZnRlclwiXSksaS5tYXJnaW5MZWZ0PW4obC5mbGV4U3R5bGVbc1swXStcIkJlZm9yZVwiXSl9fWZ1bmN0aW9uIG4oZSl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIGU/ZTpNYXRoLm1heChlLDApK1wicHhcIn10LmV4cG9ydHM9bDt2YXIgbz1lKFwiLi4vZmxleGJveFwiKX0se1wiLi4vZmxleGJveFwiOjd9XSwxODpbZnVuY3Rpb24oZSx0LHIpe2Z1bmN0aW9uIGwoZSl7Zm9yKHZhciB0LHI9LTE7dD1lWysrcl07KW4odCl9dC5leHBvcnRzPWw7dmFyIG49ZShcIi4uL3dyaXRlXCIpfSx7XCIuLi93cml0ZVwiOjE3fV19LHt9LFsxM10pKDEzKX0pOyIsIi8qXG4gKiBGdXp6eVxuICogaHR0cHM6Ly9naXRodWIuY29tL215b3JrL2Z1enp5XG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEyIE1hdHQgWW9ya1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICovXG5cbihmdW5jdGlvbigpIHtcblxudmFyIHJvb3QgPSB0aGlzO1xuXG52YXIgZnV6enkgPSB7fTtcblxuLy8gVXNlIGluIG5vZGUgb3IgaW4gYnJvd3NlclxuaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1enp5O1xufSBlbHNlIHtcbiAgcm9vdC5mdXp6eSA9IGZ1enp5O1xufVxuXG4vLyBSZXR1cm4gYWxsIGVsZW1lbnRzIG9mIGBhcnJheWAgdGhhdCBoYXZlIGEgZnV6enlcbi8vIG1hdGNoIGFnYWluc3QgYHBhdHRlcm5gLlxuZnV6enkuc2ltcGxlRmlsdGVyID0gZnVuY3Rpb24ocGF0dGVybiwgYXJyYXkpIHtcbiAgcmV0dXJuIGFycmF5LmZpbHRlcihmdW5jdGlvbihzdHJpbmcpIHtcbiAgICByZXR1cm4gZnV6enkudGVzdChwYXR0ZXJuLCBzdHJpbmcpO1xuICB9KTtcbn07XG5cbi8vIERvZXMgYHBhdHRlcm5gIGZ1enp5IG1hdGNoIGBzdHJpbmdgP1xuZnV6enkudGVzdCA9IGZ1bmN0aW9uKHBhdHRlcm4sIHN0cmluZykge1xuICByZXR1cm4gZnV6enkubWF0Y2gocGF0dGVybiwgc3RyaW5nKSAhPT0gbnVsbDtcbn07XG5cbi8vIElmIGBwYXR0ZXJuYCBtYXRjaGVzIGBzdHJpbmdgLCB3cmFwIGVhY2ggbWF0Y2hpbmcgY2hhcmFjdGVyXG4vLyBpbiBgb3B0cy5wcmVgIGFuZCBgb3B0cy5wb3N0YC4gSWYgbm8gbWF0Y2gsIHJldHVybiBudWxsXG5mdXp6eS5tYXRjaCA9IGZ1bmN0aW9uKHBhdHRlcm4sIHN0cmluZywgb3B0cykge1xuICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgdmFyIHBhdHRlcm5JZHggPSAwXG4gICAgLCByZXN1bHQgPSBbXVxuICAgICwgbGVuID0gc3RyaW5nLmxlbmd0aFxuICAgICwgdG90YWxTY29yZSA9IDBcbiAgICAsIGN1cnJTY29yZSA9IDBcbiAgICAvLyBwcmVmaXhcbiAgICAsIHByZSA9IG9wdHMucHJlIHx8ICcnXG4gICAgLy8gc3VmZml4XG4gICAgLCBwb3N0ID0gb3B0cy5wb3N0IHx8ICcnXG4gICAgLy8gU3RyaW5nIHRvIGNvbXBhcmUgYWdhaW5zdC4gVGhpcyBtaWdodCBiZSBhIGxvd2VyY2FzZSB2ZXJzaW9uIG9mIHRoZVxuICAgIC8vIHJhdyBzdHJpbmdcbiAgICAsIGNvbXBhcmVTdHJpbmcgPSAgb3B0cy5jYXNlU2Vuc2l0aXZlICYmIHN0cmluZyB8fCBzdHJpbmcudG9Mb3dlckNhc2UoKVxuICAgICwgY2gsIGNvbXBhcmVDaGFyO1xuXG4gIHBhdHRlcm4gPSBvcHRzLmNhc2VTZW5zaXRpdmUgJiYgcGF0dGVybiB8fCBwYXR0ZXJuLnRvTG93ZXJDYXNlKCk7XG5cbiAgLy8gRm9yIGVhY2ggY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcsIGVpdGhlciBhZGQgaXQgdG8gdGhlIHJlc3VsdFxuICAvLyBvciB3cmFwIGluIHRlbXBsYXRlIGlmIGl0J3MgdGhlIG5leHQgc3RyaW5nIGluIHRoZSBwYXR0ZXJuXG4gIGZvcih2YXIgaWR4ID0gMDsgaWR4IDwgbGVuOyBpZHgrKykge1xuICAgIGNoID0gc3RyaW5nW2lkeF07XG4gICAgaWYoY29tcGFyZVN0cmluZ1tpZHhdID09PSBwYXR0ZXJuW3BhdHRlcm5JZHhdKSB7XG4gICAgICBjaCA9IHByZSArIGNoICsgcG9zdDtcbiAgICAgIHBhdHRlcm5JZHggKz0gMTtcblxuICAgICAgLy8gY29uc2VjdXRpdmUgY2hhcmFjdGVycyBzaG91bGQgaW5jcmVhc2UgdGhlIHNjb3JlIG1vcmUgdGhhbiBsaW5lYXJseVxuICAgICAgY3VyclNjb3JlICs9IDEgKyBjdXJyU2NvcmU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJTY29yZSA9IDA7XG4gICAgfVxuICAgIHRvdGFsU2NvcmUgKz0gY3VyclNjb3JlO1xuICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IGNoO1xuICB9XG5cbiAgLy8gcmV0dXJuIHJlbmRlcmVkIHN0cmluZyBpZiB3ZSBoYXZlIGEgbWF0Y2ggZm9yIGV2ZXJ5IGNoYXJcbiAgaWYocGF0dGVybklkeCA9PT0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICByZXR1cm4ge3JlbmRlcmVkOiByZXN1bHQuam9pbignJyksIHNjb3JlOiB0b3RhbFNjb3JlfTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxuLy8gVGhlIG5vcm1hbCBlbnRyeSBwb2ludC4gRmlsdGVycyBgYXJyYCBmb3IgbWF0Y2hlcyBhZ2FpbnN0IGBwYXR0ZXJuYC5cbi8vIEl0IHJldHVybnMgYW4gYXJyYXkgd2l0aCBtYXRjaGluZyB2YWx1ZXMgb2YgdGhlIHR5cGU6XG4vL1xuLy8gICAgIFt7XG4vLyAgICAgICAgIHN0cmluZzogICAnPGI+bGFoJyAvLyBUaGUgcmVuZGVyZWQgc3RyaW5nXG4vLyAgICAgICAsIGluZGV4OiAgICAyICAgICAgICAvLyBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgaW4gYGFycmBcbi8vICAgICAgICwgb3JpZ2luYWw6ICdibGFoJyAgIC8vIFRoZSBvcmlnaW5hbCBlbGVtZW50IGluIGBhcnJgXG4vLyAgICAgfV1cbi8vXG4vLyBgb3B0c2AgaXMgYW4gb3B0aW9uYWwgYXJndW1lbnQgYmFnLiBEZXRhaWxzOlxuLy9cbi8vICAgIG9wdHMgPSB7XG4vLyAgICAgICAgLy8gc3RyaW5nIHRvIHB1dCBiZWZvcmUgYSBtYXRjaGluZyBjaGFyYWN0ZXJcbi8vICAgICAgICBwcmU6ICAgICAnPGI+J1xuLy9cbi8vICAgICAgICAvLyBzdHJpbmcgdG8gcHV0IGFmdGVyIG1hdGNoaW5nIGNoYXJhY3RlclxuLy8gICAgICAsIHBvc3Q6ICAgICc8L2I+J1xuLy9cbi8vICAgICAgICAvLyBPcHRpb25hbCBmdW5jdGlvbi4gSW5wdXQgaXMgYW4gZW50cnkgaW4gdGhlIGdpdmVuIGFycmAsXG4vLyAgICAgICAgLy8gb3V0cHV0IHNob3VsZCBiZSB0aGUgc3RyaW5nIHRvIHRlc3QgYHBhdHRlcm5gIGFnYWluc3QuXG4vLyAgICAgICAgLy8gSW4gdGhpcyBleGFtcGxlLCBpZiBgYXJyID0gW3tjcnlpbmc6ICdrb2FsYSd9XWAgd2Ugd291bGQgcmV0dXJuXG4vLyAgICAgICAgLy8gJ2tvYWxhJy5cbi8vICAgICAgLCBleHRyYWN0OiBmdW5jdGlvbihhcmcpIHsgcmV0dXJuIGFyZy5jcnlpbmc7IH1cbi8vICAgIH1cbmZ1enp5LmZpbHRlciA9IGZ1bmN0aW9uKHBhdHRlcm4sIGFyciwgb3B0cykge1xuICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgcmV0dXJuIGFyclxuICAgIC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgZWxlbWVudCwgaWR4LCBhcnIpIHtcbiAgICAgIHZhciBzdHIgPSBlbGVtZW50O1xuICAgICAgaWYob3B0cy5leHRyYWN0KSB7XG4gICAgICAgIHN0ciA9IG9wdHMuZXh0cmFjdChlbGVtZW50KTtcbiAgICAgIH1cbiAgICAgIHZhciByZW5kZXJlZCA9IGZ1enp5Lm1hdGNoKHBhdHRlcm4sIHN0ciwgb3B0cyk7XG4gICAgICBpZihyZW5kZXJlZCAhPSBudWxsKSB7XG4gICAgICAgIHByZXZbcHJldi5sZW5ndGhdID0ge1xuICAgICAgICAgICAgc3RyaW5nOiByZW5kZXJlZC5yZW5kZXJlZFxuICAgICAgICAgICwgc2NvcmU6IHJlbmRlcmVkLnNjb3JlXG4gICAgICAgICAgLCBpbmRleDogaWR4XG4gICAgICAgICAgLCBvcmlnaW5hbDogZWxlbWVudFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByZXY7XG4gICAgfSwgW10pXG5cbiAgICAvLyBTb3J0IGJ5IHNjb3JlLiBCcm93c2VycyBhcmUgaW5jb25zaXN0ZW50IHdydCBzdGFibGUvdW5zdGFibGVcbiAgICAvLyBzb3J0aW5nLCBzbyBmb3JjZSBzdGFibGUgYnkgdXNpbmcgdGhlIGluZGV4IGluIHRoZSBjYXNlIG9mIHRpZS5cbiAgICAvLyBTZWUgaHR0cDovL29mYi5uZXQvfnNldGhtbC9pcy1zb3J0LXN0YWJsZS5odG1sXG4gICAgLnNvcnQoZnVuY3Rpb24oYSxiKSB7XG4gICAgICB2YXIgY29tcGFyZSA9IGIuc2NvcmUgLSBhLnNjb3JlO1xuICAgICAgaWYoY29tcGFyZSkgcmV0dXJuIGNvbXBhcmU7XG4gICAgICByZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7XG4gICAgfSk7XG59O1xuXG5cbn0oKSk7XG5cbiIsIid1c2Ugc3RyaWN0Jztcbm1vZHVsZS5leHBvcnRzID0gbGVmdFBhZDtcblxudmFyIGNhY2hlID0gW1xuICAnJyxcbiAgJyAnLFxuICAnICAnLFxuICAnICAgJyxcbiAgJyAgICAnLFxuICAnICAgICAnLFxuICAnICAgICAgJyxcbiAgJyAgICAgICAnLFxuICAnICAgICAgICAnLFxuICAnICAgICAgICAgJ1xuXTtcblxuZnVuY3Rpb24gbGVmdFBhZCAoc3RyLCBsZW4sIGNoKSB7XG4gIC8vIGNvbnZlcnQgYHN0cmAgdG8gYHN0cmluZ2BcbiAgc3RyID0gc3RyICsgJyc7XG4gIC8vIGBsZW5gIGlzIHRoZSBgcGFkYCdzIGxlbmd0aCBub3dcbiAgbGVuID0gbGVuIC0gc3RyLmxlbmd0aDtcbiAgLy8gZG9lc24ndCBuZWVkIHRvIHBhZFxuICBpZiAobGVuIDw9IDApIHJldHVybiBzdHI7XG4gIC8vIGBjaGAgZGVmYXVsdHMgdG8gYCcgJ2BcbiAgaWYgKCFjaCAmJiBjaCAhPT0gMCkgY2ggPSAnICc7XG4gIC8vIGNvbnZlcnQgYGNoYCB0byBgc3RyaW5nYFxuICBjaCA9IGNoICsgJyc7XG4gIC8vIGNhY2hlIGNvbW1vbiB1c2UgY2FzZXNcbiAgaWYgKGNoID09PSAnICcgJiYgbGVuIDwgMTApIHJldHVybiBjYWNoZVtsZW5dICsgc3RyO1xuICAvLyBgcGFkYCBzdGFydHMgd2l0aCBhbiBlbXB0eSBzdHJpbmdcbiAgdmFyIHBhZCA9ICcnO1xuICAvLyBsb29wXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgLy8gYWRkIGBjaGAgdG8gYHBhZGAgaWYgYGxlbmAgaXMgb2RkXG4gICAgaWYgKGxlbiAmIDEpIHBhZCArPSBjaDtcbiAgICAvLyBkZXZpZGUgYGxlbmAgYnkgMiwgZGl0Y2ggdGhlIGZyYWN0aW9uXG4gICAgbGVuID4+PSAxO1xuICAgIC8vIFwiZG91YmxlXCIgdGhlIGBjaGAgc28gdGhpcyBvcGVyYXRpb24gY291bnQgZ3Jvd3MgbG9nYXJpdGhtaWNhbGx5IG9uIGBsZW5gXG4gICAgLy8gZWFjaCB0aW1lIGBjaGAgaXMgXCJkb3VibGVkXCIsIHRoZSBgbGVuYCB3b3VsZCBuZWVkIHRvIGJlIFwiZG91YmxlZFwiIHRvb1xuICAgIC8vIHNpbWlsYXIgdG8gZmluZGluZyBhIHZhbHVlIGluIGJpbmFyeSBzZWFyY2ggdHJlZSwgaGVuY2UgTyhsb2cobikpXG4gICAgaWYgKGxlbikgY2ggKz0gY2g7XG4gICAgLy8gYGxlbmAgaXMgMCwgZXhpdCB0aGUgbG9vcFxuICAgIGVsc2UgYnJlYWs7XG4gIH1cbiAgLy8gcGFkIGBzdHJgIVxuICByZXR1cm4gcGFkICsgc3RyO1xufVxuIiwiY29uc3Qgc2ludGVya2xhYXMgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnNvbGUubG9nKCdzaW50ZXJrbGFhcyBlYXN0ZXIgZWdnIGFjdGl2YXRlZCcpXG4gIGNvbnN0IHNlYXJjaE5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VhcmNoJylcbiAgY29uc3QgaW5wdXROb2RlID0gc2VhcmNoTm9kZS5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwic2VhcmNoXCJdJylcbiAgY29uc3QgYXV0b2NvbXBsZXRlTm9kZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5hdXRvY29tcGxldGUnKVxuICBsZXQgYXV0b2NvbXBsZXRlID0gZmFsc2VcbiAgY29uc3QgbHlyaWNzID0gW1xuICAgIFtcbiAgICAgIHt3b29yZDogJ0hvb3IgJywgdGltZTogMH0sXG4gICAgICB7d29vcmQ6ICd3aWUgJywgdGltZTogMC4zfSxcbiAgICAgIHt3b29yZDogJ2tsb3B0ICcsIHRpbWU6IDAuNn0sXG4gICAgICB7d29vcmQ6ICdkYWFyICcsIHRpbWU6IDAuOX0sXG4gICAgICB7d29vcmQ6ICdraW5kJywgdGltZTogMS4yfSxcbiAgICAgIHt3b29yZDogJ1xcJ3JlbicsIHRpbWU6IDEuNX1cbiAgICBdLFxuICAgIFtcbiAgICAgIHt3b29yZDogJ0hvb3IgJywgdGltZTogMS44fSxcbiAgICAgIHt3b29yZDogJ3dpZSAnLCB0aW1lOiAyLjF9LFxuICAgICAge3dvb3JkOiAna2xvcHQgJywgdGltZTogMi41fSxcbiAgICAgIHt3b29yZDogJ2RhYXIgJywgdGltZTogMi44fSxcbiAgICAgIHt3b29yZDogJ2tpbmQnLCB0aW1lOiAzLjF9LFxuICAgICAge3dvb3JkOiAnXFwncmVuJywgdGltZTogMy40fVxuICAgIF0sXG4gICAgW1xuICAgICAge3dvb3JkOiAnSG9vciAnLCB0aW1lOiAzLjd9LFxuICAgICAge3dvb3JkOiAnd2llICcsIHRpbWU6IDR9LFxuICAgICAge3dvb3JkOiAndGlrdCAnLCB0aW1lOiA0LjN9LFxuICAgICAge3dvb3JkOiAnZGFhciAnLCB0aW1lOiA0LjZ9LFxuICAgICAge3dvb3JkOiAnemFjaHQnLCB0aW1lOiA0Ljh9LFxuICAgICAge3dvb3JkOiAnamVzICcsIHRpbWU6IDUuM30sXG4gICAgICB7d29vcmQ6ICd0ZWdlbiAnLCB0aW1lOiA1LjV9LFxuICAgICAge3dvb3JkOiAnXFwndCAnLCB0aW1lOiA2LjF9LFxuICAgICAge3dvb3JkOiAncmFhbSAnLCB0aW1lOiA2LjJ9XG4gICAgXVxuICBdXG5cbiAgY29uc3Qgb3JpZ2luYWxWYWx1ZSA9IGlucHV0Tm9kZS52YWx1ZVxuXG4gIGlucHV0Tm9kZS52YWx1ZSA9ICcnXG4gIGlucHV0Tm9kZS5wbGFjZWhvbGRlciA9ICcnXG5cbiAgbHlyaWNzLmZvckVhY2goKHJvdywgcm93SW5kZXgpID0+IHtcbiAgICByb3cuZm9yRWFjaCgod29yZCwgd29yZEluZGV4KSA9PiB7XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHdvcmRJbmRleCA9PT0gMCkgaW5wdXROb2RlLnBsYWNlaG9sZGVyID0gJydcbiAgICAgICAgaW5wdXROb2RlLnBsYWNlaG9sZGVyICs9IHdvcmQud29vcmRcbiAgICAgIH0sIHdvcmQudGltZSAqIDEwMDApXG4gICAgICBpZiAobHlyaWNzLmxlbmd0aCA9PT0gcm93SW5kZXggKyAxICYmXG4gICAgICAgICAgbHlyaWNzW3Jvd0luZGV4XS5sZW5ndGggPT09IHdvcmRJbmRleCArIDEpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKGlucHV0Tm9kZS52YWx1ZSA9PT0gJycpIHtcbiAgICAgICAgICAgIGlucHV0Tm9kZS52YWx1ZSA9IG9yaWdpbmFsVmFsdWVcbiAgICAgICAgICB9XG4gICAgICAgICAgaW5wdXROb2RlLnBsYWNlaG9sZGVyID0gJ1pvZWtlbidcbiAgICAgICAgICBhdXRvY29tcGxldGUgPSB0cnVlXG4gICAgICAgIH0sIHdvcmQudGltZSAqIDEwMDAgKyAxMDAwKVxuICAgICAgfVxuICAgIH0pXG4gIH0pXG5cbiAgaW5wdXROb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgZnVuY3Rpb24gKCkge1xuICAgIGlmICghYXV0b2NvbXBsZXRlKSByZXR1cm5cblxuICAgIGF1dG9jb21wbGV0ZU5vZGUuaW5uZXJIVE1MID0gJydcblxuICAgIGNvbnN0IGF1dG9jb21wbGV0ZUx5cmljcyA9IFtcbiAgICAgIGAndCBJcyBlZW4gdnJlZW1kJ2xpbmcgemVrZXIsYCxcbiAgICAgIGBkaWUgdmVyZHdhYWx0IGlzIHpla2VyLmAsXG4gICAgICBgJ2sgWmFsIGVlbnMgZXZlbiB2cmFnZW4gbmFhciB6aWpuIG5hYW06YFxuICAgIF1cblxuICAgIGF1dG9jb21wbGV0ZUx5cmljcy5mb3JFYWNoKHJvdyA9PiB7XG4gICAgICBjb25zdCByZXN1bHROb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKVxuICAgICAgcmVzdWx0Tm9kZS5pbm5lckhUTUwgPSByb3dcbiAgICAgIGF1dG9jb21wbGV0ZU5vZGUuYXBwZW5kQ2hpbGQocmVzdWx0Tm9kZSlcbiAgICB9KVxuICB9KVxuXG4gIGlucHV0Tm9kZS5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIWF1dG9jb21wbGV0ZSkgcmV0dXJuXG4gICAgaWYgKGlucHV0Tm9kZS52YWx1ZS50b0xvd2VyQ2FzZSgpID09PSAnc2ludCBuaWNvbGFhcycgfHxcbiAgICAgICAgaW5wdXROb2RlLnZhbHVlLnRvTG93ZXJDYXNlKCkgPT09ICdzaW50bmljb2xhYXMnIHx8XG4gICAgICAgIGlucHV0Tm9kZS52YWx1ZS50b0xvd2VyQ2FzZSgpID09PSAnc2ludCBuaWtvbGFhcycgfHxcbiAgICAgICAgaW5wdXROb2RlLnZhbHVlLnRvTG93ZXJDYXNlKCkgPT09ICdzaW50bmlrb2xhYXMnKSB7XG4gICAgICBpbnB1dE5vZGUudmFsdWUgPSAnJ1xuICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAnaHR0cHM6Ly93d3cueW91dHViZS1ub2Nvb2tpZS5jb20vZW1iZWQvanNPaUtKM2tLWE0/c3RhcnQ9MzAnXG4gICAgfVxuICB9KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHsgc2ludGVya2xhYXMgfVxuIiwidmFyIGxlZnRQYWQgPSByZXF1aXJlKCdsZWZ0LXBhZCcpXG52YXIgZ2V0V2VlayA9IHJlcXVpcmUoJy4vZ2V0V2VlaycpXG5cbmZ1bmN0aW9uIGdldFVSTE9mVXNlcnMgKHdlZWtPZmZzZXQsIHR5cGUsIGlkKSB7XG4gIHJldHVybiBgLy8ke3dpbmRvdy5sb2NhdGlvbi5ob3N0fS9tZWV0aW5ncG9pbnRQcm94eS9Sb29zdGVycy1BTCUyRmRvYyUyRmRhZ3Jvb3N0ZXJzJTJGYCArXG4gICAgICBgJHsoZ2V0V2VlaygpICsgd2Vla09mZnNldCl9JTJGJHt0eXBlfSUyRiR7dHlwZX0ke2xlZnRQYWQoaWQsIDUsICcwJyl9Lmh0bWBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRVUkxPZlVzZXJzXG4iLCIvLyBjb3BpZWQgZnJvbSBodHRwOi8vd3d3Lm1lZXRpbmdwb2ludG1jby5ubC9Sb29zdGVycy1BTC9kb2MvZGFncm9vc3RlcnMvdW50aXNzY3JpcHRzLmpzLFxuLy8gd2VyZSB1c2luZyB0aGUgc2FtZSBjb2RlIGFzIHRoZXkgZG8gdG8gYmUgc3VyZSB0aGF0IHdlIGFsd2F5cyBnZXQgdGhlIHNhbWVcbi8vIHdlZWsgbnVtYmVyLlxuZnVuY3Rpb24gZ2V0V2VlayAoKSB7XG4gIC8vIENyZWF0ZSBhIGNvcHkgb2YgdGhpcyBkYXRlIG9iamVjdFxuICBjb25zdCB0YXJnZXQgPSBuZXcgRGF0ZSgpXG5cbiAgLy8gSVNPIHdlZWsgZGF0ZSB3ZWVrcyBzdGFydCBvbiBtb25kYXlcbiAgLy8gc28gY29ycmVjdCB0aGUgZGF5IG51bWJlclxuICBjb25zdCBkYXlOciA9ICh0YXJnZXQuZ2V0RGF5KCkgKyA2KSAlIDdcblxuICAvLyBJU08gODYwMSBzdGF0ZXMgdGhhdCB3ZWVrIDEgaXMgdGhlIHdlZWtcbiAgLy8gd2l0aCB0aGUgZmlyc3QgdGh1cnNkYXkgb2YgdGhhdCB5ZWFyLlxuICAvLyBTZXQgdGhlIHRhcmdldCBkYXRlIHRvIHRoZSB0aHVyc2RheSBpbiB0aGUgdGFyZ2V0IHdlZWtcbiAgdGFyZ2V0LnNldERhdGUodGFyZ2V0LmdldERhdGUoKSAtIGRheU5yICsgMylcblxuICAvLyBTdG9yZSB0aGUgbWlsbGlzZWNvbmQgdmFsdWUgb2YgdGhlIHRhcmdldCBkYXRlXG4gIGNvbnN0IGZpcnN0VGh1cnNkYXkgPSB0YXJnZXQudmFsdWVPZigpXG5cbiAgLy8gU2V0IHRoZSB0YXJnZXQgdG8gdGhlIGZpcnN0IHRodXJzZGF5IG9mIHRoZSB5ZWFyXG4gIC8vIEZpcnN0IHNldCB0aGUgdGFyZ2V0IHRvIGphbnVhcnkgZmlyc3RcbiAgdGFyZ2V0LnNldE1vbnRoKDAsIDEpXG4gIC8vIE5vdCBhIHRodXJzZGF5PyBDb3JyZWN0IHRoZSBkYXRlIHRvIHRoZSBuZXh0IHRodXJzZGF5XG4gIGlmICh0YXJnZXQuZ2V0RGF5KCkgIT09IDQpIHtcbiAgICB0YXJnZXQuc2V0TW9udGgoMCwgMSArICgoNCAtIHRhcmdldC5nZXREYXkoKSkgKyA3KSAlIDcpXG4gIH1cblxuICAvLyBUaGUgd2Vla251bWJlciBpcyB0aGUgbnVtYmVyIG9mIHdlZWtzIGJldHdlZW4gdGhlXG4gIC8vIGZpcnN0IHRodXJzZGF5IG9mIHRoZSB5ZWFyIGFuZCB0aGUgdGh1cnNkYXkgaW4gdGhlIHRhcmdldCB3ZWVrXG4gIHJldHVybiAxICsgTWF0aC5jZWlsKChmaXJzdFRodXJzZGF5IC0gdGFyZ2V0KSAvIDYwNDgwMDAwMCkgLy8gNjA0ODAwMDAwID0gNyAqIDI0ICogMzYwMCAqIDEwMDBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRXZWVrXG4iLCIvKiBnbG9iYWwgZ2EgRkxBR1MgVVNFUlMgKi9cblxucmVxdWlyZSgnZmxleGliaWxpdHknKVxuXG5jb25zdCBmdXp6eSA9IHJlcXVpcmUoJ2Z1enp5Jylcbi8vIGNvbnN0IGdldFVzZXJzID0gcmVxdWlyZSgnLi9nZXRVc2VycycpXG5jb25zdCBnZXRVUkxPZlVzZXIgPSByZXF1aXJlKCcuL2dldFVSTE9mVXNlcicpXG5jb25zdCByZW1vdmVEaWFjcml0aWNzID0gcmVxdWlyZSgnZGlhY3JpdGljcycpLnJlbW92ZVxuY29uc3QgZ2V0V2VlayA9IHJlcXVpcmUoJy4vZ2V0V2VlaycpXG5jb25zdCBlYXN0ZXJFZ2dzID0gcmVxdWlyZSgnLi9lYXN0ZXJFZ2dzJylcblxuY29uc3Qgc2VhcmNoTm9kZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzZWFyY2gnKVxuY29uc3QgaW5wdXROb2RlID0gc2VhcmNoTm9kZS5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwic2VhcmNoXCJdJylcbmNvbnN0IGF1dG9jb21wbGV0ZU5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYXV0b2NvbXBsZXRlJylcbmNvbnN0IHNjaGVkdWxlSWZyYW1lID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NjaGVkdWxlJylcbmNvbnN0IHByZXZCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjd2Vlay1zZWxlY3RvciBidXR0b24nKVswXVxuY29uc3QgbmV4dEJ1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyN3ZWVrLXNlbGVjdG9yIGJ1dHRvbicpWzFdXG5jb25zdCBjdXJyZW50V2Vla05vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY3VycmVudCcpXG5jb25zdCBmYXZOb2RlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmZhdicpXG5cbmlmIChGTEFHUy5pbmRleE9mKCdOT19GRUFUVVJFX0RFVEVDVCcpID09PSAtMSkge1xuICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NjaGVkdWxlJykuZ2V0Q2xpZW50UmVjdHMoKVswXS5ib3R0b20gIT09XG4gICAgICBkb2N1bWVudC5ib2R5LmdldENsaWVudFJlY3RzKClbMF0uYm90dG9tKSB7XG4gICAgd2luZG93LmxvY2F0aW9uID0gJ2h0dHA6Ly93d3cubWVldGluZ3BvaW50bWNvLm5sL1Jvb3N0ZXJzLUFML2RvYy8nXG4gIH0gZWxzZSB7XG4gICAgd2luZG93Lm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB3aW5kb3cubG9jYXRpb24gPSAnaHR0cDovL3d3dy5tZWV0aW5ncG9pbnRtY28ubmwvUm9vc3RlcnMtQUwvZG9jLydcbiAgICB9XG4gIH1cbn0gZWxzZSB7XG4gIGNvbnNvbGUubG9nKCdmZWF0dXJlIGRldGVjdGlvbiBpcyBPRkYnKVxufVxuXG5sZXQgc2VsZWN0ZWRSZXN1bHQgPSAtMVxubGV0IHNlbGVjdGVkVXNlclxubGV0IHJlc3VsdHMgPSBbXVxubGV0IG9mZnNldCA9IDBcblxuZnVuY3Rpb24gZ2V0Q3VycmVudEZhdiAoKSB7XG4gIGlmICghd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKCdmYXYnKSkgcmV0dXJuXG4gIGNvbnN0IGZhdkNvZGUgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2ZhdicpLnNwbGl0KCc6JylcbiAgY29uc3QgZmF2ID0gVVNFUlMuZmlsdGVyKHVzZXIgPT4gdXNlci50eXBlID09PSBmYXZDb2RlWzBdICYmIHVzZXIuaW5kZXggPT09IE51bWJlcihmYXZDb2RlWzFdKSlcbiAgcmV0dXJuIGZhdlswXVxufVxuXG5mdW5jdGlvbiBjaGFuZ2VGYXYgKGlzRmF2KSB7XG4gIGlmICghc2VsZWN0ZWRVc2VyKSByZXR1cm5cbiAgaWYgKGlzRmF2KSB7XG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKCdmYXYnLCBzZWxlY3RlZFVzZXIudHlwZSArICc6JyArIHNlbGVjdGVkVXNlci5pbmRleClcbiAgfSBlbHNlIHtcbiAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oJ2ZhdicpXG4gIH1cbiAgdXBkYXRlRmF2Tm9kZSgpXG59XG5cbmZ1bmN0aW9uIHVzZXJzRXF1YWwgKHVzZXIxLCB1c2VyMikge1xuICBpZiAodXNlcjEgPT0gbnVsbCB8fCB1c2VyMiA9PSBudWxsKSByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIHVzZXIxLnR5cGUgPT09IHVzZXIyLnR5cGUgJiYgdXNlcjEuaW5kZXggPT09IHVzZXIyLmluZGV4XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUZhdk5vZGUgKCkge1xuICBpZiAodXNlcnNFcXVhbChnZXRDdXJyZW50RmF2KCksIHNlbGVjdGVkVXNlcikpIHtcbiAgICBmYXZOb2RlLmlubmVySFRNTCA9ICcmI3hFODM4OydcbiAgfSBlbHNlIHtcbiAgICBmYXZOb2RlLmlubmVySFRNTCA9ICcmI3hFODNBJ1xuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVdlZWtUZXh0ICgpIHtcbiAgaWYgKG9mZnNldCA9PT0gMCkgY3VycmVudFdlZWtOb2RlLmlubmVySFRNTCA9IGBXZWVrICR7Z2V0V2VlaygpICsgb2Zmc2V0fWBcbiAgZWxzZSBjdXJyZW50V2Vla05vZGUuaW5uZXJIVE1MID0gYDxzdHJvbmc+V2VlayAke2dldFdlZWsoKSArIG9mZnNldH08L3N0cm9uZz5gXG59XG5cbnVwZGF0ZVdlZWtUZXh0KClcblxuc2VhcmNoTm9kZS5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgZnVuY3Rpb24gKGUpIHtcbiAgaWYgKChyZXN1bHRzLmxlbmd0aCAhPT0gMCkgJiYgKGUua2V5ID09PSAnQXJyb3dEb3duJyB8fCBlLmtleSA9PT0gJ0Fycm93VXAnKSkge1xuICAgIGUucHJldmVudERlZmF1bHQoKVxuXG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWxlY3RlZCcpKSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2VsZWN0ZWQnKS5jbGFzc0xpc3QucmVtb3ZlKCdzZWxlY3RlZCcpXG5cbiAgICBjb25zdCBjaGFuZ2UgPSBlLmtleSA9PT0gJ0Fycm93RG93bicgPyAxIDogLTFcbiAgICBzZWxlY3RlZFJlc3VsdCArPSBjaGFuZ2VcbiAgICBpZiAoc2VsZWN0ZWRSZXN1bHQgPCAtMSkgc2VsZWN0ZWRSZXN1bHQgPSByZXN1bHRzLmxlbmd0aCAtIDFcbiAgICBlbHNlIGlmIChzZWxlY3RlZFJlc3VsdCA+IHJlc3VsdHMubGVuZ3RoIC0gMSkgc2VsZWN0ZWRSZXN1bHQgPSAtMVxuXG4gICAgaWYgKHNlbGVjdGVkUmVzdWx0ICE9PSAtMSkgYXV0b2NvbXBsZXRlTm9kZS5jaGlsZHJlbltzZWxlY3RlZFJlc3VsdF0uY2xhc3NMaXN0LmFkZCgnc2VsZWN0ZWQnKVxuICB9XG59KVxuXG5sZXQgaW5wdXRFdmVudFN0clxuaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignTVNJRScpICE9PSAtMSB8fFxuICAgIG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoJ1RyaWRlbnQvJykgPiAwKSB7XG4gIGlucHV0RXZlbnRTdHIgPSAndGV4dGlucHV0JyAvLyBJRSA2LTExXG59IGVsc2Uge1xuICBpbnB1dEV2ZW50U3RyID0gJ2lucHV0JyAvLyBub3JtYWwgYnJvd3NlcnNcbn1cblxuc2VhcmNoTm9kZS5hZGRFdmVudExpc3RlbmVyKGlucHV0RXZlbnRTdHIsIGZ1bmN0aW9uIChlKSB7XG4gIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnbm8taW5wdXQnKVxuICBhdXRvY29tcGxldGVOb2RlLmlubmVySFRNTCA9ICcnXG4gIGlmIChpbnB1dE5vZGUudmFsdWUudHJpbSgpID09PSAnJykgcmV0dXJuXG5cbiAgc2VsZWN0ZWRSZXN1bHQgPSAtMVxuICByZXN1bHRzID0gZnV6enkuZmlsdGVyKHJlbW92ZURpYWNyaXRpY3MoaW5wdXROb2RlLnZhbHVlKSwgVVNFUlMsIHtcbiAgICBleHRyYWN0OiBmdW5jdGlvbiAoZWwpIHsgcmV0dXJuIHJlbW92ZURpYWNyaXRpY3MoZWwudmFsdWUpIH1cbiAgfSkuc2xpY2UoMCwgNylcblxuICByZXN1bHRzLmZvckVhY2goZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgIGNvbnN0IHJlc3VsdE5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpXG4gICAgcmVzdWx0Tm9kZS5pbm5lckhUTUwgPSBgJHtyZXN1bHQub3JpZ2luYWwudmFsdWV9YFxuICAgIGF1dG9jb21wbGV0ZU5vZGUuYXBwZW5kQ2hpbGQocmVzdWx0Tm9kZSlcbiAgfSlcbn0pXG5cbnNlYXJjaE5vZGUuYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0Jywgc3VibWl0Rm9ybSlcblxuZnVuY3Rpb24gc3VibWl0Rm9ybSAoZSkge1xuICBpZiAoZSkgZS5wcmV2ZW50RGVmYXVsdCgpXG4gIGlmIChyZXN1bHRzLmxlbmd0aCAhPT0gMCkge1xuICAgIGNvbnN0IGluZGV4SW5SZXN1bHQgPSBzZWxlY3RlZFJlc3VsdCA9PT0gLTEgPyAwIDogc2VsZWN0ZWRSZXN1bHRcbiAgICBzZWxlY3RlZFVzZXIgPSBVU0VSU1tyZXN1bHRzW2luZGV4SW5SZXN1bHRdLmluZGV4XVxuICB9XG4gIGlmIChzZWxlY3RlZFVzZXIgPT0gbnVsbCkgcmV0dXJuXG5cbiAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdzZWFyY2hlZCcpXG5cbiAgdXBkYXRlRmF2Tm9kZSgpXG5cbiAgaW5wdXROb2RlLnZhbHVlID0gc2VsZWN0ZWRVc2VyLnZhbHVlXG4gIGF1dG9jb21wbGV0ZU5vZGUuaW5uZXJIVE1MID0gJydcblxuICBpbnB1dE5vZGUuYmx1cigpXG5cbiAgc2NoZWR1bGVJZnJhbWUuc3JjID0gZ2V0VVJMT2ZVc2VyKG9mZnNldCwgc2VsZWN0ZWRVc2VyLnR5cGUsIHNlbGVjdGVkVXNlci5pbmRleCArIDEpXG5cbiAgbGV0IGV2ZW50QWN0aW9uXG4gIHN3aXRjaCAoc2VsZWN0ZWRVc2VyLnR5cGUpIHtcbiAgICBjYXNlICdjJzpcbiAgICAgIGV2ZW50QWN0aW9uID0gJ0NsYXNzJ1xuICAgICAgYnJlYWtcbiAgICBjYXNlICd0JzpcbiAgICAgIGV2ZW50QWN0aW9uID0gJ1RlYWNoZXInXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3InOlxuICAgICAgZXZlbnRBY3Rpb24gPSAnUm9vbSdcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAncyc6XG4gICAgICBldmVudEFjdGlvbiA9ICdTdHVkZW50J1xuICAgICAgYnJlYWtcbiAgfVxuICBjb25zdCBldmVudExhYmVsID0gc2VsZWN0ZWRVc2VyLnZhbHVlXG5cbiAgZ2EoZnVuY3Rpb24gKCkge1xuICAgIGdhKCdzZW5kJywgeyBoaXRUeXBlOiAnZXZlbnQnLCBldmVudENhdGVnb3J5OiAnc2VhcmNoJywgZXZlbnRBY3Rpb24sIGV2ZW50TGFiZWwgfSlcbiAgfSlcbn1cblxuYXV0b2NvbXBsZXRlTm9kZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gIGlmIChhdXRvY29tcGxldGVOb2RlLmNvbnRhaW5zKGUudGFyZ2V0KSkge1xuICAgIHNlbGVjdGVkUmVzdWx0ID0gQXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChlLnRhcmdldC5wYXJlbnRFbGVtZW50LmNoaWxkTm9kZXMsIGUudGFyZ2V0KVxuICAgIHN1Ym1pdEZvcm0oKVxuICB9XG59KVxuXG5wcmV2QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICBvZmZzZXQtLVxuICB1cGRhdGVXZWVrVGV4dCgpXG4gIHN1Ym1pdEZvcm0oKVxufSlcblxubmV4dEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgb2Zmc2V0KytcbiAgdXBkYXRlV2Vla1RleHQoKVxuICBzdWJtaXRGb3JtKClcbn0pXG5cbmlucHV0Tm9kZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgaW5wdXROb2RlLnNlbGVjdCgpXG59KVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIGZ1bmN0aW9uICgpIHtcbiAgLy8gdGhpcyB3aWxsIHJlbW92ZWQgdGhlIHNlbGVjdGlvbiB3aXRob3V0IGRyYXdpbmcgZm9jdXMgb24gaXQgKHNhZmFyaSlcbiAgLy8gdGhpcyB3aWxsIHJlbW92ZWQgc2VsZWN0aW9uIGV2ZW4gd2hlbiBmb2N1c2luZyBhbiBpZnJhbWUgKGNocm9tZSlcbiAgY29uc3Qgb2xkVmFsdWUgPSBpbnB1dE5vZGUudmFsdWVcbiAgaW5wdXROb2RlLnZhbHVlID0gJydcbiAgaW5wdXROb2RlLnZhbHVlID0gb2xkVmFsdWVcblxuICAvLyB0aGlzIHdpbGwgaGlkZSB0aGUga2V5Ym9hcmQgKGlPUyBzYWZhcmkpXG4gIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuYmx1cigpXG59KVxuXG5zZWFyY2hOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBmdW5jdGlvbiAoZSkge1xuICBhdXRvY29tcGxldGVOb2RlLmlubmVySFRNTCA9ICcnXG59KVxuXG5mYXZOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICBpZiAodXNlcnNFcXVhbChnZXRDdXJyZW50RmF2KCksIHNlbGVjdGVkVXNlcikpIHtcbiAgICBjaGFuZ2VGYXYoZmFsc2UpXG4gIH0gZWxzZSB7XG4gICAgY2hhbmdlRmF2KHRydWUpXG4gIH1cbn0pXG5cbmNvbnN0IGN1cnJlbnRGYXYgPSBnZXRDdXJyZW50RmF2KClcblxuaWYgKGN1cnJlbnRGYXYpIHtcbiAgc2VsZWN0ZWRVc2VyID0gY3VycmVudEZhdlxuICBpbnB1dE5vZGUudmFsdWUgPSBzZWxlY3RlZFVzZXIudmFsdWVcbiAgc2NoZWR1bGVJZnJhbWUuc3JjID0gZ2V0VVJMT2ZVc2VyKG9mZnNldCwgc2VsZWN0ZWRVc2VyLnR5cGUsIHNlbGVjdGVkVXNlci5pbmRleCArIDEpXG4gIHVwZGF0ZUZhdk5vZGUoKVxuXG4gIGxldCBldmVudEFjdGlvblxuICBzd2l0Y2ggKHNlbGVjdGVkVXNlci50eXBlKSB7XG4gICAgY2FzZSAnYyc6XG4gICAgICBldmVudEFjdGlvbiA9ICdDbGFzcydcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndCc6XG4gICAgICBldmVudEFjdGlvbiA9ICdUZWFjaGVyJ1xuICAgICAgYnJlYWtcbiAgICBjYXNlICdyJzpcbiAgICAgIGV2ZW50QWN0aW9uID0gJ1Jvb20nXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3MnOlxuICAgICAgZXZlbnRBY3Rpb24gPSAnU3R1ZGVudCdcbiAgICAgIGJyZWFrXG4gIH1cbiAgY29uc3QgZXZlbnRMYWJlbCA9IHNlbGVjdGVkVXNlci52YWx1ZVxuXG4gIGdhKGZ1bmN0aW9uICgpIHtcbiAgICBnYSgnc2VuZCcsIHsgaGl0VHlwZTogJ2V2ZW50JywgZXZlbnRDYXRlZ29yeTogJ3NlYXJjaCBmYXYnLCBldmVudEFjdGlvbiwgZXZlbnRMYWJlbCB9KVxuICB9KVxufSBlbHNlIGlmIChpbnB1dE5vZGUudmFsdWUgPT09ICcnKSB7XG4gIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnbm8taW5wdXQnKVxuICBpbnB1dE5vZGUuZm9jdXMoKVxufVxuXG5pZiAoaW5wdXROb2RlLnZhbHVlICE9PSAnJykge1xuICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ25vLWlucHV0JylcbiAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdzZWFyY2hlZCcpXG59XG5cbmRvY3VtZW50LmJvZHkuc3R5bGUub3BhY2l0eSA9ICcxJ1xuXG53aW5kb3cuZWFzdGVyRWdncyA9IGVhc3RlckVnZ3NcbiJdfQ==
+!function e(t,n,o){function r(i,l){if(!n[i]){if(!t[i]){var c="function"==typeof require&&require;if(!l&&c)return c(i,!0);if(s)return s(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var a=n[i]={exports:{}};t[i][0].call(a.exports,function(e){var n=t[i][1][e];return r(n?n:e)},a,a.exports,e,t,n,o)}return n[i].exports}for(var s="function"==typeof require&&require,i=0;i<o.length;i++)r(o[i]);return r}({1:[function(e,t,n){function o(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function s(e){return"number"==typeof e}function i(e){return"object"==typeof e&&null!==e}function l(e){return void 0===e}t.exports=o,o.EventEmitter=o,o.prototype._events=void 0,o.prototype._maxListeners=void 0,o.defaultMaxListeners=10,o.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},o.prototype.emit=function(e){var t,n,o,s,c,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||i(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;var a=new Error('Uncaught, unspecified "error" event. ('+t+")");throw a.context=t,a}if(n=this._events[e],l(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:s=Array.prototype.slice.call(arguments,1),n.apply(this,s)}else if(i(n))for(s=Array.prototype.slice.call(arguments,1),u=n.slice(),o=u.length,c=0;c<o;c++)u[c].apply(this,s);return!0},o.prototype.addListener=function(e,t){var n;if(!r(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,r(t.listener)?t.listener:t),this._events[e]?i(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,i(this._events[e])&&!this._events[e].warned&&(n=l(this._maxListeners)?o.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},o.prototype.on=o.prototype.addListener,o.prototype.once=function(e,t){function n(){this.removeListener(e,n),o||(o=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var o=!1;return n.listener=t,this.on(e,n),this},o.prototype.removeListener=function(e,t){var n,o,s,l;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],s=n.length,o=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(i(n)){for(l=s;l-- >0;)if(n[l]===t||n[l].listener&&n[l].listener===t){o=l;break}if(o<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(o,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},o.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},o.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},o.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},o.listenerCount=function(e,t){return e.listenerCount(t)}},{}],2:[function(e,t,n){!function(){var e=this,o={};"undefined"!=typeof n?t.exports=o:e.fuzzy=o,o.simpleFilter=function(e,t){return t.filter(function(t){return o.test(e,t)})},o.test=function(e,t){return null!==o.match(e,t)},o.match=function(e,t,n){n=n||{};var o,r=0,s=[],i=t.length,l=0,c=0,u=n.pre||"",a=n.post||"",d=n.caseSensitive&&t||t.toLowerCase();e=n.caseSensitive&&e||e.toLowerCase();for(var f=0;f<i;f++)o=t[f],d[f]===e[r]?(o=u+o+a,r+=1,c+=1+c):c=0,l+=c,s[s.length]=o;return r===e.length?(l=d===e?1/0:l,{rendered:s.join(""),score:l}):null},o.filter=function(e,t,n){return t&&0!==t.length?"string"!=typeof e?t:(n=n||{},t.reduce(function(t,r,s,i){var l=r;n.extract&&(l=n.extract(r));var c=o.match(e,l,n);return null!=c&&(t[t.length]={string:c.rendered,score:c.score,index:s,original:r}),t},[]).sort(function(e,t){var n=t.score-e.score;return n?n:e.index-t.index})):[]}}()},{}],3:[function(e,t,n){"use strict";function o(e,t,n){if(e+="",t-=e.length,t<=0)return e;if(n||0===n||(n=" "),n+=""," "===n&&t<10)return r[t]+e;for(var o="";;){if(1&t&&(o+=n),t>>=1,!t)break;n+=n}return o+e}t.exports=o;var r=[""," "," "," "," "," "," "," "," "," "]},{}],4:[function(e,t,n){!function(e,o,r){"use strict";function s(){function t(e,t){this.scrollLeft=e,this.scrollTop=t}function n(e){return.5*(1-Math.cos(Math.PI*e))}function s(e){if("object"!=typeof e||null===e||e.behavior===r||"auto"===e.behavior||"instant"===e.behavior)return!0;if("object"==typeof e&&"smooth"===e.behavior)return!1;throw new TypeError("behavior not valid")}function i(t){var n,r,s;do t=t.parentNode,n=t===o.body,r=t.clientHeight<t.scrollHeight||t.clientWidth<t.scrollWidth,s="visible"===e.getComputedStyle(t,null).overflow;while(!n&&(!r||s));return n=r=s=null,t}function l(t){t.frame=e.requestAnimationFrame(l.bind(e,t));var o,r,s,i=f(),c=(i-t.startTime)/a;if(c=c>1?1:c,o=n(c),r=t.startX+(t.x-t.startX)*o,s=t.startY+(t.y-t.startY)*o,t.method.call(t.scrollable,r,s),r===t.x&&s===t.y)return void e.cancelAnimationFrame(t.frame)}function c(n,r,s){var i,c,u,a,h,v=f();n===o.body?(i=e,c=e.scrollX||e.pageXOffset,u=e.scrollY||e.pageYOffset,a=d.scroll):(i=n,c=n.scrollLeft,u=n.scrollTop,a=t),h&&e.cancelAnimationFrame(h),l({scrollable:i,method:a,startTime:v,startX:c,startY:u,x:r,y:s,frame:h})}if(!("scrollBehavior"in o.documentElement.style)){var u=e.HTMLElement||e.Element,a=468,d={scroll:e.scroll||e.scrollTo,scrollBy:e.scrollBy,scrollIntoView:u.prototype.scrollIntoView},f=e.performance&&e.performance.now?e.performance.now.bind(e.performance):Date.now;e.scroll=e.scrollTo=function(){return s(arguments[0])?void d.scroll.call(e,arguments[0].left||arguments[0],arguments[0].top||arguments[1]):void c.call(e,o.body,~~arguments[0].left,~~arguments[0].top)},e.scrollBy=function(){return s(arguments[0])?void d.scrollBy.call(e,arguments[0].left||arguments[0],arguments[0].top||arguments[1]):void c.call(e,o.body,~~arguments[0].left+(e.scrollX||e.pageXOffset),~~arguments[0].top+(e.scrollY||e.pageYOffset))},u.prototype.scrollIntoView=function(){if(s(arguments[0]))return void d.scrollIntoView.call(this,arguments[0]||!0);var t=i(this),n=t.getBoundingClientRect(),r=this.getBoundingClientRect();t!==o.body?(c.call(this,t,t.scrollLeft+r.left-n.left,t.scrollTop+r.top-n.top),e.scrollBy({left:n.left,top:n.top,behavior:"smooth"})):e.scrollBy({left:r.left,top:r.top,behavior:"smooth"})}}}"object"==typeof n?t.exports={polyfill:s}:s()}(window,document)},{}],5:[function(e,t,n){"use strict";var o={};o.send={},o.send.search=function(e,t){var n="event",o=t?"search fav":"search",r=void 0;switch(e.type){case"c":r="Class";break;case"t":r="Teacher";break;case"r":r="Room";break;case"s":r="Student"}var s=e.value;ga(function(){ga("send",{hitType:n,eventCategory:o,eventAction:r,eventLabel:s})})},t.exports=o},{}],6:[function(e,t,n){"use strict";var o=e("events"),r=new o;r._items=[],r._selectedItemIndex=-1,r._nodes={search:document.querySelector("#search"),input:document.querySelector('input[type="search"]'),autocomplete:document.querySelector(".autocomplete")},r.getSelectedItem=function(){if(r.getItems()!==[])return r.getSelectedItemIndex()===-1?r.getItems()[0]:r.getItems()[r.getSelectedItemIndex()]},r.getSelectedItemIndex=function(){return r._selectedItemIndex},r.getItems=function(){return r._items},r.removeAllItems=function(){for(;r._nodes.autocomplete.firstChild;)r._nodes.autocomplete.removeChild(r._nodes.autocomplete.firstChild);r._items=[],r._selectedItemIndex=-1},r.addItem=function(e){var t=document.createElement("li");t.textContent=e.value,r._nodes.autocomplete.appendChild(t),r._items.push(e)},r._moveSelected=function(e){r._selectedItemIndex+e>=r.getItems().length?r._selectedItemIndex=-1:r._selectedItemIndex+e<-1?r._selectedItemIndex=r.getItems().length-1:r._selectedItemIndex+=e;for(var t=0;t<r.getItems().length;t++)r._nodes.autocomplete.children[t].classList.remove("selected");r._selectedItemIndex>=0&&r._nodes.autocomplete.children[r._selectedItemIndex].classList.add("selected")},r._handleItemClick=function(e){if(r._nodes.autocomplete.contains(e.target)){var t=Array.prototype.indexOf.call(r._nodes.autocomplete.children,e.target);r._selectedItemIndex=t,r.emit("select",r.getSelectedItem())}},r._handleKeydown=function(e){"ArrowDown"!==e.key&&"ArrowUp"!==e.key||(e.preventDefault(),"ArrowDown"===e.key?r._moveSelected(1):"ArrowUp"===e.key&&r._moveSelected(-1))},r._nodes.autocomplete.addEventListener("click",r._handleItemClick),r._nodes.input.addEventListener("keydown",r._handleKeydown),t.exports=r},{events:1}],7:[function(e,t,n){"use strict";var o={};o.isIE=navigator.userAgent.indexOf("MSIE")!==-1||navigator.appVersion.indexOf("Trident/")>0,o.isIE?o.inputEvent="textinput":o.inputEvent="input",t.exports=o},{}],8:[function(e,t,n){"use strict";var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r=e("events"),s=new r;s._nodes={toggle:document.querySelector(".fav")},s.get=function(){try{var e=function(){var e=JSON.parse(window.localStorage.getItem("fav"));if(null==e)return{v:void 0};var t=USERS.filter(function(t){return t.type===e.type&&t.value===e.value})[0];return{v:t}}();if("object"===("undefined"==typeof e?"undefined":o(e)))return e.v}catch(e){return void s.delete()}},s.set=function(e){window.localStorage.setItem("fav",JSON.stringify(e)),s._nodes.innerHTML="&#xE838;"},s.delete=function(){window.localStorage.removeItem("fav")},s.updateDom=function(e){e?s._nodes.toggle.innerHTML="&#xE838;":s._nodes.toggle.innerHTML="&#xE83A"},s.update=function(e){var t=s.get();if(null==t)return void s.updateDom(!1);var n=t.type===e.type&&t.index===e.index;s.updateDom(n)},s.toggle=function(e){var t=s.get(),n=null!=t&&t.type===e.type&&t.index===e.index;n?(s.delete(),s.updateDom(!1)):(s.set(e),s.updateDom(!0))},s._handleClick=function(){s.emit("click")},s._nodes.toggle.addEventListener("click",s._handleClick),t.exports=s},{events:1}],9:[function(e,t,n){"use strict";var o={};o._nodes={input:document.querySelector('input[type="search"]'),overflowButton:document.querySelector("#overflow-button")},o._shouldCheck=function(){return FLAGS.indexOf("NO_FEATURE_DETECT")===-1},o._redirect=function(){window.location.href="http://www.meetingpointmco.nl/Roosters-AL/doc/"},o.check=function(){o._shouldCheck()&&(window.onerror=o._redirect,o._nodes.input.getClientRects()[0].top!==o._nodes.overflowButton.getClientRects()[0].top&&o._redirect())},t.exports=o},{}],10:[function(e,t,n){"use strict";var o=e("./browserFixToolkit"),r={};r._nodes={input:document.querySelector('input[type="search"]')},r.isShown=!1,r.show=function(){document.body.classList.add("no-input"),r.isShown=!0},r.hide=function(){document.body.classList.remove("no-input"),r.isShown=!1},r._nodes.input.addEventListener(o.inputEvent,r.hide),t.exports=r},{"./browserFixToolkit":7}],11:[function(e,t,n){"use strict";e("./featureDetect").check();var o=e("./frontpage"),r=e("./search"),s=e("./schedule"),i=e("./weekSelector"),l=e("./favorite"),c=e("./scrollSnap"),u=e("./analytics"),a={};window.state=a,window.require=e,o.show(),i.updateCurrentWeek(),c.startListening(),null!=l.get()?(a.selectedItem=l.get(),l.update(a.selectedItem),u.send.search(a.selectedItem,!0),s.viewItem(i.getSelectedWeek(),a.selectedItem)):r.focus(),r.on("search",function(e){a.selectedItem=e,l.update(a.selectedItem),u.send.search(a.selectedItem),s.viewItem(i.getSelectedWeek(),a.selectedItem)}),i.on("weekChanged",function(e){u.send.search(a.selectedItem),s.viewItem(e,a.selectedItem)}),l.on("click",function(){l.toggle(a.selectedItem)}),document.body.style.opacity=1},{"./analytics":5,"./favorite":8,"./featureDetect":9,"./frontpage":10,"./schedule":12,"./scrollSnap":13,"./search":14,"./weekSelector":15}],12:[function(e,t,n){"use strict";var o=e("events"),r=e("left-pad"),s=e("./search"),i=new o;i._nodes={schedule:document.querySelector("#schedule")},i._parseMeetingpointHTML=function(e){var t=document.createElement("html");t.innerHTML=e;var n=t.querySelector("center");return n},i._handleLoad=function(e){var t=e.target;if(t.status<200||t.status>=400)return void i._handleError(e);var n=i._parseMeetingpointHTML(t.response);i._removeChilds(),i._nodes.schedule.appendChild(n),i._nodes.schedule.classList.remove("error"),i.emit("load")},i._handleError=function(e){var t=e.target,n=void 0;n=404===t.status?"Sorry, er is (nog) geen rooster voor deze week.":"Sorry, er is iets mis gegaan tijdens het laden van deze week.",i._removeChilds(),i._nodes.schedule.textContent=n,i._nodes.schedule.classList.add("error"),i.emit("load")},i._getURLOfUsers=function(e,t,n){var o=n+1;return"//"+window.location.host+"/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F"+e+"%2F"+t+"%2F"+t+r(o,5,"0")+".htm"},i._removeChilds=function(){for(;i._nodes.schedule.firstChild;)i._nodes.schedule.removeChild(i._nodes.schedule.firstChild)},i.viewItem=function(e,t){var n=i._getURLOfUsers(e,t.type,t.index);i._removeChilds();var o=new window.XMLHttpRequest;o.addEventListener("load",i._handleLoad),o.addEventListener("error",i._handleError),o.open("GET",n,!0),o.send(),s.updateDom(t)},t.exports=i},{"./search":14,events:1,"left-pad":3}],13:[function(e,t,n){"use strict";e("smoothscroll-polyfill").polyfill();var o={},r=e("./schedule");o._nodes={search:document.querySelector("#search"),weekSelector:document.querySelector("#week-selector")},o._timeoutID=null,o._getScrollPosition=function(){return document.documentElement&&document.documentElement.scrollTop||document.body.scrollTop},o._handleDoneScrolling=function(){var e=o._getScrollPosition(),t=o._nodes.weekSelector.clientHeight-o._nodes.search.clientHeight;e<t&&e>0&&window.scroll({top:t,left:0,behavior:"smooth"})},o._handleScroll=function(){null!=o._timeoutID&&window.clearTimeout(o._timeoutID),o._timeoutID=window.setTimeout(o._handleDoneScrolling,500);var e=o._getScrollPosition(),t=o._nodes.weekSelector.clientHeight-o._nodes.search.clientHeight;e>=t?document.body.classList.add("week-selector-not-visible"):document.body.classList.remove("week-selector-not-visible")},o._handleWindowResize=function(){var e=o._nodes.weekSelector.clientHeight-o._nodes.search.clientHeight,t=e-(document.body.clientHeight-window.innerHeight);t>0?document.body.style.marginBottom=t+"px":document.body.style.marginBottom=null},o.startListening=function(){window.addEventListener("scroll",o._handleScroll)},r.on("load",o._handleWindowResize),window.addEventListener("resize",o._handleWindowResize),t.exports=o},{"./schedule":12,"smoothscroll-polyfill":4}],14:[function(e,t,n){"use strict";var o=e("events"),r=e("fuzzy"),s=e("./autocomplete"),i=e("./browserFixToolkit"),l=new o;l._nodes={search:document.querySelector("#search"),input:document.querySelector('input[type="search"]')},l.submit=function(){l._nodes.input.blur(),document.body.classList.remove("week-selector-not-visible");var e=s.getSelectedItem();console.log(e),l.emit("search",e)},l.updateDom=function(e){l._nodes.input.value=e.value,s.removeAllItems(),document.body.classList.remove("no-input"),document.body.classList.add("searched")},l.focus=function(){l._nodes.input.focus()},l._handleSubmit=function(e){e.preventDefault(),l.submit()},l._calculate=function(e){var t=r.filter(e,USERS,{extract:function(e){return e.value}}),n=t.slice(0,7),o=n.map(function(e){return e.original});return o},l._handleTextUpdate=function(){var e=l._calculate(l._nodes.input.value);s.removeAllItems();for(var t=0;t<e.length;t++)s.addItem(e[t])},l._handleFocus=function(){l._nodes.input.select()},l._handleBlur=function(){var e=l._nodes.value;l._nodes.value="",l._nodes.value=e,document.activeElement.blur()},s.on("select",l.submit),l._nodes.search.addEventListener("submit",l._handleSubmit),l._nodes.input.addEventListener("focus",l._handleFocus),l._nodes.input.addEventListener("blur",l._handleBlur),l._nodes.input.addEventListener(i.inputEvent,l._handleTextUpdate),t.exports=l},{"./autocomplete":6,"./browserFixToolkit":7,events:1,fuzzy:2}],15:[function(e,t,n){"use strict";var o=e("events"),r=new o;r._nodes={prevButton:document.querySelectorAll("#week-selector button")[0],nextButton:document.querySelectorAll("#week-selector button")[1],currentWeekText:document.querySelector("#week-selector .current")},r._weekOffset=0,r.getCurrentWeek=function(e){var t=(e.getDay()+6)%7;e.setDate(e.getDate()-t+3);var n=e.valueOf();return e.setMonth(0,1),4!==e.getDay()&&e.setMonth(0,1+(4-e.getDay()+7)%7),1+Math.ceil((n-e)/6048e5)},r.getSelectedWeek=function(){var e=new Date,t=new Date(e.getTime()+604800*r._weekOffset*1e3+864e5);return r.getCurrentWeek(t)},r.updateCurrentWeek=function(){var e=r.getSelectedWeek();r.getCurrentWeek(new Date)!==e?r._nodes.currentWeekText.classList.add("changed"):r._nodes.currentWeekText.classList.remove("changed"),r.updateDom(),r.emit("weekChanged",e)},r.updateDom=function(){var e=r.getSelectedWeek(),t=0===(new Date).getDay(),n=null;if(t)switch(r._weekOffset){case 0:n="Aanstaande week";break;case 1:n="Volgende week";break;case-1:n="Afgelopen week"}else switch(r._weekOffset){case 0:n="Huidige week";break;case 1:n="Volgende week";break;case-1:n="Vorige week"}null!=n?r._nodes.currentWeekText.textContent=n+" • "+e:r._nodes.currentWeekText.textContent="Week "+e},r._handlePrevButtonClick=function(){r._weekOffset-=1,r.updateCurrentWeek()},r._handleNextButtonClick=function(){r._weekOffset+=1,r.updateCurrentWeek()},r._nodes.prevButton.addEventListener("click",r._handlePrevButtonClick),r._nodes.nextButton.addEventListener("click",r._handleNextButtonClick),t.exports=r},{events:1}]},{},[11]);
diff --git a/public/javascripts/easterEggs.js b/public/javascripts/easterEggs.js
deleted file mode 100644
index 79fb6d9..0000000
--- a/public/javascripts/easterEggs.js
+++ /dev/null
@@ -1,91 +0,0 @@
-const sinterklaas = function () {
- console.log('sinterklaas easter egg activated')
- const searchNode = document.querySelector('#search')
- const inputNode = searchNode.querySelector('input[type="search"]')
- const autocompleteNode = document.querySelector('.autocomplete')
- let autocomplete = false
- const lyrics = [
- [
- {woord: 'Hoor ', time: 0},
- {woord: 'wie ', time: 0.3},
- {woord: 'klopt ', time: 0.6},
- {woord: 'daar ', time: 0.9},
- {woord: 'kind', time: 1.2},
- {woord: '\'ren', time: 1.5}
- ],
- [
- {woord: 'Hoor ', time: 1.8},
- {woord: 'wie ', time: 2.1},
- {woord: 'klopt ', time: 2.5},
- {woord: 'daar ', time: 2.8},
- {woord: 'kind', time: 3.1},
- {woord: '\'ren', time: 3.4}
- ],
- [
- {woord: 'Hoor ', time: 3.7},
- {woord: 'wie ', time: 4},
- {woord: 'tikt ', time: 4.3},
- {woord: 'daar ', time: 4.6},
- {woord: 'zacht', time: 4.8},
- {woord: 'jes ', time: 5.3},
- {woord: 'tegen ', time: 5.5},
- {woord: '\'t ', time: 6.1},
- {woord: 'raam ', time: 6.2}
- ]
- ]
-
- const originalValue = inputNode.value
-
- inputNode.value = ''
- inputNode.placeholder = ''
-
- lyrics.forEach((row, rowIndex) => {
- row.forEach((word, wordIndex) => {
- setTimeout(function () {
- if (wordIndex === 0) inputNode.placeholder = ''
- inputNode.placeholder += word.woord
- }, word.time * 1000)
- if (lyrics.length === rowIndex + 1 &&
- lyrics[rowIndex].length === wordIndex + 1) {
- setTimeout(function () {
- if (inputNode.value === '') {
- inputNode.value = originalValue
- }
- inputNode.placeholder = 'Zoeken'
- autocomplete = true
- }, word.time * 1000 + 1000)
- }
- })
- })
-
- inputNode.addEventListener('focus', function () {
- if (!autocomplete) return
-
- autocompleteNode.innerHTML = ''
-
- const autocompleteLyrics = [
- `'t Is een vreemd'ling zeker,`,
- `die verdwaalt is zeker.`,
- `'k Zal eens even vragen naar zijn naam:`
- ]
-
- autocompleteLyrics.forEach(row => {
- const resultNode = document.createElement('li')
- resultNode.innerHTML = row
- autocompleteNode.appendChild(resultNode)
- })
- })
-
- inputNode.addEventListener('input', function () {
- if (!autocomplete) return
- if (inputNode.value.toLowerCase() === 'sint nicolaas' ||
- inputNode.value.toLowerCase() === 'sintnicolaas' ||
- inputNode.value.toLowerCase() === 'sint nikolaas' ||
- inputNode.value.toLowerCase() === 'sintnikolaas') {
- inputNode.value = ''
- window.location.href = 'https://www.youtube-nocookie.com/embed/jsOiKJ3kKXM?start=30'
- }
- })
-}
-
-module.exports = { sinterklaas }
diff --git a/public/javascripts/favorite.js b/public/javascripts/favorite.js
new file mode 100644
index 0000000..9edc248
--- /dev/null
+++ b/public/javascripts/favorite.js
@@ -0,0 +1,79 @@
+/* global USERS */
+
+const EventEmitter = require('events')
+
+const self = new EventEmitter()
+
+self._nodes = {
+ toggle: document.querySelector('.fav')
+}
+
+self.get = function () {
+ try {
+ const localStorageUser = JSON.parse(window.localStorage.getItem('fav'))
+ if (localStorageUser == null) return
+
+ const correctedUser = USERS.filter(function (user) {
+ return user.type === localStorageUser.type &&
+ user.value === localStorageUser.value
+ })[0]
+ return correctedUser
+ } catch (e) {
+ self.delete()
+ return
+ }
+}
+
+self.set = function (user) {
+ window.localStorage.setItem('fav', JSON.stringify(user))
+ self._nodes.innerHTML = '&#xE838;'
+}
+
+self.delete = function () {
+ window.localStorage.removeItem('fav')
+}
+
+self.updateDom = function (isFavorite) {
+ if (isFavorite) {
+ self._nodes.toggle.innerHTML = '&#xE838;'
+ } else {
+ self._nodes.toggle.innerHTML = '&#xE83A'
+ }
+}
+
+self.update = function (selectedUser) {
+ const currentUser = self.get()
+
+ if (currentUser == null) {
+ self.updateDom(false)
+ return
+ }
+
+ const isEqual = currentUser.type === selectedUser.type &&
+ currentUser.index === selectedUser.index
+
+ self.updateDom(isEqual)
+}
+
+self.toggle = function (selectedUser) {
+ const currentUser = self.get()
+ const isEqual = currentUser != null &&
+ currentUser.type === selectedUser.type &&
+ currentUser.index === selectedUser.index
+
+ if (isEqual) {
+ self.delete()
+ self.updateDom(false)
+ } else {
+ self.set(selectedUser)
+ self.updateDom(true)
+ }
+}
+
+self._handleClick = function () {
+ self.emit('click')
+}
+
+self._nodes.toggle.addEventListener('click', self._handleClick)
+
+module.exports = self
diff --git a/public/javascripts/featureDetect.js b/public/javascripts/featureDetect.js
new file mode 100644
index 0000000..3a072a1
--- /dev/null
+++ b/public/javascripts/featureDetect.js
@@ -0,0 +1,29 @@
+/* global FLAGS */
+
+const self = {}
+
+self._nodes = {
+ input: document.querySelector('input[type="search"]'),
+ overflowButton: document.querySelector('#overflow-button')
+}
+
+self._shouldCheck = function () {
+ return FLAGS.indexOf('NO_FEATURE_DETECT') === -1
+}
+
+self._redirect = function () {
+ window.location.href = 'http://www.meetingpointmco.nl/Roosters-AL/doc/'
+}
+
+self.check = function () {
+ if (!self._shouldCheck()) return
+
+ window.onerror = self._redirect
+
+ if (self._nodes.input.getClientRects()[0].top !==
+ self._nodes.overflowButton.getClientRects()[0].top) {
+ self._redirect()
+ }
+}
+
+module.exports = self
diff --git a/public/javascripts/frontpage.js b/public/javascripts/frontpage.js
new file mode 100644
index 0000000..17cb539
--- /dev/null
+++ b/public/javascripts/frontpage.js
@@ -0,0 +1,23 @@
+const browserFixToolkit = require('./browserFixToolkit')
+
+const self = {}
+
+self._nodes = {
+ input: document.querySelector('input[type="search"]')
+}
+
+self.isShown = false
+
+self.show = function () {
+ document.body.classList.add('no-input')
+ self.isShown = true
+}
+
+self.hide = function () {
+ document.body.classList.remove('no-input')
+ self.isShown = false
+}
+
+self._nodes.input.addEventListener(browserFixToolkit.inputEvent, self.hide)
+
+module.exports = self
diff --git a/public/javascripts/getURLOfUser.js b/public/javascripts/getURLOfUser.js
deleted file mode 100644
index 1d27175..0000000
--- a/public/javascripts/getURLOfUser.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var leftPad = require('left-pad')
-var getWeek = require('./getWeek')
-
-function getURLOfUsers (weekOffset, type, id) {
- return `//${window.location.host}/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F` +
- `${(getWeek() + weekOffset)}%2F${type}%2F${type}${leftPad(id, 5, '0')}.htm`
-}
-
-module.exports = getURLOfUsers
diff --git a/public/javascripts/getUsers.js b/public/javascripts/getUsers.js
deleted file mode 100644
index 780ae49..0000000
--- a/public/javascripts/getUsers.js
+++ /dev/null
@@ -1,7 +0,0 @@
-var Promise = require('bluebird')
-var request = Promise.promisify(require('request'))
-
-module.exports = function () {
- return request(`http://${window.location.host}/getUserIndex`)
- .then(data => JSON.parse(data.body))
-}
diff --git a/public/javascripts/getWeek.js b/public/javascripts/getWeek.js
deleted file mode 100644
index 40b0bb4..0000000
--- a/public/javascripts/getWeek.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js,
-// were using the same code as they do to be sure that we always get the same
-// week number.
-function getWeek () {
- // Create a copy of this date object
- const target = new Date()
-
- // ISO week date weeks start on monday
- // so correct the day number
- const dayNr = (target.getDay() + 6) % 7
-
- // ISO 8601 states that week 1 is the week
- // with the first thursday of that year.
- // Set the target date to the thursday in the target week
- target.setDate(target.getDate() - dayNr + 3)
-
- // Store the millisecond value of the target date
- const firstThursday = target.valueOf()
-
- // Set the target to the first thursday of the year
- // First set the target to january first
- target.setMonth(0, 1)
- // Not a thursday? Correct the date to the next thursday
- if (target.getDay() !== 4) {
- target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7)
- }
-
- // The weeknumber is the number of weeks between the
- // first thursday of the year and the thursday in the target week
- return 1 + Math.ceil((firstThursday - target) / 604800000) // 604800000 = 7 * 24 * 3600 * 1000
-}
-
-module.exports = getWeek
diff --git a/public/javascripts/main.bak.js b/public/javascripts/main.bak.js
new file mode 100644
index 0000000..895dd3f
--- /dev/null
+++ b/public/javascripts/main.bak.js
@@ -0,0 +1,244 @@
+/* global ga FLAGS USERS */
+
+require('flexibility')
+
+const fuzzy = require('fuzzy')
+// const getUsers = require('./getUsers')
+const getURLOfUser = require('./getURLOfUser')
+const removeDiacritics = require('diacritics').remove
+const getWeek = require('./getWeek')
+const easterEggs = require('./easterEggs')
+
+const searchNode = document.querySelector('#search')
+const inputNode = searchNode.querySelector('input[type="search"]')
+const autocompleteNode = document.querySelector('.autocomplete')
+const scheduleIframe = document.querySelector('#schedule')
+const prevButton = document.querySelectorAll('#week-selector button')[0]
+const nextButton = document.querySelectorAll('#week-selector button')[1]
+const currentWeekNode = document.querySelector('.current')
+const favNode = document.querySelector('.fav')
+
+if (FLAGS.indexOf('NO_FEATURE_DETECT') === -1) {
+ if (document.querySelector('#schedule').getClientRects()[0].bottom !==
+ document.body.getClientRects()[0].bottom) {
+ window.location = 'http://www.meetingpointmco.nl/Roosters-AL/doc/'
+ } else {
+ window.onerror = function () {
+ window.location = 'http://www.meetingpointmco.nl/Roosters-AL/doc/'
+ }
+ }
+} else {
+ console.log('feature detection is OFF')
+}
+
+let selectedResult = -1
+let selectedUser
+let results = []
+let offset = 0
+
+function getCurrentFav () {
+ if (!window.localStorage.getItem('fav')) return
+ const favCode = window.localStorage.getItem('fav').split(':')
+ const fav = USERS.filter(user => user.type === favCode[0] && user.index === Number(favCode[1]))
+ return fav[0]
+}
+
+function changeFav (isFav) {
+ if (!selectedUser) return
+ if (isFav) {
+ window.localStorage.setItem('fav', selectedUser.type + ':' + selectedUser.index)
+ } else {
+ window.localStorage.removeItem('fav')
+ }
+ updateFavNode()
+}
+
+function usersEqual (user1, user2) {
+ if (user1 == null || user2 == null) return false
+ return user1.type === user2.type && user1.index === user2.index
+}
+
+function updateFavNode () {
+ if (usersEqual(getCurrentFav(), selectedUser)) {
+ favNode.innerHTML = '&#xE838;'
+ } else {
+ favNode.innerHTML = '&#xE83A'
+ }
+}
+
+function updateWeekText () {
+ if (offset === 0) currentWeekNode.innerHTML = `Week ${getWeek() + offset}`
+ else currentWeekNode.innerHTML = `<strong>Week ${getWeek() + offset}</strong>`
+}
+
+updateWeekText()
+
+searchNode.addEventListener('keydown', function (e) {
+ if ((results.length !== 0) && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
+ e.preventDefault()
+
+ if (document.querySelector('.selected')) document.querySelector('.selected').classList.remove('selected')
+
+ const change = e.key === 'ArrowDown' ? 1 : -1
+ selectedResult += change
+ if (selectedResult < -1) selectedResult = results.length - 1
+ else if (selectedResult > results.length - 1) selectedResult = -1
+
+ if (selectedResult !== -1) autocompleteNode.children[selectedResult].classList.add('selected')
+ }
+})
+
+let inputEventStr
+if (navigator.userAgent.indexOf('MSIE') !== -1 ||
+ navigator.appVersion.indexOf('Trident/') > 0) {
+ inputEventStr = 'textinput' // IE 6-11
+} else {
+ inputEventStr = 'input' // normal browsers
+}
+
+searchNode.addEventListener(inputEventStr, function (e) {
+ document.body.classList.remove('no-input')
+ autocompleteNode.innerHTML = ''
+ if (inputNode.value.trim() === '') return
+
+ selectedResult = -1
+ results = fuzzy.filter(removeDiacritics(inputNode.value), USERS, {
+ extract: function (el) { return removeDiacritics(el.value) }
+ }).slice(0, 7)
+
+ results.forEach(function (result) {
+ const resultNode = document.createElement('li')
+ resultNode.innerHTML = `${result.original.value}`
+ autocompleteNode.appendChild(resultNode)
+ })
+})
+
+searchNode.addEventListener('submit', submitForm)
+
+function submitForm (e) {
+ if (e) e.preventDefault()
+ if (results.length !== 0) {
+ const indexInResult = selectedResult === -1 ? 0 : selectedResult
+ selectedUser = USERS[results[indexInResult].index]
+ }
+ if (selectedUser == null) return
+
+ document.body.classList.add('searched')
+
+ updateFavNode()
+
+ inputNode.value = selectedUser.value
+ autocompleteNode.innerHTML = ''
+
+ inputNode.blur()
+
+ scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1)
+
+ let eventAction
+ switch (selectedUser.type) {
+ case 'c':
+ eventAction = 'Class'
+ break
+ case 't':
+ eventAction = 'Teacher'
+ break
+ case 'r':
+ eventAction = 'Room'
+ break
+ case 's':
+ eventAction = 'Student'
+ break
+ }
+ const eventLabel = selectedUser.value
+
+ ga(function () {
+ ga('send', { hitType: 'event', eventCategory: 'search', eventAction, eventLabel })
+ })
+}
+
+autocompleteNode.addEventListener('click', function (e) {
+ if (autocompleteNode.contains(e.target)) {
+ selectedResult = Array.prototype.indexOf.call(e.target.parentElement.childNodes, e.target)
+ submitForm()
+ }
+})
+
+prevButton.addEventListener('click', function () {
+ offset--
+ updateWeekText()
+ submitForm()
+})
+
+nextButton.addEventListener('click', function () {
+ offset++
+ updateWeekText()
+ submitForm()
+})
+
+inputNode.addEventListener('click', function () {
+ inputNode.select()
+})
+
+window.addEventListener('blur', function () {
+ // this will removed the selection without drawing focus on it (safari)
+ // this will removed selection even when focusing an iframe (chrome)
+ const oldValue = inputNode.value
+ inputNode.value = ''
+ inputNode.value = oldValue
+
+ // this will hide the keyboard (iOS safari)
+ document.activeElement.blur()
+})
+
+searchNode.addEventListener('blur', function (e) {
+ autocompleteNode.innerHTML = ''
+})
+
+favNode.addEventListener('click', function () {
+ if (usersEqual(getCurrentFav(), selectedUser)) {
+ changeFav(false)
+ } else {
+ changeFav(true)
+ }
+})
+
+const currentFav = getCurrentFav()
+
+if (currentFav) {
+ selectedUser = currentFav
+ inputNode.value = selectedUser.value
+ scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1)
+ updateFavNode()
+
+ let eventAction
+ switch (selectedUser.type) {
+ case 'c':
+ eventAction = 'Class'
+ break
+ case 't':
+ eventAction = 'Teacher'
+ break
+ case 'r':
+ eventAction = 'Room'
+ break
+ case 's':
+ eventAction = 'Student'
+ break
+ }
+ const eventLabel = selectedUser.value
+
+ ga(function () {
+ ga('send', { hitType: 'event', eventCategory: 'search fav', eventAction, eventLabel })
+ })
+} else if (inputNode.value === '') {
+ document.body.classList.add('no-input')
+ inputNode.focus()
+}
+
+if (scheduleIframe.src !== '') {
+ document.body.classList.add('searched')
+}
+
+document.body.style.opacity = '1'
+
+window.easterEggs = easterEggs
diff --git a/public/javascripts/main.js b/public/javascripts/main.js
index 3e6d6a7..6f99621 100644
--- a/public/javascripts/main.js
+++ b/public/javascripts/main.js
@@ -1,245 +1,45 @@
-/* global ga FLAGS USERS */
-
-require('flexibility')
-
-const fuzzy = require('fuzzy')
-// const getUsers = require('./getUsers')
-const getURLOfUser = require('./getURLOfUser')
-const removeDiacritics = require('diacritics').remove
-const getWeek = require('./getWeek')
-const easterEggs = require('./easterEggs')
-
-const searchNode = document.querySelector('#search')
-const inputNode = searchNode.querySelector('input[type="search"]')
-const autocompleteNode = document.querySelector('.autocomplete')
-const scheduleIframe = document.querySelector('#schedule')
-const prevButton = document.querySelectorAll('#week-selector button')[0]
-const nextButton = document.querySelectorAll('#week-selector button')[1]
-const currentWeekNode = document.querySelector('.current')
-const favNode = document.querySelector('.fav')
-
-if (FLAGS.indexOf('NO_FEATURE_DETECT') === -1) {
- if (document.querySelector('#schedule').getClientRects()[0].bottom !==
- document.body.getClientRects()[0].bottom) {
- window.location = 'http://www.meetingpointmco.nl/Roosters-AL/doc/'
- } else {
- window.onerror = function () {
- window.location = 'http://www.meetingpointmco.nl/Roosters-AL/doc/'
- }
- }
+require('./featureDetect').check()
+
+const frontpage = require('./frontpage')
+const search = require('./search')
+const schedule = require('./schedule')
+const weekSelector = require('./weekSelector')
+const favorite = require('./favorite')
+const scrollSnap = require('./scrollSnap')
+const analytics = require('./analytics')
+
+const state = {}
+
+window.state = state
+window.require = require
+
+frontpage.show()
+weekSelector.updateCurrentWeek()
+scrollSnap.startListening()
+
+if (favorite.get() != null) {
+ state.selectedItem = favorite.get()
+ favorite.update(state.selectedItem)
+ analytics.send.search(state.selectedItem, true)
+ schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedItem)
} else {
- console.log('feature detection is OFF')
-}
-
-let selectedResult = -1
-let selectedUser
-let results = []
-let offset = 0
-
-function getCurrentFav () {
- if (!window.localStorage.getItem('fav')) return
- const favCode = window.localStorage.getItem('fav').split(':')
- const fav = USERS.filter(user => user.type === favCode[0] && user.index === Number(favCode[1]))
- return fav[0]
-}
-
-function changeFav (isFav) {
- if (!selectedUser) return
- if (isFav) {
- window.localStorage.setItem('fav', selectedUser.type + ':' + selectedUser.index)
- } else {
- window.localStorage.removeItem('fav')
- }
- updateFavNode()
-}
-
-function usersEqual (user1, user2) {
- if (user1 == null || user2 == null) return false
- return user1.type === user2.type && user1.index === user2.index
-}
-
-function updateFavNode () {
- if (usersEqual(getCurrentFav(), selectedUser)) {
- favNode.innerHTML = '&#xE838;'
- } else {
- favNode.innerHTML = '&#xE83A'
- }
-}
-
-function updateWeekText () {
- if (offset === 0) currentWeekNode.innerHTML = `Week ${getWeek() + offset}`
- else currentWeekNode.innerHTML = `<strong>Week ${getWeek() + offset}</strong>`
+ search.focus()
}
-updateWeekText()
-
-searchNode.addEventListener('keydown', function (e) {
- if ((results.length !== 0) && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
- e.preventDefault()
-
- if (document.querySelector('.selected')) document.querySelector('.selected').classList.remove('selected')
-
- const change = e.key === 'ArrowDown' ? 1 : -1
- selectedResult += change
- if (selectedResult < -1) selectedResult = results.length - 1
- else if (selectedResult > results.length - 1) selectedResult = -1
-
- if (selectedResult !== -1) autocompleteNode.children[selectedResult].classList.add('selected')
- }
+search.on('search', function (selectedItem) {
+ state.selectedItem = selectedItem
+ favorite.update(state.selectedItem)
+ analytics.send.search(state.selectedItem)
+ schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedItem)
})
-let inputEventStr
-if (navigator.userAgent.indexOf('MSIE') !== -1 ||
- navigator.appVersion.indexOf('Trident/') > 0) {
- inputEventStr = 'textinput' // IE 6-11
-} else {
- inputEventStr = 'input' // normal browsers
-}
-
-searchNode.addEventListener(inputEventStr, function (e) {
- document.body.classList.remove('no-input')
- autocompleteNode.innerHTML = ''
- if (inputNode.value.trim() === '') return
-
- selectedResult = -1
- results = fuzzy.filter(removeDiacritics(inputNode.value), USERS, {
- extract: function (el) { return removeDiacritics(el.value) }
- }).slice(0, 7)
-
- results.forEach(function (result) {
- const resultNode = document.createElement('li')
- resultNode.innerHTML = `${result.original.value}`
- autocompleteNode.appendChild(resultNode)
- })
+weekSelector.on('weekChanged', function (newWeek) {
+ analytics.send.search(state.selectedItem)
+ schedule.viewItem(newWeek, state.selectedItem)
})
-searchNode.addEventListener('submit', submitForm)
-
-function submitForm (e) {
- if (e) e.preventDefault()
- if (results.length !== 0) {
- const indexInResult = selectedResult === -1 ? 0 : selectedResult
- selectedUser = USERS[results[indexInResult].index]
- }
- if (selectedUser == null) return
-
- document.body.classList.add('searched')
-
- updateFavNode()
-
- inputNode.value = selectedUser.value
- autocompleteNode.innerHTML = ''
-
- inputNode.blur()
-
- scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1)
-
- let eventAction
- switch (selectedUser.type) {
- case 'c':
- eventAction = 'Class'
- break
- case 't':
- eventAction = 'Teacher'
- break
- case 'r':
- eventAction = 'Room'
- break
- case 's':
- eventAction = 'Student'
- break
- }
- const eventLabel = selectedUser.value
-
- ga(function () {
- ga('send', { hitType: 'event', eventCategory: 'search', eventAction, eventLabel })
- })
-}
-
-autocompleteNode.addEventListener('click', function (e) {
- if (autocompleteNode.contains(e.target)) {
- selectedResult = Array.prototype.indexOf.call(e.target.parentElement.childNodes, e.target)
- submitForm()
- }
-})
-
-prevButton.addEventListener('click', function () {
- offset--
- updateWeekText()
- submitForm()
-})
-
-nextButton.addEventListener('click', function () {
- offset++
- updateWeekText()
- submitForm()
+favorite.on('click', function () {
+ favorite.toggle(state.selectedItem)
})
-inputNode.addEventListener('click', function () {
- inputNode.select()
-})
-
-window.addEventListener('blur', function () {
- // this will removed the selection without drawing focus on it (safari)
- // this will removed selection even when focusing an iframe (chrome)
- const oldValue = inputNode.value
- inputNode.value = ''
- inputNode.value = oldValue
-
- // this will hide the keyboard (iOS safari)
- document.activeElement.blur()
-})
-
-searchNode.addEventListener('blur', function (e) {
- autocompleteNode.innerHTML = ''
-})
-
-favNode.addEventListener('click', function () {
- if (usersEqual(getCurrentFav(), selectedUser)) {
- changeFav(false)
- } else {
- changeFav(true)
- }
-})
-
-const currentFav = getCurrentFav()
-
-if (currentFav) {
- selectedUser = currentFav
- inputNode.value = selectedUser.value
- scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1)
- updateFavNode()
-
- let eventAction
- switch (selectedUser.type) {
- case 'c':
- eventAction = 'Class'
- break
- case 't':
- eventAction = 'Teacher'
- break
- case 'r':
- eventAction = 'Room'
- break
- case 's':
- eventAction = 'Student'
- break
- }
- const eventLabel = selectedUser.value
-
- ga(function () {
- ga('send', { hitType: 'event', eventCategory: 'search fav', eventAction, eventLabel })
- })
-} else if (inputNode.value === '') {
- document.body.classList.add('no-input')
- inputNode.focus()
-}
-
-if (inputNode.value !== '') {
- document.body.classList.remove('no-input')
- document.body.classList.add('searched')
-}
-
-document.body.style.opacity = '1'
-
-window.easterEggs = easterEggs
+document.body.style.opacity = 1
diff --git a/public/javascripts/schedule.js b/public/javascripts/schedule.js
new file mode 100644
index 0000000..a080ace
--- /dev/null
+++ b/public/javascripts/schedule.js
@@ -0,0 +1,71 @@
+const EventEmitter = require('events')
+const leftPad = require('left-pad')
+const search = require('./search')
+
+const self = new EventEmitter()
+
+self._nodes = {
+ schedule: document.querySelector('#schedule')
+}
+
+self._parseMeetingpointHTML = function (htmlStr) {
+ const html = document.createElement('html')
+ html.innerHTML = htmlStr
+ const centerNode = html.querySelector('center')
+ return centerNode
+}
+
+self._handleLoad = function (event) {
+ const request = event.target
+ if (request.status < 200 || request.status >= 400) {
+ self._handleError(event)
+ return
+ }
+ const document = self._parseMeetingpointHTML(request.response)
+ self._removeChilds()
+ self._nodes.schedule.appendChild(document)
+ self._nodes.schedule.classList.remove('error')
+ self.emit('load')
+}
+
+self._handleError = function (event) {
+ const request = event.target
+ let error
+ if (request.status === 404) {
+ error = 'Sorry, er is (nog) geen rooster voor deze week.'
+ } else {
+ error = 'Sorry, er is iets mis gegaan tijdens het laden van deze week.'
+ }
+ self._removeChilds()
+ self._nodes.schedule.textContent = error
+ self._nodes.schedule.classList.add('error')
+ self.emit('load')
+}
+
+self._getURLOfUsers = function (week, type, index) {
+ const id = index + 1
+ return '//' + window.location.host + '/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F' +
+ week + '%2F' + type + '%2F' + type + leftPad(id, 5, '0') + '.htm'
+}
+
+self._removeChilds = function () {
+ while (self._nodes.schedule.firstChild) {
+ self._nodes.schedule.removeChild(self._nodes.schedule.firstChild)
+ }
+}
+
+self.viewItem = function (week, selectedUser) {
+ const url = self._getURLOfUsers(week, selectedUser.type, selectedUser.index)
+
+ self._removeChilds()
+
+ const request = new window.XMLHttpRequest()
+ request.addEventListener('load', self._handleLoad)
+ request.addEventListener('error', self._handleError)
+ request.open('GET', url, true)
+ request.send()
+
+ search.updateDom(selectedUser)
+}
+
+module.exports = self
diff --git a/public/javascripts/scrollSnap.js b/public/javascripts/scrollSnap.js
new file mode 100644
index 0000000..167f0c1
--- /dev/null
+++ b/public/javascripts/scrollSnap.js
@@ -0,0 +1,55 @@
+require('smoothscroll-polyfill').polyfill()
+
+const self = {}
+const schedule = require('./schedule')
+
+self._nodes = {
+ search: document.querySelector('#search'),
+ weekSelector: document.querySelector('#week-selector')
+}
+
+self._timeoutID = null
+
+self._getScrollPosition = function () {
+ return (document.documentElement && document.documentElement.scrollTop) ||
+ document.body.scrollTop
+}
+
+self._handleDoneScrolling = function () {
+ const scrollPosition = self._getScrollPosition()
+ const weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
+ if (scrollPosition < weekSelectorHeight && scrollPosition > 0) {
+ window.scroll({ top: weekSelectorHeight, left: 0, behavior: 'smooth' })
+ }
+}
+
+self._handleScroll = function () {
+ if (self._timeoutID != null) window.clearTimeout(self._timeoutID)
+ self._timeoutID = window.setTimeout(self._handleDoneScrolling, 500)
+
+ const scrollPosition = self._getScrollPosition()
+ const weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
+ if (scrollPosition >= weekSelectorHeight) {
+ document.body.classList.add('week-selector-not-visible')
+ } else {
+ document.body.classList.remove('week-selector-not-visible')
+ }
+}
+
+self._handleWindowResize = function () {
+ const weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
+ const extraPixelsNeeded = weekSelectorHeight - (document.body.clientHeight - window.innerHeight)
+ if (extraPixelsNeeded > 0) {
+ document.body.style.marginBottom = extraPixelsNeeded + 'px'
+ } else {
+ document.body.style.marginBottom = null
+ }
+}
+
+self.startListening = function () {
+ window.addEventListener('scroll', self._handleScroll)
+}
+
+schedule.on('load', self._handleWindowResize)
+window.addEventListener('resize', self._handleWindowResize)
+module.exports = self
diff --git a/public/javascripts/search.js b/public/javascripts/search.js
new file mode 100644
index 0000000..3f223ec
--- /dev/null
+++ b/public/javascripts/search.js
@@ -0,0 +1,87 @@
+/* global USERS */
+
+const EventEmitter = require('events')
+const fuzzy = require('fuzzy')
+const autocomplete = require('./autocomplete')
+const browserFixToolkit = require('./browserFixToolkit')
+
+const self = new EventEmitter()
+
+self._nodes = {
+ search: document.querySelector('#search'),
+ input: document.querySelector('input[type="search"]')
+}
+
+self.submit = function () {
+ self._nodes.input.blur()
+ document.body.classList.remove('week-selector-not-visible') // Safari bug
+
+ const selectedItem = autocomplete.getSelectedItem()
+
+ console.log(selectedItem)
+
+ self.emit('search', selectedItem)
+}
+
+self.updateDom = function (selectedItem) {
+ self._nodes.input.value = selectedItem.value
+ autocomplete.removeAllItems()
+ document.body.classList.remove('no-input')
+ document.body.classList.add('searched')
+}
+
+self.focus = function () {
+ self._nodes.input.focus()
+}
+
+self._handleSubmit = function (event) {
+ event.preventDefault()
+ self.submit()
+}
+
+self._calculate = function (searchTerm) {
+ const allResults = fuzzy.filter(searchTerm, USERS, {
+ extract: function (item) { return item.value }
+ })
+ const firstResults = allResults.slice(0, 7)
+
+ const originalResults = firstResults.map(function (result) {
+ return result.original
+ })
+
+ return originalResults
+}
+
+self._handleTextUpdate = function () {
+ const results = self._calculate(self._nodes.input.value)
+
+ autocomplete.removeAllItems()
+ for (let i = 0; i < results.length; i++) {
+ autocomplete.addItem(results[i])
+ }
+}
+
+self._handleFocus = function () {
+ self._nodes.input.select()
+}
+
+self._handleBlur = function () {
+ // this will removed the selection without drawing focus on it (safari)
+ // this will removed selection even when focusing an iframe (chrome)
+ const oldValue = self._nodes.value
+ self._nodes.value = ''
+ self._nodes.value = oldValue
+
+ // this will hide the keyboard (iOS safari)
+ document.activeElement.blur()
+}
+
+autocomplete.on('select', self.submit)
+
+self._nodes.search.addEventListener('submit', self._handleSubmit)
+self._nodes.input.addEventListener('focus', self._handleFocus)
+self._nodes.input.addEventListener('blur', self._handleBlur)
+self._nodes.input.addEventListener(browserFixToolkit.inputEvent,
+ self._handleTextUpdate)
+
+module.exports = self
diff --git a/public/javascripts/weekSelector.js b/public/javascripts/weekSelector.js
new file mode 100644
index 0000000..6dbf2c8
--- /dev/null
+++ b/public/javascripts/weekSelector.js
@@ -0,0 +1,95 @@
+const EventEmitter = require('events')
+
+const self = new EventEmitter()
+
+self._nodes = {
+ prevButton: document.querySelectorAll('#week-selector button')[0],
+ nextButton: document.querySelectorAll('#week-selector button')[1],
+ currentWeekText: document.querySelector('#week-selector .current')
+}
+
+self._weekOffset = 0
+
+// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js,
+// were using the same code as they do to be sure that we always get the same
+// week number.
+self.getCurrentWeek = function (target) {
+ const dayNr = (target.getDay() + 6) % 7
+ target.setDate(target.getDate() - dayNr + 3)
+ const firstThursday = target.valueOf()
+ target.setMonth(0, 1)
+ if (target.getDay() !== 4) {
+ target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7)
+ }
+
+ return 1 + Math.ceil((firstThursday - target) / 604800000)
+}
+
+self.getSelectedWeek = function () {
+ const now = new Date()
+ const targetDate = new Date(now.getTime() +
+ self._weekOffset * 604800 * 1000 + 86400 * 1000)
+ return self.getCurrentWeek(targetDate)
+}
+
+self.updateCurrentWeek = function () {
+ const selectedWeekNumber = self.getSelectedWeek()
+ if (self.getCurrentWeek(new Date()) !== selectedWeekNumber) {
+ self._nodes.currentWeekText.classList.add('changed')
+ } else {
+ self._nodes.currentWeekText.classList.remove('changed')
+ }
+ self.updateDom()
+ self.emit('weekChanged', selectedWeekNumber)
+}
+
+self.updateDom = function () {
+ const selectedWeekNumber = self.getSelectedWeek()
+ const isSunday = new Date().getDay() === 0
+ let humanReadableWeek = null
+ if (isSunday) {
+ switch (self._weekOffset) {
+ case 0:
+ humanReadableWeek = 'Aanstaande week'
+ break
+ case 1:
+ humanReadableWeek = 'Volgende week'
+ break
+ case -1:
+ humanReadableWeek = 'Afgelopen week'
+ break
+ }
+ } else {
+ switch (self._weekOffset) {
+ case 0:
+ humanReadableWeek = 'Huidige week'
+ break
+ case 1:
+ humanReadableWeek = 'Volgende week'
+ break
+ case -1:
+ humanReadableWeek = 'Vorige week'
+ break
+ }
+ }
+ if (humanReadableWeek != null) {
+ self._nodes.currentWeekText.textContent = humanReadableWeek + ' • ' + selectedWeekNumber
+ } else {
+ self._nodes.currentWeekText.textContent = 'Week ' + selectedWeekNumber
+ }
+}
+
+self._handlePrevButtonClick = function () {
+ self._weekOffset -= 1
+ self.updateCurrentWeek()
+}
+
+self._handleNextButtonClick = function () {
+ self._weekOffset += 1
+ self.updateCurrentWeek()
+}
+
+self._nodes.prevButton.addEventListener('click', self._handlePrevButtonClick)
+self._nodes.nextButton.addEventListener('click', self._handleNextButtonClick)
+
+module.exports = self
diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css
index 5c51bb4..3dc309d 100644
--- a/public/stylesheets/style.css
+++ b/public/stylesheets/style.css
@@ -5,11 +5,6 @@
html, body {
margin: 0;
font-family: 'Roboto', sans-serif;
- display: flex;
- -js-display: flex;
- flex-direction: column;
- width: 100vw;
- height: 100vh;
}
.other {
@@ -23,9 +18,7 @@ html, body {
background-color: #F44336;
margin: 0 auto;
width: 100%;
- position: absolute;
- /*box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);*/
- /*box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);*/
+ position: fixed;
box-shadow: 0 0.5px 1.5px rgba(0,0,0,0.06), 0 0.5px 1px rgba(0,0,0,0.12);
}
@@ -128,10 +121,7 @@ li:hover {
}
#schedule {
- flex-grow: 1;
- width: 100vw;
- border: 0;
- padding: 0;
+ overflow: auto;
}
body.searched #search-space-filler {
@@ -176,6 +166,10 @@ body.searched #search-space-filler {
justify-content: center;
}
+#week-selector .current.changed {
+ font-weight: bold;
+}
+
#week-selector button {
background: transparent;
color: white;
@@ -232,6 +226,10 @@ ul a {
display: none;
}
+body:not(.no-input) {
+ overflow-y: scroll;
+}
+
body.no-input #week-selector {
display: none;
}
@@ -351,4 +349,31 @@ body.no-input #week-selector {
.tooltip {
display: none;
+}
+
+@media screen and (max-width: 600px) {
+ table table tr {
+ display: flex;
+ flex-direction: column;
+ }
+
+ table * {
+ padding: 0;
+ line-height: 13px;
+ font-size: 13px;
+ }
+}
+
+.error {
+ text-align: center;
+ margin-top: 100px;
+ padding: 16px;
+}
+
+body.week-selector-not-visible #search {
+ box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
+}
+
+body.week-selector-not-visible #week-selector {
+ box-shadow: inherit;
} \ No newline at end of file
diff --git a/routes/meetingpointProxy.js b/routes/meetingpointProxy.js
index cec74a8..b2b51c9 100644
--- a/routes/meetingpointProxy.js
+++ b/routes/meetingpointProxy.js
@@ -1,16 +1,17 @@
var express = require('express')
var router = express.Router()
-const Promise = require('bluebird')
-const request = Promise.promisify(require('request'))
-const encoding = require('encoding')
+const request = require('request')
/* GET home page. */
router.get('/:url', function (req, res, next) {
- request(`http://www.meetingpointmco.nl/${req.params.url}`)
- .then(raw => raw.body)
- .then(page => encoding.convert(page, 'UTF-8', 'Windows-1252'))
- .then(body => { res.end(body) })
- .catch(next)
+ const url = `http://www.meetingpointmco.nl/${req.params.url}`
+ request(url, function (err, data) {
+ if (err) {
+ next(err)
+ return
+ }
+ res.status(data.statusCode).end(data.body)
+ })
})
module.exports = router
diff --git a/views/index.jade b/views/index.jade
index dff671e..28a6495 100644
--- a/views/index.jade
+++ b/views/index.jade
@@ -14,7 +14,7 @@ block content
.logo
.text Rooster
.input-wrapper
- input(type='search', placeholder='Zoeken')
+ input(type='search', placeholder='Zoeken', autocomplete='off')
button.material-icons.fav(tabindex='0', type='button') &#xE83A;
.tooltip
span Voer hier een <strong>docentafkorting</strong>, <strong>klas</strong>, <strong>leerlingnummer</strong> of <strong>lokaalnummer</strong> in.
@@ -36,7 +36,7 @@ block content
span.current Loading...
button(type='button').material-icons &#xE5C8;
- iframe(scrolling='no')#schedule
+ #schedule
block scripts
script.