diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7176f4b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**.DS_Store diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..e6fbf56 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +term.syui.ai diff --git a/css/terminal-nyan.css b/css/terminal-nyan.css new file mode 100644 index 0000000..c63f825 --- /dev/null +++ b/css/terminal-nyan.css @@ -0,0 +1,8 @@ +#window { + -moz-box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.75); + -webkit-box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.75); + background: #333; + height: 100%; + overflow: hidden; + width: 100%; +} diff --git a/css/terminal.css b/css/terminal.css new file mode 100644 index 0000000..1b9950b --- /dev/null +++ b/css/terminal.css @@ -0,0 +1,486 @@ +html { + -webkit-font-smoothing: antialiased; + -moz-font-smoothing: antialiased; + -ms-font-smoothing: antialiased; + -o-font-smoothing: antialiased; +} +body { + background-attachment: fixed; + -webkit-background-size: cover; + background-size: cover; + color: #444; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +#window { + margin-left: auto; + margin-right: auto; + background: #333; + border-radius: 4px; + overflow: hidden; + width: 100%; + height: 100%; + margin:5px; +} + +#topbar { + width: 100%; + height: 21px; + font-size: 16px; + font-family: "Myriad Pro", sans-serif; + text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); +} +#topbar ul li { + float: left; + padding: 0 10px; + height: 21px; + line-height: 24px; +} +#topbar ul li:first-child { + font-size: 20px; + line-height: 26px; + margin-left: 5px; +} +#topbar ul li:nth-child(2) { + font-family: "Myriad-Semi", sans-serif; +} +#topbar ul li:active { + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(1, #4a82ff), color-stop(0, #0052fc)); + color: #fff; + text-shadow: none; +} +#toolbar { + width: 100%; + height: 25px; + background: #ccc; +} +#toolbar .top { + float: left; + width: 100%; + height: 23px; +} +#toolbar .bottom { + float: left; + width: 100%; + height: 30px; +} +#toolbar #lights { + float: left; + position: relative; + top: 6px; + left: 7px; +} +.light { + float: left; + width: 14px; + height: 14px; + border-radius: 14px; + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.5), 0px 0px 3px #000 inset; + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.5), 0px 0px 3px #000 inset; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.5), 0px 0px 3px #000 inset; + overflow: hidden; +} +#lights:hover .glyph { + opacity: 1; + cursor: default; +} +.light .shine { + width: 4px; + height: 3px; + border-radius: 10px; + background: -moz-radial-gradient(center, ellipse cover, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); + background-image: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(255, 255, 255, 0))); + background: -webkit-radial-gradient(center, ellipse cover, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); + background: -o-radial-gradient(center, ellipse cover, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); + background: -ms-radial-gradient(center, ellipse cover, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); + background: radial-gradient(center, ellipse cover, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); +} +.light .glow { + width: 14px; + height: 8px; + background-image: -webkit-gradient(radial, center bottom, 0, center center, 5, from(rgba(255, 255, 255, 0.75)), to(rgba(255, 255, 255, 0))); + background: 0px 0px -moz-radial-gradient(bottom, cover, rgba(255, 255, 255, 0.70) 0%, rgba(255, 255, 255, 0) 80%); +} +.red { + background: #f41b16; + background: -moz-linear-gradient(top, #f41b16 0%, #fc7471 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f41b16), color-stop(100%, #fc7471)); + background: -webkit-linear-gradient(top, #f41b16 0%, #fc7471 100%); + background: -o-linear-gradient(top, #f41b16 0%, #fc7471 100%); + background: -ms-linear-gradient(top, #f41b16 0%, #fc7471 100%); + background: linear-gradient(top, #f41b16 0%, #fc7471 100%); +} +.red:active { + background: #972f2e; + background: -moz-linear-gradient(top, #972f2e 0%, #fc7471 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #972f2e), color-stop(100%, #fc7471)); + background: -webkit-linear-gradient(top, #972f2e 0%, #fc7471 100%); + background: -o-linear-gradient(top, #972f2e 0%, #fc7471 100%); + background: -ms-linear-gradient(top, #972f2e 0%, #fc7471 100%); + background: linear-gradient(top, #972f2e 0%, #fc7471 100%); +} +.red .shine { + position: relative; + top: -21px; + left: 5px; +} +.red .glow { + position: relative; + top: -20px; +} +.red .glyph { + position: relative; + top: -5px; + left: 3px; + font-size: 14px; + font-weight: 400; + color: #9b3a36; + z-index: 50; + opacity: 0; +} +.yellow { + background: #f4a316; + background: -moz-linear-gradient(left, #f4a316 0%, #fcc371 100%); + background: -webkit-gradient(linear, left top, right top, color-stop(0%, #f4a316), color-stop(100%, #fcc371)); + background: -webkit-linear-gradient(left, #f4a316 0%, #fcc371 100%); + background: -o-linear-gradient(left, #f4a316 0%, #fcc371 100%); + background: -ms-linear-gradient(left, #f4a316 0%, #fcc371 100%); + background: linear-gradient(left, #f4a316 0%, #fcc371 100%); + margin: 0px 7px; +} +.yellow:active { + background: #ae4f1e; + background: -moz-linear-gradient(top, #ae4f1e 0%, #fcc371 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ae4f1e), color-stop(100%, #fcc371)); + background: -webkit-linear-gradient(top, #ae4f1e 0%, #fcc371 100%); + background: -o-linear-gradient(top, #ae4f1e 0%, #fcc371 100%); + background: -ms-linear-gradient(top, #ae4f1e 0%, #fcc371 100%); + background: linear-gradient(top, #ae4f1e 0%, #fcc371 100%); +} +.yellow .shine { + position: relative; + top: -21px; + left: 5px; +} +.yellow .glow { + position: relative; + top: -20px; +} +.yellow .glyph { + position: relative; + top: -5px; + left: 3px; + font-size: 24px; + color: #854322; + z-index: 50; + opacity: 0; + -webkit-transform: scaleY(1.5) scaleX(1.3); +} +.green { + background: #4cae2e; + background: -moz-linear-gradient(top, #4cae2e 0%, #dafc71 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #4cae2e), color-stop(100%, #dafc71)); + background: -webkit-linear-gradient(top, #4cae2e 0%, #dafc71 100%); + background: -o-linear-gradient(top, #4cae2e 0%, #dafc71 100%); + background: -ms-linear-gradient(top, #4cae2e 0%, #dafc71 100%); + background: linear-gradient(top, #4cae2e 0%, #dafc71 100%); +} +.green:active { + background: #48752b; + background: -moz-linear-gradient(top, #48752b 0%, #dafc71 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #48752b), color-stop(100%, #dafc71)); + background: -webkit-linear-gradient(top, #48752b 0%, #dafc71 100%); + background: -o-linear-gradient(top, #48752b 0%, #dafc71 100%); + background: -ms-linear-gradient(top, #48752b 0%, #dafc71 100%); + background: linear-gradient(top, #48752b 0%, #dafc71 100%); +} +.green .shine { + position: relative; + top: -20px; + left: 5px; +} +.green .glow { + position: relative; + top: -20px; +} +.green .glyph { + position: relative; + top: -5px; + left: 3px; + font-size: 14px; + font-weight: bold; + color: #25571d; + z-index: 50; + opacity: 0; +} +@-moz-document url-prefix() { + .red .glyph { + position: relative; + top: -5px; + } + .yellow .glyph { + top: -4px; + left: 3px; + } + .green .glyph { + position: relative; + top: -4px; + } +} +#title { + float: left; + position: relative; + top: 6px; + width: 40%; + left: 45%; + font-family: "Myriad Pro", sans-serif; + font-size: 16px; + line-height: 14px; + font-weight: bold; +} +.folder { + float: left; + margin-right: 5px; +} +.folder .tab { + width: 4px; + height: 2px; + background: #a4c5da; + border: 1px solid #728ea3; + border-bottom: none; + border-radius: 2px 2px 0px 0px; + -webkit-box-shadow: 0px -1px 0px #99b5c7 inset; + margin-left: 1px; + z-index: 5000; + margin-bottom: -1px; +} +.folder .body { + width: 14px; + height: 10px; + border: 1px solid #6e8ba1; + background: #b8cfe0; + background: -moz-linear-gradient(top, #b8cfe0 0%, #86adc8 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b8cfe0), color-stop(100%, #86adc8)); + background: -webkit-linear-gradient(top, #b8cfe0 0%, #86adc8 100%); + background: -o-linear-gradient(top, #b8cfe0 0%, #86adc8 100%); + background: -ms-linear-gradient(top, #b8cfe0 0%, #86adc8 100%); + background: linear-gradient(top, #b8cfe0 0%, #86adc8 100%); + z-index: -50; + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px 1px 0px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px 1px 0px rgba(0, 0, 0, 0.2); +} +#nav { + margin: 1px 8px; + float: left; +} +#view { + margin: 2px 0 0 110px; + display: inline-block; +} +.control_box { + height: 20px; + border-radius: 3px; + border: 1px solid #555; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(1, #fefefe), color-stop(0, #b8b8b8)); + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); +} +.control_box .control { + height: 20px; + border-right: 1px solid #2e2e2e; + float: left; + text-align: center; + width: 27px; +} +.control:last-child { + border-right: 0px solid !important; +} +.control:active { + background: #b0afb0; + -webkit-box-shadow: 0px 0px 4px #000 inset; +} +.active { + background: #707070 !important; + -webkit-box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.6) inset !important; +} +#body { + font-family: Andale Mono, monospace; + line-height: 1em; + font-size: 13px; + float: left; + width: 100%; + background: #002b36; + padding: 10px; + line-height: 1.5em; +} +#body p { + color: #63de00!important; +} +@keyframes blink { + 0% { + background: rgba(99, 222, 0, 100); + } + 100% { + background: rgba(99, 222, 0, 0); + } +} +@-webkit-keyframes blink { + 0% { + background: rgba(99, 222, 0, 100); + } + 100% { + background: rgba(99, 222, 0, 0); + } +} +@-moz-keyframes blink { + 0% { + background: rgba(99, 222, 0, 100); + } + 100% { + background: rgba(99, 222, 0, 0); + } +} +.cursor { + width: 10px; + margin-left: 0px; + color: #fff; +} +#body p::-webkit-selection { + background: #0b209e; +} +#body p::selection { + background: #0b209e; +} +#body p::-moz-selection { + background: #0b209e; +} +#body p { + margin-top: 5px; + margin-bottom: 5px; + font-size: 13px; +} +#content { + float: left; + margin-top: 1px; +} +#foot { + height: 23px; + width: 100%; + float: left; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(1, #cbcbcb), color-stop(0, #a7a7a7)); + border-top: 1px solid #515151; + border-radius: 0 0 5px 5px; +} +#foot .handle { + width: 11px; + height: 11px; + float: right; + margin: 6px; + overflow: hidden; +} +.handle .grip { + -webkit-transform: rotate(45deg) scaley(3); + margin: 2px 0 0 2px; + color: #646464; + text-shadow: 1px 1px 0 #c6c6c6; + font-size: 14px; +} +.icon .frame { + width: 82px; + height: 82px; + border-radius: 5px; + border: 2px solid transparent; +} +.icon .name { + color: #000; + padding-top: 3px; + border-radius: 15px; + width: 55px; + margin: 5px 0 0 15px; +} +.icon .folder { + margin: 15px 0 0 6px; +} +#icon-github { + text-align: -999px; + font-size: 1px; + display: block; + width: 156px; + height: 133px; + background-image: url(../img/sprite.png); + background-position: 0 133px; +} +#icon-github:hover { + background-position: 0 0px; +} +#icon-rubygems { + text-align: -999px; + font-size: 1px; + display: block; + width: 156px; + height: 133px; + background-image: url(../img/sprite.png); + background-position: 158px 133px; +} +#icon-rubygems:hover { + background-position: 158px 0px; +} +.source-urls { + margin-top: 40px; + margin-bottom: 40px; +} +.no-margin-bot { + color: #337AB7; +} +span { + font-size: 15px; +} +#particles-js { + position: absolute; + width: 98%; +} +#particles-js-no { + position: absolute; + width: 98%; +} + +#icon-github:hover, +i.icon.ion-close-circled:hover, +i.icon.ion-minus-circled:hover, +i.icon.ion-plus-circled:hover { + color: rgba(0, 0, 0, .5); +} +i.icon.ion-close-circled { + color: rgba(212, 42, 38, 0.83); + text-shadow: 0 0 1px rgba(187, 187, 187, 0.56); + padding-top: 3px; +} +i.icon.ion-minus-circled { + color: rgb(160, 165, 34); + text-shadow: 0 0 1px rgba(187, 187, 187, 0.56); + padding-top: 3px; +} +i.icon.ion-plus-circled { + color: rgb(82, 183, 51); + text-shadow: 0 0 1px rgba(187, 187, 187, 0.56); + padding-top: 3px; +} +.icon { + margin: 7px; + float: left; + font-size: 20px; +} +#title-left { + position: relative; + top: -8px; + font-family: "Myriad Pro", sans-serif; + font-size: 14px; + left: 49%; +} +#terminal-origin { + font-family: monospace; +} +@media all and (-webkit-min-device-pixel-ratio: 0) and (min-resolution: .001dpcm) { + #title-left { + top: -13px; + } +} diff --git a/css/terminal.mobile.css b/css/terminal.mobile.css new file mode 100644 index 0000000..fbf2afc --- /dev/null +++ b/css/terminal.mobile.css @@ -0,0 +1,22 @@ +@media screen and (max-width:1000px){i.icon.ion-minus-circled{display:none} +#window{width:100%;} +} +@media screen and (max-width:800px){body{padding-top:0px;} +#title-left{left:50%;} +#window{width:100%;} +.container{padding:0px;} +/*article{padding:10px 20px;}*/ +i.icon.ion-minus-circled{display:none} +} +@media screen and (max-width:800px){#title-left{left:48%;} +} +@media screen and (max-width:500px){#title-left{left:40%;} +} +@media screen and (max-width:400px){body{padding-top:0px;width:auto;} +#title-left{left:50%;} +/*article{padding:10px 10px;}*/ +#particles-js{width:auto;} +#particles-js-no{width:auto;} +i.icon.ion-minus-circled{display:none} +i.icon.ion-plus-circled{display:none} +} diff --git a/icon/ai.png b/icon/ai.png new file mode 100644 index 0000000..d21dabe Binary files /dev/null and b/icon/ai.png differ diff --git a/icon/ai.svg b/icon/ai.svg new file mode 100644 index 0000000..8926e2a --- /dev/null +++ b/icon/ai.svg @@ -0,0 +1,1882 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Created by potrace 1.16, written by Peter Selinger 2001-2019 + + + + diff --git a/icon/apple-touch-icon.png b/icon/apple-touch-icon.png new file mode 100644 index 0000000..d21dabe Binary files /dev/null and b/icon/apple-touch-icon.png differ diff --git a/icon/avatar.png b/icon/avatar.png new file mode 100644 index 0000000..f091ef1 Binary files /dev/null and b/icon/avatar.png differ diff --git a/icon/term.png b/icon/term.png new file mode 100644 index 0000000..dcff3bc Binary files /dev/null and b/icon/term.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..5e0a606 --- /dev/null +++ b/index.html @@ -0,0 +1,25 @@ + + + + ai/term + + + + + + + + + + + + + + + + + + + + + diff --git a/js/bundle.js b/js/bundle.js new file mode 100644 index 0000000..21c283e --- /dev/null +++ b/js/bundle.js @@ -0,0 +1,5241 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ var parentHotUpdateCallback = this["webpackHotUpdate"]; +/******/ this["webpackHotUpdate"] = +/******/ function webpackHotUpdateCallback(chunkId, moreModules) { // eslint-disable-line no-unused-vars +/******/ hotAddUpdateChunk(chunkId, moreModules); +/******/ if(parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules); +/******/ } +/******/ +/******/ function hotDownloadUpdateChunk(chunkId) { // eslint-disable-line no-unused-vars +/******/ var head = document.getElementsByTagName("head")[0]; +/******/ var script = document.createElement("script"); +/******/ script.type = "text/javascript"; +/******/ script.charset = "utf-8"; +/******/ script.src = __webpack_require__.p + "" + chunkId + "." + hotCurrentHash + ".hot-update.js"; +/******/ head.appendChild(script); +/******/ } +/******/ +/******/ function hotDownloadManifest(callback) { // eslint-disable-line no-unused-vars +/******/ if(typeof XMLHttpRequest === "undefined") +/******/ return callback(new Error("No browser support")); +/******/ try { +/******/ var request = new XMLHttpRequest(); +/******/ var requestPath = __webpack_require__.p + "" + hotCurrentHash + ".hot-update.json"; +/******/ request.open("GET", requestPath, true); +/******/ request.timeout = 10000; +/******/ request.send(null); +/******/ } catch(err) { +/******/ return callback(err); +/******/ } +/******/ request.onreadystatechange = function() { +/******/ if(request.readyState !== 4) return; +/******/ if(request.status === 0) { +/******/ // timeout +/******/ callback(new Error("Manifest request to " + requestPath + " timed out.")); +/******/ } else if(request.status === 404) { +/******/ // no update available +/******/ callback(); +/******/ } else if(request.status !== 200 && request.status !== 304) { +/******/ // other failure +/******/ callback(new Error("Manifest request to " + requestPath + " failed.")); +/******/ } else { +/******/ // success +/******/ try { +/******/ var update = JSON.parse(request.responseText); +/******/ } catch(e) { +/******/ callback(e); +/******/ return; +/******/ } +/******/ callback(null, update); +/******/ } +/******/ }; +/******/ } + +/******/ +/******/ +/******/ // Copied from https://github.com/facebook/react/blob/bef45b0/src/shared/utils/canDefineProperty.js +/******/ var canDefineProperty = false; +/******/ try { +/******/ Object.defineProperty({}, "x", { +/******/ get: function() {} +/******/ }); +/******/ canDefineProperty = true; +/******/ } catch(x) { +/******/ // IE will fail on defineProperty +/******/ } +/******/ +/******/ var hotApplyOnUpdate = true; +/******/ var hotCurrentHash = "df5ff963eab1d8f408b8"; // eslint-disable-line no-unused-vars +/******/ var hotCurrentModuleData = {}; +/******/ var hotCurrentParents = []; // eslint-disable-line no-unused-vars +/******/ +/******/ function hotCreateRequire(moduleId) { // eslint-disable-line no-unused-vars +/******/ var me = installedModules[moduleId]; +/******/ if(!me) return __webpack_require__; +/******/ var fn = function(request) { +/******/ if(me.hot.active) { +/******/ if(installedModules[request]) { +/******/ if(installedModules[request].parents.indexOf(moduleId) < 0) +/******/ installedModules[request].parents.push(moduleId); +/******/ if(me.children.indexOf(request) < 0) +/******/ me.children.push(request); +/******/ } else hotCurrentParents = [moduleId]; +/******/ } else { +/******/ console.warn("[HMR] unexpected require(" + request + ") from disposed module " + moduleId); +/******/ hotCurrentParents = []; +/******/ } +/******/ return __webpack_require__(request); +/******/ }; +/******/ for(var name in __webpack_require__) { +/******/ if(Object.prototype.hasOwnProperty.call(__webpack_require__, name)) { +/******/ if(canDefineProperty) { +/******/ Object.defineProperty(fn, name, (function(name) { +/******/ return { +/******/ configurable: true, +/******/ enumerable: true, +/******/ get: function() { +/******/ return __webpack_require__[name]; +/******/ }, +/******/ set: function(value) { +/******/ __webpack_require__[name] = value; +/******/ } +/******/ }; +/******/ }(name))); +/******/ } else { +/******/ fn[name] = __webpack_require__[name]; +/******/ } +/******/ } +/******/ } +/******/ +/******/ function ensure(chunkId, callback) { +/******/ if(hotStatus === "ready") +/******/ hotSetStatus("prepare"); +/******/ hotChunksLoading++; +/******/ __webpack_require__.e(chunkId, function() { +/******/ try { +/******/ callback.call(null, fn); +/******/ } finally { +/******/ finishChunkLoading(); +/******/ } +/******/ +/******/ function finishChunkLoading() { +/******/ hotChunksLoading--; +/******/ if(hotStatus === "prepare") { +/******/ if(!hotWaitingFilesMap[chunkId]) { +/******/ hotEnsureUpdateChunk(chunkId); +/******/ } +/******/ if(hotChunksLoading === 0 && hotWaitingFiles === 0) { +/******/ hotUpdateDownloaded(); +/******/ } +/******/ } +/******/ } +/******/ }); +/******/ } +/******/ if(canDefineProperty) { +/******/ Object.defineProperty(fn, "e", { +/******/ enumerable: true, +/******/ value: ensure +/******/ }); +/******/ } else { +/******/ fn.e = ensure; +/******/ } +/******/ return fn; +/******/ } +/******/ +/******/ function hotCreateModule(moduleId) { // eslint-disable-line no-unused-vars +/******/ var hot = { +/******/ // private stuff +/******/ _acceptedDependencies: {}, +/******/ _declinedDependencies: {}, +/******/ _selfAccepted: false, +/******/ _selfDeclined: false, +/******/ _disposeHandlers: [], +/******/ +/******/ // Module API +/******/ active: true, +/******/ accept: function(dep, callback) { +/******/ if(typeof dep === "undefined") +/******/ hot._selfAccepted = true; +/******/ else if(typeof dep === "function") +/******/ hot._selfAccepted = dep; +/******/ else if(typeof dep === "object") +/******/ for(var i = 0; i < dep.length; i++) +/******/ hot._acceptedDependencies[dep[i]] = callback; +/******/ else +/******/ hot._acceptedDependencies[dep] = callback; +/******/ }, +/******/ decline: function(dep) { +/******/ if(typeof dep === "undefined") +/******/ hot._selfDeclined = true; +/******/ else if(typeof dep === "number") +/******/ hot._declinedDependencies[dep] = true; +/******/ else +/******/ for(var i = 0; i < dep.length; i++) +/******/ hot._declinedDependencies[dep[i]] = true; +/******/ }, +/******/ dispose: function(callback) { +/******/ hot._disposeHandlers.push(callback); +/******/ }, +/******/ addDisposeHandler: function(callback) { +/******/ hot._disposeHandlers.push(callback); +/******/ }, +/******/ removeDisposeHandler: function(callback) { +/******/ var idx = hot._disposeHandlers.indexOf(callback); +/******/ if(idx >= 0) hot._disposeHandlers.splice(idx, 1); +/******/ }, +/******/ +/******/ // Management API +/******/ check: hotCheck, +/******/ apply: hotApply, +/******/ status: function(l) { +/******/ if(!l) return hotStatus; +/******/ hotStatusHandlers.push(l); +/******/ }, +/******/ addStatusHandler: function(l) { +/******/ hotStatusHandlers.push(l); +/******/ }, +/******/ removeStatusHandler: function(l) { +/******/ var idx = hotStatusHandlers.indexOf(l); +/******/ if(idx >= 0) hotStatusHandlers.splice(idx, 1); +/******/ }, +/******/ +/******/ //inherit from previous dispose call +/******/ data: hotCurrentModuleData[moduleId] +/******/ }; +/******/ return hot; +/******/ } +/******/ +/******/ var hotStatusHandlers = []; +/******/ var hotStatus = "idle"; +/******/ +/******/ function hotSetStatus(newStatus) { +/******/ hotStatus = newStatus; +/******/ for(var i = 0; i < hotStatusHandlers.length; i++) +/******/ hotStatusHandlers[i].call(null, newStatus); +/******/ } +/******/ +/******/ // while downloading +/******/ var hotWaitingFiles = 0; +/******/ var hotChunksLoading = 0; +/******/ var hotWaitingFilesMap = {}; +/******/ var hotRequestedFilesMap = {}; +/******/ var hotAvailibleFilesMap = {}; +/******/ var hotCallback; +/******/ +/******/ // The update info +/******/ var hotUpdate, hotUpdateNewHash; +/******/ +/******/ function toModuleId(id) { +/******/ var isNumber = (+id) + "" === id; +/******/ return isNumber ? +id : id; +/******/ } +/******/ +/******/ function hotCheck(apply, callback) { +/******/ if(hotStatus !== "idle") throw new Error("check() is only allowed in idle status"); +/******/ if(typeof apply === "function") { +/******/ hotApplyOnUpdate = false; +/******/ callback = apply; +/******/ } else { +/******/ hotApplyOnUpdate = apply; +/******/ callback = callback || function(err) { +/******/ if(err) throw err; +/******/ }; +/******/ } +/******/ hotSetStatus("check"); +/******/ hotDownloadManifest(function(err, update) { +/******/ if(err) return callback(err); +/******/ if(!update) { +/******/ hotSetStatus("idle"); +/******/ callback(null, null); +/******/ return; +/******/ } +/******/ +/******/ hotRequestedFilesMap = {}; +/******/ hotAvailibleFilesMap = {}; +/******/ hotWaitingFilesMap = {}; +/******/ for(var i = 0; i < update.c.length; i++) +/******/ hotAvailibleFilesMap[update.c[i]] = true; +/******/ hotUpdateNewHash = update.h; +/******/ +/******/ hotSetStatus("prepare"); +/******/ hotCallback = callback; +/******/ hotUpdate = {}; +/******/ var chunkId = 0; +/******/ { // eslint-disable-line no-lone-blocks +/******/ /*globals chunkId */ +/******/ hotEnsureUpdateChunk(chunkId); +/******/ } +/******/ if(hotStatus === "prepare" && hotChunksLoading === 0 && hotWaitingFiles === 0) { +/******/ hotUpdateDownloaded(); +/******/ } +/******/ }); +/******/ } +/******/ +/******/ function hotAddUpdateChunk(chunkId, moreModules) { // eslint-disable-line no-unused-vars +/******/ if(!hotAvailibleFilesMap[chunkId] || !hotRequestedFilesMap[chunkId]) +/******/ return; +/******/ hotRequestedFilesMap[chunkId] = false; +/******/ for(var moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ hotUpdate[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(--hotWaitingFiles === 0 && hotChunksLoading === 0) { +/******/ hotUpdateDownloaded(); +/******/ } +/******/ } +/******/ +/******/ function hotEnsureUpdateChunk(chunkId) { +/******/ if(!hotAvailibleFilesMap[chunkId]) { +/******/ hotWaitingFilesMap[chunkId] = true; +/******/ } else { +/******/ hotRequestedFilesMap[chunkId] = true; +/******/ hotWaitingFiles++; +/******/ hotDownloadUpdateChunk(chunkId); +/******/ } +/******/ } +/******/ +/******/ function hotUpdateDownloaded() { +/******/ hotSetStatus("ready"); +/******/ var callback = hotCallback; +/******/ hotCallback = null; +/******/ if(!callback) return; +/******/ if(hotApplyOnUpdate) { +/******/ hotApply(hotApplyOnUpdate, callback); +/******/ } else { +/******/ var outdatedModules = []; +/******/ for(var id in hotUpdate) { +/******/ if(Object.prototype.hasOwnProperty.call(hotUpdate, id)) { +/******/ outdatedModules.push(toModuleId(id)); +/******/ } +/******/ } +/******/ callback(null, outdatedModules); +/******/ } +/******/ } +/******/ +/******/ function hotApply(options, callback) { +/******/ if(hotStatus !== "ready") throw new Error("apply() is only allowed in ready status"); +/******/ if(typeof options === "function") { +/******/ callback = options; +/******/ options = {}; +/******/ } else if(options && typeof options === "object") { +/******/ callback = callback || function(err) { +/******/ if(err) throw err; +/******/ }; +/******/ } else { +/******/ options = {}; +/******/ callback = callback || function(err) { +/******/ if(err) throw err; +/******/ }; +/******/ } +/******/ +/******/ function getAffectedStuff(module) { +/******/ var outdatedModules = [module]; +/******/ var outdatedDependencies = {}; +/******/ +/******/ var queue = outdatedModules.slice(); +/******/ while(queue.length > 0) { +/******/ var moduleId = queue.pop(); +/******/ var module = installedModules[moduleId]; +/******/ if(!module || module.hot._selfAccepted) +/******/ continue; +/******/ if(module.hot._selfDeclined) { +/******/ return new Error("Aborted because of self decline: " + moduleId); +/******/ } +/******/ if(moduleId === 0) { +/******/ return; +/******/ } +/******/ for(var i = 0; i < module.parents.length; i++) { +/******/ var parentId = module.parents[i]; +/******/ var parent = installedModules[parentId]; +/******/ if(parent.hot._declinedDependencies[moduleId]) { +/******/ return new Error("Aborted because of declined dependency: " + moduleId + " in " + parentId); +/******/ } +/******/ if(outdatedModules.indexOf(parentId) >= 0) continue; +/******/ if(parent.hot._acceptedDependencies[moduleId]) { +/******/ if(!outdatedDependencies[parentId]) +/******/ outdatedDependencies[parentId] = []; +/******/ addAllToSet(outdatedDependencies[parentId], [moduleId]); +/******/ continue; +/******/ } +/******/ delete outdatedDependencies[parentId]; +/******/ outdatedModules.push(parentId); +/******/ queue.push(parentId); +/******/ } +/******/ } +/******/ +/******/ return [outdatedModules, outdatedDependencies]; +/******/ } +/******/ +/******/ function addAllToSet(a, b) { +/******/ for(var i = 0; i < b.length; i++) { +/******/ var item = b[i]; +/******/ if(a.indexOf(item) < 0) +/******/ a.push(item); +/******/ } +/******/ } +/******/ +/******/ // at begin all updates modules are outdated +/******/ // the "outdated" status can propagate to parents if they don't accept the children +/******/ var outdatedDependencies = {}; +/******/ var outdatedModules = []; +/******/ var appliedUpdate = {}; +/******/ for(var id in hotUpdate) { +/******/ if(Object.prototype.hasOwnProperty.call(hotUpdate, id)) { +/******/ var moduleId = toModuleId(id); +/******/ var result = getAffectedStuff(moduleId); +/******/ if(!result) { +/******/ if(options.ignoreUnaccepted) +/******/ continue; +/******/ hotSetStatus("abort"); +/******/ return callback(new Error("Aborted because " + moduleId + " is not accepted")); +/******/ } +/******/ if(result instanceof Error) { +/******/ hotSetStatus("abort"); +/******/ return callback(result); +/******/ } +/******/ appliedUpdate[moduleId] = hotUpdate[moduleId]; +/******/ addAllToSet(outdatedModules, result[0]); +/******/ for(var moduleId in result[1]) { +/******/ if(Object.prototype.hasOwnProperty.call(result[1], moduleId)) { +/******/ if(!outdatedDependencies[moduleId]) +/******/ outdatedDependencies[moduleId] = []; +/******/ addAllToSet(outdatedDependencies[moduleId], result[1][moduleId]); +/******/ } +/******/ } +/******/ } +/******/ } +/******/ +/******/ // Store self accepted outdated modules to require them later by the module system +/******/ var outdatedSelfAcceptedModules = []; +/******/ for(var i = 0; i < outdatedModules.length; i++) { +/******/ var moduleId = outdatedModules[i]; +/******/ if(installedModules[moduleId] && installedModules[moduleId].hot._selfAccepted) +/******/ outdatedSelfAcceptedModules.push({ +/******/ module: moduleId, +/******/ errorHandler: installedModules[moduleId].hot._selfAccepted +/******/ }); +/******/ } +/******/ +/******/ // Now in "dispose" phase +/******/ hotSetStatus("dispose"); +/******/ var queue = outdatedModules.slice(); +/******/ while(queue.length > 0) { +/******/ var moduleId = queue.pop(); +/******/ var module = installedModules[moduleId]; +/******/ if(!module) continue; +/******/ +/******/ var data = {}; +/******/ +/******/ // Call dispose handlers +/******/ var disposeHandlers = module.hot._disposeHandlers; +/******/ for(var j = 0; j < disposeHandlers.length; j++) { +/******/ var cb = disposeHandlers[j]; +/******/ cb(data); +/******/ } +/******/ hotCurrentModuleData[moduleId] = data; +/******/ +/******/ // disable module (this disables requires from this module) +/******/ module.hot.active = false; +/******/ +/******/ // remove module from cache +/******/ delete installedModules[moduleId]; +/******/ +/******/ // remove "parents" references from all children +/******/ for(var j = 0; j < module.children.length; j++) { +/******/ var child = installedModules[module.children[j]]; +/******/ if(!child) continue; +/******/ var idx = child.parents.indexOf(moduleId); +/******/ if(idx >= 0) { +/******/ child.parents.splice(idx, 1); +/******/ } +/******/ } +/******/ } +/******/ +/******/ // remove outdated dependency from module children +/******/ for(var moduleId in outdatedDependencies) { +/******/ if(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) { +/******/ var module = installedModules[moduleId]; +/******/ var moduleOutdatedDependencies = outdatedDependencies[moduleId]; +/******/ for(var j = 0; j < moduleOutdatedDependencies.length; j++) { +/******/ var dependency = moduleOutdatedDependencies[j]; +/******/ var idx = module.children.indexOf(dependency); +/******/ if(idx >= 0) module.children.splice(idx, 1); +/******/ } +/******/ } +/******/ } +/******/ +/******/ // Not in "apply" phase +/******/ hotSetStatus("apply"); +/******/ +/******/ hotCurrentHash = hotUpdateNewHash; +/******/ +/******/ // insert new code +/******/ for(var moduleId in appliedUpdate) { +/******/ if(Object.prototype.hasOwnProperty.call(appliedUpdate, moduleId)) { +/******/ modules[moduleId] = appliedUpdate[moduleId]; +/******/ } +/******/ } +/******/ +/******/ // call accept handlers +/******/ var error = null; +/******/ for(var moduleId in outdatedDependencies) { +/******/ if(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) { +/******/ var module = installedModules[moduleId]; +/******/ var moduleOutdatedDependencies = outdatedDependencies[moduleId]; +/******/ var callbacks = []; +/******/ for(var i = 0; i < moduleOutdatedDependencies.length; i++) { +/******/ var dependency = moduleOutdatedDependencies[i]; +/******/ var cb = module.hot._acceptedDependencies[dependency]; +/******/ if(callbacks.indexOf(cb) >= 0) continue; +/******/ callbacks.push(cb); +/******/ } +/******/ for(var i = 0; i < callbacks.length; i++) { +/******/ var cb = callbacks[i]; +/******/ try { +/******/ cb(outdatedDependencies); +/******/ } catch(err) { +/******/ if(!error) +/******/ error = err; +/******/ } +/******/ } +/******/ } +/******/ } +/******/ +/******/ // Load self accepted modules +/******/ for(var i = 0; i < outdatedSelfAcceptedModules.length; i++) { +/******/ var item = outdatedSelfAcceptedModules[i]; +/******/ var moduleId = item.module; +/******/ hotCurrentParents = [moduleId]; +/******/ try { +/******/ __webpack_require__(moduleId); +/******/ } catch(err) { +/******/ if(typeof item.errorHandler === "function") { +/******/ try { +/******/ item.errorHandler(err); +/******/ } catch(err) { +/******/ if(!error) +/******/ error = err; +/******/ } +/******/ } else if(!error) +/******/ error = err; +/******/ } +/******/ } +/******/ +/******/ // handle errors in accept handlers and self accepted module load +/******/ if(error) { +/******/ hotSetStatus("fail"); +/******/ return callback(error); +/******/ } +/******/ +/******/ hotSetStatus("idle"); +/******/ callback(null, outdatedModules); +/******/ } + +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false, +/******/ hot: hotCreateModule(moduleId), +/******/ parents: hotCurrentParents, +/******/ children: [] +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId)); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // __webpack_hash__ +/******/ __webpack_require__.h = function() { return hotCurrentHash; }; + +/******/ // Load entry module and return exports +/******/ return hotCreateRequire(0)(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + var riot = __webpack_require__(1); + // Provide some settings + riot.settings.brackets = '{{ }}'; + // Get application tag and mount it! Yeah baby! + __webpack_require__(3); + riot.mount('app'); + // Router + __webpack_require__(33); + // SASS + __webpack_require__(52); + __webpack_require__(54); + __webpack_require__(56); + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* Riot v2.6.8, @license MIT */ + + ;(function(window, undefined) { + 'use strict'; + var riot = { version: 'v2.6.8', settings: {} }, + // be aware, internal usage + // ATTENTION: prefix the global dynamic variables with `__` + + // counter to give a unique id to all the Tag instances + __uid = 0, + // tags instances cache + __virtualDom = [], + // tags implementation cache + __tagImpl = {}, + + /** + * Const + */ + GLOBAL_MIXIN = '__global_mixin', + + // riot specific prefixes + RIOT_PREFIX = 'riot-', + RIOT_TAG = RIOT_PREFIX + 'tag', + RIOT_TAG_IS = 'data-is', + + // for typeof == '' comparisons + T_STRING = 'string', + T_OBJECT = 'object', + T_UNDEF = 'undefined', + T_FUNCTION = 'function', + XLINK_NS = 'http://www.w3.org/1999/xlink', + XLINK_REGEX = /^xlink:(\w+)/, + // special native tags that cannot be treated like the others + SPECIAL_TAGS_REGEX = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?|opt(?:ion|group))$/, + RESERVED_WORDS_BLACKLIST = /^(?:_(?:item|id|parent)|update|root|(?:un)?mount|mixin|is(?:Mounted|Loop)|tags|parent|opts|trigger|o(?:n|ff|ne))$/, + // SVG tags list https://www.w3.org/TR/SVG/attindex.html#PresentationAttributes + SVG_TAGS_LIST = ['altGlyph', 'animate', 'animateColor', 'circle', 'clipPath', 'defs', 'ellipse', 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feGaussianBlur', 'feImage', 'feMerge', 'feMorphology', 'feOffset', 'feSpecularLighting', 'feTile', 'feTurbulence', 'filter', 'font', 'foreignObject', 'g', 'glyph', 'glyphRef', 'image', 'line', 'linearGradient', 'marker', 'mask', 'missing-glyph', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'svg', 'switch', 'symbol', 'text', 'textPath', 'tref', 'tspan', 'use'], + + // version# for IE 8-11, 0 for others + IE_VERSION = (window && window.document || {}).documentMode | 0, + + // detect firefox to fix #1374 + FIREFOX = window && !!window.InstallTrigger + /* istanbul ignore next */ + riot.observable = function(el) { + + /** + * Extend the original object or create a new empty one + * @type { Object } + */ + + el = el || {} + + /** + * Private variables + */ + var callbacks = {}, + slice = Array.prototype.slice + + /** + * Private Methods + */ + + /** + * Helper function needed to get and loop all the events in a string + * @param { String } e - event string + * @param {Function} fn - callback + */ + function onEachEvent(e, fn) { + var es = e.split(' '), l = es.length, i = 0 + for (; i < l; i++) { + var name = es[i] + if (name) fn(name, i) + } + } + + /** + * Public Api + */ + + // extend the el object adding the observable methods + Object.defineProperties(el, { + /** + * Listen to the given space separated list of `events` and + * execute the `callback` each time an event is triggered. + * @param { String } events - events ids + * @param { Function } fn - callback function + * @returns { Object } el + */ + on: { + value: function(events, fn) { + if (typeof fn != 'function') return el + + onEachEvent(events, function(name, pos) { + (callbacks[name] = callbacks[name] || []).push(fn) + fn.typed = pos > 0 + }) + + return el + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Removes the given space separated list of `events` listeners + * @param { String } events - events ids + * @param { Function } fn - callback function + * @returns { Object } el + */ + off: { + value: function(events, fn) { + if (events == '*' && !fn) callbacks = {} + else { + onEachEvent(events, function(name, pos) { + if (fn) { + var arr = callbacks[name] + for (var i = 0, cb; cb = arr && arr[i]; ++i) { + if (cb == fn) arr.splice(i--, 1) + } + } else delete callbacks[name] + }) + } + return el + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Listen to the given space separated list of `events` and + * execute the `callback` at most once + * @param { String } events - events ids + * @param { Function } fn - callback function + * @returns { Object } el + */ + one: { + value: function(events, fn) { + function on() { + el.off(events, on) + fn.apply(el, arguments) + } + return el.on(events, on) + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Execute all callback functions that listen to + * the given space separated list of `events` + * @param { String } events - events ids + * @returns { Object } el + */ + trigger: { + value: function(events) { + + // getting the arguments + var arglen = arguments.length - 1, + args = new Array(arglen), + fns + + for (var i = 0; i < arglen; i++) { + args[i] = arguments[i + 1] // skip first argument + } + + onEachEvent(events, function(name, pos) { + + fns = slice.call(callbacks[name] || [], 0) + + for (var i = 0, fn; fn = fns[i]; ++i) { + if (fn.busy) continue + fn.busy = 1 + fn.apply(el, fn.typed ? [name].concat(args) : args) + if (fns[i] !== fn) { i-- } + fn.busy = 0 + } + + if (callbacks['*'] && name != '*') + el.trigger.apply(el, ['*', name].concat(args)) + + }) + + return el + }, + enumerable: false, + writable: false, + configurable: false + } + }) + + return el + + } + /* istanbul ignore next */ + ;(function(riot) { + + /** + * Simple client-side router + * @module riot-route + */ + + + var RE_ORIGIN = /^.+?\/\/+[^\/]+/, + EVENT_LISTENER = 'EventListener', + REMOVE_EVENT_LISTENER = 'remove' + EVENT_LISTENER, + ADD_EVENT_LISTENER = 'add' + EVENT_LISTENER, + HAS_ATTRIBUTE = 'hasAttribute', + REPLACE = 'replace', + POPSTATE = 'popstate', + HASHCHANGE = 'hashchange', + TRIGGER = 'trigger', + MAX_EMIT_STACK_LEVEL = 3, + win = typeof window != 'undefined' && window, + doc = typeof document != 'undefined' && document, + hist = win && history, + loc = win && (hist.location || win.location), // see html5-history-api + prot = Router.prototype, // to minify more + clickEvent = doc && doc.ontouchstart ? 'touchstart' : 'click', + started = false, + central = riot.observable(), + routeFound = false, + debouncedEmit, + base, current, parser, secondParser, emitStack = [], emitStackLevel = 0 + + /** + * Default parser. You can replace it via router.parser method. + * @param {string} path - current path (normalized) + * @returns {array} array + */ + function DEFAULT_PARSER(path) { + return path.split(/[/?#]/) + } + + /** + * Default parser (second). You can replace it via router.parser method. + * @param {string} path - current path (normalized) + * @param {string} filter - filter string (normalized) + * @returns {array} array + */ + function DEFAULT_SECOND_PARSER(path, filter) { + var re = new RegExp('^' + filter[REPLACE](/\*/g, '([^/?#]+?)')[REPLACE](/\.\./, '.*') + '$'), + args = path.match(re) + + if (args) return args.slice(1) + } + + /** + * Simple/cheap debounce implementation + * @param {function} fn - callback + * @param {number} delay - delay in seconds + * @returns {function} debounced function + */ + function debounce(fn, delay) { + var t + return function () { + clearTimeout(t) + t = setTimeout(fn, delay) + } + } + + /** + * Set the window listeners to trigger the routes + * @param {boolean} autoExec - see route.start + */ + function start(autoExec) { + debouncedEmit = debounce(emit, 1) + win[ADD_EVENT_LISTENER](POPSTATE, debouncedEmit) + win[ADD_EVENT_LISTENER](HASHCHANGE, debouncedEmit) + doc[ADD_EVENT_LISTENER](clickEvent, click) + if (autoExec) emit(true) + } + + /** + * Router class + */ + function Router() { + this.$ = [] + riot.observable(this) // make it observable + central.on('stop', this.s.bind(this)) + central.on('emit', this.e.bind(this)) + } + + function normalize(path) { + return path[REPLACE](/^\/|\/$/, '') + } + + function isString(str) { + return typeof str == 'string' + } + + /** + * Get the part after domain name + * @param {string} href - fullpath + * @returns {string} path from root + */ + function getPathFromRoot(href) { + return (href || loc.href)[REPLACE](RE_ORIGIN, '') + } + + /** + * Get the part after base + * @param {string} href - fullpath + * @returns {string} path from base + */ + function getPathFromBase(href) { + return base[0] == '#' + ? (href || loc.href || '').split(base)[1] || '' + : (loc ? getPathFromRoot(href) : href || '')[REPLACE](base, '') + } + + function emit(force) { + // the stack is needed for redirections + var isRoot = emitStackLevel == 0, first + if (MAX_EMIT_STACK_LEVEL <= emitStackLevel) return + + emitStackLevel++ + emitStack.push(function() { + var path = getPathFromBase() + if (force || path != current) { + central[TRIGGER]('emit', path) + current = path + } + }) + if (isRoot) { + while (first = emitStack.shift()) first() // stack increses within this call + emitStackLevel = 0 + } + } + + function click(e) { + if ( + e.which != 1 // not left click + || e.metaKey || e.ctrlKey || e.shiftKey // or meta keys + || e.defaultPrevented // or default prevented + ) return + + var el = e.target + while (el && el.nodeName != 'A') el = el.parentNode + + if ( + !el || el.nodeName != 'A' // not A tag + || el[HAS_ATTRIBUTE]('download') // has download attr + || !el[HAS_ATTRIBUTE]('href') // has no href attr + || el.target && el.target != '_self' // another window or frame + || el.href.indexOf(loc.href.match(RE_ORIGIN)[0]) == -1 // cross origin + ) return + + if (el.href != loc.href + && ( + el.href.split('#')[0] == loc.href.split('#')[0] // internal jump + || base[0] != '#' && getPathFromRoot(el.href).indexOf(base) !== 0 // outside of base + || base[0] == '#' && el.href.split(base)[0] != loc.href.split(base)[0] // outside of #base + || !go(getPathFromBase(el.href), el.title || doc.title) // route not found + )) return + + e.preventDefault() + } + + /** + * Go to the path + * @param {string} path - destination path + * @param {string} title - page title + * @param {boolean} shouldReplace - use replaceState or pushState + * @returns {boolean} - route not found flag + */ + function go(path, title, shouldReplace) { + // Server-side usage: directly execute handlers for the path + if (!hist) return central[TRIGGER]('emit', getPathFromBase(path)) + + path = base + normalize(path) + title = title || doc.title + // browsers ignores the second parameter `title` + shouldReplace + ? hist.replaceState(null, title, path) + : hist.pushState(null, title, path) + // so we need to set it manually + doc.title = title + routeFound = false + emit() + return routeFound + } + + /** + * Go to path or set action + * a single string: go there + * two strings: go there with setting a title + * two strings and boolean: replace history with setting a title + * a single function: set an action on the default route + * a string/RegExp and a function: set an action on the route + * @param {(string|function)} first - path / action / filter + * @param {(string|RegExp|function)} second - title / action + * @param {boolean} third - replace flag + */ + prot.m = function(first, second, third) { + if (isString(first) && (!second || isString(second))) go(first, second, third || false) + else if (second) this.r(first, second) + else this.r('@', first) + } + + /** + * Stop routing + */ + prot.s = function() { + this.off('*') + this.$ = [] + } + + /** + * Emit + * @param {string} path - path + */ + prot.e = function(path) { + this.$.concat('@').some(function(filter) { + var args = (filter == '@' ? parser : secondParser)(normalize(path), normalize(filter)) + if (typeof args != 'undefined') { + this[TRIGGER].apply(null, [filter].concat(args)) + return routeFound = true // exit from loop + } + }, this) + } + + /** + * Register route + * @param {string} filter - filter for matching to url + * @param {function} action - action to register + */ + prot.r = function(filter, action) { + if (filter != '@') { + filter = '/' + normalize(filter) + this.$.push(filter) + } + this.on(filter, action) + } + + var mainRouter = new Router() + var route = mainRouter.m.bind(mainRouter) + + /** + * Create a sub router + * @returns {function} the method of a new Router object + */ + route.create = function() { + var newSubRouter = new Router() + // assign sub-router's main method + var router = newSubRouter.m.bind(newSubRouter) + // stop only this sub-router + router.stop = newSubRouter.s.bind(newSubRouter) + return router + } + + /** + * Set the base of url + * @param {(str|RegExp)} arg - a new base or '#' or '#!' + */ + route.base = function(arg) { + base = arg || '#' + current = getPathFromBase() // recalculate current path + } + + /** Exec routing right now **/ + route.exec = function() { + emit(true) + } + + /** + * Replace the default router to yours + * @param {function} fn - your parser function + * @param {function} fn2 - your secondParser function + */ + route.parser = function(fn, fn2) { + if (!fn && !fn2) { + // reset parser for testing... + parser = DEFAULT_PARSER + secondParser = DEFAULT_SECOND_PARSER + } + if (fn) parser = fn + if (fn2) secondParser = fn2 + } + + /** + * Helper function to get url query as an object + * @returns {object} parsed query + */ + route.query = function() { + var q = {} + var href = loc.href || current + href[REPLACE](/[?&](.+?)=([^&]*)/g, function(_, k, v) { q[k] = v }) + return q + } + + /** Stop routing **/ + route.stop = function () { + if (started) { + if (win) { + win[REMOVE_EVENT_LISTENER](POPSTATE, debouncedEmit) + win[REMOVE_EVENT_LISTENER](HASHCHANGE, debouncedEmit) + doc[REMOVE_EVENT_LISTENER](clickEvent, click) + } + central[TRIGGER]('stop') + started = false + } + } + + /** + * Start routing + * @param {boolean} autoExec - automatically exec after starting if true + */ + route.start = function (autoExec) { + if (!started) { + if (win) { + if (document.readyState == 'complete') start(autoExec) + // the timeout is needed to solve + // a weird safari bug https://github.com/riot/route/issues/33 + else win[ADD_EVENT_LISTENER]('load', function() { + setTimeout(function() { start(autoExec) }, 1) + }) + } + started = true + } + } + + /** Prepare the router **/ + route.base() + route.parser() + + riot.route = route + })(riot) + /* istanbul ignore next */ + + /** + * The riot template engine + * @version v2.4.2 + */ + /** + * riot.util.brackets + * + * - `brackets ` - Returns a string or regex based on its parameter + * - `brackets.set` - Change the current riot brackets + * + * @module + */ + + var brackets = (function (UNDEF) { + + var + REGLOB = 'g', + + R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g, + + R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'/g, + + S_QBLOCKS = R_STRINGS.source + '|' + + /(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' + + /\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?(\/)[gim]*/.source, + + UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'), + + NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g, + + FINDBRACES = { + '(': RegExp('([()])|' + S_QBLOCKS, REGLOB), + '[': RegExp('([[\\]])|' + S_QBLOCKS, REGLOB), + '{': RegExp('([{}])|' + S_QBLOCKS, REGLOB) + }, + + DEFAULT = '{ }' + + var _pairs = [ + '{', '}', + '{', '}', + /{[^}]*}/, + /\\([{}])/g, + /\\({)|{/g, + RegExp('\\\\(})|([[({])|(})|' + S_QBLOCKS, REGLOB), + DEFAULT, + /^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/, + /(^|[^\\]){=[\S\s]*?}/ + ] + + var + cachedBrackets = UNDEF, + _regex, + _cache = [], + _settings + + function _loopback (re) { return re } + + function _rewrite (re, bp) { + if (!bp) bp = _cache + return new RegExp( + re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : '' + ) + } + + function _create (pair) { + if (pair === DEFAULT) return _pairs + + var arr = pair.split(' ') + + if (arr.length !== 2 || UNSUPPORTED.test(pair)) { + throw new Error('Unsupported brackets "' + pair + '"') + } + arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' ')) + + arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr) + arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr) + arr[6] = _rewrite(_pairs[6], arr) + arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB) + arr[8] = pair + return arr + } + + function _brackets (reOrIdx) { + return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx] + } + + _brackets.split = function split (str, tmpl, _bp) { + // istanbul ignore next: _bp is for the compiler + if (!_bp) _bp = _cache + + var + parts = [], + match, + isexpr, + start, + pos, + re = _bp[6] + + isexpr = start = re.lastIndex = 0 + + while ((match = re.exec(str))) { + + pos = match.index + + if (isexpr) { + + if (match[2]) { + re.lastIndex = skipBraces(str, match[2], re.lastIndex) + continue + } + if (!match[3]) { + continue + } + } + + if (!match[1]) { + unescapeStr(str.slice(start, pos)) + start = re.lastIndex + re = _bp[6 + (isexpr ^= 1)] + re.lastIndex = start + } + } + + if (str && start < str.length) { + unescapeStr(str.slice(start)) + } + + return parts + + function unescapeStr (s) { + if (tmpl || isexpr) { + parts.push(s && s.replace(_bp[5], '$1')) + } else { + parts.push(s) + } + } + + function skipBraces (s, ch, ix) { + var + match, + recch = FINDBRACES[ch] + + recch.lastIndex = ix + ix = 1 + while ((match = recch.exec(s))) { + if (match[1] && + !(match[1] === ch ? ++ix : --ix)) break + } + return ix ? s.length : recch.lastIndex + } + } + + _brackets.hasExpr = function hasExpr (str) { + return _cache[4].test(str) + } + + _brackets.loopKeys = function loopKeys (expr) { + var m = expr.match(_cache[9]) + + return m + ? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] } + : { val: expr.trim() } + } + + _brackets.array = function array (pair) { + return pair ? _create(pair) : _cache + } + + function _reset (pair) { + if ((pair || (pair = DEFAULT)) !== _cache[8]) { + _cache = _create(pair) + _regex = pair === DEFAULT ? _loopback : _rewrite + _cache[9] = _regex(_pairs[9]) + } + cachedBrackets = pair + } + + function _setSettings (o) { + var b + + o = o || {} + b = o.brackets + Object.defineProperty(o, 'brackets', { + set: _reset, + get: function () { return cachedBrackets }, + enumerable: true + }) + _settings = o + _reset(b) + } + + Object.defineProperty(_brackets, 'settings', { + set: _setSettings, + get: function () { return _settings } + }) + + /* istanbul ignore next: in the browser riot is always in the scope */ + _brackets.settings = typeof riot !== 'undefined' && riot.settings || {} + _brackets.set = _reset + + _brackets.R_STRINGS = R_STRINGS + _brackets.R_MLCOMMS = R_MLCOMMS + _brackets.S_QBLOCKS = S_QBLOCKS + + return _brackets + + })() + + /** + * @module tmpl + * + * tmpl - Root function, returns the template value, render with data + * tmpl.hasExpr - Test the existence of a expression inside a string + * tmpl.loopKeys - Get the keys for an 'each' loop (used by `_each`) + */ + + var tmpl = (function () { + + var _cache = {} + + function _tmpl (str, data) { + if (!str) return str + + return (_cache[str] || (_cache[str] = _create(str))).call(data, _logErr) + } + + _tmpl.haveRaw = brackets.hasRaw + + _tmpl.hasExpr = brackets.hasExpr + + _tmpl.loopKeys = brackets.loopKeys + + // istanbul ignore next + _tmpl.clearCache = function () { _cache = {} } + + _tmpl.errorHandler = null + + function _logErr (err, ctx) { + + if (_tmpl.errorHandler) { + + err.riotData = { + tagName: ctx && ctx.root && ctx.root.tagName, + _riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase + } + _tmpl.errorHandler(err) + } + } + + function _create (str) { + var expr = _getTmpl(str) + + if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr + + return new Function('E', expr + ';') // eslint-disable-line no-new-func + } + + var + CH_IDEXPR = String.fromCharCode(0x2057), + RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/, + RE_QBLOCK = RegExp(brackets.S_QBLOCKS, 'g'), + RE_DQUOTE = /\u2057/g, + RE_QBMARK = /\u2057(\d+)~/g + + function _getTmpl (str) { + var + qstr = [], + expr, + parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1) + + if (parts.length > 2 || parts[0]) { + var i, j, list = [] + + for (i = j = 0; i < parts.length; ++i) { + + expr = parts[i] + + if (expr && (expr = i & 1 + + ? _parseExpr(expr, 1, qstr) + + : '"' + expr + .replace(/\\/g, '\\\\') + .replace(/\r\n?|\n/g, '\\n') + .replace(/"/g, '\\"') + + '"' + + )) list[j++] = expr + + } + + expr = j < 2 ? list[0] + : '[' + list.join(',') + '].join("")' + + } else { + + expr = _parseExpr(parts[1], 0, qstr) + } + + if (qstr[0]) { + expr = expr.replace(RE_QBMARK, function (_, pos) { + return qstr[pos] + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + }) + } + return expr + } + + var + RE_BREND = { + '(': /[()]/g, + '[': /[[\]]/g, + '{': /[{}]/g + } + + function _parseExpr (expr, asText, qstr) { + + expr = expr + .replace(RE_QBLOCK, function (s, div) { + return s.length > 2 && !div ? CH_IDEXPR + (qstr.push(s) - 1) + '~' : s + }) + .replace(/\s+/g, ' ').trim() + .replace(/\ ?([[\({},?\.:])\ ?/g, '$1') + + if (expr) { + var + list = [], + cnt = 0, + match + + while (expr && + (match = expr.match(RE_CSNAME)) && + !match.index + ) { + var + key, + jsb, + re = /,|([[{(])|$/g + + expr = RegExp.rightContext + key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1] + + while (jsb = (match = re.exec(expr))[1]) skipBraces(jsb, re) + + jsb = expr.slice(0, match.index) + expr = RegExp.rightContext + + list[cnt++] = _wrapExpr(jsb, 1, key) + } + + expr = !cnt ? _wrapExpr(expr, asText) + : cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0] + } + return expr + + function skipBraces (ch, re) { + var + mm, + lv = 1, + ir = RE_BREND[ch] + + ir.lastIndex = re.lastIndex + while (mm = ir.exec(expr)) { + if (mm[0] === ch) ++lv + else if (!--lv) break + } + re.lastIndex = lv ? expr.length : ir.lastIndex + } + } + + // istanbul ignore next: not both + var // eslint-disable-next-line max-len + JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').', + JS_VARNAME = /[,{][\$\w]+(?=:)|(^ *|[^$\w\.{])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g, + JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/ + + function _wrapExpr (expr, asText, key) { + var tb + + expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) { + if (mvar) { + pos = tb ? 0 : pos + match.length + + if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') { + match = p + '("' + mvar + JS_CONTEXT + mvar + if (pos) tb = (s = s[pos]) === '.' || s === '(' || s === '[' + } else if (pos) { + tb = !JS_NOPROPS.test(s.slice(pos)) + } + } + return match + }) + + if (tb) { + expr = 'try{return ' + expr + '}catch(e){E(e,this)}' + } + + if (key) { + + expr = (tb + ? 'function(){' + expr + '}.call(this)' : '(' + expr + ')' + ) + '?"' + key + '":""' + + } else if (asText) { + + expr = 'function(v){' + (tb + ? expr.replace('return ', 'v=') : 'v=(' + expr + ')' + ) + ';return v||v===0?v:""}.call(this)' + } + + return expr + } + + _tmpl.version = brackets.version = 'v2.4.2' + + return _tmpl + + })() + + /* + lib/browser/tag/mkdom.js + + Includes hacks needed for the Internet Explorer version 9 and below + See: http://kangax.github.io/compat-table/es5/#ie8 + http://codeplanet.io/dropping-ie8/ + */ + var mkdom = (function _mkdom() { + var + reHasYield = /|>([\S\s]*?)<\/yield\s*>|>)/ig, + reYieldSrc = /]*)['"]\s*>([\S\s]*?)<\/yield\s*>/ig, + reYieldDest = /|>([\S\s]*?)<\/yield\s*>)/ig + var + rootEls = { tr: 'tbody', th: 'tr', td: 'tr', col: 'colgroup' }, + tblTags = IE_VERSION && IE_VERSION < 10 + ? SPECIAL_TAGS_REGEX : /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?)$/ + + /** + * Creates a DOM element to wrap the given content. Normally an `DIV`, but can be + * also a `TABLE`, `SELECT`, `TBODY`, `TR`, or `COLGROUP` element. + * + * @param { String } templ - The template coming from the custom tag definition + * @param { String } [html] - HTML content that comes from the DOM element where you + * will mount the tag, mostly the original tag in the page + * @param { Boolean } checkSvg - flag needed to know if we need to force the svg rendering in case of loop nodes + * @returns {HTMLElement} DOM element with _templ_ merged through `YIELD` with the _html_. + */ + function _mkdom(templ, html, checkSvg) { + var + match = templ && templ.match(/^\s*<([-\w]+)/), + tagName = match && match[1].toLowerCase(), + el = mkEl('div', checkSvg && isSVGTag(tagName)) + + // replace all the yield tags with the tag inner html + templ = replaceYield(templ, html) + + /* istanbul ignore next */ + if (tblTags.test(tagName)) + el = specialTags(el, templ, tagName) + else + setInnerHTML(el, templ) + + el.stub = true + + return el + } + + /* + Creates the root element for table or select child elements: + tr/th/td/thead/tfoot/tbody/caption/col/colgroup/option/optgroup + */ + function specialTags(el, templ, tagName) { + var + select = tagName[0] === 'o', + parent = select ? 'select>' : 'table>' + + // trim() is important here, this ensures we don't have artifacts, + // so we can check if we have only one element inside the parent + el.innerHTML = '<' + parent + templ.trim() + ' j) { + t = tags[--i] + tags.splice(i, 1) + t.unmount() + } + } + + /** + * Move the nested custom tags in non custom loop tags + * @param { Object } child - non custom loop tag + * @param { Number } i - current position of the loop tag + */ + function moveNestedTags(child, i) { + Object.keys(child.tags).forEach(function(tagName) { + var tag = child.tags[tagName] + if (isArray(tag)) + each(tag, function (t) { + moveChildTag(t, tagName, i) + }) + else + moveChildTag(tag, tagName, i) + }) + } + + /** + * Adds the elements for a virtual tag + * @param { Tag } tag - the tag whose root's children will be inserted or appended + * @param { Node } src - the node that will do the inserting or appending + * @param { Tag } target - only if inserting, insert before this tag's first child + */ + function addVirtual(tag, src, target) { + var el = tag._root, sib + tag._virts = [] + while (el) { + sib = el.nextSibling + if (target) + src.insertBefore(el, target._root) + else + src.appendChild(el) + + tag._virts.push(el) // hold for unmounting + el = sib + } + } + + /** + * Move virtual tag and all child nodes + * @param { Tag } tag - first child reference used to start move + * @param { Node } src - the node that will do the inserting + * @param { Tag } target - insert before this tag's first child + * @param { Number } len - how many child nodes to move + */ + function moveVirtual(tag, src, target, len) { + var el = tag._root, sib, i = 0 + for (; i < len; i++) { + sib = el.nextSibling + src.insertBefore(el, target._root) + el = sib + } + } + + /** + * Insert a new tag avoiding the insert for the conditional tags + * @param {Boolean} isVirtual [description] + * @param { Tag } prevTag - tag instance used as reference to prepend our new tag + * @param { Tag } newTag - new tag to be inserted + * @param { HTMLElement } root - loop parent node + * @param { Array } tags - array containing the current tags list + * @param { Function } virtualFn - callback needed to move or insert virtual DOM + * @param { Object } dom - DOM node we need to loop + */ + function insertTag(isVirtual, prevTag, newTag, root, tags, virtualFn, dom) { + if (isInStub(prevTag.root)) return + if (isVirtual) virtualFn(prevTag, root, newTag, dom.childNodes.length) + else root.insertBefore(prevTag.root, newTag.root) // #1374 some browsers reset selected here + } + + + /** + * Manage tags having the 'each' + * @param { Object } dom - DOM node we need to loop + * @param { Tag } parent - parent tag instance where the dom node is contained + * @param { String } expr - string contained in the 'each' attribute + */ + function _each(dom, parent, expr) { + + // remove the each property from the original tag + remAttr(dom, 'each') + + var mustReorder = typeof getAttr(dom, 'no-reorder') !== T_STRING || remAttr(dom, 'no-reorder'), + tagName = getTagName(dom), + impl = __tagImpl[tagName] || { tmpl: getOuterHTML(dom) }, + useRoot = SPECIAL_TAGS_REGEX.test(tagName), + root = dom.parentNode, + ref = document.createTextNode(''), + child = getTag(dom), + isOption = tagName.toLowerCase() === 'option', // the option tags must be treated differently + tags = [], + oldItems = [], + hasKeys, + isVirtual = dom.tagName == 'VIRTUAL' + + // parse the each expression + expr = tmpl.loopKeys(expr) + + // insert a marked where the loop tags will be injected + root.insertBefore(ref, dom) + + // clean template code + parent.one('before-mount', function () { + + // remove the original DOM node + dom.parentNode.removeChild(dom) + if (root.stub) root = parent.root + + }).on('update', function () { + // get the new items collection + var items = tmpl(expr.val, parent), + // create a fragment to hold the new DOM nodes to inject in the parent tag + frag = document.createDocumentFragment() + + // object loop. any changes cause full redraw + if (!isArray(items)) { + hasKeys = items || false + items = hasKeys ? + Object.keys(items).map(function (key) { + return mkitem(expr, key, items[key]) + }) : [] + } + + // loop all the new items + var i = 0, + itemsLength = items.length + + for (; i < itemsLength; i++) { + // reorder only if the items are objects + var + item = items[i], + _mustReorder = mustReorder && typeof item == T_OBJECT && !hasKeys, + oldPos = oldItems.indexOf(item), + pos = ~oldPos && _mustReorder ? oldPos : i, + // does a tag exist in this position? + tag = tags[pos] + + item = !hasKeys && expr.key ? mkitem(expr, item, i) : item + + // new tag + if ( + !_mustReorder && !tag // with no-reorder we just update the old tags + || + _mustReorder && !~oldPos || !tag // by default we always try to reorder the DOM elements + ) { + + tag = new Tag(impl, { + parent: parent, + isLoop: true, + hasImpl: !!__tagImpl[tagName], + root: useRoot ? root : dom.cloneNode(), + item: item + }, dom.innerHTML) + + tag.mount() + + if (isVirtual) tag._root = tag.root.firstChild // save reference for further moves or inserts + // this tag must be appended + if (i == tags.length || !tags[i]) { // fix 1581 + if (isVirtual) + addVirtual(tag, frag) + else frag.appendChild(tag.root) + } + // this tag must be insert + else { + insertTag(isVirtual, tag, tags[i], root, tags, addVirtual, dom) + oldItems.splice(i, 0, item) + } + + tags.splice(i, 0, tag) + pos = i // handled here so no move + } else tag.update(item, true) + + // reorder the tag if it's not located in its previous position + if ( + pos !== i && _mustReorder && + tags[i] // fix 1581 unable to reproduce it in a test! + ) { + // #closes 2040 PLEASE DON'T REMOVE IT! + // there are no tests for this feature + if (contains(items, oldItems[i])) + insertTag(isVirtual, tag, tags[i], root, tags, moveVirtual, dom) + + // update the position attribute if it exists + if (expr.pos) + tag[expr.pos] = i + // move the old tag instance + tags.splice(i, 0, tags.splice(pos, 1)[0]) + // move the old item + oldItems.splice(i, 0, oldItems.splice(pos, 1)[0]) + // if the loop tags are not custom + // we need to move all their custom tags into the right position + if (!child && tag.tags) moveNestedTags(tag, i) + } + + // cache the original item to use it in the events bound to this node + // and its children + tag._item = item + // cache the real parent tag internally + defineProperty(tag, '_parent', parent) + } + + // remove the redundant tags + unmountRedundant(items, tags) + + // insert the new nodes + root.insertBefore(frag, ref) + if (isOption) { + + // #1374 FireFox bug in