diff --git a/css/003-sugarcube-overwrite/general.css b/css/003-sugarcube-overwrite/general.css index f56e07d0bef13e8d74659df813020796984f5728..9600307bfb2f4c9fac4970bbbb3ffeaaf6c662fc 100644 --- a/css/003-sugarcube-overwrite/general.css +++ b/css/003-sugarcube-overwrite/general.css @@ -41,3 +41,8 @@ hr { .passage button:hover { background-color: var(--button-hover-color); } + +select { + padding-top: 0.4em; + padding-bottom: 0.4em; +} diff --git a/css/icons/README.md b/css/icons/README.md deleted file mode 100644 index b239f6f0d2a069b02d88960dd24d3439f128f8be..0000000000000000000000000000000000000000 --- a/css/icons/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# FC custom icon fonts - -__Warning:__ These fonts have slightly different dimensions than the SC inbuilt ones have. This is especially noticeable when replacing icons. - - -## Add new icons - -To add new icons create a new font with your new icons. - -1. Copy an existing font CSS file and name it. -2. Change the `font-family` property in your new file. -3. Download SVG file(s) from Awesome Icons (or other sources). -4. Use https://glyphter.com/ to create WOFF file. - * Default settings are fine. -5. On Linux: - * Run `base64 <FILE>.woff > font.base64` -6. Open with preferred text editor - 1. Delete any line breaks or spaces - 2. Copy everything and replace the Base64 data in your new CSS font-face. -7. Done. diff --git a/css/icons/empty_star.css b/css/icons/empty_star.css deleted file mode 100644 index 4be934e2f7751b9c43346c6822cb60bd879a1cc3..0000000000000000000000000000000000000000 --- a/css/icons/empty_star.css +++ /dev/null @@ -1,16 +0,0 @@ -@font-face { - /* Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc. */ - /* Generated by Glyphter (http://www.glyphter.com) */ - /* - Codes: - Solid star: 0x41 - Empty star: 0x42 - */ - font-family: fc-star-font; - font-display: block; - src: url("data:application/octet-stream;base64,d09GRgABAAAAAAScAAoAAAAABvgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAAA9AAAAD4AAABWVrVjNGNtYXAAAAE0AAAAPgAAAUoClQF3Z2x5ZgAAAXQAAAE3AAABTFJXHAZoZWFkAAACrAAAADEAAAA2KVReHGhoZWEAAALgAAAAHAAAACQIZAP+aG10eAAAAvwAAAAMAAAADAwAAABsb2NhAAADCAAAAAgAAAAIAEAApm1heHAAAAMQAAAAHgAAACABDwBKbmFtZQAAAzAAAAFQAAACnUUcl7pwb3N0AAAEgAAAABkAAAAsAREBA3icY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGBwYHBmcWEDcGBaIMCOIAACX0gedAAB4nGNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZiALKf//8EqHEH0/wNQ9UDAyMZAOWBkooIhAwcAtlIHCgAAeJwNjr1OwlAYhs/3nXLs76GHhtNSQ5ECNhAsxCbWxXIjziYO3IGOXdm9APRWCCEODHAFGHQwYSFhsNjkfaZneF4C5z9CFEoPpEsIxBCyC1rhKFtAWYATcGWGEU2zUkU9OsZ7NegG6mvxU/MN1VyOqNXs2KeT3WladLQ0VcOvFd8v9NN2HPtMBuiGbWtR7ES7jmqeqyivBFwurHbo4gAIIXguyj6W/R55KB/cStepBMiq4EiOUa/CYkydKIYM0p6TQTKul66cK6uQ3rUgup6UjGCMhEuWQ587GtO3CerSN4tjcTR9qWOy1ZnmcOjnTHJ2kxje7l0o0UrKVaSIjy/PeKIHbha/QxR+Q9sUa6thA5vNGNqeBfFGa/gCh1Az+Zv1+CyVcC68/dQwpntPzENFrgn5B5r3QZkAeJxjYGRgYABi59fdHfH8Nl8ZuFkYQOCxNM90GP3/LwMDCzPzRyCXg4EJJAoAJjYKNQAAAHicY2BkYGBhAIIYEPn/FwsbAyMDKmAGADYlAm0EAAAABAAAAAQAAAAAAAAAAEAApnicY2BkYGBgZrBjYGIAARDJBYQMDP/BfAYADtcBWgAAeJx9j7lOw0AURa+zIRJEAQpKOTQIEdlZRJUKCSku6FKE2nHGWeTY1ngSKS3/QMHX8Bl0dHwGEjfOKwJSsPU85963+A2AC3zCwf5pMvbs4IxqzyWc4Fq4TP9WuEK+F66igQfhGv0n4TraeBZu4BIvnOBUTqnu8CrsoIV34RLO8SFcpv8lXCF/C1dx5TSFa2g5beE6xs6jcAM3zpuvE20Cq6dqslV+vM3mVpsodHMbGDdKEzvSs3Uc/LIOeaxNvkgT1fO6h/avsflm1rc2UpFJV2rIrI7jVGUmXerQenNrs0GnE4nvhekKPjQShkEAy3MKhQm2/PqIeWaYF75BhBAucqqAyqVO2WkxYnaGNauDf6qO+eNido5FoRV68NA9Wn182xwbbtGnu/uXYhj2rEhD6dXcMCYr3mmXW9IJ6XvFDS3dATp8oz/1Hqs46QeoJHpleJxjYGKAAC4G7ICZgYGRiZEZxAQAAiwAFwAAAA==") format("woff"); -} - -.icons-star { - font-family: 'fc-star-font'; -} diff --git a/css/icons/unicode_icons.css b/css/icons/unicode_icons.css new file mode 100644 index 0000000000000000000000000000000000000000..b4f13f3a15ab50a24af76fb0b23a8a48db22919f --- /dev/null +++ b/css/icons/unicode_icons.css @@ -0,0 +1,4 @@ +/* Scale Font up, since some Unicode Icons are a bit small (depending on font) */ +.unicode-icons { + font-size: 1.5em; +} diff --git a/devNotes/sugarcube stuff/sugarcube-fc-changes.patch b/devNotes/sugarcube stuff/sugarcube-fc-changes.patch index 35f91e3d91adcceed1ad0b5c0c286b44cfee89ca..48d4e7d7efd09ad994ef9fe8c214950e977a6c8e 100644 --- a/devNotes/sugarcube stuff/sugarcube-fc-changes.patch +++ b/devNotes/sugarcube stuff/sugarcube-fc-changes.patch @@ -384,10 +384,10 @@ index 8e2d05a..d0bb5a2 100644 diff --git a/src/idb_backend.js b/src/idb_backend.js new file mode 100644 -index 0000000..84ce1d9 +index 0000000..1780ec4 --- /dev/null +++ b/src/idb_backend.js -@@ -0,0 +1,1466 @@ +@@ -0,0 +1,1469 @@ +/* eslint no-undef: "off", no-param-reassign: "off", no-alert: "off", no-fallthrough: "off", no-dupe-args: "warn", no-irregular-whitespace: "warn", max-len: "off", key-spacing: ["warn", {beforeColon: false, afterColon: true}], comma-dangle: ["warn", "always-multiline"], quotes: ["warn", "double"], indent: ["warn", "tab", {SwitchCase: 1}], id-length: "off", brace-style: ["warn", "1tbs"] */ + +/* @@ -1156,7 +1156,10 @@ index 0000000..84ce1d9 + `${L10n.get("textSave")}\u2026`, + L10n.get("savesLabelDiskSave"), + typeof Config.saves.isAllowed !== "function" || Config.saves.isAllowed(Save.Type.Disk) -+ ? () => Save.disk.save(Story.name) ++ ? () => { ++ Save.disk.save(Story.name); ++ Dialog.close(); ++ } + : null, + )) + .append(createActionItem( @@ -2405,7 +2408,7 @@ index ef475a2..50de80b 100644 // Activate the new top moment. diff --git a/src/storage/adapters/FCHost.Storage.js b/src/storage/adapters/FCHost.Storage.js new file mode 100644 -index 0000000..b22446d +index 0000000..e48a6c8 --- /dev/null +++ b/src/storage/adapters/FCHost.Storage.js @@ -0,0 +1,171 @@ @@ -2417,7 +2420,7 @@ index 0000000..b22446d + Use of this source code is governed by a BSD 2-clause "Simplified" License, which may be found in the LICENSE file. + +***********************************************************************************************************************/ -+/* global SimpleStore, Util */ ++/* global SimpleStore, Serial */ + +SimpleStore.adapters.push((() => { + 'use strict'; @@ -2534,11 +2537,11 @@ index 0000000..b22446d + } + + static _serialize(obj) { -+ return JSON.stringify(obj); ++ return Serial.stringify(obj); + } + + static _deserialize(str) { -+ return JSON.parse(str); ++ return Serial.parse(str); + } + } + diff --git a/devTools/dictionaries/misc.txt b/devTools/dictionaries/misc.txt index 607e433212f6f097d38de4ac30a57377314ca728..4dac21b18d7d7a4cfb932ebc529552146cd87d92 100644 --- a/devTools/dictionaries/misc.txt +++ b/devTools/dictionaries/misc.txt @@ -1,3 +1,4 @@ +Engineerix orthodontal SDXL swinir diff --git a/devTools/tweeGo/storyFormats/sugarcube-2/format.js b/devTools/tweeGo/storyFormats/sugarcube-2/format.js index e5ddc82962c254b96ac14879a6e8021cd4e06eb9..668fb557c7c8943e79c0cc50d7ca7af1ccca2fc0 100644 --- a/devTools/tweeGo/storyFormats/sugarcube-2/format.js +++ b/devTools/tweeGo/storyFormats/sugarcube-2/format.js @@ -1 +1 @@ -window.storyFormat({"name":"SugarCube","version":"2.37.3","description":"A full featured, highly customizable story format. See its <a href=\"http://www.motoslave.net/sugarcube/2/#documentation\" target=\"_blank\">documentation</a>.","author":"Thomas Michael Edwards","image":"icon.svg","url":"http://www.motoslave.net/sugarcube/","license":"BSD-2-Clause","proofing":false,"source":"<!DOCTYPE html>\n<html data-init=\"no-js\">\n<head>\n<meta charset=\"UTF-8\" />\n<title>{{STORY_NAME}}</title>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n<meta name=\"application-name\" content=\"SugarCube\" />\n<meta name=\"version\" content=\"2.37.3\" />\n<!--\n\nSugarCube (v2.37.3): A free (gratis and libre) story format.\n\nCopyright © 2013–2021 Thomas Michael Edwards <thomasmedwards@gmail.com>.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n-->\n<script id=\"script-libraries\" type=\"text/javascript\">\nif(document.head&&document.addEventListener&&document.querySelector&&Object.create&&Object.freeze&&JSON){document.documentElement.setAttribute(\"data-init\", \"loading\");\n/*! @source http://purl.eligrey.com/github/classList.js/blob/1.2.20171210/classList.js */\n\"document\"in self&&(\"classList\"in document.createElement(\"_\")&&(!document.createElementNS||\"classList\"in document.createElementNS(\"http://www.w3.org/2000/svg\",\"g\"))||!function(t){\"use strict\";if(\"Element\"in t){var e=\"classList\",n=\"prototype\",i=t.Element[n],s=Object,r=String[n].trim||function(){return this.replace(/^\\s+|\\s+$/g,\"\")},o=Array[n].indexOf||function(t){for(var e=0,n=this.length;n>e;e++)if(e in this&&this[e]===t)return e;return-1},c=function(t,e){this.name=t,this.code=DOMException[t],this.message=e},a=function(t,e){if(\"\"===e)throw new c(\"SYNTAX_ERR\",\"The token must not be empty.\");if(/\\s/.test(e))throw new c(\"INVALID_CHARACTER_ERR\",\"The token must not contain space characters.\");return o.call(t,e)},l=function(t){for(var e=r.call(t.getAttribute(\"class\")||\"\"),n=e?e.split(/\\s+/):[],i=0,s=n.length;s>i;i++)this.push(n[i]);this._updateClassName=function(){t.setAttribute(\"class\",this.toString())}},u=l[n]=[],h=function(){return new l(this)};if(c[n]=Error[n],u.item=function(t){return this[t]||null},u.contains=function(t){return~a(this,t+\"\")},u.add=function(){var t,e=arguments,n=0,i=e.length,s=!1;do t=e[n]+\"\",~a(this,t)||(this.push(t),s=!0);while(++n<i);s&&this._updateClassName()},u.remove=function(){var t,e,n=arguments,i=0,s=n.length,r=!1;do for(t=n[i]+\"\",e=a(this,t);~e;)this.splice(e,1),r=!0,e=a(this,t);while(++i<s);r&&this._updateClassName()},u.toggle=function(t,e){var n=this.contains(t),i=n?e!==!0&&\"remove\":e!==!1&&\"add\";return i&&this[i](t),e===!0||e===!1?e:!n},u.replace=function(t,e){var n=a(t+\"\");~n&&(this.splice(n,1,e),this._updateClassName())},u.toString=function(){return this.join(\" \")},s.defineProperty){var f={get:h,enumerable:!0,configurable:!0};try{s.defineProperty(i,e,f)}catch(p){void 0!==p.number&&-2146823252!==p.number||(f.enumerable=!1,s.defineProperty(i,e,f))}}else s[n].__defineGetter__&&i.__defineGetter__(e,h)}}(self),function(){\"use strict\";var t=document.createElement(\"_\");if(t.classList.add(\"c1\",\"c2\"),!t.classList.contains(\"c2\")){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var n,i=arguments.length;for(n=0;i>n;n++)t=arguments[n],e.call(this,t)}};e(\"add\"),e(\"remove\")}if(t.classList.toggle(\"c3\",!1),t.classList.contains(\"c3\")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(t,e){return 1 in arguments&&!this.contains(t)==!e?e:n.call(this,t)}}\"replace\"in document.createElement(\"_\").classList||(DOMTokenList.prototype.replace=function(t,e){var n=this.toString().split(\" \"),i=n.indexOf(t+\"\");~i&&(n=n.slice(i),this.remove.apply(this,n),this.add(e),this.add.apply(this,n.slice(1)))}),t=null}());\n/*!\n * https://github.com/es-shims/es5-shim\n * @license es5-shim Copyright 2009-2020 by contributors, MIT License\n * see https://github.com/es-shims/es5-shim/blob/v4.5.14/LICENSE\n */\n(function(t,r){\"use strict\";if(typeof define===\"function\"&&define.amd){define(r)}else if(typeof exports===\"object\"){module.exports=r()}else{t.returnExports=r()}})(this,function(){var t=Array;var r=t.prototype;var e=Object;var n=e.prototype;var i=Function;var a=i.prototype;var o=String;var f=o.prototype;var u=Number;var l=u.prototype;var s=r.slice;var c=r.splice;var v=r.push;var h=r.unshift;var p=r.concat;var y=r.join;var d=a.call;var g=a.apply;var w=Math.max;var b=Math.min;var T=n.toString;var m=typeof Symbol===\"function\"&&typeof Symbol.toStringTag===\"symbol\";var D;var S=Function.prototype.toString,x=/^\\s*class /,O=function isES6ClassFn(t){try{var r=S.call(t);var e=r.replace(/\\/\\/.*\\n/g,\"\");var n=e.replace(/\\/\\*[.\\s\\S]*\\*\\//g,\"\");var i=n.replace(/\\n/gm,\" \").replace(/ {2}/g,\" \");return x.test(i)}catch(a){return false}},E=function tryFunctionObject(t){try{if(O(t)){return false}S.call(t);return true}catch(r){return false}},j=\"[object Function]\",I=\"[object GeneratorFunction]\",D=function isCallable(t){if(!t){return false}if(typeof t!==\"function\"&&typeof t!==\"object\"){return false}if(m){return E(t)}if(O(t)){return false}var r=T.call(t);return r===j||r===I};var M;var U=RegExp.prototype.exec,$=function tryRegexExec(t){try{U.call(t);return true}catch(r){return false}},F=\"[object RegExp]\";M=function isRegex(t){if(typeof t!==\"object\"){return false}return m?$(t):T.call(t)===F};var N;var C=String.prototype.valueOf,k=function tryStringObject(t){try{C.call(t);return true}catch(r){return false}},A=\"[object String]\";N=function isString(t){if(typeof t===\"string\"){return true}if(typeof t!==\"object\"){return false}return m?k(t):T.call(t)===A};var R=e.defineProperty&&function(){try{var t={};e.defineProperty(t,\"x\",{enumerable:false,value:t});for(var r in t){return false}return t.x===t}catch(n){return false}}();var P=function(t){var r;if(R){r=function(t,r,n,i){if(!i&&r in t){return}e.defineProperty(t,r,{configurable:true,enumerable:false,writable:true,value:n})}}else{r=function(t,r,e,n){if(!n&&r in t){return}t[r]=e}}return function defineProperties(e,n,i){for(var a in n){if(t.call(n,a)){r(e,a,n[a],i)}}}}(n.hasOwnProperty);var J=function isPrimitive(t){var r=typeof t;return t===null||r!==\"object\"&&r!==\"function\"};var Y=u.isNaN||function isActualNaN(t){return t!==t};var z={ToInteger:function ToInteger(t){var r=+t;if(Y(r)){r=0}else if(r!==0&&r!==1/0&&r!==-(1/0)){r=(r>0||-1)*Math.floor(Math.abs(r))}return r},ToPrimitive:function ToPrimitive(t){var r,e,n;if(J(t)){return t}e=t.valueOf;if(D(e)){r=e.call(t);if(J(r)){return r}}n=t.toString;if(D(n)){r=n.call(t);if(J(r)){return r}}throw new TypeError},ToObject:function(t){if(t==null){throw new TypeError(\"can't convert \"+t+\" to object\")}return e(t)},ToUint32:function ToUint32(t){return t>>>0}};var Z=function Empty(){};P(a,{bind:function bind(t){var r=this;if(!D(r)){throw new TypeError(\"Function.prototype.bind called on incompatible \"+r)}var n=s.call(arguments,1);var a;var o=function(){if(this instanceof a){var i=g.call(r,this,p.call(n,s.call(arguments)));if(e(i)===i){return i}return this}else{return g.call(r,t,p.call(n,s.call(arguments)))}};var f=w(0,r.length-n.length);var u=[];for(var l=0;l<f;l++){v.call(u,\"$\"+l)}a=i(\"binder\",\"return function (\"+y.call(u,\",\")+\"){ return binder.apply(this, arguments); }\")(o);if(r.prototype){Z.prototype=r.prototype;a.prototype=new Z;Z.prototype=null}return a}});var G=d.bind(n.hasOwnProperty);var H=d.bind(n.toString);var W=d.bind(s);var B=g.bind(s);if(typeof document===\"object\"&&document&&document.documentElement){try{W(document.documentElement.childNodes)}catch(X){var L=W;var q=B;W=function arraySliceIE(t){var r=[];var e=t.length;while(e-- >0){r[e]=t[e]}return q(r,L(arguments,1))};B=function arraySliceApplyIE(t,r){return q(W(t),r)}}}var K=d.bind(f.slice);var Q=d.bind(f.split);var V=d.bind(f.indexOf);var _=d.bind(v);var tt=d.bind(n.propertyIsEnumerable);var rt=d.bind(r.sort);var et=t.isArray||function isArray(t){return H(t)===\"[object Array]\"};var nt=[].unshift(0)!==1;P(r,{unshift:function(){h.apply(this,arguments);return this.length}},nt);P(t,{isArray:et});var it=e(\"a\");var at=it[0]!==\"a\"||!(0 in it);var ot=function properlyBoxed(t){var r=true;var e=true;var n=false;if(t){try{t.call(\"foo\",function(t,e,n){if(typeof n!==\"object\"){r=false}});t.call([1],function(){\"use strict\";e=typeof this===\"string\"},\"x\")}catch(i){n=true}}return!!t&&!n&&r&&e};P(r,{forEach:function forEach(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=-1;var i=z.ToUint32(e.length);var a;if(arguments.length>1){a=arguments[1]}if(!D(t)){throw new TypeError(\"Array.prototype.forEach callback must be a function\")}while(++n<i){if(n in e){if(typeof a===\"undefined\"){t(e[n],n,r)}else{t.call(a,e[n],n,r)}}}}},!ot(r.forEach));P(r,{map:function map(r){var e=z.ToObject(this);var n=at&&N(this)?Q(this,\"\"):e;var i=z.ToUint32(n.length);var a=t(i);var o;if(arguments.length>1){o=arguments[1]}if(!D(r)){throw new TypeError(\"Array.prototype.map callback must be a function\")}for(var f=0;f<i;f++){if(f in n){if(typeof o===\"undefined\"){a[f]=r(n[f],f,e)}else{a[f]=r.call(o,n[f],f,e)}}}return a}},!ot(r.map));P(r,{filter:function filter(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);var i=[];var a;var o;if(arguments.length>1){o=arguments[1]}if(!D(t)){throw new TypeError(\"Array.prototype.filter callback must be a function\")}for(var f=0;f<n;f++){if(f in e){a=e[f];if(typeof o===\"undefined\"?t(a,f,r):t.call(o,a,f,r)){_(i,a)}}}return i}},!ot(r.filter));P(r,{every:function every(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);var i;if(arguments.length>1){i=arguments[1]}if(!D(t)){throw new TypeError(\"Array.prototype.every callback must be a function\")}for(var a=0;a<n;a++){if(a in e&&!(typeof i===\"undefined\"?t(e[a],a,r):t.call(i,e[a],a,r))){return false}}return true}},!ot(r.every));P(r,{some:function some(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);var i;if(arguments.length>1){i=arguments[1]}if(!D(t)){throw new TypeError(\"Array.prototype.some callback must be a function\")}for(var a=0;a<n;a++){if(a in e&&(typeof i===\"undefined\"?t(e[a],a,r):t.call(i,e[a],a,r))){return true}}return false}},!ot(r.some));var ft=false;if(r.reduce){ft=typeof r.reduce.call(\"es5\",function(t,r,e,n){return n})===\"object\"}P(r,{reduce:function reduce(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);if(!D(t)){throw new TypeError(\"Array.prototype.reduce callback must be a function\")}if(n===0&&arguments.length===1){throw new TypeError(\"reduce of empty array with no initial value\")}var i=0;var a;if(arguments.length>=2){a=arguments[1]}else{do{if(i in e){a=e[i++];break}if(++i>=n){throw new TypeError(\"reduce of empty array with no initial value\")}}while(true)}for(;i<n;i++){if(i in e){a=t(a,e[i],i,r)}}return a}},!ft);var ut=false;if(r.reduceRight){ut=typeof r.reduceRight.call(\"es5\",function(t,r,e,n){return n})===\"object\"}P(r,{reduceRight:function reduceRight(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);if(!D(t)){throw new TypeError(\"Array.prototype.reduceRight callback must be a function\")}if(n===0&&arguments.length===1){throw new TypeError(\"reduceRight of empty array with no initial value\")}var i;var a=n-1;if(arguments.length>=2){i=arguments[1]}else{do{if(a in e){i=e[a--];break}if(--a<0){throw new TypeError(\"reduceRight of empty array with no initial value\")}}while(true)}if(a<0){return i}do{if(a in e){i=t(i,e[a],a,r)}}while(a--);return i}},!ut);var lt=r.indexOf&&[0,1].indexOf(1,2)!==-1;P(r,{indexOf:function indexOf(t){var r=at&&N(this)?Q(this,\"\"):z.ToObject(this);var e=z.ToUint32(r.length);if(e===0){return-1}var n=0;if(arguments.length>1){n=z.ToInteger(arguments[1])}n=n>=0?n:w(0,e+n);for(;n<e;n++){if(n in r&&r[n]===t){return n}}return-1}},lt);var st=r.lastIndexOf&&[0,1].lastIndexOf(0,-3)!==-1;P(r,{lastIndexOf:function lastIndexOf(t){var r=at&&N(this)?Q(this,\"\"):z.ToObject(this);var e=z.ToUint32(r.length);if(e===0){return-1}var n=e-1;if(arguments.length>1){n=b(n,z.ToInteger(arguments[1]))}n=n>=0?n:e-Math.abs(n);for(;n>=0;n--){if(n in r&&t===r[n]){return n}}return-1}},st);var ct=function(){var t=[1,2];var r=t.splice();return t.length===2&&et(r)&&r.length===0}();P(r,{splice:function splice(t,r){if(arguments.length===0){return[]}else{return c.apply(this,arguments)}}},!ct);var vt=function(){var t={};r.splice.call(t,0,0,1);return t.length===1}();P(r,{splice:function splice(t,r){if(arguments.length===0){return[]}var e=arguments;this.length=w(z.ToInteger(this.length),0);if(arguments.length>0&&typeof r!==\"number\"){e=W(arguments);if(e.length<2){_(e,this.length-t)}else{e[1]=z.ToInteger(r)}}return c.apply(this,e)}},!vt);var ht=function(){var r=new t(1e5);r[8]=\"x\";r.splice(1,1);return r.indexOf(\"x\")===7}();var pt=function(){var t=256;var r=[];r[t]=\"a\";r.splice(t+1,0,\"b\");return r[t]===\"a\"}();P(r,{splice:function splice(t,r){var e=z.ToObject(this);var n=[];var i=z.ToUint32(e.length);var a=z.ToInteger(t);var f=a<0?w(i+a,0):b(a,i);var u=arguments.length===0?0:arguments.length===1?i-f:b(w(z.ToInteger(r),0),i-f);var l=0;var s;while(l<u){s=o(f+l);if(G(e,s)){n[l]=e[s]}l+=1}var c=W(arguments,2);var v=c.length;var h;if(v<u){l=f;var p=i-u;while(l<p){s=o(l+u);h=o(l+v);if(G(e,s)){e[h]=e[s]}else{delete e[h]}l+=1}l=i;var y=i-u+v;while(l>y){delete e[l-1];l-=1}}else if(v>u){l=i-u;while(l>f){s=o(l+u-1);h=o(l+v-1);if(G(e,s)){e[h]=e[s]}else{delete e[h]}l-=1}}l=f;for(var d=0;d<c.length;++d){e[l]=c[d];l+=1}e.length=i-u+v;return n}},!ht||!pt);var yt=r.join;var dt;try{dt=Array.prototype.join.call(\"123\",\",\")!==\"1,2,3\"}catch(X){dt=true}if(dt){P(r,{join:function join(t){var r=typeof t===\"undefined\"?\",\":t;return yt.call(N(this)?Q(this,\"\"):this,r)}},dt)}var gt=[1,2].join(undefined)!==\"1,2\";if(gt){P(r,{join:function join(t){var r=typeof t===\"undefined\"?\",\":t;return yt.call(this,r)}},gt)}var wt=function push(t){var r=z.ToObject(this);var e=z.ToUint32(r.length);var n=0;while(n<arguments.length){r[e+n]=arguments[n];n+=1}r.length=e+n;return e+n};var bt=function(){var t={};var r=Array.prototype.push.call(t,undefined);return r!==1||t.length!==1||typeof t[0]!==\"undefined\"||!G(t,0)}();P(r,{push:function push(t){if(et(this)){return v.apply(this,arguments)}return wt.apply(this,arguments)}},bt);var Tt=function(){var t=[];var r=t.push(undefined);return r!==1||t.length!==1||typeof t[0]!==\"undefined\"||!G(t,0)}();P(r,{push:wt},Tt);P(r,{slice:function(t,r){var e=N(this)?Q(this,\"\"):this;return B(e,arguments)}},at);var mt=function(){try{[1,2].sort(null)}catch(t){try{[1,2].sort({})}catch(r){return false}}return true}();var Dt=function(){try{[1,2].sort(/a/);return false}catch(t){}return true}();var St=function(){try{[1,2].sort(undefined);return true}catch(t){}return false}();P(r,{sort:function sort(t){if(typeof t===\"undefined\"){return rt(this)}if(!D(t)){throw new TypeError(\"Array.prototype.sort callback must be a function\")}return rt(this,t)}},mt||!St||!Dt);var xt=!tt({toString:null},\"toString\");var Ot=tt(function(){},\"prototype\");var Et=!G(\"x\",\"0\");var jt=function(t){var r=t.constructor;return r&&r.prototype===t};var It={$applicationCache:true,$console:true,$external:true,$frame:true,$frameElement:true,$frames:true,$innerHeight:true,$innerWidth:true,$onmozfullscreenchange:true,$onmozfullscreenerror:true,$outerHeight:true,$outerWidth:true,$pageXOffset:true,$pageYOffset:true,$parent:true,$scrollLeft:true,$scrollTop:true,$scrollX:true,$scrollY:true,$self:true,$webkitIndexedDB:true,$webkitStorageInfo:true,$window:true,$width:true,$height:true,$top:true,$localStorage:true};var Mt=function(){if(typeof window===\"undefined\"){return false}for(var t in window){try{if(!It[\"$\"+t]&&G(window,t)&&window[t]!==null&&typeof window[t]===\"object\"){jt(window[t])}}catch(r){return true}}return false}();var Ut=function(t){if(typeof window===\"undefined\"||!Mt){return jt(t)}try{return jt(t)}catch(r){return false}};var $t=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"];var Ft=$t.length;var Nt=function isArguments(t){return H(t)===\"[object Arguments]\"};var Ct=function isArguments(t){return t!==null&&typeof t===\"object\"&&typeof t.length===\"number\"&&t.length>=0&&!et(t)&&D(t.callee)};var kt=Nt(arguments)?Nt:Ct;P(e,{keys:function keys(t){var r=D(t);var e=kt(t);var n=t!==null&&typeof t===\"object\";var i=n&&N(t);if(!n&&!r&&!e){throw new TypeError(\"Object.keys called on a non-object\")}var a=[];var f=Ot&&r;if(i&&Et||e){for(var u=0;u<t.length;++u){_(a,o(u))}}if(!e){for(var l in t){if(!(f&&l===\"prototype\")&&G(t,l)){_(a,o(l))}}}if(xt){var s=Ut(t);for(var c=0;c<Ft;c++){var v=$t[c];if(!(s&&v===\"constructor\")&&G(t,v)){_(a,v)}}}return a}});var At=e.keys&&function(){return e.keys(arguments).length===2}(1,2);var Rt=e.keys&&function(){var t=e.keys(arguments);return arguments.length!==1||t.length!==1||t[0]!==1}(1);var Pt=e.keys;P(e,{keys:function keys(t){if(kt(t)){return Pt(W(t))}else{return Pt(t)}}},!At||Rt);var Jt=new Date(-0xc782b5b342b24).getUTCMonth()!==0;var Yt=new Date(-0x55d318d56a724);var zt=new Date(14496624e5);var Zt=Yt.toUTCString()!==\"Mon, 01 Jan -45875 11:59:59 GMT\";var Gt;var Ht;var Wt=Yt.getTimezoneOffset();if(Wt<-720){Gt=Yt.toDateString()!==\"Tue Jan 02 -45875\";Ht=!/^Thu Dec 10 2015 \\d\\d:\\d\\d:\\d\\d GMT[-+]\\d\\d\\d\\d(?: |$)/.test(String(zt))}else{Gt=Yt.toDateString()!==\"Mon Jan 01 -45875\";Ht=!/^Wed Dec 09 2015 \\d\\d:\\d\\d:\\d\\d GMT[-+]\\d\\d\\d\\d(?: |$)/.test(String(zt))}var Bt=d.bind(Date.prototype.getFullYear);var Xt=d.bind(Date.prototype.getMonth);var Lt=d.bind(Date.prototype.getDate);var qt=d.bind(Date.prototype.getUTCFullYear);var Kt=d.bind(Date.prototype.getUTCMonth);var Qt=d.bind(Date.prototype.getUTCDate);var Vt=d.bind(Date.prototype.getUTCDay);var _t=d.bind(Date.prototype.getUTCHours);var tr=d.bind(Date.prototype.getUTCMinutes);var rr=d.bind(Date.prototype.getUTCSeconds);var er=d.bind(Date.prototype.getUTCMilliseconds);var nr=[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"];var ir=[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];var ar=function daysInMonth(t,r){return Lt(new Date(r,t,0))};P(Date.prototype,{getFullYear:function getFullYear(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=Bt(this);if(t<0&&Xt(this)>11){return t+1}return t},getMonth:function getMonth(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=Bt(this);var r=Xt(this);if(t<0&&r>11){return 0}return r},getDate:function getDate(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=Bt(this);var r=Xt(this);var e=Lt(this);if(t<0&&r>11){if(r===12){return e}var n=ar(0,t+1);return n-e+1}return e},getUTCFullYear:function getUTCFullYear(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=qt(this);if(t<0&&Kt(this)>11){return t+1}return t},getUTCMonth:function getUTCMonth(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=qt(this);var r=Kt(this);if(t<0&&r>11){return 0}return r},getUTCDate:function getUTCDate(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=qt(this);var r=Kt(this);var e=Qt(this);if(t<0&&r>11){if(r===12){return e}var n=ar(0,t+1);return n-e+1}return e}},Jt);P(Date.prototype,{toUTCString:function toUTCString(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=Vt(this);var r=Qt(this);var e=Kt(this);var n=qt(this);var i=_t(this);var a=tr(this);var o=rr(this);return nr[t]+\", \"+(r<10?\"0\"+r:r)+\" \"+ir[e]+\" \"+n+\" \"+(i<10?\"0\"+i:i)+\":\"+(a<10?\"0\"+a:a)+\":\"+(o<10?\"0\"+o:o)+\" GMT\"}},Jt||Zt);P(Date.prototype,{toDateString:function toDateString(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=this.getDay();var r=this.getDate();var e=this.getMonth();var n=this.getFullYear();return nr[t]+\" \"+ir[e]+\" \"+(r<10?\"0\"+r:r)+\" \"+n}},Jt||Gt);if(Jt||Ht){Date.prototype.toString=function toString(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=this.getDay();var r=this.getDate();var e=this.getMonth();var n=this.getFullYear();var i=this.getHours();var a=this.getMinutes();var o=this.getSeconds();var f=this.getTimezoneOffset();var u=Math.floor(Math.abs(f)/60);var l=Math.floor(Math.abs(f)%60);return nr[t]+\" \"+ir[e]+\" \"+(r<10?\"0\"+r:r)+\" \"+n+\" \"+(i<10?\"0\"+i:i)+\":\"+(a<10?\"0\"+a:a)+\":\"+(o<10?\"0\"+o:o)+\" GMT\"+(f>0?\"-\":\"+\")+(u<10?\"0\"+u:u)+(l<10?\"0\"+l:l)};if(R){e.defineProperty(Date.prototype,\"toString\",{configurable:true,enumerable:false,writable:true})}}var or=-621987552e5;var fr=\"-000001\";var ur=Date.prototype.toISOString&&new Date(or).toISOString().indexOf(fr)===-1;var lr=Date.prototype.toISOString&&new Date(-1).toISOString()!==\"1969-12-31T23:59:59.999Z\";var sr=d.bind(Date.prototype.getTime);P(Date.prototype,{toISOString:function toISOString(){if(!isFinite(this)||!isFinite(sr(this))){throw new RangeError(\"Date.prototype.toISOString called on non-finite value.\")}var t=qt(this);var r=Kt(this);t+=Math.floor(r/12);r=(r%12+12)%12;var e=[r+1,Qt(this),_t(this),tr(this),rr(this)];t=(t<0?\"-\":t>9999?\"+\":\"\")+K(\"00000\"+Math.abs(t),0<=t&&t<=9999?-4:-6);for(var n=0;n<e.length;++n){e[n]=K(\"00\"+e[n],-2)}return t+\"-\"+W(e,0,2).join(\"-\")+\"T\"+W(e,2).join(\":\")+\".\"+K(\"000\"+er(this),-3)+\"Z\"}},ur||lr);var cr=function(){try{return Date.prototype.toJSON&&new Date(NaN).toJSON()===null&&new Date(or).toJSON().indexOf(fr)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return true}})}catch(t){return false}}();if(!cr){Date.prototype.toJSON=function toJSON(t){var r=e(this);var n=z.ToPrimitive(r);if(typeof n===\"number\"&&!isFinite(n)){return null}var i=r.toISOString;if(!D(i)){throw new TypeError(\"toISOString property is not callable\")}return i.call(r)}}var vr=Date.parse(\"+033658-09-27T01:46:40.000Z\")===1e15;var hr=!isNaN(Date.parse(\"2012-04-04T24:00:00.500Z\"))||!isNaN(Date.parse(\"2012-11-31T23:59:59.000Z\"))||!isNaN(Date.parse(\"2012-12-31T23:59:60.000Z\"));var pr=isNaN(Date.parse(\"2000-01-01T00:00:00.000Z\"));if(pr||hr||!vr){var yr=Math.pow(2,31)-1;var dr=Y(new Date(1970,0,1,0,0,0,yr+1).getTime());Date=function(t){var r=function Date(e,n,i,a,f,u,l){var s=arguments.length;var c;if(this instanceof t){var v=u;var h=l;if(dr&&s>=7&&l>yr){var p=Math.floor(l/yr)*yr;var y=Math.floor(p/1e3);v+=y;h-=y*1e3}c=s===1&&o(e)===e?new t(r.parse(e)):s>=7?new t(e,n,i,a,f,v,h):s>=6?new t(e,n,i,a,f,v):s>=5?new t(e,n,i,a,f):s>=4?new t(e,n,i,a):s>=3?new t(e,n,i):s>=2?new t(e,n):s>=1?new t(e instanceof t?+e:e):new t}else{c=t.apply(this,arguments)}if(!J(c)){P(c,{constructor:r},true)}return c};var e=new RegExp(\"^\"+\"(\\\\d{4}|[+-]\\\\d{6})\"+\"(?:-(\\\\d{2})\"+\"(?:-(\\\\d{2})\"+\"(?:\"+\"T(\\\\d{2})\"+\":(\\\\d{2})\"+\"(?:\"+\":(\\\\d{2})\"+\"(?:(\\\\.\\\\d{1,}))?\"+\")?\"+\"(\"+\"Z|\"+\"(?:\"+\"([-+])\"+\"(\\\\d{2})\"+\":(\\\\d{2})\"+\")\"+\")?)?)?)?\"+\"$\");var n=[0,31,59,90,120,151,181,212,243,273,304,334,365];var i=function dayFromMonth(t,r){var e=r>1?1:0;return n[r]+Math.floor((t-1969+e)/4)-Math.floor((t-1901+e)/100)+Math.floor((t-1601+e)/400)+365*(t-1970)};var a=function toUTC(r){var e=0;var n=r;if(dr&&n>yr){var i=Math.floor(n/yr)*yr;var a=Math.floor(i/1e3);e+=a;n-=a*1e3}return u(new t(1970,0,1,0,0,e,n))};for(var f in t){if(G(t,f)){r[f]=t[f]}}P(r,{now:t.now,UTC:t.UTC},true);r.prototype=t.prototype;P(r.prototype,{constructor:r},true);var l=function parse(r){var n=e.exec(r);if(n){var o=u(n[1]),f=u(n[2]||1)-1,l=u(n[3]||1)-1,s=u(n[4]||0),c=u(n[5]||0),v=u(n[6]||0),h=Math.floor(u(n[7]||0)*1e3),p=Boolean(n[4]&&!n[8]),y=n[9]===\"-\"?1:-1,d=u(n[10]||0),g=u(n[11]||0),w;var b=c>0||v>0||h>0;if(s<(b?24:25)&&c<60&&v<60&&h<1e3&&f>-1&&f<12&&d<24&&g<60&&l>-1&&l<i(o,f+1)-i(o,f)){w=((i(o,f)+l)*24+s+d*y)*60;w=((w+c+g*y)*60+v)*1e3+h;if(p){w=a(w)}if(-864e13<=w&&w<=864e13){return w}}return NaN}return t.parse.apply(this,arguments)};P(r,{parse:l});return r}(Date)}if(!Date.now){Date.now=function now(){return(new Date).getTime()}}var gr=l.toFixed&&(8e-5.toFixed(3)!==\"0.000\"||.9.toFixed(0)!==\"1\"||1.255.toFixed(2)!==\"1.25\"||(1000000000000000128).toFixed(0)!==\"1000000000000000128\");var wr={base:1e7,size:6,data:[0,0,0,0,0,0],multiply:function multiply(t,r){var e=-1;var n=r;while(++e<wr.size){n+=t*wr.data[e];wr.data[e]=n%wr.base;n=Math.floor(n/wr.base)}},divide:function divide(t){var r=wr.size;var e=0;while(--r>=0){e+=wr.data[r];wr.data[r]=Math.floor(e/t);e=e%t*wr.base}},numToString:function numToString(){var t=wr.size;var r=\"\";while(--t>=0){if(r!==\"\"||t===0||wr.data[t]!==0){var e=o(wr.data[t]);if(r===\"\"){r=e}else{r+=K(\"0000000\",0,7-e.length)+e}}}return r},pow:function pow(t,r,e){return r===0?e:r%2===1?pow(t,r-1,e*t):pow(t*t,r/2,e)},log:function log(t){var r=0;var e=t;while(e>=4096){r+=12;e/=4096}while(e>=2){r+=1;e/=2}return r}};var br=function toFixed(t){var r,e,n,i,a,f,l,s;r=u(t);r=Y(r)?0:Math.floor(r);if(r<0||r>20){throw new RangeError(\"Number.toFixed called with invalid number of decimals\")}e=u(this);if(Y(e)){return\"NaN\"}if(e<=-1e21||e>=1e21){return o(e)}n=\"\";if(e<0){n=\"-\";e=-e}i=\"0\";if(e>1e-21){a=wr.log(e*wr.pow(2,69,1))-69;f=a<0?e*wr.pow(2,-a,1):e/wr.pow(2,a,1);f*=4503599627370496;a=52-a;if(a>0){wr.multiply(0,f);l=r;while(l>=7){wr.multiply(1e7,0);l-=7}wr.multiply(wr.pow(10,l,1),0);l=a-1;while(l>=23){wr.divide(1<<23);l-=23}wr.divide(1<<l);wr.multiply(1,1);wr.divide(2);i=wr.numToString()}else{wr.multiply(0,f);wr.multiply(1<<-a,0);i=wr.numToString()+K(\"0.00000000000000000000\",2,2+r)}}if(r>0){s=i.length;if(s<=r){i=n+K(\"0.0000000000000000000\",0,r-s+2)+i}else{i=n+K(i,0,s-r)+\".\"+K(i,s-r)}}else{i=n+i}return i};P(l,{toFixed:br},gr);var Tr=function(){try{return 1..toPrecision(undefined)===\"1\"}catch(t){return true}}();var mr=l.toPrecision;P(l,{toPrecision:function toPrecision(t){return typeof t===\"undefined\"?mr.call(this):mr.call(this,t)}},Tr);if(\"ab\".split(/(?:ab)*/).length!==2||\".\".split(/(.?)(.?)/).length!==4||\"tesst\".split(/(s)*/)[1]===\"t\"||\"test\".split(/(?:)/,-1).length!==4||\"\".split(/.?/).length||\".\".split(/()()/).length>1){(function(){var t=typeof/()??/.exec(\"\")[1]===\"undefined\";var r=Math.pow(2,32)-1;f.split=function(e,n){var i=String(this);if(typeof e===\"undefined\"&&n===0){return[]}if(!M(e)){return Q(this,e,n)}var a=[];var o=(e.ignoreCase?\"i\":\"\")+(e.multiline?\"m\":\"\")+(e.unicode?\"u\":\"\")+(e.sticky?\"y\":\"\"),f=0,u,l,s,c;var h=new RegExp(e.source,o+\"g\");if(!t){u=new RegExp(\"^\"+h.source+\"$(?!\\\\s)\",o)}var p=typeof n===\"undefined\"?r:z.ToUint32(n);l=h.exec(i);while(l){s=l.index+l[0].length;if(s>f){_(a,K(i,f,l.index));if(!t&&l.length>1){l[0].replace(u,function(){for(var t=1;t<arguments.length-2;t++){if(typeof arguments[t]===\"undefined\"){l[t]=void 0}}})}if(l.length>1&&l.index<i.length){v.apply(a,W(l,1))}c=l[0].length;f=s;if(a.length>=p){break}}if(h.lastIndex===l.index){h.lastIndex++}l=h.exec(i)}if(f===i.length){if(c||!h.test(\"\")){_(a,\"\")}}else{_(a,K(i,f))}return a.length>p?W(a,0,p):a}})()}else if(\"0\".split(void 0,0).length){f.split=function split(t,r){if(typeof t===\"undefined\"&&r===0){return[]}return Q(this,t,r)}}var Dr=f.replace;var Sr=function(){var t=[];\"x\".replace(/x(.)?/g,function(r,e){_(t,e)});return t.length===1&&typeof t[0]===\"undefined\"}();if(!Sr){f.replace=function replace(t,r){var e=D(r);var n=M(t)&&/\\)[*?]/.test(t.source);if(!e||!n){return Dr.call(this,t,r)}else{var i=function(e){var n=arguments.length;var i=t.lastIndex;t.lastIndex=0;var a=t.exec(e)||[];t.lastIndex=i;_(a,arguments[n-2],arguments[n-1]);return r.apply(this,a)};return Dr.call(this,t,i)}}}var xr=f.substr;var Or=\"\".substr&&\"0b\".substr(-1)!==\"b\";P(f,{substr:function substr(t,r){var e=t;if(t<0){e=w(this.length+t,0)}return xr.call(this,e,r)}},Or);var Er=\"\\t\\n\\x0B\\f\\r \\xa0\\u1680\\u2000\\u2001\\u2002\\u2003\"+\"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\"+\"\\u2029\\ufeff\";var jr=\"\\u200b\";var Ir=\"[\"+Er+\"]\";var Mr=new RegExp(\"^\"+Ir+Ir+\"*\");var Ur=new RegExp(Ir+Ir+\"*$\");var $r=f.trim&&(Er.trim()||!jr.trim());P(f,{trim:function trim(){if(typeof this===\"undefined\"||this===null){throw new TypeError(\"can't convert \"+this+\" to object\")}return o(this).replace(Mr,\"\").replace(Ur,\"\")}},$r);var Fr=d.bind(String.prototype.trim);var Nr=f.lastIndexOf&&\"abc\\u3042\\u3044\".lastIndexOf(\"\\u3042\\u3044\",2)!==-1;P(f,{lastIndexOf:function lastIndexOf(t){if(typeof this===\"undefined\"||this===null){throw new TypeError(\"can't convert \"+this+\" to object\")}var r=o(this);var e=o(t);var n=arguments.length>1?u(arguments[1]):NaN;var i=Y(n)?Infinity:z.ToInteger(n);var a=b(w(i,0),r.length);var f=e.length;var l=a+f;while(l>0){l=w(0,l-f);var s=V(K(r,l,a+f),e);if(s!==-1){return l+s}}return-1}},Nr);var Cr=f.lastIndexOf;P(f,{lastIndexOf:function lastIndexOf(t){return Cr.apply(this,arguments)}},f.lastIndexOf.length!==1);if(parseInt(Er+\"08\")!==8||parseInt(Er+\"0x16\")!==22){parseInt=function(t){var r=/^[-+]?0[xX]/;return function parseInt(e,n){if(typeof e===\"symbol\"){\"\"+e}var i=Fr(String(e));var a=u(n)||(r.test(i)?16:10);return t(i,a)}}(parseInt)}if(1/parseFloat(\"-0\")!==-Infinity){parseFloat=function(t){return function parseFloat(r){var e=Fr(String(r));var n=t(e);return n===0&&K(e,0,1)===\"-\"?-0:n}}(parseFloat)}if(String(new RangeError(\"test\"))!==\"RangeError: test\"){var kr=function toString(){if(typeof this===\"undefined\"||this===null){throw new TypeError(\"can't convert \"+this+\" to object\")}var t=this.name;if(typeof t===\"undefined\"){t=\"Error\"}else if(typeof t!==\"string\"){t=o(t)}var r=this.message;if(typeof r===\"undefined\"){r=\"\"}else if(typeof r!==\"string\"){r=o(r)}if(!t){return r}if(!r){return t}return t+\": \"+r};Error.prototype.toString=kr}if(R){var Ar=function(t,r){if(tt(t,r)){var e=Object.getOwnPropertyDescriptor(t,r);if(e.configurable){e.enumerable=false;Object.defineProperty(t,r,e)}}};Ar(Error.prototype,\"message\");if(Error.prototype.message!==\"\"){Error.prototype.message=\"\"}Ar(Error.prototype,\"name\")}if(String(/a/gim)!==\"/a/gim\"){var Rr=function toString(){var t=\"/\"+this.source+\"/\";if(this.global){t+=\"g\"}if(this.ignoreCase){t+=\"i\"}if(this.multiline){t+=\"m\"}return t};RegExp.prototype.toString=Rr}});\n/*!\n * https://github.com/paulmillr/es6-shim\n * @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)\n * and contributors, MIT License\n * es6-shim: v0.35.4\n * see https://github.com/paulmillr/es6-shim/blob/0.35.4/LICENSE\n * Details and documentation:\n * https://github.com/paulmillr/es6-shim/\n */\n(function(e,t){if(typeof define===\"function\"&&define.amd){define(t)}else if(typeof exports===\"object\"){module.exports=t()}else{e.returnExports=t()}})(this,function(){\"use strict\";var e=Function.call.bind(Function.apply);var t=Function.call.bind(Function.call);var r=Array.isArray;var n=Object.keys;var o=function notThunker(t){return function notThunk(){return!e(t,this,arguments)}};var i=function(e){try{e();return false}catch(t){return true}};var a=function valueOrFalseIfThrows(e){try{return e()}catch(t){return false}};var u=o(i);var f=function(){return!i(function(){return Object.defineProperty({},\"x\",{get:function(){}})})};var s=!!Object.defineProperty&&f();var c=function foo(){}.name===\"foo\";var l=Function.call.bind(Array.prototype.forEach);var p=Function.call.bind(Array.prototype.reduce);var v=Function.call.bind(Array.prototype.filter);var y=Function.call.bind(Array.prototype.some);var h=function(e,t,r,n){if(!n&&t in e){return}if(s){Object.defineProperty(e,t,{configurable:true,enumerable:false,writable:true,value:r})}else{e[t]=r}};var b=function(e,t,r){l(n(t),function(n){var o=t[n];h(e,n,o,!!r)})};var g=Function.call.bind(Object.prototype.toString);var d=typeof/abc/===\"function\"?function IsCallableSlow(e){return typeof e===\"function\"&&g(e)===\"[object Function]\"}:function IsCallableFast(e){return typeof e===\"function\"};var m={getter:function(e,t,r){if(!s){throw new TypeError(\"getters require true ES5 support\")}Object.defineProperty(e,t,{configurable:true,enumerable:false,get:r})},proxy:function(e,t,r){if(!s){throw new TypeError(\"getters require true ES5 support\")}var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,{configurable:n.configurable,enumerable:n.enumerable,get:function getKey(){return e[t]},set:function setKey(r){e[t]=r}})},redefine:function(e,t,r){if(s){var n=Object.getOwnPropertyDescriptor(e,t);n.value=r;Object.defineProperty(e,t,n)}else{e[t]=r}},defineByDescriptor:function(e,t,r){if(s){Object.defineProperty(e,t,r)}else if(\"value\"in r){e[t]=r.value}},preserveToString:function(e,t){if(t&&d(t.toString)){h(e,\"toString\",t.toString.bind(t),true)}}};var O=Object.create||function(e,t){var r=function Prototype(){};r.prototype=e;var o=new r;if(typeof t!==\"undefined\"){n(t).forEach(function(e){m.defineByDescriptor(o,e,t[e])})}return o};var w=function(e,t){if(!Object.setPrototypeOf){return false}return a(function(){var r=function Subclass(t){var r=new e(t);Object.setPrototypeOf(r,Subclass.prototype);return r};Object.setPrototypeOf(r,e);r.prototype=O(e.prototype,{constructor:{value:r}});return t(r)})};var j=function(){if(typeof self!==\"undefined\"){return self}if(typeof window!==\"undefined\"){return window}if(typeof global!==\"undefined\"){return global}throw new Error(\"unable to locate global object\")};var S=j();var T=S.isFinite;var I=Function.call.bind(String.prototype.indexOf);var E=Function.apply.bind(Array.prototype.indexOf);var P=Function.call.bind(Array.prototype.concat);var C=Function.call.bind(String.prototype.slice);var M=Function.call.bind(Array.prototype.push);var x=Function.apply.bind(Array.prototype.push);var N=Function.call.bind(Array.prototype.shift);var A=Math.max;var R=Math.min;var _=Math.floor;var k=Math.abs;var L=Math.exp;var F=Math.log;var D=Math.sqrt;var z=Function.call.bind(Object.prototype.hasOwnProperty);var q;var W=function(){};var G=S.Map;var H=G&&G.prototype[\"delete\"];var V=G&&G.prototype.get;var B=G&&G.prototype.has;var U=G&&G.prototype.set;var $=S.Symbol||{};var J=$.species||\"@@species\";var X=Number.isNaN||function isNaN(e){return e!==e};var K=Number.isFinite||function isFinite(e){return typeof e===\"number\"&&T(e)};var Z=d(Math.sign)?Math.sign:function sign(e){var t=Number(e);if(t===0){return t}if(X(t)){return t}return t<0?-1:1};var Y=function log1p(e){var t=Number(e);if(t<-1||X(t)){return NaN}if(t===0||t===Infinity){return t}if(t===-1){return-Infinity}return 1+t-1===0?t:t*(F(1+t)/(1+t-1))};var Q=function isArguments(e){return g(e)===\"[object Arguments]\"};var ee=function isArguments(e){return e!==null&&typeof e===\"object\"&&typeof e.length===\"number\"&&e.length>=0&&g(e)!==\"[object Array]\"&&g(e.callee)===\"[object Function]\"};var te=Q(arguments)?Q:ee;var re={primitive:function(e){return e===null||typeof e!==\"function\"&&typeof e!==\"object\"},string:function(e){return g(e)===\"[object String]\"},regex:function(e){return g(e)===\"[object RegExp]\"},symbol:function(e){return typeof S.Symbol===\"function\"&&typeof e===\"symbol\"}};var ne=function overrideNative(e,t,r){var n=e[t];h(e,t,r,true);m.preserveToString(e[t],n)};var oe=typeof $===\"function\"&&typeof $[\"for\"]===\"function\"&&re.symbol($());var ie=re.symbol($.iterator)?$.iterator:\"_es6-shim iterator_\";if(S.Set&&typeof(new S.Set)[\"@@iterator\"]===\"function\"){ie=\"@@iterator\"}if(!S.Reflect){h(S,\"Reflect\",{},true)}var ae=S.Reflect;var ue=String;var fe=typeof document===\"undefined\"||!document?null:document.all;var se=fe==null?function isNullOrUndefined(e){return e==null}:function isNullOrUndefinedAndNotDocumentAll(e){return e==null&&e!==fe};var ce={Call:function Call(t,r){var n=arguments.length>2?arguments[2]:[];if(!ce.IsCallable(t)){throw new TypeError(t+\" is not a function\")}return e(t,r,n)},RequireObjectCoercible:function(e,t){if(se(e)){throw new TypeError(t||\"Cannot call method on \"+e)}return e},TypeIsObject:function(e){if(e===void 0||e===null||e===true||e===false){return false}return typeof e===\"function\"||typeof e===\"object\"||e===fe},ToObject:function(e,t){return Object(ce.RequireObjectCoercible(e,t))},IsCallable:d,IsConstructor:function(e){return ce.IsCallable(e)},ToInt32:function(e){return ce.ToNumber(e)>>0},ToUint32:function(e){return ce.ToNumber(e)>>>0},ToNumber:function(e){if(g(e)===\"[object Symbol]\"){throw new TypeError(\"Cannot convert a Symbol value to a number\")}return+e},ToInteger:function(e){var t=ce.ToNumber(e);if(X(t)){return 0}if(t===0||!K(t)){return t}return(t>0?1:-1)*_(k(t))},ToLength:function(e){var t=ce.ToInteger(e);if(t<=0){return 0}if(t>Number.MAX_SAFE_INTEGER){return Number.MAX_SAFE_INTEGER}return t},SameValue:function(e,t){if(e===t){if(e===0){return 1/e===1/t}return true}return X(e)&&X(t)},SameValueZero:function(e,t){return e===t||X(e)&&X(t)},IsIterable:function(e){return ce.TypeIsObject(e)&&(typeof e[ie]!==\"undefined\"||te(e))},GetIterator:function(e){if(te(e)){return new q(e,\"value\")}var t=ce.GetMethod(e,ie);if(!ce.IsCallable(t)){throw new TypeError(\"value is not an iterable\")}var r=ce.Call(t,e);if(!ce.TypeIsObject(r)){throw new TypeError(\"bad iterator\")}return r},GetMethod:function(e,t){var r=ce.ToObject(e)[t];if(se(r)){return void 0}if(!ce.IsCallable(r)){throw new TypeError(\"Method not callable: \"+t)}return r},IteratorComplete:function(e){return!!e.done},IteratorClose:function(e,t){var r=ce.GetMethod(e,\"return\");if(r===void 0){return}var n,o;try{n=ce.Call(r,e)}catch(i){o=i}if(t){return}if(o){throw o}if(!ce.TypeIsObject(n)){throw new TypeError(\"Iterator's return method returned a non-object.\")}},IteratorNext:function(e){var t=arguments.length>1?e.next(arguments[1]):e.next();if(!ce.TypeIsObject(t)){throw new TypeError(\"bad iterator\")}return t},IteratorStep:function(e){var t=ce.IteratorNext(e);var r=ce.IteratorComplete(t);return r?false:t},Construct:function(e,t,r,n){var o=typeof r===\"undefined\"?e:r;if(!n&&ae.construct){return ae.construct(e,t,o)}var i=o.prototype;if(!ce.TypeIsObject(i)){i=Object.prototype}var a=O(i);var u=ce.Call(e,a,t);return ce.TypeIsObject(u)?u:a},SpeciesConstructor:function(e,t){var r=e.constructor;if(r===void 0){return t}if(!ce.TypeIsObject(r)){throw new TypeError(\"Bad constructor\")}var n=r[J];if(se(n)){return t}if(!ce.IsConstructor(n)){throw new TypeError(\"Bad @@species\")}return n},CreateHTML:function(e,t,r,n){var o=ce.ToString(e);var i=\"<\"+t;if(r!==\"\"){var a=ce.ToString(n);var u=a.replace(/\"/g,\""\");i+=\" \"+r+'=\"'+u+'\"'}var f=i+\">\";var s=f+o;return s+\"</\"+t+\">\"},IsRegExp:function IsRegExp(e){if(!ce.TypeIsObject(e)){return false}var t=e[$.match];if(typeof t!==\"undefined\"){return!!t}return re.regex(e)},ToString:function ToString(e){return ue(e)}};if(s&&oe){var le=function defineWellKnownSymbol(e){if(re.symbol($[e])){return $[e]}var t=$[\"for\"](\"Symbol.\"+e);Object.defineProperty($,e,{configurable:false,enumerable:false,writable:false,value:t});return t};if(!re.symbol($.search)){var pe=le(\"search\");var ve=String.prototype.search;h(RegExp.prototype,pe,function search(e){return ce.Call(ve,e,[this])});var ye=function search(e){var t=ce.RequireObjectCoercible(this);if(!se(e)){var r=ce.GetMethod(e,pe);if(typeof r!==\"undefined\"){return ce.Call(r,e,[t])}}return ce.Call(ve,t,[ce.ToString(e)])};ne(String.prototype,\"search\",ye)}if(!re.symbol($.replace)){var he=le(\"replace\");var be=String.prototype.replace;h(RegExp.prototype,he,function replace(e,t){return ce.Call(be,e,[this,t])});var ge=function replace(e,t){var r=ce.RequireObjectCoercible(this);if(!se(e)){var n=ce.GetMethod(e,he);if(typeof n!==\"undefined\"){return ce.Call(n,e,[r,t])}}return ce.Call(be,r,[ce.ToString(e),t])};ne(String.prototype,\"replace\",ge)}if(!re.symbol($.split)){var de=le(\"split\");var me=String.prototype.split;h(RegExp.prototype,de,function split(e,t){return ce.Call(me,e,[this,t])});var Oe=function split(e,t){var r=ce.RequireObjectCoercible(this);if(!se(e)){var n=ce.GetMethod(e,de);if(typeof n!==\"undefined\"){return ce.Call(n,e,[r,t])}}return ce.Call(me,r,[ce.ToString(e),t])};ne(String.prototype,\"split\",Oe)}var we=re.symbol($.match);var je=we&&function(){var e={};e[$.match]=function(){return 42};return\"a\".match(e)!==42}();if(!we||je){var Se=le(\"match\");var Te=String.prototype.match;h(RegExp.prototype,Se,function match(e){return ce.Call(Te,e,[this])});var Ie=function match(e){var t=ce.RequireObjectCoercible(this);if(!se(e)){var r=ce.GetMethod(e,Se);if(typeof r!==\"undefined\"){return ce.Call(r,e,[t])}}return ce.Call(Te,t,[ce.ToString(e)])};ne(String.prototype,\"match\",Ie)}}var Ee=function wrapConstructor(e,t,r){m.preserveToString(t,e);if(Object.setPrototypeOf){Object.setPrototypeOf(e,t)}if(s){l(Object.getOwnPropertyNames(e),function(n){if(n in W||r[n]){return}m.proxy(e,n,t)})}else{l(Object.keys(e),function(n){if(n in W||r[n]){return}t[n]=e[n]})}t.prototype=e.prototype;m.redefine(e.prototype,\"constructor\",t)};var Pe=function(){return this};var Ce=function(e){if(s&&!z(e,J)){m.getter(e,J,Pe)}};var Me=function(e,t){var r=t||function iterator(){return this};h(e,ie,r);if(!e[ie]&&re.symbol(ie)){e[ie]=r}};var xe=function createDataProperty(e,t,r){if(s){Object.defineProperty(e,t,{configurable:true,enumerable:true,writable:true,value:r})}else{e[t]=r}};var Ne=function createDataPropertyOrThrow(e,t,r){xe(e,t,r);if(!ce.SameValue(e[t],r)){throw new TypeError(\"property is nonconfigurable\")}};var Ae=function(e,t,r,n){if(!ce.TypeIsObject(e)){throw new TypeError(\"Constructor requires `new`: \"+t.name)}var o=t.prototype;if(!ce.TypeIsObject(o)){o=r}var i=O(o);for(var a in n){if(z(n,a)){var u=n[a];h(i,a,u,true)}}return i};if(String.fromCodePoint&&String.fromCodePoint.length!==1){var Re=String.fromCodePoint;ne(String,\"fromCodePoint\",function fromCodePoint(e){return ce.Call(Re,this,arguments)})}var _e={fromCodePoint:function fromCodePoint(e){var t=[];var r;for(var n=0,o=arguments.length;n<o;n++){r=Number(arguments[n]);if(!ce.SameValue(r,ce.ToInteger(r))||r<0||r>1114111){throw new RangeError(\"Invalid code point \"+r)}if(r<65536){M(t,String.fromCharCode(r))}else{r-=65536;M(t,String.fromCharCode((r>>10)+55296));M(t,String.fromCharCode(r%1024+56320))}}return t.join(\"\")},raw:function raw(e){var t=ce.ToObject(e,\"bad callSite\");var r=ce.ToObject(t.raw,\"bad raw value\");var n=r.length;var o=ce.ToLength(n);if(o<=0){return\"\"}var i=[];var a=0;var u,f,s,c;while(a<o){u=ce.ToString(a);s=ce.ToString(r[u]);M(i,s);if(a+1>=o){break}f=a+1<arguments.length?arguments[a+1]:\"\";c=ce.ToString(f);M(i,c);a+=1}return i.join(\"\")}};if(String.raw&&String.raw({raw:{0:\"x\",1:\"y\",length:2}})!==\"xy\"){ne(String,\"raw\",_e.raw)}b(String,_e);var ke=function repeat(e,t){if(t<1){return\"\"}if(t%2){return repeat(e,t-1)+e}var r=repeat(e,t/2);return r+r};var Le=Infinity;var Fe={repeat:function repeat(e){var t=ce.ToString(ce.RequireObjectCoercible(this));var r=ce.ToInteger(e);if(r<0||r>=Le){throw new RangeError(\"repeat count must be less than infinity and not overflow maximum string size\")}return ke(t,r)},startsWith:function startsWith(e){var t=ce.ToString(ce.RequireObjectCoercible(this));if(ce.IsRegExp(e)){throw new TypeError('Cannot call method \"startsWith\" with a regex')}var r=ce.ToString(e);var n;if(arguments.length>1){n=arguments[1]}var o=A(ce.ToInteger(n),0);return C(t,o,o+r.length)===r},endsWith:function endsWith(e){var t=ce.ToString(ce.RequireObjectCoercible(this));if(ce.IsRegExp(e)){throw new TypeError('Cannot call method \"endsWith\" with a regex')}var r=ce.ToString(e);var n=t.length;var o;if(arguments.length>1){o=arguments[1]}var i=typeof o===\"undefined\"?n:ce.ToInteger(o);var a=R(A(i,0),n);return C(t,a-r.length,a)===r},includes:function includes(e){if(ce.IsRegExp(e)){throw new TypeError('\"includes\" does not accept a RegExp')}var t=ce.ToString(e);var r;if(arguments.length>1){r=arguments[1]}return I(this,t,r)!==-1},codePointAt:function codePointAt(e){var t=ce.ToString(ce.RequireObjectCoercible(this));var r=ce.ToInteger(e);var n=t.length;if(r>=0&&r<n){var o=t.charCodeAt(r);var i=r+1===n;if(o<55296||o>56319||i){return o}var a=t.charCodeAt(r+1);if(a<56320||a>57343){return o}return(o-55296)*1024+(a-56320)+65536}}};if(String.prototype.includes&&\"a\".includes(\"a\",Infinity)!==false){ne(String.prototype,\"includes\",Fe.includes)}if(String.prototype.startsWith&&String.prototype.endsWith){var De=i(function(){return\"/a/\".startsWith(/a/)});var ze=a(function(){return\"abc\".startsWith(\"a\",Infinity)===false});if(!De||!ze){ne(String.prototype,\"startsWith\",Fe.startsWith);ne(String.prototype,\"endsWith\",Fe.endsWith)}}if(oe){var qe=a(function(){var e=/a/;e[$.match]=false;return\"/a/\".startsWith(e)});if(!qe){ne(String.prototype,\"startsWith\",Fe.startsWith)}var We=a(function(){var e=/a/;e[$.match]=false;return\"/a/\".endsWith(e)});if(!We){ne(String.prototype,\"endsWith\",Fe.endsWith)}var Ge=a(function(){var e=/a/;e[$.match]=false;return\"/a/\".includes(e)});if(!Ge){ne(String.prototype,\"includes\",Fe.includes)}}b(String.prototype,Fe);var He=[\"\\t\\n\\x0B\\f\\r \\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\",\"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\",\"\\u2029\\ufeff\"].join(\"\");var Ve=new RegExp(\"(^[\"+He+\"]+)|([\"+He+\"]+$)\",\"g\");var Be=function trim(){return ce.ToString(ce.RequireObjectCoercible(this)).replace(Ve,\"\")};var Ue=[\"\\x85\",\"\\u200b\",\"\\ufffe\"].join(\"\");var $e=new RegExp(\"[\"+Ue+\"]\",\"g\");var Je=/^[-+]0x[0-9a-f]+$/i;var Xe=Ue.trim().length!==Ue.length;h(String.prototype,\"trim\",Be,Xe);var Ke=function(e){return{value:e,done:arguments.length===0}};var Ze=function(e){ce.RequireObjectCoercible(e);this._s=ce.ToString(e);this._i=0};Ze.prototype.next=function(){var e=this._s;var t=this._i;if(typeof e===\"undefined\"||t>=e.length){this._s=void 0;return Ke()}var r=e.charCodeAt(t);var n,o;if(r<55296||r>56319||t+1===e.length){o=1}else{n=e.charCodeAt(t+1);o=n<56320||n>57343?1:2}this._i=t+o;return Ke(e.substr(t,o))};Me(Ze.prototype);Me(String.prototype,function(){return new Ze(this)});var Ye={from:function from(e){var r=this;var n;if(arguments.length>1){n=arguments[1]}var o,i;if(typeof n===\"undefined\"){o=false}else{if(!ce.IsCallable(n)){throw new TypeError(\"Array.from: when provided, the second argument must be a function\")}if(arguments.length>2){i=arguments[2]}o=true}var a=typeof(te(e)||ce.GetMethod(e,ie))!==\"undefined\";var u,f,s;if(a){f=ce.IsConstructor(r)?Object(new r):[];var c=ce.GetIterator(e);var l,p;s=0;while(true){l=ce.IteratorStep(c);if(l===false){break}p=l.value;try{if(o){p=typeof i===\"undefined\"?n(p,s):t(n,i,p,s)}f[s]=p}catch(v){ce.IteratorClose(c,true);throw v}s+=1}u=s}else{var y=ce.ToObject(e);u=ce.ToLength(y.length);f=ce.IsConstructor(r)?Object(new r(u)):new Array(u);var h;for(s=0;s<u;++s){h=y[s];if(o){h=typeof i===\"undefined\"?n(h,s):t(n,i,h,s)}Ne(f,s,h)}}f.length=u;return f},of:function of(){var e=arguments.length;var t=this;var n=r(t)||!ce.IsCallable(t)?new Array(e):ce.Construct(t,[e]);for(var o=0;o<e;++o){Ne(n,o,arguments[o])}n.length=e;return n}};b(Array,Ye);Ce(Array);q=function(e,t){this.i=0;this.array=e;this.kind=t};b(q.prototype,{next:function(){var e=this.i;var t=this.array;if(!(this instanceof q)){throw new TypeError(\"Not an ArrayIterator\")}if(typeof t!==\"undefined\"){var r=ce.ToLength(t.length);for(;e<r;e++){var n=this.kind;var o;if(n===\"key\"){o=e}else if(n===\"value\"){o=t[e]}else if(n===\"entry\"){o=[e,t[e]]}this.i=e+1;return Ke(o)}}this.array=void 0;return Ke()}});Me(q.prototype);var Qe=Array.of===Ye.of||function(){var e=function Foo(e){this.length=e};e.prototype=[];var t=Array.of.apply(e,[1,2]);return t instanceof e&&t.length===2}();if(!Qe){ne(Array,\"of\",Ye.of)}var et={copyWithin:function copyWithin(e,t){var r=ce.ToObject(this);var n=ce.ToLength(r.length);var o=ce.ToInteger(e);var i=ce.ToInteger(t);var a=o<0?A(n+o,0):R(o,n);var u=i<0?A(n+i,0):R(i,n);var f;if(arguments.length>2){f=arguments[2]}var s=typeof f===\"undefined\"?n:ce.ToInteger(f);var c=s<0?A(n+s,0):R(s,n);var l=R(c-u,n-a);var p=1;if(u<a&&a<u+l){p=-1;u+=l-1;a+=l-1}while(l>0){if(u in r){r[a]=r[u]}else{delete r[a]}u+=p;a+=p;l-=1}return r},fill:function fill(e){var t;if(arguments.length>1){t=arguments[1]}var r;if(arguments.length>2){r=arguments[2]}var n=ce.ToObject(this);var o=ce.ToLength(n.length);t=ce.ToInteger(typeof t===\"undefined\"?0:t);r=ce.ToInteger(typeof r===\"undefined\"?o:r);var i=t<0?A(o+t,0):R(t,o);var a=r<0?o+r:r;for(var u=i;u<o&&u<a;++u){n[u]=e}return n},find:function find(e){var r=ce.ToObject(this);var n=ce.ToLength(r.length);if(!ce.IsCallable(e)){throw new TypeError(\"Array#find: predicate must be a function\")}var o=arguments.length>1?arguments[1]:null;for(var i=0,a;i<n;i++){a=r[i];if(o){if(t(e,o,a,i,r)){return a}}else if(e(a,i,r)){return a}}},findIndex:function findIndex(e){var r=ce.ToObject(this);var n=ce.ToLength(r.length);if(!ce.IsCallable(e)){throw new TypeError(\"Array#findIndex: predicate must be a function\")}var o=arguments.length>1?arguments[1]:null;for(var i=0;i<n;i++){if(o){if(t(e,o,r[i],i,r)){return i}}else if(e(r[i],i,r)){return i}}return-1},keys:function keys(){return new q(this,\"key\")},values:function values(){return new q(this,\"value\")},entries:function entries(){return new q(this,\"entry\")}};if(Array.prototype.keys&&!ce.IsCallable([1].keys().next)){delete Array.prototype.keys}if(Array.prototype.entries&&!ce.IsCallable([1].entries().next)){delete Array.prototype.entries}if(Array.prototype.keys&&Array.prototype.entries&&!Array.prototype.values&&Array.prototype[ie]){b(Array.prototype,{values:Array.prototype[ie]});if(re.symbol($.unscopables)){Array.prototype[$.unscopables].values=true}}if(c&&Array.prototype.values&&Array.prototype.values.name!==\"values\"){var tt=Array.prototype.values;ne(Array.prototype,\"values\",function values(){return ce.Call(tt,this,arguments)});h(Array.prototype,ie,Array.prototype.values,true)}b(Array.prototype,et);if(1/[true].indexOf(true,-0)<0){h(Array.prototype,\"indexOf\",function indexOf(e){var t=E(this,arguments);if(t===0&&1/t<0){return 0}return t},true)}Me(Array.prototype,function(){return this.values()});if(Object.getPrototypeOf){Me(Object.getPrototypeOf([].values()))}var rt=function(){return a(function(){return Array.from({length:-1}).length===0})}();var nt=function(){var e=Array.from([0].entries());return e.length===1&&r(e[0])&&e[0][0]===0&&e[0][1]===0}();if(!rt||!nt){ne(Array,\"from\",Ye.from)}var ot=function(){return a(function(){return Array.from([0],void 0)})}();if(!ot){var it=Array.from;ne(Array,\"from\",function from(e){if(arguments.length>1&&typeof arguments[1]!==\"undefined\"){return ce.Call(it,this,arguments)}else{return t(it,this,e)}})}var at=-(Math.pow(2,32)-1);var ut=function(e,r){var n={length:at};n[r?(n.length>>>0)-1:0]=true;return a(function(){t(e,n,function(){throw new RangeError(\"should not reach here\")},[]);return true})};if(!ut(Array.prototype.forEach)){var ft=Array.prototype.forEach;ne(Array.prototype,\"forEach\",function forEach(e){return ce.Call(ft,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.map)){var st=Array.prototype.map;ne(Array.prototype,\"map\",function map(e){return ce.Call(st,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.filter)){var ct=Array.prototype.filter;ne(Array.prototype,\"filter\",function filter(e){return ce.Call(ct,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.some)){var lt=Array.prototype.some;ne(Array.prototype,\"some\",function some(e){return ce.Call(lt,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.every)){var pt=Array.prototype.every;ne(Array.prototype,\"every\",function every(e){return ce.Call(pt,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.reduce)){var vt=Array.prototype.reduce;ne(Array.prototype,\"reduce\",function reduce(e){return ce.Call(vt,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.reduceRight,true)){var yt=Array.prototype.reduceRight;ne(Array.prototype,\"reduceRight\",function reduceRight(e){return ce.Call(yt,this.length>=0?this:[],arguments)},true)}var ht=Number(\"0o10\")!==8;var bt=Number(\"0b10\")!==2;var gt=y(Ue,function(e){return Number(e+0+e)===0});if(ht||bt||gt){var dt=Number;var mt=/^0b[01]+$/i;var Ot=/^0o[0-7]+$/i;var wt=mt.test.bind(mt);var jt=Ot.test.bind(Ot);var St=function(e){var t;if(typeof e.valueOf===\"function\"){t=e.valueOf();if(re.primitive(t)){return t}}if(typeof e.toString===\"function\"){t=e.toString();if(re.primitive(t)){return t}}throw new TypeError(\"No default value\")};var Tt=$e.test.bind($e);var It=Je.test.bind(Je);var Et=function(){var e=function Number(t){var r;if(arguments.length>0){r=re.primitive(t)?t:St(t,\"number\")}else{r=0}if(typeof r===\"string\"){r=ce.Call(Be,r);if(wt(r)){r=parseInt(C(r,2),2)}else if(jt(r)){r=parseInt(C(r,2),8)}else if(Tt(r)||It(r)){r=NaN}}var n=this;var o=a(function(){dt.prototype.valueOf.call(n);return true});if(n instanceof e&&!o){return new dt(r)}return dt(r)};return e}();Ee(dt,Et,{});b(Et,{NaN:dt.NaN,MAX_VALUE:dt.MAX_VALUE,MIN_VALUE:dt.MIN_VALUE,NEGATIVE_INFINITY:dt.NEGATIVE_INFINITY,POSITIVE_INFINITY:dt.POSITIVE_INFINITY});Number=Et;m.redefine(S,\"Number\",Et)}var Pt=Math.pow(2,53)-1;b(Number,{MAX_SAFE_INTEGER:Pt,MIN_SAFE_INTEGER:-Pt,EPSILON:2.220446049250313e-16,parseInt:S.parseInt,parseFloat:S.parseFloat,isFinite:K,isInteger:function isInteger(e){return K(e)&&ce.ToInteger(e)===e},isSafeInteger:function isSafeInteger(e){return Number.isInteger(e)&&k(e)<=Number.MAX_SAFE_INTEGER},isNaN:X});h(Number,\"parseInt\",S.parseInt,Number.parseInt!==S.parseInt);if([,1].find(function(){return true})===1){ne(Array.prototype,\"find\",et.find)}if([,1].findIndex(function(){return true})!==0){ne(Array.prototype,\"findIndex\",et.findIndex)}var Ct=Function.bind.call(Function.bind,Object.prototype.propertyIsEnumerable);var Mt=function ensureEnumerable(e,t){if(s&&Ct(e,t)){Object.defineProperty(e,t,{enumerable:false})}};var xt=function sliceArgs(){var e=Number(this);var t=arguments.length;var r=t-e;var n=new Array(r<0?0:r);for(var o=e;o<t;++o){n[o-e]=arguments[o]}return n};var Nt=function assignTo(e){return function assignToSource(t,r){t[r]=e[r];return t}};var At=function(e,t){var r=n(Object(t));var o;if(ce.IsCallable(Object.getOwnPropertySymbols)){o=v(Object.getOwnPropertySymbols(Object(t)),Ct(t))}return p(P(r,o||[]),Nt(t),e)};var Rt={assign:function(e,t){var r=ce.ToObject(e,\"Cannot convert undefined or null to object\");return p(ce.Call(xt,1,arguments),At,r)},is:function is(e,t){return ce.SameValue(e,t)}};var _t=Object.assign&&Object.preventExtensions&&function(){var e=Object.preventExtensions({1:2});try{Object.assign(e,\"xy\")}catch(t){return e[1]===\"y\"}}();if(_t){ne(Object,\"assign\",Rt.assign)}b(Object,Rt);if(s){var kt={setPrototypeOf:function(e,r){var n;var o=function(e,t){if(!ce.TypeIsObject(e)){throw new TypeError(\"cannot set prototype on a non-object\")}if(!(t===null||ce.TypeIsObject(t))){throw new TypeError(\"can only set prototype to an object or null\"+t)}};var i=function(e,r){o(e,r);t(n,e,r);return e};try{n=e.getOwnPropertyDescriptor(e.prototype,r).set;t(n,{},null)}catch(a){if(e.prototype!=={}[r]){return}n=function(e){this[r]=e};i.polyfill=i(i({},null),e.prototype)instanceof e}return i}(Object,\"__proto__\")};b(Object,kt)}if(Object.setPrototypeOf&&Object.getPrototypeOf&&Object.getPrototypeOf(Object.setPrototypeOf({},null))!==null&&Object.getPrototypeOf(Object.create(null))===null){(function(){var e=Object.create(null);var t=Object.getPrototypeOf;var r=Object.setPrototypeOf;Object.getPrototypeOf=function(r){var n=t(r);return n===e?null:n};Object.setPrototypeOf=function(t,n){var o=n===null?e:n;return r(t,o)};Object.setPrototypeOf.polyfill=false})()}var Lt=!i(function(){return Object.keys(\"foo\")});if(!Lt){var Ft=Object.keys;ne(Object,\"keys\",function keys(e){return Ft(ce.ToObject(e))});n=Object.keys}var Dt=i(function(){return Object.keys(/a/g)});if(Dt){var zt=Object.keys;ne(Object,\"keys\",function keys(e){if(re.regex(e)){var t=[];for(var r in e){if(z(e,r)){M(t,r)}}return t}return zt(e)});n=Object.keys}if(Object.getOwnPropertyNames){var qt=!i(function(){return Object.getOwnPropertyNames(\"foo\")});if(!qt){var Wt=typeof window===\"object\"?Object.getOwnPropertyNames(window):[];var Gt=Object.getOwnPropertyNames;ne(Object,\"getOwnPropertyNames\",function getOwnPropertyNames(e){var t=ce.ToObject(e);if(g(t)===\"[object Window]\"){try{return Gt(t)}catch(r){return P([],Wt)}}return Gt(t)})}}if(Object.getOwnPropertyDescriptor){var Ht=!i(function(){return Object.getOwnPropertyDescriptor(\"foo\",\"bar\")});if(!Ht){var Vt=Object.getOwnPropertyDescriptor;ne(Object,\"getOwnPropertyDescriptor\",function getOwnPropertyDescriptor(e,t){return Vt(ce.ToObject(e),t)})}}if(Object.seal){var Bt=!i(function(){return Object.seal(\"foo\")});if(!Bt){var Ut=Object.seal;ne(Object,\"seal\",function seal(e){if(!ce.TypeIsObject(e)){return e}return Ut(e)})}}if(Object.isSealed){var $t=!i(function(){return Object.isSealed(\"foo\")});if(!$t){var Jt=Object.isSealed;ne(Object,\"isSealed\",function isSealed(e){if(!ce.TypeIsObject(e)){return true}return Jt(e)})}}if(Object.freeze){var Xt=!i(function(){return Object.freeze(\"foo\")});if(!Xt){var Kt=Object.freeze;ne(Object,\"freeze\",function freeze(e){if(!ce.TypeIsObject(e)){return e}return Kt(e)})}}if(Object.isFrozen){var Zt=!i(function(){return Object.isFrozen(\"foo\")});if(!Zt){var Yt=Object.isFrozen;ne(Object,\"isFrozen\",function isFrozen(e){if(!ce.TypeIsObject(e)){return true}return Yt(e)})}}if(Object.preventExtensions){var Qt=!i(function(){return Object.preventExtensions(\"foo\")});if(!Qt){var er=Object.preventExtensions;ne(Object,\"preventExtensions\",function preventExtensions(e){if(!ce.TypeIsObject(e)){return e}return er(e)})}}if(Object.isExtensible){var tr=!i(function(){return Object.isExtensible(\"foo\")});if(!tr){var rr=Object.isExtensible;ne(Object,\"isExtensible\",function isExtensible(e){if(!ce.TypeIsObject(e)){return false}return rr(e)})}}if(Object.getPrototypeOf){var nr=!i(function(){return Object.getPrototypeOf(\"foo\")});if(!nr){var or=Object.getPrototypeOf;ne(Object,\"getPrototypeOf\",function getPrototypeOf(e){return or(ce.ToObject(e))})}}var ir=s&&function(){var e=Object.getOwnPropertyDescriptor(RegExp.prototype,\"flags\");return e&&ce.IsCallable(e.get)}();if(s&&!ir){var ar=function flags(){if(!ce.TypeIsObject(this)){throw new TypeError(\"Method called on incompatible type: must be an object.\")}var e=\"\";if(this.global){e+=\"g\"}if(this.ignoreCase){e+=\"i\"}if(this.multiline){e+=\"m\"}if(this.unicode){e+=\"u\"}if(this.sticky){e+=\"y\"}return e};m.getter(RegExp.prototype,\"flags\",ar)}var ur=s&&a(function(){return String(new RegExp(/a/g,\"i\"))===\"/a/i\"});var fr=oe&&s&&function(){var e=/./;e[$.match]=false;return RegExp(e)===e}();var sr=a(function(){return RegExp.prototype.toString.call({source:\"abc\"})===\"/abc/\"});var cr=sr&&a(function(){return RegExp.prototype.toString.call({source:\"a\",flags:\"b\"})===\"/a/b\"});if(!sr||!cr){var lr=RegExp.prototype.toString;h(RegExp.prototype,\"toString\",function toString(){var e=ce.RequireObjectCoercible(this);if(re.regex(e)){return t(lr,e)}var r=ue(e.source);var n=ue(e.flags);return\"/\"+r+\"/\"+n},true);m.preserveToString(RegExp.prototype.toString,lr)}if(s&&(!ur||fr)){var pr=Object.getOwnPropertyDescriptor(RegExp.prototype,\"flags\").get;var vr=Object.getOwnPropertyDescriptor(RegExp.prototype,\"source\")||{};var yr=function(){return this.source};var hr=ce.IsCallable(vr.get)?vr.get:yr;var br=RegExp;var gr=function(){return function RegExp(e,t){var r=ce.IsRegExp(e);var n=this instanceof RegExp;if(!n&&r&&typeof t===\"undefined\"&&e.constructor===RegExp){return e}var o=e;var i=t;if(re.regex(e)){o=ce.Call(hr,e);i=typeof t===\"undefined\"?ce.Call(pr,e):t;return new RegExp(o,i)}else if(r){o=e.source;i=typeof t===\"undefined\"?e.flags:t}return new br(e,t)}}();Ee(br,gr,{$input:true});RegExp=gr;m.redefine(S,\"RegExp\",gr)}if(s){var dr={input:\"$_\",lastMatch:\"$&\",lastParen:\"$+\",leftContext:\"$`\",rightContext:\"$'\"};l(n(dr),function(e){if(e in RegExp&&!(dr[e]in RegExp)){m.getter(RegExp,dr[e],function get(){return RegExp[e]})}})}Ce(RegExp);var mr=1/Number.EPSILON;var Or=function roundTiesToEven(e){return e+mr-mr};var wr=Math.pow(2,-23);var jr=Math.pow(2,127)*(2-wr);var Sr=Math.pow(2,-126);var Tr=Math.E;var Ir=Math.LOG2E;var Er=Math.LOG10E;var Pr=Number.prototype.clz;delete Number.prototype.clz;var Cr={acosh:function acosh(e){var t=Number(e);if(X(t)||e<1){return NaN}if(t===1){return 0}if(t===Infinity){return t}var r=1/(t*t);if(t<2){return Y(t-1+D(1-r)*t)}var n=t/2;return Y(n+D(1-r)*n-1)+1/Ir},asinh:function asinh(e){var t=Number(e);if(t===0||!T(t)){return t}var r=k(t);var n=r*r;var o=Z(t);if(r<1){return o*Y(r+n/(D(n+1)+1))}return o*(Y(r/2+D(1+1/n)*r/2-1)+1/Ir)},atanh:function atanh(e){var t=Number(e);if(t===0){return t}if(t===-1){return-Infinity}if(t===1){return Infinity}if(X(t)||t<-1||t>1){return NaN}var r=k(t);return Z(t)*Y(2*r/(1-r))/2},cbrt:function cbrt(e){var t=Number(e);if(t===0){return t}var r=t<0;var n;if(r){t=-t}if(t===Infinity){n=Infinity}else{n=L(F(t)/3);n=(t/(n*n)+2*n)/3}return r?-n:n},clz32:function clz32(e){var t=Number(e);var r=ce.ToUint32(t);if(r===0){return 32}return Pr?ce.Call(Pr,r):31-_(F(r+.5)*Ir)},cosh:function cosh(e){var t=Number(e);if(t===0){return 1}if(X(t)){return NaN}if(!T(t)){return Infinity}var r=L(k(t)-1);return(r+1/(r*Tr*Tr))*(Tr/2)},expm1:function expm1(e){var t=Number(e);if(t===-Infinity){return-1}if(!T(t)||t===0){return t}if(k(t)>.5){return L(t)-1}var r=t;var n=0;var o=1;while(n+r!==n){n+=r;o+=1;r*=t/o}return n},hypot:function hypot(e,t){var r=0;var n=0;for(var o=0;o<arguments.length;++o){var i=k(Number(arguments[o]));if(n<i){r*=n/i*(n/i);r+=1;n=i}else{r+=i>0?i/n*(i/n):i}}return n===Infinity?Infinity:n*D(r)},log2:function log2(e){return F(e)*Ir},log10:function log10(e){return F(e)*Er},log1p:Y,sign:Z,sinh:function sinh(e){var t=Number(e);if(!T(t)||t===0){return t}var r=k(t);if(r<1){var n=Math.expm1(r);return Z(t)*n*(1+1/(n+1))/2}var o=L(r-1);return Z(t)*(o-1/(o*Tr*Tr))*(Tr/2)},tanh:function tanh(e){var t=Number(e);if(X(t)||t===0){return t}if(t>=20){return 1}if(t<=-20){return-1}return(Math.expm1(t)-Math.expm1(-t))/(L(t)+L(-t))},trunc:function trunc(e){var t=Number(e);return t<0?-_(-t):_(t)},imul:function imul(e,t){var r=ce.ToUint32(e);var n=ce.ToUint32(t);var o=r>>>16&65535;var i=r&65535;var a=n>>>16&65535;var u=n&65535;return i*u+(o*u+i*a<<16>>>0)|0},fround:function fround(e){var t=Number(e);if(t===0||t===Infinity||t===-Infinity||X(t)){return t}var r=Z(t);var n=k(t);if(n<Sr){return r*Or(n/Sr/wr)*Sr*wr}var o=(1+wr/Number.EPSILON)*n;var i=o-(o-n);if(i>jr||X(i)){return r*Infinity}return r*i}};var Mr=function withinULPDistance(e,t,r){return k(1-e/t)/Number.EPSILON<(r||8)};b(Math,Cr);h(Math,\"sinh\",Cr.sinh,Math.sinh(710)===Infinity);h(Math,\"cosh\",Cr.cosh,Math.cosh(710)===Infinity);h(Math,\"log1p\",Cr.log1p,Math.log1p(-1e-17)!==-1e-17);h(Math,\"asinh\",Cr.asinh,Math.asinh(-1e7)!==-Math.asinh(1e7));h(Math,\"asinh\",Cr.asinh,Math.asinh(1e300)===Infinity);h(Math,\"atanh\",Cr.atanh,Math.atanh(1e-300)===0);h(Math,\"tanh\",Cr.tanh,Math.tanh(-2e-17)!==-2e-17);\nh(Math,\"acosh\",Cr.acosh,Math.acosh(Number.MAX_VALUE)===Infinity);h(Math,\"acosh\",Cr.acosh,!Mr(Math.acosh(1+Number.EPSILON),Math.sqrt(2*Number.EPSILON)));h(Math,\"cbrt\",Cr.cbrt,!Mr(Math.cbrt(1e-300),1e-100));h(Math,\"sinh\",Cr.sinh,Math.sinh(-2e-17)!==-2e-17);var xr=Math.expm1(10);h(Math,\"expm1\",Cr.expm1,xr>22025.465794806718||xr<22025.465794806718);var Nr=Math.round;var Ar=Math.round(.5-Number.EPSILON/4)===0&&Math.round(-.5+Number.EPSILON/3.99)===1;var Rr=mr+1;var _r=2*mr-1;var kr=[Rr,_r].every(function(e){return Math.round(e)===e});h(Math,\"round\",function round(e){var t=_(e);var r=t===-1?-0:t+1;return e-t<.5?t:r},!Ar||!kr);m.preserveToString(Math.round,Nr);var Lr=Math.imul;if(Math.imul(4294967295,5)!==-5){Math.imul=Cr.imul;m.preserveToString(Math.imul,Lr)}if(Math.imul.length!==2){ne(Math,\"imul\",function imul(e,t){return ce.Call(Lr,Math,arguments)})}var Fr=function(){var e=S.setTimeout;if(typeof e!==\"function\"&&typeof e!==\"object\"){return}ce.IsPromise=function(e){if(!ce.TypeIsObject(e)){return false}if(typeof e._promise===\"undefined\"){return false}return true};var r=function(e){if(!ce.IsConstructor(e)){throw new TypeError(\"Bad promise constructor\")}var t=this;var r=function(e,r){if(t.resolve!==void 0||t.reject!==void 0){throw new TypeError(\"Bad Promise implementation!\")}t.resolve=e;t.reject=r};t.resolve=void 0;t.reject=void 0;t.promise=new e(r);if(!(ce.IsCallable(t.resolve)&&ce.IsCallable(t.reject))){throw new TypeError(\"Bad promise constructor\")}};var n;if(typeof window!==\"undefined\"&&ce.IsCallable(window.postMessage)){n=function(){var e=[];var t=\"zero-timeout-message\";var r=function(r){M(e,r);window.postMessage(t,\"*\")};var n=function(r){if(r.source===window&&r.data===t){r.stopPropagation();if(e.length===0){return}var n=N(e);n()}};window.addEventListener(\"message\",n,true);return r}}var o=function(){var e=S.Promise;var t=e&&e.resolve&&e.resolve();return t&&function(e){return t.then(e)}};var i=ce.IsCallable(S.setImmediate)?S.setImmediate:typeof process===\"object\"&&process.nextTick?process.nextTick:o()||(ce.IsCallable(n)?n():function(t){e(t,0)});var a=function(e){return e};var u=function(e){throw e};var f=0;var s=1;var c=2;var l=0;var p=1;var v=2;var y={};var h=function(e,t,r){i(function(){g(e,t,r)})};var g=function(e,t,r){var n,o;if(t===y){return e(r)}try{n=e(r);o=t.resolve}catch(i){n=i;o=t.reject}o(n)};var d=function(e,t){var r=e._promise;var n=r.reactionLength;if(n>0){h(r.fulfillReactionHandler0,r.reactionCapability0,t);r.fulfillReactionHandler0=void 0;r.rejectReactions0=void 0;r.reactionCapability0=void 0;if(n>1){for(var o=1,i=0;o<n;o++,i+=3){h(r[i+l],r[i+v],t);e[i+l]=void 0;e[i+p]=void 0;e[i+v]=void 0}}}r.result=t;r.state=s;r.reactionLength=0};var m=function(e,t){var r=e._promise;var n=r.reactionLength;if(n>0){h(r.rejectReactionHandler0,r.reactionCapability0,t);r.fulfillReactionHandler0=void 0;r.rejectReactions0=void 0;r.reactionCapability0=void 0;if(n>1){for(var o=1,i=0;o<n;o++,i+=3){h(r[i+p],r[i+v],t);e[i+l]=void 0;e[i+p]=void 0;e[i+v]=void 0}}}r.result=t;r.state=c;r.reactionLength=0};var O=function(e){var t=false;var r=function(r){var n;if(t){return}t=true;if(r===e){return m(e,new TypeError(\"Self resolution\"))}if(!ce.TypeIsObject(r)){return d(e,r)}try{n=r.then}catch(o){return m(e,o)}if(!ce.IsCallable(n)){return d(e,r)}i(function(){j(e,r,n)})};var n=function(r){if(t){return}t=true;return m(e,r)};return{resolve:r,reject:n}};var w=function(e,r,n,o){if(e===I){t(e,r,n,o,y)}else{t(e,r,n,o)}};var j=function(e,t,r){var n=O(e);var o=n.resolve;var i=n.reject;try{w(r,t,o,i)}catch(a){i(a)}};var T,I;var E=function(){var e=function Promise(t){if(!(this instanceof e)){throw new TypeError('Constructor Promise requires \"new\"')}if(this&&this._promise){throw new TypeError(\"Bad construction\")}if(!ce.IsCallable(t)){throw new TypeError(\"not a valid resolver\")}var r=Ae(this,e,T,{_promise:{result:void 0,state:f,reactionLength:0,fulfillReactionHandler0:void 0,rejectReactionHandler0:void 0,reactionCapability0:void 0}});var n=O(r);var o=n.reject;try{t(n.resolve,o)}catch(i){o(i)}return r};return e}();T=E.prototype;var P=function(e,t,r,n){var o=false;return function(i){if(o){return}o=true;t[e]=i;if(--n.count===0){var a=r.resolve;a(t)}}};var C=function(e,t,r){var n=e.iterator;var o=[];var i={count:1};var a,u;var f=0;while(true){try{a=ce.IteratorStep(n);if(a===false){e.done=true;break}u=a.value}catch(s){e.done=true;throw s}o[f]=void 0;var c=t.resolve(u);var l=P(f,o,r,i);i.count+=1;w(c.then,c,l,r.reject);f+=1}if(--i.count===0){var p=r.resolve;p(o)}return r.promise};var x=function(e,t,r){var n=e.iterator;var o,i,a;while(true){try{o=ce.IteratorStep(n);if(o===false){e.done=true;break}i=o.value}catch(u){e.done=true;throw u}a=t.resolve(i);w(a.then,a,r.resolve,r.reject)}return r.promise};b(E,{all:function all(e){var t=this;if(!ce.TypeIsObject(t)){throw new TypeError(\"Promise is not object\")}var n=new r(t);var o,i;try{o=ce.GetIterator(e);i={iterator:o,done:false};return C(i,t,n)}catch(a){var u=a;if(i&&!i.done){try{ce.IteratorClose(o,true)}catch(f){u=f}}var s=n.reject;s(u);return n.promise}},race:function race(e){var t=this;if(!ce.TypeIsObject(t)){throw new TypeError(\"Promise is not object\")}var n=new r(t);var o,i;try{o=ce.GetIterator(e);i={iterator:o,done:false};return x(i,t,n)}catch(a){var u=a;if(i&&!i.done){try{ce.IteratorClose(o,true)}catch(f){u=f}}var s=n.reject;s(u);return n.promise}},reject:function reject(e){var t=this;if(!ce.TypeIsObject(t)){throw new TypeError(\"Bad promise constructor\")}var n=new r(t);var o=n.reject;o(e);return n.promise},resolve:function resolve(e){var t=this;if(!ce.TypeIsObject(t)){throw new TypeError(\"Bad promise constructor\")}if(ce.IsPromise(e)){var n=e.constructor;if(n===t){return e}}var o=new r(t);var i=o.resolve;i(e);return o.promise}});b(T,{\"catch\":function(e){return this.then(null,e)},then:function then(e,t){var n=this;if(!ce.IsPromise(n)){throw new TypeError(\"not a promise\")}var o=ce.SpeciesConstructor(n,E);var i;var b=arguments.length>2&&arguments[2]===y;if(b&&o===E){i=y}else{i=new r(o)}var g=ce.IsCallable(e)?e:a;var d=ce.IsCallable(t)?t:u;var m=n._promise;var O;if(m.state===f){if(m.reactionLength===0){m.fulfillReactionHandler0=g;m.rejectReactionHandler0=d;m.reactionCapability0=i}else{var w=3*(m.reactionLength-1);m[w+l]=g;m[w+p]=d;m[w+v]=i}m.reactionLength+=1}else if(m.state===s){O=m.result;h(g,i,O)}else if(m.state===c){O=m.result;h(d,i,O)}else{throw new TypeError(\"unexpected Promise state\")}return i.promise}});y=new r(E);I=T.then;return E}();if(S.Promise){delete S.Promise.accept;delete S.Promise.defer;delete S.Promise.prototype.chain}if(typeof Fr===\"function\"){b(S,{Promise:Fr});var Dr=w(S.Promise,function(e){return e.resolve(42).then(function(){})instanceof e});var zr=!i(function(){return S.Promise.reject(42).then(null,5).then(null,W)});var qr=i(function(){return S.Promise.call(3,W)});var Wr=function(e){var t=e.resolve(5);t.constructor={};var r=e.resolve(t);try{r.then(null,W).then(null,W)}catch(n){return true}return t===r}(S.Promise);var Gr=s&&function(){var e=0;var t=Object.defineProperty({},\"then\",{get:function(){e+=1}});Promise.resolve(t);return e===1}();var Hr=function BadResolverPromise(e){var t=new Promise(e);e(3,function(){});this.then=t.then;this.constructor=BadResolverPromise};Hr.prototype=Promise.prototype;Hr.all=Promise.all;var Vr=a(function(){return!!Hr.all([1,2])});if(!Dr||!zr||!qr||Wr||!Gr||Vr){Promise=Fr;ne(S,\"Promise\",Fr)}if(Promise.all.length!==1){var Br=Promise.all;ne(Promise,\"all\",function all(e){return ce.Call(Br,this,arguments)})}if(Promise.race.length!==1){var Ur=Promise.race;ne(Promise,\"race\",function race(e){return ce.Call(Ur,this,arguments)})}if(Promise.resolve.length!==1){var $r=Promise.resolve;ne(Promise,\"resolve\",function resolve(e){return ce.Call($r,this,arguments)})}if(Promise.reject.length!==1){var Jr=Promise.reject;ne(Promise,\"reject\",function reject(e){return ce.Call(Jr,this,arguments)})}Mt(Promise,\"all\");Mt(Promise,\"race\");Mt(Promise,\"resolve\");Mt(Promise,\"reject\");Ce(Promise)}var Xr=function(e){var t=n(p(e,function(e,t){e[t]=true;return e},{}));return e.join(\":\")===t.join(\":\")};var Kr=Xr([\"z\",\"a\",\"bb\"]);var Zr=Xr([\"z\",1,\"a\",\"3\",2]);if(s){var Yr=function fastkey(e,t){if(!t&&!Kr){return null}if(se(e)){return\"^\"+ce.ToString(e)}else if(typeof e===\"string\"){return\"$\"+e}else if(typeof e===\"number\"){if(!Zr){return\"n\"+e}return e}else if(typeof e===\"boolean\"){return\"b\"+e}return null};var Qr=function emptyObject(){return Object.create?Object.create(null):{}};var en=function addIterableToMap(e,n,o){if(r(o)||re.string(o)){l(o,function(e){if(!ce.TypeIsObject(e)){throw new TypeError(\"Iterator value \"+e+\" is not an entry object\")}n.set(e[0],e[1])})}else if(o instanceof e){t(e.prototype.forEach,o,function(e,t){n.set(t,e)})}else{var i,a;if(!se(o)){a=n.set;if(!ce.IsCallable(a)){throw new TypeError(\"bad map\")}i=ce.GetIterator(o)}if(typeof i!==\"undefined\"){while(true){var u=ce.IteratorStep(i);if(u===false){break}var f=u.value;try{if(!ce.TypeIsObject(f)){throw new TypeError(\"Iterator value \"+f+\" is not an entry object\")}t(a,n,f[0],f[1])}catch(s){ce.IteratorClose(i,true);throw s}}}}};var tn=function addIterableToSet(e,n,o){if(r(o)||re.string(o)){l(o,function(e){n.add(e)})}else if(o instanceof e){t(e.prototype.forEach,o,function(e){n.add(e)})}else{var i,a;if(!se(o)){a=n.add;if(!ce.IsCallable(a)){throw new TypeError(\"bad set\")}i=ce.GetIterator(o)}if(typeof i!==\"undefined\"){while(true){var u=ce.IteratorStep(i);if(u===false){break}var f=u.value;try{t(a,n,f)}catch(s){ce.IteratorClose(i,true);throw s}}}}};var rn={Map:function(){var e={};var r=function MapEntry(e,t){this.key=e;this.value=t;this.next=null;this.prev=null};r.prototype.isRemoved=function isRemoved(){return this.key===e};var n=function isMap(e){return!!e._es6map};var o=function requireMapSlot(e,t){if(!ce.TypeIsObject(e)||!n(e)){throw new TypeError(\"Method Map.prototype.\"+t+\" called on incompatible receiver \"+ce.ToString(e))}};var i=function MapIterator(e,t){o(e,\"[[MapIterator]]\");this.head=e._head;this.i=this.head;this.kind=t};i.prototype={isMapIterator:true,next:function next(){if(!this.isMapIterator){throw new TypeError(\"Not a MapIterator\")}var e=this.i;var t=this.kind;var r=this.head;if(typeof this.i===\"undefined\"){return Ke()}while(e.isRemoved()&&e!==r){e=e.prev}var n;while(e.next!==r){e=e.next;if(!e.isRemoved()){if(t===\"key\"){n=e.key}else if(t===\"value\"){n=e.value}else{n=[e.key,e.value]}this.i=e;return Ke(n)}}this.i=void 0;return Ke()}};Me(i.prototype);var a;var u=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires \"new\"')}if(this&&this._es6map){throw new TypeError(\"Bad construction\")}var e=Ae(this,Map,a,{_es6map:true,_head:null,_map:G?new G:null,_size:0,_storage:Qr()});var t=new r(null,null);t.next=t.prev=t;e._head=t;if(arguments.length>0){en(Map,e,arguments[0])}return e};a=u.prototype;m.getter(a,\"size\",function(){if(typeof this._size===\"undefined\"){throw new TypeError(\"size method called on incompatible Map\")}return this._size});b(a,{get:function get(e){o(this,\"get\");var t;var r=Yr(e,true);if(r!==null){t=this._storage[r];if(t){return t.value}else{return}}if(this._map){t=V.call(this._map,e);if(t){return t.value}else{return}}var n=this._head;var i=n;while((i=i.next)!==n){if(ce.SameValueZero(i.key,e)){return i.value}}},has:function has(e){o(this,\"has\");var t=Yr(e,true);if(t!==null){return typeof this._storage[t]!==\"undefined\"}if(this._map){return B.call(this._map,e)}var r=this._head;var n=r;while((n=n.next)!==r){if(ce.SameValueZero(n.key,e)){return true}}return false},set:function set(e,t){o(this,\"set\");var n=this._head;var i=n;var a;var u=Yr(e,true);if(u!==null){if(typeof this._storage[u]!==\"undefined\"){this._storage[u].value=t;return this}else{a=this._storage[u]=new r(e,t);i=n.prev}}else if(this._map){if(B.call(this._map,e)){V.call(this._map,e).value=t}else{a=new r(e,t);U.call(this._map,e,a);i=n.prev}}while((i=i.next)!==n){if(ce.SameValueZero(i.key,e)){i.value=t;return this}}a=a||new r(e,t);if(ce.SameValue(-0,e)){a.key=+0}a.next=this._head;a.prev=this._head.prev;a.prev.next=a;a.next.prev=a;this._size+=1;return this},\"delete\":function(t){o(this,\"delete\");var r=this._head;var n=r;var i=Yr(t,true);if(i!==null){if(typeof this._storage[i]===\"undefined\"){return false}n=this._storage[i].prev;delete this._storage[i]}else if(this._map){if(!B.call(this._map,t)){return false}n=V.call(this._map,t).prev;H.call(this._map,t)}while((n=n.next)!==r){if(ce.SameValueZero(n.key,t)){n.key=e;n.value=e;n.prev.next=n.next;n.next.prev=n.prev;this._size-=1;return true}}return false},clear:function clear(){o(this,\"clear\");this._map=G?new G:null;this._size=0;this._storage=Qr();var t=this._head;var r=t;var n=r.next;while((r=n)!==t){r.key=e;r.value=e;n=r.next;r.next=r.prev=t}t.next=t.prev=t},keys:function keys(){o(this,\"keys\");return new i(this,\"key\")},values:function values(){o(this,\"values\");return new i(this,\"value\")},entries:function entries(){o(this,\"entries\");return new i(this,\"key+value\")},forEach:function forEach(e){o(this,\"forEach\");var r=arguments.length>1?arguments[1]:null;var n=this.entries();for(var i=n.next();!i.done;i=n.next()){if(r){t(e,r,i.value[1],i.value[0],this)}else{e(i.value[1],i.value[0],this)}}}});Me(a,a.entries);return u}(),Set:function(){var e=function isSet(e){return e._es6set&&typeof e._storage!==\"undefined\"};var r=function requireSetSlot(t,r){if(!ce.TypeIsObject(t)||!e(t)){throw new TypeError(\"Set.prototype.\"+r+\" called on incompatible receiver \"+ce.ToString(t))}};var o;var i=function Set(){if(!(this instanceof Set)){throw new TypeError('Constructor Set requires \"new\"')}if(this&&this._es6set){throw new TypeError(\"Bad construction\")}var e=Ae(this,Set,o,{_es6set:true,\"[[SetData]]\":null,_storage:Qr()});if(!e._es6set){throw new TypeError(\"bad set\")}if(arguments.length>0){tn(Set,e,arguments[0])}return e};o=i.prototype;var a=function(e){var t=e;if(t===\"^null\"){return null}else if(t===\"^undefined\"){return void 0}else{var r=t.charAt(0);if(r===\"$\"){return C(t,1)}else if(r===\"n\"){return+C(t,1)}else if(r===\"b\"){return t===\"btrue\"}}return+t};var u=function ensureMap(e){if(!e[\"[[SetData]]\"]){var t=new rn.Map;e[\"[[SetData]]\"]=t;l(n(e._storage),function(e){var r=a(e);t.set(r,r)});e[\"[[SetData]]\"]=t}e._storage=null};m.getter(i.prototype,\"size\",function(){r(this,\"size\");if(this._storage){return n(this._storage).length}u(this);return this[\"[[SetData]]\"].size});b(i.prototype,{has:function has(e){r(this,\"has\");var t;if(this._storage&&(t=Yr(e))!==null){return!!this._storage[t]}u(this);return this[\"[[SetData]]\"].has(e)},add:function add(e){r(this,\"add\");var t;if(this._storage&&(t=Yr(e))!==null){this._storage[t]=true;return this}u(this);this[\"[[SetData]]\"].set(e,e);return this},\"delete\":function(e){r(this,\"delete\");var t;if(this._storage&&(t=Yr(e))!==null){var n=z(this._storage,t);return delete this._storage[t]&&n}u(this);return this[\"[[SetData]]\"][\"delete\"](e)},clear:function clear(){r(this,\"clear\");if(this._storage){this._storage=Qr()}if(this[\"[[SetData]]\"]){this[\"[[SetData]]\"].clear()}},values:function values(){r(this,\"values\");u(this);return new f(this[\"[[SetData]]\"].values())},entries:function entries(){r(this,\"entries\");u(this);return new f(this[\"[[SetData]]\"].entries())},forEach:function forEach(e){r(this,\"forEach\");var n=arguments.length>1?arguments[1]:null;var o=this;u(o);this[\"[[SetData]]\"].forEach(function(r,i){if(n){t(e,n,i,i,o)}else{e(i,i,o)}})}});h(i.prototype,\"keys\",i.prototype.values,true);Me(i.prototype,i.prototype.values);var f=function SetIterator(e){this.it=e};f.prototype={isSetIterator:true,next:function next(){if(!this.isSetIterator){throw new TypeError(\"Not a SetIterator\")}return this.it.next()}};Me(f.prototype);return i}()};var nn=S.Set&&!Set.prototype[\"delete\"]&&Set.prototype.remove&&Set.prototype.items&&Set.prototype.map&&Array.isArray((new Set).keys);if(nn){S.Set=rn.Set}if(S.Map||S.Set){var on=a(function(){return new Map([[1,2]]).get(1)===2});if(!on){S.Map=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires \"new\"')}var e=new G;if(arguments.length>0){en(Map,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,S.Map.prototype);return e};S.Map.prototype=O(G.prototype);h(S.Map.prototype,\"constructor\",S.Map,true);m.preserveToString(S.Map,G)}var an=new Map;var un=function(){var e=new Map([[1,0],[2,0],[3,0],[4,0]]);e.set(-0,e);return e.get(0)===e&&e.get(-0)===e&&e.has(0)&&e.has(-0)}();var fn=an.set(1,2)===an;if(!un||!fn){ne(Map.prototype,\"set\",function set(e,r){t(U,this,e===0?0:e,r);return this})}if(!un){b(Map.prototype,{get:function get(e){return t(V,this,e===0?0:e)},has:function has(e){return t(B,this,e===0?0:e)}},true);m.preserveToString(Map.prototype.get,V);m.preserveToString(Map.prototype.has,B)}var sn=new Set;var cn=Set.prototype[\"delete\"]&&Set.prototype.add&&Set.prototype.has&&function(e){e[\"delete\"](0);e.add(-0);return!e.has(0)}(sn);var ln=sn.add(1)===sn;if(!cn||!ln){var pn=Set.prototype.add;Set.prototype.add=function add(e){t(pn,this,e===0?0:e);return this};m.preserveToString(Set.prototype.add,pn)}if(!cn){var vn=Set.prototype.has;Set.prototype.has=function has(e){return t(vn,this,e===0?0:e)};m.preserveToString(Set.prototype.has,vn);var yn=Set.prototype[\"delete\"];Set.prototype[\"delete\"]=function SetDelete(e){return t(yn,this,e===0?0:e)};m.preserveToString(Set.prototype[\"delete\"],yn)}var hn=w(S.Map,function(e){var t=new e([]);t.set(42,42);return t instanceof e});var bn=Object.setPrototypeOf&&!hn;var gn=function(){try{return!(S.Map()instanceof S.Map)}catch(e){return e instanceof TypeError}}();if(S.Map.length!==0||bn||!gn){S.Map=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires \"new\"')}var e=new G;if(arguments.length>0){en(Map,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,Map.prototype);return e};S.Map.prototype=G.prototype;h(S.Map.prototype,\"constructor\",S.Map,true);m.preserveToString(S.Map,G)}var dn=w(S.Set,function(e){var t=new e([]);t.add(42,42);return t instanceof e});var mn=Object.setPrototypeOf&&!dn;var On=function(){try{return!(S.Set()instanceof S.Set)}catch(e){return e instanceof TypeError}}();if(S.Set.length!==0||mn||!On){var wn=S.Set;S.Set=function Set(){if(!(this instanceof Set)){throw new TypeError('Constructor Set requires \"new\"')}var e=new wn;if(arguments.length>0){tn(Set,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,Set.prototype);return e};S.Set.prototype=wn.prototype;h(S.Set.prototype,\"constructor\",S.Set,true);m.preserveToString(S.Set,wn)}var jn=new S.Map;var Sn=!a(function(){return jn.keys().next().done});if(typeof S.Map.prototype.clear!==\"function\"||(new S.Set).size!==0||jn.size!==0||typeof S.Map.prototype.keys!==\"function\"||typeof S.Set.prototype.keys!==\"function\"||typeof S.Map.prototype.forEach!==\"function\"||typeof S.Set.prototype.forEach!==\"function\"||u(S.Map)||u(S.Set)||typeof jn.keys().next!==\"function\"||Sn||!hn){b(S,{Map:rn.Map,Set:rn.Set},true)}if(S.Set.prototype.keys!==S.Set.prototype.values){h(S.Set.prototype,\"keys\",S.Set.prototype.values,true)}Me(Object.getPrototypeOf((new S.Map).keys()));Me(Object.getPrototypeOf((new S.Set).keys()));if(c&&S.Set.prototype.has.name!==\"has\"){var Tn=S.Set.prototype.has;ne(S.Set.prototype,\"has\",function has(e){return t(Tn,this,e)})}}b(S,rn);Ce(S.Map);Ce(S.Set)}var In=function throwUnlessTargetIsObject(e){if(!ce.TypeIsObject(e)){throw new TypeError(\"target must be an object\")}};var En={apply:function apply(){return ce.Call(ce.Call,null,arguments)},construct:function construct(e,t){if(!ce.IsConstructor(e)){throw new TypeError(\"First argument must be a constructor.\")}var r=arguments.length>2?arguments[2]:e;if(!ce.IsConstructor(r)){throw new TypeError(\"new.target must be a constructor.\")}return ce.Construct(e,t,r,\"internal\")},deleteProperty:function deleteProperty(e,t){In(e);if(s){var r=Object.getOwnPropertyDescriptor(e,t);if(r&&!r.configurable){return false}}return delete e[t]},has:function has(e,t){In(e);return t in e}};if(Object.getOwnPropertyNames){Object.assign(En,{ownKeys:function ownKeys(e){In(e);var t=Object.getOwnPropertyNames(e);if(ce.IsCallable(Object.getOwnPropertySymbols)){x(t,Object.getOwnPropertySymbols(e))}return t}})}var Pn=function ConvertExceptionToBoolean(e){return!i(e)};if(Object.preventExtensions){Object.assign(En,{isExtensible:function isExtensible(e){In(e);return Object.isExtensible(e)},preventExtensions:function preventExtensions(e){In(e);return Pn(function(){return Object.preventExtensions(e)})}})}if(s){var Cn=function get(e,t,r){var n=Object.getOwnPropertyDescriptor(e,t);if(!n){var o=Object.getPrototypeOf(e);if(o===null){return void 0}return Cn(o,t,r)}if(\"value\"in n){return n.value}if(n.get){return ce.Call(n.get,r)}return void 0};var Mn=function set(e,r,n,o){var i=Object.getOwnPropertyDescriptor(e,r);if(!i){var a=Object.getPrototypeOf(e);if(a!==null){return Mn(a,r,n,o)}i={value:void 0,writable:true,enumerable:true,configurable:true}}if(\"value\"in i){if(!i.writable){return false}if(!ce.TypeIsObject(o)){return false}var u=Object.getOwnPropertyDescriptor(o,r);if(u){return ae.defineProperty(o,r,{value:n})}else{return ae.defineProperty(o,r,{value:n,writable:true,enumerable:true,configurable:true})}}if(i.set){t(i.set,o,n);return true}return false};Object.assign(En,{defineProperty:function defineProperty(e,t,r){In(e);return Pn(function(){return Object.defineProperty(e,t,r)})},getOwnPropertyDescriptor:function getOwnPropertyDescriptor(e,t){In(e);return Object.getOwnPropertyDescriptor(e,t)},get:function get(e,t){In(e);var r=arguments.length>2?arguments[2]:e;return Cn(e,t,r)},set:function set(e,t,r){In(e);var n=arguments.length>3?arguments[3]:e;return Mn(e,t,r,n)}})}if(Object.getPrototypeOf){var xn=Object.getPrototypeOf;En.getPrototypeOf=function getPrototypeOf(e){In(e);return xn(e)}}if(Object.setPrototypeOf&&En.getPrototypeOf){var Nn=function(e,t){var r=t;while(r){if(e===r){return true}r=En.getPrototypeOf(r)}return false};Object.assign(En,{setPrototypeOf:function setPrototypeOf(e,t){In(e);if(t!==null&&!ce.TypeIsObject(t)){throw new TypeError(\"proto must be an object or null\")}if(t===ae.getPrototypeOf(e)){return true}if(ae.isExtensible&&!ae.isExtensible(e)){return false}if(Nn(e,t)){return false}Object.setPrototypeOf(e,t);return true}})}var An=function(e,t){if(!ce.IsCallable(S.Reflect[e])){h(S.Reflect,e,t)}else{var r=a(function(){S.Reflect[e](1);S.Reflect[e](NaN);S.Reflect[e](true);return true});if(r){ne(S.Reflect,e,t)}}};Object.keys(En).forEach(function(e){An(e,En[e])});var Rn=S.Reflect.getPrototypeOf;if(c&&Rn&&Rn.name!==\"getPrototypeOf\"){ne(S.Reflect,\"getPrototypeOf\",function getPrototypeOf(e){return t(Rn,S.Reflect,e)})}if(S.Reflect.setPrototypeOf){if(a(function(){S.Reflect.setPrototypeOf(1,{});return true})){ne(S.Reflect,\"setPrototypeOf\",En.setPrototypeOf)}}if(S.Reflect.defineProperty){if(!a(function(){var e=!S.Reflect.defineProperty(1,\"test\",{value:1});var t=typeof Object.preventExtensions!==\"function\"||!S.Reflect.defineProperty(Object.preventExtensions({}),\"test\",{});return e&&t})){ne(S.Reflect,\"defineProperty\",En.defineProperty)}}if(S.Reflect.construct){if(!a(function(){var e=function F(){};return S.Reflect.construct(function(){},[],e)instanceof e})){ne(S.Reflect,\"construct\",En.construct)}}if(String(new Date(NaN))!==\"Invalid Date\"){var _n=Date.prototype.toString;var kn=function toString(){var e=+this;if(e!==e){return\"Invalid Date\"}return ce.Call(_n,this)};ne(Date.prototype,\"toString\",kn)}var Ln={anchor:function anchor(e){return ce.CreateHTML(this,\"a\",\"name\",e)},big:function big(){return ce.CreateHTML(this,\"big\",\"\",\"\")},blink:function blink(){return ce.CreateHTML(this,\"blink\",\"\",\"\")},bold:function bold(){return ce.CreateHTML(this,\"b\",\"\",\"\")},fixed:function fixed(){return ce.CreateHTML(this,\"tt\",\"\",\"\")},fontcolor:function fontcolor(e){return ce.CreateHTML(this,\"font\",\"color\",e)},fontsize:function fontsize(e){return ce.CreateHTML(this,\"font\",\"size\",e)},italics:function italics(){return ce.CreateHTML(this,\"i\",\"\",\"\")},link:function link(e){return ce.CreateHTML(this,\"a\",\"href\",e)},small:function small(){return ce.CreateHTML(this,\"small\",\"\",\"\")},strike:function strike(){return ce.CreateHTML(this,\"strike\",\"\",\"\")},sub:function sub(){return ce.CreateHTML(this,\"sub\",\"\",\"\")},sup:function sub(){return ce.CreateHTML(this,\"sup\",\"\",\"\")}};l(Object.keys(Ln),function(e){var r=String.prototype[e];var n=false;if(ce.IsCallable(r)){var o=t(r,\"\",' \" ');var i=P([],o.match(/\"/g)).length;n=o!==o.toLowerCase()||i>2}else{n=true}if(n){ne(String.prototype,e,Ln[e])}});var Fn=function(){if(!oe){return false}var e=typeof JSON===\"object\"&&typeof JSON.stringify===\"function\"?JSON.stringify:null;if(!e){return false}if(typeof e($())!==\"undefined\"){return true}if(e([$()])!==\"[null]\"){return true}var t={a:$()};t[$()]=true;if(e(t)!==\"{}\"){return true}return false}();var Dn=a(function(){if(!oe){return true}return JSON.stringify(Object($()))===\"{}\"&&JSON.stringify([Object($())])===\"[{}]\"});if(Fn||!Dn){var zn=JSON.stringify;ne(JSON,\"stringify\",function stringify(e){if(typeof e===\"symbol\"){return}var n;if(arguments.length>1){n=arguments[1]}var o=[e];if(!r(n)){var i=ce.IsCallable(n)?n:null;var a=function(e,r){var n=i?t(i,this,e,r):r;if(typeof n!==\"symbol\"){if(re.symbol(n)){return Nt({})(n)}else{return n}}};o.push(a)}else{o.push(n)}if(arguments.length>2){o.push(arguments[2])}return zn.apply(this,o)})}return S});\n/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */\n!function(e,t){\"use strict\";\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(ie,e){\"use strict\";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return\"function\"==typeof e&&\"number\"!=typeof e.nodeType&&\"function\"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement(\"script\");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?n[i.call(e)]||\"object\":typeof e}var t=\"3.7.1\",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&\"length\"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&0<t&&t-1 in e)}function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}ce.fn=ce.prototype={jquery:t,constructor:ce,length:0,toArray:function(){return ae.call(this)},get:function(e){return null==e?ae.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=ce.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return ce.each(this,e)},map:function(n){return this.pushStack(ce.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(ae.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ce.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(ce.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:oe.sort,splice:oe.splice},ce.extend=ce.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||v(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],\"__proto__\"!==t&&a!==r&&(l&&r&&(ce.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||ce.isPlainObject(n)?n:{},i=!1,a[t]=ce.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},ce.extend({expando:\"jQuery\"+(t+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==i.call(e))&&(!(t=r(e))||\"function\"==typeof(n=ue.call(t,\"constructor\")&&t.constructor)&&o.call(n)===a)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){m(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(c(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},text:function(e){var t,n=\"\",r=0,i=e.nodeType;if(!i)while(t=e[r++])n+=ce.text(t);return 1===i||11===i?e.textContent:9===i?e.documentElement.textContent:3===i||4===i?e.nodeValue:n},makeArray:function(e,t){var n=t||[];return null!=e&&(c(Object(e))?ce.merge(n,\"string\"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},isXMLDoc:function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!l.test(t||n&&n.nodeName||\"HTML\")},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(c(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:le}),\"function\"==typeof Symbol&&(ce.fn[Symbol.iterator]=oe[Symbol.iterator]),ce.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){n[\"[object \"+t+\"]\"]=t.toLowerCase()});var pe=oe.pop,de=oe.sort,he=oe.splice,ge=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",ve=new RegExp(\"^\"+ge+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ge+\"+$\",\"g\");ce.contains=function(e,t){var n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(e.contains?e.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))};var f=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g;function p(e,t){return t?\"\\0\"===e?\"\\ufffd\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e}ce.escapeSelector=function(e){return(e+\"\").replace(f,p)};var ye=C,me=s;!function(){var e,b,w,o,a,T,r,C,d,i,k=me,S=ce.expando,E=0,n=0,s=W(),c=W(),u=W(),h=W(),l=function(e,t){return e===t&&(a=!0),0},f=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",t=\"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\"+ge+\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",p=\"\\\\[\"+ge+\"*(\"+t+\")(?:\"+ge+\"*([*^$|!~]?=)\"+ge+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+t+\"))|)\"+ge+\"*\\\\]\",g=\":(\"+t+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+p+\")*)|.*)\\\\)|)\",v=new RegExp(ge+\"+\",\"g\"),y=new RegExp(\"^\"+ge+\"*,\"+ge+\"*\"),m=new RegExp(\"^\"+ge+\"*([>+~]|\"+ge+\")\"+ge+\"*\"),x=new RegExp(ge+\"|>\"),j=new RegExp(g),A=new RegExp(\"^\"+t+\"$\"),D={ID:new RegExp(\"^#(\"+t+\")\"),CLASS:new RegExp(\"^\\\\.(\"+t+\")\"),TAG:new RegExp(\"^(\"+t+\"|[*])\"),ATTR:new RegExp(\"^\"+p),PSEUDO:new RegExp(\"^\"+g),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ge+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ge+\"*(?:([+-]|)\"+ge+\"*(\\\\d+)|))\"+ge+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+f+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ge+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ge+\"*((?:-\\\\d)?\\\\d*)\"+ge+\"*\\\\)|)(?=[^-]|$)\",\"i\")},N=/^(?:input|select|textarea|button)$/i,q=/^h\\d$/i,L=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,H=/[+~]/,O=new RegExp(\"\\\\\\\\[\\\\da-fA-F]{1,6}\"+ge+\"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\",\"g\"),P=function(e,t){var n=\"0x\"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,\"fieldset\")},{dir:\"parentNode\",next:\"legend\"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],\"string\"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+\" \"]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute(\"id\"))?s=ce.escapeSelector(s):e.setAttribute(\"id\",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?\"#\"+s:\":scope\")+\" \"+Q(l[o]);c=l.join(\",\")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute(\"id\")}}}return re(t.replace(ve,\"$1\"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+\" \")>b.cacheLength&&delete e[r.shift()],e[t+\" \"]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,\"input\")&&e.type===t}}function _(t){return function(e){return(fe(e,\"input\")||fe(e,\"button\"))&&e.type===t}}function z(t){return function(e){return\"form\"in e?e.parentNode&&!1===e.disabled?\"label\"in e?\"label\"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:\"label\"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener(\"unload\",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,\"*\")}),le.scope=$(function(){return T.querySelectorAll(\":scope\")}),le.cssHas=$(function(){try{return T.querySelector(\":has(*,:jqfake)\"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute(\"id\")===t}},b.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return t&&t.value===n}},b.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML=\"<a id='\"+S+\"' href='' disabled='disabled'></a><select id='\"+S+\"-\\r\\\\' disabled='disabled'><option selected=''></option></select>\",e.querySelectorAll(\"[selected]\").length||d.push(\"\\\\[\"+ge+\"*(?:value|\"+f+\")\"),e.querySelectorAll(\"[id~=\"+S+\"-]\").length||d.push(\"~=\"),e.querySelectorAll(\"a#\"+S+\"+*\").length||d.push(\".#.+[+~]\"),e.querySelectorAll(\":checked\").length||d.push(\":checked\"),(t=T.createElement(\"input\")).setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&d.push(\":enabled\",\":disabled\"),(t=T.createElement(\"input\")).setAttribute(\"name\",\"\"),e.appendChild(t),e.querySelectorAll(\"[name='']\").length||d.push(\"\\\\[\"+ge+\"*name\"+ge+\"*=\"+ge+\"*(?:''|\\\"\\\")\")}),le.cssHas||d.push(\":has\"),d=d.length&&new RegExp(d.join(\"|\")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+\" \"]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0<I(t,T,null,[e]).length},I.contains=function(e,t){return(e.ownerDocument||e)!=T&&V(e),ce.contains(e,t)},I.attr=function(e,t){(e.ownerDocument||e)!=T&&V(e);var n=b.attrHandle[t.toLowerCase()],r=n&&ue.call(b.attrHandle,t.toLowerCase())?n(e,t,!C):void 0;return void 0!==r?r:e.getAttribute(t)},I.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},ce.uniqueSort=function(e){var t,n=[],r=0,i=0;if(a=!le.sortStable,o=!le.sortStable&&ae.call(e,0),de.call(e,l),a){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)he.call(e,n[r],1)}return o=null,e},ce.fn.uniqueSort=function(){return this.pushStack(ce.uniqueSort(ae.apply(this)))},(b=ce.expr={cacheLength:50,createPseudo:F,match:D,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||\"\").replace(O,P),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+\" \"];return t||(t=new RegExp(\"(^|\"+ge+\")\"+e+\"(\"+ge+\"|$)\"))&&s(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?\"!=\"===r:!r||(t+=\"\",\"=\"===r?t===i:\"!=\"===r?t!==i:\"^=\"===r?i&&0===t.indexOf(i):\"*=\"===r?i&&-1<t.indexOf(i):\"$=\"===r?i&&t.slice(-i.length)===i:\"~=\"===r?-1<(\" \"+t.replace(v,\" \")+\" \").indexOf(i):\"|=\"===r&&(t===i||t.slice(0,i.length+1)===i+\"-\"))}},CHILD:function(d,e,t,h,g){var v=\"nth\"!==d.slice(0,3),y=\"last\"!==d.slice(-4),m=\"of-type\"===e;return 1===h&&0===g?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u=v!==y?\"nextSibling\":\"previousSibling\",l=e.parentNode,c=m&&e.nodeName.toLowerCase(),f=!n&&!m,p=!1;if(l){if(v){while(u){o=e;while(o=o[u])if(m?fe(o,c):1===o.nodeType)return!1;s=u=\"only\"===d&&!s&&\"nextSibling\"}return!0}if(s=[y?l.firstChild:l.lastChild],y&&f){p=(a=(r=(i=l[S]||(l[S]={}))[d]||[])[0]===E&&r[1])&&r[2],o=a&&l.childNodes[a];while(o=++a&&o&&o[u]||(p=a=0)||s.pop())if(1===o.nodeType&&++p&&o===e){i[d]=[E,a,p];break}}else if(f&&(p=a=(r=(i=e[S]||(e[S]={}))[d]||[])[0]===E&&r[1]),!1===p)while(o=++a&&o&&o[u]||(p=a=0)||s.pop())if((m?fe(o,c):1===o.nodeType)&&++p&&(f&&((i=o[S]||(o[S]={}))[d]=[E,p]),o===e))break;return(p-=g)===h||p%h==0&&0<=p/h}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||I.error(\"unsupported pseudo: \"+e);return a[S]?a(o):1<a.length?(t=[e,e,\"\",o],b.setFilters.hasOwnProperty(e.toLowerCase())?F(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=se.call(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:F(function(e){var r=[],i=[],s=ne(e.replace(ve,\"$1\"));return s[S]?F(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:F(function(t){return function(e){return 0<I(t,e).length}}),contains:F(function(t){return t=t.replace(O,P),function(e){return-1<(e.textContent||ce.text(e)).indexOf(t)}}),lang:F(function(n){return A.test(n||\"\")||I.error(\"unsupported lang: \"+n),n=n.replace(O,P).toLowerCase(),function(e){var t;do{if(t=C?e.lang:e.getAttribute(\"xml:lang\")||e.getAttribute(\"lang\"))return(t=t.toLowerCase())===n||0===t.indexOf(n+\"-\")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=ie.location&&ie.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===r},focus:function(e){return e===function(){try{return T.activeElement}catch(e){}}()&&T.hasFocus()&&!!(e.type||e.href||~e.tabIndex)},enabled:z(!1),disabled:z(!0),checked:function(e){return fe(e,\"input\")&&!!e.checked||fe(e,\"option\")&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return q.test(e.nodeName)},input:function(e){return N.test(e.nodeName)},button:function(e){return fe(e,\"input\")&&\"button\"===e.type||fe(e,\"button\")},text:function(e){var t;return fe(e,\"input\")&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:X(function(){return[0]}),last:X(function(e,t){return[t-1]}),eq:X(function(e,t,n){return[n<0?n+t:n]}),even:X(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:X(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:X(function(e,t,n){var r;for(r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:X(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=B(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=_(e);function G(){}function Y(e,t){var n,r,i,o,a,s,u,l=c[e+\" \"];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=y.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=m.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(ve,\" \")}),a=a.slice(n.length)),b.filter)!(r=D[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?I.error(e):c(e,s).slice(0)}function Q(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function J(a,e,t){var s=e.dir,u=e.next,l=u||s,c=t&&\"parentNode\"===l,f=n++;return e.first?function(e,t,n){while(e=e[s])if(1===e.nodeType||c)return a(e,t,n);return!1}:function(e,t,n){var r,i,o=[E,f];if(n){while(e=e[s])if((1===e.nodeType||c)&&a(e,t,n))return!0}else while(e=e[s])if(1===e.nodeType||c)if(i=e[S]||(e[S]={}),u&&fe(e,u))e=e[s]||e;else{if((r=i[l])&&r[0]===E&&r[1]===f)return o[2]=r[2];if((i[l]=o)[2]=a(e,t,n))return!0}return!1}}function K(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Z(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function ee(d,h,g,v,y,e){return v&&!v[S]&&(v=ee(v)),y&&!y[S]&&(y=ee(y,e)),F(function(e,t,n,r){var i,o,a,s,u=[],l=[],c=t.length,f=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)I(e,t[r],n);return n}(h||\"*\",n.nodeType?[n]:n,[]),p=!d||!e&&h?f:Z(f,u,d,n,r);if(g?g(p,s=y||(e?d:c||v)?[]:t,n,r):s=p,v){i=Z(s,l),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(s[l[o]]=!(p[l[o]]=a))}if(e){if(y||d){if(y){i=[],o=s.length;while(o--)(a=s[o])&&i.push(p[o]=a);y(null,s=[],i,r)}o=s.length;while(o--)(a=s[o])&&-1<(i=y?se.call(e,a):u[o])&&(e[i]=!(t[i]=a))}}else s=Z(s===t?s.splice(c,s.length):s),y?y(null,t,s,r):k.apply(t,s)})}function te(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[\" \"],s=o?1:0,u=J(function(e){return e===i},a,!0),l=J(function(e){return-1<se.call(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!=w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[J(K(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return ee(1<s&&K(c),1<s&&Q(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace(ve,\"$1\"),t,s<n&&te(e.slice(s,n)),n<r&&te(e=e.slice(n)),n<r&&Q(e))}c.push(t)}return K(c)}function ne(e,t){var n,v,y,m,x,r,i=[],o=[],a=u[e+\" \"];if(!a){t||(t=Y(e)),n=t.length;while(n--)(a=te(t[n]))[S]?i.push(a):o.push(a);(a=u(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l=\"0\",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG(\"*\",i),h=E+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==T||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==T||(V(o),n=!C);while(s=v[a++])if(s(o,t||T,n)){k.call(r,o);break}i&&(E=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=pe.call(r));f=Z(f)}k.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&ce.uniqueSort(r)}return i&&(E=h,w=p),c},m?F(r):r))).selector=e}return a}function re(e,t,n,r){var i,o,a,s,u,l=\"function\"==typeof e&&e,c=!r&&Y(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&\"ID\"===(a=o[0]).type&&9===t.nodeType&&C&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(O,P),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=D.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(O,P),H.test(o[0].type)&&U(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&Q(o)))return k.apply(n,r),n;break}}}return(l||ne(e,c))(r,t,!C,n,!t||H.test(e)&&U(t.parentNode)||t),n}G.prototype=b.filters=b.pseudos,b.setFilters=new G,le.sortStable=S.split(\"\").sort(l).join(\"\")===S,V(),le.sortDetached=$(function(e){return 1&e.compareDocumentPosition(T.createElement(\"fieldset\"))}),ce.find=I,ce.expr[\":\"]=ce.expr.pseudos,ce.unique=ce.uniqueSort,I.compile=ne,I.select=re,I.setDocument=V,I.tokenize=Y,I.escape=ce.escapeSelector,I.getText=ce.text,I.isXML=ce.isXMLDoc,I.selectors=ce.expr,I.support=ce.support,I.uniqueSort=ce.uniqueSort}();var d=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&ce(e).is(n))break;r.push(e)}return r},h=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},b=ce.expr.match.needsContext,w=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):\"string\"!=typeof n?ce.grep(e,function(e){return-1<se.call(n,e)!==r}):ce.filter(n,e,r)}ce.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?ce.find.matchesSelector(r,e)?[r]:[]:ce.find.matches(e,ce.grep(t,function(e){return 1===e.nodeType}))},ce.fn.extend({find:function(e){var t,n,r=this.length,i=this;if(\"string\"!=typeof e)return this.pushStack(ce(e).filter(function(){for(t=0;t<r;t++)if(ce.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)ce.find(e,i[t],n);return 1<r?ce.uniqueSort(n):n},filter:function(e){return this.pushStack(T(this,e||[],!1))},not:function(e){return this.pushStack(T(this,e||[],!0))},is:function(e){return!!T(this,\"string\"==typeof e&&b.test(e)?ce(e):e||[],!1).length}});var k,S=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,\"string\"==typeof e){if(!(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(ce.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a=\"string\"!=typeof e&&ce(e);if(!b.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&ce.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?ce.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?se.call(ce(e),this[0]):se.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(ce.uniqueSort(ce.merge(this.get(),ce(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),ce.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return d(e,\"parentNode\")},parentsUntil:function(e,t,n){return d(e,\"parentNode\",n)},next:function(e){return A(e,\"nextSibling\")},prev:function(e){return A(e,\"previousSibling\")},nextAll:function(e){return d(e,\"nextSibling\")},prevAll:function(e){return d(e,\"previousSibling\")},nextUntil:function(e,t,n){return d(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return d(e,\"previousSibling\",n)},siblings:function(e){return h((e.parentNode||{}).firstChild,e)},children:function(e){return h(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(fe(e,\"template\")&&(e=e.content||e),ce.merge([],e.childNodes))}},function(r,i){ce.fn[r]=function(e,t){var n=ce.map(this,i,e);return\"Until\"!==r.slice(-5)&&(t=e),t&&\"string\"==typeof t&&(n=ce.filter(t,n)),1<this.length&&(j[r]||ce.uniqueSort(n),E.test(r)&&n.reverse()),this.pushStack(n)}});var D=/[^\\x20\\t\\r\\n\\f]+/g;function N(e){return e}function q(e){throw e}function L(e,t,n,r){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(n):e&&v(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}ce.Callbacks=function(r){var e,n;r=\"string\"==typeof r?(e=r,n={},ce.each(e.match(D)||[],function(e,t){n[t]=!0}),n):ce.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:\"\")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){ce.each(e,function(e,t){v(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&\"string\"!==x(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return ce.each(arguments,function(e,t){var n;while(-1<(n=ce.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<ce.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t=\"\",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=\"\"),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},ce.extend({Deferred:function(e){var o=[[\"notify\",\"progress\",ce.Callbacks(\"memory\"),ce.Callbacks(\"memory\"),2],[\"resolve\",\"done\",ce.Callbacks(\"once memory\"),ce.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",ce.Callbacks(\"once memory\"),ce.Callbacks(\"once memory\"),1,\"rejected\"]],i=\"pending\",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},\"catch\":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return ce.Deferred(function(r){ce.each(o,function(e,t){var n=v(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&v(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+\"With\"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError(\"Thenable self-resolution\");t=e&&(\"object\"==typeof e||\"function\"==typeof e)&&e.then,v(t)?s?t.call(e,l(u,o,N,s),l(u,o,q,s)):(u++,t.call(e,l(u,o,N,s),l(u,o,q,s),l(u,o,N,o.notifyWith))):(a!==N&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){ce.Deferred.exceptionHook&&ce.Deferred.exceptionHook(e,t.error),u<=i+1&&(a!==q&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(ce.Deferred.getErrorHook?t.error=ce.Deferred.getErrorHook():ce.Deferred.getStackHook&&(t.error=ce.Deferred.getStackHook()),ie.setTimeout(t))}}return ce.Deferred(function(e){o[0][3].add(l(0,e,v(r)?r:N,e.notifyWith)),o[1][3].add(l(0,e,v(t)?t:N)),o[2][3].add(l(0,e,v(n)?n:q))}).promise()},promise:function(e){return null!=e?ce.extend(e,a):a}},s={};return ce.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+\"With\"](this===s?void 0:this,arguments),this},s[t[0]+\"With\"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=ae.call(arguments),o=ce.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?ae.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(L(e,o.done(a(t)).resolve,o.reject,!n),\"pending\"===o.state()||v(i[t]&&i[t].then)))return o.then();while(t--)L(i[t],a(t),o.reject);return o.promise()}});var H=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;ce.Deferred.exceptionHook=function(e,t){ie.console&&ie.console.warn&&e&&H.test(e.name)&&ie.console.warn(\"jQuery.Deferred exception: \"+e.message,e.stack,t)},ce.readyException=function(e){ie.setTimeout(function(){throw e})};var O=ce.Deferred();function P(){C.removeEventListener(\"DOMContentLoaded\",P),ie.removeEventListener(\"load\",P),ce.ready()}ce.fn.ready=function(e){return O.then(e)[\"catch\"](function(e){ce.readyException(e)}),this},ce.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--ce.readyWait:ce.isReady)||(ce.isReady=!0)!==e&&0<--ce.readyWait||O.resolveWith(C,[ce])}}),ce.ready.then=O.then,\"complete\"===C.readyState||\"loading\"!==C.readyState&&!C.documentElement.doScroll?ie.setTimeout(ce.ready):(C.addEventListener(\"DOMContentLoaded\",P),ie.addEventListener(\"load\",P));var M=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===x(n))for(s in i=!0,n)M(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,v(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(ce(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},R=/^-ms-/,I=/-([a-z])/g;function W(e,t){return t.toUpperCase()}function F(e){return e.replace(R,\"ms-\").replace(I,W)}var $=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function B(){this.expando=ce.expando+B.uid++}B.uid=1,B.prototype={cache:function(e){var t=e[this.expando];return t||(t={},$(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if(\"string\"==typeof t)i[F(t)]=n;else for(r in t)i[F(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][F(t)]},access:function(e,t,n){return void 0===t||t&&\"string\"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(F):(t=F(t))in r?[t]:t.match(D)||[]).length;while(n--)delete r[t[n]]}(void 0===t||ce.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!ce.isEmptyObject(t)}};var _=new B,z=new B,X=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,U=/[A-Z]/g;function V(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r=\"data-\"+t.replace(U,\"-$&\").toLowerCase(),\"string\"==typeof(n=e.getAttribute(r))){try{n=\"true\"===(i=n)||\"false\"!==i&&(\"null\"===i?null:i===+i+\"\"?+i:X.test(i)?JSON.parse(i):i)}catch(e){}z.set(e,t,n)}else n=void 0;return n}ce.extend({hasData:function(e){return z.hasData(e)||_.hasData(e)},data:function(e,t,n){return z.access(e,t,n)},removeData:function(e,t){z.remove(e,t)},_data:function(e,t,n){return _.access(e,t,n)},_removeData:function(e,t){_.remove(e,t)}}),ce.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=z.get(o),1===o.nodeType&&!_.get(o,\"hasDataAttrs\"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf(\"data-\")&&(r=F(r.slice(5)),V(o,r,i[r]));_.set(o,\"hasDataAttrs\",!0)}return i}return\"object\"==typeof n?this.each(function(){z.set(this,n)}):M(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=z.get(o,n))?t:void 0!==(t=V(o,n))?t:void 0;this.each(function(){z.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){z.remove(this,e)})}}),ce.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=_.get(e,t),n&&(!r||Array.isArray(n)?r=_.access(e,t,ce.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=ce.queue(e,t),r=n.length,i=n.shift(),o=ce._queueHooks(e,t);\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,function(){ce.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return _.get(e,n)||_.access(e,n,{empty:ce.Callbacks(\"once memory\").add(function(){_.remove(e,[t+\"queue\",n])})})}}),ce.fn.extend({queue:function(t,n){var e=2;return\"string\"!=typeof t&&(n=t,t=\"fx\",e--),arguments.length<e?ce.queue(this[0],t):void 0===n?this:this.each(function(){var e=ce.queue(this,t,n);ce._queueHooks(this,t),\"fx\"===t&&\"inprogress\"!==e[0]&&ce.dequeue(this,t)})},dequeue:function(e){return this.each(function(){ce.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=ce.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";while(a--)(n=_.get(o[a],e+\"queueHooks\"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var G=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,Y=new RegExp(\"^(?:([+-])=|)(\"+G+\")([a-z%]*)$\",\"i\"),Q=[\"Top\",\"Right\",\"Bottom\",\"Left\"],J=C.documentElement,K=function(e){return ce.contains(e.ownerDocument,e)},Z={composed:!0};J.getRootNode&&(K=function(e){return ce.contains(e.ownerDocument,e)||e.getRootNode(Z)===e.ownerDocument});var ee=function(e,t){return\"none\"===(e=t||e).style.display||\"\"===e.style.display&&K(e)&&\"none\"===ce.css(e,\"display\")};function te(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return ce.css(e,t,\"\")},u=s(),l=n&&n[3]||(ce.cssNumber[t]?\"\":\"px\"),c=e.nodeType&&(ce.cssNumber[t]||\"px\"!==l&&+u)&&Y.exec(ce.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)ce.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,ce.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ne={};function re(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?(\"none\"===n&&(l[c]=_.get(r,\"display\")||null,l[c]||(r.style.display=\"\")),\"\"===r.style.display&&ee(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ne[s])||(o=a.body.appendChild(a.createElement(s)),u=ce.css(o,\"display\"),o.parentNode.removeChild(o),\"none\"===u&&(u=\"block\"),ne[s]=u)))):\"none\"!==n&&(l[c]=\"none\",_.set(r,\"display\",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}ce.fn.extend({show:function(){return re(this,!0)},hide:function(){return re(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){ee(this)?ce(this).show():ce(this).hide()})}});var xe,be,we=/^(?:checkbox|radio)$/i,Te=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i,Ce=/^$|^module$|\\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement(\"div\")),(be=C.createElement(\"input\")).setAttribute(\"type\",\"radio\"),be.setAttribute(\"checked\",\"checked\"),be.setAttribute(\"name\",\"t\"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML=\"<textarea>x</textarea>\",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML=\"<option></option>\",le.option=!!xe.lastChild;var ke={thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};function Se(e,t){var n;return n=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n<r;n++)_.set(e[n],\"globalEval\",!t||_.get(t[n],\"globalEval\"))}ke.tbody=ke.tfoot=ke.colgroup=ke.caption=ke.thead,ke.th=ke.td,le.option||(ke.optgroup=ke.option=[1,\"<select multiple='multiple'>\",\"</select>\"]);var je=/<|&#?\\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if(\"object\"===x(o))ce.merge(p,o.nodeType?[o]:o);else if(je.test(o)){a=a||f.appendChild(t.createElement(\"div\")),s=(Te.exec(o)||[\"\",\"\"])[1].toLowerCase(),u=ke[s]||ke._default,a.innerHTML=u[1]+ce.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;ce.merge(p,a.childNodes),(a=f.firstChild).textContent=\"\"}else p.push(t.createTextNode(o));f.textContent=\"\",d=0;while(o=p[d++])if(r&&-1<ce.inArray(o,r))i&&i.push(o);else if(l=K(o),a=Se(f.appendChild(o),\"script\"),l&&Ee(a),n){c=0;while(o=a[c++])Ce.test(o.type||\"\")&&n.push(o)}return f}var De=/^([^.]*)(?:\\.(.+)|)/;function Ne(){return!0}function qe(){return!1}function Le(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){for(s in\"string\"!=typeof n&&(r=r||n,n=void 0),t)Le(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=qe;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return ce().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=ce.guid++)),e.each(function(){ce.event.add(this,t,i,r,n)})}function He(e,r,t){t?(_.set(e,r,!1),ce.event.add(e,r,{namespace:!1,handler:function(e){var t,n=_.get(this,r);if(1&e.isTrigger&&this[r]){if(n)(ce.event.special[r]||{}).delegateType&&e.stopPropagation();else if(n=ae.call(arguments),_.set(this,r,n),this[r](),t=_.get(this,r),_.set(this,r,!1),n!==t)return e.stopImmediatePropagation(),e.preventDefault(),t}else n&&(_.set(this,r,ce.event.trigger(n[0],n.slice(1),this)),e.stopPropagation(),e.isImmediatePropagationStopped=Ne)}})):void 0===_.get(e,r)&&ce.event.add(e,r,Ne)}ce.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=_.get(t);if($(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&ce.find.matchesSelector(J,i),n.guid||(n.guid=ce.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return\"undefined\"!=typeof ce&&ce.event.triggered!==e.type?ce.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||\"\").match(D)||[\"\"]).length;while(l--)d=g=(s=De.exec(e[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d&&(f=ce.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=ce.event.special[d]||{},c=ce.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&ce.expr.match.needsContext.test(i),namespace:h.join(\".\")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),ce.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=_.hasData(e)&&_.get(e);if(v&&(u=v.events)){l=(t=(t||\"\").match(D)||[\"\"]).length;while(l--)if(d=g=(s=De.exec(t[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d){f=ce.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&(\"**\"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||ce.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)ce.event.remove(e,d+t[l],n,r,!0);ce.isEmptyObject(u)&&_.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=ce.event.fix(e),l=(_.get(this,\"events\")||Object.create(null))[u.type]||[],c=ce.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=ce.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((ce.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!(\"click\"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(\"click\"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+\" \"]&&(a[i]=r.needsContext?-1<ce(i,this).index(l):ce.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(ce.Event.prototype,t,{enumerable:!0,configurable:!0,get:v(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[ce.expando]?e:new ce.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return we.test(t.type)&&t.click&&fe(t,\"input\")&&He(t,\"click\",!0),!1},trigger:function(e){var t=this||e;return we.test(t.type)&&t.click&&fe(t,\"input\")&&He(t,\"click\"),!0},_default:function(e){var t=e.target;return we.test(t.type)&&t.click&&fe(t,\"input\")&&_.get(t,\"click\")||fe(t,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},ce.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},ce.Event=function(e,t){if(!(this instanceof ce.Event))return new ce.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ne:qe,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&ce.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[ce.expando]=!0},ce.Event.prototype={constructor:ce.Event,isDefaultPrevented:qe,isPropagationStopped:qe,isImmediatePropagationStopped:qe,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ne,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ne,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ne,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},ce.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,\"char\":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},ce.event.addProp),ce.each({focus:\"focusin\",blur:\"focusout\"},function(r,i){function o(e){if(C.documentMode){var t=_.get(this,\"handle\"),n=ce.event.fix(e);n.type=\"focusin\"===e.type?\"focus\":\"blur\",n.isSimulated=!0,t(e),n.target===n.currentTarget&&t(n)}else ce.event.simulate(i,e.target,ce.event.fix(e))}ce.event.special[r]={setup:function(){var e;if(He(this,r,!0),!C.documentMode)return!1;(e=_.get(this,i))||this.addEventListener(i,o),_.set(this,i,(e||0)+1)},trigger:function(){return He(this,r),!0},teardown:function(){var e;if(!C.documentMode)return!1;(e=_.get(this,i)-1)?_.set(this,i,e):(this.removeEventListener(i,o),_.remove(this,i))},_default:function(e){return _.get(e.target,r)},delegateType:i},ce.event.special[i]={setup:function(){var e=this.ownerDocument||this.document||this,t=C.documentMode?this:e,n=_.get(t,i);n||(C.documentMode?this.addEventListener(i,o):e.addEventListener(r,o,!0)),_.set(t,i,(n||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=C.documentMode?this:e,n=_.get(t,i)-1;n?_.set(t,i,n):(C.documentMode?this.removeEventListener(i,o):e.removeEventListener(r,o,!0),_.remove(t,i))}}}),ce.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,i){ce.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||ce.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),ce.fn.extend({on:function(e,t,n,r){return Le(this,e,t,n,r)},one:function(e,t,n,r){return Le(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,ce(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&\"function\"!=typeof t||(n=t,t=void 0),!1===n&&(n=qe),this.each(function(){ce.event.remove(this,e,n,t)})}});var Oe=/<script|<style|<link/i,Pe=/checked\\s*(?:[^=]|=\\s*.checked.)/i,Me=/^\\s*<!\\[CDATA\\[|\\]\\]>\\s*$/g;function Re(e,t){return fe(e,\"table\")&&fe(11!==t.nodeType?t:t.firstChild,\"tr\")&&ce(e).children(\"tbody\")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function We(e){return\"true/\"===(e.type||\"\").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute(\"type\"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,\"handle events\"),s)for(n=0,r=s[i].length;n<r;n++)ce.event.add(t,i,s[i][n]);z.hasData(e)&&(o=z.access(e),a=ce.extend({},o),z.set(t,a))}}function $e(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=v(d);if(h||1<f&&\"string\"==typeof d&&!le.checkClone&&Pe.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),$e(t,r,i,o)});if(f&&(t=(e=Ae(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=ce.map(Se(e,\"script\"),Ie)).length;c<f;c++)u=e,c!==p&&(u=ce.clone(u,!0,!0),s&&ce.merge(a,Se(u,\"script\"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,ce.map(a,We),c=0;c<s;c++)u=a[c],Ce.test(u.type||\"\")&&!_.access(u,\"globalEval\")&&ce.contains(l,u)&&(u.src&&\"module\"!==(u.type||\"\").toLowerCase()?ce._evalUrl&&!u.noModule&&ce._evalUrl(u.src,{nonce:u.nonce||u.getAttribute(\"nonce\")},l):m(u.textContent.replace(Me,\"\"),u,l))}return n}function Be(e,t,n){for(var r,i=t?ce.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||ce.cleanData(Se(r)),r.parentNode&&(n&&K(r)&&Ee(Se(r,\"script\")),r.parentNode.removeChild(r));return e}ce.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=K(e);if(!(le.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||ce.isXMLDoc(e)))for(a=Se(c),r=0,i=(o=Se(e)).length;r<i;r++)s=o[r],u=a[r],void 0,\"input\"===(l=u.nodeName.toLowerCase())&&we.test(s.type)?u.checked=s.checked:\"input\"!==l&&\"textarea\"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||Se(e),a=a||Se(c),r=0,i=o.length;r<i;r++)Fe(o[r],a[r]);else Fe(e,c);return 0<(a=Se(c,\"script\")).length&&Ee(a,!f&&Se(e,\"script\")),c},cleanData:function(e){for(var t,n,r,i=ce.event.special,o=0;void 0!==(n=e[o]);o++)if($(n)){if(t=n[_.expando]){if(t.events)for(r in t.events)i[r]?ce.event.remove(n,r):ce.removeEvent(n,r,t.handle);n[_.expando]=void 0}n[z.expando]&&(n[z.expando]=void 0)}}}),ce.fn.extend({detach:function(e){return Be(this,e,!0)},remove:function(e){return Be(this,e)},text:function(e){return M(this,function(e){return void 0===e?ce.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return $e(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Re(this,e).appendChild(e)})},prepend:function(){return $e(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Re(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return $e(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return $e(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(ce.cleanData(Se(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return ce.clone(this,e,t)})},html:function(e){return M(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!Oe.test(e)&&!ke[(Te.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=ce.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(ce.cleanData(Se(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return $e(this,arguments,function(e){var t=this.parentNode;ce.inArray(this,n)<0&&(ce.cleanData(Se(this)),t&&t.replaceChild(e,this))},n)}}),ce.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,a){ce.fn[e]=function(e){for(var t,n=[],r=ce(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),ce(r[o])[a](t),s.apply(n,t.get());return this.pushStack(n)}});var _e=new RegExp(\"^(\"+G+\")(?!px)[a-z%]+$\",\"i\"),ze=/^--/,Xe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=ie),t.getComputedStyle(e)},Ue=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Ve=new RegExp(Q.join(\"|\"),\"i\");function Ge(e,t,n){var r,i,o,a,s=ze.test(t),u=e.style;return(n=n||Xe(e))&&(a=n.getPropertyValue(t)||n[t],s&&a&&(a=a.replace(ve,\"$1\")||void 0),\"\"!==a||K(e)||(a=ce.style(e,t)),!le.pixelBoxStyles()&&_e.test(a)&&Ve.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=n.width,u.width=r,u.minWidth=i,u.maxWidth=o)),void 0!==a?a+\"\":a}function Ye(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText=\"position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0\",l.style.cssText=\"position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%\",J.appendChild(u).appendChild(l);var e=ie.getComputedStyle(l);n=\"1%\"!==e.top,s=12===t(e.marginLeft),l.style.right=\"60%\",o=36===t(e.right),r=36===t(e.width),l.style.position=\"absolute\",i=12===t(l.offsetWidth/3),J.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=C.createElement(\"div\"),l=C.createElement(\"div\");l.style&&(l.style.backgroundClip=\"content-box\",l.cloneNode(!0).style.backgroundClip=\"\",le.clearCloneStyle=\"content-box\"===l.style.backgroundClip,ce.extend(le,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=C.createElement(\"table\"),t=C.createElement(\"tr\"),n=C.createElement(\"div\"),e.style.cssText=\"position:absolute;left:-11111px;border-collapse:separate\",t.style.cssText=\"box-sizing:content-box;border:1px solid\",t.style.height=\"1px\",n.style.height=\"9px\",n.style.display=\"block\",J.appendChild(e).appendChild(t).appendChild(n),r=ie.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,J.removeChild(e)),a}}))}();var Qe=[\"Webkit\",\"Moz\",\"ms\"],Je=C.createElement(\"div\").style,Ke={};function Ze(e){var t=ce.cssProps[e]||Ke[e];return t||(e in Je?e:Ke[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Qe.length;while(n--)if((e=Qe[n]+t)in Je)return e}(e)||e)}var et=/^(none|table(?!-c[ea]).+)/,tt={position:\"absolute\",visibility:\"hidden\",display:\"block\"},nt={letterSpacing:\"0\",fontWeight:\"400\"};function rt(e,t,n){var r=Y.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||\"px\"):t}function it(e,t,n,r,i,o){var a=\"width\"===t?1:0,s=0,u=0,l=0;if(n===(r?\"border\":\"content\"))return 0;for(;a<4;a+=2)\"margin\"===n&&(l+=ce.css(e,n+Q[a],!0,i)),r?(\"content\"===n&&(u-=ce.css(e,\"padding\"+Q[a],!0,i)),\"margin\"!==n&&(u-=ce.css(e,\"border\"+Q[a]+\"Width\",!0,i))):(u+=ce.css(e,\"padding\"+Q[a],!0,i),\"padding\"!==n?u+=ce.css(e,\"border\"+Q[a]+\"Width\",!0,i):s+=ce.css(e,\"border\"+Q[a]+\"Width\",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e[\"offset\"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u+l}function ot(e,t,n){var r=Xe(e),i=(!le.boxSizingReliable()||n)&&\"border-box\"===ce.css(e,\"boxSizing\",!1,r),o=i,a=Ge(e,t,r),s=\"offset\"+t[0].toUpperCase()+t.slice(1);if(_e.test(a)){if(!n)return a;a=\"auto\"}return(!le.boxSizingReliable()&&i||!le.reliableTrDimensions()&&fe(e,\"tr\")||\"auto\"===a||!parseFloat(a)&&\"inline\"===ce.css(e,\"display\",!1,r))&&e.getClientRects().length&&(i=\"border-box\"===ce.css(e,\"boxSizing\",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+it(e,t,n||(i?\"border\":\"content\"),o,r,a)+\"px\"}function at(e,t,n,r,i){return new at.prototype.init(e,t,n,r,i)}ce.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Ge(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=F(t),u=ze.test(t),l=e.style;if(u||(t=Ze(s)),a=ce.cssHooks[t]||ce.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];\"string\"===(o=typeof n)&&(i=Y.exec(n))&&i[1]&&(n=te(e,t,i),o=\"number\"),null!=n&&n==n&&(\"number\"!==o||u||(n+=i&&i[3]||(ce.cssNumber[s]?\"\":\"px\")),le.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(l[t]=\"inherit\"),a&&\"set\"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=F(t);return ze.test(t)||(t=Ze(s)),(a=ce.cssHooks[t]||ce.cssHooks[s])&&\"get\"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Ge(e,t,r)),\"normal\"===i&&t in nt&&(i=nt[t]),\"\"===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),ce.each([\"height\",\"width\"],function(e,u){ce.cssHooks[u]={get:function(e,t,n){if(t)return!et.test(ce.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?ot(e,u,n):Ue(e,tt,function(){return ot(e,u,n)})},set:function(e,t,n){var r,i=Xe(e),o=!le.scrollboxSize()&&\"absolute\"===i.position,a=(o||n)&&\"border-box\"===ce.css(e,\"boxSizing\",!1,i),s=n?it(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e[\"offset\"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-it(e,u,\"border\",!1,i)-.5)),s&&(r=Y.exec(t))&&\"px\"!==(r[3]||\"px\")&&(e.style[u]=t,t=ce.css(e,u)),rt(0,t,s)}}}),ce.cssHooks.marginLeft=Ye(le.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Ge(e,\"marginLeft\"))||e.getBoundingClientRect().left-Ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+\"px\"}),ce.each({margin:\"\",padding:\"\",border:\"Width\"},function(i,o){ce.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r=\"string\"==typeof e?e.split(\" \"):[e];t<4;t++)n[i+Q[t]+o]=r[t]||r[t-2]||r[0];return n}},\"margin\"!==i&&(ce.cssHooks[i+o].set=rt)}),ce.fn.extend({css:function(e,t){return M(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Xe(e),i=t.length;a<i;a++)o[t[a]]=ce.css(e,t[a],!1,r);return o}return void 0!==n?ce.style(e,t,n):ce.css(e,t)},e,t,1<arguments.length)}}),((ce.Tween=at).prototype={constructor:at,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||ce.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(ce.cssNumber[n]?\"\":\"px\")},cur:function(){var e=at.propHooks[this.prop];return e&&e.get?e.get(this):at.propHooks._default.get(this)},run:function(e){var t,n=at.propHooks[this.prop];return this.options.duration?this.pos=t=ce.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):at.propHooks._default.set(this),this}}).init.prototype=at.prototype,(at.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=ce.css(e.elem,e.prop,\"\"))&&\"auto\"!==t?t:0},set:function(e){ce.fx.step[e.prop]?ce.fx.step[e.prop](e):1!==e.elem.nodeType||!ce.cssHooks[e.prop]&&null==e.elem.style[Ze(e.prop)]?e.elem[e.prop]=e.now:ce.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=at.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},ce.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},ce.fx=at.prototype.init,ce.fx.step={};var st,ut,lt,ct,ft=/^(?:toggle|show|hide)$/,pt=/queueHooks$/;function dt(){ut&&(!1===C.hidden&&ie.requestAnimationFrame?ie.requestAnimationFrame(dt):ie.setTimeout(dt,ce.fx.interval),ce.fx.tick())}function ht(){return ie.setTimeout(function(){st=void 0}),st=Date.now()}function gt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i[\"margin\"+(n=Q[r])]=i[\"padding\"+n]=e;return t&&(i.opacity=i.width=e),i}function vt(e,t,n){for(var r,i=(yt.tweeners[t]||[]).concat(yt.tweeners[\"*\"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function yt(o,e,t){var n,a,r=0,i=yt.prefilters.length,s=ce.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=st||ht(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:ce.extend({},e),opts:ce.extend(!0,{specialEasing:{},easing:ce.easing._default},t),originalProperties:e,originalOptions:t,startTime:st||ht(),duration:t.duration,tweens:[],createTween:function(e,t){var n=ce.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=F(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=ce.cssHooks[r])&&\"expand\"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=yt.prefilters[r].call(l,o,c,l.opts))return v(n.stop)&&(ce._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return ce.map(c,vt,l),v(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),ce.fx.timer(ce.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}ce.Animation=ce.extend(yt,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return te(n.elem,e,Y.exec(t),n),n}]},tweener:function(e,t){v(e)?(t=e,e=[\"*\"]):e=e.match(D);for(var n,r=0,i=e.length;r<i;r++)n=e[r],yt.tweeners[n]=yt.tweeners[n]||[],yt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f=\"width\"in t||\"height\"in t,p=this,d={},h=e.style,g=e.nodeType&&ee(e),v=_.get(e,\"fxshow\");for(r in n.queue||(null==(a=ce._queueHooks(e,\"fx\")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,ce.queue(e,\"fx\").length||a.empty.fire()})})),t)if(i=t[r],ft.test(i)){if(delete t[r],o=o||\"toggle\"===i,i===(g?\"hide\":\"show\")){if(\"show\"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||ce.style(e,r)}if((u=!ce.isEmptyObject(t))||!ce.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=_.get(e,\"display\")),\"none\"===(c=ce.css(e,\"display\"))&&(l?c=l:(re([e],!0),l=e.style.display||l,c=ce.css(e,\"display\"),re([e]))),(\"inline\"===c||\"inline-block\"===c&&null!=l)&&\"none\"===ce.css(e,\"float\")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l=\"none\"===c?\"\":c)),h.display=\"inline-block\")),n.overflow&&(h.overflow=\"hidden\",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?\"hidden\"in v&&(g=v.hidden):v=_.access(e,\"fxshow\",{display:l}),o&&(v.hidden=!g),g&&re([e],!0),p.done(function(){for(r in g||re([e]),_.remove(e,\"fxshow\"),d)ce.style(e,r,d[r])})),u=vt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?yt.prefilters.unshift(e):yt.prefilters.push(e)}}),ce.speed=function(e,t,n){var r=e&&\"object\"==typeof e?ce.extend({},e):{complete:n||!n&&t||v(e)&&e,duration:e,easing:n&&t||t&&!v(t)&&t};return ce.fx.off?r.duration=0:\"number\"!=typeof r.duration&&(r.duration in ce.fx.speeds?r.duration=ce.fx.speeds[r.duration]:r.duration=ce.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){v(r.old)&&r.old.call(this),r.queue&&ce.dequeue(this,r.queue)},r},ce.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ee).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=ce.isEmptyObject(t),o=ce.speed(e,n,r),a=function(){var e=yt(this,ce.extend({},t),o);(i||_.get(this,\"finish\"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return\"string\"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||\"fx\",[]),this.each(function(){var e=!0,t=null!=i&&i+\"queueHooks\",n=ce.timers,r=_.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&pt.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||ce.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||\"fx\"),this.each(function(){var e,t=_.get(this),n=t[a+\"queue\"],r=t[a+\"queueHooks\"],i=ce.timers,o=n?n.length:0;for(t.finish=!0,ce.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),ce.each([\"toggle\",\"show\",\"hide\"],function(e,r){var i=ce.fn[r];ce.fn[r]=function(e,t,n){return null==e||\"boolean\"==typeof e?i.apply(this,arguments):this.animate(gt(r,!0),e,t,n)}}),ce.each({slideDown:gt(\"show\"),slideUp:gt(\"hide\"),slideToggle:gt(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,r){ce.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),ce.timers=[],ce.fx.tick=function(){var e,t=0,n=ce.timers;for(st=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||ce.fx.stop(),st=void 0},ce.fx.timer=function(e){ce.timers.push(e),ce.fx.start()},ce.fx.interval=13,ce.fx.start=function(){ut||(ut=!0,dt())},ce.fx.stop=function(){ut=null},ce.fx.speeds={slow:600,fast:200,_default:400},ce.fn.delay=function(r,e){return r=ce.fx&&ce.fx.speeds[r]||r,e=e||\"fx\",this.queue(e,function(e,t){var n=ie.setTimeout(e,r);t.stop=function(){ie.clearTimeout(n)}})},lt=C.createElement(\"input\"),ct=C.createElement(\"select\").appendChild(C.createElement(\"option\")),lt.type=\"checkbox\",le.checkOn=\"\"!==lt.value,le.optSelected=ct.selected,(lt=C.createElement(\"input\")).value=\"t\",lt.type=\"radio\",le.radioValue=\"t\"===lt.value;var mt,xt=ce.expr.attrHandle;ce.fn.extend({attr:function(e,t){return M(this,ce.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){ce.removeAttr(this,e)})}}),ce.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return\"undefined\"==typeof e.getAttribute?ce.prop(e,t,n):(1===o&&ce.isXMLDoc(e)||(i=ce.attrHooks[t.toLowerCase()]||(ce.expr.match.bool.test(t)?mt:void 0)),void 0!==n?null===n?void ce.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:null==(r=ce.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!le.radioValue&&\"radio\"===t&&fe(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(D);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),mt={set:function(e,t,n){return!1===t?ce.removeAttr(e,n):e.setAttribute(n,n),n}},ce.each(ce.expr.match.bool.source.match(/\\w+/g),function(e,t){var a=xt[t]||ce.find.attr;xt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=xt[o],xt[o]=r,r=null!=a(e,t,n)?o:null,xt[o]=i),r}});var bt=/^(?:input|select|textarea|button)$/i,wt=/^(?:a|area)$/i;function Tt(e){return(e.match(D)||[]).join(\" \")}function Ct(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function kt(e){return Array.isArray(e)?e:\"string\"==typeof e&&e.match(D)||[]}ce.fn.extend({prop:function(e,t){return M(this,ce.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[ce.propFix[e]||e]})}}),ce.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&ce.isXMLDoc(e)||(t=ce.propFix[t]||t,i=ce.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=ce.find.attr(e,\"tabindex\");return t?parseInt(t,10):bt.test(e.nodeName)||wt.test(e.nodeName)&&e.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),le.optSelected||(ce.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),ce.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){ce.propFix[this.toLowerCase()]=this}),ce.fn.extend({addClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){ce(this).addClass(t.call(this,e,Ct(this)))}):(e=kt(t)).length?this.each(function(){if(r=Ct(this),n=1===this.nodeType&&\" \"+Tt(r)+\" \"){for(o=0;o<e.length;o++)i=e[o],n.indexOf(\" \"+i+\" \")<0&&(n+=i+\" \");a=Tt(n),r!==a&&this.setAttribute(\"class\",a)}}):this},removeClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){ce(this).removeClass(t.call(this,e,Ct(this)))}):arguments.length?(e=kt(t)).length?this.each(function(){if(r=Ct(this),n=1===this.nodeType&&\" \"+Tt(r)+\" \"){for(o=0;o<e.length;o++){i=e[o];while(-1<n.indexOf(\" \"+i+\" \"))n=n.replace(\" \"+i+\" \",\" \")}a=Tt(n),r!==a&&this.setAttribute(\"class\",a)}}):this:this.attr(\"class\",\"\")},toggleClass:function(t,n){var e,r,i,o,a=typeof t,s=\"string\"===a||Array.isArray(t);return v(t)?this.each(function(e){ce(this).toggleClass(t.call(this,e,Ct(this),n),n)}):\"boolean\"==typeof n&&s?n?this.addClass(t):this.removeClass(t):(e=kt(t),this.each(function(){if(s)for(o=ce(this),i=0;i<e.length;i++)r=e[i],o.hasClass(r)?o.removeClass(r):o.addClass(r);else void 0!==t&&\"boolean\"!==a||((r=Ct(this))&&_.set(this,\"__className__\",r),this.setAttribute&&this.setAttribute(\"class\",r||!1===t?\"\":_.get(this,\"__className__\")||\"\"))}))},hasClass:function(e){var t,n,r=0;t=\" \"+e+\" \";while(n=this[r++])if(1===n.nodeType&&-1<(\" \"+Tt(Ct(n))+\" \").indexOf(t))return!0;return!1}});var St=/\\r/g;ce.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=v(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,ce(this).val()):n)?t=\"\":\"number\"==typeof t?t+=\"\":Array.isArray(t)&&(t=ce.map(t,function(e){return null==e?\"\":e+\"\"})),(r=ce.valHooks[this.type]||ce.valHooks[this.nodeName.toLowerCase()])&&\"set\"in r&&void 0!==r.set(this,t,\"value\")||(this.value=t))})):t?(r=ce.valHooks[t.type]||ce.valHooks[t.nodeName.toLowerCase()])&&\"get\"in r&&void 0!==(e=r.get(t,\"value\"))?e:\"string\"==typeof(e=t.value)?e.replace(St,\"\"):null==e?\"\":e:void 0}}),ce.extend({valHooks:{option:{get:function(e){var t=ce.find.attr(e,\"value\");return null!=t?t:Tt(ce.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a=\"select-one\"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!fe(n.parentNode,\"optgroup\"))){if(t=ce(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=ce.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<ce.inArray(ce.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),ce.each([\"radio\",\"checkbox\"],function(){ce.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<ce.inArray(ce(e).val(),t)}},le.checkOn||(ce.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Et=ie.location,jt={guid:Date.now()},At=/\\?/;ce.parseXML=function(e){var t,n;if(!e||\"string\"!=typeof e)return null;try{t=(new ie.DOMParser).parseFromString(e,\"text/xml\")}catch(e){}return n=t&&t.getElementsByTagName(\"parsererror\")[0],t&&!n||ce.error(\"Invalid XML: \"+(n?ce.map(n.childNodes,function(e){return e.textContent}).join(\"\\n\"):e)),t};var Dt=/^(?:focusinfocus|focusoutblur)$/,Nt=function(e){e.stopPropagation()};ce.extend(ce.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||C],d=ue.call(e,\"type\")?e.type:e,h=ue.call(e,\"namespace\")?e.namespace.split(\".\"):[];if(o=f=a=n=n||C,3!==n.nodeType&&8!==n.nodeType&&!Dt.test(d+ce.event.triggered)&&(-1<d.indexOf(\".\")&&(d=(h=d.split(\".\")).shift(),h.sort()),u=d.indexOf(\":\")<0&&\"on\"+d,(e=e[ce.expando]?e:new ce.Event(d,\"object\"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join(\".\"),e.rnamespace=e.namespace?new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:ce.makeArray(t,[e]),c=ce.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!y(n)){for(s=c.delegateType||d,Dt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||C)&&p.push(a.defaultView||a.parentWindow||ie)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(_.get(o,\"events\")||Object.create(null))[e.type]&&_.get(o,\"handle\"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&$(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!$(n)||u&&v(n[d])&&!y(n)&&((a=n[u])&&(n[u]=null),ce.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,Nt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,Nt),ce.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=ce.extend(new ce.Event,n,{type:e,isSimulated:!0});ce.event.trigger(r,null,t)}}),ce.fn.extend({trigger:function(e,t){return this.each(function(){ce.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return ce.event.trigger(e,t,n,!0)}});var qt=/\\[\\]$/,Lt=/\\r?\\n/g,Ht=/^(?:submit|button|image|reset|file)$/i,Ot=/^(?:input|select|textarea|keygen)/i;function Pt(n,e,r,i){var t;if(Array.isArray(e))ce.each(e,function(e,t){r||qt.test(n)?i(n,t):Pt(n+\"[\"+(\"object\"==typeof t&&null!=t?e:\"\")+\"]\",t,r,i)});else if(r||\"object\"!==x(e))i(n,e);else for(t in e)Pt(n+\"[\"+t+\"]\",e[t],r,i)}ce.param=function(e,t){var n,r=[],i=function(e,t){var n=v(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(null==e)return\"\";if(Array.isArray(e)||e.jquery&&!ce.isPlainObject(e))ce.each(e,function(){i(this.name,this.value)});else for(n in e)Pt(n,e[n],t,i);return r.join(\"&\")},ce.fn.extend({serialize:function(){return ce.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=ce.prop(this,\"elements\");return e?ce.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!ce(this).is(\":disabled\")&&Ot.test(this.nodeName)&&!Ht.test(e)&&(this.checked||!we.test(e))}).map(function(e,t){var n=ce(this).val();return null==n?null:Array.isArray(n)?ce.map(n,function(e){return{name:t.name,value:e.replace(Lt,\"\\r\\n\")}}):{name:t.name,value:n.replace(Lt,\"\\r\\n\")}}).get()}});var Mt=/%20/g,Rt=/#.*$/,It=/([?&])_=[^&]*/,Wt=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Ft=/^(?:GET|HEAD)$/,$t=/^\\/\\//,Bt={},_t={},zt=\"*/\".concat(\"*\"),Xt=C.createElement(\"a\");function Ut(o){return function(e,t){\"string\"!=typeof e&&(t=e,e=\"*\");var n,r=0,i=e.toLowerCase().match(D)||[];if(v(t))while(n=i[r++])\"+\"===n[0]?(n=n.slice(1)||\"*\",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Vt(t,i,o,a){var s={},u=t===_t;function l(e){var r;return s[e]=!0,ce.each(t[e]||[],function(e,t){var n=t(i,o,a);return\"string\"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s[\"*\"]&&l(\"*\")}function Gt(e,t){var n,r,i=ce.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&ce.extend(!0,e,r),e}Xt.href=Et.href,ce.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:\"GET\",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":zt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":ce.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Gt(Gt(e,ce.ajaxSettings),t):Gt(ce.ajaxSettings,e)},ajaxPrefilter:Ut(Bt),ajaxTransport:Ut(_t),ajax:function(e,t){\"object\"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=ce.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?ce(y):ce.event,x=ce.Deferred(),b=ce.Callbacks(\"once memory\"),w=v.statusCode||{},a={},s={},u=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Wt.exec(p))n[t[1].toLowerCase()+\" \"]=(n[t[1].toLowerCase()+\" \"]||[]).concat(t[2])}t=n[e.toLowerCase()+\" \"]}return null==t?null:t.join(\", \")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Et.href)+\"\").replace($t,Et.protocol+\"//\"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||\"*\").toLowerCase().match(D)||[\"\"],null==v.crossDomain){r=C.createElement(\"a\");try{r.href=v.url,r.href=r.href,v.crossDomain=Xt.protocol+\"//\"+Xt.host!=r.protocol+\"//\"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&\"string\"!=typeof v.data&&(v.data=ce.param(v.data,v.traditional)),Vt(Bt,v,t,T),h)return T;for(i in(g=ce.event&&v.global)&&0==ce.active++&&ce.event.trigger(\"ajaxStart\"),v.type=v.type.toUpperCase(),v.hasContent=!Ft.test(v.type),f=v.url.replace(Rt,\"\"),v.hasContent?v.data&&v.processData&&0===(v.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(v.data=v.data.replace(Mt,\"+\")):(o=v.url.slice(f.length),v.data&&(v.processData||\"string\"==typeof v.data)&&(f+=(At.test(f)?\"&\":\"?\")+v.data,delete v.data),!1===v.cache&&(f=f.replace(It,\"$1\"),o=(At.test(f)?\"&\":\"?\")+\"_=\"+jt.guid+++o),v.url=f+o),v.ifModified&&(ce.lastModified[f]&&T.setRequestHeader(\"If-Modified-Since\",ce.lastModified[f]),ce.etag[f]&&T.setRequestHeader(\"If-None-Match\",ce.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader(\"Content-Type\",v.contentType),T.setRequestHeader(\"Accept\",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+(\"*\"!==v.dataTypes[0]?\", \"+zt+\"; q=0.01\":\"\"):v.accepts[\"*\"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u=\"abort\",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Vt(_t,v,t,T)){if(T.readyState=1,g&&m.trigger(\"ajaxSend\",[T,v]),h)return T;v.async&&0<v.timeout&&(d=ie.setTimeout(function(){T.abort(\"timeout\")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,\"No Transport\");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&ie.clearTimeout(d),c=void 0,p=r||\"\",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while(\"*\"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+\" \"+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<ce.inArray(\"script\",v.dataTypes)&&ce.inArray(\"json\",v.dataTypes)<0&&(v.converters[\"text script\"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(!(a=l[u+\" \"+o]||l[\"* \"+o]))for(i in l)if((s=i.split(\" \"))[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e[\"throws\"])t=a(t);else try{t=a(t)}catch(e){return{state:\"parsererror\",error:a?e:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader(\"Last-Modified\"))&&(ce.lastModified[f]=u),(u=T.getResponseHeader(\"etag\"))&&(ce.etag[f]=u)),204===e||\"HEAD\"===v.type?l=\"nocontent\":304===e?l=\"notmodified\":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l=\"error\",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+\"\",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?\"ajaxSuccess\":\"ajaxError\",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger(\"ajaxComplete\",[T,v]),--ce.active||ce.event.trigger(\"ajaxStop\")))}return T},getJSON:function(e,t,n){return ce.get(e,t,n,\"json\")},getScript:function(e,t){return ce.get(e,void 0,t,\"script\")}}),ce.each([\"get\",\"post\"],function(e,i){ce[i]=function(e,t,n,r){return v(t)&&(r=r||n,n=t,t=void 0),ce.ajax(ce.extend({url:e,type:i,dataType:r,data:t,success:n},ce.isPlainObject(e)&&e))}}),ce.ajaxPrefilter(function(e){var t;for(t in e.headers)\"content-type\"===t.toLowerCase()&&(e.contentType=e.headers[t]||\"\")}),ce._evalUrl=function(e,t,n){return ce.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,converters:{\"text script\":function(){}},dataFilter:function(e){ce.globalEval(e,t,n)}})},ce.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=ce(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return v(n)?this.each(function(e){ce(this).wrapInner(n.call(this,e))}):this.each(function(){var e=ce(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=v(t);return this.each(function(e){ce(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not(\"body\").each(function(){ce(this).replaceWith(this.childNodes)}),this}}),ce.expr.pseudos.hidden=function(e){return!ce.expr.pseudos.visible(e)},ce.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},ce.ajaxSettings.xhr=function(){try{return new ie.XMLHttpRequest}catch(e){}};var Yt={0:200,1223:204},Qt=ce.ajaxSettings.xhr();le.cors=!!Qt&&\"withCredentials\"in Qt,le.ajax=Qt=!!Qt,ce.ajaxTransport(function(i){var o,a;if(le.cors||Qt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e[\"X-Requested-With\"]||(e[\"X-Requested-With\"]=\"XMLHttpRequest\"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,\"abort\"===e?r.abort():\"error\"===e?\"number\"!=typeof r.status?t(0,\"error\"):t(r.status,r.statusText):t(Yt[r.status]||r.status,r.statusText,\"text\"!==(r.responseType||\"text\")||\"string\"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o(\"error\"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&ie.setTimeout(function(){o&&a()})},o=o(\"abort\");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),ce.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),ce.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return ce.globalEval(e),e}}}),ce.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")}),ce.ajaxTransport(\"script\",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=ce(\"<script>\").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on(\"load error\",i=function(e){r.remove(),i=null,e&&t(\"error\"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\\?(?=&|$)|\\?\\?/;ce.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=Kt.pop()||ce.expando+\"_\"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter(\"json jsonp\",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?\"url\":\"string\"==typeof e.data&&0===(e.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Zt.test(e.data)&&\"data\");if(a||\"jsonp\"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,\"$1\"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?\"&\":\"?\")+e.jsonp+\"=\"+r),e.converters[\"script json\"]=function(){return o||ce.error(r+\" was not called\"),o[0]},e.dataTypes[0]=\"json\",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),\"script\"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument(\"\").body).innerHTML=\"<form></form><form></form>\",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return\"string\"!=typeof e?[]:(\"boolean\"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument(\"\")).createElement(\"base\")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(\" \");return-1<s&&(r=Tt(e.slice(s)),e=e.slice(0,s)),v(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(i=\"POST\"),0<a.length&&ce.ajax({url:e,type:i||\"GET\",dataType:\"html\",data:t}).done(function(e){o=arguments,a.html(r?ce(\"<div>\").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,\"position\"),c=ce(e),f={};\"static\"===l&&(e.style.position=\"relative\"),s=c.offset(),o=ce.css(e,\"top\"),u=ce.css(e,\"left\"),(\"absolute\"===l||\"fixed\"===l)&&-1<(o+u).indexOf(\"auto\")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),\"using\"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if(\"fixed\"===ce.css(r,\"position\"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&\"static\"===ce.css(e,\"position\"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,\"borderTopWidth\",!0),i.left+=ce.css(e,\"borderLeftWidth\",!0))}return{top:t.top-i.top-ce.css(r,\"marginTop\",!0),left:t.left-i.left-ce.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&\"static\"===ce.css(e,\"position\"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(t,i){var o=\"pageYOffset\"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each([\"top\",\"left\"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+\"px\":t})}),ce.each({Height:\"height\",Width:\"width\"},function(a,s){ce.each({padding:\"inner\"+a,content:s,\"\":\"outer\"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||\"boolean\"!=typeof e),i=r||(!0===e||!0===t?\"margin\":\"border\");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf(\"outer\")?e[\"inner\"+a]:e.document.documentElement[\"client\"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body[\"scroll\"+a],r[\"scroll\"+a],e.body[\"offset\"+a],r[\"offset\"+a],r[\"client\"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)},hover:function(e,t){return this.on(\"mouseenter\",e).on(\"mouseleave\",t||e)}}),ce.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,n){ce.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var en=/^[\\s\\uFEFF\\xA0]+|([^\\s\\uFEFF\\xA0])[\\s\\uFEFF\\xA0]+$/g;ce.proxy=function(e,t){var n,r,i;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),v(e))return r=ae.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(ae.call(arguments)))}).guid=e.guid=e.guid||ce.guid++,i},ce.holdReady=function(e){e?ce.readyWait++:ce.ready(!0)},ce.isArray=Array.isArray,ce.parseJSON=JSON.parse,ce.nodeName=fe,ce.isFunction=v,ce.isWindow=y,ce.camelCase=F,ce.type=x,ce.now=Date.now,ce.isNumeric=function(e){var t=ce.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},ce.trim=function(e){return null==e?\"\":(e+\"\").replace(en,\"$1\")},\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return ce});var tn=ie.jQuery,nn=ie.$;return ce.noConflict=function(e){return ie.$===ce&&(ie.$=nn),e&&ie.jQuery===ce&&(ie.jQuery=tn),ce},\"undefined\"==typeof e&&(ie.jQuery=ie.$=ce),ce});\n/*\n * jQuery throttle / debounce - v1.1 - 3/7/2010\n * http://benalman.com/projects/jquery-throttle-debounce-plugin/\n * \n * Copyright (c) 2010 \"Cowboy\" Ben Alman\n * Dual licensed under the MIT and GPL licenses.\n * http://benalman.com/about/license/\n */\n(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!==\"boolean\"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);\n/*!\n * imagesLoaded PACKAGED v4.1.4\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n!function(e,t){\"function\"==typeof define&&define.amd?define(\"ev-emitter/ev-emitter\",t):\"object\"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}(\"undefined\"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o<i.length;o++){var r=i[o],s=n&&n[r];s&&(this.off(e,r),delete n[r]),r.apply(this,t)}return this}},t.allOff=function(){delete this._events,delete this._onceEvents},e}),function(e,t){\"use strict\";\"function\"==typeof define&&define.amd?define([\"ev-emitter/ev-emitter\"],function(i){return t(e,i)}):\"object\"==typeof module&&module.exports?module.exports=t(e,require(\"ev-emitter\")):e.imagesLoaded=t(e,e.EvEmitter)}(\"undefined\"!=typeof window?window:this,function(e,t){function i(e,t){for(var i in t)e[i]=t[i];return e}function n(e){if(Array.isArray(e))return e;var t=\"object\"==typeof e&&\"number\"==typeof e.length;return t?d.call(e):[e]}function o(e,t,r){if(!(this instanceof o))return new o(e,t,r);var s=e;return\"string\"==typeof e&&(s=document.querySelectorAll(e)),s?(this.elements=n(s),this.options=i({},this.options),\"function\"==typeof t?r=t:i(this.options,t),r&&this.on(\"always\",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(this.check.bind(this))):void a.error(\"Bad element for imagesLoaded \"+(s||e))}function r(e){this.img=e}function s(e,t){this.url=e,this.element=t,this.img=new Image}var h=e.jQuery,a=e.console,d=Array.prototype.slice;o.prototype=Object.create(t.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)},o.prototype.addElementImages=function(e){\"IMG\"==e.nodeName&&this.addImage(e),this.options.background===!0&&this.addElementBackgroundImages(e);var t=e.nodeType;if(t&&u[t]){for(var i=e.querySelectorAll(\"img\"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if(\"string\"==typeof this.options.background){var r=e.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var u={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(e){var t=getComputedStyle(e);if(t)for(var i=/url\\((['\"])?(.*?)\\1\\)/gi,n=i.exec(t.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,e),n=i.exec(t.backgroundImage)}},o.prototype.addImage=function(e){var t=new r(e);this.images.push(t)},o.prototype.addBackground=function(e,t){var i=new s(e,t);this.images.push(i)},o.prototype.check=function(){function e(e,i,n){setTimeout(function(){t.progress(e,i,n)})}var t=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(t){t.once(\"progress\",e),t.check()}):void this.complete()},o.prototype.progress=function(e,t,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded,this.emitEvent(\"progress\",[this,e,t]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,e),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log(\"progress: \"+i,e,t)},o.prototype.complete=function(){var e=this.hasAnyBroken?\"fail\":\"done\";if(this.isComplete=!0,this.emitEvent(e,[this]),this.emitEvent(\"always\",[this]),this.jqDeferred){var t=this.hasAnyBroken?\"reject\":\"resolve\";this.jqDeferred[t](this)}},r.prototype=Object.create(t.prototype),r.prototype.check=function(){var e=this.getIsImageComplete();return e?void this.confirm(0!==this.img.naturalWidth,\"naturalWidth\"):(this.proxyImage=new Image,this.proxyImage.addEventListener(\"load\",this),this.proxyImage.addEventListener(\"error\",this),this.img.addEventListener(\"load\",this),this.img.addEventListener(\"error\",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},r.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent(\"progress\",[this,this.img,t])},r.prototype.handleEvent=function(e){var t=\"on\"+e.type;this[t]&&this[t](e)},r.prototype.onload=function(){this.confirm(!0,\"onload\"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,\"onerror\"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener(\"load\",this),this.proxyImage.removeEventListener(\"error\",this),this.img.removeEventListener(\"load\",this),this.img.removeEventListener(\"error\",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener(\"load\",this),this.img.addEventListener(\"error\",this),this.img.src=this.url;var e=this.getIsImageComplete();e&&(this.confirm(0!==this.img.naturalWidth,\"naturalWidth\"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener(\"load\",this),this.img.removeEventListener(\"error\",this)},s.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent(\"progress\",[this,this.element,t])},o.makeJQueryPlugin=function(t){t=t||e.jQuery,t&&(h=t,h.fn.imagesLoaded=function(e,t){var i=new o(this,e,t);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o});\n/*! lz-string.min.js v1.5.0 | (c) 2023 Pieroxy | MIT license */\nvar LZString=function(){var r=String.fromCharCode,o=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\",n=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$\",e={};function t(r,o){if(!e[r]){e[r]={};for(var n=0;n<r.length;n++)e[r][r.charAt(n)]=n}return e[r][o]}var i={compressToBase64:function(r){if(null==r)return\"\";var n=i._compress(r,6,function(r){return o.charAt(r)});switch(n.length%4){default:case 0:return n;case 1:return n+\"===\";case 2:return n+\"==\";case 3:return n+\"=\"}},decompressFromBase64:function(r){return null==r?\"\":\"\"==r?null:i._decompress(r.length,32,function(n){return t(o,r.charAt(n))})},compressToUTF16:function(o){return null==o?\"\":i._compress(o,15,function(o){return r(o+32)})+\" \"},decompressFromUTF16:function(r){return null==r?\"\":\"\"==r?null:i._decompress(r.length,16384,function(o){return r.charCodeAt(o)-32})},compressToUint8Array:function(r){for(var o=i.compress(r),n=new Uint8Array(2*o.length),e=0,t=o.length;e<t;e++){var s=o.charCodeAt(e);n[2*e]=s>>>8,n[2*e+1]=s%256}return n},decompressFromUint8Array:function(o){if(null==o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;e<t;e++)n[e]=256*o[2*e]+o[2*e+1];var s=[];return n.forEach(function(o){s.push(r(o))}),i.decompress(s.join(\"\"))},compressToEncodedURIComponent:function(r){return null==r?\"\":i._compress(r,6,function(r){return n.charAt(r)})},decompressFromEncodedURIComponent:function(r){return null==r?\"\":\"\"==r?null:(r=r.replace(/ /g,\"+\"),i._decompress(r.length,32,function(o){return t(n,r.charAt(o))}))},compress:function(o){return i._compress(o,16,function(o){return r(o)})},_compress:function(r,o,n){if(null==r)return\"\";var e,t,i,s={},u={},a=\"\",p=\"\",c=\"\",l=2,f=3,h=2,d=[],m=0,v=0;for(i=0;i<r.length;i+=1)if(a=r.charAt(i),Object.prototype.hasOwnProperty.call(s,a)||(s[a]=f++,u[a]=!0),p=c+a,Object.prototype.hasOwnProperty.call(s,p))c=p;else{if(Object.prototype.hasOwnProperty.call(u,c)){if(c.charCodeAt(0)<256){for(e=0;e<h;e++)m<<=1,v==o-1?(v=0,d.push(n(m)),m=0):v++;for(t=c.charCodeAt(0),e=0;e<8;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;e<h;e++)m=m<<1|t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=c.charCodeAt(0),e=0;e<16;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;0==--l&&(l=Math.pow(2,h),h++),s[p]=f++,c=String(a)}if(\"\"!==c){if(Object.prototype.hasOwnProperty.call(u,c)){if(c.charCodeAt(0)<256){for(e=0;e<h;e++)m<<=1,v==o-1?(v=0,d.push(n(m)),m=0):v++;for(t=c.charCodeAt(0),e=0;e<8;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;e<h;e++)m=m<<1|t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=c.charCodeAt(0),e=0;e<16;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;0==--l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;for(;;){if(m<<=1,v==o-1){d.push(n(m));break}v++}return d.join(\"\")},decompress:function(r){return null==r?\"\":\"\"==r?null:i._decompress(r.length,32768,function(o){return r.charCodeAt(o)})},_decompress:function(o,n,e){var t,i,s,u,a,p,c,l=[],f=4,h=4,d=3,m=\"\",v=[],g={val:e(0),position:n,index:1};for(t=0;t<3;t+=1)l[t]=t;for(s=0,a=Math.pow(2,2),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 2:return\"\"}for(l[3]=c,i=c,v.push(c);;){if(g.index>o)return\"\";for(s=0,a=Math.pow(2,d),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(c=s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 2:return v.join(\"\")}if(0==f&&(f=Math.pow(2,d),d++),l[c])m=l[c];else{if(c!==h)return null;m=i+i.charAt(0)}v.push(m),l[h++]=i+m.charAt(0),i=m,0==--f&&(f=Math.pow(2,d),d++)}}};return i}();\"function\"==typeof define&&define.amd?define(function(){return LZString}):\"undefined\"!=typeof module&&null!=module?module.exports=LZString:\"undefined\"!=typeof angular&&null!=angular&&angular.module(\"LZString\",[]).factory(\"LZString\",function(){return LZString});\n/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/dist/FileSaver.js */\n(function(a,b){if(\"function\"==typeof define&&define.amd)define([],b);else if(\"undefined\"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){\"use strict\";function b(a,b){return\"undefined\"==typeof b?b={autoBom:!1}:\"object\"!=typeof b&&(console.warn(\"Deprecated: Expected third argument to be a object\"),b={autoBom:!b}),b.autoBom&&/^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(a.type)?new Blob([\"\\uFEFF\",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open(\"GET\",a),d.responseType=\"blob\",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error(\"could not download file\")},d.send()}function d(a){var b=new XMLHttpRequest;b.open(\"HEAD\",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent(\"click\"))}catch(c){var b=document.createEvent(\"MouseEvents\");b.initMouseEvent(\"click\",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f=\"object\"==typeof window&&window.window===window?window:\"object\"==typeof self&&self.self===self?self:\"object\"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||(\"object\"!=typeof window||window!==f?function(){}:\"download\"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement(\"a\");g=g||b.name||\"download\",j.download=g,j.rel=\"noopener\",\"string\"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target=\"_blank\")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:\"msSaveOrOpenBlob\"in navigator?function(f,g,h){if(g=g||f.name||\"download\",\"string\"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement(\"a\");i.href=f,i.target=\"_blank\",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open(\"\",\"_blank\"),g&&(g.document.title=g.document.body.innerText=\"downloading...\"),\"string\"==typeof b)return c(b,d,e);var h=\"application/octet-stream\"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\\/[\\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&\"undefined\"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,\"data:attachment/file;\"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,\"undefined\"!=typeof module&&(module.exports=g)});\n/*! seedrandom.js v3.0.5 | Copyright 2019 David Bau. | MIT license */\n!function(f,a,c){var s,l=256,p=\"random\",d=c.pow(l,6),g=c.pow(2,52),y=2*g,h=l-1;function n(n,t,r){function e(){for(var n=u.g(6),t=d,r=0;n<g;)n=(n+r)*l,t*=l,r=u.g(1);for(;y<=n;)n/=2,t/=2,r>>>=1;return(n+r)/t}var o=[],i=j(function n(t,r){var e,o=[],i=typeof t;if(r&&\"object\"==i)for(e in t)try{o.push(n(t[e],r-1))}catch(n){}return o.length?o:\"string\"==i?t:t+\"\\0\"}((t=1==t?{entropy:!0}:t||{}).entropy?[n,S(a)]:null==n?function(){try{var n;return s&&(n=s.randomBytes)?n=n(l):(n=new Uint8Array(l),(f.crypto||f.msCrypto).getRandomValues(n)),S(n)}catch(n){var t=f.navigator,r=t&&t.plugins;return[+new Date,f,r,f.screen,S(a)]}}():n,3),o),u=new m(o);return e.int32=function(){return 0|u.g(4)},e.quick=function(){return u.g(4)/4294967296},e.double=e,j(S(u.S),a),(t.pass||r||function(n,t,r,e){return e&&(e.S&&v(e,u),n.state=function(){return v(u,{})}),r?(c[p]=n,t):n})(e,i,\"global\"in t?t.global:this==c,t.state)}function m(n){var t,r=n.length,u=this,e=0,o=u.i=u.j=0,i=u.S=[];for(r||(n=[r++]);e<l;)i[e]=e++;for(e=0;e<l;e++)i[e]=i[o=h&o+n[e%r]+(t=i[e])],i[o]=t;(u.g=function(n){for(var t,r=0,e=u.i,o=u.j,i=u.S;n--;)t=i[e=h&e+1],r=r*l+i[h&(i[e]=i[o=h&o+t])+(i[o]=t)];return u.i=e,u.j=o,r})(l)}function v(n,t){return t.i=n.i,t.j=n.j,t.S=n.S.slice(),t}function j(n,t){for(var r,e=n+\"\",o=0;o<e.length;)t[h&o]=h&(r^=19*t[h&o])+e.charCodeAt(o++);return S(t)}function S(n){return String.fromCharCode.apply(0,n)}if(j(c.random(),a),\"object\"==typeof module&&module.exports){module.exports=n;try{s=require(\"crypto\")}catch(n){}}else\"function\"==typeof define&&define.amd?define(function(){return n}):c[\"seed\"+p]=n}(\"undefined\"!=typeof self?self:this,[],Math);\n/*! console_hack.js | (c) 2015 Thomas Michael Edwards | Licensed under SugarCube's Simple BSD license */\n!function(){for(var methods=[\"assert\",\"clear\",\"count\",\"debug\",\"dir\",\"dirxml\",\"error\",\"exception\",\"group\",\"groupCollapsed\",\"groupEnd\",\"info\",\"log\",\"markTimeline\",\"profile\",\"profileEnd\",\"table\",\"time\",\"timeEnd\",\"timeline\",\"timelineEnd\",\"timeStamp\",\"trace\",\"warn\"],length=methods.length,noop=function(){},console=window.console=window.console||{};length--;){var method=methods[length];console[method]||(console[method]=noop)}}();\n}else{document.documentElement.setAttribute(\"data-init\", \"lacking\");}\n</script>\n<style id=\"style-normalize\" type=\"text/css\">/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}</style>\n<style id=\"style-init-screen\" type=\"text/css\">@-webkit-keyframes init-loading-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes init-loading-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes init-loading-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}#init-screen{display:none;z-index:500000;position:fixed;top:0;left:0;height:100%;width:100%;font:28px/1 Helmet,Freesans,sans-serif;font-weight:700;color:#eee;background-color:#111;text-align:center}#init-screen>div{display:none;position:relative;margin:0 auto;max-width:1136px;top:25%}html[data-init=lacking] #init-screen,html[data-init=loading] #init-screen,html[data-init=no-js] #init-screen{display:block}html[data-init=lacking] #init-lacking,html[data-init=no-js] #init-no-js{display:block;padding:0 1em}html[data-init=no-js] #init-no-js{color:red}html[data-init=loading] #init-loading{-webkit-animation:init-loading-spin 2s linear infinite;-o-animation:init-loading-spin 2s linear infinite;animation:init-loading-spin 2s linear infinite;border:12px solid transparent;border-bottom-color:#7f7f7f;border-radius:50%;border-top-color:#7f7f7f;display:block;height:100px;width:100px}html[data-init=loading] #init-loading>div{text-indent:16128px;overflow:hidden;white-space:nowrap}html[data-init=loading] #story,html[data-init=loading] #ui-bar{display:none!important}</style>\n<style id=\"style-font-icons\" type=\"text/css\">@font-face{font-family:sc-icons;font-display:block;src:url(\"data:application/octet-stream;base64,d09GRgABAAAAAFRoAAsAAAAAVBwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgD1IUnWNtYXAAAAFoAAACdAAAAnQzsxFSZ2FzcAAAA9wAAAAIAAAACAAAABBnbHlmAAAD5AAASzgAAEs4ynuL3WhlYWQAAE8cAAAANgAAADYc3WiNaGhlYQAAT1QAAAAkAAAAJAiCBP1obXR4AABPeAAAAfAAAAHwyjAFu2xvY2EAAFFoAAAA+gAAAPpXLER0bWF4cAAAUmQAAAAgAAAAIACEAIVuYW1lAABShAAAAcIAAAHCiTu08nBvc3QAAFRIAAAAIAAAACAAAwAAAAMDyQGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA+CoDgP+AAIADgACAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEAlgAAACSAIAABgASAAEAIPAC8AXwDvAR8BPwFfAZ8CPwKPAu8E7wWvBe8GPwaPBq8G7wcfB48InwjfCT8JzwoPDC8MfwyfDQ8Nrw5/Dr8P7xDvEQ8SfxOvE+8ULxRPFG8UrxUvGG8YjxkfGr8d3x4PH48gXyRPKL8o3y6vLt8vHy+fMe813zgvQQ9Vr1b/V09cD2qfeM99n4Kv/9//8AAAAAACDwAvAE8AzwEPAT8BXwGfAj8CbwLvBI8FDwXvBg8GXwavBu8HDwd/CJ8I3wk/Cc8KDwwfDH8Mnw0PDX8Ofw6/D+8Q3xEPEn8TfxPvFB8UTxRvFK8VDxhfGI8ZHxq/Hd8eDx+PIE8kDyi/KN8ury7fLx8vnzHvNd84H0EPVa9W31dPXA9qn3jPfZ+Cn//f//AAH/4xACEAEP+w/6D/kP+A/1D+wP6g/lD8wPyw/ID8cPxg/FD8IPwQ+8D6wPqQ+kD5wPmQ95D3UPdA9uD2gPXA9ZD0cPOQ84DyIPEw8QDw4PDQ8MDwkPBA7SDtEOyQ6wDn8OfQ5mDlsOIQ3bDdoNfg18DXkNcg1ODRAM7QxgCxcLBQsBCrYJzgjsCKAIUQADAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAIAAP+OA/IDgAArAEcAACUWFA8BBiIvAS4BPQEOASMiJy4BJyY1NDc+ATc2MzIXHgEXFhUUBgczMhYXJTI3PgE3NjU0Jy4BJyYjIgcOAQcGFRQXHgEXFgPyDg45DigOxwcHNYNIVkxMcSAhISBxTExWVkxMcSAhLykhCRIH/nU1Ly5GFBQUFEYuLzU1Ly5GFBQUFEYuLwsOKA45Dg7HBxIJISkvISBxTExWVkxMcSAhISBxTExWSIM1BwcOFBRGLi81NS8uRhQUFBRGLi81NS8uRhQUAAAAAAEAEv/TA+4DNQAjAAABFhceAQcGBwEGIicBJicmNjc2NzY3NhYXFh8BNzY3PgEXFhcDnS8YGQUUFCr+fRM1Ev59KxMUBRkYLyoxMWUvMCYnJyYwL2UxMikDAyg2NnI3Nyz+cBMTAZAsNzdyNjYoIw8OCBYWJykpJxYWCA4PIwAAAQA8/4cERANcABgAAAE2MhcTBR4BDwETFgYnJQUGJjcTJyY2NyUCBxFQEYMBJCgYHNQyB0Ej/vv++yNBBzLUHBknASQDXCQk/vgrBksczv7dKC4SiooSLigBI84cSwYrAAAAAAEADwARA/EC7wAVAAAlASY0PwE2Mh8BATYyHwEWFAcBBiInAVz+sw8PSA8rD+AB4A8rD0gPD/2zDyoPEQFNDyoPSQ8P4AHgDw9JDyoP/bMPDwAAAAEAEgAyAq4CzgAjAAABFxYUDwEGIi8BBwYiLwEmND8BJyY0PwE2Mh8BNzYyHwEWFAcB5ckSEi0SNBPIyBM0Ei0SEsnJEhItEjQTyMgTNBItEhIBgMgTNBItEhLJyRISLRI0E8jIEzQSLRISyckSEi0SNBMAAwAA/44D8gOAACMAUABsAAABFRQGKwEVFAYrASImPQEjIiY9ATQ2OwE1NDY7ATIWHQEzMhYBBwYiLwEuAT0BDgEjIicuAScmNTQ3PgE3NjMyFx4BFxYVFAYHMzIWHwEWFAcBNCcuAScmIyIHDgEHBhUUFx4BFxYzMjc+ATc2AmAOCnAOCkAKDnAKDg4KcA4KQAoOcAoOAZI5DicOyAcHNYNIVkxMcSAhISBxTExWVkxMcSAhLykhCRIHxw4O/r4VFkkyMjg4MjFKFhUVFkkyMjg4MjFKFhUCAEAKDnAKDg4KcA4KQAoOcAoODgpwDv29OQ4OxwcSCSEpLyEgcUxMVlZMTHEgISEgcUxMVkiDNQcHxw4oDgIZODIxShYVFRZJMjI4ODIxShYVFRZJMjIAAAMAAP+OA/IDgAAPADwAWAAAARUUBiMhIiY9ATQ2MyEyFgEHBiIvAS4BPQEOASMiJy4BJyY1NDc+ATc2MzIXHgEXFhUUBgczMhYfARYUBwE0Jy4BJyYjIgcOAQcGFRQXHgEXFjMyNz4BNzYCYA4K/rAKDg4KAVAKDgGSOQ4nDsgHBzWDSFZMTHEgISEgcUxMVlZMTHEgIS8pIQkSB8cODv6+FRZJMjI4ODIxShYVFRZJMjI4ODIxShYVAgBACg4OCkAKDg79vTkODscHEgkhKS8hIHFMTFZWTExxICEhIHFMTFZIgzUHB8cOKA4CGTgyMUoWFRUWSTIyODgyMUoWFRUWSTIyAAAAAAIAEP+QA/ADgAA+AE4AAAEWFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzY3NhYfARYGBw4BFRQXHgEXFjMyNz4BNzY1NCYnLgE/AT4BFwMUBisBIiY1ETQ2OwEyFhUDIC8nJjYPDycnhlpaZ2ZbWocoJw8ONyYmMBEqCx8JBw8+ShoaWz49RkU9PVwbGkdBDwcJHwsqEdAcFEAUHBwUQBQcAxQiLCxnOjs+Z1pahycnJyeGWltmPzo6aCwsIgwJEzgQIwsujVNFPT1cGhsaGlw9PkdOjjALIxA4EwkM/lwUHBwUAeAUHBwUAAAAAgAm/5wD2gNkAFMAXwAAAR4BBw4BBw4BLwEOAQcVFAYHBiInLgE9AS4BJwcGJicuAScmNj8BJjQ3Jy4BNz4BNz4BHwE+ATc1NDY3PgEXHgEdAR4BFzc2FhceARcWBg8BFhQHBTI2NTQmIyIGFRQWA88HBgIRNyUGEQdVGz4hCgk0bzcICyE+GlYHEQUlOBECBgdWBwdWBwYCETglBREHVRs+IQsING83CAshPhtVBxEFJTgRAgYHVQYG/oZCXl5CQl5eAQkFDwk1YCgGAwUxFyQLYwgNAgwMAg0IYwskFzEFAwYoYDUJDwQyIkcjMQQQCDZfKAcCBDEXIwxiCQ0CCwEMAg0JYgwjFzEEAgYpXzYIDwUxI0YjWl5CQl5eQkJeAAAAAAIAAP/ABIADQAAjAFcAAAE+ATMyFhcBERQGIyciJjU4ATE1NCYrASIGHQEUBiMHIiY1ESUeARUUBg8BDgEjIiYnAS4BIyIGBwEOASMiJi8BLgE1NDY3AT4BMzIWHwE1NDY7ATIWFRECMQMIBAQIAwFxEw3gDRMTDYANExMN4A0TA7cEBQMCMwQJBgQIA/4pAwgEBAgD/ikDCAQGCQQzAgMFBAH6DCARESAMsw4KcAoOAlcDAwMD/tH+uA0TARIOvw0TEw2/DhIBEw0BSGEDCgYECAM+BAUDAwGDAwMDA/59AwMFBD4DCAUFCgMBoQoMDAqTkQoODgr+6wAAAAQAAP+ABAADgAAWAC0AOQBFAAABMzIWFREzMhYHAQYiJwEmNjsBETQ2MwEVFAYjISImPQE0NjMhFxYyPwEhMhYVBzQmIyIGFRQWMzI2NzQmIyIGFRQWMzI2AbCgFByvGxQS/s8LIAv+zxMVGrAcFAJQHBT8YBQcHBQBJWIfVB9iASUUHPgXERAYFxEQGIAXERAYFxEQGAOAHBT+sDET/s8LCwExEzEBUBQc/RDgFBwcFOAUHGIeHmIcFLAQGBcREBgXERAYFxEQGBcAAAIAAP+AA4ADgAAgACkAAAEyFhURFAYjISImNRE0NjsBNTQ3PgE3NjMyFx4BFxYdASM1NCYjIgYdAQMgKDg4KP1AKDg4KDAYGFI4Nz8/NzhSGBigVDw8VAHAOCj+gCg4OCgBgCg4kD83OFIYGBgYUjg3P5CQPFRUPJAAAAABAAAADgIAAvIAEQAAATYWFREUBi8BIyImNRE0NjsBAa4WPDsXsswUHBwUzALyFhgg/WAgGBayHBQBIBQcAAAAAgAAAAwDAALwABEAKgAAATYWFREUBi8BIyImNRE0NjsBBR4BFRQGBwYmJyY2Nz4BNTQmJy4BNz4BFwGuFzs7F7LMFBwcFMwBqCsxMSsRJgoJCxEUFhYUEQsJCiYRAvAWGCD9YCAYFrIcFAEgFBwmGFIwMFIYCQsREiYJCyUWFiULCSYSEQsJAAQAAP+oBIADWAARADoAWwB0AAABNhYVERQGLwEjIiY1ETQ2OwEBFhceARcWFRQHDgEHBgcGJicmNjc2Nz4BNzY1NCcuAScmJy4BNz4BFxMUBw4BBwYHBiYnJjY3PgE1NCYnLgE3PgEXFhceARcWFSUeARUUBgcGJicmNjc+ATU0JicuATc+ARcBrhc7OxeyzBQcHBTMAoU8Ly9CEhEREkIvLzwSJwoLCBExKCc2Dw4ODzYnKDERCAsLJxE/DAstHyApEiYKCggRPENDPBEICgsnECkgHy0LDP7kKzExKxEmCgkLERQWFhQRCwkKJhEC8hYYIP1gIBgWshwUASAUHAEYJzQ0ekRER0dERHo0NCcLCRARJwsgKytlODk7Ozk4ZSsrIAsnEREIC/4oMC0tUCMiGQwLDxEnCyZ7RkZ7JgsnERAJCxkiI1AtLTCaGFIwMFIYCQsREiYJCyUWFiULCSYSEQsJAAAAAAEAAP+AAwADgAAKAAAXETQ2MyEyFhURJQA4KAJAKDj+gIADoCg4OCj8YOAAAQCA/8ADAANAABkAABcRNDY7ATIWFREBNhYVERQGJwERFAYrASImgA4KYAoOAYcfSkof/nkOCmAKDigDUAoODgr+nwFqGiIp/QApIhoBaP6hCg4OAAAAAAEAAAAABAADAAAkAAA3ETQ2OwEyFhURATYWFREBNhYVERQGJwERFAYnAREUBisBIiY1AA4KUAoOAVcfSgFXH0pKH/6pSh/+qQ4KUAoOGALQCg4OCv7QATkaIin++AE5GiIp/YApIhoBNv77KSIaATb+0woODgoAAAIAFwAPBAAC8QALABcAABMmNDcBNhYVERQGJxMmNDcBNhYVERQGJxcXFwGAH0pKH4AXFwGAH0pKHwFPEzwTAUAaIin9gCkiGgFAEzwTAUAaIin9gCkiGgABAAD/jQNRA3MACwAAARYUBwEGJjURNDYXA1EvL/1AMGFmKwHTHG4c/mAcNzgDQD8tGQAAAgAA/8IDgANCAA8AHwAABSMiJjURNDY7ATIWFREUBiUUBisBIiY1ETQ2OwEyFhUBIMAoODgowCg4OAI4OCjAKDg4KMAoOD44KALAKDg4KP1AKDhgKDg4KALAKDg4KAAAAQAA/8ADgANAAA8AAAEyFhURFAYjISImNRE0NjMDICg4OCj9QCg4OCgDQDgo/UAoODgoAsAoOAACAAAADwPpAvEACwAXAAABFhQHAQYmNRE0NhcDFhQHAQYmNRE0NhcD6RcX/oAfSkofgBcX/oAfSkofAbETPBP+wBoiKQKAKSIa/sATPBP+wBoiKQKAKSIaAAAAAAEAAAAABAADAAAjAAABERQGKwEiJjURAQYmNREBBiY1ETQ2FwERNDYXARE0NjsBMhYEAA4KUAoO/qkfSv6pH0pKHwFXSh8BVw4KUAoOAuj9MAoODgoBMP7HGiIpAQj+xxoiKQKAKSIa/skBBikiGv7JAS4KDg4AAAEAgP/AAwADQAAZAAABERQGKwEiJjURAQYmNRE0NhcBETQ2OwEyFgMADgpgCg7+eR9KSh8Bhw4KYAoOAyj8sAoODgoBYf6WGiIpAwApIhr+mAFfCg4OAAACAAD/wAOAAyEADwAcAAAlFRQGIyEiJj0BNDYzITIWJSImNwE2MhcBFgYjIQOAJRv9ABslJRsDABsl/OA+MyoBYB1UHQFgKjM+/UCAgBslJRuAGyUlZXMuAYAfH/6ALnMAAAAAAQBF/9kCOwMnABUAABMBNjIfARYUBwkBFhQPAQYiJwEmNDdFAYUOKA4tDg7+zAE0Dg4tDigO/nsODgGiAYUODi4OJw/+y/7LDycOLg4OAYUOKA4AAQBF/9kCOwMnABUAAAkBBiIvASY0NwkBJjQ/ATYyFwEWFAcCO/57DigOLQ4OATT+zA4OLQ4oDgGFDg4BXv57Dg4uDicPATUBNQ8nDi4ODv57DigOAAAAAAIAEP+QA/ADcAAbAD8AAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzYBNTQmKwE1NCYrASIGHQEjIgYdARQWOwEVFBY7ATI2PQEzMjYCAGdaWocnJycnh1paZ2daWocnJycnh1paAYcOCrgOCnAKDrgKDg4KuA4KcAoOuAoOA3AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf92HAKDrgKDg4KuA4KcAoOuAoODgq4DgAAAAIAEP+QA/ADcAAbACsAAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzYDITI2PQE0JiMhIgYdARQWAgBnWlqHJycnJ4daWmdnWlqHJycnJ4daWqECEAoODgr98AoODgNwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/cAOCnAKDg4KcAoOAAACABD/kAPwA3AAGwBAAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2ASc3NjQvASYiDwEnJiIPAQYUHwEHBhQfARYyPwEXFjI/ATY0JwIAZ1pahycnJyeHWlpnZ1pahycnJyeHWloBWoODBwdPBxQHgoIHFAdPBweDgwcHTwcUB4KCBxQHTwcHA3AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf9joKCBxQHTwcHg4MHB08HFAeCggcUB08HB4ODBwdPBxQHAAIAEP+QA/ADcAAbADEAAAEUBw4BBwYjIicuAScmNTQ3PgE3NjMyFx4BFxYJATY0LwEmIgcBJyYiDwEGFB8BFjI3A/AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf91wFwCQkuCRsJ/tSMCRsJLgkJ0AoaCgGAZ1pahycnJyeHWlpnZ1pahycnJyeHWlr+kgFwChoKLQkJ/tSMCQktChoK0AkJAAAAAwAQ/5AD8ANwABsASQBVAAABFAcOAQcGIyInLgEnJjU0Nz4BNzYzMhceARcWJSIGBwYWHwEWNjc+ATMyFhUUBgcOAR0BFBY7ATI2PQE0Nz4BNzY1NCcuAScmIwMiBhUUFjMyNjU0JgPwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/h1RbykFAwhFCBMGGy8pHzwiHyNKDgpwCg4aGj4aGhQVQiopKw0mNjYmJjY2AYBnWlqHJycnJ4daWmdnWlqHJycnJ4daWuVCPgcTBjUGAwgiJSQeFh0REzw+CAoODgoDFQ4PKCEgOiwlJTcPEP4QNiYmNjYmJjYAAAAAAwAQ/5AD8ANwABsAJwBGAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2FyIGFRQWMzI2NTQmEzU0JisBNTQmKwEiBh0BFBY7ARUjIgYdARQWOwEyNgIAZ1pahycnJyeHWlpnZ1pahycnJyeHWlpnIzExIyMxMU0OChgOCoAKDg4KGBgKDg4KsAoOA3AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyfcMSMjMTEjIzH+BDAKDsgKDg4KMAoOgA4KMAoODgAAAAADABD/kAPwA3AAGwArADsAAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzYFJicuAQcGBwE2NzYmJyYnARYXHgE3NjcBBgcGFhcWFwIAZ1pahycnJyeHWlpnZ1pahycnJyeHWloBazE8PH4+PTUCASUQEQoaGzH9+DE8PH4+PTX9/yUQEQoaGzEDcCcnh1paZ2daWocnJycnh1paZ2daWocnJ+wxGxoKERAl/f81PT5+PDwx/fgxGxoKERAlAgE1PT5+PDwxAAEADv/ZA4ADJwAeAAAlBwYiJwEmNDcBNjIfARYUDwEhMhYdARQGIyEXFhQHAgMsDigO/nsODgGFDigOLA4P8QI/FBwcFP3B8Q8OBi0ODgGFDigOAYUODi0OKA7mHBRAFBzmDigOAAAAAQAA/9kDcgMnAB4AAAE3NjIXARYUBwEGIi8BJjQ/ASEiJj0BNDYzIScmNDcBfSwOKA4BhQ4O/nsOKA4sDg/x/cEUHBwUAj/xDw4C+i0ODv57DigO/nsODi0OKA7mHBRAFBzmDigOAAABABn/wANmAzIAHgAAEycmNDcBNjIXARYUDwEGIi8BERQGKwEiJjURBwYiJ0YtDg4BhQ4oDgGEDw8sDikO5RwUQBQc5g4oDgE9LA4oDgGFDg7+ew4nDi0OD/H9wRQcHBQCP/EPDgAAAAEAGf/OA2cDQAAeAAABFxYUBwEGIicBJjQ/ATYyHwERNDY7ATIWFRE3NjIXAzotDg7+ew4oDv57Dg4tDigO5hwUQBQc5g4oDgHDLA4oDv57Dg4BhQ4oDiwOD/ECPxQcHBT9wfEPDgAABAAA/8ADgANAABQAKQA+AFMAABM1NDY7ATIWHQEUBisBFRQGKwEiJgE0NjsBMhYdARQGKwEiJj0BIyImNQEyFh0BFAYrASImPQE0NjsBNTQ2MwEUBisBIiY9ATQ2OwEyFh0BMzIWFQAcFPgKDg4KqA4KUAoOAkAOCvgUHA4KUAoOqAoOASgKDhwU+AoODgqoDgr+KA4K+BQcDgpQCg6oCg4CGPgUHA4KUAoOqAoODgEaCg4cFPgKDg4KqA4K/igOCvgUHA4KUAoOqAoO/tgKDhwU+AoODgqoDgoAAAQAAP/AA4ADQAAUACkAPgBTAAABIyImPQE0NjsBMhYdATMyFh0BFAYlFAYrASImPQE0NjsBNTQ2OwEyFhURFAYrASImPQEjIiY9ATQ2OwEyFhUFFAYrASImPQE0NjsBMhYdARQGKwEDaPgUHA4KUAoOqAoODv3OHBT4Cg4OCqgOClAKDg4KUAoOqAoODgr4FBwBgA4KUAoOHBT4Cg4OCqgCABwU+AoODgqoDgpQCg4wFBwOClAKDqgKDg4K/LAKDg4KqA4KUAoOHBT4Cg4OCvgUHA4KUAoOAAEAAP/AA4ADQAAjAAABMhYdARQGIyERFAYrASImNREhIiY9ATQ2MyERNDY7ATIWFREDQBslJRv+4CUbQBsl/uAbJSUbASAlG0AbJQHgJRtAGyX+4BslJRsBICUbQBslASAbJSUb/uAAAQAAASADgAHgAA8AAAEyFh0BFAYjISImPQE0NjMDQBslJRv9ABslJRsB4CUbQBslJRtAGyUAAAADABD/kAPwA3AAGwAnADcAAAEUBw4BBwYjIicuAScmNTQ3PgE3NjMyFx4BFxYFIgYVFBYzMjY1NCYDEx4BOwEyNjcTNiYrASIGA/AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf+ECY2NiYmNjZ9DgEOCWIJDgEOAQ4LfgsOAYBnWlqHJycnJ4daWmdnWlqHJycnJ4daWss2JiY2NiYmNgFL/vAKDQ0KARAKDw8AAwAAAAAEgAMAACgASQBlAAABHgEVFAYHBgcOAQcGIyInLgEnJicuATU0Njc2Nz4BNzYzMhceARcWFwE4ATEyNz4BNzY1MTQnLgEnJiMiBw4BBwYVFBceARcWMxE4ATEyFhUUBiMiJjU0NjceATMyNjU0Jic+ATMEeQMEBAMpOzuTVlVcXFVWkzs7KQMEBAMpOzuTVlVcXFVWkzs7Kf3HPDQ1ThYXFxZONTQ8PDQ1ThYXFxZONTQ8UHBwUE9wAwQLHRAoOAoJDBoNAZ0GDwgIDwZQQUFeGRoaGV5BQVAGDwgIDwZQQUFeGRoaGV5BQVD+wxcWTjU0PDw0NU4WFxcWTjU0PDw0NU4WFwHgcFBPcHBPDRoMCQo4KBAdCwQEAAAAAwAA/4AFAAOAAB8ATwB0AAAlMjY3Fw4BIyInLgEnJicuATU0Njc+ATcXFhceARcWMwUeARUUBg8BDgEjIiYnAS4BNTQ2PwE+ATMyFh8BPgEzMhceARcWFx4BFRQGBw4BByc+ATU4ATE0Jy4BJyYjMSIGBxc+ATU0Jic+ATMyFhUcARUUBgcCgA0aDWgmTihcVVaTOzspAwQEAw8mFNIEGBhNMjI5AnQFBwQDJwQOBwYKBPtnBQcEAycEDgcGCgT+QpVQXFVWkzs7KQMEBAMeUjKTDQ8XFk41NDw0XSWTAQIKCQ0bDU9vBgRgAwJQCgsaGV5BQVAGDwgIDwYeNxqiODAxSBQVdAUNBwYKBDMFBwQDA40FDQcGCgQzBQcEA8QjKBoZXkFBUAYPCAgPBjtnKnEbPSA8NDVOFhcjH3IFCgUQHQsEBG9OAQEBEB0OAAAAAwAN/4AEcwNQAAsAFwAnAAAlFgYjISImNwE2MhcDIgYVFBYzMjY1NCYDEx4BOwEyNjcTNiYrASIGBHMcODf8QDc4HAHgHG8bUyY2NiYmNjZ9DgEOCWIJDgEOAQ4LfgsOEDBgYDADQDAw/Ww2JiY2NiYmNgFL/vAKDQ0KARAKDw8AAAAAAQAZAIUDZwJ7ABUAAAkBFhQPAQYiJwkBBiIvASY0NwE2MhcB4gGFDg4uDicP/sv+yw8nDi4ODgGFDigOAnv+ew4oDi0ODgE0/swODi0OKA4BhQ4OAAAAAAEAGQCFA2cCewAVAAAlASY0PwE2MhcJATYyHwEWFAcBBiInAZ7+ew4OLg4nDwE1ATUPJw4uDg7+ew4oDoUBhQ4oDi0ODv7MATQODi0OKA7+ew4OAAEAPP+IAkADgAAPAAABEQUGJjcTJyY2NyUTPgEzAkD++yNBBzLUHBknASSDCCARA4D8kYkTLycBI84cSwYrAQgSEgAAAQAA/4kDAAOAAC0AAAEeARUUBiMhFRQGDwEGIi8BLgE9ASEiJjU0Nj8BIyImPQE0NjMhMhYdARQGKwECVEhkHBT+8AEBMAQUBDABAf7wFBxjSRhUFBwcFAIgFBwcFFQB0yF1TRQc0AIEAWAJCWABBALQHBRMdiHtHBRgFBwcFGAUHAAABAAA/4AEAAN1ABYAMAA8AEgAACUjIiY1ESMiJjcBNjIXARYGKwERFAYjJRUUBiMhIiY9ATQ2MyEVFBY7ATI2PQEhMhYHNCYjIgYVFBYzMjY3NCYjIgYVFBYzMjYCUKAUHK8bFBIBMQsgCwExExUbrxwUAbAcFPxgFBwcFAEQQi6gLkIBEBQc+BcREBgXERAYgBcREBgXERAYgBwUAVAxEwExCwv+zxMx/rAUHBDgFBwcFOAUHBAuQkIuEBzEEBgXERAYFxEQGBcREBgXAAAAAAEAAP+AA4ADgAAwAAABMhYVERQGIyEiJjURNDY7ATU0Nz4BNzYzMhceARcWHQEUBisBIiY9ATQmBw4BHQEhAyAoODgo/UAoODgoMBgXUzc3Pz84N1MYGBwUQBQcVTw8UwHwAYA4KP7AKDg4KAFAKDjNPzg4UxgZGBdTODc/IBQcHBQgPFUBAVU8zgAABAAAAAAEgAMAAA8AJAAwADwAAAEVFAYjISImPQE0NjMhMhYnITgBMSIGBxM+ATMhMhYXEy4BIzEHIgYVFBYzMjY1NCYjIgYVFBYzMjY1NCYEgDgo/EAoODgoA8AoOGD8QBEeD8IMKhkCGhkqDMIPHxBgGyUlGxslJdsbJSUbGyUlASDAKDg4KMAoODh4BgYBIRQXFxT+3wYGwCUbGyUlGxslJRsbJSUbGyUAAAIAFv+WA+oDagA+AH0AAAEWFxYUBwYHMAYxBwYHBiInJicmJyY0NzY/ATYWFx4BFxYGDwEOARcWMj8BNjQnLgEnLgE1JjY/AT4BFx4BFwEWFxYUBwYPAQYmJy4BJyY2PwE+AScmIg8BBhQXHgEXHgEVFgYPAQ4BJy4BJyYnJjQ3NjcwNjE3Njc2MhcWFwKNLRYWFhYsAYYtODh1ODgsLRYWFhYtSg8nAQEJCQMEBhsqAioqeCuGKioFCwUGBwELDSoIGAkLFQkBGi0WFhYWLUoPJwEBCQkDBAYbKgIqKngrhioqBQsFBgcBCw0qCBgJCxUJLRYWFhYsAYYtODh1ODgsAg0tODh0ODgsAYYtFhYWFi0sODh1ODgtSg8PFRs1GggSBxoqdysrKoYrdyoGCAMEDgcQIAwqCAIGCBEKARosODh1ODgtSg8PFRs1GggSBxoqdysrKoYrdyoGCAMEDgcQIAwqCAIGCBEKLTg4dDg4LAGGLRYWFhYtAAAAAQAA/8AFAANAADcAAAEWFx4BFxYVFAcOAQcGIyEiJy4BJyY1NDc+ATc2NzwBNTQ3PgE3NjMyFx4BFxYXPgEzMhYVFAYHBDMsJSY3DxAUFEYuLzX9IDw0NU4WFw4PMyMjKhkZVzo7QiwqKUcdHhQXNh5PcQcGAbsJFxdCKiouNS8uRhQUFxZONTQ8LysrRxobDwQIBEI7OlcZGQwLKh4dJA8RcU8SIxAAAwAA/8ADgANAABMAHwA0AAABHgEVERQGIyEiJjURNDYzITIWFwMyNjU0JiMiBhUUFhM0Ji8BLgEjISIGHQEUFjMhMjY9AQNkDQ84KP1AKDg4KAIYFCMN/DVLSzU1S0v1BAMHAwkF/jcKDg4KAdAKDgJ8DSMU/egoODgoAsAoOA8N/RxLNTVLSzU1SwJhBQkDBwMEDgrQCg4OCskAAwAA//gDgAMIAA8AHwAvAAATIiY9ATQ2MyEyFh0BFAYjASImPQE0NjMhMhYdARQGIwEiJj0BNDYzITIWHQEUBiMgDRMTDQNADRMTDfzADRMTDQNADRMTDfzADRMTDQNADRMTDQJ4Ew1QDRMTDVANE/7AEw1QDRMTDVANE/7AEw1QDRMTDVANEwAAAAAFAAD/gAQAA4AABwAPABcALQAxAAABLwE/AR8BBwUvAT8BHwEHAR8BDwEvATcTFhQHAQ4BIyImLwEmNDcBPgEzMhYXAzcnBwHAIEBAICBAQP7ANWtrNTVrawKLNWtrNTVra8ITE/0qCRgMDRcKqRMTAtYJGAwNFwp1rWatAsBAICBAQCAgwGs1NWtrNTX+lWs1NWtrNTUB7xM1E/0qCgkJCqkTNRMC1goJCQr+fK1mrQAAAAABACIAugJdAgAADAAAEyEyFgcBBiInASY2Mz8CAhsUE/7/DCEL/v4TFRsCADET/v4LCwECEzEAAAEAIgDAAl4CBgALAAAlISImNwE2MhcBFgYCQf3+GxUTAQILIgsBAhMVwDETAQILC/7+EzEAAAAAAQA6AGIBgAKeAAwAAAERFAYnASY0NwE2FhUBgDET/v4LCwECEzECgf3+GxUTAQILIgsBAhMVGwABAAAAYgFGAp4ADAAANxE0NhcBFhQHAQYmNQAxEwECCwv+/hMxfwICGxUT/v4LIgv+/hMVGwAAAAEAAP+AAnkDgAAZAAABMhYHAQ4BIyImNxMjIiY3Ez4BMyEyFgcDMwJQHBsO/qAGFwwXHQVc7RYcAkADGxIBIBgcBlXnAkAwGP2gCw0kFwGFIRUB4BIYJhb+/AAAAwAA/4ACwAOAABIANABKAAAXNSEVFAYPAQ4BKwEiJi8BLgE1AzQ3PgE3NjMyFx4BFxYVFAYHDgEHHAExITA0NS4BJy4BNSUyNjU0JiMiBw4BBwYVFBYzMjY1NDbAAUAGBSIJHBB8EBwJIgUGwBoaXkBATUlAQV8cHC4pGUEP/sAPQRkpLgFgDRMTDS4pKT0REhMNDRNeDU1NCRIIMw0QEA0zCBIJAi1GP0BhHR0bHGBAQElDdi8caTEBAQEBMWkcL3ZDoBMNDRMSET0pKS4NExMNQl4AAAAAAgAA/8ADgANAAA8AMwAAATIWFREUBiMhIiY1ETQ2MwE1NCYrATU0JisBIgYdASMiBh0BFBY7ARUUFjsBMjY9ATMyNgMgKDg4KP1AKDg4KAKADgq4DgpwCg64Cg4OCrgOCnAKDrgKDgNAOCj9QCg4OCgCwCg4/ghwCg64Cg4OCrgOCnAKDrgKDg4KuA4AAAAAAgAA/8AEAANAACAAQQAAATIWFREUBiMhIiY1ETQ3PgE3NjsBMhYdARQGKwEiBh0BITIWFREUBiMhIiY1ETQ3PgE3NjsBMhYdARQGKwEiBh0BA6AoODgo/wAoOBkZVzo7QhAUHBwUEDVL/mAoODgo/wAoOBkZVzo7QhAUHBwUEDVLAYA4KP8AKDg4KAHgQjs6VxkZHBRgFBxLNYA4KP8AKDg4KAHgQjs6VxkZHBRgFBxLNYAAAgAA/8AEAANAACAAQQAAATIWFREUBw4BBwYrASImPQE0NjsBMjY9ASMiJjURNDYzITIWFREUBw4BBwYrASImPQE0NjsBMjY9ASMiJjURNDYzA6AoOBkZVzo7QhAUHBwUEDVLoCg4OCj+wCg4GRlXOjtCEBQcHBQQNUugKDg4KANAOCj+IEI7OlcZGRwUYBQcSzWAOCgBACg4OCj+IEI7OlcZGRwUYBQcSzWAOCgBACg4AAAABwAA/4AEAAOAAAsAFwAjAC8AOwBHAFMAAAEUBiMiJjU0NjMyFgMyFhUUBiMiJjU0NgEyFhUUBiMiJjU0NgUUBiMiJjU0NjMyFhcyFhUUBiMiJjU0NiEyFhUUBiMiJjU0NgEyFhUUBiMiJjU0NgJgOCgoODgoKDhgKDg4KCg4OAHIKDg4KCg4OP1IOCgoODgoKDgaKDg4KCg4OAJ0KDg4KCg4OP3cKDg4KCg4OAMgKDg4KCg4OPz4OCgoODgoKDgBoDgoKDg4KCg4YCg4OCgoODjuOCgoODgoKDg4KCg4OCgoOAJMOCgoODgoKDgAAAAAAwAO/44D8gNyACUATABcAAAlFhQPAQYHBiInJicmJyY0NzY/ATYyHwEWFA8BBhQXFjI/ATYyFwMnJjQ/ATY3NjIXFhcWFxYUBwYPAQYiLwEmND8BNjQnJiIPAQYiJwEGIicBJjQ/ATYyFwEWFAcCYAcHWS04OHU4OCwtFhYWFi1ZBxQHTwcHWSoqKngqWQcUByJPBwdZLTg4dTg4LC0WFhYWLVkHFAdPBwdZKioqeCpZBxQHAdYOKA78jQ4OLQ4oDgNzDg5UBxQHWS0WFhYWLSw4OHU4OC1ZBwdPBxQHWSp4KioqWQcHAbpPBxQHWS0WFhYWLSw4OHU4OC1ZBwdPBxQHWSp4KioqWQcH/TEODgNzDigOLQ4O/I0OKA4AAAAAAgAQ/5AD8ANwABsAMQAABSInLgEnJjU0Nz4BNzYzMhceARcWFRQHDgEHBgkBFjI/ATY0LwE3NjQvASYiBwEGFBcCAGdaWocnJycnh1paZ2daWocnJycnh1pa/rUBDw4oDiIODsvLDg4iDigO/vEODnAnJ4daWmdnWlqHJycnJ4daWmdnWlqHJycBzv7xDg4iDigOy8sOKA4iDg7+8Q4oDgAAAAACABD/kAPwA3AAGwAxAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2CQEmIg8BBhQfAQcGFB8BFjI3ATY0JwIAZ1pahycnJyeHWlpnZ1pahycnJyeHWloBS/7xDigOIg4Oy8sODiIOKA4BDw4OA3AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf+MgEPDg4iDigOy8sOKA4iDg4BDw4oDgAAAAIAEP+QA/ADcAAbADEAABM0Nz4BNzYzMhceARcWFRQHDgEHBiMiJy4BJyYJAQYUHwEWMj8BFxYyPwE2NCcBJiIHECcnh1paZ2daWocnJycnh1paZ2daWocnJwHO/vEODiIOKA7Lyw4oDiIODv7xDigOAYBnWlqHJycnJ4daWmdnWlqHJycnJ4daWgFL/vEOKA4iDg7Lyw4OIg4oDgEPDg4AAAAAAgAQ/5AD8ANwABsAMQAAARQHDgEHBiMiJy4BJyY1NDc+ATc2MzIXHgEXFgkBNjQvASYiDwEnJiIPAQYUFwEWMjcD8Ccnh1paZ2daWocnJycnh1paZ2daWocnJ/4yAQ8ODiIOKA7Lyw4oDiIODgEPDigOAYBnWlqHJycnJ4daWmdnWlqHJycnJ4daWv61AQ8OKA4iDg7Lyw4OIg4oDv7xDg4AAAACAAD/gAOAA4AAMAA+AAABMhYVERQGIyEiJjURNDY7ATU0Nz4BNzYzMhceARcWHQEUBisBIiY9ATQmBw4BHQEhATU0JiMiBh0BFBYzMjYDICg4OCj9QCg4OCgwGBdTNzc/Pzg3UxgYHBRAFBxVPDxTAfD+8C8hIS8vISEvAYA4KP7AKDg4KAFAKDjNPzg4UxgZGBdTODc/IBQcHBQgPFUBAVU8zv7QYCEvLyFgIS8vAAMAEADwA/ACEAALABcAIwAAARQGIyImNTQ2MzIWNzIWFRQGIyImNTQ2ITIWFRQGIyImNTQ2ApBUPDxUVDw8VNA8VFQ8PFRU/Xw8VFQ8PFRUAYA8VFQ8PFRUVFQ8PFRUPDxUVDw8VFQ8PFQAAAMAMP+QAVADcAALABcAIwAAEzIWFRQGIyImNTQ2JzQ2MzIWFRQGIyImETQ2MzIWFRQGIyImwDxUVDw8VFRUVDw8VFQ8PFRUPDxUVDw8VAIQVDw8VFQ8PFTQPFRUPDxUVP18PFRUPDxUVAAAAAIAEP+QA/ADcAAbACcAAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzYBNjQnJSYGFREUFjcCAGdaWocnJycnh1paZ2daWocnJycnh1paAU4ZGf6gFzAwFwNwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/eAOOA7WDRsc/mAcGw0AAAIAAP/AA4ADQAAPAB8AAAEyFhURFAYjISImNRE0NjMTITI2PQE0JiMhIgYdARQWAyAoODgo/UAoODgoWAIQCg4OCv3wCg4OA0A4KP1AKDg4KALAKDj98A4KcAoODgpwCg4AAAACAAD/wAOAA0AADwAlAAAFISImNRE0NjMhMhYVERQGJQE2NC8BJiIHAScmIg8BBhQfARYyNwMg/UAoODgoAsAoODj+PwFwCQkuCRsJ/tSMCRsJLgkJ0AoaCkA4KALAKDg4KP1AKDjEAXAJGwkuCQn+1IwJCS4JGwnQCQkAAgAA/8ADgANAAA8AGwAAAREUBiMhIiY1ETQ2MyEyFgEXFjI/ATYmIyEiBgOAOCj9QCg4OCgCwCg4/Tn2BxQH9gsMEP4UEAwC4P1AKDg4KALAKDg4/r/2Bwf2Cx4eAAAAAgAA/8ADgANAAA8AHAAANxE0NjMhMhYVERQGIyEiJgEnJiIPAQYWMyEyNicAOCgCwCg4OCj9QCg4Asf2BxQH9gsMEAHsEAwLIALAKDg4KP1AKDg4AUH2Bwf2Cx4eCwAAAgAA/8ADgANAAA8AHAAAEyEyFhURFAYjISImNRE0NgE3NjQvASYGFREUFjdgAsAoODgo/UAoODgBQfYHB/YLHh4LA0A4KP1AKDg4KALAKDj9OfYHFAf2CwwQ/hQQDAsAAwAT/5MD7QNtAAsAMwBPAAABMhYVFAYjIiY1NDYFFhQPARcWBi8BBwYiLwEHBiY/AScmND8BJyY2HwE3NjIfATc2Fg8BAzY3NjQnJicmJyYiBwYHBgcGFBcWFxYXFjI3NgIAT3FxT09xcQI8ExS9QwceFcleCisJX8kUHgdDvhMTvkMHHhTJXwoqCl/JFB4HQ3olExMTEyUlMC9iLzAlJRMTExMlJTAvYi8wAkBxT09xcU9PcaEKKgpfyRQeB0O+ExO+QwceFMlfCioKX8kUHgdDvhMTvkMHHhXI/s0lMC9iLzAlJRMTExMlJTAvYi8wJSUTExMTAAABADb/gAPEA4AALAAABSInLgEnJjU0Nz4BNzYzMhYXHgEHBgcOAQcGFRQXHgEXFjc2FgcGBw4BBwYjAjZqXV2LKCkpKItdXWoYLxcQBg8vJSY0Dg8oKIRWVl0QEgskLC1lODg8gCgpi11dampdXosoKAQFAyEIGyUmWjM0Nl5QUG0YGBEDHA0tIyMxDQ0AAAACAAD/kwQAA4AASgBZAAABDgErARUUBgcXFhQHBiIvAQ4BIxE0JisBIgYVESImJwcGIicmND8BLgE9ASMiJicmNjsBNScmNDc2Mh8BITc2MhcWFA8BFTMyFgcBMhceARcWFSE0Nz4BNzYEAAEmGm8ODXgTExI2Em4lXDQOCjAKDjRcJW4SNhITE3gNDm8aJgEBJhtwXRMTEjYSbgHKbhI2EhMTXXAbJgH+Ai4pKT0REv5AEhE9KSkBPhokICE9HHkSNhITE20eIgHoCg4OCv4YIh5tExMSNhJ5HD0hICQaGyd1XhI2EhMTbW0TExI2El51JxsCQhIRPSkpLi4pKT0REgAAAAIAAP/AA4ADQAAPABwAAAUhIiY1ETQ2MyEyFhURFAYBBwYUHwEWNjURNCYHAyD9QCg4OCgCwCg4OP6/9gcH9gseHgtAOCgCwCg4OCj9QCg4Asf2BxQH9gsMEAHsEAwLAAUAAABABQACwAAKABQAXgBoAIIAAAEXIzc+ATEzMBYXATIWFREUBiMhEQU1NCYrATU0JisBIgYdASMiBh0BFBY7AQ4BBy4BJy4BDwIOARceARcOAQcOAR8BHgE3PgE3HgEXFjY/ATYmJy4BJz4BNzMyNjUlNDYzIREhIiY1NwYWOwEyNj8BMxceATsBMjYnAy4BKwEiBgcBMBZMFgULAQoFA6AUHBwU/dACAA4KgA4KIAoOgAoODgrlCh4UChIHBhIIDw0JBAYJFQwMGg4JBQUQBRQIEyQQESMTCRMFEAUFCA0bDB8sChcKDvtgHBQCMP3QFBx2BA4NLQgNAhN4EwINCC4MDgRzAg0HQQgNAgGoS0sSMDASARgcFP3gFBwCgPAgCg4gCg4OCiAOCiAKDhUsFQoVCggEBQgIBRUIDRoNCRIJBRMIHAkFBQwZDQ0ZDAUFCRwIEwUIEwkiRyMOCsAUHP2AHBRwDBQKB0BABwoUDAFSBwkJBwABAED/wAOAA0AAKgAAARUUBisBERQGKwEiJjURIxEUBisBIiY9ASMiJy4BJyY1NDc+ATc2MyEyFgOAEw1gEw1ADRNAEw1ADRNAQjs6VxkZGRlXOjtCAeANEwMgQA0T/SANExMNAuD9IA0TEw3gGRlXOjtCQjs6VxkZEwAAAQAA/4ADgAOAADYAAAEyFhUUBiMiJjU4ATE0NjcnDgEjIiY1NDYzMhYXNy4BNTQ2MzIWFRQGIyImJwceARUUBgcXPgECwFBwcFBQcAIDzRk9IlBwcFAiPRnNAwJwUFBwcFAiPRnNAwICA80ZPQEAcFBQcHBQCxUKgBQWcFBQcBYUgAoVC1BwcFBQcBYUgAoVCwsVCoAUFgACAAD/gAOAA4AAHQAoAAABMhYdARQGIyEiJj0BNDY7ATc+ATsBOAExMhYfATMBAyEDDgEjISImJwNgDRMTDfzADRMTDfATBhYO5Q4XBhPw/QoqAwAqAzcm/hQmNwMDQBMNQA0TEw1ADRMlDA8PDCX8mgKm/VomNDQmAAAAAwAAAAAEgAMAAB0AOQBQAAABMhceARcWFRQHDgEHBiMhIicuAScmNTQ3PgE3NjMBFBceARcWMzI3PgE3NjU0Jy4BJyYjIgcOAQcGATI3PgE3NjU0Jy4BJyYrARYXFhQHBgcDAFBFRmkeHh4eaUZFUP6AUEVGaR4eHh5pRkVQ/wAUFEYuLzU1Ly5GFBQUFEYuLzU1Ly5GFBQCgDUvLkYUFBQURi4vNWIxGRgYGTEDAB4eaUZFUFBFRmkeHh4eaUZFUFBFRmkeHv6ANS8uRhQUFBRGLi81NS8uRhQUFBRGLi/+yxQURi4vNTUvLkYUFDdCQopCQjcAAAACAAAAAASAAwAAHQA5AAABMhceARcWFRQHDgEHBiMhIicuAScmNTQ3PgE3NjMBMjc+ATc2NTQnLgEnJiMiBw4BBwYVFBceARcWAwBPRkZpHh4eHmlGRVD+gE9GRmkeHh4eaUZFUAGANS8uRhQUFBRGLi81NS8uRhQUFBRGLi8DAB4eaUZFUE9GRmkeHh4eaUZFUE9GRmkeHv2AFBRGLi81NS8uRhQUFBRGLi81NS8uRhQUAAADAAAAQAUAAsAABwAhACUAAAEhESE1MzUjEzIWHQEzMhYVERQGKwEVFAYjISImNRE0NjMFESERBED8QAPAQEAgKDgQFBwcFBA4KPwAKDg4KAOg/MACQP6AgIABADgoIBwU/uAUHCAoODgoAcAoOMD/AAEAAAMAAABABQACwAAHACEAJQAAASERITUzNSMTMhYdATMyFhURFAYrARUUBiMhIiY1ETQ2MwURIREEQPxAA8BAQCAoOBAUHBwUEDgo/AAoODgoAuD9gAJA/oCAgAEAOCggHBT+4BQcICg4OCgBwCg4wP8AAQAAAwAAAEAFAALAAAcAIQAlAAABIREhNTM1IxMyFh0BMzIWFREUBisBFRQGIyEiJjURNDYzBREhEQRA/EADwEBAICg4EBQcHBQQOCj8ACg4OCgCIP5AAkD+gICAAQA4KCAcFP7gFBwgKDg4KAHAKDjA/wABAAADAAAAQAUAAsAABwAhACUAAAEhESE1MzUjEzIWHQEzMhYVERQGKwEVFAYjISImNRE0NjMFESERBED8QAPAQEAgKDgQFBwcFBA4KPwAKDg4KAFg/wACQP6AgIABADgoIBwU/uAUHCAoODgoAcAoOMD/AAEAAAIAAABABQACwAAHACEAAAEhESE1MzUjEzIWHQEzMhYVERQGKwEVFAYjISImNRE0NjMEQPxAA8BAQCAoOBAUHBwUEDgo/AAoODgoAkD+gICAAQA4KCAcFP7gFBwgKDg4KAHAKDgAAAAAAwAQ/5AD8ANwABsAKwA7AAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2ExE0JisBIgYVERQWOwEyNjcRNCYrASIGFREUFjsBMjYCAGdaWocnJycnh1paZ2daWocnJycnh1paRxMNYA0TEw1gDRPgEw1gDRMTDWANEwNwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/XABQA0TEw3+wA0TEw0BQA0TEw3+wA0TEwACABD/kAPwA3AAGwArAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2ARE0JiMhIgYVERQWMyEyNgIAZ1pahycnJyeHWlpnZ1pahycnJyeHWloBJxMN/sANExMNAUANEwNwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/XABQA0TEw3+wA0TEwAAAAEAEP+QA/ADcABEAAABMhceARcWFRQHDgEHBiMiJy4BJyYnLgE/ATYyFx4BMzI3PgE3Njc2Jy4BJyYHDgEHFxYGIyEiJjURNDYfATY3PgE3NjMB/2daW4cnJycnh1paZzAtLlQmJiEIAQhPBxMHLnE+Rj0+WhoaAQEbG10+PkVAdC5TFxkg/vQUHDsXRyInJ1YvLzIDcCcnh1paZ2daWocnJwkJIRcYHgcUCE8HBigrGxpbPTxESD4+XBoaAQEuLFMXOxwUAQwgGRdHHxoZJAkKAAAABQAA/4ADgAOAAAkAFwAlADMAUQAAFxEhERQGIyEiJgERFBYzMjY1ETQmIyIGBxEUFjMyNjURNCYjIgYHERQWMzI2NRE0JiMiBgEyFh0BFAYjISImPQE0NjsBNz4BOwE4ATEyFh8BM0ADADgo/cAoOAIgEw0NExMNDRPAEw0NExMNDRPAEw0NExMNDRMCgA0TEw38wA0TEw3wEwYWDuUOFwYT8CACoP1gKDg4Aij+QA0TEw0BwA0TEw3+QA0TEw0BwA0TEw3+QA0TEw0BwA0TEwFTEw1ADRMTDUANEyUMDw8MJQAAAgAQ/5AD8ANwACsAWAAAAS4BIyIHDgEHBgcOASsBIiY3Njc+ATc2MzIXHgEXFhc3NhYVERQGIyEiJjcFITIWDwEeATMyNz4BNzY3PgE7ATIWBwYHDgEHBiMiJy4BJyYnBwYmNRE0NjMC5S53QDo1NVYfHw4CDQhzCw4CECwsgVJRWzIvL1cnJyJHFzscFP70IBkX/a4BDCAZF1Mud0A6NTVWHx8OAg0IcwsOAhAsLIFSUVsyLy9XJyciRxc7HBQCdSwvExNDLy44CAoRC1dJSmwfHwkKJBkZIEcXGSD+9BQcOxfyOxdTLC8TE0MvLjgIChELV0lKbB8fCQokGRkgRxcZIAEMFBwAAQAQ/5AD8ANwAEQAAAEyFx4BFxYXNzYWFREUBiMhIiY/AS4BJyYHDgEHBhcWFx4BFxYzMjY3NjIfARYGBwYHDgEHBiMiJy4BJyY1NDc+ATc2MwIBMi8vVicnIkcXOxwU/vQgGRdTLnRART4+XRsbAQEaGlo+PUY+cS4HEwdPCAEIISYmVC4tMGdaWocnJycnh1taZwNwCgkkGRofRxcZIP70FBw7F1MsLgEBGhpcPj5IRDw9WxobKygGB08IFAceGBchCQknJ4daWmdnWlqHJycAAAABAAD/wAOAA0AASAAAJRUUBiM4ATEjIiY/AScHFxYGKwEiJjU4ATE1NDYfATcnBwYmPQE0NjM4ATEzMhYPARc3JyY2OwEyFhU4ATEVFAYvAQcXNzYWFQOAHBTgIBkXSNbWSBcZIOAUHDsXSNfXSBc7HBTgIBkXSNbWSBcZIOAUHDsXSNfXSBc70OAUHDsXSNfXSBc7HBTgIBkXSNbXSRcZIOAUHDsXSNfXSBc7HBTgIBkXSNbXSRcZIAAAAAIAAP+ABAADgAAeADoAAAEyFhURFAYjISImNRE0NjMhMhYdARQGIyERITU0NjMTMhYVERQGLwEBDgEjIiYvAS4BNTQ2NwEnJjYzA2ANEzgo/UAoODgoAUANExMN/uACgBMNsBQcOxdH/hgGEgoKEQctBwcHBwHnRxcZIAEAEw3/ACg4OCgCwCg4Ew1ADRP9gOANEwKAHBT/ACAYFkf+GQcHBwctBxEKChIGAehHFzsAAgAA/8AFAANAADcATQAAARYXHgEXFhUUBw4BBwYjISInLgEnJjU0Nz4BNzY3PAE1NDc+ATc2MzIXHgEXFhc+ATMyFhUUBgcFNiYrATU0JisBIgYdASMiBh8BFjI3BDMsJSY3DxAUFEYuLzX9IDw0NU4WFw4PMyMjKhkZVzo7QiwqKUcdHhQXNh5PcQcG/vYQERWDEw1gDRODFREQ0goaCgG7CRcXQioqLjUvLkYUFBcWTjU0PC8rK0caGw8ECARCOzpXGRkMCyoeHSQPEXFPEiMQshAn4A0TEw3gJxDSCgoAAAAAAgAA/8AFAANAADcATgAAARYXHgEXFhUUBw4BBwYjISInLgEnJjU0Nz4BNzY3PAE1NDc+ATc2MzIXHgEXFhc+ATMyFhUUBgcFMjYvASYiDwEGFjsBFRQWOwEyNj0BMwQzLCUmNw8QFBRGLi81/SA8NDVOFhcODzMjIyoZGVc6O0IsKilHHR4UFzYeT3EHBv7gFREQ0goaCtIQERWDEw1gDRODAbsJFxdCKiouNS8uRhQUFxZONTQ8LysrRxobDwQIBEI7OlcZGQwLKh4dJA8RcU8SIxB7JxDSCgrSECfgDRMTDeAAAgAA/8AEAANAAA8ANAAAATIWFREUBiMhIiY1ETQ2MwEnNzY0LwEmIg8BJyYiDwEGFB8BBwYUHwEWMj8BFxYyPwE2NCcDoCg4OCj8wCg4OCgCmYaGBwdRBxUHhYUHFQdRBweGhgcHUQcVB4WFBxUHUQcHA0A4KP1AKDg4KALAKDj9u4WFBxUHUQcHhoYHB1EHFQeFhQcVB1EHB4aGBwdRBxUHAAACABMAAAUAAwAAFAA5AAABMhYVERQGIyEiJicBJjQ3AT4BMyEDJzc2NC8BJiIPAScmIg8BBhQfAQcGFB8BFjI/ARcWMj8BNjQnBIA1S0s1/RsaLxL+0xMTAS0RLxoC5ql8fAkJLgkbCXx8CRsJLgkJfX0JCS4JGwl8fAkbCS4JCQMASzX+ADVLExIBLhI2EgEtEhT+BHx8CRsJLgkJfX0JCS4JGwl8fAkbCS4JCXx8CQkuCRsJAAAAAwAA/4ADAAOAABEAJwAyAAABFBYzIREUBiMhIiY1ETQ2MyETNiYrATU0JisBIgYdASMiBh8BFjI3AR4BHQEhETMyFhcBwBwUARAcFP1gFBwcFAGQmQ8QFoITDUANE4IWEA/BChwKAVoHB/8ADAoRBwJwFBz9cBQcHBQDoBQc/UkPKKANExMNoCgPvwoKAqQHEQoMAQAHBwADAAD/gAR2A4AACgAaADYAAAEVIREzMhYfAR4BARYUDwEGJj0BIzUzNTQ2FwUUFjMhERQGIyEiJjURNDYzIREUFjMhESEiBhUDAP8ADAoRB8QHBwF2Cgq/ECeAgCcQ/ckTDQFgHBT9YBQcHBQBkBwUARD+oA0TAowMAQAHB8QHEf6CChwKwQ8QFoKAghYQD/kNE/7wFBwcFAOgFBz+8BQc/wATDQAAAAADAAD/gAQAA4AACQAUADcAABMzFSMiJj0BNDYBHgEdASERMzIWFwMUFjMhERQGIyEiJjURIRUUFj8BNjQvASYGHQEhETQ2MyERIODgDRMTA98HB/8ADAoRB24cFAEQHBT9YBQcAQAnEL8KCr8PKP8AHBQBkAFAgBMNQA0TAW4HEQoMAQAHB/7+FBz9cBQcHBQBEIIWEA/BChwKwQ8QFoICEBQc/vAAAAADAAD/gAMAA4AAEQAoADMAAAEUFjMhERQGIyEiJjURNDYzIRMyNi8BJiIPAQYWOwEVFBY7ATI2PQEzEx4BHQEhETMyFhcBwBwUARAcFP1gFBwcFAGQghYQD8EKHArBDxAWghMNQA0TgrAHB/8ADAoRBwJwFBz9cBQcHBQDoBQc/UAoD78KCr8PKKANExMNoAHuBxEKDAEABwcAAAACABP/gAQdA4AAIQAoAAABHgEPARMWBiMiJiclBQ4BIyImNxMnJjY3JRM+ATMyFhcTEzclJxEXAwP5Jxkc1DIFKRwHDwf++v76Bw8IHCgFMtQcGScBJYMIIBERIAmCMqX+6Xz5MAIpBksczv7dHywEA4qJBAQsHwEjzhxLBisBCBISEhL++P7foCn8/YWCARQAAAAAAgAAAA4D9wLyABEANQAAATYWFREUBi8BIyImNRE0NjsBBRcWFA8BBiIvAQcGIi8BJjQ/AScmND8BNjIfATc2Mh8BFhQHAa4XOzsXsswUHBwUzAKfXAkJLgoaCltbChoKLgkJXFwJCS4KGgpbWwoaCi4JCQLyFhgg/WAgGBayHBQBIBQcwFsKGgouCQlcXAkJLgoaCltbChoKLgkJXFwJCS4KGgoAAAAABAAJ/4kD9wN3ABYALABCAFgAAAEyFh0BFAYvAQcGIi8BJjQ/AScmNjsBNyImPQE0Nh8BNzYyHwEWFA8BFxYGIwMXFhQPAQYiLwEHBiY9ATQ2OwEyFgcBNhYdARQGKwEiJj8BJyY0PwE2Mh8BAZAUHDsXPscJGwkzCQnHQhcZIODgFBw7Fz7HCRsJMwkJx0IXGSAgxwkJMwkbCcc+FzscFOAgGRf9/Bc7HBTgIBkXQscJCTMJGwnHAUAcFOAgGRdCxwkJMwkbCcc+FzuAHBTgIBkXQscJCTMJGwnHPhc7/vDHCRsJMwkJx0IXGSDgFBw7FwIEFhgg4BQcOxc+xwkaCjMJCccAAAAABAAA/5YD9wOAABUANABAAEwAACUWFA8BBiIvAS4BNycjAzcFFRc2FhcnIgYHJyY2Nz4BFx4BDwEfATc2FhcWBgcOAQcnLgEjBwYWFwcGIicmNDcBAzI2NTQmIyIGFRQWA+oWFmkWPhbqIg4U1XzAgAEA1SpeI2kMGQykASgrOJJHDggKlReHlQobAxImNxQsGCceTSvPCAYM+CVqJiUlATHWFBwcFBQcHGkWPhZpFhbqI14q1QEAgMB81RQOImsDA6Q5bCs3JhIDGwqViBaVCggNR5M4Ex0LJx4gpCBAHfglJSZqJQEx/kUcFBQcHBQUHAAAAAMAAP+AA4ADgAAKACMAQQAAFwMhAw4BIyEiJicTBhY7ARUUFjsBMjY9ATMyNi8BLgEjIgYHATIWHQEUBiMhIiY9ATQ2OwE3PgE7ATgBMTIWHwEzaioDACoDNyb+FCY3A40PEBVzEw1ADRNzFREQsgULBwcLBQG3DRMTDfzADRMTDfATBhYO5Q4XBhPwJgKm/VomNDQmAWAQKuANExMN4CoQvAUFBQUBShMNQA0TEw1ADRMlDA8PDCUAAAAAAwAA/4ADgAOAAAkAIgBAAAAXESERFAYjISImEwYWOwEVFBY7ATI2PQEzMjYvAS4BIyIGBwEyFh0BFAYjISImPQE0NjsBNz4BOwE4ATEyFh8BM0ADADgo/cAoOLcPEBVzEw1ADRNzFREQsgULBwcLBQG3DRMTDfzADRMTDfATBhYO5Q4XBhPwIAKg/WAoODgBghAq4A0TEw3gKhC8BQUFBQFKEw1ADRMTDUANEyUMDw8MJQAAAQAAAAEAAII1aM1fDzz1AAsEAAAAAADcXxJIAAAAANxfEkgAAP+ABQADgAAAAAgAAgAAAAAAAAABAAADgP+AAAAFAAAAAAAFAAABAAAAAAAAAAAAAAAAAAAAfAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAEgSAADwEAAAPAsAAEgQAAAAEAAAABAAAEAQAACYEgAAABAAAAAOAAAACAAAAAwAAAASAAAADAAAAA4AAgAQAAAAEAAAXA4AAAAOAAAADgAAABAAAAAQAAAADgACAA4AAAAKAAEUCgABFBAAAEAQAABAEAAAQBAAAEAQAABAEAAAQBAAAEAOAAA4DgAAAA4AAGQOAABkDgAAAA4AAAAOAAAADgAAABAAAEASAAAAFAAAABIAADQOAABkDgAAZBIAAPAMAAAAEAAAAA4AAAASAAAAEAAAWBQAAAAOAAAADgAAABAAAAAKAACICgAAiAYAAOgGAAAACgAAAAsAAAAOAAAAEAAAABAAAAAQAAAAEAAAOBAAAEAQAABAEAAAQBAAAEAOAAAAEAAAQAYAAMAQAABADgAAAA4AAAAOAAAADgAAAA4AAAAQAABMEAAA2BAAAAAOAAAAFAAAAA4AAQAOAAAADgAAABIAAAASAAAAFAAAABQAAAAUAAAAFAAAABQAAAAQAABAEAAAQBAAAEAOAAAAEAAAQBAAAEAOAAAAEAAAABQAAAAUAAAAEAAAABQAAEwMAAAAEgAAABAAAAAMAAAAEMAATBAAAAAQAAAkEAAAAA4AAAAOAAAAAAAAAAAoAFAAeAIoAygD8ASYBYAH4AnwC8gOEBAIEaASmBMYFCgW+BdQGAAY8BmgGggayBs4G/Ac4B2QHlgfAB+wIRgiKCO4JQAm+CiIKhgq6Cu4LIgtWC8QMMAxkDIAM1g1mDg4OUA58DqYOyA8KD3IPuBAOEMwRIBFuEbQSDhIqEkYSYhJ+EqwTGBNgE7oUFBSMFRwVbhXAFhIWZBa8FvIXKBdqF5wX2hgKGDoYahjmGS4ZsBngGpwa2hsmG2Qb4Bw6HHQcrhzoHSIdVh2uHfQeXh7QH1QfviAcIHQg5iFYIaoiBiJSIqYi+iNII5Ij5iRqJOQlQiWcAAAAAQAAAHwAgwAHAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAwAAAABAAAAAAACAAcAjQABAAAAAAADAAwARQABAAAAAAAEAAwAogABAAAAAAAFAAsAJAABAAAAAAAGAAwAaQABAAAAAAAKABoAxgADAAEECQABABgADAADAAEECQACAA4AlAADAAEECQADABgAUQADAAEECQAEABgArgADAAEECQAFABYALwADAAEECQAGABgAdQADAAEECQAKADQA4HNjLWljb25zLTkwMABzAGMALQBpAGMAbwBuAHMALQA5ADAAMFZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMHNjLWljb25zLTkwMABzAGMALQBpAGMAbwBuAHMALQA5ADAAMHNjLWljb25zLTkwMABzAGMALQBpAGMAbwBuAHMALQA5ADAAMFJlZ3VsYXIAUgBlAGcAdQBsAGEAcnNjLWljb25zLTkwMABzAGMALQBpAGMAbwBuAHMALQA5ADAAMEZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\") format(\"woff\")}</style>\n<style id=\"style-font-emoji\" type=\"text/css\">@font-face{font-family:color-emoji;src:local(\"Twemoji Mozilla\"),local(\"Apple Color Emoji\"),local(\"Segoe UI Emoji\"),local(\"Segoe UI Symbol\"),local(\"Noto Color Emoji\"),local(\"EmojiOne Color\"),local(\"Android Emoji\")}</style>\n<style id=\"style-core\" type=\"text/css\">#store-area,tw-storydata{display:none!important;z-index:0}::-webkit-scrollbar{height:8px;width:8px}::-webkit-scrollbar-corner,::-webkit-scrollbar-track{background-color:#111}::-webkit-scrollbar-thumb{background-color:#333;border:1px solid #111}*{scrollbar-color:#333 #111;scrollbar-width:thin}:-webkit-full-screen{height:100%;width:100%}:-ms-fullscreen{height:100%;width:100%}:fullscreen{height:100%;width:100%}body::-ms-backdrop{background:0 0}:focus{outline:thin dotted}:disabled{cursor:not-allowed!important}html{font-family:-apple-system,system-ui,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen-Sans,Cantarell,Ubuntu,\"Helvetica Neue\",Helvetica,Arial,sans-serif,color-emoji;font-size:16px;line-height:1}body{color:#eee;background-color:#111;overflow:auto}a{cursor:pointer;color:#68d;text-decoration:none;-webkit-transition-duration:.2s;-o-transition-duration:.2s;transition-duration:.2s}a:hover,html[data-outlines] a:focus{color:#8af;text-decoration:underline}a.link-broken{color:#c22}a.link-broken:hover,html[data-outlines] a.link-broken:focus{color:#e44}a[disabled],span.link-disabled{color:#aaa;cursor:not-allowed!important;text-decoration:none}a.link-internal{-webkit-touch-callout:none}area{cursor:pointer}button{cursor:pointer;color:#eee;background-color:#35a;border:1px solid #57c;line-height:normal;padding:.4em;-webkit-transition-duration:.2s;-o-transition-duration:.2s;transition-duration:.2s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}button:hover,html[data-outlines] button:focus{background-color:#57c;border-color:#79e}button:disabled{background-color:#444;border:1px solid #666}code,kbd,pre,samp,var{font-family:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Lucida Console\",\"Courier New\",Courier,monospace,monospace}pre{overflow:auto}input,select,textarea{color:#eee;background-color:transparent;border:1px solid #444;padding:.4em}select{padding:.34em .4em}input[type=text]{min-width:18em}textarea{min-width:30em;resize:vertical}input[type=checkbox],input[type=file],input[type=radio],select{cursor:pointer}input[type=range]{-webkit-appearance:none;min-height:1.2em}input[type=range]:focus{outline:0}input[type=range]::-webkit-slider-runnable-track{background:#222;border:1px solid #444;border-radius:0;cursor:pointer;height:10px;width:100%}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:#35a;border:1px solid #57c;border-radius:0;cursor:pointer;height:18px;margin-top:-5px;width:33px}input[type=range]:focus::-webkit-slider-runnable-track{background:#222}input[type=range]::-moz-range-track{background:#222;border:1px solid #444;border-radius:0;cursor:pointer;height:10px;width:100%}input[type=range]::-moz-range-thumb{background:#35a;border:1px solid #57c;border-radius:0;cursor:pointer;height:18px;width:33px}input[type=range]::-ms-track{background:0 0;border-color:transparent;color:transparent;cursor:pointer;height:10px;width:calc(100% - 1px)}input[type=range]::-ms-fill-lower{background:#222;border:1px solid #444;border-radius:0}input[type=range]::-ms-fill-upper{background:#222;border:1px solid #444;border-radius:0}input[type=range]::-ms-thumb{background:#35a;border:1px solid #57c;border-radius:0;cursor:pointer;height:16px;width:33px}html[data-outlines] input:focus,html[data-outlines] select:focus,html[data-outlines] textarea:focus,input:hover,select:hover,textarea:hover{background-color:#333;border-color:#eee}input:disabled,select:disabled,textarea:disabled{color:#333;background-color:transparent;border-color:#111}hr{display:block;height:1px;border:none;border-top:1px solid #eee;margin:1em 0;padding:0}audio,canvas,progress,video{max-width:100%;vertical-align:middle}.no-transition{-webkit-transition:none!important;-o-transition:none!important;transition:none!important}.error-view{background-color:#511;border-left:.5em solid #c22;display:inline-block;margin:.1em;max-width:100%;padding:0 .25em;position:relative}.error-view>.error-toggle{background-color:transparent;border:none;line-height:inherit;left:0;padding:0;position:absolute;top:0;width:1.75em}.error-view>.error-toggle:hover,html[data-outlines] .error-view>.error-toggle:focus{background-color:transparent}.error-view>.error{display:inline-block;margin-left:.25em}.error-view>.error-toggle+.error{margin-left:1.5em}.error-view>.error-source[hidden]{display:none}.error-view>.error-source:not([hidden]){background-color:rgba(0,0,0,.2);display:block;margin:0 0 .25em;overflow-x:auto;padding:.25em}.highlight,.marked{color:#ff0;font-weight:700;font-style:italic}.nobr{white-space:nowrap}.error-view>.error-toggle::before,.error-view>.error::before,[data-icon-after]::after,[data-icon-before]::before,[data-icon]::before,a.link-external::after{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}[data-icon]::before{content:attr(data-icon)}[data-icon-before]::before{content:attr(data-icon-before);margin-right:.35em}[data-icon-after]::after{content:attr(data-icon-after);margin-left:.35em}.error-view>.error-toggle::before{content:\"\\f0da\"}.error-view>.error-toggle.enabled::before{content:\"\\f0d7\"}.error-view>.error::before{content:\"\\f071\";margin-right:.35em}a.link-external::after{content:\"\\f35d\";margin-left:.25em}</style>\n<style id=\"style-core-display\" type=\"text/css\">#story{z-index:10;margin:2.5em}@media screen and (max-width:1136px){#story{margin-right:1.5em}}#passages{max-width:54em;margin:0 auto}</style>\n<style id=\"style-core-passage\" type=\"text/css\">.passage{line-height:1.75;text-align:left;-webkit-transition:opacity .4s ease-in;-o-transition:opacity .4s ease-in;transition:opacity .4s ease-in}.passage-in{opacity:0}.passage ol,.passage ul{margin-left:.5em;padding-left:1.5em}.passage table{margin:1em 0;border-collapse:collapse;font-size:100%}.passage caption,.passage td,.passage th,.passage tr{padding:3px}@media (prefers-reduced-motion:reduce){.passage{-webkit-transition:opacity 0s;-o-transition:opacity 0s;transition:opacity 0s}}</style>\n<style id=\"style-core-macro\" type=\"text/css\">@-webkit-keyframes cursor-blink{0%{opacity:1}50%{opacity:0}100%{opacity:1}}@-o-keyframes cursor-blink{0%{opacity:1}50%{opacity:0}100%{opacity:1}}@keyframes cursor-blink{0%{opacity:1}50%{opacity:0}100%{opacity:1}}.macro-append-insert,.macro-linkappend-insert,.macro-linkprepend-insert,.macro-linkreplace-insert,.macro-prepend-insert,.macro-repeat-insert,.macro-replace-insert,.macro-timed-insert{-webkit-transition:opacity .4s ease-in;-o-transition:opacity .4s ease-in;transition:opacity .4s ease-in}.macro-append-in,.macro-linkappend-in,.macro-linkprepend-in,.macro-linkreplace-in,.macro-prepend-in,.macro-repeat-in,.macro-replace-in,.macro-timed-in{opacity:0}.macro-type-cursor::after{-webkit-animation:cursor-blink 1s infinite;-o-animation:cursor-blink 1s infinite;animation:cursor-blink 1s infinite;content:\"\\2590\";opacity:1}</style>\n<style id=\"style-ui-dialog\" type=\"text/css\">html[data-dialog] body{overflow:hidden}#ui-overlay{background-color:#000;height:200%;left:-50%;opacity:0;position:fixed;top:-50%;-webkit-transition:visibility .2s step-end,opacity .2s ease-in;-o-transition:visibility .2s step-end,opacity .2s ease-in;transition:visibility .2s step-end,opacity .2s ease-in;visibility:hidden;width:200%;z-index:100000}#ui-overlay.open{opacity:.8;-webkit-transition:visibility 0s;-o-transition:visibility 0s;transition:visibility 0s;visibility:visible}#ui-dialog{display:none;margin:0;max-width:66em;opacity:0;padding:0;position:fixed;top:50px;z-index:100100}#ui-dialog.open{display:block;opacity:1;-webkit-transition:opacity .2s ease-in;-o-transition:opacity .2s ease-in;transition:opacity .2s ease-in}#ui-dialog>*{-webkit-box-sizing:border-box;box-sizing:border-box}#ui-dialog-titlebar{background-color:#444;min-height:24px;position:relative}#ui-dialog-title{font-size:1.5em;margin:0;padding:.2em 3.5em .2em .5em;text-align:center;text-transform:uppercase}#ui-dialog-close{background-color:transparent;border:1px solid transparent;cursor:pointer;display:block;font-size:120%;height:92%;margin:0;padding:0;position:absolute;right:0;top:0;-webkit-transition-duration:.2s;-o-transition-duration:.2s;transition-duration:.2s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;width:3.6em;font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#ui-dialog-close:hover{background-color:#b44;border-color:#d66}#ui-dialog-body{background-color:#111;border:1px solid #444;height:calc(100% - 2.1em);line-height:1.5;min-width:300px;overflow:auto;padding:1em;text-align:left}#ui-dialog-body>:first-child{margin-top:0}#ui-dialog-body hr{background-color:#444}#ui-dialog-body ul.buttons{margin:0;padding:0;list-style:none}#ui-dialog-body ul.buttons li{display:inline-block;margin:0;padding:.4em .4em 0 0}#ui-dialog-body ul.buttons>li+li>button{margin-left:1em}@media (prefers-reduced-motion:reduce){#ui-overlay{-webkit-transition:opacity 0s;-o-transition:opacity 0s;transition:opacity 0s}#ui-overlay.open{-webkit-transition:opacity 0s;-o-transition:opacity 0s;transition:opacity 0s}#ui-dialog.open{-webkit-transition:opacity 0s;-o-transition:opacity 0s;transition:opacity 0s}}</style>\n<style id=\"style-ui-dialog-saves\" type=\"text/css\">#ui-dialog-body.saves{padding:0 0 1px}#ui-dialog-body.saves>:not(:first-child){border-top:1px solid #444}#ui-dialog-body.saves>h2{background-color:#222;font-size:inherit;margin:0;padding:.1em 0 .1em .4em}#ui-dialog-body.saves table{border-spacing:0;width:100%}#ui-dialog-body.saves tr:not(:first-child){border-top:1px solid #444}#ui-dialog-body.saves td{padding:.33em}#ui-dialog-body.saves td:first-child{display:none!important}#ui-dialog-body.saves td:nth-child(2){min-width:calc(2.237em * 2 + 1px)}#ui-dialog-body.saves td:nth-child(3){line-height:1.2;width:100%}#ui-dialog-body.saves td:last-child{text-align:right}#ui-dialog-body.saves .empty{color:#999;speak:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#ui-dialog-body.saves .details{font-size:75%;margin-left:.25em}#ui-dialog-body.saves #saves-list button{color:#eee;background-color:transparent;border:1px solid #444;height:2.237em;width:2.237em}#ui-dialog-body.saves #saves-list button:disabled{color:#444;border-color:#444}#ui-dialog-body.saves #saves-list button:not(:disabled):hover{background-color:#222;border-color:#ddd}#ui-dialog-body.saves #saves-list button.delete:not(:disabled),#ui-dialog-body.saves button[id=saves-clear]:not(:disabled){background-color:#911;border-color:#b33}#ui-dialog-body.saves #saves-list button.delete:not(:disabled):hover,#ui-dialog-body.saves button[id=saves-clear]:not(:disabled):hover{background-color:#b33;border-color:#d55}#ui-dialog-body.saves #saves-list button.load:not(:disabled){background-color:#161;border-color:#383}#ui-dialog-body.saves #saves-list button.load:not(:disabled):hover{background-color:#383;border-color:#5a5}#ui-dialog-body.saves .buttons li{padding:.4em}#ui-dialog-body.saves .buttons>li+li>button{margin-left:.2em}#ui-dialog-body.saves .buttons.slots>li:last-child{float:right}#ui-dialog-body.saves #saves-list button::before,#ui-dialog-body.saves .buttons button::before{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#ui-dialog-body.saves .buttons button::before{margin-right:.35em}#ui-dialog-body.saves button.delete::before{content:\"\\f2ed\"}#ui-dialog-body.saves button.delete:disabled::before{content:\"\\f1f8\"}#ui-dialog-body.saves button.load::before{content:\"\\f04b\"}#ui-dialog-body.saves button.save::before{content:\"\\f0c7\"}#ui-dialog-body.saves button[id=saves-export]::before{content:\"\\f56e\"}#ui-dialog-body.saves button[id=saves-import]::before{content:\"\\f56f\"}#ui-dialog-body.saves button[id=saves-clear]::before{content:\"\\f2ed\"}#ui-dialog-body.saves button[id=saves-clear]:disabled::before{content:\"\\f1f8\"}#ui-dialog-body.saves button[id=saves-disk-save]::before{content:\"\\f56d\"}#ui-dialog-body.saves button[id=saves-disk-load]::before{content:\"\\f574\"}#ui-dialog-body.saves button[id=saves-clipboard-save]::before{content:\"\\f019\"}</style>\n<style id=\"style-ui-dialog-settings\" type=\"text/css\">#ui-dialog-body.settings [id|=setting-body]>div:first-child{display:table;width:100%}#ui-dialog-body.settings [id|=setting-label]{display:table-cell;padding:.4em 2em .4em 0}#ui-dialog-body.settings [id|=setting-label]+div{display:table-cell;min-width:8em;text-align:right;vertical-align:middle;white-space:nowrap}#ui-dialog-body.settings div[id|=header-body]{margin:1em 0}#ui-dialog-body.settings div[id|=header-body]:first-child{margin-top:0}#ui-dialog-body.settings div[id|=header-body]:not(:first-child){border-top:1px solid #444;padding-top:1em}#ui-dialog-body.settings div[id|=header-body]>*{margin:0}#ui-dialog-body.settings h2[id|=header-heading]{font-size:1.375em}#ui-dialog-body.settings p[id|=header-desc],#ui-dialog-body.settings p[id|=setting-desc]{font-size:87.5%;margin:0 0 0 .5em}#ui-dialog-body.settings div[id|=setting-body]+div[id|=setting-body]{margin:1em 0}#ui-dialog-body.settings [id|=setting-control]{white-space:nowrap}#ui-dialog-body.settings button[id|=setting-control]{color:#eee;background-color:transparent;border:1px solid #444;padding:.4em}#ui-dialog-body.settings button[id|=setting-control]:hover{background-color:#333;border-color:#eee}#ui-dialog-body.settings button[id|=setting-control].enabled{background-color:#282;border-color:#4a4}#ui-dialog-body.settings button[id|=setting-control].enabled:hover{background-color:#4a4;border-color:#6c6}#ui-dialog-body.settings input[type=range][id|=setting-control]{max-width:35vw}#ui-dialog-body.settings span[id|=setting-input]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#ui-dialog-body.settings button[id|=setting-control].enabled::after,#ui-dialog-body.settings button[id|=setting-control]::after{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin-left:.35em}#ui-dialog-body.settings button[id|=setting-control]::after{content:\"\\f204\"}#ui-dialog-body.settings button[id|=setting-control].enabled::after{content:\"\\f205\"}</style>\n<style id=\"style-ui-dialog-legacy\" type=\"text/css\">#ui-dialog-body.list{padding:0}#ui-dialog-body.list ul{margin:0;padding:0;list-style:none;border:1px solid transparent}#ui-dialog-body.list li{margin:0}#ui-dialog-body.list li:not(:first-child){border-top:1px solid #444}#ui-dialog-body.list li a{display:block;padding:.25em .75em;border:1px solid transparent;color:#eee;text-decoration:none}#ui-dialog-body.list li a:hover{background-color:#333;border-color:#eee}#ui-dialog-body.list a{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}</style>\n<style id=\"style-ui-bar\" type=\"text/css\">#story{margin-left:20em;-webkit-transition:margin-left .2s ease-in;-o-transition:margin-left .2s ease-in;transition:margin-left .2s ease-in}#ui-bar.stowed~#story{margin-left:4.5em}@media screen and (max-width:1136px){#story{margin-left:19em}#ui-bar.stowed~#story{margin-left:3.5em}}@media screen and (max-width:768px){#story{margin-left:3.5em}}#ui-bar{background-color:#222;border-right:1px solid #444;height:100%;left:0;margin:0;padding:0;position:fixed;text-align:center;top:0;-webkit-transition:left .2s ease-in;-o-transition:left .2s ease-in;transition:left .2s ease-in;width:17.5em;z-index:50}#ui-bar.stowed{left:-15.5em}#ui-bar-tray{position:absolute;top:.2em;left:0;right:0}#ui-bar-body{height:calc(100% - 2.5em);line-height:1.5;margin:2.5em 0;overflow:auto;padding:0 1.5em}#ui-bar.stowed #ui-bar-body,#ui-bar.stowed #ui-bar-history{visibility:hidden;-webkit-transition:visibility .2s step-end;-o-transition:visibility .2s step-end;transition:visibility .2s step-end}#ui-bar a{text-decoration:none}#ui-bar hr{border-color:#444}#ui-bar-tray button{color:#eee;background-color:transparent;border:1px solid #444}#ui-bar-tray button:hover{background-color:#444;border-color:#eee}#ui-bar-tray button:disabled{color:#444;background-color:transparent;border-color:#444}button#ui-bar-toggle{border-right:none;position:absolute;right:0;top:0}#ui-bar-history{margin:0 auto}#ui-bar-history button:not(:first-child){margin-left:1.2em}#ui-bar-body>:not(:first-child){margin-top:2em}#story-title{margin:0;font-size:162.5%}#story-author{margin-top:2em;font-weight:700}#menu ul{margin:1em 0 0;padding:0;list-style:none;border:1px solid #444}#menu ul:empty{display:none}#menu li{margin:0}#menu li:not(:first-child){border-top:1px solid #444}#menu li a{display:block;padding:.25em .75em;border:1px solid transparent;color:#eee;text-transform:uppercase}#menu li a:hover{background-color:#444;border-color:#eee}#menu a,#ui-bar-tray button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#menu-core li[id|=menu-item] a::before,#ui-bar-tray button::before{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#ui-bar-tray button::before{display:block;font-size:1.1em;width:1em}#ui-bar-toggle::before{content:\"\\f053\"}#ui-bar.stowed #ui-bar-toggle::before{content:\"\\f054\"}#ui-bar-tray #history-backward::before{content:\"\\f060\"}#ui-bar-tray #history-jumpto::before{content:\"\\f0e7\"}#ui-bar-tray #history-forward::before{content:\"\\f061\"}#menu-item-continue a::before,#menu-item-restart a::before,#menu-item-saves a::before,#menu-item-settings a::before,#menu-item-share a::before{margin-right:.35em}#menu-item-continue a::before{content:\"\\f04b\"}#menu-item-saves a::before{content:\"\\f0c7\"}#menu-item-settings a::before{content:\"\\f013\"}#menu-item-restart a::before{content:\"\\f011\"}#menu-item-share a::before{content:\"\\f1e0\"}@media (prefers-reduced-motion:reduce){#story{-webkit-transition:margin-left 0s;-o-transition:margin-left 0s;transition:margin-left 0s}#ui-bar{-webkit-transition:left 0s;-o-transition:left 0s;transition:left 0s}}</style>\n<style id=\"style-idb-backend\" type=\"text/css\">#saves-export-reminder{padding:.5em 1em 0}.idb-saves-list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.idb-saves-list .savesListRow{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;border-top:1px solid #444;padding:4px}@media (min-width:40rem){.idb-saves-list .savesListRow{max-height:2.4em}}.idb-saves-list .savesListRow .saveGroup{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;min-width:0}.idb-saves-list .savesListRow .saveGroup>div{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;margin:0 10px;-webkit-box-flex:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.idb-saves-list .savesListRow .saveGroup .saveId{min-width:2em;margin-left:4px;margin-right:-6px}.idb-saves-list .savesListRow .saveGroup .saveButton{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;min-width:110px;margin:0 10px}.idb-saves-list .savesListRow .saveGroup .saveName{width:5em}.idb-saves-list .savesListRow .saveGroup .saveButton input{margin:3px 0}.idb-saves-list .savesListRow .saveGroup>.saveDetails{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-pack:stretch;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch;min-width:100px}.idb-saves-list .savesListRow .saveGroup>.saveDetails span{max-height:80px;white-space:nowrap;overflow-x:clip}.jumpToSaveTransition{background-color:#444;-webkit-transition-duration:1s;-o-transition-duration:1s;transition-duration:1s}#savesListFooter{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:0!important;line-height:normal}#savesListFooter div{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:stretch;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch}.datestamp{font-size:.8em}.listMargin{display:inline-block;margin:1px 0}.right{float:right}.saveMenuButton{background-color:#35a!important}.saveMenuButton:hover{background-color:#35a!important}.saveMenuConfirm{margin-top:20px;margin-left:150px}.green{color:#38b20a}.gold{color:gold}.red{color:#ec3535}.saveBorder{max-width:700px;margin:10px 2px;padding:5px 2px 30px;border:1px solid var(--200)}#saveList ul.buttons{margin:0;padding:0;list-style:none;border-top:1px solid var(--750)}#saveList ul.buttons li{padding:.4em;display:inline-block;margin:0}#saveList ul.buttons li:last-child{float:right}#saveList button[id=saves-export]:before{content:\"\\e829\\00a0\"}#saveList button[id=saves-toClipboard]:before{content:\"\\e82b\\00a0\"}#saveList button[id=saves-import]:before{content:\"\\e82a\\00a0\"}#saveList button[id=saves-clear]:before{content:\"\\e827\\00a0\"}.saves-loading .saves{text-align:center;margin-top:1em}</style>\n<style id=\"style-ui-debug-bar\" type=\"text/css\">#debug-bar{background-color:#222;border-left:1px solid #444;border-top:1px solid #444;bottom:0;margin:0;max-height:95%;max-width:66em;min-width:300px;padding:.5em;position:fixed;right:0;z-index:99900}#debug-bar>div:not([id])+div{margin-top:.5em}#debug-bar>div>label{margin-right:.5em}#debug-bar>div>input[type=text]{min-width:8em;width:14em}#debug-bar>div>select{width:22em}#debug-bar-toggle{color:#eee;background-color:#222;border:1px solid #444;height:calc(100% + 1px);left:calc(-2em - 1px);position:absolute;top:-1px;width:2em}#debug-bar-toggle:hover{background-color:#333;border-color:#eee}#debug-bar-hint{bottom:.75em;font-size:4.5em;opacity:.33;pointer-events:none;position:fixed;right:.6em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap}#debug-bar-watch{background-color:#222;border-left:1px solid #444;border-top:1px solid #444;bottom:calc(100% + 1px);font-size:.9em;left:-1px;max-height:280%;max-height:calc(95vh - 100%);position:absolute;overflow-x:hidden;overflow-y:scroll;right:0;z-index:99800}#debug-bar-watch[hidden]{display:none}#debug-bar-watch div{color:#999;font-style:italic;margin:1em auto;text-align:center}#debug-bar-watch table{width:100%}#debug-bar-watch tr:nth-child(2n){background-color:rgba(127,127,127,.15)}#debug-bar-watch td{padding:.2em 0}#debug-bar-watch td:first-child+td{padding:.2em .3em .2em .1em}#debug-bar-watch .watch-delete{background-color:transparent;border:none;color:#c00}#debug-bar-watch-all,#debug-bar-watch-clear{margin-left:.5em}#debug-bar-views-toggle,#debug-bar-watch-toggle{color:#eee;background-color:transparent;border:1px solid #444;margin-right:1em;padding:.4em}#debug-bar-views-toggle:hover,#debug-bar-watch-toggle:hover{background-color:#333;border-color:#eee}#debug-bar-watch:not([hidden])~div #debug-bar-watch-toggle,html[data-debug-view] #debug-bar-views-toggle{background-color:#282;border-color:#4a4}#debug-bar-watch:not([hidden])~div #debug-bar-watch-toggle:hover,html[data-debug-view] #debug-bar-views-toggle:hover{background-color:#4a4;border-color:#6c6}#debug-bar-hint::after,#debug-bar-passage-play::before,#debug-bar-toggle::before,#debug-bar-views-toggle::after,#debug-bar-watch .watch-delete::before,#debug-bar-watch-add::before,#debug-bar-watch-all::before,#debug-bar-watch-clear::before,#debug-bar-watch-toggle::after{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#debug-bar-toggle::before{content:\"\\f188\"}#debug-bar-hint::after{content:\"\\f188\\202f\\f061\"}#debug-bar-watch .watch-delete::before{content:\"\\f00d\"}#debug-bar-watch-add::before{content:\"\\f067\"}#debug-bar-watch-all::before{content:\"\\f0d0\"}#debug-bar-watch-clear::before{content:\"\\f2ed\"}#debug-bar-views-toggle::after,#debug-bar-watch-toggle::after{content:\"\\f204\";margin-left:.35em}#debug-bar-watch:not([hidden])~div #debug-bar-watch-toggle::after,html[data-debug-view] #debug-bar-views-toggle::after{content:\"\\f205\"}#debug-bar-passage-play::before{content:\"\\f04b\"}</style>\n<style id=\"style-ui-debug-views\" type=\"text/css\">html[data-debug-view] .debug{padding:.25em;background-color:#234}html[data-debug-view] .debug[title]{cursor:help}html[data-debug-view] .debug.block{display:inline-block;vertical-align:middle}html[data-debug-view] .debug.invalid{text-decoration:line-through}html[data-debug-view] .debug.hidden,html[data-debug-view] .debug.hidden .debug{background-color:#555}html:not([data-debug-view]) .debug.hidden{display:none}html[data-debug-view] .debug[data-name][data-type].nonvoid::after,html[data-debug-view] .debug[data-name][data-type]::before{background-color:rgba(0,0,0,.25);font-family:monospace,monospace;white-space:pre}html[data-debug-view] .debug[data-name][data-type]::before{content:attr(data-name)}html[data-debug-view] .debug[data-name][data-type|=macro]::before{content:\"<<\" attr(data-name) \">>\"}html[data-debug-view] .debug[data-name][data-type|=macro].nonvoid::after{content:\"<</\" attr(data-name) \">>\"}html[data-debug-view] .debug[data-name][data-type|=html]::before{content:\"<\" attr(data-name) \">\"}html[data-debug-view] .debug[data-name][data-type|=html].nonvoid::after{content:\"</\" attr(data-name) \">\"}html[data-debug-view] .debug[data-name][data-type]:not(:empty)::before{margin-right:.25em}html[data-debug-view] .debug[data-name][data-type].nonvoid:not(:empty)::after{margin-left:.25em}html[data-debug-view] .debug[data-name][data-type|=special],html[data-debug-view] .debug[data-name][data-type|=special]::before{display:block}</style>\n</head>\n<body>\n\t<div id=\"init-screen\">\n\t\t<div id=\"init-no-js\"><noscript>JavaScript must be enabled to play.</noscript></div>\n\t\t<div id=\"init-lacking\"><p>Browser lacks capabilities required to play.</p><p>Upgrade or switch to another browser.</p></div>\n\t\t<div id=\"init-loading\"><div>Loading…</div></div>\n\t</div>\n\t{{STORY_DATA}}\n\t<script id=\"script-sugarcube\" type=\"text/javascript\">\n\t/*! SugarCube JS */\n\tif(document.documentElement.getAttribute(\"data-init\")===\"loading\"){(function(window,document,jQuery,undefined){\"use strict\";var errorPrologRegExp=/^(?:(?:uncaught\\s+(?:exception:\\s+)?)?\\w*(?:error|exception|_err):\\s+)+/i,Alert=(()=>{function mesg(where,error,isFatal,isUncaught){let mesg=\"Error\",nice=`A${isFatal?\" fatal\":\"n\"} error has occurred.`;nice+=isFatal?\" Aborting.\":\" You may be able to continue, but some parts may not work properly.\";const isObject=null!==error&&\"object\"==typeof error;null!=where&&(mesg+=` [${where}]`),mesg+=`: ${(isObject&&\"message\"in error?String(error.message).replace(errorPrologRegExp,\"\"):String(error)).trim()||\"unknown error\"}.`,isObject&&\"stack\"in error&&(mesg+=`\\n\\nStack Trace:\\n${error.stack}`),mesg&&(nice+=`\\n\\n${mesg}`),isUncaught||console[isFatal?\"error\":\"warn\"](mesg),window.alert(nice)}var origOnError;return origOnError=window.onerror,window.onerror=function(what,source,lineNum,colNum,error){\"complete\"===document.readyState?mesg(null,null!=error?error:what,!1,!0):(mesg(null,null!=error?error:what,!0,!0),window.onerror=origOnError,\"function\"==typeof window.onerror&&window.onerror.apply(this,arguments))},Object.preventExtensions(Object.create(null,{error:{value:function(where,error){mesg(where,error)}},fatal:{value:function(where,error){mesg(where,error,!0)}}}))})(),Patterns=(()=>{const space=(()=>{const wsMap=new Map([[\" \",\"\\\\u0020\"],[\"\\f\",\"\\\\f\"],[\"\\n\",\"\\\\n\"],[\"\\r\",\"\\\\r\"],[\"\\t\",\"\\\\t\"],[\"\\v\",\"\\\\v\"],[\" \",\"\\\\u00a0\"],[\" \",\"\\\\u1680\"],[\"á Ž\",\"\\\\u180e\"],[\" \",\"\\\\u2000\"],[\"â€\",\"\\\\u2001\"],[\" \",\"\\\\u2002\"],[\" \",\"\\\\u2003\"],[\" \",\"\\\\u2004\"],[\" \",\"\\\\u2005\"],[\" \",\"\\\\u2006\"],[\" \",\"\\\\u2007\"],[\" \",\"\\\\u2008\"],[\" \",\"\\\\u2009\"],[\" \",\"\\\\u200a\"],[\"\\u2028\",\"\\\\u2028\"],[\"\\u2029\",\"\\\\u2029\"],[\" \",\"\\\\u202f\"],[\"âŸ\",\"\\\\u205f\"],[\" \",\"\\\\u3000\"],[\"\\ufeff\",\"\\\\ufeff\"]]),wsRe=/^\\s$/;let missing=\"\";return wsMap.forEach(((pat,char)=>{wsRe.test(char)||(missing+=pat)})),missing?`[\\\\s${missing}]`:\"\\\\s\"})(),spaceNoTerminator=\"[\\\\u0020\\\\f\\\\t\\\\v\\\\u00a0\\\\u1680\\\\u180e\\\\u2000-\\\\u200a\\\\u202f\\\\u205f\\\\u3000\\\\ufeff]\",notSpace=\"\\\\s\"===space?\"\\\\S\":space.replace(/^\\[/,\"[^\"),anyLetter=\"[0-9A-Z_a-z\\\\-\\\\u00c0-\\\\u00d6\\\\u00d8-\\\\u00f6\\\\u00f8-\\\\u00ff\\\\u0150\\\\u0170\\\\u0151\\\\u0171]\",anyLetterStrict=anyLetter.replace(\"\\\\-\",\"\"),htmlTagName=(()=>{const cENChar=\"(?:[\\\\x2D.0-9A-Z_a-z\\\\xB7\\\\xC0-\\\\xD6\\\\xD8-\\\\xF6\\\\xF8-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C\\\\u200D\\\\u203F\\\\u2040\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD]|[\\\\uD800-\\\\uDB7F][\\\\uDC00-\\\\uDFFF])\";return`[A-Za-z](?:${cENChar}*-${cENChar}*|[0-9A-Za-z]*)`})(),inlineCss=`(${anyLetter}+)\\\\(([^\\\\)\\\\|\\\\n]+)\\\\):|${spaceNoTerminator}*(${anyLetter}+)${spaceNoTerminator}*:([^;\\\\|\\\\n]+);|${spaceNoTerminator}*((?:[#.]${anyLetter}+${spaceNoTerminator}*)+);`,url=\"(?:file|https?|mailto|ftp|javascript|irc|news|data):[^\\\\s'\\\"]+\",externalUrl=url.replace(/\\|javascript|\\|data/g,\"\");return Object.freeze(Object.assign(Object.create(null),{space:space,spaceNoTerminator:spaceNoTerminator,lineTerminator:\"[\\\\n\\\\r\\\\u2028\\\\u2029]\",notSpace:notSpace,anyChar:\"(?:.|[\\\\n\\\\r\\\\u2028\\\\u2029])\",anyLetter:anyLetter,anyLetterStrict:anyLetterStrict,identifierFirstChar:\"[$A-Z_a-z]\",identifierNextChar:\"[$0-9A-Z_a-z]\",identifier:\"[$A-Z_a-z][$0-9A-Z_a-z]*\",variableSigil:\"[$_]\",variable:\"[$_][$A-Z_a-z][$0-9A-Z_a-z]*\",macroName:\"[A-Za-z][\\\\w-]*|[=-]\",templateName:\"[A-Za-z][\\\\w-]*\",htmlTagName:htmlTagName,cssIdOrClassSigil:\"[#.]\",cssImage:\"\\\\[[<>]?[Ii][Mm][Gg]\\\\[(?:\\\\s|\\\\S)*?\\\\]\\\\]+\",inlineCss:inlineCss,url:url,externalUrl:externalUrl}))})();(()=>{const _trimString=(()=>{const startWSRe=new RegExp(`^${Patterns.space}${Patterns.space}*`),endWSRe=new RegExp(`${Patterns.space}${Patterns.space}*$`);return function(str,where){const val=String(str);if(!val)return val;switch(where){case\"start\":return startWSRe.test(val)?val.replace(startWSRe,\"\"):val;case\"end\":return endWSRe.test(val)?val.replace(endWSRe,\"\"):val;default:throw new Error(`_trimString called with incorrect where parameter value: \"${where}\"`)}}})();function _createPadString(length,padding){const targetLength=Number.parseInt(length,10)||0;if(targetLength<1)return\"\";let padString=void 0===padding?\"\":String(padding);for(\"\"===padString&&(padString=\" \");padString.length<targetLength;){const curPadLength=padString.length,remainingLength=targetLength-curPadLength;padString+=curPadLength>remainingLength?padString.slice(0,remainingLength):padString}return padString.length>targetLength&&(padString=padString.slice(0,targetLength)),padString}if(Array.prototype.flat||Object.defineProperty(Array.prototype,\"flat\",{configurable:!0,writable:!0,value:function flat(){if(null==this)throw new TypeError(\"Array.prototype.flat called on null or undefined\");const depth=0===arguments.length?1:Number(arguments[0])||0;if(depth<1)return Array.prototype.slice.call(this);const push=Array.prototype.push;return Array.prototype.reduce.call(this,((acc,cur)=>(cur instanceof Array?push.apply(acc,flat.call(cur,depth-1)):acc.push(cur),acc)),[])}}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,\"flatMap\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.flatMap called on null or undefined\");return Array.prototype.map.apply(this,arguments).flat()}}),Array.prototype.includes||Object.defineProperty(Array.prototype,\"includes\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.includes called on null or undefined\");if(0===arguments.length)return!1;const length=this.length>>>0;if(0===length)return!1;const needle=arguments[0];let i=Number(arguments[1])||0;for(i<0&&(i=Math.max(0,length+i));i<length;++i){const value=this[i];if(value===needle||value!=value&&needle!=needle)return!0}return!1}}),Object.entries||Object.defineProperty(Object,\"entries\",{configurable:!0,writable:!0,value(obj){if(\"object\"!=typeof obj||null===obj)throw new TypeError(\"Object.entries object parameter must be an object\");return Object.keys(obj).map((key=>[key,obj[key]]))}}),Object.fromEntries||Object.defineProperty(Object,\"fromEntries\",{configurable:!0,writable:!0,value:iter=>Array.from(iter).reduce(((acc,pair)=>{if(Object(pair)!==pair)throw new TypeError(\"Object.fromEntries iterable parameter must yield objects\");return pair[0]in acc?Object.defineProperty(acc,pair[0],{configurable:!0,enumerable:!0,writable:!0,value:pair[1]}):acc[pair[0]]=pair[1],acc}),{})}),Object.getOwnPropertyDescriptors||Object.defineProperty(Object,\"getOwnPropertyDescriptors\",{configurable:!0,writable:!0,value(obj){if(null==obj)throw new TypeError(\"Object.getOwnPropertyDescriptors object parameter is null or undefined\");const O=Object(obj);return Reflect.ownKeys(O).reduce(((acc,key)=>{const desc=Object.getOwnPropertyDescriptor(O,key);return void 0!==desc&&(key in acc?Object.defineProperty(acc,key,{configurable:!0,enumerable:!0,writable:!0,value:desc}):acc[key]=desc),acc}),{})}}),!Object.hasOwn){const hasOwnProperty=Object.prototype.hasOwnProperty;Object.defineProperty(Object,\"hasOwn\",{configurable:!0,writable:!0,value:(O,P)=>hasOwnProperty.call(Object(O),P)})}Object.values||Object.defineProperty(Object,\"values\",{configurable:!0,writable:!0,value(obj){if(\"object\"!=typeof obj||null===obj)throw new TypeError(\"Object.values object parameter must be an object\");return Object.keys(obj).map((key=>obj[key]))}}),String.prototype.padStart||Object.defineProperty(String.prototype,\"padStart\",{configurable:!0,writable:!0,value(length,padding){if(null==this)throw new TypeError(\"String.prototype.padStart called on null or undefined\");const baseString=String(this),baseLength=baseString.length,targetLength=Number.parseInt(length,10);return targetLength<=baseLength?baseString:_createPadString(targetLength-baseLength,padding)+baseString}}),String.prototype.padEnd||Object.defineProperty(String.prototype,\"padEnd\",{configurable:!0,writable:!0,value(length,padding){if(null==this)throw new TypeError(\"String.prototype.padEnd called on null or undefined\");const baseString=String(this),baseLength=baseString.length,targetLength=Number.parseInt(length,10);return targetLength<=baseLength?baseString:baseString+_createPadString(targetLength-baseLength,padding)}}),String.prototype.trimStart||Object.defineProperty(String.prototype,\"trimStart\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.trimStart called on null or undefined\");return _trimString(this,\"start\")}}),String.prototype.trimLeft||Object.defineProperty(String.prototype,\"trimLeft\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.trimLeft called on null or undefined\");return _trimString(this,\"start\")}}),String.prototype.trimEnd||Object.defineProperty(String.prototype,\"trimEnd\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.trimEnd called on null or undefined\");return _trimString(this,\"end\")}}),String.prototype.trimRight||Object.defineProperty(String.prototype,\"trimRight\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.trimRight called on null or undefined\");return _trimString(this,\"end\")}})})(),(()=>{const _nativeMathRandom=Math.random;function _random(){let min,max;switch(arguments.length){case 0:throw new Error(\"_random called with insufficient parameters\");case 1:min=0,max=arguments[0];break;default:min=arguments[0],max=arguments[1]}return min>max&&([min,max]=[max,min]),Math.floor(_nativeMathRandom()*(max-min+1))+min}function _randomIndex(length,boundsArgs){let min,max;switch(boundsArgs.length){case 1:min=0,max=length-1;break;case 2:min=0,max=Math.trunc(boundsArgs[1]);break;default:min=Math.trunc(boundsArgs[1]),max=Math.trunc(boundsArgs[2])}return Number.isNaN(min)?min=0:!Number.isFinite(min)||min>=length?min=length-1:min<0&&(min=length+min,min<0&&(min=0)),Number.isNaN(max)?max=0:!Number.isFinite(max)||max>=length?max=length-1:max<0&&(max=length+max,max<0&&(max=length-1)),_random(min,max)}function _getCodePointStartAndEnd(str,pos){const code=str.charCodeAt(pos);if(Number.isNaN(code))return{char:\"\",start:-1,end:-1};if(code<55296||code>57343)return{char:str.charAt(pos),start:pos,end:pos};if(code>=55296&&code<=56319){const nextPos=pos+1;if(nextPos>=str.length)throw new Error(\"high surrogate without trailing low surrogate\");const nextCode=str.charCodeAt(nextPos);if(nextCode<56320||nextCode>57343)throw new Error(\"high surrogate without trailing low surrogate\");return{char:str.charAt(pos)+str.charAt(nextPos),start:pos,end:nextPos}}if(0===pos)throw new Error(\"low surrogate without leading high surrogate\");const prevPos=pos-1,prevCode=str.charCodeAt(prevPos);if(prevCode<55296||prevCode>56319)throw new Error(\"low surrogate without leading high surrogate\");return{char:str.charAt(prevPos)+str.charAt(pos),start:prevPos,end:pos}}Object.defineProperty(Array.prototype,\"concatUnique\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.concatUnique called on null or undefined\");const result=Array.from(this);if(0===arguments.length)return result;const items=Array.prototype.reduce.call(arguments,((prev,cur)=>prev.concat(cur)),[]),addSize=items.length;if(0===addSize)return result;const indexOf=Array.prototype.indexOf,push=Array.prototype.push;for(let i=0;i<addSize;++i){const value=items[i];-1===indexOf.call(result,value)&&push.call(result,value)}return result}}),Object.defineProperty(Array.prototype,\"count\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.count called on null or undefined\");const indexOf=Array.prototype.indexOf,needle=arguments[0];let pos=Number(arguments[1])||0,count=0;for(;-1!==(pos=indexOf.call(this,needle,pos));)++count,++pos;return count}}),Object.defineProperty(Array.prototype,\"countWith\",{configurable:!0,writable:!0,value(predicate,thisArg){if(null==this)throw new TypeError(\"Array.prototype.countWith called on null or undefined\");if(\"function\"!=typeof predicate)throw new Error(\"Array.prototype.countWith predicate parameter must be a function\");const length=this.length>>>0;if(0===length)return 0;let count=0;for(let i=0;i<length;++i)predicate.call(thisArg,this[i],i,this)&&++count;return count}}),Object.defineProperty(Array.prototype,\"deleteAll\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.deleteAll called on null or undefined\");if(0===arguments.length)return[];const length=this.length>>>0;if(0===length)return[];const needles=Array.prototype.concat.apply([],arguments),needlesLength=needles.length,indices=[];for(let i=0;i<length;++i){const value=this[i];for(let j=0;j<needlesLength;++j){const needle=needles[j];if(value===needle||value!=value&&needle!=needle){indices.push(i);break}}}const result=[];for(let i=0,iend=indices.length;i<iend;++i)result[i]=this[indices[i]];const splice=Array.prototype.splice;for(let i=indices.length-1;i>=0;--i)splice.call(this,indices[i],1);return result}}),Object.defineProperty(Array.prototype,\"deleteAt\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.deleteAt called on null or undefined\");if(0===arguments.length)return[];const length=this.length>>>0;if(0===length)return[];const splice=Array.prototype.splice,cpyIndices=Array.from(new Set(Array.from(arguments).map((x=>x<0?Math.max(0,length+x):x))).values()),delIndices=Array.from(cpyIndices).sort(((a,b)=>b-a)),result=[];for(let i=0,iend=cpyIndices.length;i<iend;++i)result[i]=this[cpyIndices[i]];for(let i=0,iend=delIndices.length;i<iend;++i)splice.call(this,delIndices[i],1);return result}}),Object.defineProperty(Array.prototype,\"deleteFirst\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.deleteFirst called on null or undefined\");if(0===arguments.length)return;const length=this.length>>>0;if(0===length)return;const splice=Array.prototype.splice,needles=Array.prototype.concat.apply([],arguments),result=[];for(let i=0;i<length&&needles.length>0;++i){const value=this[i];for(let j=0;j<needles.length;++j){const needle=needles[j];if(value===needle||value!=value&&needle!=needle){result.push(value),splice.call(this,i--,1),needles.splice(j--,1);break}}}return result}}),Object.defineProperty(Array.prototype,\"deleteLast\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.deleteLast called on null or undefined\");if(0===arguments.length)return;const length=this.length>>>0;if(0===length)return;const splice=Array.prototype.splice,needles=Array.prototype.concat.apply([],arguments),result=[];for(let i=length-1;i>=0&&needles.length>0;--i){const value=this[i];for(let j=0;j<needles.length;++j){const needle=needles[j];if(value===needle||value!=value&&needle!=needle){result.push(value),splice.call(this,i++,1),needles.splice(j--,1);break}}}return result}}),Object.defineProperty(Array.prototype,\"deleteWith\",{configurable:!0,writable:!0,value(predicate,thisArg){if(null==this)throw new TypeError(\"Array.prototype.deleteWith called on null or undefined\");if(\"function\"!=typeof predicate)throw new Error(\"Array.prototype.deleteWith predicate parameter must be a function\");const length=this.length>>>0;if(0===length)return[];const splice=Array.prototype.splice,indices=[],result=[];for(let i=0;i<length;++i)predicate.call(thisArg,this[i],i,this)&&(result.push(this[i]),indices.push(i));for(let i=indices.length-1;i>=0;--i)splice.call(this,indices[i],1);return result}}),Object.defineProperty(Array.prototype,\"first\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.first called on null or undefined\");if(0!==this.length>>>0)return this[0]}}),Object.defineProperty(Array.prototype,\"includesAll\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.includesAll called on null or undefined\");if(1===arguments.length)return Array.isArray(arguments[0])?Array.prototype.includesAll.apply(this,arguments[0]):Array.prototype.includes.apply(this,arguments);for(let i=0,iend=arguments.length;i<iend;++i)if(!Array.prototype.some.call(this,(function(val){return val===this.val||val!=val&&this.val!=this.val}),{val:arguments[i]}))return!1;return!0}}),Object.defineProperty(Array.prototype,\"includesAny\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.includesAny called on null or undefined\");if(1===arguments.length)return Array.isArray(arguments[0])?Array.prototype.includesAny.apply(this,arguments[0]):Array.prototype.includes.apply(this,arguments);for(let i=0,iend=arguments.length;i<iend;++i)if(Array.prototype.some.call(this,(function(val){return val===this.val||val!=val&&this.val!=this.val}),{val:arguments[i]}))return!0;return!1}}),Object.defineProperty(Array.prototype,\"last\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.last called on null or undefined\");const length=this.length>>>0;if(0!==length)return this[length-1]}}),Object.defineProperty(Array.prototype,\"pluck\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.pluck called on null or undefined\");const length=this.length>>>0;if(0===length)return;const index=0===arguments.length?_random(0,length-1):_randomIndex(length,Array.from(arguments));return Array.prototype.splice.call(this,index,1)[0]}}),Object.defineProperty(Array.prototype,\"pluckMany\",{configurable:!0,writable:!0,value(wantSize){if(null==this)throw new TypeError(\"Array.prototype.pluckMany called on null or undefined\");const length=this.length>>>0;if(0===length)return[];let want=Math.trunc(wantSize);if(!Number.isInteger(want))throw new Error(\"Array.prototype.pluckMany want parameter must be an integer\");if(want<1)return[];want>length&&(want=length);const splice=Array.prototype.splice,result=[];let max=length-1;do{result.push(splice.call(this,_random(0,max--),1)[0])}while(result.length<want);return result}}),Object.defineProperty(Array.prototype,\"pushUnique\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.pushUnique called on null or undefined\");const addSize=arguments.length;if(0===addSize)return this.length>>>0;const indexOf=Array.prototype.indexOf,push=Array.prototype.push;for(let i=0;i<addSize;++i){const value=arguments[i];-1===indexOf.call(this,value)&&push.call(this,value)}return this.length>>>0}}),Object.defineProperty(Array.prototype,\"random\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.random called on null or undefined\");const length=this.length>>>0;if(0===length)return;return this[0===arguments.length?_random(0,length-1):_randomIndex(length,Array.from(arguments))]}}),Object.defineProperty(Array.prototype,\"randomMany\",{configurable:!0,writable:!0,value(wantSize){if(null==this)throw new TypeError(\"Array.prototype.randomMany called on null or undefined\");const length=this.length>>>0;if(0===length)return[];let want=Math.trunc(wantSize);if(!Number.isInteger(want))throw new Error(\"Array.prototype.randomMany want parameter must be an integer\");if(want<1)return[];want>length&&(want=length);const picked=new Map,result=[],max=length-1;do{let i;do{i=_random(0,max)}while(picked.has(i));picked.set(i,!0),result.push(this[i])}while(result.length<want);return result}}),Object.defineProperty(Array.prototype,\"shuffle\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.shuffle called on null or undefined\");const length=this.length>>>0;if(0===length)return this;for(let i=length-1;i>0;--i){const j=Math.floor(_nativeMathRandom()*(i+1));if(i===j)continue;const swap=this[i];this[i]=this[j],this[j]=swap}return this}}),Object.defineProperty(Array.prototype,\"toShuffled\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.toShuffled called on null or undefined\");return Array.from(this).shuffle()}}),Object.defineProperty(Array.prototype,\"toUnique\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.toUnique called on null or undefined\");return Array.from(new Set(this))}}),Object.defineProperty(Array.prototype,\"unshiftUnique\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.unshiftUnique called on null or undefined\");const addSize=arguments.length;if(0===addSize)return this.length>>>0;const indexOf=Array.prototype.indexOf,unshift=Array.prototype.unshift;for(let i=0;i<addSize;++i){const value=arguments[i];-1===indexOf.call(this,value)&&unshift.call(this,value)}return this.length>>>0}}),Object.defineProperty(Function.prototype,\"partial\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Function.prototype.partial called on null or undefined\");const slice=Array.prototype.slice,fn=this,bound=slice.call(arguments,0);return function(){const applied=[];let argc=0;for(let i=0;i<bound.length;++i)applied.push(bound[i]===undefined?arguments[argc++]:bound[i]);return fn.apply(this,applied.concat(slice.call(arguments,argc)))}}}),Object.defineProperty(Math,\"clamp\",{configurable:!0,writable:!0,value(num,min,max){if(3!==arguments.length)throw new Error(`Math.clamp called with an incorrect number of parameters (want: 3, received: ${arguments.length})`);const value=Number(num);let minVal=Number(min),maxVal=Number(max);return minVal>maxVal&&([minVal,maxVal]=[maxVal,minVal]),Math.min(Math.max(value,minVal),maxVal)}}),RegExp.escape||(()=>{const _regExpMetaCharsRe=/[\\\\^$*+?.()|[\\]{}]/g,_hasRegExpMetaCharsRe=new RegExp(_regExpMetaCharsRe.source);Object.defineProperty(RegExp,\"escape\",{configurable:!0,writable:!0,value(str){const val=String(str);return val&&_hasRegExpMetaCharsRe.test(val)?val.replace(_regExpMetaCharsRe,\"\\\\$&\"):val}})})(),(()=>{const _formatRegExp=/{(\\d+)(?:,([+-]?\\d+))?}/g,_hasFormatRegExp=new RegExp(_formatRegExp.source);Object.defineProperty(String,\"format\",{configurable:!0,writable:!0,value(format){if(arguments.length<2)return 0===arguments.length?\"\":format;const args=2===arguments.length&&Array.isArray(arguments[1])?Array.from(arguments[1]):Array.prototype.slice.call(arguments,1);return 0===args.length?format:_hasFormatRegExp.test(format)?(_formatRegExp.lastIndex=0,format.replace(_formatRegExp,((match,index,align)=>{let retval=args[index];if(null==retval)return\"\";for(;\"function\"==typeof retval;)retval=retval();switch(typeof retval){case\"string\":break;case\"object\":retval=JSON.stringify(retval);break;default:retval=String(retval)}return function(str,align,pad){if(!align)return str;const plen=Math.abs(align)-str.length;if(plen<1)return str;const padding=String(pad).repeat(plen);return align<0?str+padding:padding+str}(retval,align?Number.parseInt(align,10):0,\" \")}))):format}})})(),Object.defineProperty(String.prototype,\"count\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.count called on null or undefined\");const needle=String(arguments[0]||\"\");if(\"\"===needle)return 0;const indexOf=String.prototype.indexOf,step=needle.length;let pos=Number(arguments[1])||0,count=0;for(;-1!==(pos=indexOf.call(this,needle,pos));)++count,pos+=step;return count}}),Object.defineProperty(String.prototype,\"first\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.first called on null or undefined\");const str=String(this),{char:char}=_getCodePointStartAndEnd(str,0);return char}}),Object.defineProperty(String.prototype,\"last\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.last called on null or undefined\");const str=String(this),{char:char}=_getCodePointStartAndEnd(str,str.length-1);return char}}),Object.defineProperty(String.prototype,\"splice\",{configurable:!0,writable:!0,value(startAt,delCount,replacement){if(null==this)throw new TypeError(\"String.prototype.splice called on null or undefined\");const length=this.length>>>0;if(0===length)return\"\";let start=Number(startAt);Number.isSafeInteger(start)?start<0&&(start+=length,start<0&&(start=0)):start=0,start>length&&(start=length);let count=Number(delCount);(!Number.isSafeInteger(count)||count<0)&&(count=0);let res=this.slice(0,start);return void 0!==replacement&&(res+=replacement),start+count<length&&(res+=this.slice(start+count)),res}}),Object.defineProperty(String.prototype,\"splitOrEmpty\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.splitOrEmpty called on null or undefined\");return\"\"===String(this)?[]:String.prototype.split.apply(this,arguments)}}),Object.defineProperty(String.prototype,\"toLocaleUpperFirst\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.toLocaleUpperFirst called on null or undefined\");const str=String(this),{char:char,end:end}=_getCodePointStartAndEnd(str,0);return-1===end?\"\":char.toLocaleUpperCase()+str.slice(end+1)}}),Object.defineProperty(String.prototype,\"toUpperFirst\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.toUpperFirst called on null or undefined\");const str=String(this),{char:char,end:end}=_getCodePointStartAndEnd(str,0);return-1===end?\"\":char.toUpperCase()+str.slice(end+1)}}),Object.defineProperty(Array.prototype,\"delete\",{configurable:!0,writable:!0,value(){if(console.warn(\"[DEPRECATED] <Array>.delete() is deprecated.\"),null==this)throw new TypeError(\"Array.prototype.delete called on null or undefined\");return Array.prototype.deleteAll.apply(this,arguments)}}),Object.defineProperty(JSON,\"reviveWrapper\",{configurable:!0,writable:!0,value(code,data){if(console.warn(\"[DEPRECATED] JSON.reviveWrapper() is deprecated.\"),\"string\"!=typeof code)throw new TypeError(\"JSON.reviveWrapper code parameter must be a string\");return Serial.createReviver(code,data)}}),Object.defineProperty(Math,\"easeInOut\",{configurable:!0,writable:!0,value:num=>(console.warn(\"[DEPRECATED] Math.easeInOut() is deprecated.\"),1-(Math.cos(Number(num)*Math.PI)+1)/2)}),Object.defineProperty(Number.prototype,\"clamp\",{configurable:!0,writable:!0,value(){if(console.warn(\"[DEPRECATED] <Number>.clamp() is deprecated.\"),null==this)throw new TypeError(\"Number.prototype.clamp called on null or undefined\");if(2!==arguments.length)throw new Error(`Number.prototype.clamp called with an incorrect number of parameters (want: 2, received: ${arguments.length})`);return Math.clamp(this,arguments[0],arguments[1])}})})(),(()=>{function onKeypressFn(ev){13!==ev.which&&32!==ev.which||(ev.preventDefault(),triggerEvent(\"click\",getActiveElement()||this))}function onClickFnWrapper(fn){return function(){const $this=jQuery(this),dataPassage=$this.attr(\"data-passage\"),initialDataPassage=window&&window.SugarCube&&window.SugarCube.State&&window.SugarCube.State.passage,savedYOffset=window.pageYOffset;$this.is(\"[aria-pressed]\")&&$this.attr(\"aria-pressed\",\"true\"===$this.attr(\"aria-pressed\")?\"false\":\"true\"),fn.apply(this,arguments);!dataPassage||window.lastDataPassageLink!==dataPassage&&initialDataPassage!==dataPassage||window.scrollTo(0,savedYOffset),window.lastDataPassageLink=dataPassage}}function disableTabindex(el){if(!el.hasAttribute(\"data-last-tabindex\")){const tabindex=el.getAttribute(\"tabindex\");el.setAttribute(\"data-last-tabindex\",null!==tabindex?tabindex.trim():\"\")}el.setAttribute(\"tabindex\",-1)}function restoreTabindex(el){const lastTabindex=el.getAttribute(\"data-last-tabindex\");null!==lastTabindex&&(el.removeAttribute(\"data-last-tabindex\"),\"\"===lastTabindex?el.removeAttribute(\"tabindex\"):el.setAttribute(\"tabindex\",lastTabindex))}jQuery.fn.extend({ariaClick(options,handler){if(0===this.length||0===arguments.length)return this;let opts=options,fn=handler;return null==fn&&(fn=opts,opts=undefined),opts=jQuery.extend({namespace:undefined,one:!1,selector:undefined,data:undefined,role:undefined,tabindex:0,controls:undefined,pressed:undefined,label:undefined},opts),\"string\"!=typeof opts.namespace?opts.namespace=\"\":\".\"!==opts.namespace[0]&&(opts.namespace=`.${opts.namespace}`),\"boolean\"==typeof opts.pressed&&(opts.pressed=opts.pressed?\"true\":\"false\"),this.filter(\"button\").prop(\"type\",\"button\"),null!=opts.role?this.attr(\"role\",opts.role):this.not(\"[role]\").filter(\"a,[data-passage]\").attr(\"role\",\"link\").end().not(\"a\").not(\"[data-passage]\").attr(\"role\",\"button\").end().end().end(),this.attr(\"tabindex\",opts.tabindex),null!=opts.controls&&this.attr(\"aria-controls\",opts.controls),null!=opts.pressed&&this.attr(\"aria-pressed\",opts.pressed),null!=opts.label&&this.attr({\"aria-label\":opts.label,title:opts.label}),this.not(\"button\").on(`keypress.aria-clickable${opts.namespace}`,opts.selector,onKeypressFn),this.on(`click.aria-clickable${opts.namespace}`,opts.selector,opts.data,opts.one?function(fn){return onClickFnWrapper((function(){jQuery(this).off(\".aria-clickable\").removeAttr(\"role tabindex aria-controls aria-pressed\").filter(\"button\").prop(\"disabled\",!0),fn.apply(this,arguments)}))}(fn):onClickFnWrapper(fn)),this},ariaDisabled(disable){if(0===this.length||0===arguments.length)return this;const $nonDisableable=this.not(\"button,fieldset,input,menuitem,optgroup,option,select,textarea\"),$disableable=this.filter(\"button,fieldset,input,menuitem,optgroup,option,select,textarea\");return disable?($nonDisableable.each((function(){this.setAttribute(\"disabled\",\"disabled\"),this.setAttribute(\"aria-disabled\",\"true\"),disableTabindex(this)})),$disableable.each((function(){this.disabled=!0,this.setAttribute(\"aria-disabled\",\"true\"),disableTabindex(this)}))):($nonDisableable.each((function(){this.removeAttribute(\"disabled\"),this.removeAttribute(\"aria-disabled\"),restoreTabindex(this)})),$disableable.each((function(){this.disabled=!1,this.removeAttribute(\"aria-disabled\"),restoreTabindex(this)}))),this},ariaIsDisabled(){return this.is(\"[disabled]\")}})})(),jQuery.fn.extend({getForbiddenInteractiveContentTagNames(){if(0===this.length)return[];const forbidden=new Set;return this.find(\"a,button,fieldset,form,input,menuitem,optgroup,option,select,textarea\").each(((_,el)=>forbidden.add(el.nodeName.toLowerCase()))),Array.from(forbidden)}}),jQuery.extend({wikiWithOptions(options,...sources){if(0===sources.length)return;const frag=document.createDocumentFragment();sources.forEach((content=>new Wikifier(frag,content,options)));const errors=Array.from(frag.querySelectorAll(\".error\")).map((errEl=>errEl.textContent.replace(errorPrologRegExp,\"\")));if(errors.length>0)throw new Error(errors.join(\"; \"))},wiki(...sources){this.wikiWithOptions(undefined,...sources)},wikiPassage(name){this.wikiWithOptions(undefined,Story.get(name).processText())}}),jQuery.fn.extend({wikiWithOptions(options,...sources){if(0===this.length||0===sources.length)return this;const frag=document.createDocumentFragment();return sources.forEach((content=>new Wikifier(frag,content,options))),this.append(frag),this},wiki(...sources){return this.wikiWithOptions(undefined,...sources)},wikiPassage(name){return this.wikiWithOptions(undefined,Story.get(name).processText())}});var Browser=(()=>{const userAgent=navigator.userAgent.toLowerCase(),winPhone=userAgent.includes(\"windows phone\"),isMobile=Object.freeze({Android:!winPhone&&userAgent.includes(\"android\"),BlackBerry:/blackberry|bb10/.test(userAgent),iOS:!winPhone&&/ip(?:hone|ad|od)/.test(userAgent),Opera:!winPhone&&(\"object\"==typeof window.operamini||userAgent.includes(\"opera mini\")),Windows:winPhone||/iemobile|wpdesktop/.test(userAgent),any:()=>isMobile.Android||isMobile.BlackBerry||isMobile.iOS||isMobile.Opera||isMobile.Windows}),isGecko=!isMobile.Windows&&!/khtml|trident|edge/.test(userAgent)&&userAgent.includes(\"gecko\"),isIE=!userAgent.includes(\"opera\")&&/msie|trident/.test(userAgent),ieVersion=isIE?(()=>{const ver=/(?:msie\\s+|rv:)(\\d+\\.\\d)/.exec(userAgent);return ver?Number(ver[1]):0})():null,isOpera=userAgent.includes(\"opera\")||userAgent.includes(\" opr/\"),operaVersion=isOpera?(()=>{const ver=new RegExp((/khtml|chrome/.test(userAgent)?\"opr\":\"version\")+\"\\\\/(\\\\d+\\\\.\\\\d+)\").exec(userAgent);return ver?Number(ver[1]):0})():null,isVivaldi=userAgent.includes(\"vivaldi\");return Object.freeze(Object.assign(Object.create(null),{userAgent:userAgent,isMobile:isMobile,isGecko:isGecko,isIE:isIE,ieVersion:ieVersion,isOpera:isOpera,operaVersion:operaVersion,isVivaldi:isVivaldi}))})(),Has=(()=>{const hasAudioElement=(()=>{try{return\"function\"==typeof document.createElement(\"audio\").canPlayType}catch(ex){}return!1})(),hasFile=(()=>{try{return\"Blob\"in window&&\"File\"in window&&\"FileList\"in window&&\"FileReader\"in window&&(!Browser.isOpera||Browser.operaVersion>=15)}catch(ex){}return!1})(),hasGeolocation=(()=>{try{return\"geolocation\"in navigator&&\"function\"==typeof navigator.geolocation.getCurrentPosition&&\"function\"==typeof navigator.geolocation.watchPosition}catch(ex){}return!1})(),hasMutationObserver=(()=>{try{return\"MutationObserver\"in window&&\"function\"==typeof window.MutationObserver}catch(ex){}return!1})(),hasPerformance=(()=>{try{return\"performance\"in window&&\"function\"==typeof window.performance.now}catch(ex){}return!1})(),hasTouch=(()=>{try{return\"ontouchstart\"in window||!!window.DocumentTouch&&document instanceof window.DocumentTouch||!!navigator.maxTouchPoints||!!navigator.msMaxTouchPoints}catch(ex){}return!1})(),hasTransitionEndEvent=(()=>{try{const teMap=new Map([[\"transition\",\"transitionend\"],[\"MSTransition\",\"msTransitionEnd\"],[\"WebkitTransition\",\"webkitTransitionEnd\"],[\"MozTransition\",\"transitionend\"]]),teKeys=Array.from(teMap.keys()),el=document.createElement(\"div\");for(let i=0;i<teKeys.length;++i)if(el.style[teKeys[i]]!==undefined)return teMap.get(teKeys[i])}catch(ex){}return!1})();return Object.freeze(Object.assign(Object.create(null),{audio:hasAudioElement,fileAPI:hasFile,geolocation:hasGeolocation,mutationObserver:hasMutationObserver,performance:hasPerformance,touch:hasTouch,transitionEndEvent:hasTransitionEndEvent}))})(),Fullscreen=(()=>{const vendor=(()=>{try{return Object.freeze([{isEnabled:\"fullscreenEnabled\",element:\"fullscreenElement\",requestFn:\"requestFullscreen\",exitFn:\"exitFullscreen\",changeEvent:\"fullscreenchange\",errorEvent:\"fullscreenerror\"},{isEnabled:\"webkitFullscreenEnabled\",element:\"webkitFullscreenElement\",requestFn:\"webkitRequestFullscreen\",exitFn:\"webkitExitFullscreen\",changeEvent:\"webkitfullscreenchange\",errorEvent:\"webkitfullscreenerror\"},{isEnabled:\"mozFullScreenEnabled\",element:\"mozFullScreenElement\",requestFn:\"mozRequestFullScreen\",exitFn:\"mozCancelFullScreen\",changeEvent:\"mozfullscreenchange\",errorEvent:\"mozfullscreenerror\"},{isEnabled:\"msFullscreenEnabled\",element:\"msFullscreenElement\",requestFn:\"msRequestFullscreen\",exitFn:\"msExitFullscreen\",changeEvent:\"MSFullscreenChange\",errorEvent:\"MSFullscreenError\"}].find((vnd=>vnd.isEnabled in document)))}catch(ex){}return undefined})(),_returnsPromise=function(){let _hasPromise=null;return function(){if(null!==_hasPromise)return _hasPromise;if(_hasPromise=!1,vendor)try{const value=document.exitFullscreen();value.catch((()=>{})),_hasPromise=value instanceof Promise}catch(ex){}return _hasPromise}}();function _selectElement(requestedEl){let selectedEl=requestedEl||document.documentElement;return selectedEl===document.documentElement&&(\"msRequestFullscreen\"===vendor.requestFn||Browser.isOpera&&Browser.operaVersion<15)&&(selectedEl=document.body),selectedEl}function isFullscreen(){return Boolean(vendor&&document[vendor.element])}function requestFullscreen(options,requestedEl){if(!vendor)return Promise.reject(new Error(\"fullscreen not supported\"));const element=_selectElement(requestedEl);if(\"function\"!=typeof element[vendor.requestFn])return Promise.reject(new Error(\"fullscreen not supported\"));if(isFullscreen())return Promise.resolve();if(_returnsPromise())return element[vendor.requestFn](options);{const namespace=\".Fullscreen_requestFullscreen\";return new Promise(((resolve,reject)=>{const $element=jQuery(element);$element.off(namespace).one(`${vendor.errorEvent}${namespace} ${vendor.changeEvent}${namespace}`,(ev=>{$element.off(namespace),ev.type===vendor.errorEvent?reject(new Error(\"unknown fullscreen request error\")):resolve()})),element[vendor.requestFn](options)}))}}function exitFullscreen(){if(!vendor||\"function\"!=typeof document[vendor.exitFn])return Promise.reject(new TypeError(\"fullscreen not supported\"));if(!isFullscreen())return Promise.reject(new TypeError(\"fullscreen mode not active\"));if(_returnsPromise())return document[vendor.exitFn]();{const namespace=\".Fullscreen_exitFullscreen\";return new Promise(((resolve,reject)=>{const $document=jQuery(document);$document.off(namespace).one(`${vendor.errorEvent}${namespace} ${vendor.changeEvent}${namespace}`,(ev=>{$document.off(namespace),ev.type===vendor.errorEvent?reject(new Error(\"unknown fullscreen exit error\")):resolve()})),document[vendor.exitFn]()}))}}return Object.preventExtensions(Object.create(null,{vendor:{get:function(){return vendor}},element:{get:function(){return vendor?document[vendor.element]:null}},isEnabled:{value:function(){return Boolean(vendor&&document[vendor.isEnabled])}},isFullscreen:{value:isFullscreen},request:{value:requestFullscreen},exit:{value:exitFullscreen},toggle:{value:function(options,requestedEl){return isFullscreen()?exitFullscreen():requestFullscreen(options,requestedEl)}},onChange:{value:function(handlerFn,requestedEl){if(!vendor)return;const element=_selectElement(requestedEl);jQuery(element).on(vendor.changeEvent,handlerFn)}},offChange:{value:function(handlerFn,requestedEl){if(!vendor)return;const element=_selectElement(requestedEl);handlerFn?jQuery(element).off(vendor.changeEvent,handlerFn):jQuery(element).off(vendor.changeEvent)}},onError:{value:function(handlerFn,requestedEl){if(!vendor)return;const element=_selectElement(requestedEl);jQuery(element).on(vendor.errorEvent,handlerFn)}},offError:{value:function(handlerFn,requestedEl){if(!vendor)return;const element=_selectElement(requestedEl);handlerFn?jQuery(element).off(vendor.errorEvent,handlerFn):jQuery(element).off(vendor.errorEvent)}}}))})(),Outliner=(()=>{let lastEvent,styleEl=null;function outlinerHide(){document.documentElement.removeAttribute(\"data-outlines\"),styleEl.styleSheet?styleEl.styleSheet.cssText=\"*:focus{outline:none;}\":styleEl.textContent=\"*:focus{outline:none;}\"}function outlinerShow(){document.documentElement.setAttribute(\"data-outlines\",\"\"),styleEl.styleSheet?styleEl.styleSheet.cssText=\"\":styleEl.textContent=\"\"}return Object.preventExtensions(Object.create(null,{init:{value:function(){styleEl||(styleEl=document.createElement(\"style\"),jQuery(styleEl).attr({id:\"style-outliner\",type:\"text/css\"}).appendTo(document.head),jQuery(document).on(\"mousedown.style-outliner keydown.style-outliner\",(ev=>{ev.type!==lastEvent&&(lastEvent=ev.type,\"keydown\"===ev.type?outlinerShow():outlinerHide())})),lastEvent=\"mousedown\",outlinerHide())}},hide:{value:outlinerHide},show:{value:outlinerShow}}))})(),Serial=(()=>{const supportedTypes=Object.freeze([{id:\"Date\",get reference(){return Date.prototype},method(){return[\"(revive:date)\",this.toISOString()]}},{id:\"Function\",get reference(){return Function.prototype},method(){return[\"(revive:)\",[`(${this.toString()})`]]}},{id:\"Map\",get reference(){return Map.prototype},method(){return[\"(revive:map)\",Array.from(this)]}},{id:\"RegExp\",get reference(){return RegExp.prototype},method(){return[\"(revive:)\",[this.toString()]]}},{id:\"Set\",get reference(){return Set.prototype},method(){return[\"(revive:set)\",Array.from(this)]}}]);function createReviver(code,data){if(\"string\"!=typeof code)throw new TypeError(\"Serial.createReviver code parameter must be a string\");return[\"(revive:)\",[code,data]]}function parse(text,reviver){return JSON.parse(text,((key,val)=>{let value=val;if(value instanceof Array&&2===value.length)switch(value[0]){case\"(revive:set)\":value=new Set(value[1]);break;case\"(revive:map)\":value=new Map(value[1]);break;case\"(revive:date)\":value=new Date(value[1]);break;case\"(revive:eval)\":case\"(revive:)\":try{const $ReviveData$=value[1][1];value=eval(value[1][0])}catch(ex){}}if(\"function\"==typeof reviver)try{value=reviver(key,value)}catch(ex){}return value}))}function stringify(value,replacer,space){const origMethodCache=new Map;supportedTypes.forEach((({id:id,reference:reference,method:method})=>{Object.hasOwn(reference,\"toJSON\")&&origMethodCache.set(id,reference.toJSON),Object.defineProperty(reference,\"toJSON\",{configurable:!0,writable:!0,value:method})}));const notation=JSON.stringify(value,((key,val)=>{let value=val;if(\"function\"==typeof replacer)try{value=replacer(key,value)}catch(ex){}switch(value){case undefined:value=[\"(revive:)\",[\"undefined\"]];break;case 1/0:value=[\"(revive:)\",[\"Infinity\"]]}return value}),space);return supportedTypes.forEach((({id:id,reference:reference})=>{origMethodCache.has(id)?(Object.defineProperty(reference,\"toJSON\",{configurable:!0,writable:!0,value:origMethodCache.get(id)}),origMethodCache.delete(id)):delete reference.toJSON})),notation}return Object.preventExtensions(Object.create(null,{createReviver:{value:createReviver},parse:{value:parse},stringify:{value:stringify}}))})(),Visibility=(()=>{const vendor=(()=>{try{return Object.freeze([{hiddenProperty:\"hidden\",stateProperty:\"visibilityState\",changeEvent:\"visibilitychange\"},{hiddenProperty:\"webkitHidden\",stateProperty:\"webkitVisibilityState\",changeEvent:\"webkitvisibilitychange\"},{hiddenProperty:\"mozHidden\",stateProperty:\"mozVisibilityState\",changeEvent:\"mozvisibilitychange\"},{hiddenProperty:\"msHidden\",stateProperty:\"msVisibilityState\",changeEvent:\"msvisibilitychange\"}].find((vnd=>vnd.hiddenProperty in document)))}catch(ex){}return undefined})();return Object.preventExtensions(Object.create(null,{vendor:{get:function(){return vendor}},state:{get:function(){return vendor&&document[vendor.stateProperty]||\"visible\"}},isEnabled:{value:function(){return Boolean(vendor)}},isHidden:{value:function(){return Boolean(vendor&&document[vendor.hiddenProperty])}},hiddenProperty:{value:vendor&&vendor.hiddenProperty},stateProperty:{value:vendor&&vendor.stateProperty},changeEvent:{value:vendor&&vendor.changeEvent}}))})();function appendError(output,message,source,stack){const $wrapper=jQuery(document.createElement(\"div\")),$toggle=jQuery(document.createElement(\"button\")),$source=jQuery(document.createElement(\"pre\")),mesg=`${L10n.get(\"errorViewTitle\")}: ${message||\"unknown error\"} ${Config.saves.version}`;if($toggle.addClass(\"error-toggle\").ariaClick({label:L10n.get(\"errorViewLabelToggle\")},(()=>{$toggle.hasClass(\"enabled\")?($toggle.removeClass(\"enabled\"),$source.attr({\"aria-hidden\":!0,hidden:\"hidden\"})):($toggle.addClass(\"enabled\"),$source.removeAttr(\"aria-hidden hidden\"))})).appendTo($wrapper),jQuery(document.createElement(\"span\")).addClass(\"error\").text(mesg).appendTo($wrapper),jQuery(document.createElement(\"code\")).text(source).appendTo($source),$source.addClass(\"error-source\").attr({\"aria-hidden\":!0,hidden:\"hidden\"}).appendTo($wrapper),stack){const lines=stack.split(\"\\n\");for(const ll of lines){const div=document.createElement(\"div\");div.append(ll.replace(/file:.*\\//,\"<path>/\")),$source.append(div)}}return $wrapper.addClass(\"error-view\").appendTo(output),console.warn(`${mesg}\\n\\t${source.replace(/\\n/g,\"\\n\\t\")}`),!1}var throwError=appendError;function charAndPosAt(string,position){const str=String(string),pos=Math.trunc(position),code=str.charCodeAt(pos);if(Number.isNaN(code))return{char:\"\",start:-1,end:-1};const retval={char:str.charAt(pos),start:pos,end:pos};if(code<55296||code>57343)return retval;if(code>=55296&&code<=56319){const nextPos=pos+1;if(nextPos>=str.length)return retval;const nextCode=str.charCodeAt(nextPos);return nextCode<56320||nextCode>57343||(retval.char=retval.char+str.charAt(nextPos),retval.end=nextPos),retval}if(0===pos)return retval;const prevPos=pos-1,prevCode=str.charCodeAt(prevPos);return prevCode<55296||prevCode>56319||(retval.char=str.charAt(prevPos)+retval.char,retval.start=prevPos),retval}function clone(O){if(\"object\"!=typeof O||null===O)return O;if(\"function\"==typeof O.clone)return O.clone(!0);let copy;if(O instanceof Array)copy=new Array(O.length);else if(O instanceof Date)copy=new Date(O.getTime());else if(O instanceof Map)copy=new Map,O.forEach(((val,key)=>copy.set(clone(key),clone(val))));else if(O instanceof RegExp)copy=new RegExp(O);else if(O instanceof Set)copy=new Set,O.forEach((val=>copy.add(clone(val))));else{const type=getTypeOf(O);if(\"Object\"!==type)throw new TypeError(`attempted to clone unsupported type: ${type}`);copy=Object.create(Object.getPrototypeOf(O))}return Object.keys(O).forEach((P=>copy[P]=clone(O[P]))),copy}var convertBreaks=(()=>{const isNotSpaceRE=new RegExp(Patterns.notSpace);function isParagraphEmpty(para){if(!para.hasChildNodes())return!0;const nodes=para.childNodes,length=nodes.length;for(let i=0;i<length;++i){const node=nodes[i];switch(node.nodeType){case Node.TEXT_NODE:if(isNotSpaceRE.test(node.nodeValue))return!1;break;case Node.COMMENT_NODE:break;default:return!1}}return!0}return function(source){const output=document.createDocumentFragment();let node,para=document.createElement(\"p\");for(;null!==(node=source.firstChild);){if(node.nodeType===Node.ELEMENT_NODE){switch(node.nodeName.toUpperCase()){case\"BR\":if(null!==node.nextSibling&&node.nextSibling.nodeType===Node.ELEMENT_NODE&&\"BR\"===node.nextSibling.nodeName.toUpperCase()){source.removeChild(node.nextSibling),source.removeChild(node),isParagraphEmpty(para)||output.appendChild(para),para=document.createElement(\"p\");continue}if(isParagraphEmpty(para)){source.removeChild(node);continue}break;case\"ADDRESS\":case\"ARTICLE\":case\"ASIDE\":case\"BLOCKQUOTE\":case\"CENTER\":case\"DIV\":case\"DL\":case\"FIGURE\":case\"FOOTER\":case\"FORM\":case\"H1\":case\"H2\":case\"H3\":case\"H4\":case\"H5\":case\"H6\":case\"HEADER\":case\"HR\":case\"MAIN\":case\"NAV\":case\"OL\":case\"P\":case\"PRE\":case\"SECTION\":case\"TABLE\":case\"UL\":isParagraphEmpty(para)||(output.appendChild(para),para=document.createElement(\"p\")),output.appendChild(node);continue}}para.appendChild(node)}isParagraphEmpty(para)||output.appendChild(para),source.appendChild(output)}})(),createFilename=(()=>{const illegalCharsRE=/[\\x00-\\x1f\"#$%&'*+,/:;<=>?\\\\^`|\\x7f-\\x9f]+/g;return function(str){return String(str).trim().replace(illegalCharsRE,\"\")}})(),createSlug=(()=>{const illegalCharsRE=/[\\x00-\\x20!-/:-@[-^`{-\\x9f]+/g,isInvalidSlugRE=/^-*$/,storySigilRE=/^\\$/,tempSigilRE=/^_/;return function(str){const base=String(str).trim(),legacy=base.replace(/[^\\w\\s\\u2013\\u2014-]+/g,\"\").replace(/[_\\s\\u2013\\u2014-]+/g,\"-\").toLocaleLowerCase();return isInvalidSlugRE.test(legacy)?base.replace(storySigilRE,\"\").replace(tempSigilRE,\"-\").replace(illegalCharsRE,\"\"):legacy}})();function cssPropToDOMProp(cssName){if(!cssName.includes(\"-\"))switch(cssName){case\"bgcolor\":return\"backgroundColor\";case\"float\":return\"cssFloat\";default:return cssName}return(\"-ms-\"===cssName.slice(0,4)?cssName.slice(1):cssName).split(\"-\").map(((part,i)=>0===i?part:part.toUpperFirst())).join(\"\")}const cssTimeToMS=(()=>{const cssTimeRE=/^([+-]?(?:\\d*\\.)?\\d+)([Mm]?[Ss])$/;return function(cssTime){const match=cssTimeRE.exec(String(cssTime));if(null===match)throw new SyntaxError(`invalid time value syntax: \"${cssTime}\"`);let msec=Number(match[1]);if(1===match[2].length&&(msec*=1e3),Number.isNaN(msec)||!Number.isFinite(msec))throw new RangeError(`invalid time value: \"${cssTime}\"`);return msec}})();var decodeEntities=(()=>{const escapedHtmlRE=/&(?:amp|#38|#x26|lt|#60|#x3c|gt|#62|#x3e|quot|#34|#x22|apos|#39|#x27|#96|#x60);/gi,hasEscapedHtmlRE=new RegExp(escapedHtmlRE.source,\"i\"),escapedHtmlTable=enumFrom({\"&\":\"&\",\"&\":\"&\",\"&\":\"&\",\"<\":\"<\",\"<\":\"<\",\"<\":\"<\",\">\":\">\",\">\":\">\",\">\":\">\",\""\":'\"',\""\":'\"',\""\":'\"',\"'\":\"'\",\"'\":\"'\",\"'\":\"'\",\"`\":\"`\",\"`\":\"`\"});return function(str){if(null==str)return\"\";const val=String(str);return val&&hasEscapedHtmlRE.test(val)?val.replace(escapedHtmlRE,(entity=>escapedHtmlTable[entity.toLowerCase()])):val}})(),encodeEntities=(()=>{const htmlCharsRE=/[&<>\"'`]/g,hasHtmlCharsRE=new RegExp(htmlCharsRE.source),htmlCharsTable=enumFrom({\"&\":\"&\",\"<\":\"<\",\">\":\">\",'\"':\""\",\"'\":\"'\",\"`\":\"`\"});return function(str){if(null==str)return\"\";const val=String(str);return val&&hasHtmlCharsRE.test(val)?val.replace(htmlCharsRE,(ch=>htmlCharsTable[ch])):val}})(),encodeMarkup=(()=>{const markupCharsRE=/[!\"#$&'*\\-/<=>?@[\\\\\\]^_`{|}~]/g,hasMarkupCharsRE=new RegExp(markupCharsRE.source),markupCharsTable=enumFrom({\"!\":\"!\",'\"':\""\",\"#\":\"#\",$:\"$\",\"&\":\"&\",\"'\":\"'\",\"*\":\"*\",\"-\":\"-\",\"/\":\"/\",\"<\":\"<\",\"=\":\"=\",\">\":\">\",\"?\":\"?\",\"@\":\"@\",\"[\":\"[\",\"\\\\\":\"\\",\"]\":\"]\",\"^\":\"^\",_:\"_\",\"`\":\"`\",\"{\":\"{\",\"|\":\"|\",\"}\":\"}\",\"~\":\"~\"});return function(str){if(null==str)return\"\";const val=String(str);return val&&hasMarkupCharsRE.test(val)?val.replace(markupCharsRE,(ch=>markupCharsTable[ch])):val}})(),enquote=(()=>{const unescapedDQuoteRE=/(^|[^\\\\])(\")/g,unescapedSQuoteRE=/(^|[^\\\\])(')/g;return function(string){let dqCount=0,sqCount=0;for(let i=0;i<string.length;++i)switch(string[i]){case\"\\\\\":++i;break;case'\"':++dqCount;break;case\"'\":++sqCount}if(0===dqCount)return`\"${string}\"`;if(0===sqCount)return`'${string}'`;const quote=dqCount<=sqCount?'\"':\"'\";return`${quote}${string.replace('\"'===quote?unescapedDQuoteRE:unescapedSQuoteRE,\"$1\\\\$2\")}${quote}`}})();function enumFrom(O){const pEnum=Object.create(null);if(O instanceof Array)O.forEach(((val,i)=>pEnum[String(val)]=i));else if(O instanceof Set)Array.from(O).forEach(((val,i)=>pEnum[String(val)]=i));else if(O instanceof Map)O.forEach(((val,key)=>pEnum[String(key)]=val));else{if(null===O||\"object\"!=typeof O||Object.getPrototypeOf(O)!==Object.prototype)throw new TypeError(\"enumFrom object parameter must be an Array, Map, Set, or generic object\");Object.assign(pEnum,O)}return Object.freeze(Object.defineProperties(pEnum,{nameFrom:{value(needle){const entry=Object.entries(this).find((entry=>entry[1]===needle));return entry?entry[0]:undefined}}}))}var exceptionFrom=(()=>{const extraProps=Object.freeze([\"code\",\"data\",\"result\",\"stack\",\"columnNumber\",\"fileName\",\"lineNumber\",\"description\",\"number\"]);return function(original,exceptionType,override){if(null===original||\"object\"!=typeof original)throw new Error(\"exceptionFrom original parameter must be an object\");if(\"function\"!=typeof exceptionType)throw new Error(\"exceptionFrom exceptionType parameter must be an error type constructor\");const overrideType=typeof override;if(\"undefined\"!==overrideType&&\"string\"!==overrideType&&\"object\"!==overrideType)throw new Error(\"exceptionFrom override parameter must be an object or string\");const propValues=new Map;extraProps.forEach((name=>{void 0!==original[name]&&propValues.set(name,original[name])})),\"string\"===overrideType?propValues.set(\"message\",override):\"object\"===overrideType&&null!==override&&Object.getOwnPropertyNames(override).forEach((name=>{void 0!==override[name]&&propValues.set(name,override[name])}));const ex=new exceptionType(propValues.get(\"message\"));return propValues.delete(\"message\"),propValues.forEach(((value,name)=>{void 0===ex[name]?Object.defineProperty(ex,name,{value:value,configurable:!0,writable:!0}):ex[name]=value})),ex}})();function getActiveElement(){try{return document.activeElement||null}catch(ex){return null}}function getErrorMessage(O){return null==O?\"unknown error\":\"object\"==typeof O&&\"message\"in O?`${O.name||\"NoErrorName\"}: ${O.message}`:String(O)}var getToStringTag=(()=>{const toString=Object.prototype.toString,slice=String.prototype.slice;return\"[object Object]\"===toString.call(new Map)?function(O){return O instanceof Map?\"Map\":O instanceof Set?\"Set\":slice.call(toString.call(O),8,-1)}:function(O){return slice.call(toString.call(O),8,-1)}})(),getTypeOf=(()=>{const toString=Object.prototype.toString,slice=String.prototype.slice;return function(O){if(null===O)return\"null\";const baseType=typeof O;return\"object\"===baseType?slice.call(toString.call(O),8,-1):baseType}})(),hasMediaQuery=\"function\"!=typeof window.matchMedia?function(){return!1}:function(mediaQuery){return window.matchMedia(mediaQuery).matches},isExternalLink=(()=>{const externalUrlRE=new RegExp(`^${Patterns.externalUrl}`,\"gim\"),fingerprintRE=/[/\\\\?]/;return function(link){return!Story.has(link)&&(externalUrlRE.test(link)||fingerprintRE.test(link))}})();function msToCSSTime(msec){if(\"number\"!=typeof msec||Number.isNaN(msec)||!Number.isFinite(msec)){let what;switch(typeof msec){case\"string\":what=`\"${msec}\"`;break;case\"number\":what=String(msec);break;default:what=getTypeOf(msec)}throw new TypeError(`invalid milliseconds value: ${what}`)}return`${msec}ms`}var now=(()=>{const clock=Has.performance?performance:Date;return function(){return clock.now()}})(),onUserActivation=(()=>{const uaEvents=Object.freeze([\"keydown\",\"mousedown\",\"pointerdown\",\"pointerup\",\"touchend\"]);return function(namespace,callback){jQuery(document).off(namespace).on(uaEvents.map((name=>`${name}${namespace}`)).join(\" \"),(ev=>{callback(ev).then((()=>jQuery(document).off(namespace)),(ex=>{if(\"NotAllowedError\"!==ex.name)throw jQuery(document).off(namespace),ex}))}))}})();function parseURL(url){const parser=document.createElement(\"a\"),searchParams=Object.create(null);parser.href=url,parser.search&&parser.search.replace(/^\\?/,\"\").splitOrEmpty(/(?:&(?:amp;)?|;)/).forEach((query=>{const[key,value]=query.split(\"=\");Object.hasOwn(searchParams,key)?searchParams[key].push(value):searchParams[key]=[value]}));const pathname=parser.host&&\"/\"!==parser.pathname[0]?`/${parser.pathname}`:parser.pathname;return Object.freeze(Object.assign(Object.create(null),{href:parser.href,protocol:parser.protocol,host:parser.host,hostname:parser.hostname,port:parser.port,path:`${pathname}${parser.search}`,pathname:pathname,search:parser.search,searchParams:Object.freeze(searchParams),hash:parser.hash}))}function sameValueZero(a,b){return a===b||a!=a&&b!=b}var scrubEventKey=(()=>{let separatorKey,decimalKey;if(\"undefined\"!=typeof Intl&&\"function\"==typeof Intl.NumberFormat){const match=(new Intl.NumberFormat).format(111111.5).match(/(\\D*)\\d+(\\D*)\\d$/);match&&(separatorKey=match[1],decimalKey=match[2])}return separatorKey||decimalKey||(separatorKey=\",\",decimalKey=\".\"),function(key){switch(key){case\"Scroll\":return\"ScrollLock\";case\"Spacebar\":return\" \";case\"Left\":return\"ArrowLeft\";case\"Right\":return\"ArrowRight\";case\"Up\":return\"ArrowUp\";case\"Down\":return\"ArrowDown\";case\"Del\":return\"Delete\";case\"Crsel\":return\"CrSel\";case\"Exsel\":return\"ExSel\";case\"Esc\":return\"Escape\";case\"Apps\":return\"ContextMenu\";case\"Nonconvert\":return\"NonConvert\";case\"MediaNextTrack\":return\"MediaTrackNext\";case\"MediaPreviousTrack\":return\"MediaTrackPrevious\";case\"VolumeUp\":return\"AudioVolumeUp\";case\"VolumeDown\":return\"AudioVolumeDown\";case\"VolumeMute\":return\"AudioVolumeMute\";case\"Zoom\":return\"ZoomToggle\";case\"SelectMedia\":case\"MediaSelect\":return\"LaunchMediaPlayer\";case\"Add\":return\"+\";case\"Divide\":return\"/\";case\"Multiply\":return\"*\";case\"Subtract\":return\"-\";case\"Decimal\":return decimalKey;case\"Separator\":return separatorKey}return key}})(),setDisplayTitle=function(title,isPlainText){if(\"string\"!=typeof title)throw new TypeError(`title parameter must be a string (received: ${getTypeOf(title)})`);let render,text;isPlainText?(render=title.trim(),text=render):(render=document.createDocumentFragment(),new Wikifier(render,title,{noCleanup:!0}),text=function(source){const copy=source.cloneNode(!0),frag=document.createDocumentFragment();let node;for(;null!==(node=copy.firstChild);){if(node.nodeType===Node.ELEMENT_NODE)switch(node.nodeName.toUpperCase()){case\"BR\":case\"DIV\":case\"P\":frag.appendChild(document.createTextNode(\" \"))}frag.appendChild(node)}return frag.textContent}(render).trim()),document.title=Config.passages.displayTitles&&\"\"!==State.passage&&State.passage!==Config.passages.start?`${State.passage} | ${text}`:text,jQuery(\"#story-title\").empty().append(render)};function setPageElement(idOrElement,titles,defaultText){const el=\"object\"==typeof idOrElement?idOrElement:document.getElementById(idOrElement);if(null==el)return null;const ids=titles instanceof Array?titles:[titles];jQuery(el).empty();for(let i=0;i<ids.length;++i)if(Story.has(ids[i]))return new Wikifier(el,Story.get(ids[i]).processText().trim()),el;if(null!=defaultText){const text=String(defaultText).trim();\"\"!==text&&new Wikifier(el,text)}return el}function stringFrom(value){switch(typeof value){case\"function\":return\"[function]\";case\"number\":if(Number.isNaN(value))return\"[number NaN]\";break;case\"object\":if(null===value)return\"[null]\";if(value instanceof Array)return value.map((val=>stringFrom(val))).join(\", \");if(value instanceof Set)return Array.from(value).map((val=>stringFrom(val))).join(\", \");if(value instanceof Map){return`{ ${Array.from(value).map((([key,val])=>`${stringFrom(key)} → ${stringFrom(val)}`)).join(\", \")} }`}if(value instanceof Date)return value.toLocaleString();if(value instanceof Element){if(value===document.documentElement||value===document.head||value===document.body)throw new Error(\"illegal operation; attempting to convert the <html>, <head>, or <body> tags to string is not allowed\");return value.outerHTML}if(value instanceof Node)return value.textContent;break;case\"symbol\":return`[symbol${void 0!==value.description?` \"${value.description}\"`:\"\"}]`;case\"undefined\":return\"[undefined]\"}return String(value)}var triggerEvent=(()=>{const createEvent=(()=>{try{return new CustomEvent(\"click\",{bubbles:!0}),function(name,options){const{bubbles:bubbles,cancelable:cancelable,composed:composed,detail:detail,...custom}=Object.assign({bubbles:!0,cancelable:!0,composed:!1},options),event=new CustomEvent(name,{bubbles:bubbles,cancelable:cancelable,composed:composed,detail:detail});for(let i=0,keys=Object.keys(custom);i<keys.length;++i){const key=keys[i];void 0!==custom[key]&&(event[key]=options[key])}return event}}catch(ex){return function(name,options){const{bubbles:bubbles,cancelable:cancelable,...custom}=Object.assign({bubbles:!0,cancelable:!0},options),event=document.createEvent(\"Event\");for(let i=0,keys=Object.keys(custom);i<keys.length;++i){const key=keys[i];void 0!==custom[key]&&(event[key]=options[key])}return event.initEvent(name,bubbles,cancelable),event}}})();return function(name,targets,options){const event=createEvent(name,options),elems=[];if(targets)if(targets instanceof jQuery||targets instanceof NodeList||targets instanceof Array)for(let i=0;i<targets.length;++i)elems.push(targets[i]);else elems.push(targets);else elems.push(document);for(let i=0;i<elems.length;++i)elems[i].dispatchEvent(event)}})(),SimpleStore=(()=>{const _adapters=[];let _initialized=null;return Object.preventExtensions(Object.create(null,{adapters:{value:_adapters},create:{value:function(storageId,persistent){if(_initialized)return _initialized.create(storageId,persistent);for(let i=0;i<_adapters.length;++i)if(_adapters[i].init(storageId,persistent))return _initialized=_adapters[i],_initialized.create(storageId,persistent);throw new Error(\"No valid storage adapters found\")}}}))})();SimpleStore.adapters.push((()=>{let _ok=!1;class _FCHostStorageAdapter{constructor(persistent){let engine=null,name=null;persistent?(engine=window.FCHostPersistent,name=\"FCHostPersistent\"):(engine=window.FCHostSession,name=\"FCHostSession\"),Object.defineProperties(this,{_engine:{value:engine},name:{value:name},persistent:{value:!!persistent}})}get length(){return this._engine.size()}size(){return this._engine.size()}keys(){return this._engine.keys()}has(key){return!(\"string\"!=typeof key||!key)&&this._engine.has(key)}get(key){if(\"string\"!=typeof key||!key)return null;const value=this._engine.get(key);return null==value?null:_FCHostStorageAdapter._deserialize(value)}set(key,value){return!(\"string\"!=typeof key||!key)&&(this._engine.set(key,_FCHostStorageAdapter._serialize(value)),!0)}delete(key){return!(\"string\"!=typeof key||!key)&&(this._engine.remove(key),!0)}clear(){return this._engine.clear(),!0}static _serialize(obj){return JSON.stringify(obj)}static _deserialize(str){return JSON.parse(str)}}return Object.freeze(Object.defineProperties({},{init:{value:function(){return _ok=function(){try{if(void 0!==window.FCHostPersistent)return!0}catch(ex){}return!1}(),_ok}},create:{value:function(storageId,persistent){if(!_ok)throw new Error(\"adapter not initialized\");return new _FCHostStorageAdapter(persistent)}}}))})()),SimpleStore.adapters.push((()=>{let _ok=!1;class WebStorageAdapter{constructor(storageId,persistent){const prefix=`${storageId}.`;let engine=null,name=null;persistent?(engine=window.localStorage,name=\"localStorage\"):(engine=window.sessionStorage,name=\"sessionStorage\"),Object.defineProperties(this,{_engine:{value:engine},_prefix:{value:prefix},_prefixRe:{value:new RegExp(`^${RegExp.escape(prefix)}`)},name:{value:name},id:{value:storageId},persistent:{value:Boolean(persistent)}})}get size(){return this.keys().length}keys(){const keys=[];for(let i=0;i<this._engine.length;++i){const key=this._engine.key(i);this._prefixRe.test(key)&&keys.push(key.replace(this._prefixRe,\"\"))}return keys}has(key){return!(\"string\"!=typeof key||!key)&&Object.hasOwn(this._engine,this._prefix+key)}get(key){if(\"string\"!=typeof key||!key)return null;const value=this._engine.getItem(this._prefix+key);return null==value?null:WebStorageAdapter._deserialize(value)}set(key,value,compression=!0){if(\"string\"!=typeof key||!key)return!1;try{this._engine.setItem(this._prefix+key,WebStorageAdapter._serialize(value,this.persistent&&compression))}catch(ex){if(isQuotaDOMException(ex))throw exceptionFrom(ex,Error,{cause:{origin:ex},message:`${this.name} quota exceeded`});throw ex}return!0}delete(key){return!(\"string\"!=typeof key||!key)&&(this._engine.removeItem(this._prefix+key),!0)}clear(){const keys=this.keys();for(let i=0,length=keys.length;i<length;++i)this.delete(keys[i]);return!0}static _serialize(obj,compression){return compression?LZString.compressToUTF16(Serial.stringify(obj)):Serial.stringify(obj)}static _deserialize(str){return Serial.parse(str&&\"{\"!==str[0]?LZString.decompressFromUTF16(str):str)}}const isQuotaErrorRE=/quota.?(?:exceeded|reached)/i;function isQuotaDOMException(ex){return ex instanceof DOMException&&(22===ex.code||1014===ex.code||isQuotaErrorRE.test(ex.name)||isQuotaErrorRE.test(ex.message))}return Object.preventExtensions(Object.create(null,{init:{value:function(){function hasWebStorage(storeId){let store;try{store=window[storeId];const val=`_sc_${String(Date.now())}`;store.setItem(val,val);const result=store.getItem(val)===val;return store.removeItem(val),result}catch(ex){return store&&0!==store.length&&isQuotaDOMException(ex)}}return _ok=hasWebStorage(\"localStorage\")&&hasWebStorage(\"sessionStorage\"),_ok}},create:{value:function(storageId,persistent){if(!_ok)throw new Error(\"adapter not initialized\");return new WebStorageAdapter(storageId,persistent)}}}))})()),SimpleStore.adapters.push((()=>{const _MAX_EXPIRY=\"Tue, 19 Jan 2038 03:14:07 GMT\",_MIN_EXPIRY=\"Thu, 01 Jan 1970 00:00:00 GMT\";let _ok=!1;class CookieAdapter{constructor(storageId,persistent){const prefix=`${storageId}${persistent?\"!\":\"*\"}.`;Object.defineProperties(this,{_prefix:{value:prefix},_prefixRe:{value:new RegExp(`^${RegExp.escape(prefix)}`)},name:{value:\"cookie\"},id:{value:storageId},persistent:{value:Boolean(persistent)}})}get size(){return this.keys().length}keys(){if(\"\"===document.cookie)return[];const cookies=document.cookie.split(/;\\s*/),keys=[];for(let i=0;i<cookies.length;++i){const kvPair=cookies[i].split(\"=\"),key=decodeURIComponent(kvPair[0]);if(this._prefixRe.test(key)){\"\"!==decodeURIComponent(kvPair[1])&&keys.push(key.replace(this._prefixRe,\"\"))}}return keys}has(key){return!(\"string\"!=typeof key||!key)&&null!==CookieAdapter._getCookie(this._prefix+key)}get(key){if(\"string\"!=typeof key||!key)return null;const value=CookieAdapter._getCookie(this._prefix+key);return null===value?null:CookieAdapter._deserialize(value)}set(key,value){if(\"string\"!=typeof key||!key)return!1;try{if(CookieAdapter._setCookie(this._prefix+key,CookieAdapter._serialize(value),this.persistent?_MAX_EXPIRY:undefined),!this.has(key))throw new Error(\"unknown validation error during set\")}catch(ex){throw exceptionFrom(ex,Error,{cause:{origin:ex},message:`cookie error: ${ex.message}`})}return!0}delete(key){if(\"string\"!=typeof key||!key||!this.has(key))return!1;try{if(CookieAdapter._setCookie(this._prefix+key,undefined,_MIN_EXPIRY),this.has(key))throw new Error(\"unknown validation error during delete\")}catch(ex){throw exceptionFrom(ex,Error,{cause:{origin:ex},message:`cookie error: ${ex.message}`})}return!0}clear(){const keys=this.keys();for(let i=0,length=keys.length;i<length;++i)this.delete(keys[i]);return!0}static _getCookie(prefixedKey){if(!prefixedKey||\"\"===document.cookie)return null;const cookies=document.cookie.split(/;\\s*/);for(let i=0;i<cookies.length;++i){const kvPair=cookies[i].split(\"=\");if(prefixedKey===decodeURIComponent(kvPair[0])){return decodeURIComponent(kvPair[1])||null}}return null}static _setCookie(prefixedKey,value,expiry){if(!prefixedKey)return;let payload=`${encodeURIComponent(prefixedKey)}=`;null!=value&&(payload+=encodeURIComponent(value)),null!=expiry&&(payload+=`; expires=${expiry}`),payload+=\"; path=/\",document.cookie=payload}static _serialize(obj){return LZString.compressToBase64(Serial.stringify(obj))}static _deserialize(str){return Serial.parse(LZString.decompressFromBase64(str))}}return Object.preventExtensions(Object.create(null,{init:{value:function(storageId){try{const tid=`_sc_${String(Date.now())}`;CookieAdapter._setCookie(tid,CookieAdapter._serialize(tid),undefined),_ok=CookieAdapter._deserialize(CookieAdapter._getCookie(tid))===tid,CookieAdapter._setCookie(tid,undefined,_MIN_EXPIRY)}catch(ex){_ok=!1}return _ok&&function(storageId){if(\"\"===document.cookie)return;const oldPrefix=`${storageId}.`,oldPrefixRe=new RegExp(`^${RegExp.escape(oldPrefix)}`),persistPrefix=`${storageId}!.`,sessionPrefix=`${storageId}*.`,sessionTestRe=/\\.(?:state|rcWarn)$/,cookies=document.cookie.split(/;\\s*/);for(let i=0;i<cookies.length;++i){const kvPair=cookies[i].split(\"=\"),key=decodeURIComponent(kvPair[0]);if(oldPrefixRe.test(key)){const value=decodeURIComponent(kvPair[1]);if(\"\"!==value){const persist=!sessionTestRe.test(key);CookieAdapter._setCookie(key,undefined,_MIN_EXPIRY),CookieAdapter._setCookie(key.replace(oldPrefixRe,(()=>persist?persistPrefix:sessionPrefix)),value,persist?_MAX_EXPIRY:undefined)}}}}(storageId),_ok}},create:{value:function(storageId,persistent){if(!_ok)throw new Error(\"adapter not initialized\");return new CookieAdapter(storageId,persistent)}}}))})());var DebugView=(()=>{class DebugView{constructor(parent,type,name,title){Object.defineProperties(this,{parent:{value:parent},view:{value:document.createElement(\"span\")},break:{value:document.createElement(\"wbr\")}}),jQuery(this.view).attr({title:title,\"aria-label\":title,\"data-type\":null!=type?type:\"\",\"data-name\":null!=name?name:\"\"}).addClass(\"debug\"),jQuery(this.break).addClass(\"debug hidden\"),this.parent.appendChild(this.view),this.parent.appendChild(this.break)}get output(){return this.view}get type(){return this.view.getAttribute(\"data-type\")}set type(type){this.view.setAttribute(\"data-type\",null!=type?type:\"\")}get name(){return this.view.getAttribute(\"data-name\")}set name(name){this.view.setAttribute(\"data-name\",null!=name?name:\"\")}get title(){return this.view.title}set title(title){this.view.title=title}append(el){return jQuery(this.view).append(el),this}modes(options){if(null==options){const current={};return this.view.className.splitOrEmpty(/\\s+/).forEach((name=>{\"debug\"!==name&&(current[name]=!0)})),current}if(\"object\"==typeof options)return Object.keys(options).forEach((function(name){this[options[name]?\"addClass\":\"removeClass\"](name)}),jQuery(this.view)),this;throw new Error(\"DebugView.prototype.modes options parameter must be an object or null/undefined\")}remove(){const $view=jQuery(this.view);this.view.hasChildNodes()&&$view.contents().appendTo(this.parent),$view.remove(),jQuery(this.break).remove()}static isEnabled(){return\"enabled\"===jQuery(document.documentElement).attr(\"data-debug-view\")}static enable(){jQuery(document.documentElement).attr(\"data-debug-view\",\"enabled\"),triggerEvent(\":debugviewupdate\")}static disable(){jQuery(document.documentElement).removeAttr(\"data-debug-view\"),triggerEvent(\":debugviewupdate\")}static toggle(){DebugView.isEnabled()?DebugView.disable():DebugView.enable()}}return DebugView})(),NodeTyper=(()=>{class NodeTyper{constructor(config){if(\"object\"!=typeof config||null===config)throw new Error(`config parameter must be an object (received: ${getTypeOf(config)})`);if(!(Object.hasOwn(config,\"targetNode\")&&config.targetNode instanceof Node))throw new Error('config parameter object \"targetNode\" property must be a node');Object.defineProperties(this,{node:{value:config.targetNode},childNodes:{value:[]},nodeValue:{writable:!0,value:\"\"},appendTo:{writable:!0,value:config.parentNode||null},classNames:{writable:!0,value:config.classNames||null},finished:{writable:!0,value:!1}});const node=this.node;let childNode;for(node.nodeValue&&(this.nodeValue=node.nodeValue,node.nodeValue=\"\");null!==(childNode=node.firstChild);)this.childNodes.push(new NodeTyper({targetNode:childNode,parentNode:node,classNames:this.classNames})),node.removeChild(childNode)}finish(){for(;this.type(!0););return!1}type(flush){if(this.finished)return!1;if(this.appendTo){if(this.appendTo.appendChild(this.node),this.appendTo=null,this.node.nodeType!==Node.ELEMENT_NODE&&this.node.nodeType!==Node.TEXT_NODE||\"none\"===jQuery(this.node.parentNode).css(\"display\"))return this.finish();this.node.parentNode&&this.classNames&&jQuery(this.node.parentNode).addClass(this.classNames)}if(this.nodeValue){if(flush)this.node.nodeValue+=this.nodeValue,this.nodeValue=\"\";else{const{char:char,start:start,end:end}=charAndPosAt(this.nodeValue,0);this.node.nodeValue+=char,this.nodeValue=this.nodeValue.slice(1+end-start)}return!0}this.classNames&&(jQuery(this.node.parentNode).removeClass(this.classNames),this.classNames=null);const childNodes=this.childNodes;for(;childNodes.length>0;){if(childNodes[0].type())return!0;childNodes.shift()}return this.finished=!0,!1}}return NodeTyper})(),StyleWrapper=(()=>{const _imageMarkupRe=new RegExp(Patterns.cssImage,\"g\"),_hasImageMarkupRe=new RegExp(Patterns.cssImage);return class{constructor(style){if(null==style)throw new TypeError(\"StyleWrapper style parameter must be an HTMLStyleElement object\");Object.defineProperties(this,{style:{value:style}})}isEmpty(){return 0===this.style.cssRules.length}set(rawCss){this.clear(),this.add(rawCss)}add(rawCss){let css=rawCss;_hasImageMarkupRe.test(css)&&(_imageMarkupRe.lastIndex=0,css=css.replace(_imageMarkupRe,(wikiImage=>{const markup=Wikifier.helpers.parseSquareBracketedMarkup({source:wikiImage,matchStart:0});if(Object.hasOwn(markup,\"error\")||markup.pos<wikiImage.length)return wikiImage;let source=markup.source;if(\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);passage.tags.includes(\"Twine.image\")&&(source=passage.text.trim())}return`url(\"${source.replace(/\"/g,\"%22\")}\")`}))),this.style.styleSheet?this.style.styleSheet.cssText+=css:this.style.appendChild(document.createTextNode(css))}clear(){this.style.styleSheet?this.style.styleSheet.cssText=\"\":jQuery(this.style).empty()}}})(),Diff=(()=>{const Op=enumFrom({Delete:0,SpliceArray:1,Copy:2,CopyDate:3});function isNumeric(O){let num;switch(typeof O){case\"number\":num=O;break;case\"string\":num=Number(O);break;default:return!1}return!Number.isNaN(num)&&Number.isFinite(num)}return Object.preventExtensions(Object.create(null,{Op:{value:Op},diff:{value:function diff(a,b){const toString=Object.prototype.toString,aIsArray=a instanceof Array,delta=Object.create(null),keys=[...Object.keys(a),...Object.keys(b)].sort().filter(((val,i,arr)=>0===i||arr[i-1]!==val));let aOpKey;const isAOpKey=key=>key===aOpKey;for(let i=0,klen=keys.length;i<klen;++i){const key=keys[i],aVal=a[key],bVal=b[key];if(Object.hasOwn(a,key))if(Object.hasOwn(b,key)){if(aVal===bVal)continue;if(typeof aVal==typeof bVal)if(\"function\"==typeof aVal)aVal.toString()!==bVal.toString()&&(delta[key]=[Op.Copy,bVal]);else if(\"object\"!=typeof aVal||null===aVal)delta[key]=[Op.Copy,bVal];else{const aValType=toString.call(aVal);if(aValType===toString.call(bVal))if(aVal instanceof Date)aVal.getTime()!==bVal.getTime()&&(delta[key]=[Op.Copy,clone(bVal)]);else if(aVal instanceof Map)delta[key]=[Op.Copy,clone(bVal)];else if(aVal instanceof RegExp)aVal.toString()!==bVal.toString()&&(delta[key]=[Op.Copy,clone(bVal)]);else if(aVal instanceof Set)delta[key]=[Op.Copy,clone(bVal)];else if(aVal instanceof Array||\"[object Object]\"===aValType){const subDelta=diff(aVal,bVal);null!==subDelta&&(delta[key]=subDelta)}else delta[key]=[Op.Copy,clone(bVal)];else delta[key]=[Op.Copy,clone(bVal)]}else delta[key]=[Op.Copy,\"object\"!=typeof bVal||null===bVal?bVal:clone(bVal)]}else if(aIsArray&&isNumeric(key)){const index=Number(key);if(!aOpKey){aOpKey=\"\";do{aOpKey+=\"~\"}while(keys.some(isAOpKey));delta[aOpKey]=[Op.SpliceArray,index,index]}index<delta[aOpKey][1]&&(delta[aOpKey][1]=index),index>delta[aOpKey][2]&&(delta[aOpKey][2]=index)}else delta[key]=Op.Delete;else delta[key]=[Op.Copy,\"object\"!=typeof bVal||null===bVal?bVal:clone(bVal)]}return Object.keys(delta).length>0?delta:null}},patch:{value:function patch(orig,delta){const keys=delta?Object.keys(delta):[],patched=clone(orig);for(let i=0,klen=keys.length;i<klen;++i){const key=keys[i],value=delta[key];if(value===Op.Delete)delete patched[key];else if(value instanceof Array)switch(value[0]){case Op.SpliceArray:patched.splice(value[1],value[2]-value[1]+1);break;case Op.Copy:patched[key]=clone(value[1]);break;case Op.CopyDate:patched[key]=new Date(value[1])}else patched[key]=patch(patched[key],value)}return patched}}}))})(),L10n=(()=>{const replaceRE=/\\{\\w+\\}/g,hasReplaceRE=new RegExp(replaceRE.source);return Object.preventExtensions(Object.create(null,{init:{value:function(){}},get:{value:function(ids,overrides){if(!ids)return\"\";const id=(Array.isArray(ids)?ids:[ids]).find((id=>Object.hasOwn(l10nStrings,id)));if(!id)return\"\";let value=l10nStrings[id],i=0;for(;hasReplaceRE.test(value);){if(++i>50)throw new Error(\"L10n.get exceeded maximum replacement depth, probable infinite loop\");replaceRE.lastIndex=0,value=value.replace(replaceRE,(replacement=>{const rid=replacement.slice(1,-1);return overrides&&Object.hasOwn(overrides,rid)?overrides[rid]:Object.hasOwn(l10nStrings,rid)?l10nStrings[rid]:void 0}))}return value}}}))})(),l10nStrings={textAbort:\"Abort\",textAborting:\"Aborting\",textCancel:\"Cancel\",textClear:\"Clear\",textClose:\"Close\",textDelete:\"Delete\",textExport:\"Export\",textIdentity:\"game\",textImport:\"Import\",textLoad:\"Load\",textOff:\"Off\",textOk:\"OK\",textOn:\"On\",textSave:\"Save\",textTurn:\"Turn\",savesEnableIdb:\"Enable indexedDB\",savesDisallowedReplay:\"The scene viewer is currently in use, preventing the use of the save system.\",savesExportReminder:\"Warning: If your browser cache is cleared, saves here will be lost! Consider saving to file every so often!\",savesHeaderSaveLoad:\"Save/Load\",savesHeaderIDName:\"ID/Name\",savesHeaderDetails:\"Details\",savesDescTitle:\"Title:\",savesDescName:\"Save Name:\",savesDescId:\"Save Id:\",savesDescDate:\"Date:\",savesPagerJump:\"Jump to most recent manual save\",savesPagerPage:\"Page:\",savesPagerSavesPerPage:\"Saves per page:\",savesOptionsConfirmOn:\"Require confirmation on:\",savesOptionsOverwrite:\"Overwrite\",savesOptionsUseLegacy:\"Switch to legacy save storage\",savesWarningSaveOnSlot:\"Save on slot\",savesWarningOverwriteSlot:\"Overwrite save in slot\",savesWarningOverwriteID:\"Save ID does not match, continue with overwrite?\",savesWarningDeleteInSlot:\"Delete save in slot\",savesWarningLoad:\"Load slot\",savesWarningDeleteAll:\"WARNING - DO YOU REALLY WANT TO DELETE ALL SAVES?\",errorNonexistentPassage:'the passage \"{passage}\" does not exist',warningNoStorage:\"All usable storage APIs are missing. Possible causes are a disabled third-party cookie setting, which also affects Web Storage, or a private browsing mode.\",warningNoWebStorage:\"The Web Storage API is missing, so this {textIdentity} is running in a degraded mode. You may be able to continue, however, some parts may not work properly.\",warningDegraded:\"Some capabilities required to support this {textIdentity} are missing, so it is running in a degraded mode. You may be able to continue, however, some parts may not work properly.\",warningNoSaves:\"Some capabilities required to support saves are missing, so saves have been disabled for this session.\",saveErrorDisallowed:\"Saving is currently disallowed.\",saveErrorDecodeFail:\"unable to decode save, likely due to corruption\",saveErrorDiskLoadFail:\"failed to load save file from disk\",saveErrorIdMismatch:\"save is from the wrong {textIdentity}\",saveErrorInvalidData:\"save is missing required data, likely due to corruption\",saveErrorLoadTooEarly:\"cannot load save this early\",saveErrorNonexistent:\"save does not exist\",uiBarLabelToggle:\"Toggle the UI bar\",uiBarLabelBackward:\"Go backward within the {textIdentity} history\",uiBarLabelForward:\"Go forward within the {textIdentity} history\",uiBarLabelJumpto:\"Jump to a specific point within the {textIdentity} history\",alertTitle:\"Alert\",restartTitle:\"Restart\",restartMesgPrompt:\"All unsaved progress will be lost. Are you sure that you want to restart?\",continueTitle:\"Continue\",savesTitle:\"Saves\",savesHeaderBrowser:\"In Browser\",savesHeaderDisk:\"On Disk\",savesLabelBrowserClear:\"Clear all browser saves\",savesLabelBrowserExport:\"Export browser saves to bundle\",savesLabelBrowserImport:\"Import browser saves from bundle\",savesLabelDiskLoad:\"Load from disk\",savesLabelDiskSave:\"Save to disk\",savesLabelToClipboard:\"Save to Clipboard\",savesTextBrowserAuto:\"Auto\",savesTextBrowserSlot:\"Slot\",savesTextNoDate:\"unknown date\",settingsTitle:\"Settings\",settingsTextReset:\"Reset to Defaults\",errorViewTitle:\"Error\",errorViewLabelToggle:\"Toggle the error view\",debugBarLabelToggle:\"Toggle the debug bar\",debugBarLabelViewsToggle:\"Toggle the debug views\",debugBarLabelWatchAdd:\"Add a new watch\",debugBarLabelWatchAll:\"Watch all\",debugBarLabelWatchClear:\"Clear all watches\",debugBarLabelWatchDelete:\"Delete this watch\",debugBarLabelWatchPlaceholder:\"variable name\",debugBarLabelPassagePlaceholder:\"passage name\",debugBarLabelPassagePlay:\"Play passage\",debugBarLabelWatchToggle:\"Toggle the watch panel\",debugBarMesgNoWatches:\"No watches set\",debugBarTextAdd:\"Add\",debugBarTextPassage:\"Passage\",debugBarTextViews:\"Views\",debugBarTextWatch:\"Watch\",macroBackText:\"Back\",macroReturnText:\"Return\",autoloadTitle:\"Autoload\",autoloadMesgPrompt:\"An autosave exists. Load it now or go to the start?\",autoloadTextCancel:\"Go to start\",autoloadTextOk:\"Load autosave\",jumptoTitle:\"Jump To\",jumptoMesgUnavailable:\"No jump points currently available…\",shareTitle:\"Share\"},Config=(()=>{let _navigationOverride,_passagesStart,_passagesOnProcess,_passagesTransitionOut,_savesDescriptions,_savesId,_savesIsAllowed,_savesMetadata,_savesVersion,_savesAutoload,_addVisitedLinkClass=!1,_cleanupWikifierOutput=!1,_debug=!1,_enableOptionalDebugging=!1,_loadDelay=0,_audioPauseOnFadeToZero=!0,_audioPreloadMetadata=!0,_historyControls=!0,_historyMaxStates=40,_macrosMaxLoopIterations=1e3,_macrosTypeSkipKey=\" \",_macrosTypeVisitedPassages=!0,_passagesDisplayTitles=!1,_passagesNobr=!1,_savesMaxAuto=0,_savesMaxSlot=8,_uiStowBarInitially=800,_uiUpdateStoryElements=!0;const errPassagesDescriptionsDeprecated=\"[DEPRECATED] Config.passages.descriptions has been deprecated, see Config.saves.descriptions instead\",errSavesAutoloadDeprecated=\"[DEPRECATED] Config.saves.autoload has been deprecated, see the Save.browser.continue API instead\",_baseSavesAutosaveDeprecated=\"[DEPRECATED] Config.saves.autosave has been deprecated\",errSavesOnLoadDeprecated=\"[DEPRECATED] Config.saves.onLoad has been deprecated, see the Save.onLoad API instead\",errSavesOnSaveDeprecated=\"[DEPRECATED] Config.saves.onSave has been deprecated, see the Save.onSave API instead\",errSavesSlotsDeprecated=\"[DEPRECATED] Config.saves.slots has been deprecated, see Config.saves.maxSlotSaves instead\";return Object.freeze({get addVisitedLinkClass(){return _addVisitedLinkClass},set addVisitedLinkClass(value){_addVisitedLinkClass=Boolean(value)},get cleanupWikifierOutput(){return _cleanupWikifierOutput},set cleanupWikifierOutput(value){_cleanupWikifierOutput=Boolean(value)},get debug(){return _debug},set debug(value){_debug=Boolean(value)},get enableOptionalDebugging(){return _enableOptionalDebugging},set enableOptionalDebugging(value){_enableOptionalDebugging=Boolean(value)},get loadDelay(){return _loadDelay},set loadDelay(value){if(!Number.isSafeInteger(value)||value<0)throw new RangeError(\"Config.loadDelay must be a non-negative integer\");_loadDelay=value},audio:Object.freeze({get pauseOnFadeToZero(){return _audioPauseOnFadeToZero},set pauseOnFadeToZero(value){_audioPauseOnFadeToZero=Boolean(value)},get preloadMetadata(){return _audioPreloadMetadata},set preloadMetadata(value){_audioPreloadMetadata=Boolean(value)}}),history:Object.freeze({get controls(){return _historyControls},set controls(value){const controls=Boolean(value);if(1===_historyMaxStates&&controls)throw new Error(\"Config.history.controls must be false when Config.history.maxStates is 1\");_historyControls=controls},get maxStates(){return _historyMaxStates},set maxStates(value){if(!Number.isSafeInteger(value)||value<1)throw new RangeError(\"Config.history.maxStates must be a positive integer\");_historyMaxStates=value,_historyControls&&1===value&&(_historyControls=!1)}}),macros:Object.freeze({get maxLoopIterations(){return _macrosMaxLoopIterations},set maxLoopIterations(value){if(!Number.isSafeInteger(value)||value<1)throw new RangeError(\"Config.macros.maxLoopIterations must be a positive integer\");_macrosMaxLoopIterations=value},get typeSkipKey(){return _macrosTypeSkipKey},set typeSkipKey(value){_macrosTypeSkipKey=String(value)},get typeVisitedPassages(){return _macrosTypeVisitedPassages},set typeVisitedPassages(value){_macrosTypeVisitedPassages=Boolean(value)},get ifAssignmentError(){throw new Error(\"[DEPRECATED] Config.macros.ifAssignmentError has been deprecated, see Config.enableOptionalDebugging instead\")},set ifAssignmentError(value){console.warn(\"[DEPRECATED] Config.macros.ifAssignmentError has been deprecated, see Config.enableOptionalDebugging instead\"),Config.enableOptionalDebugging=value}}),navigation:Object.freeze({get override(){return _navigationOverride},set override(value){if(!(null==value||value instanceof Function))throw new TypeError(`Config.navigation.override must be a function or null/undefined (received: ${getTypeOf(value)})`);_navigationOverride=value}}),passages:Object.freeze({get displayTitles(){return _passagesDisplayTitles},set displayTitles(value){_passagesDisplayTitles=Boolean(value)},get nobr(){return _passagesNobr},set nobr(value){_passagesNobr=Boolean(value)},get onProcess(){return _passagesOnProcess},set onProcess(value){if(null!=value){const valueType=getTypeOf(value);if(\"function\"!==valueType)throw new TypeError(`Config.passages.onProcess must be a function or null/undefined (received: ${valueType})`)}_passagesOnProcess=value},get start(){return _passagesStart},set start(value){if(null!=value){const valueType=getTypeOf(value);if(\"string\"!==valueType)throw new TypeError(`Config.passages.start must be a string or null/undefined (received: ${valueType})`)}_passagesStart=value},get transitionOut(){return _passagesTransitionOut},set transitionOut(value){if(null!=value){const valueType=getTypeOf(value);if(\"string\"!==valueType&&(\"number\"!==valueType||!Number.isSafeInteger(value)||value<0))throw new TypeError(`Config.passages.transitionOut must be a string, non-negative integer, or null/undefined (received: ${valueType})`)}_passagesTransitionOut=value},get descriptions(){throw new Error(errPassagesDescriptionsDeprecated)},set descriptions(value){switch(console.warn(errPassagesDescriptionsDeprecated),typeof value){case\"boolean\":value&&!Config.saves.descriptions&&(Config.saves.descriptions=function(){return State.passage});break;case\"function\":Config.saves.descriptions||(Config.saves.descriptions=value);break;case\"undefined\":case\"object\":if(value&&!Config.saves.descriptions){const dict=value;Config.saves.descriptions=function(){return Object.hasOwn(dict,State.passage)&&dict[State.passage]}}break;default:throw new TypeError(`Config.passages.descriptions must be a boolean, object, function, or null/undefined (received: ${getTypeOf(value)})`)}}}),saves:Object.freeze({get descriptions(){return _savesDescriptions},set descriptions(value){if(!(null==value||value instanceof Function))throw new TypeError(`Config.saves.descriptions must be a function or null/undefined (received: ${getTypeOf(value)})`);_savesDescriptions=value},get id(){return _savesId},set id(value){if(\"string\"!=typeof value||\"\"===value)throw new TypeError(`Config.saves.id must be a non-empty string (received: ${getTypeOf(value)})`);_savesId=value},get isAllowed(){return _savesIsAllowed},set isAllowed(value){if(!(null==value||value instanceof Function))throw new TypeError(`Config.saves.isAllowed must be a function or null/undefined (received: ${getTypeOf(value)})`);_savesIsAllowed=value},get maxAutoSaves(){return _savesMaxAuto},set maxAutoSaves(value){if(!Number.isInteger(value))throw new TypeError(\"Config.saves.maxAutoSaves must be an integer\");if(value<0||value>Save.MAX_INDEX+1)throw new RangeError(`Config.saves.maxAutoSaves out of bounds (range: 0–${Save.MAX_INDEX+1}; received: ${value})`);_savesMaxAuto=value},get maxSlotSaves(){return _savesMaxSlot},set maxSlotSaves(value){if(!Number.isInteger(value))throw new TypeError(\"Config.saves.maxSlotSaves must be an integer\");if(value<0||value>Save.MAX_INDEX+1)throw new RangeError(`Config.saves.maxSlotSaves out of bounds (range: 0–${Save.MAX_INDEX+1}; received: ${value})`);_savesMaxSlot=value},get metadata(){return _savesMetadata},set metadata(value){if(!(null==value||value instanceof Function))throw new TypeError(`Config.saves.metadata must be a function or null/undefined (received: ${getTypeOf(value)})`);_savesMetadata=value},get version(){return _savesVersion},set version(value){_savesVersion=value},get _internal_autoload_(){return _savesAutoload},get autoload(){return console.warn(errSavesAutoloadDeprecated),_savesAutoload},set autoload(value){if(console.warn(errSavesAutoloadDeprecated),null!=value){const valueType=getTypeOf(value);if(\"boolean\"!==valueType&&(\"string\"!==valueType||\"prompt\"!==value)&&\"function\"!==valueType)throw new TypeError(`Config.saves.autoload must be a boolean, string ('prompt'), function, or null/undefined (received: ${valueType})`)}_savesAutoload=value},get autosave(){throw new Error(`${_baseSavesAutosaveDeprecated}, see Config.saves.maxAutoSaves and Config.saves.isAllowed instead`)},set autosave(value){switch(typeof value){case\"boolean\":console.warn(`${_baseSavesAutosaveDeprecated}, for boolean usage see Config.saves.maxAutoSaves instead`);break;case\"function\":if(console.warn(`${_baseSavesAutosaveDeprecated}, for function usage see Config.saves.isAllowed instead`),!Config.saves.isAllowed){const callback=value;Config.saves.isAllowed=function(saveType){return saveType!==Save.Type.Auto||callback(saveType)}}break;default:if(console.warn(`${_baseSavesAutosaveDeprecated}, for tag usage see Config.saves.isAllowed instead`),!(value instanceof Array)||0===value.length||value.some((tag=>\"string\"!=typeof tag))){const valueType=getTypeOf(value);throw new TypeError(`Config.saves.autosave must be a boolean, Array<string>, function, or null/undefined (received: ${valueType}${\"Array\"===valueType?\"<any>\":\"\"})`)}if(!Config.saves.isAllowed){const userTags=value;Config.saves.isAllowed=function(saveType){return saveType!==Save.Type.Auto||userTags.includesAny(Story.get(State.passage).tags)}}}0===Config.saves.maxAutoSaves&&(Config.saves.maxAutoSaves=1)},get onLoad(){throw new Error(errSavesOnLoadDeprecated)},set onLoad(value){console.warn(errSavesOnLoadDeprecated),Save.onLoad.add(value)},get onSave(){throw new Error(errSavesOnSaveDeprecated)},set onSave(value){console.warn(errSavesOnSaveDeprecated),Save.onSave.add(value)},get slots(){throw new Error(errSavesSlotsDeprecated)},set slots(value){console.warn(errSavesSlotsDeprecated),Config.saves.maxSlotSaves=value},get tryDiskOnMobile(){return console.warn(\"[DEPRECATED] Config.saves.tryDiskOnMobile has been deprecated\"),!0},set tryDiskOnMobile(value){console.warn(\"[DEPRECATED] Config.saves.tryDiskOnMobile has been deprecated\")}}),ui:Object.freeze({get stowBarInitially(){return _uiStowBarInitially},set stowBarInitially(value){const valueType=getTypeOf(value);if(\"boolean\"!==valueType&&(\"number\"!==valueType||!Number.isSafeInteger(value)||value<0))throw new TypeError(`Config.ui.stowBarInitially must be a boolean or non-negative integer (received: ${valueType})`);_uiStowBarInitially=value},get updateStoryElements(){return _uiUpdateStoryElements},set updateStoryElements(value){_uiUpdateStoryElements=Boolean(value)}})})})(),SimpleAudio=(()=>{const _specialIds=Object.freeze([\":not\",\":all\",\":looped\",\":muted\",\":paused\",\":playing\",\":stopped\"]),_formatSpecRe=/^([\\w-]+)\\s*\\|\\s*(\\S.*)$/,_badIdRe=/[:\\s]/,_tracks=new Map,_groups=new Map,_lists=new Map,_subscribers=new Map;let _masterRate=1,_masterVolume=1,_masterMute=!1,_masterMuteOnHidden=!1;const _playReturnsPromise=function(){let _hasPromise=null;return function(){if(null!==_hasPromise)return _hasPromise;if(_hasPromise=!1,Has.audio)try{const audio=document.createElement(\"audio\");audio.muted=!0;const value=audio.play();value.catch((()=>{})),_hasPromise=value instanceof Promise}catch(ex){}return _hasPromise}}();class AudioTrack{constructor(obj){if(obj instanceof Array)this._create(obj);else{if(!(obj instanceof AudioTrack))throw new Error(\"sources parameter must be either an array, of URIs or source objects, or an AudioTrack instance\");this._copy(obj)}}_create(sourceList){const dataUriRe=/^data:\\s*audio\\/(?:x-)?([^;,]+)\\s*[;,]/i,extRe=/\\.([^./\\\\]+)$/,formats=AudioTrack.formats,usedSources=[],audio=document.createElement(\"audio\");audio.preload=\"none\",sourceList.forEach((src=>{let srcUri=null;switch(typeof src){case\"string\":{let match;if(\"data:\"===src.slice(0,5)){if(match=dataUriRe.exec(src),null===match)throw new Error(\"source data URI missing media type\")}else if(match=extRe.exec(parseURL(src).pathname),null===match)throw new Error(\"source URL missing file extension\");formats[match[1]]&&(srcUri=src);break}case\"object\":if(null===src)throw new Error(\"source object cannot be null\");if(!Object.hasOwn(src,\"src\"))throw new Error('source object missing required \"src\" property');if(!Object.hasOwn(src,\"format\"))throw new Error('source object missing required \"format\" property');formats[src.format]&&(srcUri=src.src);break;default:throw new Error(`invalid source value (type: ${typeof src})`)}if(null!==srcUri){const source=document.createElement(\"source\");source.src=srcUri,audio.appendChild(source),usedSources.push(srcUri)}})),audio.hasChildNodes()&&Config.audio.preloadMetadata&&(audio.preload=\"metadata\"),this._finalize(audio,usedSources,clone(sourceList))}_copy(obj){this._finalize(obj.audio.cloneNode(!0),clone(obj.sources),clone(obj.originals))}_finalize(audio,sources,originals){Object.defineProperties(this,{audio:{configurable:!0,value:audio},sources:{value:Object.freeze(sources)},originals:{value:Object.freeze(originals)},_error:{writable:!0,value:!1},_faderId:{writable:!0,value:null},_mute:{writable:!0,value:!1},_rate:{writable:!0,value:1},_volume:{writable:!0,value:1}}),jQuery(this.audio).on(\"loadstart.AudioTrack\",(()=>this._error=!1)).on(\"error.AudioTrack\",(()=>this._error=!0)).find(\"source:last-of-type\").on(\"error.AudioTrack\",(()=>this._trigger(\"error\"))),function(id,callback){if(\"function\"!=typeof callback)throw new Error(\"callback parameter must be a function\");_subscribers.set(id,callback)}(this,(mesg=>{if(this.audio)switch(mesg){case\"loadwithscreen\":if(this.hasSource()){const lockId=LoadScreen.lock();this.off(\".AudioTrack_loadwithscreen\").one(\"canplaythrough.AudioTrack_loadwithscreen error.AudioTrack_loadwithscreen\",(function(){jQuery(this).off(\".AudioTrack_loadwithscreen\"),LoadScreen.unlock(lockId)})).load()}break;case\"load\":this.load();break;case\"mute\":this._updateAudioMute();break;case\"rate\":this._updateAudioRate();break;case\"stop\":this.stop();break;case\"volume\":this._updateAudioVolume();break;case\"unload\":this.unload()}else unsubscribe(this)})),this._updateAudioMute(),this._updateAudioRate(),this._updateAudioVolume()}_trigger(eventName){triggerEvent(eventName,this.audio,{bubbles:!1})}_destroy(){unsubscribe(this),this.audio&&(jQuery(this.audio).off(),this.unload(),this._error=!0,delete this.audio)}clone(){return new AudioTrack(this)}load(){if(this.fadeStop(),this.audio.pause(),!this.audio.hasChildNodes()){if(0===this.sources.length)return;this.sources.forEach((srcUri=>{const source=document.createElement(\"source\");source.src=srcUri,this.audio.appendChild(source)}))}\"auto\"!==this.audio.preload&&(this.audio.preload=\"auto\"),this.isLoading()||this.audio.load()}unload(){this.fadeStop(),this.stop();const audio=this.audio;for(audio.preload=\"none\";audio.hasChildNodes();)audio.removeChild(audio.firstChild);audio.load()}play(){if(!this.hasSource())return Promise.reject(new Error(\"none of the candidate sources were acceptable\"));if(this.isUnloaded())return Promise.reject(new Error(\"no sources are loaded\"));if(this.isFailed())return Promise.reject(new Error(\"failed to load any of the sources\"));\"auto\"!==this.audio.preload&&(this.audio.preload=\"auto\");const namespace=\".AudioTrack_play\";return _playReturnsPromise()?this.audio.play():new Promise(((resolve,reject)=>{this.isPlaying()?resolve():(jQuery(this.audio).off(namespace).one(`error${namespace} playing${namespace} timeupdate${namespace}`,(ev=>{jQuery(this.audio).off(namespace),\"error\"===ev.type?reject(new Error(\"unknown audio play error\")):resolve()})),this.audio.play())}))}playWhenAllowed(){return this.play().catch((ex=>{if(\"NotAllowedError\"!==ex.name)throw ex;onUserActivation(\".AudioTrack_playWhenAllowed\",(()=>this.audio.play()))}))}pause(){this.audio.pause()}stop(){this.audio.pause(),this.time(0),this._trigger(\":stopped\")}fade(duration,toVol,fromVol){if(\"number\"!=typeof duration)throw new TypeError(\"duration parameter must be a number\");if(\"number\"!=typeof toVol)throw new TypeError(\"toVolume parameter must be a number\");if(null!=fromVol&&\"number\"!=typeof fromVol)throw new TypeError(\"fromVolume parameter must be a number\");if(!this.hasSource())return Promise.reject(new Error(\"none of the candidate sources were acceptable\"));if(this.isUnloaded())return Promise.reject(new Error(\"no sources are loaded\"));if(this.isFailed())return Promise.reject(new Error(\"failed to load any of the sources\"));this.fadeStop();const from=Math.clamp(null==fromVol?this.volume():fromVol,0,1),to=Math.clamp(toVol,0,1);return from!==to?(this.volume(from),jQuery(this.audio).off(\"timeupdate.AudioTrack_fade\").one(\"timeupdate.AudioTrack_fade\",(()=>{let min,max;from<to?(min=from,max=to):(min=to,max=from);const time=Math.max(duration,1),delta=(to-from)/(time/.025);this._trigger(\":fading\"),this._faderId=setInterval((()=>{this.isPlaying()?(this.volume(Math.clamp(this.volume()+delta,min,max)),Config.audio.pauseOnFadeToZero&&0===this.volume()&&this.pause(),this.volume()===to&&(this.fadeStop(),this._trigger(\":faded\"))):this.fadeStop()}),25)})),this.play()):void 0}fadeIn(duration,fromVol){return this.fade(duration,1,fromVol)}fadeOut(duration,fromVol){return this.fade(duration,0,fromVol)}fadeStop(){null!==this._faderId&&(clearInterval(this._faderId),this._faderId=null)}loop(loop){return null==loop?this.audio.loop:(this.audio.loop=!!loop,this)}mute(mute){return null==mute?this._mute:(this._mute=!!mute,this._updateAudioMute(),this)}_updateAudioMute(){this.audio.muted=this._mute||_masterMute}rate(rate){if(null==rate)return this._rate;if(\"number\"!=typeof rate)throw new TypeError(\"rate parameter must be a number\");return this._rate=Math.clamp(rate,.2,5),this._updateAudioRate(),this}_updateAudioRate(){this.audio.playbackRate=Math.clamp(this._rate*_masterRate,.2,5)}time(time){if(null==time)return this.audio.currentTime;if(\"number\"!=typeof time)throw new TypeError(\"time parameter must be a number\");return this.hasMetadata()?this.audio.currentTime=time:jQuery(this.audio).off(\"loadedmetadata.AudioTrack_time\").one(\"loadedmetadata.AudioTrack_time\",(()=>this.audio.currentTime=time)),this}volume(volume){if(null==volume)return this._volume;if(\"number\"!=typeof volume)throw new TypeError(\"volume parameter must be a number\");return this._volume=Math.clamp(volume,0,1),this._updateAudioVolume(),this}_updateAudioVolume(){this.audio.volume=Math.clamp(this._volume*_masterVolume,0,1)}duration(){return this.audio.duration}remaining(){return this.audio.duration-this.audio.currentTime}isFailed(){return this._error}isLoading(){return this.audio.networkState===HTMLMediaElement.NETWORK_LOADING}isUnloaded(){return!this.audio.hasChildNodes()}isUnavailable(){return!this.hasSource()||this.isUnloaded()||this.isFailed()}isPlaying(){return!this.audio.paused&&this.hasSomeData()}isPaused(){return this.audio.paused&&(this.audio.duration===1/0||this.audio.currentTime>0)&&!this.audio.ended}isStopped(){return this.audio.paused&&0===this.audio.currentTime}isEnded(){return this.audio.ended}isFading(){return null!==this._faderId}isSeeking(){return this.audio.seeking}hasSource(){return this.sources.length>0}hasNoData(){return this.audio.readyState===HTMLMediaElement.HAVE_NOTHING}hasMetadata(){return this.audio.readyState>=HTMLMediaElement.HAVE_METADATA}hasSomeData(){return this.audio.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA}hasData(){return this.audio.readyState===HTMLMediaElement.HAVE_ENOUGH_DATA}on(...args){return jQuery.fn.on.apply(jQuery(this.audio),args),this}one(...args){return jQuery.fn.one.apply(jQuery(this.audio),args),this}off(...args){return jQuery.fn.off.apply(jQuery(this.audio),args),this}}Object.defineProperties(AudioTrack,{formats:{value:(()=>{const audio=document.createElement(\"audio\"),types=new Map;function canPlay(mimeType){return types.has(mimeType)||types.set(mimeType,\"\"!==audio.canPlayType(mimeType).replace(/^no$/i,\"\")),types.get(mimeType)}return Object.assign(Object.create(null),{aac:canPlay(\"audio/aac\"),caf:canPlay(\"audio/x-caf\")||canPlay(\"audio/caf\"),flac:canPlay(\"audio/x-flac\")||canPlay(\"audio/flac\"),mp3:canPlay('audio/mpeg; codecs=\"mp3\"')||canPlay(\"audio/mpeg\")||canPlay(\"audio/mp3\")||canPlay(\"audio/mpa\"),mpeg:canPlay(\"audio/mpeg\"),m4a:canPlay(\"audio/x-m4a\")||canPlay(\"audio/m4a\")||canPlay(\"audio/aac\"),mp4:canPlay(\"audio/x-mp4\")||canPlay(\"audio/mp4\")||canPlay(\"audio/aac\"),ogg:canPlay(\"audio/ogg\"),oga:canPlay(\"audio/ogg\"),opus:canPlay('audio/ogg; codecs=\"opus\"')||canPlay(\"audio/opus\"),wav:canPlay('audio/wave; codecs=\"1\"')||canPlay('audio/wav; codecs=\"1\"')||canPlay(\"audio/wave\")||canPlay(\"audio/wav\"),wave:canPlay('audio/wave; codecs=\"1\"')||canPlay('audio/wav; codecs=\"1\"')||canPlay(\"audio/wave\")||canPlay(\"audio/wav\"),weba:canPlay(\"audio/webm\"),webm:canPlay(\"audio/webm\")})})()}});class AudioList{constructor(obj){if(obj instanceof Array)this._create(obj);else{if(!(obj instanceof AudioList))throw new Error(\"tracks parameter must be either an array, of track objects, or an AudioTrack instance\");this._copy(obj)}}_create(trackList){this._finalize(trackList.map((trackObj=>{if(\"object\"!=typeof trackObj)throw new Error(\"tracks parameter array members must be objects\");let own,rate,track,volume;if(trackObj instanceof AudioTrack)own=!0,rate=trackObj.rate(),track=trackObj.clone(),volume=trackObj.volume();else{if(!Object.hasOwn(trackObj,\"track\"))throw new Error('track object missing required \"track\" property');if(!(trackObj.track instanceof AudioTrack))throw new Error('track object\\'s \"track\" property must be an AudioTrack object');own=Object.hasOwn(trackObj,\"own\")&&trackObj.own,rate=Object.hasOwn(trackObj,\"rate\")?trackObj.rate:trackObj.track.rate(),track=trackObj.track,volume=Object.hasOwn(trackObj,\"volume\")?trackObj.volume:trackObj.track.volume()}return track.stop(),track.loop(!1),track.mute(!1),track.rate(rate),track.volume(volume),track.on(\"ended.AudioList\",(()=>this._onEnd())),{own:own,track:track,volume:volume,rate:rate}})))}_copy(obj){this._finalize(clone(obj.tracks))}_finalize(tracks){Object.defineProperties(this,{tracks:{configurable:!0,value:Object.freeze(tracks)},queue:{configurable:!0,value:[]},current:{writable:!0,value:null},_rate:{writable:!0,value:1},_volume:{writable:!0,value:1},_mute:{writable:!0,value:!1},_loop:{writable:!0,value:!1},_shuffle:{writable:!0,value:!1}})}_destroy(){this.stop(),this.tracks.filter((trackObj=>trackObj.own)).forEach((trackObj=>trackObj.track._destroy())),delete this.tracks,delete this.queue}load(){this.tracks.forEach((trackObj=>trackObj.track.load()))}unload(){this.stop(),this.tracks.forEach((trackObj=>trackObj.track.unload()))}play(){return null!==this.current&&!this.current.track.isUnavailable()&&!this.current.track.isEnded()||(0===this.queue.length&&this._fillQueue(),this._next())?this.current.track.play():Promise.reject(new Error(\"no tracks were available\"))}playWhenAllowed(){return this.play().catch((ex=>{if(\"NotAllowedError\"!==ex.name)throw ex;onUserActivation(\".AudioList_playWhenAllowed\",(()=>this.play()))}))}pause(){null!==this.current&&this.current.track.pause()}stop(){null!==this.current&&(this.current.track.stop(),this.current=null),this._drainQueue()}skip(){this._next()?this.current.track.play():this._loop&&this.play()}fade(duration,toVol,fromVol){if(\"number\"!=typeof duration)throw new TypeError(\"duration parameter must be a number\");if(\"number\"!=typeof toVol)throw new TypeError(\"toVolume parameter must be a number\");if(null!=fromVol&&\"number\"!=typeof fromVol)throw new TypeError(\"fromVolume parameter must be a number\");if(0===this.queue.length&&this._fillQueue(),(null===this.current||this.current.track.isUnavailable()||this.current.track.isEnded())&&!this._next())return;const adjToVol=Math.clamp(toVol,0,1)*this.current.volume;let adjFromVol;return null!=fromVol&&(adjFromVol=Math.clamp(fromVol,0,1)*this.current.volume),this._volume=toVol,this.current.track.fade(duration,adjToVol,adjFromVol)}fadeIn(duration,fromVol){return this.fade(duration,1,fromVol)}fadeOut(duration,fromVol){return this.fade(duration,0,fromVol)}fadeStop(){null!==this.current&&this.current.track.fadeStop()}loop(loop){return null==loop?this._loop:(this._loop=!!loop,this)}mute(mute){return null==mute?this._mute:(this._mute=!!mute,null!==this.current&&this.current.track.mute(this._mute),this)}rate(rate){if(null==rate)return this._rate;if(\"number\"!=typeof rate)throw new TypeError(\"rate parameter must be a number\");return this._rate=Math.clamp(rate,.2,5),null!==this.current&&this.current.track.rate(this._rate*this.current.rate),this}shuffle(shuffle){if(null==shuffle)return this._shuffle;if(this._shuffle=!!shuffle,this.queue.length>0&&(this._fillQueue(),!this._shuffle&&null!==this.current&&this.queue.length>1)){const firstIndex=this.queue.findIndex((trackObj=>trackObj===this.current));-1!==firstIndex&&this.queue.push(...this.queue.splice(0,firstIndex+1))}return this}volume(volume){if(null==volume)return this._volume;if(\"number\"!=typeof volume)throw new TypeError(\"volume parameter must be a number\");return this._volume=Math.clamp(volume,0,1),null!==this.current&&this.current.track.volume(this._volume*this.current.volume),this}duration(){if(arguments.length>0)throw new Error(\"duration takes no parameters\");return this.tracks.map((trackObj=>trackObj.track.duration())).reduce(((prev,cur)=>prev+cur),0)}remaining(){if(arguments.length>0)throw new Error(\"remaining takes no parameters\");let remainingTime=this.queue.map((trackObj=>trackObj.track.duration())).reduce(((prev,cur)=>prev+cur),0);return null!==this.current&&(remainingTime+=this.current.track.remaining()),remainingTime}time(){if(arguments.length>0)throw new Error(\"time takes no parameters\");return this.duration()-this.remaining()}isPlaying(){return null!==this.current&&this.current.track.isPlaying()}isPaused(){return null===this.current||this.current.track.isPaused()}isStopped(){return 0===this.queue.length&&null===this.current}isEnded(){return 0===this.queue.length&&(null===this.current||this.current.track.isEnded())}isFading(){return null!==this.current&&this.current.track.isFading()}_next(){let nextTrack;for(null!==this.current&&(this.current.track.stop(),this.current=null);nextTrack=this.queue.shift();)if(!nextTrack.track.isUnavailable()){this.current=nextTrack;break}return null!==this.current&&(this.current.track.mute(this._mute),this.current.track.rate(this._rate*this.current.rate),this.current.track.volume(this._volume*this.current.volume),this.current.track.loop(!1),!0)}_onEnd(){if(0===this.queue.length){if(!this._loop)return;this._fillQueue()}this._next()&&this.current.track.play()}_drainQueue(){this.queue.splice(0)}_fillQueue(){this._drainQueue(),this.queue.push(...this.tracks.filter((trackObj=>!trackObj.track.isUnavailable()))),0!==this.queue.length&&this._shuffle&&(this.queue.shuffle(),this.queue.length>1&&this.queue[0]===this.current&&this.queue.push(this.queue.shift()))}}class AudioRunner{constructor(list){if(!(list instanceof Set||list instanceof AudioRunner))throw new TypeError(\"list parameter must be a Set or a AudioRunner instance\");Object.defineProperties(this,{trackIds:{value:new Set(list instanceof AudioRunner?list.trackIds:list)}})}load(){AudioRunner._run(this.trackIds,AudioTrack.prototype.load)}unload(){AudioRunner._run(this.trackIds,AudioTrack.prototype.unload)}play(){AudioRunner._run(this.trackIds,AudioTrack.prototype.play)}playWhenAllowed(){AudioRunner._run(this.trackIds,AudioTrack.prototype.playWhenAllowed)}pause(){AudioRunner._run(this.trackIds,AudioTrack.prototype.pause)}stop(){AudioRunner._run(this.trackIds,AudioTrack.prototype.stop)}fade(duration,toVol,fromVol){if(null==duration||null==toVol)throw new Error(\"fade requires parameters\");AudioRunner._run(this.trackIds,AudioTrack.prototype.fade,duration,toVol,fromVol)}fadeIn(duration,fromVol){if(null==duration)throw new Error(\"fadeIn requires a parameter\");AudioRunner._run(this.trackIds,AudioTrack.prototype.fadeIn,duration,fromVol)}fadeOut(duration,fromVol){if(null==duration)throw new Error(\"fadeOut requires a parameter\");AudioRunner._run(this.trackIds,AudioTrack.prototype.fadeOut,duration,fromVol)}fadeStop(){AudioRunner._run(this.trackIds,AudioTrack.prototype.fadeStop)}loop(loop){if(null==loop)throw new Error(\"loop requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.loop,loop),this}mute(mute){if(null==mute)throw new Error(\"mute requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.mute,mute),this}rate(rate){if(null==rate)throw new Error(\"rate requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.rate,rate),this}time(time){if(null==time)throw new Error(\"time requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.time,time),this}volume(volume){if(null==volume)throw new Error(\"volume requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.volume,volume),this}on(...args){return AudioRunner._run(this.trackIds,AudioTrack.prototype.on,...args),this}one(...args){return AudioRunner._run(this.trackIds,AudioTrack.prototype.one,...args),this}off(...args){return AudioRunner._run(this.trackIds,AudioTrack.prototype.off,...args),this}static _run(ids,fn,...args){ids.forEach((id=>{const track=_tracks.get(id);track&&fn.apply(track,args)}))}}const _runnerParseSelector=(()=>{const notWsRe=/\\S/g,parenRe=/[()]/g;function processNegation(str,startPos){let match;if(notWsRe.lastIndex=startPos,match=notWsRe.exec(str),null===match||\"(\"!==match[0])throw new Error('invalid \":not()\" syntax: missing parenthesis');parenRe.lastIndex=notWsRe.lastIndex;const start=notWsRe.lastIndex,result={str:\"\",nextMatch:-1};let depth=1;for(;null!==(match=parenRe.exec(str));)if(\"(\"===match[0]?++depth:--depth,depth<1){result.nextMatch=parenRe.lastIndex,result.str=str.slice(start,result.nextMatch-1);break}return result}return function parseSelector(idArg){const ids=[],idRe=/:?[^\\s:()]+/g;let match;for(;null!==(match=idRe.exec(idArg));){const id=match[0];if(\":not\"===id){if(0===ids.length)throw new Error('invalid negation: no group ID preceded \":not()\"');const parent=ids[ids.length-1];if(!parent.id.startsWith(\":\"))throw new Error(`invalid negation of track \"${parent.id}\": only groups may be negated with \":not()\"`);const negation=processNegation(idArg,idRe.lastIndex);if(-1===negation.nextMatch)throw new Error('unknown error parsing \":not()\"');idRe.lastIndex=negation.nextMatch,parent.not=parseSelector(negation.str)}else ids.push({id:id})}return ids}})();function masterMute(mute){if(null==mute)return _masterMute;_masterMute=!!mute,publish(\"mute\",_masterMute)}function unsubscribe(id){_subscribers.delete(id)}function publish(mesg,data){_subscribers.forEach((fn=>fn(mesg,data)))}function _newTrack(sources){return new AudioTrack(sources.map((source=>{if(\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);if(passage.tags.includes(\"Twine.audio\"))return passage.text.trim()}const match=_formatSpecRe.exec(source);return null===match?source:{format:match[1],src:match[2]}})))}return Object.preventExtensions(Object.create(null,{tracks:{value:Object.preventExtensions(Object.create(null,{add:{value:function(){if(arguments.length<2){const errors=[];throw arguments.length<1&&errors.push(\"track ID\"),arguments.length<2&&errors.push(\"sources\"),new Error(`no ${errors.join(\" or \")} specified`)}const id=String(arguments[0]).trim(),what=`track ID \"${id}\"`;if(_badIdRe.test(id))throw new Error(`invalid ${what}: track IDs must not contain colons or whitespace`);const sources=Array.isArray(arguments[1])?Array.from(arguments[1]):Array.from(arguments).slice(1);let track;try{track=_newTrack(sources)}catch(ex){throw new Error(`${what}: error during track initialization: ${ex.message}`)}if(Config.debug&&!track.hasSource())throw new Error(`${what}: no supported audio sources found`);_tracks.has(id)&&_tracks.get(id)._destroy(),_tracks.set(id,track)}},delete:{value:function(id){return _tracks.has(id)&&_tracks.get(id)._destroy(),_tracks.delete(id)}},clear:{value:function(){_tracks.forEach((track=>track._destroy())),_tracks.clear()}},has:{value:function(id){return _tracks.has(id)}},get:{value:function(id){return _tracks.get(id)||null}}}))},groups:{value:Object.preventExtensions(Object.create(null,{add:{value:function(){if(arguments.length<2){const errors=[];throw arguments.length<1&&errors.push(\"group ID\"),arguments.length<2&&errors.push(\"track IDs\"),new Error(`no ${errors.join(\" or \")} specified`)}const id=String(arguments[0]).trim(),what=`group ID \"${id}\"`;if(!id.startsWith(\":\")||_badIdRe.test(id.slice(1)))throw new Error(`invalid ${what}: group IDs must start with a colon and must not contain colons or whitespace`);if(_specialIds.includes(id))throw new Error(`cannot clobber special ${what}`);const trackIds=Array.isArray(arguments[1])?Array.from(arguments[1]):Array.from(arguments).slice(1);let group;try{group=new Set(trackIds.map((trackId=>{if(!_tracks.has(trackId))throw new Error(`track \"${trackId}\" does not exist`);return trackId})))}catch(ex){throw new Error(`${what}: error during group initialization: ${ex.message}`)}_groups.set(id,Object.freeze(Array.from(group)))}},delete:{value:function(id){return _groups.delete(id)}},clear:{value:function(){_groups.clear()}},has:{value:function(id){return _groups.has(id)}},get:{value:function(id){return _groups.get(id)||null}}}))},lists:{value:Object.preventExtensions(Object.create(null,{add:{value:function(){if(arguments.length<2){const errors=[];throw arguments.length<1&&errors.push(\"list ID\"),arguments.length<2&&errors.push(\"track IDs\"),new Error(`no ${errors.join(\" or \")} specified`)}const id=String(arguments[0]).trim(),what=`list ID \"${id}\"`;if(_badIdRe.test(id))return this.error(`invalid ${what}: list IDs must not contain colons or whitespace`);const descriptors=Array.isArray(arguments[1])?Array.from(arguments[1]):Array.from(arguments).slice(1);let list;try{list=new AudioList(descriptors.map((desc=>{if(null===desc)throw new Error(\"track descriptor must be a string or object (type: null)\");switch(typeof desc){case\"string\":desc={id:desc};break;case\"object\":if(!Object.hasOwn(desc,\"id\")&&!Object.hasOwn(desc,\"sources\"))throw new Error('track descriptor must contain one of either an \"id\" or a \"sources\" property');if(Object.hasOwn(desc,\"id\")&&Object.hasOwn(desc,\"sources\"))throw new Error('track descriptor must contain either an \"id\" or a \"sources\" property, not both');break;default:throw new Error(`track descriptor must be a string or object (type: ${typeof desc})`)}let own,track,volume;if(Object.hasOwn(desc,\"id\")){if(\"string\"!=typeof desc.id)throw new Error('\"id\" property must be a string');if(!_tracks.has(desc.id))throw new Error(`track \"${desc.id}\" does not exist`);track=_tracks.get(desc.id)}else if(Object.hasOwn(desc,\"sources\")){if(!Array.isArray(desc.sources)||0===desc.sources.length)throw new Error('\"sources\" property must be a non-empty array');if(Object.hasOwn(desc,\"own\"))throw new Error('\"own\" property is not allowed with the \"sources\" property');try{track=_newTrack(desc.sources),own=!0}catch(ex){throw new Error(`error during track initialization: ${ex.message}`)}if(Config.debug&&!track.hasSource())throw new Error(\"no supported audio sources found\")}if(Object.hasOwn(desc,\"own\")){if(\"boolean\"!=typeof desc.own)throw new Error('\"own\" property must be a boolean');own=desc.own,own&&(track=track.clone())}if(Object.hasOwn(desc,\"volume\")){if(\"number\"!=typeof desc.volume||Number.isNaN(desc.volume)||!Number.isFinite(desc.volume)||desc.volume<0)throw new Error('\"volume\" property must be a non-negative finite number');volume=desc.volume}return{own:null!=own&&own,track:track,volume:null!=volume?volume:track.volume()}})))}catch(ex){throw new Error(`${what}: error during playlist initialization: ${ex.message}`)}_lists.has(id)&&_lists.get(id)._destroy(),_lists.set(id,list)}},delete:{value:function(id){return _lists.has(id)&&_lists.get(id)._destroy(),_lists.delete(id)}},clear:{value:function(){_lists.forEach((list=>list._destroy())),_lists.clear()}},has:{value:function(id){return _lists.has(id)}},get:{value:function(id){return _lists.get(id)||null}}}))},select:{value:function(){if(0===arguments.length)throw new Error(\"no track selector specified\");const selector=String(arguments[0]).trim(),trackIds=new Set;try{const allIds=Array.from(_tracks.keys());function renderIds(idObj){const id=idObj.id;let ids;switch(id){case\":all\":ids=allIds;break;case\":looped\":ids=allIds.filter((id=>_tracks.get(id).loop()));break;case\":muted\":ids=allIds.filter((id=>_tracks.get(id).mute()));break;case\":paused\":ids=allIds.filter((id=>_tracks.get(id).isPaused()));break;case\":playing\":ids=allIds.filter((id=>_tracks.get(id).isPlaying()));break;case\":stopped\":ids=allIds.filter((id=>_tracks.get(id).isStopped()));break;default:if(id.startsWith(\":\")){const group=_groups.get(id);if(!group)throw new Error(`group \"${id}\" does not exist`);ids=group}else ids=[id]}if(Object.hasOwn(idObj,\"not\")){const negated=idObj.not.map((idObj=>renderIds(idObj))).flat(1/0);ids=ids.filter((id=>!negated.includes(id)))}return ids}_runnerParseSelector(selector).forEach((idObj=>renderIds(idObj).forEach((id=>{if(!_tracks.has(id))throw new Error(`track \"${id}\" does not exist`);trackIds.add(id)}))))}catch(ex){throw new Error(`error during runner initialization: ${ex.message}`)}return new AudioRunner(trackIds)}},load:{value:function(){publish(\"load\")}},loadWithScreen:{value:function(){publish(\"loadwithscreen\")}},mute:{value:masterMute},muteOnHidden:{value:function(mute){if(!Visibility.isEnabled())return!1;if(null==mute)return _masterMuteOnHidden;_masterMuteOnHidden=!!mute;const namespace=\".SimpleAudio_masterMuteOnHidden\";if(_masterMuteOnHidden){const visibilityChange=`${Visibility.changeEvent}${namespace}`;jQuery(document).off(namespace).on(visibilityChange,(()=>masterMute(Visibility.isHidden()))),Visibility.isHidden()&&masterMute(!0)}else jQuery(document).off(namespace)}},rate:{value:function(rate){if(null==rate)return _masterRate;if(\"number\"!=typeof rate||Number.isNaN(rate)||!Number.isFinite(rate))throw new Error(\"rate must be a finite number\");_masterRate=Math.clamp(rate,.2,5),publish(\"rate\",_masterRate)}},stop:{value:function(){publish(\"stop\")}},unload:{value:function(){publish(\"unload\")}},volume:{value:function(volume){if(null==volume)return _masterVolume;if(\"number\"!=typeof volume||Number.isNaN(volume)||!Number.isFinite(volume))throw new Error(\"volume must be a finite number\");_masterVolume=Math.clamp(volume,0,1),publish(\"volume\",_masterVolume)}}}))})(),State=(()=>{let _history=[],_active=momentCreate(),_activeIndex=-1,_prng=null,_temporary=Object.create(null);function stateMarshal(noDelta){const state={index:_activeIndex};return noDelta?state.history=clone(_history):state.delta=historyDeltaEncode(_history),null!==_prng&&(state.seed=_prng.seed),state}function stateUnmarshal(state,noDelta){if(null==state)throw new Error(\"state object is null or undefined\");if(!Object.hasOwn(state,noDelta?\"history\":\"delta\")||0===state[noDelta?\"history\":\"delta\"].length)throw new Error(\"state object has no history or history is empty\");if(!Object.hasOwn(state,\"index\"))throw new Error(\"state object has no index\");if(null!==_prng&&!Object.hasOwn(state,\"seed\"))throw new Error(\"state object has no seed, but PRNG is enabled\");if(null===_prng&&Object.hasOwn(state,\"seed\"))throw new Error(\"state object has seed, but PRNG is disabled\");_history=noDelta?clone(state.history):historyDeltaDecode(state.delta),_activeIndex=state.index,Object.hasOwn(state,\"seed\")&&(_prng.seed=state.seed),momentActivate(_activeIndex)}function momentCreate(title,variables){return{title:null==title?\"\":String(title),variables:null==variables?{}:variables}}function momentActivate(moment){if(null==moment)throw new Error(\"moment activation attempted with null or undefined\");switch(typeof moment){case\"object\":_active=clone(moment);break;case\"number\":if(historyIsEmpty())throw new Error(\"moment activation attempted with index on empty history\");if(moment<0||moment>=historySize())throw new RangeError(`moment activation attempted with out-of-bounds index; need [0, ${historySize()-1}], got ${moment}`);_active=clone(_history[moment]);break;default:throw new TypeError(`moment activation attempted with a \"${typeof moment}\"; must be an object or valid history stack index`)}return null!==_prng&&(_prng=function(state){const prng=prngCreate(state.seed);for(let i=state.pull;i>0;--i)prng.random();return prng}({seed:_prng.seed,pull:_active.pull})),session.set(\"state\",stateMarshal()),triggerEvent(\":historyupdate\"),_active}function historyLength(){return _activeIndex+1}function historySize(){return _history.length}function historyIsEmpty(){return 0===_history.length}function historyTop(){return _history.length>0?_history[_history.length-1]:null}function historyGoTo(index){return!(null==index||index<0||index>=historySize()||index===_activeIndex)&&(_activeIndex=index,momentActivate(_activeIndex),!0)}function historyDeltaEncode(historyArr){if(!Array.isArray(historyArr))return null;if(0===historyArr.length)return[];const delta=[historyArr[0]];for(let i=1,iend=historyArr.length;i<iend;++i)delta.push(Diff.diff(historyArr[i-1],historyArr[i]));return delta}function historyDeltaDecode(delta){if(!Array.isArray(delta))return null;if(0===delta.length)return[];const historyArr=[clone(delta[0])];for(let i=1,iend=delta.length;i<iend;++i)historyArr.push(Diff.patch(historyArr[i-1],delta[i]));return historyArr}function prngCreate(seedBase,mixEntropy){return new Math.seedrandom(seedBase,{entropy:Boolean(mixEntropy),pass:(prng,seed)=>Object.create(null,{prng:{value:prng},seed:{writable:!0,value:seed},pull:{writable:!0,value:0},random:{value(){return++this.pull,this.prng()}}})})}function tempVariablesClear(){_temporary=Object.create(null)}const _METADATA_STORE=\"metadata\";function metadataDelete(key){if(\"string\"!=typeof key)throw new TypeError(`State.metadata.delete key parameter must be a string (received: ${typeof key})`);const store=storage.get(_METADATA_STORE);store&&Object.hasOwn(store,key)&&(1===Object.keys(store).length?storage.delete(_METADATA_STORE):(delete store[key],storage.set(_METADATA_STORE,store)))}return Object.preventExtensions(Object.create(null,{reset:{value:function(){session.delete(\"state\"),_history=[],_active=momentCreate(),_activeIndex=-1,_prng=null===_prng?null:prngCreate(_prng.seed),tempVariablesClear()}},restore:{value:function(){const state=session.get(\"state\");return null!=state&&(stateUnmarshal(state),!0)}},marshalForSave:{value:function(){return stateMarshal(!0)}},unmarshalForSave:{value:function(state){return stateUnmarshal(state,!0)}},expired:{get:function(){return[]}},turns:{get:function(){return historyLength()}},passages:{get:function(){return _history.slice(0,historyLength()).map((moment=>moment.title))}},hasPlayed:{value:function(title){return null!=title&&\"\"!==title&&!!_history.slice(0,historyLength()).some((moment=>moment.title===title))}},active:{get:function(){return _active}},activeIndex:{get:function(){return _activeIndex}},passage:{get:function(){return _active.title}},variables:{get:function(){return _active.variables}},history:{get:function(){return _history}},length:{get:historyLength},size:{get:historySize},isEmpty:{value:historyIsEmpty},current:{get:function(){return _history.length>0?_history[_activeIndex]:null}},top:{get:historyTop},bottom:{get:function(){return _history.length>0?_history[0]:null}},index:{value:function(index){return historyIsEmpty()||index<0||index>_activeIndex?null:_history[index]}},peek:{value:function(offset){if(historyIsEmpty())return null;const lengthOffset=1+(offset?Math.abs(offset):0);return lengthOffset>historyLength()?null:_history[historyLength()-lengthOffset]}},has:{value:function(title){if(historyIsEmpty()||null==title||\"\"===title)return!1;for(let i=_activeIndex;i>=0;--i)if(_history[i].title===title)return!0;return!1}},create:{value:function(title){for(0,historyLength()<historySize()&&_history.splice(historyLength(),historySize()-historyLength()),_history.push(momentCreate(title,_active.variables)),_prng&&(historyTop().pull=_prng.pull);historySize()>Config.history.maxStates;)_history.shift();return _activeIndex=historySize()-1,momentActivate(_activeIndex),historyLength()}},goTo:{value:historyGoTo},go:{value:function(offset){return null!=offset&&0!==offset&&historyGoTo(_activeIndex+offset)}},deltaEncode:{value:historyDeltaEncode},deltaDecode:{value:historyDeltaDecode},prng:{value:Object.preventExtensions(Object.create(null,{init:{value:function(seedBase,mixEntropy){if(!historyIsEmpty()){let what;throw what=\"the story JavaScript section\",new Error(`State.prng.init must be called during initialization, within either ${what} or the StoryInit special passage`)}_prng=prngCreate(seedBase,Boolean(mixEntropy)),_active.pull=_prng.pull}},isEnabled:{value:function(){return null!==_prng}},pull:{get:function(){return null!==_prng?_prng.pull:NaN}},seed:{get:function(){return null!==_prng?_prng.seed:null}}}))},random:{value:function(){return null!==_prng?_prng.random():Math.random()}},clearTemporary:{value:tempVariablesClear},temporary:{get:function(){return _temporary}},getVar:{value:function(varExpression){try{return Scripting.evalTwineScript(varExpression)}catch(ex){}}},setVar:{value:function(varExpression,value){try{return Scripting.evalTwineScript(`${varExpression} = SCRIPT$DATA$`,null,value),!0}catch(ex){}return!1}},metadata:{value:Object.preventExtensions(Object.create(null,{clear:{value:function(){storage.delete(_METADATA_STORE)}},delete:{value:metadataDelete},entries:{value:function(){const store=storage.get(_METADATA_STORE);return store&&Object.entries(store)}},get:{value:function(key){if(\"string\"!=typeof key)throw new TypeError(`State.metadata.get key parameter must be a string (received: ${typeof key})`);const store=storage.get(_METADATA_STORE);return store&&Object.hasOwn(store,key)?store[key]:undefined}},has:{value:function(key){if(\"string\"!=typeof key)throw new TypeError(`State.metadata.has key parameter must be a string (received: ${typeof key})`);const store=storage.get(_METADATA_STORE);return store&&Object.hasOwn(store,key)}},keys:{value:function(){const store=storage.get(_METADATA_STORE);return store&&Object.keys(store)}},set:{value:function(key,value){if(\"string\"!=typeof key)throw new TypeError(`State.metadata.set key parameter must be a string (received: ${typeof key})`);if(void 0===value)metadataDelete(key);else{const store=storage.get(_METADATA_STORE)||{};store[key]=value,storage.set(_METADATA_STORE,store)}}},size:{get:function(){const store=storage.get(_METADATA_STORE);return store?Object.keys(store).length:0}}}))}}))})(),Scripting=(()=>{function toStringOrDefault(value){return console.warn(\"[DEPRECATED] toStringOrDefault() is deprecated.\"),stringFrom(value)}function either(){if(0!==arguments.length)return Array.prototype.concat.apply([],arguments).random()}function forget(key){if(\"string\"!=typeof key)throw new TypeError(`forget key parameter must be a string (received: ${getTypeOf(key)})`);State.metadata.delete(key)}function hasVisited(){if(0===arguments.length)throw new Error(\"hasVisited called with insufficient parameters\");if(State.isEmpty())return!1;const needles=Array.prototype.concat.apply([],arguments),played=State.passages;for(let i=0;i<needles.length;++i)if(!played.includes(needles[i]))return!1;return!0}function lastVisited(){if(0===arguments.length)throw new Error(\"lastVisited called with insufficient parameters\");if(State.isEmpty())return-1;const needles=Array.prototype.concat.apply([],arguments),played=State.passages,uBound=played.length-1;let turns=State.turns;for(let i=0;i<needles.length&&turns>-1;++i){const lastIndex=played.lastIndexOf(needles[i]);turns=Math.min(turns,-1===lastIndex?-1:uBound-lastIndex)}return turns}function memorize(key,value){if(\"string\"!=typeof key)throw new TypeError(`memorize key parameter must be a string (received: ${getTypeOf(key)})`);State.metadata.set(key,value)}function passage(){return State.passage}function previous(){const passages=State.passages;if(arguments.length>0){const offset=Number(arguments[0]);if(!Number.isSafeInteger(offset)||offset<1)throw new RangeError(\"previous offset parameter must be a positive integer greater than zero\");return passages.length>offset?passages[passages.length-1-offset]:\"\"}for(let i=passages.length-2;i>=0;--i)if(passages[i]!==State.passage)return passages[i];return\"\"}function random(){let min,max;switch(arguments.length){case 0:throw new Error(\"random called with insufficient parameters\");case 1:min=0,max=Math.trunc(arguments[0]);break;default:min=Math.trunc(arguments[0]),max=Math.trunc(arguments[1])}if(!Number.isInteger(min))throw new TypeError(\"random min parameter must be an integer\");if(!Number.isInteger(max))throw new TypeError(\"random max parameter must be an integer\");return min>max&&([min,max]=[max,min]),Math.floor(State.random()*(max-min+1))+min}function randomFloat(){let min,max;switch(arguments.length){case 0:throw new Error(\"randomFloat called with insufficient parameters\");case 1:min=0,max=Number(arguments[0]);break;default:min=Number(arguments[0]),max=Number(arguments[1])}if(Number.isNaN(min)||!Number.isFinite(min))throw new TypeError(\"randomFloat min parameter must be a number\");if(Number.isNaN(max)||!Number.isFinite(max))throw new TypeError(\"randomFloat max parameter must be a number\");return min>max&&([min,max]=[max,min]),State.random()*(max-min)+min}function recall(key,defaultValue){if(\"string\"!=typeof key)throw new TypeError(`recall key parameter must be a string (received: ${getTypeOf(key)})`);return State.metadata.has(key)?State.metadata.get(key):defaultValue}function tags(){if(0===arguments.length)return Story.get(State.passage).tags;const passages=Array.prototype.concat.apply([],arguments);let tags=[];for(let i=0;i<passages.length;++i)tags=tags.concat(Story.get(passages[i]).tags);return tags}function temporary(){return State.temporary}function time(){return null===Engine.lastPlay?0:now()-Engine.lastPlay}function turns(){return State.turns}function variables(){return State.variables}function visited(){if(State.isEmpty())return 0;const needles=Array.prototype.concat.apply([],0===arguments.length?[State.passage]:arguments),played=State.passages;let count=State.turns;for(let i=0;i<needles.length&&count>0;++i)count=Math.min(count,played.count(needles[i]));return count}function visitedTags(){if(0===arguments.length)throw new Error(\"visitedTags called with insufficient parameters\");if(State.isEmpty())return 0;const needles=Array.prototype.concat.apply([],arguments),nLength=needles.length,played=State.passages,seen=new Map;let count=0;for(let i=0;i<played.length;++i){const title=played[i];if(seen.has(title))seen.get(title)&&++count;else{const tags=Story.get(title).tags;if(tags.length>0){let found=0;for(let j=0;j<nLength;++j)tags.includes(needles[j])&&++found;found===nLength?(++count,seen.set(title,!0)):seen.set(title,!1)}}}return count}var{importScripts:importScripts,importStyles:importStyles}=(()=>{function slugifyUrl(url){return parseURL(url).path.replace(/^[^\\w]+|[^\\w]+$/g,\"\").replace(/[^\\w]+/g,\"-\").toLocaleLowerCase()}function addScript(url){return new Promise(((resolve,reject)=>{let kind,src;if(\"string\"==typeof url)kind=url.trim().toLowerCase().endsWith(\".mjs\")?\"module\":\"text/javascript\",src=url;else{if(\"object\"!=typeof url)throw new Error(\"importScripts url parameter must be a string or object\");kind=url.type,src=url.src}jQuery(document.createElement(\"script\")).one(\"load abort error\",(ev=>{jQuery(ev.target).off(),\"load\"===ev.type?resolve(ev.target):reject(new Error(`importScripts failed to load the script \"${src}\"`))})).appendTo(document.head).attr({id:`script-imported-${slugifyUrl(src)}`,type:kind,src:src})}))}function addStyle(url){return new Promise(((resolve,reject)=>{if(\"string\"!=typeof url)throw new Error(\"importStyles url parameter must be a string\");jQuery(document.createElement(\"link\")).one(\"load abort error\",(ev=>{jQuery(ev.target).off(),\"load\"===ev.type?resolve(ev.target):reject(new Error(`importStyles failed to load the stylesheet \"${url}\"`))})).appendTo(document.head).attr({id:`style-imported-${slugifyUrl(url)}`,rel:\"stylesheet\",href:url})}))}function sequence(callbacks){return callbacks.reduce(((seq,fn)=>seq.then(fn)),Promise.resolve())}return{importScripts:function(...urls){return Promise.all(urls.map((oneOrSeries=>Array.isArray(oneOrSeries)?sequence(oneOrSeries.map((url=>()=>addScript(url)))):addScript(oneOrSeries))))},importStyles:function(...urls){return Promise.all(urls.map((oneOrSeries=>Array.isArray(oneOrSeries)?sequence(oneOrSeries.map((url=>()=>addStyle(url)))):addStyle(oneOrSeries))))}}})();const desugar=(()=>{const tokenTable=enumFrom({$:\"State.variables.\",_:\"State.temporary.\",to:\"=\",eq:\"==\",neq:\"!=\",is:\"===\",isnot:\"!==\",gt:\">\",gte:\">=\",lt:\"<\",lte:\"<=\",and:\"&&\",or:\"||\",not:\"!\",def:'\"undefined\" !== typeof',ndef:'\"undefined\" === typeof'}),desugarRE=new RegExp([\"(?:\\\"\\\"|''|``)\",'(?:\"(?:\\\\\\\\.|[^\"\\\\\\\\])+\")',\"(?:'(?:\\\\\\\\.|[^'\\\\\\\\])+')\",\"(`(?:\\\\\\\\.|[^`\\\\\\\\])+`)\",\"(?:[=+\\\\-*\\\\/%<>&\\\\|\\\\^~!?:,;\\\\(\\\\)\\\\[\\\\]{}]+)\",\"(?:\\\\.{3})\",\"([^\\\"'=+\\\\-*\\\\/%<>&\\\\|\\\\^~!?:,;\\\\(\\\\)\\\\[\\\\]{}\\\\s]+)\"].join(\"|\"),\"g\"),varTest=new RegExp(`^${Patterns.variable}`);function desugar(sugaredCode){desugarRE.lastIndex=0;let match,code=sugaredCode;for(;null!==(match=desugarRE.exec(code));)if(match[1]){const sugaredTemplate=match[1],template=desugarTemplate(sugaredTemplate);template!==sugaredTemplate&&(code=code.splice(match.index,sugaredTemplate.length,template),desugarRE.lastIndex+=template.length-sugaredTemplate.length)}else if(match[2]){let token=match[2];if(\"$\"===token||\"_\"===token)continue;varTest.test(token)&&(token=token[0]),tokenTable[token]&&(code=code.splice(match.index,token.length,tokenTable[token]),desugarRE.lastIndex+=tokenTable[token].length-token.length)}return code}const templateGroupStartRE=/\\$\\{/g,templateGroupParseRE=new RegExp([\"(?:\\\"\\\"|'')\",'(?:\"(?:\\\\\\\\.|[^\"\\\\\\\\])+\")',\"(?:'(?:\\\\\\\\.|[^'\\\\\\\\])+')\",\"(\\\\{)\",\"(\\\\})\"].join(\"|\"),\"g\");function desugarTemplate(sugaredLiteral){templateGroupStartRE.lastIndex=0;let startMatch,template=sugaredLiteral;for(;null!==(startMatch=templateGroupStartRE.exec(template));){const startIndex=startMatch.index+2;let endMatch,endIndex=startIndex,depth=1;for(templateGroupParseRE.lastIndex=startIndex;null!==(endMatch=templateGroupParseRE.exec(template));)if(endMatch[1]?++depth:endMatch[2]&&--depth,0===depth){endIndex=endMatch.index;break}if(endIndex>startIndex){const desugarREIndex=desugarRE.lastIndex,sugaredGroup=template.slice(startIndex,endIndex),group=desugar(sugaredGroup);desugarRE.lastIndex=desugarREIndex,template=template.splice(startIndex,sugaredGroup.length,group),templateGroupStartRE.lastIndex+=group.length-sugaredGroup.length}}return template}return desugar})();function evalJavaScript(code,output,data){return function(code,output,SCRIPT$DATA$){return eval(code)}.call(output?{output:output}:null,String(code),output,data)}function evalTwineScript(code,output,data){return function(code,output,SCRIPT$DATA$){return eval(code)}.call(output?{output:output}:null,desugar(String(code)),output,data)}return Object.preventExtensions(Object.create(null,{desugar:{value:desugar},evalJavaScript:{value:evalJavaScript},evalTwineScript:{value:evalTwineScript},parse:{value:desugar}}))})(),{EOF:EOF,Lexer:Lexer}={EOF:-1,Lexer:class{constructor(source,initialState){if(arguments.length<2)throw new Error(\"Lexer constructor called with too few parameters (source:string , initialState:function)\");Object.defineProperties(this,{source:{value:source},initial:{value:initialState},state:{writable:!0,value:initialState},start:{writable:!0,value:0},pos:{writable:!0,value:0},depth:{writable:!0,value:0},items:{writable:!0,value:[]},data:{writable:!0,value:{}}})}reset(){this.state=this.initial,this.start=0,this.pos=0,this.depth=0,this.items=[],this.data={}}run(){for(;null!==this.state;)this.state=this.state(this);return this.items}nextItem(){for(;0===this.items.length&&null!==this.state;)this.state=this.state(this);return this.items.shift()}next(){return this.pos>=this.source.length?-1:this.source[this.pos++]}peek(){return this.pos>=this.source.length?-1:this.source[this.pos]}backup(num){this.pos-=num||1}forward(num){this.pos+=num||1}ignore(){this.start=this.pos}accept(valid){const ch=this.next();return!(-1===ch||!valid.includes(ch)&&(this.backup(),1))}acceptRe(validRe){const ch=this.next();return!(-1===ch||!validRe.test(ch)&&(this.backup(),1))}acceptRun(valid){for(;;){const ch=this.next();if(-1===ch)return;if(!valid.includes(ch))break}this.backup()}acceptRunRe(validRe){for(;;){const ch=this.next();if(-1===ch)return;if(!validRe.test(ch))break}this.backup()}emit(type){this.items.push({type:type,text:this.source.slice(this.start,this.pos),start:this.start,pos:this.pos}),this.start=this.pos}error(type,message){if(arguments.length<2)throw new Error(\"Lexer.prototype.error called with too few parameters (type:number , message:string)\");return this.items.push({type:type,message:message,text:this.source.slice(this.start,this.pos),start:this.start,pos:this.pos}),null}static enumFromNames(names){const obj=names.reduce(((obj,name,i)=>(obj[name]=i,obj)),{});return Object.freeze(Object.assign(Object.create(null),obj))}}},Wikifier=(()=>{let _callDepth=0;class Wikifier{constructor(destination,source,options){Wikifier.Parser.Profile.isEmpty()&&Wikifier.Parser.Profile.compile(),Object.defineProperties(this,{source:{value:String(source)},options:{writable:!0,value:Object.assign({profile:\"all\"},options)},nextMatch:{writable:!0,value:0},output:{writable:!0,value:null},_rawArgs:{writable:!0,value:\"\"}}),this.output=null==destination?document.createDocumentFragment():destination instanceof jQuery?destination[0]:destination;try{++_callDepth,this.subWikify(this.output),1===_callDepth&&(Object.hasOwn(this.options,\"cleanup\")&&null!=this.options.cleanup?this.options.cleanup:Config.cleanupWikifierOutput)&&convertBreaks(this.output)}finally{--_callDepth}}subWikify(output,terminator,options){const oldOutput=this.output;let newOptions,oldOptions;this.output=output,Wikifier.Option.length>0&&(newOptions=Object.assign(newOptions||{},Wikifier.Option.options)),null!==options&&\"object\"==typeof options&&(newOptions=Object.assign(newOptions||{},options)),newOptions&&(oldOptions=this.options,this.options=Object.assign({},this.options,newOptions));const parsersProfile=Wikifier.Parser.Profile.get(this.options.profile),terminatorRegExp=terminator?new RegExp(`(?:${terminator})`,this.options.ignoreTerminatorCase?\"gim\":\"gm\"):null;let terminatorMatch,parserMatch;do{if(parsersProfile.parserRegExp.lastIndex=this.nextMatch,terminatorRegExp&&(terminatorRegExp.lastIndex=this.nextMatch),parserMatch=parsersProfile.parserRegExp.exec(this.source),terminatorMatch=terminatorRegExp?terminatorRegExp.exec(this.source):null,terminatorMatch&&(!parserMatch||terminatorMatch.index<=parserMatch.index))return terminatorMatch.index>this.nextMatch&&this.outputText(this.output,this.nextMatch,terminatorMatch.index),this.matchStart=terminatorMatch.index,this.matchLength=terminatorMatch[0].length,this.matchText=terminatorMatch[0],this.nextMatch=terminatorRegExp.lastIndex,this.output=oldOutput,void(oldOptions&&(this.options=oldOptions));if(parserMatch){let matchingParser;parserMatch.index>this.nextMatch&&this.outputText(this.output,this.nextMatch,parserMatch.index),this.matchStart=parserMatch.index,this.matchLength=parserMatch[0].length,this.matchText=parserMatch[0],this.nextMatch=parsersProfile.parserRegExp.lastIndex;for(let i=1,iend=parserMatch.length;i<iend;++i)if(parserMatch[i]){matchingParser=i-1;break}if(parsersProfile.parsers[matchingParser].handler(this),null!=TempState.break)break}}while(terminatorMatch||parserMatch);null==TempState.break?this.nextMatch<this.source.length&&(this.outputText(this.output,this.nextMatch,this.source.length),this.nextMatch=this.source.length):this.output.lastChild&&this.output.lastChild.nodeType===Node.ELEMENT_NODE&&\"BR\"===this.output.lastChild.nodeName.toUpperCase()&&jQuery(this.output.lastChild).remove(),this.output=oldOutput,oldOptions&&(this.options=oldOptions)}outputText(destination,startPos,endPos){destination.appendChild(document.createTextNode(this.source.substring(startPos,endPos)))}rawArgs(){return console.warn(\"[DEPRECATED] Wikifier.rawArgs() is deprecated.\"),this._rawArgs}fullArgs(){return console.warn(\"[DEPRECATED] Wikifier.fullArgs() is deprecated.\"),Scripting.desugar(this._rawArgs)}static wikifyEval(text){const output=document.createDocumentFragment();new Wikifier(output,text);const errors=output.querySelector(\".error\");if(null!==errors)throw new Error(errors.textContent.replace(errorPrologRegExp,\"\"));return output}static createInternalLink(destination,passage,text,callback){const $link=jQuery(document.createElement(\"a\"));return null!=passage&&($link.attr(\"data-passage\",passage),Story.has(passage)?($link.addClass(\"link-internal\"),Config.addVisitedLinkClass&&State.hasPlayed(passage)&&$link.addClass(\"link-visited\")):$link.addClass(\"link-broken\"),$link.ariaClick({one:!0},(()=>{\"function\"==typeof callback&&callback(),Engine.play(passage)}))),text&&$link.append(document.createTextNode(text)),destination&&$link.appendTo(destination),$link[0]}static createExternalLink(destination,url,text){const $link=jQuery(document.createElement(\"a\")).attr(\"target\",\"_blank\").addClass(\"link-external\").text(text).appendTo(destination);return null!=url&&$link.attr({href:url,tabindex:0}),$link[0]}}return Object.defineProperty(Wikifier,\"Option\",{value:(()=>{let _optionsStack=[];return Object.preventExtensions(Object.create(null,{length:{get:function(){return _optionsStack.length}},options:{get:function(){return Object.assign({},..._optionsStack)}},clear:{value:function(){_optionsStack=[]}},get:{value:function(index){return _optionsStack[index]}},pop:{value:function(){return _optionsStack.pop()}},push:{value:function(options){if(\"object\"!=typeof options||null===options)throw new TypeError(`Wikifier.Option.push options parameter must be an object (received: ${getTypeOf(options)})`);return _optionsStack.push(options)}}}))})()}),Object.defineProperty(Wikifier,\"Parser\",{value:(()=>{const _parsers=[];let _profiles;function parsersHas(name){return!!_parsers.find((parser=>parser.name===name))}return Object.preventExtensions(Object.create(null,{parsers:{get:function(){return _parsers}},add:{value:function(parser){if(\"object\"!=typeof parser)throw new Error(\"Wikifier.Parser.add parser parameter must be an object\");if(!Object.hasOwn(parser,\"name\"))throw new Error('parser object missing required \"name\" property');if(\"string\"!=typeof parser.name)throw new Error('parser object \"name\" property must be a string');if(!Object.hasOwn(parser,\"match\"))throw new Error('parser object missing required \"match\" property');if(\"string\"!=typeof parser.match)throw new Error('parser object \"match\" property must be a string');if(!Object.hasOwn(parser,\"handler\"))throw new Error('parser object missing required \"handler\" property');if(\"function\"!=typeof parser.handler)throw new Error('parser object \"handler\" property must be a function');if(Object.hasOwn(parser,\"profiles\")&&!Array.isArray(parser.profiles))throw new Error('parser object \"profiles\" property must be an array');if(parsersHas(parser.name))throw new Error(`cannot clobber existing parser \"${parser.name}\"`);_parsers.push(parser)}},delete:{value:function(name){const parser=_parsers.find((parser=>parser.name===name));parser&&_parsers.delete(parser)}},isEmpty:{value:function(){return 0===_parsers.length}},has:{value:parsersHas},get:{value:function(name){return _parsers.find((parser=>parser.name===name))||null}},Profile:{value:Object.preventExtensions(Object.create(null,{profiles:{get:function(){return _profiles}},compile:{value:function(){const all=_parsers,core=all.filter((parser=>!Array.isArray(parser.profiles)||parser.profiles.includes(\"core\")));return _profiles=Object.freeze({all:{parsers:all,parserRegExp:new RegExp(all.map((parser=>`(${parser.match})`)).join(\"|\"),\"gm\")},core:{parsers:core,parserRegExp:new RegExp(core.map((parser=>`(${parser.match})`)).join(\"|\"),\"gm\")}}),_profiles}},isEmpty:{value:function(){return\"object\"!=typeof _profiles||0===Object.keys(_profiles).length}},has:{value:function(profile){return\"object\"==typeof _profiles&&Object.hasOwn(_profiles,profile)}},get:{value:function(profile){if(\"object\"!=typeof _profiles||!Object.hasOwn(_profiles,profile))throw new Error(`nonexistent parser profile \"${profile}\"`);return _profiles[profile]}}}))}}))})()}),Object.defineProperties(Wikifier,{helpers:{value:{}},isExternalLink:{value:isExternalLink},getValue:{value:State.getVar},setValue:{value:State.setVar},parse:{value:Scripting.desugar},evalExpression:{value:Scripting.evalTwineScript},evalStatements:{value:Scripting.evalTwineScript},textPrimitives:{value:Patterns}}),Object.defineProperties(Wikifier.helpers,{inlineCss:{value:(()=>{const lookaheadRe=new RegExp(Patterns.inlineCss,\"gm\"),idOrClassRe=new RegExp(`(${Patterns.cssIdOrClassSigil})(${Patterns.anyLetter}+)`,\"g\");return function(w){const css={classes:[],id:\"\",styles:{}};let matched;do{lookaheadRe.lastIndex=w.nextMatch;const match=lookaheadRe.exec(w.source);if(matched=match&&match.index===w.nextMatch,matched){if(match[1])css.styles[cssPropToDOMProp(match[1])]=match[2].trim();else if(match[3])css.styles[cssPropToDOMProp(match[3])]=match[4].trim();else if(match[5]){let subMatch;for(idOrClassRe.lastIndex=0;null!==(subMatch=idOrClassRe.exec(match[5]));)\".\"===subMatch[1]?css.classes.push(subMatch[2]):css.id=subMatch[2]}w.nextMatch=lookaheadRe.lastIndex}}while(matched);return css}})()},evalText:{value(text){let result;try{switch(result=Scripting.evalTwineScript(text),typeof result){case\"string\":\"\"===result.trim()&&(result=text);break;case\"number\":result=String(result);break;default:result=text}}catch(ex){result=text}return result}},evalPassageId:{value:passage=>null==passage||Story.has(passage)?passage:Wikifier.helpers.evalText(passage)},hasBlockContext:{value(nodes){const hasGCS=\"function\"==typeof window.getComputedStyle;for(let i=nodes.length-1;i>=0;--i){const node=nodes[i];switch(node.nodeType){case Node.ELEMENT_NODE:{const tagName=node.nodeName.toUpperCase();if(\"BR\"===tagName)return!0;const styles=hasGCS?window.getComputedStyle(node,null):node.currentStyle;if(styles&&styles.display){if(\"none\"===styles.display)continue;return\"block\"===styles.display}switch(tagName){case\"ADDRESS\":case\"ARTICLE\":case\"ASIDE\":case\"BLOCKQUOTE\":case\"CENTER\":case\"DIV\":case\"DL\":case\"FIGURE\":case\"FOOTER\":case\"FORM\":case\"H1\":case\"H2\":case\"H3\":case\"H4\":case\"H5\":case\"H6\":case\"HEADER\":case\"HR\":case\"MAIN\":case\"NAV\":case\"OL\":case\"P\":case\"PRE\":case\"SECTION\":case\"TABLE\":case\"UL\":return!0}return!1}case Node.COMMENT_NODE:continue;default:return!1}}return!0}},shadowHandler:{value:(()=>{let macroParser=null;return function(code){const shadowStore=Object.create(null);return macroParser||function(){if(!macroParser&&(macroParser=Wikifier.Parser.get(\"macro\"),!macroParser))throw new Error('cannot find \"macro\" parser')}(),macroParser.context&¯oParser.context.shadowView.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;shadowStore[varName]=store[varKey]})),function(){const shadowNames=Object.keys(shadowStore),valueCache=shadowNames.length>0?{}:null;try{return shadowNames.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;Object.hasOwn(store,varKey)&&(valueCache[varKey]=store[varKey]),store[varKey]=shadowStore[varName]})),Scripting.evalJavaScript(code)}finally{shadowNames.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;shadowStore[varName]=store[varKey],Object.hasOwn(valueCache,varKey)?store[varKey]=valueCache[varKey]:delete store[varKey]}))}}}})()},parseSquareBracketedMarkup:{value:(()=>{const Item=Lexer.enumFromNames([\"Error\",\"DelimLTR\",\"DelimRTL\",\"InnerMeta\",\"ImageMeta\",\"LinkMeta\",\"Link\",\"RightMeta\",\"Setter\",\"Source\",\"Text\"]),Delim=Lexer.enumFromNames([\"None\",\"LTR\",\"RTL\"]);function slurpQuote(lexer,endQuote){loop:for(;;)switch(lexer.next()){case\"\\\\\":{const ch=lexer.next();if(ch!==EOF&&\"\\n\"!==ch)break}case EOF:case\"\\n\":return EOF;case endQuote:break loop}return lexer.pos}function lexLeftMeta(lexer){if(!lexer.accept(\"[\"))return lexer.error(Item.Error,\"malformed square-bracketed markup\");if(lexer.accept(\"[\"))lexer.data.isLink=!0,lexer.emit(Item.LinkMeta);else{if(lexer.accept(\"<>\"),!(lexer.accept(\"Ii\")&&lexer.accept(\"Mm\")&&lexer.accept(\"Gg\")&&lexer.accept(\"[\")))return lexer.error(Item.Error,\"malformed square-bracketed markup\");lexer.data.isLink=!1,lexer.emit(Item.ImageMeta)}return lexer.depth=2,lexCoreComponents}function lexCoreComponents(lexer){const what=lexer.data.isLink?\"link\":\"image\";let delim=Delim.None;for(;;)switch(lexer.next()){case EOF:case\"\\n\":return lexer.error(Item.Error,`unterminated ${what} markup`);case'\"':if(slurpQuote(lexer,'\"')===EOF)return lexer.error(Item.Error,`unterminated double quoted string in ${what} markup`);break;case\"|\":delim===Delim.None&&(delim=Delim.LTR,lexer.backup(),lexer.emit(Item.Text),lexer.forward(),lexer.emit(Item.DelimLTR));break;case\"-\":delim===Delim.None&&\">\"===lexer.peek()&&(delim=Delim.LTR,lexer.backup(),lexer.emit(Item.Text),lexer.forward(2),lexer.emit(Item.DelimLTR));break;case\"<\":delim===Delim.None&&\"-\"===lexer.peek()&&(delim=Delim.RTL,lexer.backup(),lexer.emit(lexer.data.isLink?Item.Link:Item.Source),lexer.forward(2),lexer.emit(Item.DelimRTL));break;case\"[\":++lexer.depth;break;case\"]\":if(--lexer.depth,1===lexer.depth)switch(lexer.peek()){case\"[\":return++lexer.depth,lexer.backup(),delim===Delim.RTL?lexer.emit(Item.Text):lexer.emit(lexer.data.isLink?Item.Link:Item.Source),lexer.forward(2),lexer.emit(Item.InnerMeta),lexer.data.isLink?lexSetter:lexImageLink;case\"]\":return--lexer.depth,lexer.backup(),delim===Delim.RTL?lexer.emit(Item.Text):lexer.emit(lexer.data.isLink?Item.Link:Item.Source),lexer.forward(2),lexer.emit(Item.RightMeta),null;default:return lexer.error(Item.Error,`malformed ${what} markup`)}}}function lexImageLink(lexer){const what=lexer.data.isLink?\"link\":\"image\";for(;;)switch(lexer.next()){case EOF:case\"\\n\":return lexer.error(Item.Error,`unterminated ${what} markup`);case'\"':if(slurpQuote(lexer,'\"')===EOF)return lexer.error(Item.Error,`unterminated double quoted string in ${what} markup link component`);break;case\"[\":++lexer.depth;break;case\"]\":if(--lexer.depth,1===lexer.depth)switch(lexer.peek()){case\"[\":return++lexer.depth,lexer.backup(),lexer.emit(Item.Link),lexer.forward(2),lexer.emit(Item.InnerMeta),lexSetter;case\"]\":return--lexer.depth,lexer.backup(),lexer.emit(Item.Link),lexer.forward(2),lexer.emit(Item.RightMeta),null;default:return lexer.error(Item.Error,`malformed ${what} markup`)}}}function lexSetter(lexer){const what=lexer.data.isLink?\"link\":\"image\";for(;;)switch(lexer.next()){case EOF:case\"\\n\":return lexer.error(Item.Error,`unterminated ${what} markup`);case'\"':if(slurpQuote(lexer,'\"')===EOF)return lexer.error(Item.Error,`unterminated double quoted string in ${what} markup setter component`);break;case\"'\":if(slurpQuote(lexer,\"'\")===EOF)return lexer.error(Item.Error,`unterminated single quoted string in ${what} markup setter component`);break;case\"[\":++lexer.depth;break;case\"]\":if(--lexer.depth,1===lexer.depth)return\"]\"!==lexer.peek()?lexer.error(Item.Error,`malformed ${what} markup`):(--lexer.depth,lexer.backup(),lexer.emit(Item.Setter),lexer.forward(2),lexer.emit(Item.RightMeta),null)}}return function(w){const lexer=new Lexer(w.source,lexLeftMeta);lexer.start=lexer.pos=w.matchStart;const markup={},items=lexer.run(),last=items.last();return last&&last.type===Item.Error?markup.error=last.message:items.forEach((item=>{const text=item.text.trim();switch(item.type){case Item.ImageMeta:markup.isImage=!0,\"<\"===text[1]?markup.align=\"left\":\">\"===text[1]&&(markup.align=\"right\");break;case Item.LinkMeta:markup.isLink=!0;break;case Item.Link:\"~\"===text[0]?(markup.forceInternal=!0,markup.link=text.slice(1)):markup.link=text;break;case Item.Setter:markup.setter=text;break;case Item.Source:markup.source=text;break;case Item.Text:markup.text=text}})),markup.pos=lexer.pos,markup}})()}}),Wikifier})();(()=>{function _verbatimTagHandler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);match&&match.index===w.matchStart&&(w.nextMatch=this.lookahead.lastIndex,jQuery(document.createDocumentFragment()).append(match[1]).appendTo(w.output))}Wikifier.Parser.add({name:\"quoteByBlock\",profiles:[\"block\"],match:\"^<<<\\\\n\",terminator:\"^<<<\\\\n\",handler(w){Wikifier.helpers.hasBlockContext(w.output.childNodes)?w.subWikify(jQuery(document.createElement(\"blockquote\")).appendTo(w.output).get(0),this.terminator):jQuery(w.output).append(document.createTextNode(w.matchText))}}),Wikifier.Parser.add({name:\"quoteByLine\",profiles:[\"block\"],match:\"^>+\",lookahead:/^>+/gm,terminator:\"\\\\n\",handler(w){if(!Wikifier.helpers.hasBlockContext(w.output.childNodes))return void jQuery(w.output).append(document.createTextNode(w.matchText));const destStack=[w.output];let matched,i,curLevel=0,newLevel=w.matchLength;do{if(newLevel>curLevel)for(i=curLevel;i<newLevel;++i)destStack.push(jQuery(document.createElement(\"blockquote\")).appendTo(destStack[destStack.length-1]).get(0));else if(newLevel<curLevel)for(i=curLevel;i>newLevel;--i)destStack.pop();curLevel=newLevel,w.subWikify(destStack[destStack.length-1],this.terminator),jQuery(document.createElement(\"br\")).appendTo(destStack[destStack.length-1]),this.lookahead.lastIndex=w.nextMatch;const match=this.lookahead.exec(w.source);matched=match&&match.index===w.nextMatch,matched&&(newLevel=match[0].length,w.nextMatch+=match[0].length)}while(matched)}}),Wikifier.Parser.add({name:\"macro\",profiles:[\"core\"],match:\"<<\",lookahead:new RegExp(`<<(/?${Patterns.macroName})(?:\\\\s*)((?:(?:/\\\\*[^*]*\\\\*+(?:[^/*][^*]*\\\\*+)*/)|(?://.*\\\\n)|(?:\\`(?:\\\\\\\\.|[^\\`\\\\\\\\])*\\`)|(?:\"(?:\\\\\\\\.|[^\"\\\\\\\\])*\")|(?:'(?:\\\\\\\\.|[^'\\\\\\\\])*')|(?:\\\\[(?:[<>]?[Ii][Mm][Gg])?\\\\[[^\\\\r\\\\n]*?\\\\]\\\\]+)|[^>]|(?:>(?!>)))*)>>`,\"gm\"),working:{source:\"\",name:\"\",arguments:\"\",index:0},context:null,handler(w){const matchStart=this.lookahead.lastIndex=w.matchStart;if(this.parseTag(w)){const nextMatch=w.nextMatch,name=this.working.name,rawArgs=this.working.arguments;let macro;try{if(macro=Macro.get(name),!macro){if(Macro.tags.has(name)){const tags=Macro.tags.get(name);return appendError(w.output,`child tag <<${name}>> was found outside of a call to its parent macro${1===tags.length?\"\":\"s\"} <<${tags.join(\">>, <<\")}>>`,w.source.slice(matchStart,w.nextMatch))}return appendError(w.output,`macro <<${name}>> does not exist`,w.source.slice(matchStart,w.nextMatch))}{let payload=null;if(void 0!==macro.tags&&(payload=this.parseBody(w,macro),!payload))return w.nextMatch=nextMatch,appendError(w.output,`cannot find a closing tag for macro <<${name}>>`,`${w.source.slice(matchStart,w.nextMatch)}…`);if(\"function\"!=typeof macro.handler)return appendError(w.output,`macro <<${name}>> handler function ${void 0===macro.handler?\"does not exist\":\"is not a function\"}`,w.source.slice(matchStart,w.nextMatch));{const args=payload?payload[0].args:this.createArgs(rawArgs,this.skipArgs(macro,macro.name));if(void 0!==macro._MACRO_API){this.context=new MacroContext({macro:macro,name:name,args:args,payload:payload,source:w.source.slice(matchStart,w.nextMatch),parent:this.context,parser:w});try{macro.handler.call(this.context)}finally{this.context=this.context.parent}}else{console.warn(`[DEPRECATED] The legacy macro API, used by <<${name}>>, is deprecated.`);const prevRawArgs=w._rawArgs;w._rawArgs=rawArgs;try{macro.handler(w.output,name,args,w,payload)}finally{w._rawArgs=prevRawArgs}}}}}catch(ex){return appendError(w.output,`cannot execute ${macro&¯o.isWidget?\"widget\":\"macro\"} <<${name}>>: ${ex.message}`,w.source.slice(matchStart,w.nextMatch))}finally{this.working.source=\"\",this.working.name=\"\",this.working.arguments=\"\",this.working.index=0}}else w.outputText(w.output,w.matchStart,w.nextMatch)},parseTag(w){const match=this.lookahead.exec(w.source);return!(!match||match.index!==w.matchStart||!match[1])&&(w.nextMatch=this.lookahead.lastIndex,this.working.source=w.source.slice(match.index,this.lookahead.lastIndex),this.working.name=match[1],this.working.arguments=match[2],this.working.index=match.index,!0)},parseBody(w,macro){const openTag=this.working.name,closeTag=`/${openTag}`,closeAlt=`end${openTag}`,bodyTags=!!Array.isArray(macro.tags)&¯o.tags,payload=[];let end=-1,opened=1,curSource=this.working.source,curTag=this.working.name,curArgument=this.working.arguments,contentStart=w.nextMatch;for(;-1!==(w.matchStart=w.source.indexOf(this.match,w.nextMatch));){if(!this.parseTag(w)){this.lookahead.lastIndex=w.nextMatch=w.matchStart+this.match.length;continue}const tagSource=this.working.source,tagName=this.working.name,tagArgs=this.working.arguments,tagBegin=this.working.index,tagEnd=w.nextMatch,hasArgs=\"\"!==tagArgs.trim();switch(tagName){case openTag:++opened;break;case closeAlt:case closeTag:if(hasArgs)throw w.nextMatch=tagBegin+2+tagName.length,new Error(`malformed closing tag: \"${tagSource}\"`);--opened;break;default:if(hasArgs&&(tagName.startsWith(\"/\")||tagName.startsWith(\"end\"))){this.lookahead.lastIndex=w.nextMatch=tagBegin+2+tagName.length;continue}if(1===opened&&bodyTags)for(let i=0,iend=bodyTags.length;i<iend;++i)tagName===bodyTags[i]&&(payload.push({source:curSource,name:curTag,arguments:curArgument,args:this.createArgs(curArgument,this.skipArgs(macro,curTag)),contents:w.source.slice(contentStart,tagBegin)}),curSource=tagSource,curTag=tagName,curArgument=tagArgs,contentStart=tagEnd)}if(0===opened){payload.push({source:curSource,name:curTag,arguments:curArgument,args:this.createArgs(curArgument,this.skipArgs(macro,curTag)),contents:w.source.slice(contentStart,tagBegin)}),end=tagEnd;break}}return-1!==end?(w.nextMatch=end,payload):null},createArgs(rawArgsString,skipArgs){const args=skipArgs?[]:this.parseArgs(rawArgsString);return Object.defineProperties(args,{raw:{value:rawArgsString},full:{value:Scripting.desugar(rawArgsString)}}),args},skipArgs(macro,tagName){if(void 0!==macro.skipArgs){const sa=macro.skipArgs;return\"boolean\"==typeof sa&&sa||Array.isArray(sa)&&sa.includes(tagName)}return void 0!==macro.skipArg0&&(macro.skipArg0&¯o.name===tagName)},parseArgs:(()=>{const Item=Lexer.enumFromNames([\"Error\",\"Bareword\",\"Expression\",\"String\",\"SquareBracket\"]),spaceRe=new RegExp(Patterns.space),notSpaceRe=new RegExp(Patterns.notSpace),varTest=new RegExp(`^${Patterns.variable}`);function slurpQuote(lexer,endQuote){loop:for(;;)switch(lexer.next()){case\"\\\\\":{const ch=lexer.next();if(ch!==EOF&&\"\\n\"!==ch)break}case EOF:case\"\\n\":return EOF;case endQuote:break loop}return lexer.pos}function lexSpace(lexer){const offset=lexer.source.slice(lexer.pos).search(notSpaceRe);if(offset===EOF)return null;switch(0!==offset&&(lexer.pos+=offset,lexer.ignore()),lexer.next()){case\"`\":return lexExpression;case'\"':return lexDoubleQuote;case\"'\":return lexSingleQuote;case\"[\":return lexSquareBracket;default:return lexBareword}}function lexExpression(lexer){return slurpQuote(lexer,\"`\")===EOF?lexer.error(Item.Error,\"unterminated backquote expression\"):(lexer.emit(Item.Expression),lexSpace)}function lexDoubleQuote(lexer){return slurpQuote(lexer,'\"')===EOF?lexer.error(Item.Error,\"unterminated double quoted string\"):(lexer.emit(Item.String),lexSpace)}function lexSingleQuote(lexer){return slurpQuote(lexer,\"'\")===EOF?lexer.error(Item.Error,\"unterminated single quoted string\"):(lexer.emit(Item.String),lexSpace)}function lexSquareBracket(lexer){let what;if(lexer.accept(\"<>IiMmGg\")?(what=\"image\",lexer.acceptRun(\"<>IiMmGg\")):what=\"link\",!lexer.accept(\"[\"))return lexer.error(Item.Error,`malformed ${what} markup`);lexer.depth=2;loop:for(;;)switch(lexer.next()){case\"\\\\\":{const ch=lexer.next();if(ch!==EOF&&\"\\n\"!==ch)break}case EOF:case\"\\n\":return lexer.error(Item.Error,`unterminated ${what} markup`);case\"[\":++lexer.depth;break;case\"]\":if(--lexer.depth,lexer.depth<0)return lexer.error(Item.Error,\"unexpected right square bracket ']'\");if(1===lexer.depth){if(\"]\"===lexer.next()){--lexer.depth;break loop}lexer.backup()}}return lexer.emit(Item.SquareBracket),lexSpace}function lexBareword(lexer){const offset=lexer.source.slice(lexer.pos).search(spaceRe);return lexer.pos=offset===EOF?lexer.source.length:lexer.pos+offset,lexer.emit(Item.Bareword),offset===EOF?null:lexSpace}return function(rawArgsString){const lexer=new Lexer(rawArgsString,lexSpace),args=[];return lexer.run().forEach((item=>{let arg=item.text;switch(item.type){case Item.Error:throw new Error(`unable to parse macro argument \"${arg}\": ${item.message}`);case Item.Bareword:if(varTest.test(arg))arg=State.getVar(arg);else if(/^(?:settings|setup)[.[]/.test(arg))try{arg=Scripting.evalTwineScript(arg)}catch(ex){throw new Error(`unable to parse macro argument \"${arg}\": ${ex.message}`)}else if(\"null\"===arg)arg=null;else if(\"undefined\"===arg)arg=undefined;else if(\"true\"===arg)arg=!0;else if(\"false\"===arg)arg=!1;else if(\"NaN\"===arg)arg=NaN;else{const argAsNum=Number(arg);Number.isNaN(argAsNum)||(arg=argAsNum)}break;case Item.Expression:if(arg=arg.slice(1,-1).trim(),\"\"===arg)arg=undefined;else try{arg=Scripting.evalTwineScript(`(${arg})`)}catch(ex){throw new Error(`unable to parse macro argument expression \"${arg}\": ${ex.message}`)}break;case Item.String:try{arg=Scripting.evalJavaScript(arg)}catch(ex){throw new Error(`unable to parse macro argument string \"${arg}\": ${ex.message}`)}break;case Item.SquareBracket:{const markup=Wikifier.helpers.parseSquareBracketedMarkup({source:arg,matchStart:0});if(Object.hasOwn(markup,\"error\"))throw new Error(`unable to parse macro argument \"${arg}\": ${markup.error}`);if(markup.pos<arg.length)throw new Error(`unable to parse macro argument \"${arg}\": unexpected character(s) \"${arg.slice(markup.pos)}\" (pos: ${markup.pos})`);markup.isLink?(arg={isLink:!0},arg.count=Object.hasOwn(markup,\"text\")?2:1,arg.link=Wikifier.helpers.evalPassageId(markup.link),arg.text=Object.hasOwn(markup,\"text\")?Wikifier.helpers.evalText(markup.text):arg.link,arg.external=!markup.forceInternal&&Wikifier.isExternalLink(arg.link),arg.setFn=Object.hasOwn(markup,\"setter\")?Wikifier.helpers.shadowHandler(Scripting.desugar(markup.setter)):null):markup.isImage&&(arg=(source=>{const imgObj={source:source,isImage:!0};if(\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);passage.tags.includes(\"Twine.image\")&&(imgObj.source=passage.text,imgObj.passage=passage.name)}return imgObj})(Wikifier.helpers.evalPassageId(markup.source)),Object.hasOwn(markup,\"align\")&&(arg.align=markup.align),Object.hasOwn(markup,\"text\")&&(arg.title=Wikifier.helpers.evalText(markup.text)),Object.hasOwn(markup,\"link\")&&(arg.link=Wikifier.helpers.evalPassageId(markup.link),arg.external=!markup.forceInternal&&Wikifier.isExternalLink(arg.link)),arg.setFn=Object.hasOwn(markup,\"setter\")?Wikifier.helpers.shadowHandler(Scripting.desugar(markup.setter)):null);break}}args.push(arg)})),args}})()}),Wikifier.Parser.add({name:\"link\",profiles:[\"core\"],match:\"\\\\[\\\\[[^[]\",handler(w){const markup=Wikifier.helpers.parseSquareBracketedMarkup(w);if(Object.hasOwn(markup,\"error\"))return void w.outputText(w.output,w.matchStart,w.nextMatch);w.nextMatch=markup.pos;const link=Wikifier.helpers.evalPassageId(markup.link),text=Object.hasOwn(markup,\"text\")?Wikifier.helpers.evalText(markup.text):link,setFn=Object.hasOwn(markup,\"setter\")?Wikifier.helpers.shadowHandler(Scripting.desugar(markup.setter)):null,output=(Config.debug?new DebugView(w.output,\"link-markup\",\"[[link]]\",w.source.slice(w.matchStart,w.nextMatch)):w).output;markup.forceInternal||!Wikifier.isExternalLink(link)?Wikifier.createInternalLink(output,link,text,setFn):Wikifier.createExternalLink(output,link,text)}}),Wikifier.Parser.add({name:\"urlLink\",profiles:[\"core\"],match:Patterns.url,handler(w){w.outputText(Wikifier.createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch)}}),Wikifier.Parser.add({name:\"image\",profiles:[\"core\"],match:\"\\\\[[<>]?[Ii][Mm][Gg]\\\\[\",handler(w){const markup=Wikifier.helpers.parseSquareBracketedMarkup(w);if(Object.hasOwn(markup,\"error\"))return void w.outputText(w.output,w.matchStart,w.nextMatch);let debugView;w.nextMatch=markup.pos,Config.debug&&(debugView=new DebugView(w.output,\"image-markup\",Object.hasOwn(markup,\"link\")?\"[img[][link]]\":\"[img[]]\",w.source.slice(w.matchStart,w.nextMatch)),debugView.modes({block:!0}));const setFn=Object.hasOwn(markup,\"setter\")?Wikifier.helpers.shadowHandler(Scripting.desugar(markup.setter)):null;let source,el=(Config.debug?debugView:w).output;if(Object.hasOwn(markup,\"link\")){const link=Wikifier.helpers.evalPassageId(markup.link);el=markup.forceInternal||!Wikifier.isExternalLink(link)?Wikifier.createInternalLink(el,link,null,setFn):Wikifier.createExternalLink(el,link),el.classList.add(\"link-image\")}if(el=jQuery(document.createElement(\"img\")).appendTo(el).get(0),source=Wikifier.helpers.evalPassageId(markup.source),\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);passage.tags.includes(\"Twine.image\")&&(el.setAttribute(\"data-passage\",passage.name),source=passage.text.trim())}el.src=source,Object.hasOwn(markup,\"text\")&&(el.title=Wikifier.helpers.evalText(markup.text)),Object.hasOwn(markup,\"align\")&&(el.align=markup.align)}}),Wikifier.Parser.add({name:\"monospacedByBlock\",profiles:[\"block\"],match:\"^\\\\{\\\\{\\\\{\\\\n\",lookahead:/^\\{\\{\\{\\n((?:^[^\\n]*\\n)+?)(^\\}\\}\\}$\\n?)/gm,handler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);if(match&&match.index===w.matchStart){const pre=jQuery(document.createElement(\"pre\"));jQuery(document.createElement(\"code\")).text(match[1]).appendTo(pre),pre.appendTo(w.output),w.nextMatch=this.lookahead.lastIndex}}}),Wikifier.Parser.add({name:\"formatByChar\",profiles:[\"core\"],match:\"''|//|__|\\\\^\\\\^|~~|==|\\\\{\\\\{\\\\{\",handler(w){switch(w.matchText){case\"''\":w.subWikify(jQuery(document.createElement(\"strong\")).appendTo(w.output).get(0),\"''\");break;case\"//\":w.subWikify(jQuery(document.createElement(\"em\")).appendTo(w.output).get(0),\"//\");break;case\"__\":w.subWikify(jQuery(document.createElement(\"u\")).appendTo(w.output).get(0),\"__\");break;case\"^^\":w.subWikify(jQuery(document.createElement(\"sup\")).appendTo(w.output).get(0),\"\\\\^\\\\^\");break;case\"~~\":w.subWikify(jQuery(document.createElement(\"sub\")).appendTo(w.output).get(0),\"~~\");break;case\"==\":w.subWikify(jQuery(document.createElement(\"s\")).appendTo(w.output).get(0),\"==\");break;case\"{{{\":{const lookahead=/\\{\\{\\{((?:.|\\n)*?)\\}\\}\\}/gm;lookahead.lastIndex=w.matchStart;const match=lookahead.exec(w.source);match&&match.index===w.matchStart&&(jQuery(document.createElement(\"code\")).text(match[1]).appendTo(w.output),w.nextMatch=lookahead.lastIndex);break}}}}),Wikifier.Parser.add({name:\"customStyle\",profiles:[\"core\"],match:\"@@\",terminator:\"@@\",blockRe:/\\s*\\n/gm,handler(w){const css=Wikifier.helpers.inlineCss(w);this.blockRe.lastIndex=w.nextMatch;const blockMatch=this.blockRe.exec(w.source),blockLevel=blockMatch&&blockMatch.index===w.nextMatch,$el=jQuery(document.createElement(blockLevel?\"div\":\"span\")).appendTo(w.output);0===css.classes.length&&\"\"===css.id&&0===Object.keys(css.styles).length?$el.addClass(\"marked\"):(css.classes.forEach((className=>$el.addClass(className))),\"\"!==css.id&&$el.attr(\"id\",css.id),$el.css(css.styles)),blockLevel?(w.nextMatch+=blockMatch[0].length,w.subWikify($el[0],`\\\\n?${this.terminator}`)):w.subWikify($el[0],this.terminator)}}),Wikifier.Parser.add({name:\"verbatimText\",profiles:[\"core\"],match:'\"{3}|<[Nn][Oo][Ww][Ii][Kk][Ii]>',lookahead:/(?:\"{3}((?:.|\\n)*?)\"{3})|(?:<[Nn][Oo][Ww][Ii][Kk][Ii]>((?:.|\\n)*?)<\\/[Nn][Oo][Ww][Ii][Kk][Ii]>)/gm,handler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);match&&match.index===w.matchStart&&(w.nextMatch=this.lookahead.lastIndex,jQuery(document.createElement(\"span\")).addClass(\"verbatim\").text(match[1]||match[2]).appendTo(w.output))}}),Wikifier.Parser.add({name:\"horizontalRule\",profiles:[\"core\"],match:\"^----+\\\\s*$\",handler(w){jQuery(document.createElement(\"hr\")).appendTo(w.output)}}),Wikifier.Parser.add({name:\"emdash\",profiles:[\"core\"],match:\"--\",handler(w){jQuery(document.createTextNode(\"—\")).appendTo(w.output)}}),Wikifier.Parser.add({name:\"doubleDollarSign\",profiles:[\"core\"],match:\"\\\\${2}\",handler(w){jQuery(document.createTextNode(\"$\")).appendTo(w.output)}}),Wikifier.Parser.add({name:\"nakedVariable\",profiles:[\"core\"],match:`${Patterns.variable}(?:(?:\\\\.${Patterns.identifier})|(?:\\\\[\\\\d+\\\\])|(?:\\\\[\"(?:\\\\\\\\.|[^\"\\\\\\\\])+\"\\\\])|(?:\\\\['(?:\\\\\\\\.|[^'\\\\\\\\])+'\\\\])|(?:\\\\[${Patterns.variable}\\\\]))*`,handler(w){const result=State.getVar(w.matchText);null==result?jQuery(document.createTextNode(w.matchText)).appendTo(w.output):new Wikifier((Config.debug?new DebugView(w.output,\"variable\",w.matchText,w.matchText):w).output,stringFrom(result))}}),Wikifier.Parser.add({name:\"template\",profiles:[\"core\"],match:`\\\\?${Patterns.templateName}`,handler(w){const name=w.matchText.slice(1);let template=Template.get(name),result=null;switch(template instanceof Array&&(template=template.random()),typeof template){case\"function\":try{result=stringFrom(template.call({name:name}))}catch(ex){return appendError(w.output,`cannot execute function template ?${name}: ${ex.message}`,w.source.slice(w.matchStart,w.nextMatch))}break;case\"string\":result=template}null===result?jQuery(document.createTextNode(w.matchText)).appendTo(w.output):new Wikifier((Config.debug?new DebugView(w.output,\"template\",w.matchText,w.matchText):w).output,result)}}),Wikifier.Parser.add({name:\"heading\",profiles:[\"block\"],match:\"^!{1,6}\",terminator:\"\\\\n\",handler(w){Wikifier.helpers.hasBlockContext(w.output.childNodes)?w.subWikify(jQuery(document.createElement(`h${w.matchLength}`)).appendTo(w.output).get(0),this.terminator):jQuery(w.output).append(document.createTextNode(w.matchText))}}),Wikifier.Parser.add({name:\"table\",profiles:[\"block\"],match:\"^\\\\|(?:[^\\\\n]*)\\\\|(?:[fhck]?)$\",lookahead:/^\\|([^\\n]*)\\|([fhck]?)$/gm,rowTerminator:\"\\\\|(?:[cfhk]?)$\\\\n?\",cellPattern:\"(?:\\\\|([^\\\\n\\\\|]*)\\\\|)|(\\\\|[cfhk]?$\\\\n?)\",cellTerminator:\"(?:\\\\u0020*)\\\\|\",rowTypes:{c:\"caption\",f:\"tfoot\",h:\"thead\",\"\":\"tbody\"},handler(w){if(!Wikifier.helpers.hasBlockContext(w.output.childNodes))return void jQuery(w.output).append(document.createTextNode(w.matchText));const table=jQuery(document.createElement(\"table\")).appendTo(w.output).get(0),prevColumns=[];let matched,curRowType=null,$rowContainer=null,rowCount=0;w.nextMatch=w.matchStart;do{this.lookahead.lastIndex=w.nextMatch;const match=this.lookahead.exec(w.source);if(matched=match&&match.index===w.nextMatch,matched){const nextRowType=match[2];\"k\"===nextRowType?(table.className=match[1],w.nextMatch+=match[0].length+1):(nextRowType!==curRowType&&(curRowType=nextRowType,$rowContainer=jQuery(document.createElement(this.rowTypes[nextRowType])).appendTo(table)),\"c\"===curRowType?($rowContainer.css(\"caption-side\",0===rowCount?\"top\":\"bottom\"),w.nextMatch+=1,w.subWikify($rowContainer[0],this.rowTerminator)):this.rowHandler(w,jQuery(document.createElement(\"tr\")).appendTo($rowContainer).get(0),prevColumns),++rowCount)}}while(matched)},rowHandler(w,rowEl,prevColumns){const cellRe=new RegExp(this.cellPattern,\"gm\");let matched,col=0,curColCount=1;do{cellRe.lastIndex=w.nextMatch;const cellMatch=cellRe.exec(w.source);if(matched=cellMatch&&cellMatch.index===w.nextMatch,matched){if(\"~\"===cellMatch[1]){const last=prevColumns[col];last&&(++last.rowCount,last.$element.attr(\"rowspan\",last.rowCount).css(\"vertical-align\",\"middle\")),w.nextMatch=cellMatch.index+cellMatch[0].length-1}else if(\">\"===cellMatch[1])++curColCount,w.nextMatch=cellMatch.index+cellMatch[0].length-1;else{if(cellMatch[2]){w.nextMatch=cellMatch.index+cellMatch[0].length;break}{++w.nextMatch;const css=Wikifier.helpers.inlineCss(w);let $cell,spaceLeft=!1,spaceRight=!1;for(;\" \"===w.source.substr(w.nextMatch,1);)spaceLeft=!0,++w.nextMatch;\"!\"===w.source.substr(w.nextMatch,1)?($cell=jQuery(document.createElement(\"th\")).appendTo(rowEl),++w.nextMatch):$cell=jQuery(document.createElement(\"td\")).appendTo(rowEl),prevColumns[col]={rowCount:1,$element:$cell},curColCount>1&&($cell.attr(\"colspan\",curColCount),curColCount=1),w.subWikify($cell[0],this.cellTerminator),\" \"===w.matchText.substr(w.matchText.length-2,1)&&(spaceRight=!0),css.classes.forEach((className=>$cell.addClass(className))),\"\"!==css.id&&$cell.attr(\"id\",css.id),spaceLeft&&spaceRight?css.styles[\"text-align\"]=\"center\":spaceLeft?css.styles[\"text-align\"]=\"right\":spaceRight&&(css.styles[\"text-align\"]=\"left\"),$cell.css(css.styles),w.nextMatch=w.nextMatch-1}}++col}}while(matched)}}),Wikifier.Parser.add({name:\"list\",profiles:[\"block\"],match:\"^(?:(?:\\\\*+)|(?:#+))\",lookahead:/^(?:(\\*+)|(#+))/gm,terminator:\"\\\\n\",handler(w){if(!Wikifier.helpers.hasBlockContext(w.output.childNodes))return void jQuery(w.output).append(document.createTextNode(w.matchText));w.nextMatch=w.matchStart;const destStack=[w.output];let matched,i,curType=null,curLevel=0;do{this.lookahead.lastIndex=w.nextMatch;const match=this.lookahead.exec(w.source);if(matched=match&&match.index===w.nextMatch,matched){const newType=match[2]?\"ol\":\"ul\",newLevel=match[0].length;if(w.nextMatch+=match[0].length,newLevel>curLevel)for(i=curLevel;i<newLevel;++i)destStack.push(jQuery(document.createElement(newType)).appendTo(destStack[destStack.length-1]).get(0));else if(newLevel<curLevel)for(i=curLevel;i>newLevel;--i)destStack.pop();else newLevel===curLevel&&newType!==curType&&(destStack.pop(),destStack.push(jQuery(document.createElement(newType)).appendTo(destStack[destStack.length-1]).get(0)));curLevel=newLevel,curType=newType,w.subWikify(jQuery(document.createElement(\"li\")).appendTo(destStack[destStack.length-1]).get(0),this.terminator)}}while(matched)}}),Wikifier.Parser.add({name:\"commentByBlock\",profiles:[\"core\"],match:\"(?:/(?:%|\\\\*))|(?:\\x3c!--)\",lookahead:/(?:\\/(%|\\*)(?:(?:.|\\n)*?)\\1\\/)|(?:<!--(?:(?:.|\\n)*?)-->)/gm,handler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);match&&match.index===w.matchStart&&(w.nextMatch=this.lookahead.lastIndex)}}),Wikifier.Parser.add({name:\"lineContinuation\",profiles:[\"core\"],match:`\\\\\\\\${Patterns.spaceNoTerminator}*\\\\n|\\\\n${Patterns.spaceNoTerminator}*\\\\\\\\|\\\\n?\\\\\\\\${Patterns.spaceNoTerminator}*$|^${Patterns.spaceNoTerminator}*\\\\\\\\\\\\n?`,handler(w){w.nextMatch=w.matchStart+w.matchLength}}),Wikifier.Parser.add({name:\"lineBreak\",profiles:[\"core\"],match:\"\\\\n\",handler(w){w.options.nobr||jQuery(document.createElement(\"br\")).appendTo(w.output)}}),Wikifier.Parser.add({name:\"htmlCharacterReference\",profiles:[\"core\"],match:\"(?:(?:&#?[0-9A-Za-z]{2,8};|.)(?:&#?(?:x0*(?:3[0-6][0-9A-Fa-f]|1D[C-Fc-f][0-9A-Fa-f]|20[D-Fd-f][0-9A-Fa-f]|FE2[0-9A-Fa-f])|0*(?:76[89]|7[7-9][0-9]|8[0-7][0-9]|761[6-9]|76[2-7][0-9]|84[0-3][0-9]|844[0-7]|6505[6-9]|6506[0-9]|6507[0-1]));)+|&#?[0-9A-Za-z]{2,8};)\",handler(w){jQuery(document.createDocumentFragment()).append(w.matchText).appendTo(w.output)}}),Wikifier.Parser.add({name:\"xmlProlog\",profiles:[\"core\"],match:\"<\\\\?[Xx][Mm][Ll][^>]*\\\\?>\",handler(w){w.nextMatch=w.matchStart+w.matchLength}}),Wikifier.Parser.add({name:\"verbatimHtml\",profiles:[\"core\"],match:\"<[Hh][Tt][Mm][Ll]>\",lookahead:/<[Hh][Tt][Mm][Ll]>((?:.|\\n)*?)<\\/[Hh][Tt][Mm][Ll]>/gm,handler:_verbatimTagHandler}),Wikifier.Parser.add({name:\"verbatimScriptTag\",profiles:[\"core\"],match:\"<[Ss][Cc][Rr][Ii][Pp][Tt][^>]*>\",lookahead:/(<[Ss][Cc][Rr][Ii][Pp][Tt][^>]*>(?:.|\\n)*?<\\/[Ss][Cc][Rr][Ii][Pp][Tt]>)/gm,handler:_verbatimTagHandler}),Wikifier.Parser.add({name:\"styleTag\",profiles:[\"core\"],match:\"<[Ss][Tt][Yy][Ll][Ee][^>]*>\",lookahead:/(<[Ss][Tt][Yy][Ll][Ee][^>]*>)((?:.|\\n)*?)(<\\/[Ss][Tt][Yy][Ll][Ee]>)/gm,imageMarkup:new RegExp(Patterns.cssImage,\"g\"),hasImageMarkup:new RegExp(Patterns.cssImage),handler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);if(match&&match.index===w.matchStart){w.nextMatch=this.lookahead.lastIndex;let css=match[2];this.hasImageMarkup.test(css)&&(this.imageMarkup.lastIndex=0,css=css.replace(this.imageMarkup,(wikiImage=>{const markup=Wikifier.helpers.parseSquareBracketedMarkup({source:wikiImage,matchStart:0});if(Object.hasOwn(markup,\"error\")||markup.pos<wikiImage.length)return wikiImage;let source=Wikifier.helpers.evalPassageId(markup.source);if(\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);passage.tags.includes(\"Twine.image\")&&(source=passage.text)}return`url(\"${source.replace(/\"/g,\"%22\")}\")`}))),jQuery(document.createDocumentFragment()).append(match[1]+css+match[3]).appendTo(w.output)}}}),Wikifier.Parser.add({name:\"svgTag\",profiles:[\"core\"],match:\"<[Ss][Vv][Gg][^>]*>\",lookahead:/<(\\/?)[Ss][Vv][Gg][^>]*>/gm,namespace:\"http://www.w3.org/2000/svg\",handler(w){this.lookahead.lastIndex=w.nextMatch;let match,depth=1;for(;depth>0&&null!==(match=this.lookahead.exec(w.source));)depth+=\"/\"===match[1]?-1:1;if(0===depth){w.nextMatch=this.lookahead.lastIndex;const svgTag=w.source.slice(w.matchStart,this.lookahead.lastIndex),$frag=jQuery(document.createDocumentFragment()).append(svgTag);$frag.find(\"a[data-passage],image[data-passage]\").each(((_,el)=>{const tagName=el.tagName.toLowerCase();try{this.processAttributeDirectives(el)}catch(ex){return appendError(w.output,`svg|<${tagName}>: ${ex.message}`,`${w.matchText}…`)}el.hasAttribute(\"data-passage\")&&this.processDataAttributes(el,tagName)})),$frag.appendTo(w.output)}},processAttributeDirectives(el){Array.from(el.attributes).forEach((({name:name,value:value})=>{const evalShorthand=\"@\"===name[0];if(evalShorthand||name.startsWith(\"sc-eval:\")){const newName=name.slice(evalShorthand?1:8);if(\"data-setter\"===newName)throw new Error(`evaluation directive is not allowed on the data-setter attribute: \"${name}\"`);let result;try{result=Scripting.evalTwineScript(value)}catch(ex){throw new Error(`bad evaluation from attribute directive \"${name}\": ${ex.message}`)}try{el.setAttribute(newName,result),el.removeAttribute(name)}catch(ex){throw new Error(`cannot transform attribute directive \"${name}\" into attribute \"${newName}\"`)}}}))},processDataAttributes(el,tagName){let passage=el.getAttribute(\"data-passage\");if(null==passage)return;const evaluated=Wikifier.helpers.evalPassageId(passage);if(evaluated!==passage&&(passage=evaluated,el.setAttribute(\"data-passage\",evaluated)),\"\"!==passage)if(\"image\"===tagName)\"data:\"!==passage.slice(0,5)&&Story.has(passage)&&(passage=Story.get(passage),passage.tags.includes(\"Twine.image\")&&el.setAttribute(\"href\",passage.text.trim()));else{let setFn,setter=el.getAttribute(\"data-setter\");null!=setter&&(setter=String(setter).trim(),\"\"!==setter&&(setFn=Wikifier.helpers.shadowHandler(Scripting.desugar(setter)))),Story.has(passage)?(el.classList.add(\"link-internal\"),Config.addVisitedLinkClass&&State.hasPlayed(passage)&&el.classList.add(\"link-visited\")):el.classList.add(\"link-broken\"),jQuery(el).ariaClick({one:!0},(function(){\"function\"==typeof setFn&&setFn.call(this),Engine.play(passage)}))}}}),Wikifier.Parser.add({name:\"htmlTag\",profiles:[\"core\"],match:`<${Patterns.htmlTagName}(?:\\\\s+[^\\\\u0000-\\\\u001F\\\\u007F-\\\\u009F\\\\s\"'>\\\\/=]+(?:\\\\s*=\\\\s*(?:\"[^\"]*?\"|'[^']*?'|[^\\\\s\"'=<>\\`]+))?)*\\\\s*\\\\/?>`,tagRe:new RegExp(`^<(${Patterns.htmlTagName})`),mediaTags:[\"audio\",\"img\",\"source\",\"track\",\"video\"],nobrTags:[\"audio\",\"colgroup\",\"datalist\",\"dl\",\"figure\",\"meter\",\"ol\",\"optgroup\",\"picture\",\"progress\",\"ruby\",\"select\",\"table\",\"tbody\",\"tfoot\",\"thead\",\"tr\",\"ul\",\"video\"],voidTags:[\"area\",\"base\",\"br\",\"col\",\"embed\",\"hr\",\"img\",\"input\",\"keygen\",\"link\",\"menuitem\",\"meta\",\"param\",\"source\",\"track\",\"wbr\"],handler(w){const tagMatch=this.tagRe.exec(w.matchText),tag=tagMatch&&tagMatch[1],tagName=tag&&tag.toLowerCase();if(tagName){const isVoid=this.voidTags.includes(tagName)||w.matchText.endsWith(\"/>\"),isNobr=this.nobrTags.includes(tagName);let terminator,terminatorMatch;if(!isVoid){terminator=`<\\\\/${tagName}\\\\s*>`;const terminatorRe=new RegExp(terminator,\"gim\");terminatorRe.lastIndex=w.matchStart,terminatorMatch=terminatorRe.exec(w.source)}if(!isVoid&&!terminatorMatch)return appendError(w.output,`cannot find a closing tag for HTML <${tag}>`,`${w.matchText}…`);{let debugView,output=w.output,el=document.createElement(w.output.tagName);for(el.innerHTML=w.matchText;el.firstChild;)el=el.firstChild;try{this.processAttributeDirectives(el)}catch(ex){return appendError(w.output,`<${tagName}>: ${ex.message}`,`${w.matchText}…`)}if(el.hasAttribute(\"data-passage\")){if(el.hasAttribute(\"href\"))return appendError(w.output,`<${tagName}>: elements may not include both \"data-passage\" and \"href\" atttributes`,`${w.matchText}…`);this.processDataAttributes(el,tagName),Config.debug&&(debugView=new DebugView(w.output,`html-${tagName}`,tagName,w.matchText),debugView.modes({block:\"img\"===tagName,nonvoid:terminatorMatch}),output=debugView.output)}else el.hasAttribute(\"href\")&&Wikifier.isExternalLink(el.getAttribute(\"href\"))&&el.classList.add(\"link-external\");if(terminatorMatch){try{Wikifier.Option.push({nobr:isNobr}),w.subWikify(el,terminator,{ignoreTerminatorCase:!0})}finally{Wikifier.Option.pop()}debugView&&jQuery(el).find(\".debug.block\").length>0&&debugView.modes({block:!0})}output.appendChild(\"track\"===tagName?el.cloneNode(!0):el)}}},processAttributeDirectives(el){Array.from(el.attributes).forEach((({name:name,value:value})=>{const evalShorthand=\"@\"===name[0];if(evalShorthand||name.startsWith(\"sc-eval:\")){const newName=name.slice(evalShorthand?1:8);if(\"data-setter\"===newName)throw new Error(`evaluation directive is not allowed on the data-setter attribute: \"${name}\"`);let result;try{result=Scripting.evalTwineScript(value)}catch(ex){throw new Error(`bad evaluation from attribute directive \"${name}\": ${ex.message}`)}try{el.setAttribute(newName,result),el.removeAttribute(name)}catch(ex){throw new Error(`cannot transform attribute directive \"${name}\" into attribute \"${newName}\"`)}}}))},processDataAttributes(el,tagName){let passage=el.getAttribute(\"data-passage\");if(null==passage)return;const evaluated=Wikifier.helpers.evalPassageId(passage);if(evaluated!==passage&&(passage=evaluated,el.setAttribute(\"data-passage\",evaluated)),\"\"!==passage)if(this.mediaTags.includes(tagName)){if(\"data:\"!==passage.slice(0,5)&&Story.has(passage)){let parentName,twineTag;switch(passage=Story.get(passage),tagName){case\"audio\":case\"video\":twineTag=`Twine.${tagName}`;break;case\"img\":twineTag=\"Twine.image\";break;case\"track\":twineTag=\"Twine.vtt\";break;case\"source\":{const $parent=$(el).closest(\"audio,picture,video\");$parent.length>0&&(parentName=$parent.get(0).tagName.toLowerCase(),twineTag=`Twine.${\"picture\"===parentName?\"image\":parentName}`);break}}passage.tags.includes(twineTag)&&(el[\"picture\"===parentName?\"srcset\":\"src\"]=passage.text.trim())}}else{let setFn,setter=el.getAttribute(\"data-setter\");null!=setter&&(setter=String(setter).trim(),\"\"!==setter&&(setFn=Wikifier.helpers.shadowHandler(Scripting.desugar(setter)))),Story.has(passage)?(el.classList.add(\"link-internal\"),Config.addVisitedLinkClass&&State.hasPlayed(passage)&&el.classList.add(\"link-visited\")):el.classList.add(\"link-broken\"),jQuery(el).ariaClick({one:!0},(function(){\"function\"==typeof setFn&&setFn.call(this),Engine.play(passage)}))}}})})();var Template=(()=>{const _templates=new Map,_validNameRe=new RegExp(`^(?:${Patterns.templateName})$`),_validType=template=>{const templateType=typeof template;return\"function\"===templateType||\"string\"===templateType};return Object.preventExtensions(Object.create(null,{add:{value:function(name,template){if(!(_validType(template)||template instanceof Array&&template.length>0&&template.every(_validType)))throw new TypeError(`invalid template type (${name}); templates must be: functions, strings, or an array of either`);(name instanceof Array?name:[name]).forEach((name=>{if(!_validNameRe.test(name))throw new Error(`invalid template name \"${name}\"`);if(_templates.has(name))throw new Error(`cannot clobber existing template ?${name}`);_templates.set(name,template)}))}},delete:{value:function(name){(name instanceof Array?name:[name]).forEach((name=>_templates.delete(name)))}},get:{value:function(name){return _templates.has(name)?_templates.get(name):null}},has:{value:function(name){return _templates.has(name)}},size:{get:function(){return _templates.size}}}))})(),Macro=(()=>{const _macros={},_tags={},_validNameRe=new RegExp(`^(?:${Patterns.macroName})$`);function macrosHas(name){return Object.hasOwn(_macros,name)}function tagsRegister(parent,bodyTags){if(!parent)throw new Error(\"no parent specified\");const allTags=[].concat([`/${parent}`,`end${parent}`],Array.isArray(bodyTags)?bodyTags:[]);for(let i=0;i<allTags.length;++i){const tag=allTags[i];if(macrosHas(tag))throw new Error(\"cannot register tag for an existing macro\");tagsHas(tag)?_tags[tag].includes(parent)||(_tags[tag].push(parent),_tags[tag].sort()):_tags[tag]=[parent]}}function tagsUnregister(parent){if(!parent)throw new Error(\"no parent specified\");Object.keys(_tags).forEach((tag=>{const i=_tags[tag].indexOf(parent);-1!==i&&(1===_tags[tag].length?delete _tags[tag]:_tags[tag].splice(i,1))}))}function tagsHas(name){return Object.hasOwn(_tags,name)}return Object.preventExtensions(Object.create(null,{add:{value:function macrosAdd(name,def){if(Array.isArray(name))name.forEach((name=>macrosAdd(name,def)));else{if(!_validNameRe.test(name))throw new Error(`invalid macro name \"${name}\"`);if(macrosHas(name))throw new Error(`cannot clobber existing macro <<${name}>>`);if(tagsHas(name))throw new Error(`cannot clobber child tag <<${name}>> of parent macro${1===_tags[name].length?\"\":\"s\"} <<${_tags[name].join(\">>, <<\")}>>`);try{if(\"object\"==typeof def)_macros[name]=Object.assign(Object.create(null),def,{_MACRO_API:!0});else{if(!macrosHas(def))throw new Error(`cannot create alias of nonexistent macro <<${def}>>`);_macros[name]=Object.create(_macros[def],{_ALIAS_OF:{enumerable:!0,value:def}})}Object.defineProperty(_macros,name,{writable:!1})}catch(ex){throw\"TypeError\"===ex.name?new Error(`cannot clobber protected macro <<${name}>>`):new Error(`unknown error when attempting to add macro <<${name}>>: [${ex.name}] ${ex.message}`)}if(void 0!==_macros[name].tags)if(null==_macros[name].tags)tagsRegister(name);else{if(!Array.isArray(_macros[name].tags))throw new Error(`bad value for \"tags\" property of macro <<${name}>>`);tagsRegister(name,_macros[name].tags)}}}},delete:{value:function macrosDelete(name){if(Array.isArray(name))name.forEach((name=>macrosDelete(name)));else if(macrosHas(name)){void 0!==_macros[name].tags&&tagsUnregister(name);try{Object.defineProperty(_macros,name,{writable:!0}),delete _macros[name]}catch(ex){throw new Error(`unknown error removing macro <<${name}>>: ${ex.message}`)}}else if(tagsHas(name))throw new Error(`cannot remove child tag <<${name}>> of parent macro <<${_tags[name]}>>`)}},isEmpty:{value:function(){return 0===Object.keys(_macros).length}},has:{value:macrosHas},get:{value:function(name){let macro=null;return macrosHas(name)&&\"function\"==typeof _macros[name].handler?macro=_macros[name]:Object.hasOwn(macros,name)&&\"function\"==typeof macros[name].handler&&(macro=macros[name]),macro}},init:{value:function(handler=\"init\"){Object.keys(_macros).forEach((name=>{\"function\"==typeof _macros[name][handler]&&_macros[name][handler](name)})),Object.keys(macros).forEach((name=>{\"function\"==typeof macros[name][handler]&¯os[name][handler](name)}))}},tags:{value:Object.preventExtensions(Object.create(null,{register:{value:tagsRegister},unregister:{value:tagsUnregister},has:{value:tagsHas},get:{value:function(name){return tagsHas(name)?_tags[name]:null}}}))},evalStatements:{value:(...args)=>Scripting.evalJavaScript(...args)}}))})(),MacroContext=(()=>{class MacroContext{constructor(contextData){const context=Object.assign({parent:null,macro:null,name:\"\",displayName:\"\",args:null,payload:null,parser:null,source:\"\"},contextData);if(null===context.macro||\"\"===context.name||null===context.parser)throw new TypeError(\"context object missing required properties\");Object.defineProperties(this,{self:{value:context.macro},name:{value:void 0===context.macro._ALIAS_OF?context.name:context.macro._ALIAS_OF},displayName:{value:context.name},args:{value:context.args},payload:{value:context.payload},source:{value:context.source},parent:{value:context.parent},parser:{value:context.parser},_output:{value:context.parser.output},_shadows:{writable:!0,value:null},_debugView:{writable:!0,value:null},_debugViewEnabled:{writable:!0,value:Config.debug}})}get output(){return this._debugViewEnabled?this.debugView.output:this._output}get shadows(){return Array.from(this._shadows)}get shadowView(){const view=new Set;for(let context=this;null!==context;context=context.parent)context._shadows&&context._shadows.forEach((name=>view.add(name)));return Array.from(view)}get debugView(){return this._debugViewEnabled?null!==this._debugView?this._debugView:this.createDebugView():null}contextFilter(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"<MacroContext>.contextFilter() predicate parameter must be a function\");const result=[];for(let context=this.parent;null!==context;context=context.parent)predicate.call(void 0===thisArg?this:thisArg,context)&&result.push(context);return result}contextFind(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"<MacroContext>.contextFind() predicate parameter must be a function\");for(let context=this.parent;null!==context;context=context.parent)if(predicate.call(void 0===thisArg?this:thisArg,context))return context}contextSome(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"<MacroContext>.contextSome() predicate parameter must be a function\");for(let context=this.parent;null!==context;context=context.parent)if(predicate.call(void 0===thisArg?this:thisArg,context))return!0;return!1}addShadow(...names){this._shadows||(this._shadows=new Set);const varRe=new RegExp(`^${Patterns.variable}$`);names.flat(1/0).forEach((name=>{if(\"string\"!=typeof name)throw new TypeError(\"variable name must be a string; type: \"+typeof name);if(!varRe.test(name))throw new Error(`invalid variable name \"${name}\"`);this._shadows.add(name)}))}shadowHandler(callback,doneCallback,startCallback){const shadowContext=this;let shadowStore;return\"function\"==typeof callback&&(shadowStore=Object.create(null),this.shadowView.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;shadowStore[varName]=store[varKey]}))),function(...args){if(\"function\"==typeof startCallback&&startCallback.apply(this,args),\"function\"==typeof callback){const shadowNames=Object.keys(shadowStore),valueCache=shadowNames.length>0?{}:null,macroParser=Wikifier.Parser.get(\"macro\");let contextCache;try{shadowNames.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;Object.hasOwn(store,varKey)&&(valueCache[varKey]=store[varKey]),store[varKey]=shadowStore[varName]})),contextCache=macroParser.context,macroParser.context=shadowContext,callback.apply(this,args)}finally{contextCache!==undefined&&(macroParser.context=contextCache),shadowNames.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;shadowStore[varName]=store[varKey],Object.hasOwn(valueCache,varKey)?store[varKey]=valueCache[varKey]:delete store[varKey]}))}}\"function\"==typeof doneCallback&&doneCallback.apply(this,args)}}createDebugView(name,title){return this._debugView=new DebugView(this._output,\"macro\",name||this.displayName,title||this.source),null!==this.payload&&this.payload.length>0&&this._debugView.modes({nonvoid:!0}),this._debugViewEnabled=!0,this._debugView}removeDebugView(){null!==this._debugView&&(this._debugView.remove(),this._debugView=null),this._debugViewEnabled=!1}error(message,source,stack){return appendError(this._output,`<<${this.displayName}>>: ${message}`,source||this.source,stack)}}return Object.defineProperties(MacroContext.prototype,{contextHas:{value(...args){return console.warn(\"[DEPRECATED] <MacroContext>.contextHas() is deprecated.\"),MacroContext.prototype.contextSome.apply(this,args)}},contextSelect:{value(...args){return console.warn(\"[DEPRECATED] <MacroContext>.contextSelect() is deprecated.\"),MacroContext.prototype.contextFind.apply(this,args)}},contextSelectAll:{value(...args){return console.warn(\"[DEPRECATED] <MacroContext>.contextSelectAll() is deprecated.\"),MacroContext.prototype.contextFilter.apply(this,args)}},createShadowWrapper:{value(...args){return console.warn(\"[DEPRECATED] <MacroContext>.createShadowWrapper() is deprecated.\"),MacroContext.prototype.shadowHandler.apply(this,args)}}}),MacroContext})();Macro.add([\"addclass\",\"toggleclass\"],{handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"selector\"),this.args.length<2&&errors.push(\"class names\"),this.error(`no ${errors.join(\" or \")} specified`)}const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);switch(this.name){case\"addclass\":$targets.addClass(this.args[1].trim());break;case\"toggleclass\":$targets.toggleClass(this.args[1].trim())}Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add([\"append\",\"prepend\",\"replace\"],{tags:null,t8nRe:/^(?:transition|t8n)$/,handler(){if(0===this.args.length)return this.error(\"no selector specified\");const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);if(\"\"!==this.payload[0].contents){let $insert;switch(this.args.length>1&&this.self.t8nRe.test(this.args[1])?($insert=jQuery(document.createElement(\"span\")),$insert.addClass(`macro-${this.name}-insert macro-${this.name}-in`),setTimeout((()=>$insert.removeClass(`macro-${this.name}-in`)),Engine.DOM_DELAY)):$insert=jQuery(document.createDocumentFragment()),$insert.wiki(this.payload[0].contents),this.name){case\"replace\":$targets.empty();case\"append\":$targets.append($insert);break;case\"prepend\":$targets.prepend($insert)}}else\"replace\"===this.name&&$targets.empty();Config.debug&&this.debugView.modes({hidden:!0})}}),(()=>{if(Has.audio){const errorOnePlaybackAction=(cur,prev)=>`only one playback action allowed per invocation, \"${cur}\" cannot be combined with \"${prev}\"`;Macro.add(\"audio\",{handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"track and/or group IDs\"),this.args.length<2&&errors.push(\"actions\"),this.error(`no ${errors.join(\" or \")} specified`)}let selected;try{selected=SimpleAudio.select(this.args[0])}catch(ex){return this.error(ex.message)}const args=this.args.slice(1);let action,fadeTo,loop,mute,passage,time,volume,fadeOver=5;for(;args.length>0;){const arg=args.shift();let raw;switch(arg){case\"load\":case\"pause\":case\"play\":case\"stop\":case\"unload\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=arg;break;case\"fadein\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=\"fade\",fadeTo=1;break;case\"fadeout\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=\"fade\",fadeTo=0;break;case\"fadeto\":if(action)return this.error(errorOnePlaybackAction(arg,action));if(0===args.length)return this.error(\"fadeto missing required level value\");if(action=\"fade\",raw=args.shift(),fadeTo=Number.parseFloat(raw),Number.isNaN(fadeTo)||!Number.isFinite(fadeTo))return this.error(`cannot parse fadeto: ${raw}`);break;case\"fadeoverto\":if(action)return this.error(errorOnePlaybackAction(arg,action));if(args.length<2){const errors=[];return args.length<1&&errors.push(\"seconds\"),args.length<2&&errors.push(\"level\"),this.error(`fadeoverto missing required ${errors.join(\" and \")} value${errors.length>1?\"s\":\"\"}`)}if(action=\"fade\",raw=args.shift(),fadeOver=Number.parseFloat(raw),Number.isNaN(fadeOver)||!Number.isFinite(fadeOver))return this.error(`cannot parse fadeoverto: ${raw}`);if(raw=args.shift(),fadeTo=Number.parseFloat(raw),Number.isNaN(fadeTo)||!Number.isFinite(fadeTo))return this.error(`cannot parse fadeoverto: ${raw}`);break;case\"volume\":if(0===args.length)return this.error(\"volume missing required level value\");if(raw=args.shift(),volume=Number.parseFloat(raw),Number.isNaN(volume)||!Number.isFinite(volume))return this.error(`cannot parse volume: ${raw}`);break;case\"mute\":case\"unmute\":mute=\"mute\"===arg;break;case\"time\":if(0===args.length)return this.error(\"time missing required seconds value\");if(raw=args.shift(),time=Number.parseFloat(raw),Number.isNaN(time)||!Number.isFinite(time))return this.error(`cannot parse time: ${raw}`);break;case\"loop\":case\"unloop\":loop=\"loop\"===arg;break;case\"goto\":if(0===args.length)return this.error(\"goto missing required passage title\");if(raw=args.shift(),passage=\"object\"==typeof raw?raw.link:raw,!Story.has(passage))return this.error(`passage \"${passage}\" does not exist`);break;default:return this.error(`unknown action: ${arg}`)}}try{if(null!=volume&&selected.volume(volume),null!=time&&selected.time(time),null!=mute&&selected.mute(mute),null!=loop&&selected.loop(loop),null!=passage){const nsEnded=`ended.macros.macro-${this.name}_goto`;selected.off(nsEnded).one(nsEnded,(()=>{selected.off(nsEnded),Engine.play(passage)}))}switch(action){case\"fade\":selected.fade(fadeOver,fadeTo);break;case\"load\":selected.load();break;case\"pause\":selected.pause();break;case\"play\":selected.playWhenAllowed();break;case\"stop\":selected.stop();break;case\"unload\":selected.unload()}Config.debug&&this.debugView.modes({hidden:!0})}catch(ex){return this.error(`error executing action: ${ex.message}`)}}}),Macro.add(\"cacheaudio\",{handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"track ID\"),this.args.length<2&&errors.push(\"sources\"),this.error(`no ${errors.join(\" or \")} specified`)}const id=String(this.args[0]).trim();try{SimpleAudio.tracks.add(id,this.args.slice(1))}catch(ex){return this.error(ex.message)}if(Config.debug&&!SimpleAudio.tracks.get(id).hasSource())return this.error(`track ID \"${id}\": no supported audio sources found`);Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"createaudiogroup\",{tags:[\"track\"],handler(){if(0===this.args.length)return this.error(\"no group ID specified\");if(1===this.payload.length)return this.error(\"no tracks defined via <<track>>\");Config.debug&&this.debugView.modes({nonvoid:!1,hidden:!0});const groupId=String(this.args[0]).trim(),trackIds=[];for(let i=1,len=this.payload.length;i<len;++i){if(this.payload[i].args.length<1)return this.error(\"no track ID specified\");trackIds.push(String(this.payload[i].args[0]).trim()),Config.debug&&this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1,hidden:!0})}try{SimpleAudio.groups.add(groupId,trackIds)}catch(ex){return this.error(ex.message)}Config.debug&&this.createDebugView(`/${this.name}`,`<</${this.name}>>`).modes({nonvoid:!1,hidden:!0})}}),Macro.add(\"createplaylist\",{tags:[\"track\"],handler(){if(0===this.args.length)return this.error(\"no list ID specified\");if(1===this.payload.length)return this.error(\"no tracks defined via <<track>>\");Config.debug&&this.debugView.modes({nonvoid:!1,hidden:!0});const listId=String(this.args[0]).trim(),trackObjs=[];for(let i=1,len=this.payload.length;i<len;++i){if(0===this.payload[i].args.length)return this.error(\"no track ID specified\");const trackObj={id:String(this.payload[i].args[0]).trim()},args=this.payload[i].args.slice(1);for(;args.length>0;){const arg=args.shift();let raw,parsed;switch(arg){case\"own\":trackObj.own=!0;break;case\"rate\":args.length>0&&args.shift();break;case\"volume\":if(0===args.length)return this.error(\"volume missing required level value\");if(raw=args.shift(),parsed=Number.parseFloat(raw),Number.isNaN(parsed)||!Number.isFinite(parsed))return this.error(`cannot parse volume: ${raw}`);trackObj.volume=parsed;break;default:return this.error(`unknown action: ${arg}`)}}trackObjs.push(trackObj),Config.debug&&this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1,hidden:!0})}try{SimpleAudio.lists.add(listId,trackObjs)}catch(ex){return this.error(ex.message)}Config.debug&&this.createDebugView(`/${this.name}`,`<</${this.name}>>`).modes({nonvoid:!1,hidden:!0})}}),Macro.add(\"masteraudio\",{handler(){if(0===this.args.length)return this.error(\"no actions specified\");const args=this.args.slice(0);let action,mute,muteOnHide,volume;for(;args.length>0;){const arg=args.shift();let raw;switch(arg){case\"load\":case\"stop\":case\"unload\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=arg;break;case\"mute\":case\"unmute\":mute=\"mute\"===arg;break;case\"muteonhide\":case\"nomuteonhide\":muteOnHide=\"muteonhide\"===arg;break;case\"volume\":if(0===args.length)return this.error(\"volume missing required level value\");if(raw=args.shift(),volume=Number.parseFloat(raw),Number.isNaN(volume)||!Number.isFinite(volume))return this.error(`cannot parse volume: ${raw}`);break;default:return this.error(`unknown action: ${arg}`)}}try{switch(null!=mute&&SimpleAudio.mute(mute),null!=muteOnHide&&SimpleAudio.muteOnHidden(muteOnHide),null!=volume&&SimpleAudio.volume(volume),action){case\"load\":SimpleAudio.load();break;case\"stop\":SimpleAudio.stop();break;case\"unload\":SimpleAudio.unload()}Config.debug&&this.debugView.modes({hidden:!0})}catch(ex){return this.error(`error executing action: ${ex.message}`)}}}),Macro.add(\"playlist\",{handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"list ID\"),this.args.length<2&&errors.push(\"actions\"),this.error(`no ${errors.join(\" or \")} specified`)}const id=String(this.args[0]).trim();if(!SimpleAudio.lists.has(id))return this.error(`playlist \"${id}\" does not exist`);const list=SimpleAudio.lists.get(id),args=this.args.slice(1);let action,fadeTo,loop,mute,shuffle,volume,fadeOver=5;for(;args.length>0;){const arg=args.shift();let raw;switch(arg){case\"load\":case\"pause\":case\"play\":case\"skip\":case\"stop\":case\"unload\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=arg;break;case\"fadein\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=\"fade\",fadeTo=1;break;case\"fadeout\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=\"fade\",fadeTo=0;break;case\"fadeto\":if(action)return this.error(errorOnePlaybackAction(arg,action));if(0===args.length)return this.error(\"fadeto missing required level value\");if(action=\"fade\",raw=args.shift(),fadeTo=Number.parseFloat(raw),Number.isNaN(fadeTo)||!Number.isFinite(fadeTo))return this.error(`cannot parse fadeto: ${raw}`);break;case\"fadeoverto\":if(action)return this.error(errorOnePlaybackAction(arg,action));if(args.length<2){const errors=[];return args.length<1&&errors.push(\"seconds\"),args.length<2&&errors.push(\"level\"),this.error(`fadeoverto missing required ${errors.join(\" and \")} value${errors.length>1?\"s\":\"\"}`)}if(action=\"fade\",raw=args.shift(),fadeOver=Number.parseFloat(raw),Number.isNaN(fadeOver)||!Number.isFinite(fadeOver))return this.error(`cannot parse fadeoverto: ${raw}`);if(raw=args.shift(),fadeTo=Number.parseFloat(raw),Number.isNaN(fadeTo)||!Number.isFinite(fadeTo))return this.error(`cannot parse fadeoverto: ${raw}`);break;case\"volume\":if(0===args.length)return this.error(\"volume missing required level value\");if(raw=args.shift(),volume=Number.parseFloat(raw),Number.isNaN(volume)||!Number.isFinite(volume))return this.error(`cannot parse volume: ${raw}`);break;case\"mute\":case\"unmute\":mute=\"mute\"===arg;break;case\"loop\":case\"unloop\":loop=\"loop\"===arg;break;case\"shuffle\":case\"unshuffle\":shuffle=\"shuffle\"===arg;break;default:return this.error(`unknown action: ${arg}`)}}try{switch(null!=volume&&list.volume(volume),null!=mute&&list.mute(mute),null!=loop&&list.loop(loop),null!=shuffle&&list.shuffle(shuffle),action){case\"fade\":list.fade(fadeOver,fadeTo);break;case\"load\":list.load();break;case\"pause\":list.pause();break;case\"play\":list.playWhenAllowed();break;case\"skip\":list.skip();break;case\"stop\":list.stop();break;case\"unload\":list.unload()}Config.debug&&this.debugView.modes({hidden:!0})}catch(ex){return this.error(`error executing action: ${ex.message}`)}}}),Macro.add(\"removeaudiogroup\",{handler(){if(0===this.args.length)return this.error(\"no group ID specified\");const id=String(this.args[0]).trim();if(!SimpleAudio.groups.has(id))return this.error(`group \"${id}\" does not exist`);SimpleAudio.groups.delete(id),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"removeplaylist\",{handler(){if(0===this.args.length)return this.error(\"no list ID specified\");const id=String(this.args[0]).trim();if(!SimpleAudio.lists.has(id))return this.error(`playlist \"${id}\" does not exist`);SimpleAudio.lists.delete(id),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"waitforaudio\",{skipArgs:!0,handler(){SimpleAudio.loadWithScreen()}})}else Macro.add([\"audio\",\"cacheaudio\",\"createaudiogroup\",\"createplaylist\",\"masteraudio\",\"playlist\",\"removeaudiogroup\",\"removeplaylist\",\"waitforaudio\"],{skipArgs:!0,handler(){Config.debug&&this.debugView.modes({hidden:!0})}})})(),Macro.add([\"back\",\"return\"],{handler(){let passage,content,$link,momentIndex=-1;if(this.args.length>0)if(\"object\"==typeof this.args[0])if(this.args[0].isImage){content=document.createElement(\"img\");const $image=jQuery(content).attr(\"src\",this.args[0].source);Object.hasOwn(this.args[0],\"passage\")&&$image.attr(\"data-passage\",this.args[0].passage),Object.hasOwn(this.args[0],\"title\")&&$image.attr(\"title\",this.args[0].title),Object.hasOwn(this.args[0],\"align\")&&$image.attr(\"align\",this.args[0].align),Object.hasOwn(this.args[0],\"link\")&&(passage=this.args[0].link)}else content=document.createTextNode(this.args[0].text),passage=this.args[0].link;else{content=document.createDocumentFragment();const forbidden=jQuery(content).wikiWithOptions({cleanup:!1,profile:\"core\"},this.args[0]).getForbiddenInteractiveContentTagNames();if(forbidden.length>0)throw new Error(`text content contains restricted elements: <${forbidden.join(\">, <\")}>`);passage=this.args.length>1?this.args[1]:undefined}if(null==passage){for(let i=State.length-2;i>=0;--i)if(State.history[i].title!==State.passage){momentIndex=i,passage=State.history[i].title;break}if(null==passage&&\"return\"===this.name)for(let i=State.expired.length-1;i>=0;--i)if(State.expired[i]!==State.passage){passage=State.expired[i];break}}else{if(!Story.has(passage))return this.error(`passage \"${passage}\" does not exist`);if(\"back\"===this.name){for(let i=State.length-2;i>=0;--i)if(State.history[i].title===passage){momentIndex=i;break}if(-1===momentIndex)return this.error(`cannot find passage \"${passage}\" in the current story history`)}}if(null==passage)return this.error(\"cannot find passage\");\"back\"!==this.name||-1!==momentIndex?($link=jQuery(document.createElement(\"a\")).addClass(\"link-internal\").ariaClick({one:!0},\"return\"===this.name?()=>Engine.play(passage):()=>Engine.goTo(momentIndex)),content instanceof HTMLImageElement&&$link.addClass(\"link-image\")):$link=jQuery(document.createElement(\"span\")).addClass(\"link-disabled\"),$link.addClass(`macro-${this.name}`).append(content||document.createTextNode(L10n.get(`macro${this.name.toUpperFirst()}Text`))).appendTo(this.output)}}),Macro.add([\"button\",\"link\"],{isAsync:!0,tags:null,handler(){if(0===this.args.length)return this.error(`no ${\"button\"===this.name?\"button\":\"link\"} text specified`);const $link=jQuery(document.createElement(\"button\"===this.name?\"button\":\"a\"));let passage;if(\"object\"==typeof this.args[0])if(this.args[0].isImage){const $image=jQuery(document.createElement(\"img\")).attr(\"src\",this.args[0].source).appendTo($link);$link.addClass(\"link-image\"),Object.hasOwn(this.args[0],\"passage\")&&$image.attr(\"data-passage\",this.args[0].passage),Object.hasOwn(this.args[0],\"title\")&&$image.attr(\"title\",this.args[0].title),Object.hasOwn(this.args[0],\"align\")&&$image.attr(\"align\",this.args[0].align),passage=this.args[0].link}else $link.append(document.createTextNode(this.args[0].text)),passage=this.args[0].link;else{const $frag=jQuery(document.createDocumentFragment()).wikiWithOptions({cleanup:!1,profile:\"core\"},this.args[0]),forbidden=$frag.getForbiddenInteractiveContentTagNames();if(forbidden.length>0)throw new Error(`text content contains restricted elements: <${forbidden.join(\">, <\")}>`);$link.append($frag),passage=this.args.length>1?this.args[1]:undefined}null!=passage?($link.attr(\"data-passage\",passage),Story.has(passage)?($link.addClass(\"link-internal\"),Config.addVisitedLinkClass&&State.hasPlayed(passage)&&$link.addClass(\"link-visited\")):$link.addClass(\"link-broken\")):$link.addClass(\"link-internal\"),$link.addClass(`macro-${this.name}`).ariaClick({namespace:\".macros\",role:null!=passage?\"link\":\"button\",one:null!=passage},this.shadowHandler(\"\"!==this.payload[0].contents?()=>Wikifier.wikifyEval(this.payload[0].contents.trim()):null,null!=passage?()=>Engine.play(passage):null)).appendTo(this.output)}}),Macro.add(\"capture\",{skipArgs:!0,tags:null,tsVarRe:new RegExp(`(${Patterns.variable})`,\"g\"),handler(){if(0===this.args.raw.length)return this.error(\"no story/temporary variable list specified\");const valueCache={};try{const tsVarRe=this.self.tsVarRe;let match;for(;null!==(match=tsVarRe.exec(this.args.raw));){const varName=match[1],varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;Object.hasOwn(store,varKey)&&(valueCache[varKey]=store[varKey]),this.addShadow(varName)}new Wikifier(this.output,this.payload[0].contents)}finally{this.shadows.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;Object.hasOwn(valueCache,varKey)?store[varKey]=valueCache[varKey]:delete store[varKey]}))}}}),Macro.add(\"checkbox\",{isAsync:!0,handler(){if(this.args.length<3){const errors=[];return this.args.length<1&&errors.push(\"variable name\"),this.args.length<2&&errors.push(\"unchecked value\"),this.args.length<3&&errors.push(\"checked value\"),this.error(`no ${errors.join(\" or \")} specified`)}if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);const varId=createSlug(varName),uncheckValue=this.args[1],checkValue=this.args[2],el=document.createElement(\"input\");switch(jQuery(el).attr({id:`${this.name}-${varId}`,name:`${this.name}-${varId}`,type:\"checkbox\",tabindex:0}).addClass(`macro-${this.name}`).on(\"change.macros\",this.shadowHandler((function(){State.setVar(varName,this.checked?checkValue:uncheckValue)}))).appendTo(this.output),this.args[3]){case\"autocheck\":State.getVar(varName)===checkValue?el.checked=!0:State.setVar(varName,uncheckValue);break;case\"checked\":el.checked=!0,State.setVar(varName,checkValue);break;default:State.setVar(varName,uncheckValue)}}}),Macro.add(\"copy\",{handler(){if(0===this.args.length)return this.error(\"no selector specified\");const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);jQuery(this.output).append($targets.html()),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add([\"cycle\",\"listbox\"],{isAsync:!0,skipArgs:[\"optionsfrom\"],tags:[\"option\",\"optionsfrom\"],handler(){if(0===this.args.length)return this.error(\"no variable name specified\");if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);const varId=createSlug(varName),len=this.payload.length;if(1===len)return this.error(\"no options specified\");const config={autoselect:!1,once:!1};for(let i=1;i<this.args.length;++i){const arg=this.args[i];switch(arg){case\"once\":config.once=!0;break;case\"autoselect\":config.autoselect=!0;break;default:return this.error(`unknown argument: ${arg}`)}}const options=[],tagCount={option:0,optionsfrom:0};let index=-1;for(let i=1;i<len;++i){const payload=this.payload[i];if(\"option\"===payload.name){if(++tagCount.option,0===payload.args.length)return this.error(`no arguments specified for <<${payload.name}>> (#${tagCount.option})`);const option={label:String(payload.args[0])};let isSelected=!1;switch(payload.args.length){case 1:option.value=payload.args[0];break;case 2:\"selected\"===payload.args[1]?(option.value=payload.args[0],isSelected=!0):option.value=payload.args[1];break;default:option.value=payload.args[1],\"selected\"===payload.args[2]&&(isSelected=!0)}if(options.push(option),isSelected){if(config.autoselect)return this.error(\"cannot specify both the autoselect and selected keywords\");if(-1!==index)return this.error(`multiple selected keywords specified for <<${payload.name}>> (#${index+1} & #${tagCount.option})`);index=options.length-1}}else{if(++tagCount.optionsfrom,0===payload.args.full.length)return this.error(`no expression specified for <<${payload.name}>> (#${tagCount.optionsfrom})`);let result;try{const exp=payload.args.full;result=Scripting.evalJavaScript(\"{\"===exp[0]?`(${exp})`:exp)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`)}if(\"object\"!=typeof result||null===result)return this.error(`expression must yield a supported collection or generic object (type: ${null===result?\"null\":typeof result})`);if(result instanceof Array||result instanceof Set)result.forEach((val=>options.push({label:String(val),value:val})));else if(result instanceof Map)result.forEach(((val,key)=>options.push({label:String(key),value:val})));else{const oType=getToStringTag(result);if(\"Object\"!==oType)return this.error(`expression must yield a supported collection or generic object (object type: ${oType})`);Object.keys(result).forEach((key=>options.push({label:key,value:result[key]})))}}}if(-1===index)if(config.autoselect){const curValue=State.getVar(varName),curValueIndex=options.findIndex((opt=>sameValueZero(opt.value,curValue)));index=-1===curValueIndex?0:curValueIndex}else index=0;if(\"cycle\"===this.name){const lastIndex=options.length-1;if(config.once&&index===lastIndex)jQuery(this.output).wikiWithOptions({cleanup:!1,profile:\"core\"},options[index].label);else{let cycleIndex=index;jQuery(document.createElement(\"a\")).wikiWithOptions({cleanup:!1,profile:\"core\"},options[index].label).attr(\"id\",`${this.name}-${varId}`).addClass(`macro-${this.name}`).ariaClick({namespace:\".macros\",role:\"button\"},this.shadowHandler((function(){const $this=$(this);cycleIndex=(cycleIndex+1)%options.length,State.setVar(varName,options[cycleIndex].value),$this.empty().wikiWithOptions({cleanup:!1,profile:\"core\"},options[cycleIndex].label),config.once&&cycleIndex===lastIndex&&$this.off().contents().unwrap()}))).appendTo(this.output)}}else{const $select=jQuery(document.createElement(\"select\"));options.forEach(((opt,i)=>{jQuery(document.createElement(\"option\")).val(i).text(opt.label).appendTo($select)})),$select.attr({id:`${this.name}-${varId}`,name:`${this.name}-${varId}`,tabindex:0}).addClass(`macro-${this.name}`).val(index).on(\"change.macros\",this.shadowHandler((function(){State.setVar(varName,options[Number(this.value)].value)}))).appendTo(this.output)}State.setVar(varName,options[index].value)}}),jQuery(document).on(\":redo\",(ev=>{const evTags=ev.detail&&ev.detail.tags||[],selector=0===evTags.length?\".redo-target\":evTags.map((tag=>`.redo-target[data-do-tags~=\"${tag}\"]`)).join(\", \");triggerEvent(\":redo-internal\",jQuery(selector),{bubbles:!1,detail:ev.detail})})),Macro.add(\"do\",{tags:null,handler(){let elTag=\"span\",tags=[];const options=this.args.slice();for(;options.length>0;){const option=options.shift();switch(option){case\"tag\":{if(0===options.length)return this.error(\"tag option missing required tag name(s)\");const raw=String(options.shift()).trim();if(\"\"===raw)throw new Error(\"tag option tag name(s) must be non-empty\");tags=String(raw).trim().splitOrEmpty(/\\s+/);break}case\"element\":if(0===options.length)return this.error(\"element option missing required element tag name\");if(elTag=String(options.shift()).trim(),\"\"===elTag)throw new Error(\"element option tag name must be non-empty\");break;default:return this.error(`unknown option: ${option}`)}}const contents=this.payload[0].contents;if(\"\"===contents.trim())return;Config.debug&&this.debugView.modes({block:\"span\"!==elTag});const $target=jQuery(document.createElement(elTag)).addClass(`macro-${this.name} redo-target`).attr(\"data-do-tags\",tags.join(\" \")).wiki(contents).on(\":redo-internal\",jQuery.throttle(Engine.DOM_DELAY,this.shadowHandler((()=>{const frag=document.createDocumentFragment();new Wikifier(frag,contents),$target.empty().append(frag)})))).appendTo(this.output)}}),Macro.add(\"redo\",{handler(){const failRE=/^(?:do|for)$/,passRE=/^(?:button|link(?:append|prepend|replace)?)$/,closest=this.contextFind((ctx=>failRE.test(ctx.name)||passRE.test(ctx.name)));if(closest&&failRE.test(closest.name))return this.error(`must not be used directly within macro <<${closest.name}>>`);const tags=this.args.length>0?String(this.args[0]).trim().splitOrEmpty(/\\s+/):[];triggerEvent(\":redo\",document,{detail:{tags:tags}})}}),Macro.add(\"done\",{skipArgs:!0,tags:null,handler(){const contents=this.payload[0].contents.trim();\"\"!==contents&&setTimeout(this.shadowHandler((()=>$.wiki(contents))),Engine.DOM_DELAY)}}),Macro.add(\"for\",{skipArgs:!0,tags:null,isRangeRe:new RegExp(`^(?:\\\\S${Patterns.anyChar}*?\\\\s+)?range\\\\s+\\\\S${Patterns.anyChar}*?$`),rangeRe:new RegExp(`^(?:(?:State\\\\.(variables|temporary)\\\\.(${Patterns.identifier})\\\\s*,\\\\s*)?State\\\\.(variables|temporary)\\\\.(${Patterns.identifier})\\\\s+)?range\\\\s+(\\\\S${Patterns.anyChar}*?)$`),threePartRe:/^([^;]*?)\\s*;\\s*([^;]*?)\\s*;\\s*([^;]*?)$/,forInRe:/^\\S+\\s+in\\s+\\S+/i,forOfRe:/^\\S+\\s+of\\s+\\S+/i,handler(){const argsStr=this.args.full.trim(),payload=this.payload[0].contents.replace(/\\n$/,\"\");if(0===argsStr.length)this.self.handleFor.call(this,payload,null,!0,null);else if(this.self.isRangeRe.test(argsStr)){const parts=argsStr.match(this.self.rangeRe);if(null===parts)return this.error(\"invalid range form syntax, format: [[index ,] value] range collection\");this.self.handleForRange.call(this,payload,{type:parts[1],name:parts[2]},{type:parts[3],name:parts[4]},parts[5])}else{let init,condition,post;if(-1===argsStr.indexOf(\";\")){if(this.self.forInRe.test(argsStr))return this.error(\"invalid syntax, for…in is not supported; see: for…range\");if(this.self.forOfRe.test(argsStr))return this.error(\"invalid syntax, for…of is not supported; see: for…range\");condition=argsStr}else{const parts=argsStr.match(this.self.threePartRe);if(null===parts)return this.error(\"invalid 3-part conditional form syntax, format: [init] ; [condition] ; [post]\");init=parts[1],condition=parts[2].trim(),post=parts[3],0===condition.length&&(condition=!0)}this.self.handleFor.call(this,payload,init,condition,post)}},handleFor(payload,init,condition,post){const evalJavaScript=Scripting.evalJavaScript;let first=!0,safety=Config.macros.maxLoopIterations;Config.debug&&this.debugView.modes({block:!0});try{if(TempState.break=null,init)try{evalJavaScript(init)}catch(ex){return this.error(`bad init expression: ${getErrorMessage(ex)}`)}for(;evalJavaScript(condition);){if(--safety<0)return this.error(`exceeded configured maximum loop iterations (${Config.macros.maxLoopIterations})`);if(new Wikifier(this.output,first?payload.replace(/^\\n/,\"\"):payload),first&&(first=!1),null!=TempState.break)if(1===TempState.break)TempState.break=null;else if(2===TempState.break){TempState.break=null;break}if(post)try{evalJavaScript(post)}catch(ex){return this.error(`bad post expression: ${getErrorMessage(ex)}`)}}}catch(ex){return this.error(`bad conditional expression: ${getErrorMessage(ex)}`)}finally{TempState.break=null}},handleForRange(payload,keyVar,valueVar,rangeExp){let rangeable,first=!0;try{rangeable=this.self.toRangeable(rangeExp)}catch(ex){return this.error(ex.message)}Config.debug&&this.debugView.modes({block:!0});try{for(TempState.break=null;;){const entry=rangeable.next();if(entry.done)break;if(keyVar.name&&(State[keyVar.type][keyVar.name]=entry.key),valueVar.name&&(State[valueVar.type][valueVar.name]=entry.value),new Wikifier(this.output,first?payload.replace(/^\\n/,\"\"):payload),first&&(first=!1),null!=TempState.break)if(1===TempState.break)TempState.break=null;else if(2===TempState.break){TempState.break=null;break}}}catch(ex){return this.error(getErrorMessage(ex))}finally{TempState.break=null}},toRangeable(rangeExp){let collection;try{collection=Scripting.evalJavaScript(\"{\"===rangeExp[0]?`(${rangeExp})`:rangeExp)}catch(ex){if(\"object\"!=typeof ex)throw new Error(`bad range expression: ${ex}`);throw ex.message=`bad range expression: ${ex.message}`,ex}switch(typeof collection){case\"number\":if(Number.isNaN(collection)||!Number.isFinite(collection))throw new Error(`unsupported range expression type: ${stringFrom(collection)}`);if(!Number.isInteger(collection))throw new Error(\"unsupported range expression type: floating-point number\");if(!Number.isSafeInteger(collection))throw new Error(\"unsupported range expression type: unsafe integer\");return collection<=0?{next:()=>({done:!0})}:{end:collection,pos:0,next(){if(this.pos<this.end){const key=this.pos++;return{key:key,value:key,done:!1}}return{done:!0}}};case\"string\":return{list:collection,end:collection.length,pos:0,next(){if(this.pos<this.end){const O=charAndPosAt(this.list,this.pos),key=this.pos;return this.pos=O.end+1,{key:key,value:O.char,done:!1}}return{done:!0}}};case\"object\":if(collection instanceof Array)return{list:collection,end:collection.length,pos:0,next(){if(this.pos<this.end){const key=this.pos++;return{key:key,value:this.list[key],done:!1}}return{done:!0}}};if(collection instanceof Set)return collection=Array.from(collection),{list:collection,end:collection.length,pos:0,next(){if(this.pos<this.end){const key=this.pos++;return{key:key,value:this.list[key],done:!1}}return{done:!0}}};if(collection instanceof Map){const keys=Array.from(collection.keys());return{keys:keys,list:collection,end:keys.length,pos:0,next(){if(this.pos<this.end){const key=this.keys[this.pos++];return{key:key,value:this.list.get(key),done:!1}}return{done:!0}}}}if(\"Object\"===getToStringTag(collection)){const keys=Object.keys(collection);return{keys:keys,list:collection,end:keys.length,pos:0,next(){if(this.pos<this.end){const key=this.keys[this.pos++];return{key:key,value:this.list[key],done:!1}}return{done:!0}}}}throw new Error(`unsupported range expression type: ${getToStringTag(collection)}`);default:throw new Error(\"unsupported range expression type: \"+typeof collection)}}}),Macro.add([\"break\",\"continue\"],{skipArgs:!0,handler(){if(!this.contextSome((ctx=>\"for\"===ctx.name)))return this.error(\"must only be used in conjunction with its parent macro <<for>>\");TempState.break=\"continue\"===this.name?1:2,Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"goto\",{handler(){if(0===this.args.length)return this.error(\"no passage specified\");let passage;if(passage=\"object\"==typeof this.args[0]?this.args[0].link:this.args[0],!Story.has(passage))return this.error(`passage \"${passage}\" does not exist`);setTimeout((()=>Engine.play(passage)),Engine.DOM_DELAY)}}),Macro.add(\"if\",{skipArgs:!0,tags:[\"elseif\",\"else\"],isElseifWsRE:/^\\s*if\\b/i,isAssignRE:/[^!%&*+\\-/<=>?^|]=[^=>]/,isLiteralRE:new RegExp([\"(?:\\\"\\\"|''|``)\",'(?:\"(?:\\\\\\\\.|[^\"\\\\\\\\])+\")',\"(?:'(?:\\\\\\\\.|[^'\\\\\\\\])+')\",\"(?:`(?:\\\\\\\\.|[^`\\\\\\\\])+`)\"].join(\"|\"),\"g\"),handler(){let i;try{const len=this.payload.length,isElseifWsRE=this.self.isElseifWsRE,isAssignRE=this.self.isAssignRE,isLiteralRE=this.self.isLiteralRE;for(i=0;i<len;++i)if(\"else\"===this.payload[i].name){if(this.payload[i].args.raw.length>0)return isElseifWsRE.test(this.payload[i].args.raw)?this.error('whitespace is not allowed between the \"else\" and \"if\" in <<elseif>> clause'+(i>0?` (#${i})`:\"\")):this.error(`<<else>> does not accept a conditional expression (perhaps you meant to use <<elseif>>), invalid: ${this.payload[i].args.raw}`);if(i+1!==len)return this.error(\"<<else>> must be the final clause\")}else{if(0===this.payload[i].args.full.length)return this.error(`no conditional expression specified for <<${this.payload[i].name}>> clause${i>0?` (#${i})`:\"\"}`);if((Config.debug||Config.enableOptionalDebugging)&&isAssignRE.test(this.payload[i].args.full.replace(isLiteralRE,\"\")))return this.error(`assignment operator found within <<${this.payload[i].name}>> clause${i>0?` (#${i})`:\"\"} (perhaps you meant to use an equality operator: ==, ===, eq, is), invalid: ${this.payload[i].args.raw}`)}const evalJavaScript=Scripting.evalJavaScript;let success=!1;for(i=0;i<len;++i){if(Config.debug&&this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1}),\"else\"===this.payload[i].name||evalJavaScript(this.payload[i].args.full)){success=!0,new Wikifier(this.output,this.payload[i].contents);break}Config.debug&&this.debugView.modes({hidden:!0,invalid:!0})}if(Config.debug){for(++i;i<len;++i)this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1,hidden:!0,invalid:!0});this.createDebugView(`/${this.name}`,`<</${this.name}>>`).modes({nonvoid:!1,hidden:!success,invalid:!success})}}catch(ex){return this.error(`bad conditional expression in <<${0===i?\"if\":\"elseif\"}>> clause${i>0?` (#${i})`:\"\"}: ${getErrorMessage(ex)}`,null,ex.stack)}}}),Macro.add(\"include\",{handler(){if(\"display\"===this.name&&console.warn(`[DEPRECATED] <<${this.name}>> macro is deprecated.`),0===this.args.length)return this.error(\"no passage specified\");let passage,$el;if(passage=\"object\"==typeof this.args[0]?this.args[0].link:this.args[0],!Story.has(passage))return this.error(`passage \"${passage}\" does not exist`);Config.debug&&this.debugView.modes({block:!0}),passage=Story.get(passage),$el=this.args[1]?jQuery(document.createElement(this.args[1])).addClass(`${passage.id} macro-${this.name}`).attr(\"data-passage\",passage.name).appendTo(this.output):jQuery(this.output),$el.wiki(passage.processText())}}),Macro.add([\"linkappend\",\"linkprepend\",\"linkreplace\"],{isAsync:!0,tags:null,t8nRe:/^(?:transition|t8n)$/,handler(){if(0===this.args.length)return this.error(\"no link text specified\");const $link=jQuery(document.createElement(\"a\")),$insert=jQuery(document.createElement(\"span\")),transition=this.args.length>1&&this.self.t8nRe.test(this.args[1]);$link.wikiWithOptions({cleanup:!1,profile:\"core\"},this.args[0]).addClass(`link-internal macro-${this.name}`).ariaClick({namespace:\".macros\",one:!0},this.shadowHandler((()=>{if(\"linkreplace\"===this.name?$link.remove():$link.wrap(`<span class=\"macro-${this.name}\"></span>`).replaceWith((()=>$link.html())),\"\"!==this.payload[0].contents){const frag=document.createDocumentFragment();new Wikifier(frag,this.payload[0].contents,{cleanup:!1}),$insert.append(frag)}transition&&setTimeout((()=>$insert.removeClass(`macro-${this.name}-in`)),Engine.DOM_DELAY)}))).appendTo(this.output),$insert.addClass(`macro-${this.name}-insert`),transition&&$insert.addClass(`macro-${this.name}-in`),\"linkprepend\"===this.name?$insert.insertBefore($link):$insert.insertAfter($link)}}),Macro.add(\"nobr\",{skipArgs:!0,tags:null,handler(){new Wikifier(this.output,this.payload[0].contents.replace(/^\\n+|\\n+$/g,\"\").replace(/\\n+/g,\" \"))}}),Macro.add([\"numberbox\",\"textbox\"],{isAsync:!0,handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"variable name\"),this.args.length<2&&errors.push(\"default value\"),this.error(`no ${errors.join(\" or \")} specified`)}if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);Config.debug&&this.debugView.modes({block:!0});const asNumber=\"numberbox\"===this.name,defaultValue=asNumber?Number(this.args[1]):this.args[1];if(asNumber&&Number.isNaN(defaultValue))return this.error(`default value \"${this.args[1]}\" is neither a number nor can it be parsed into a number`);const varId=createSlug(varName),el=document.createElement(\"input\");let passage,autofocus=!1;this.args.length>3?(passage=this.args[2],autofocus=\"autofocus\"===this.args[3]):this.args.length>2&&(\"autofocus\"===this.args[2]?autofocus=!0:passage=this.args[2]),\"object\"==typeof passage&&(passage=passage.link),jQuery(el).attr({id:`${this.name}-${varId}`,name:`${this.name}-${varId}`,type:asNumber?\"number\":\"text\",inputmode:asNumber?\"decimal\":\"text\",tabindex:0}).addClass(`macro-${this.name}`).on(\"change.macros\",this.shadowHandler((function(){State.setVar(varName,asNumber?Number(this.value):this.value)}))).on(\"keypress.macros\",this.shadowHandler((function(ev){13===ev.which&&(ev.preventDefault(),State.setVar(varName,asNumber?Number(this.value):this.value),null!=passage&&Engine.play(passage))}))).appendTo(this.output),asNumber&&(el.step=\"any\"),State.setVar(varName,defaultValue),el.value=defaultValue,autofocus&&(el.setAttribute(\"autofocus\",\"autofocus\"),Engine.isPlaying()?jQuery(document).one(\":passageend\",(()=>{setTimeout((()=>el.focus()),Engine.DOM_DELAY)})):setTimeout((()=>el.focus()),Engine.DOM_DELAY))}}),Macro.add([\"print\",\"=\",\"-\"],{skipArgs:!0,handler(){if(0===this.args.full.length)return this.error(\"no expression specified\");try{const result=stringFrom(Scripting.evalJavaScript(this.args.full));null!==result&&new Wikifier(this.output,\"-\"===this.name?encodeEntities(result):result)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`,null,ex.stack)}}}),Macro.add(\"radiobutton\",{isAsync:!0,handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"variable name\"),this.args.length<2&&errors.push(\"checked value\"),this.error(`no ${errors.join(\" or \")} specified`)}if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);const varId=createSlug(varName),checkValue=this.args[1],el=document.createElement(\"input\");switch(Object.hasOwn(TempState,this.name)||(TempState[this.name]={}),Object.hasOwn(TempState[this.name],varId)||(TempState[this.name][varId]=0),jQuery(el).attr({id:`${this.name}-${varId}-${TempState[this.name][varId]++}`,name:`${this.name}-${varId}`,type:\"radio\",tabindex:0}).addClass(`macro-${this.name}`).on(\"change.macros\",this.shadowHandler((function(){this.checked&&State.setVar(varName,checkValue)}))).appendTo(this.output),this.args[2]){case\"autocheck\":State.getVar(varName)===checkValue&&(el.checked=!0);break;case\"checked\":el.checked=!0,State.setVar(varName,checkValue)}}}),Macro.add(\"remove\",{handler(){if(0===this.args.length)return this.error(\"no selector specified\");const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);$targets.remove(),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"removeclass\",{handler(){if(0===this.args.length)return this.error(\"no selector specified\");const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);this.args.length>1?$targets.removeClass(this.args[1].trim()):$targets.removeClass(),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"repeat\",{isAsync:!0,tags:null,timers:new Set,t8nRe:/^(?:transition|t8n)$/,handler(){if(0===this.args.length)return this.error(\"no time value specified\");let delay;try{delay=Math.max(Engine.DOM_DELAY,cssTimeToMS(this.args[0]))}catch(ex){return this.error(ex.message)}Config.debug&&this.debugView.modes({block:!0});const transition=this.args.length>1&&this.self.t8nRe.test(this.args[1]),$wrapper=jQuery(document.createElement(\"span\")).addClass(`macro-${this.name}`).appendTo(this.output);this.self.registerInterval(this.shadowHandler((()=>{const frag=document.createDocumentFragment();new Wikifier(frag,this.payload[0].contents,{cleanup:!1});let $output=$wrapper;transition&&($output=jQuery(document.createElement(\"span\")).addClass(\"macro-repeat-insert macro-repeat-in\").appendTo($output)),$output.append(frag),transition&&setTimeout((()=>$output.removeClass(\"macro-repeat-in\")),Engine.DOM_DELAY)})),delay)},registerInterval(callback,delay){if(\"function\"!=typeof callback)throw new TypeError(\"callback parameter must be a function\");const passage=State.passage,turn=State.turns,timers=this.timers;let timerId=null;timerId=setInterval((()=>{if(State.passage!==passage||State.turns!==turn)return clearInterval(timerId),void timers.delete(timerId);let timerIdCache;try{TempState.break=null,Object.hasOwn(TempState,\"repeatTimerId\")&&(timerIdCache=TempState.repeatTimerId),TempState.repeatTimerId=timerId,callback.call(this)}finally{void 0!==timerIdCache?TempState.repeatTimerId=timerIdCache:delete TempState.repeatTimerId,TempState.break=null}}),delay),timers.add(timerId),1===timers.size&&jQuery(document).one(\":passageinit\",(()=>{timers.forEach((timerId=>clearInterval(timerId))),timers.clear()}))}}),Macro.add(\"stop\",{skipArgs:!0,handler(){if(!Object.hasOwn(TempState,\"repeatTimerId\"))return this.error(\"must only be used in conjunction with its parent macro <<repeat>>\");const timers=Macro.get(\"repeat\").timers,timerId=TempState.repeatTimerId;clearInterval(timerId),timers.delete(timerId),TempState.break=2,Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"script\",{tags:null,handler(){let evalScript;switch(this.args.length>0?String(this.args[0]).toLowerCase():\"javascript\"){case\"javascript\":evalScript=Scripting.evalJavaScript;break;case\"twinescript\":evalScript=Scripting.evalTwineScript;break;default:return this.error(`unknown language \"${this.args[0]}\"`)}const output=document.createDocumentFragment();try{evalScript(this.payload[0].contents,output)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`)}Config.debug&&this.createDebugView(),output.hasChildNodes()&&this.output.appendChild(output)}}),Macro.add(\"set\",{skipArgs:!0,handler(){if(0===this.args.full.length)return this.error(\"no expression specified\");try{Scripting.evalJavaScript(this.args.full)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`,null,ex.stack)}Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"run\",\"set\"),Macro.add(\"silent\",{skipArgs:!0,tags:null,handler(){\"silently\"===this.name&&console.warn(`[DEPRECATED] <<${this.name}>> macro is deprecated.`);const frag=document.createDocumentFragment();if(new Wikifier(frag,this.payload[0].contents.trim()),Config.debug)this.debugView.modes({block:!0,hidden:!0}),this.output.appendChild(frag);else{const errList=Array.from(frag.querySelectorAll(\".error\")).map((errEl=>errEl.textContent));if(errList.length>0)return this.error(`error${1===errList.length?\"\":\"s\"} within contents (${errList.join(\"; \")})`)}}}),Macro.add(\"switch\",{skipArgs:[\"switch\"],tags:[\"case\",\"default\"],handler(){if(0===this.args.full.length)return this.error(\"no expression specified\");const len=this.payload.length;if(1===len)return this.error(\"no cases specified\");let i,result;for(i=1;i<len;++i)if(\"default\"===this.payload[i].name){if(this.payload[i].args.length>0)return this.error(`<<default>> does not accept values, invalid: ${this.payload[i].args.raw}`);if(i+1!==len)return this.error(\"<<default>> must be the final case\")}else if(0===this.payload[i].args.length)return this.error(`no value(s) specified for <<${this.payload[i].name}>> (#${i})`);try{result=Scripting.evalJavaScript(this.args.full)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`)}const debugView=this.debugView;let success=!1;for(Config.debug&&debugView.modes({nonvoid:!1,hidden:!0}),i=1;i<len;++i){if(Config.debug&&this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1}),\"default\"===this.payload[i].name||this.payload[i].args.some((val=>val===result))){success=!0,new Wikifier(this.output,this.payload[i].contents);break}Config.debug&&this.debugView.modes({hidden:!0,invalid:!0})}if(Config.debug){for(++i;i<len;++i)this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1,hidden:!0,invalid:!0});debugView.modes({nonvoid:!1,hidden:!0,invalid:!success}),this.createDebugView(`/${this.name}`,`<</${this.name}>>`).modes({nonvoid:!1,hidden:!0,invalid:!success})}}}),Macro.add(\"textarea\",{isAsync:!0,handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"variable name\"),this.args.length<2&&errors.push(\"default value\"),this.error(`no ${errors.join(\" or \")} specified`)}if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);Config.debug&&this.debugView.modes({block:!0});const varId=createSlug(varName),defaultValue=this.args[1],autofocus=\"autofocus\"===this.args[2],el=document.createElement(\"textarea\");jQuery(el).attr({id:`${this.name}-${varId}`,name:`${this.name}-${varId}`,rows:4,tabindex:0}).addClass(`macro-${this.name}`).on(\"change.macros\",this.shadowHandler((function(){State.setVar(varName,this.value)}))).appendTo(this.output),State.setVar(varName,defaultValue),el.textContent=defaultValue,autofocus&&(el.setAttribute(\"autofocus\",\"autofocus\"),Engine.isPlaying()?jQuery(document).one(\":passageend\",(()=>{setTimeout((()=>el.focus()),Engine.DOM_DELAY)})):setTimeout((()=>el.focus()),Engine.DOM_DELAY))}}),Macro.add(\"timed\",{isAsync:!0,tags:[\"next\"],timers:new Set,t8nRe:/^(?:transition|t8n)$/,handler(){if(0===this.args.length)return this.error(\"no time value specified in <<timed>>\");const items=[];try{items.push({name:this.name,source:this.source,delay:Math.max(Engine.DOM_DELAY,cssTimeToMS(this.args[0])),content:this.payload[0].contents})}catch(ex){return this.error(`${ex.message} in <<timed>>`)}if(this.payload.length>1){let i;try{let len;for(i=1,len=this.payload.length;i<len;++i)items.push({name:this.payload[i].name,source:this.payload[i].source,delay:0===this.payload[i].args.length?items[items.length-1].delay:Math.max(Engine.DOM_DELAY,cssTimeToMS(this.payload[i].args[0])),content:this.payload[i].contents})}catch(ex){return this.error(`${ex.message} in <<next>> (#${i})`)}}Config.debug&&this.debugView.modes({block:!0});const transition=this.args.length>1&&this.self.t8nRe.test(this.args[1]),$wrapper=jQuery(document.createElement(\"span\")).addClass(`macro-${this.name}`).appendTo(this.output);this.self.registerTimeout(this.shadowHandler((item=>{const frag=document.createDocumentFragment();new Wikifier(frag,item.content,{cleanup:!1});let $output=$wrapper;Config.debug&&\"next\"===item.name&&($output=jQuery(new DebugView($output[0],\"macro\",item.name,item.source).output)),transition&&($output=jQuery(document.createElement(\"span\")).addClass(\"macro-timed-insert macro-timed-in\").appendTo($output)),$output.append(frag),transition&&setTimeout((()=>$output.removeClass(\"macro-timed-in\")),Engine.DOM_DELAY)})),items)},registerTimeout(callback,items){if(\"function\"!=typeof callback)throw new TypeError(\"callback parameter must be a function\");const passage=State.passage,turn=State.turns,timers=this.timers;let timerId=null,nextItem=items.shift();const worker=function(){if(timers.delete(timerId),State.passage!==passage||State.turns!==turn)return;const curItem=nextItem;null!=(nextItem=items.shift())&&(timerId=setTimeout(worker,nextItem.delay),timers.add(timerId)),callback.call(this,curItem)};timerId=setTimeout(worker,nextItem.delay),timers.add(timerId),1===timers.size&&jQuery(document).one(\":passageinit\",(()=>{timers.forEach((timerId=>clearTimeout(timerId))),timers.clear()}))}}),Macro.add(\"type\",{isAsync:!0,tags:null,typeId:0,handler(){if(0===this.args.length)return this.error(\"no speed specified\");const speed=cssTimeToMS(this.args[0]);if(speed<0)return this.error(`speed time value must be non-negative (received: ${this.args[0]})`);let cursor,elClass=\"\",elId=\"\",elTag=\"div\",skipKey=Config.macros.typeSkipKey,start=400;const options=this.args.slice(1);for(;options.length>0;){const option=options.shift();switch(option){case\"class\":if(0===options.length)return this.error(\"class option missing required class name(s)\");if(elClass=options.shift(),\"\"===elClass)throw new Error('class option class name(s) must be non-empty (received: \"\")');break;case\"element\":if(0===options.length)return this.error(\"element option missing required element tag name\");if(elTag=options.shift(),\"\"===elTag)throw new Error('element option tag name must be non-empty (received: \"\")');break;case\"id\":if(0===options.length)return this.error(\"id option missing required ID\");if(elId=options.shift(),\"\"===elId)throw new Error('id option ID must be non-empty (received: \"\")');break;case\"keep\":cursor=\"keep\";break;case\"none\":cursor=\"none\";break;case\"skipkey\":if(0===options.length)return this.error(\"skipkey option missing required key value\");if(skipKey=options.shift(),\"\"===skipKey)throw new Error('skipkey option key value must be non-empty (received: \"\")');break;case\"start\":{if(0===options.length)return this.error(\"start option missing required time value\");const value=options.shift();if(start=cssTimeToMS(value),start<0)throw new Error(`start option time value must be non-negative (received: ${value})`);break}default:return this.error(`unknown option: ${option}`)}}const contents=this.payload[0].contents;if(\"\"===contents.trim())return;Config.debug&&this.debugView.modes({block:!0});const className=`macro-${this.name}`,namespace=`.${className}`,$target=jQuery(document.createElement(elTag)).addClass(`${className} ${className}-target`).appendTo(this.output);TempState.macroTypeQueue||(TempState.macroTypeQueue=[],$(document).off(namespace).one(`:passageinit${namespace}`,(()=>$(document).off(namespace))));const startTyping=0===TempState.macroTypeQueue.length,selfId=++this.self.typeId,allowCleanup=this.self.allowCleanup;TempState.macroTypeQueue.push({id:selfId,handler:this.shadowHandler((()=>{const $wrapper=jQuery(document.createElement(elTag)).addClass(className);elId&&$wrapper.attr(\"id\",elId),elClass&&$wrapper.addClass(elClass),new Wikifier($wrapper,contents,allowCleanup(elTag)?undefined:{cleanup:!1});const passage=State.passage,turn=State.turns;if(0===speed||!Config.macros.typeVisitedPassages&&State.passages.slice(0,-1).some((title=>title===passage))||$wrapper.find(\".error\").length>0)return $target.replaceWith($wrapper),TempState.macroTypeQueue.shift(),void(TempState.macroTypeQueue.length>0&&TempState.macroTypeQueue.first().handler());const typer=new NodeTyper({targetNode:$wrapper.get(0),classNames:\"none\"===cursor?null:`${className}-cursor`});$target.replaceWith($wrapper);const keydownAndNS=`keydown${namespace}`,typingStopAndNS=`:typingstop${namespace}`;$(document).off(keydownAndNS).on(keydownAndNS,(ev=>{scrubEventKey(ev.key)!==skipKey||ev.target!==document.body&&ev.target!==document.documentElement||(ev.preventDefault(),$(document).off(keydownAndNS),typer.finish())})).one(typingStopAndNS,(()=>{TempState.macroTypeQueue&&(0===TempState.macroTypeQueue.length?triggerEvent(\":typingcomplete\"):TempState.macroTypeQueue.first().handler())}));const typeNode=function(){const typeNodeMember=function(typeIntervalId){State.passage===passage&&State.turns===turn&&typer.type()||(typeIntervalId&&clearInterval(typeIntervalId),TempState.macroTypeQueue&&TempState.macroTypeQueue.length>0&&TempState.macroTypeQueue.first().id===selfId&&TempState.macroTypeQueue.shift(),triggerEvent(\":typingstop\",$wrapper),$wrapper.addClass(`${className}-done`),\"keep\"===cursor&&$wrapper.addClass(`${className}-cursor`))};triggerEvent(\":typingstart\",$wrapper),typeNodeMember();const typeNodeMemberId=setInterval((()=>typeNodeMember(typeNodeMemberId)),speed)};start?setTimeout(typeNode,start):typeNode()}))}),startTyping&&(Engine.isPlaying()?$(document).one(`:passageend${namespace}`,(()=>TempState.macroTypeQueue.first().handler())):TempState.macroTypeQueue.first().handler())},allowCleanup(tagName){switch(tagName.toUpperCase()){case\"ARTICLE\":case\"DIV\":case\"FOOTER\":case\"FORM\":case\"HEADER\":case\"MAIN\":case\"SECTION\":return!0}return!1}}),Macro.add(\"unset\",{skipArgs:!0,handler(){if(0===this.args.full.length)return this.error(\"no story/temporary variable list specified\");const searchRe=/[,;\\s]*((?:State\\.(?:variables|temporary)|setup)\\.)/g,replacer=(_,p1)=>`; delete ${p1}`,cleanupRe=/^; /;try{const unsetExp=this.args.full.replace(searchRe,replacer).replace(cleanupRe,\"\");Scripting.evalJavaScript(unsetExp)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`)}Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"widget\",{tags:null,handler(){if(0===this.args.length)return this.error(\"no widget name specified\");const widgetName=this.args[0],isNonVoid=this.args.length>1&&\"container\"===this.args[1];if(Macro.has(widgetName))return this.error(`cannot clobber existing ${Macro.get(widgetName).isWidget?\"widget\":\"macro\"} \"${widgetName}\"`);try{const widgetDef={isWidget:!0,handler:(widgetCode=this.payload[0].contents,function(){const shadowStore={};Object.hasOwn(State.temporary,\"args\")&&(shadowStore._args=State.temporary.args),State.temporary.args=Array.from(this.args),State.temporary.args.raw=this.args.raw,State.temporary.args.full=this.args.full,State.temporary.args.name=this.name,this.addShadow(\"_args\"),isNonVoid&&(Object.hasOwn(State.temporary,\"contents\")&&(shadowStore._contents=State.temporary.contents),State.temporary.contents=this.payload[0].contents,this.addShadow(\"_contents\")),Object.hasOwn(State.variables,\"args\")&&(shadowStore.$args=State.variables.args),State.variables.args=State.temporary.args,this.addShadow(\"$args\");try{const resFrag=document.createDocumentFragment(),errList=[];if(new Wikifier(resFrag,widgetCode),Array.from(resFrag.querySelectorAll(\".error\")).forEach((errEl=>{errList.push(errEl.textContent)})),0!==errList.length)return this.error(`error${errList.length>1?\"s\":\"\"} within widget code (${errList.join(\"; \")})`);this.output.appendChild(resFrag)}catch(ex){return this.error(`cannot execute widget: ${ex.message}`)}finally{Object.hasOwn(shadowStore,\"_args\")?State.temporary.args=shadowStore._args:delete State.temporary.args,isNonVoid&&(Object.hasOwn(shadowStore,\"_contents\")?State.temporary.contents=shadowStore._contents:delete State.temporary.contents),Object.hasOwn(shadowStore,\"$args\")?State.variables.args=shadowStore.$args:delete State.variables.args}})};isNonVoid&&(widgetDef.tags=[]),Macro.add(widgetName,widgetDef),Config.debug&&this.debugView.modes({hidden:!0})}catch(ex){return this.error(`cannot create widget macro \"${widgetName}\": ${ex.message}`)}var widgetCode}}),Macro.add(\"silently\",\"silent\"),Macro.add(\"actions\",{handler(){console.warn(`[DEPRECATED] <<${this.name}>> macro is deprecated.`);const $list=jQuery(document.createElement(\"ul\")).addClass(this.name).appendTo(this.output);for(let i=0;i<this.args.length;++i){let passage,text,$image,setFn;if(\"object\"==typeof this.args[i]?this.args[i].isImage?($image=jQuery(document.createElement(\"img\")).attr(\"src\",this.args[i].source),Object.hasOwn(this.args[i],\"passage\")&&$image.attr(\"data-passage\",this.args[i].passage),Object.hasOwn(this.args[i],\"title\")&&$image.attr(\"title\",this.args[i].title),Object.hasOwn(this.args[i],\"align\")&&$image.attr(\"align\",this.args[i].align),passage=this.args[i].link,setFn=this.args[i].setFn):(text=this.args[i].text,passage=this.args[i].link,setFn=this.args[i].setFn):text=passage=this.args[i],Object.hasOwn(State.variables,\"#actions\")&&Object.hasOwn(State.variables[\"#actions\"],passage)&&State.variables[\"#actions\"][passage])continue;const $link=jQuery(Wikifier.createInternalLink(jQuery(document.createElement(\"li\")).appendTo($list),passage,null,((passage,fn)=>()=>{Object.hasOwn(State.variables,\"#actions\")||(State.variables[\"#actions\"]={}),State.variables[\"#actions\"][passage]=!0,\"function\"==typeof fn&&fn()})(passage,setFn))).addClass(`macro-${this.name}`).append($image||document.createTextNode(text));$image&&$link.addClass(\"link-image\")}}}),Macro.add(\"choice\",{handler(){if(console.warn(`[DEPRECATED] <<${this.name}>> macro is deprecated.`),0===this.args.length)return this.error(\"no passage specified\");const choiceId=State.passage;let passage,text,$image,setFn,$link;if(1===this.args.length?\"object\"==typeof this.args[0]?this.args[0].isImage?($image=jQuery(document.createElement(\"img\")).attr(\"src\",this.args[0].source),Object.hasOwn(this.args[0],\"passage\")&&$image.attr(\"data-passage\",this.args[0].passage),Object.hasOwn(this.args[0],\"title\")&&$image.attr(\"title\",this.args[0].title),Object.hasOwn(this.args[0],\"align\")&&$image.attr(\"align\",this.args[0].align),passage=this.args[0].link,setFn=this.args[0].setFn):(text=this.args[0].text,passage=this.args[0].link,setFn=this.args[0].setFn):text=passage=this.args[0]:(passage=this.args[0],text=this.args[1]),Object.hasOwn(State.variables,\"#choice\")&&Object.hasOwn(State.variables[\"#choice\"],choiceId)&&State.variables[\"#choice\"][choiceId])return $link=jQuery(document.createElement(\"span\")).addClass(`link-disabled macro-${this.name}`).attr(\"tabindex\",-1).append($image||document.createTextNode(text)).appendTo(this.output),void($image&&$link.addClass(\"link-image\"));$link=jQuery(Wikifier.createInternalLink(this.output,passage,null,(()=>{Object.hasOwn(State.variables,\"#choice\")||(State.variables[\"#choice\"]={}),State.variables[\"#choice\"][choiceId]=!0,\"function\"==typeof setFn&&setFn()}))).addClass(`macro-${this.name}`).append($image||document.createTextNode(text)),$image&&$link.addClass(\"link-image\")}});var Dialog=(()=>{const DEFAULT_TOP=50;let $overlay=null,$dialog=null,$title=null,$body=null,lastActive=null,observer=null,onCloseFn=null,scrollbarWidth=0;function calcInset(top){const $window=jQuery(window),inset={left:\"\",right:\"\",top:\"\",bottom:\"\"};$dialog.css(inset);let horzSpace=$window.width()-$dialog.outerWidth(!0)-1,vertSpace=$window.height()-$dialog.outerHeight(!0)-1;if(horzSpace<=20+scrollbarWidth&&(vertSpace-=scrollbarWidth),vertSpace<=20+scrollbarWidth&&(horzSpace-=scrollbarWidth),inset.left=inset.right=horzSpace<=20?\"10px\":(horzSpace/2|0)+\"px\",vertSpace<=20)inset.top=inset.bottom=\"10px\";else{const vertPos=vertSpace/2|0;inset.top=vertPos>top?top+\"px\":inset.bottom=vertPos+\"px\"}return inset}function onResize(top){\"block\"===$dialog.css(\"display\")&&$dialog.css(calcInset(null!=top?top:DEFAULT_TOP))}function close(ev){if(triggerEvent(\":dialogclosing\",$body),jQuery(document).off(\".dialog-close\"),observer?(observer.disconnect(),observer=null):$body.off(\".dialog-resize\"),jQuery(window).off(\".dialog-resize\"),$dialog.removeClass(\"open\").css({left:\"\",right:\"\",top:\"\",bottom:\"\"}),jQuery(\"#ui-bar,#story\").find(\"[tabindex=-2]\").removeAttr(\"aria-hidden\").attr(\"tabindex\",0),jQuery(\"body>[tabindex=-3]\").removeAttr(\"aria-hidden\").removeAttr(\"tabindex\"),$overlay.removeClass(\"open\"),jQuery(document.documentElement).removeAttr(\"data-dialog\"),$title.empty(),$body.empty().removeClass(),lastActive&&(lastActive.focus(),lastActive=null),onCloseFn)try{onCloseFn(ev)}finally{onCloseFn=null}return triggerEvent(\":dialogclose\",$body),triggerEvent(\":dialogclosed\",$body),Dialog}function create(title,classNames){return $title.empty().append((null!=title?String(title):\"\")||\" \"),$body.empty().removeClass(),null!=classNames&&$body.addClass(classNames),Dialog}function getBody(){return $body.get(0)}function isOpen(classNames){return $dialog.hasClass(\"open\")&&(!classNames||classNames.splitOrEmpty(/\\s+/).every((cn=>$body.hasClass(cn))))}function wiki(...args){return $body.wiki(...args),Dialog}return Object.preventExtensions(Object.create(null,{append:{value:function(...args){return $body.append(...args),Dialog}},body:{value:getBody},close:{value:close},create:{value:create},empty:{value:function(){return $body.empty(),Dialog}},init:{value:function(){if(document.getElementById(\"ui-dialog\"))return;scrollbarWidth=(()=>{let calcWidth;try{const inner=document.createElement(\"p\");inner.style.width=\"100%\",inner.style.height=\"200px\";const outer=document.createElement(\"div\");outer.style.position=\"absolute\",outer.style.left=\"0\",outer.style.top=\"0\",outer.style.width=\"100px\",outer.style.height=\"100px\",outer.style.visibility=\"hidden\",outer.style.overflow=\"hidden\",outer.appendChild(inner),document.body.appendChild(outer);const w1=inner.offsetWidth;outer.style.overflow=\"auto\";let w2=inner.offsetWidth;w1===w2&&(w2=outer.clientWidth),document.body.removeChild(outer),calcWidth=w1-w2}catch(ex){}return calcWidth||17})();const $elems=jQuery(document.createDocumentFragment()).append(`<div id=\"ui-overlay\" class=\"ui-close\"></div><div id=\"ui-dialog\" tabindex=\"0\" role=\"dialog\" aria-labelledby=\"ui-dialog-title\" aria-modal=\"true\"><div id=\"ui-dialog-titlebar\"><h1 id=\"ui-dialog-title\"></h1><button id=\"ui-dialog-close\" class=\"ui-close\" tabindex=\"0\" aria-label=\"${L10n.get(\"textClose\")}\">ï€</button></div><div id=\"ui-dialog-body\"></div></div>`);$overlay=jQuery($elems.find(\"#ui-overlay\").get(0)),$dialog=jQuery($elems.find(\"#ui-dialog\").get(0)),$title=jQuery($elems.find(\"#ui-dialog-title\").get(0)),$body=jQuery($elems.find(\"#ui-dialog-body\").get(0)),$elems.insertBefore(\"body>script#script-sugarcube\")}},isOpen:{value:isOpen},open:{value:function(options,onClose){const{top:top}=Object.assign({top:DEFAULT_TOP},options);if(null!=onClose){const closeType=getTypeOf(onClose);if(\"function\"!==closeType)throw new TypeError(`Dialog.open onClose parameter must be a function (received: ${closeType})`);onCloseFn=onClose}else onCloseFn=null;triggerEvent(\":dialogopening\",$body),isOpen()||(lastActive=getActiveElement()),jQuery(document.documentElement).attr(\"data-dialog\",\"open\"),$overlay.addClass(\"open\"),jQuery(\"body>:not(script,#store-area,tw-storydata,#ui-bar,#ui-overlay,#ui-dialog)\").attr(\"tabindex\",-3).attr(\"aria-hidden\",!0),jQuery(\"#ui-bar,#story\").find(\"[tabindex]:not([tabindex^=-])\").attr(\"tabindex\",-2).attr(\"aria-hidden\",!0);const resizeHandler=jQuery.throttle(40,(()=>onResize(top)));return $body.imagesLoaded().always(resizeHandler),$dialog.css(calcInset(top)).addClass(\"open\").focus(),jQuery(window).off(\".dialog-resize\").on(\"resize.dialog-resize\",resizeHandler),Has.mutationObserver?(observer=new MutationObserver((mutations=>{for(let i=0;i<mutations.length;++i)if(\"childList\"===mutations[i].type){$body.imagesLoaded().always(resizeHandler),resizeHandler();break}})),observer.observe(getBody(),{childList:!0,subtree:!0})):$body.off(\".dialog-resize\").on(\"DOMNodeInserted.dialog-resize DOMNodeRemoved.dialog-resize\",(()=>{$body.imagesLoaded().always(resizeHandler),resizeHandler()})),jQuery(document).off(\".dialog-close\").one(\"click.dialog-close\",\".ui-close\",(ev=>{close(ev)})).one(\"keypress.dialog-close\",\".ui-close\",(function(ev){13!==ev.which&&32!==ev.which||triggerEvent(\"click\",this)})),triggerEvent(\":dialogopen\",$body),triggerEvent(\":dialogopened\",$body),Dialog}},resize:{value:function(options){return onResize(\"object\"==typeof options?options.top:undefined)}},wiki:{value:wiki},wikiPassage:{value:function(name){return wiki(Story.get(name).processText())}},setup:{value:function(title,classNames){return console.warn(\"[DEPRECATED] Dialog.setup() is deprecated.\"),create(title,classNames),getBody()}}}))})(),Engine=(()=>{const States=enumFrom({Init:\"init\",Idle:\"idle\",Playing:\"playing\",Rendering:\"rendering\"}),DOM_DELAY=40,_initDebugViews=[];let _state=States.Init,_lastPlay=null;function engineGo(offset){const succeeded=State.go(offset);return succeeded&&engineShow(),succeeded}function engineShow(){return enginePlay(State.passage,!0)}function enginePlay(title,noHistory){if(_state===States.Init)return!1;let passageReadyOutput,passageDoneOutput,passageTitle=title;if(_state=States.Playing,TempState={},State.clearTemporary(),\"function\"==typeof Config.navigation.override)try{const overrideTitle=Config.navigation.override(passageTitle);overrideTitle&&(passageTitle=overrideTitle)}catch(ex){}const passage=Story.get(passageTitle);if(jQuery.event.trigger({passage:passage,type:\":passageinit\",detail:{passage:passage}}),Object.keys(prehistory).forEach((task=>{\"function\"==typeof prehistory[task]&&prehistory[task].call(passage,task)})),noHistory||State.create(passage.name),document.body.className&&(document.body.className=\"\"),_lastPlay=now(),Object.keys(predisplay).forEach((task=>{\"function\"==typeof predisplay[task]&&predisplay[task].call(passage,task)})),Story.has(\"PassageReady\"))try{passageReadyOutput=Wikifier.wikifyEval(Story.get(\"PassageReady\").text)}catch(ex){console.error(ex),Alert.error(\"PassageReady\",ex.message)}_state=States.Rendering;const dataTags=passage.tags.length>0?passage.tags.join(\" \"):null,passageEl=document.createElement(\"div\");jQuery(passageEl).attr({id:passage.id,\"data-passage\":passage.name,\"data-tags\":dataTags}).addClass(`passage passage-in ${passage.className}`),jQuery(document.body).attr(\"data-tags\",dataTags).addClass(passage.className),jQuery(document.documentElement).attr(\"data-tags\",dataTags),jQuery.event.trigger({content:passageEl,passage:passage,type:\":passagestart\",detail:{content:passageEl,passage:passage}}),Object.keys(prerender).forEach((task=>{\"function\"==typeof prerender[task]&&prerender[task].call(passage,passageEl,task)})),Story.has(\"PassageHeader\")&&new Wikifier(passageEl,Story.get(\"PassageHeader\").processText()),passageEl.appendChild(passage.render()),Story.has(\"PassageFooter\")&&new Wikifier(passageEl,Story.get(\"PassageFooter\").processText()),jQuery.event.trigger({content:passageEl,passage:passage,type:\":passagerender\",detail:{content:passageEl,passage:passage}}),Object.keys(postrender).forEach((task=>{\"function\"==typeof postrender[task]&&postrender[task].call(passage,passageEl,task)}));const containerEl=document.getElementById(\"passages\");if(containerEl.hasChildNodes()&&(\"number\"==typeof Config.passages.transitionOut||\"string\"==typeof Config.passages.transitionOut&&\"\"!==Config.passages.transitionOut&&Has.transitionEndEvent?Array.from(containerEl.childNodes).forEach((outgoing=>{const $outgoing=jQuery(outgoing);if(outgoing.nodeType===Node.ELEMENT_NODE&&$outgoing.hasClass(\"passage\")){if($outgoing.hasClass(\"passage-out\"))return;$outgoing.attr({id:`out-${$outgoing.attr(\"id\")}`,\"aria-hidden\":\"true\",\"aria-live\":\"off\"}).addClass(\"passage-out\"),\"string\"==typeof Config.passages.transitionOut?$outgoing.on(Has.transitionEndEvent,(ev=>{ev.originalEvent.propertyName===Config.passages.transitionOut&&$outgoing.remove()})):setTimeout((()=>$outgoing.remove()),Math.max(DOM_DELAY,Config.passages.transitionOut))}else $outgoing.remove()})):jQuery(containerEl).empty()),jQuery(passageEl).appendTo(containerEl),setTimeout((()=>jQuery(passageEl).removeClass(\"passage-in\")),DOM_DELAY/2),window.scroll(0,0),_state=States.Playing,Story.has(\"PassageDone\"))try{passageDoneOutput=Wikifier.wikifyEval(Story.get(\"PassageDone\").text)}catch(ex){console.error(ex),Alert.error(\"PassageDone\",ex.message)}if(jQuery.event.trigger({content:passageEl,passage:passage,type:\":passagedisplay\",detail:{content:passageEl,passage:passage}}),Object.keys(postdisplay).forEach((task=>{\"function\"==typeof postdisplay[task]&&postdisplay[task].call(passage,task)})),UI.update(),Config.debug){let debugView;null!=passageReadyOutput&&(debugView=new DebugView(document.createDocumentFragment(),\"special\",\"PassageReady\",\"PassageReady\"),debugView.modes({hidden:!0}),debugView.append(passageReadyOutput),jQuery(passageEl).prepend(debugView.output)),null!=passageDoneOutput&&(debugView=new DebugView(document.createDocumentFragment(),\"special\",\"PassageDone\",\"PassageDone\"),debugView.modes({hidden:!0}),debugView.append(passageDoneOutput),jQuery(passageEl).append(debugView.output)),1===State.turns&&_initDebugViews.length>0&&jQuery(passageEl).prepend(_initDebugViews)}return jQuery(\"#story\").find(\"a,link,button,input,select,textarea\").not(\"[tabindex]\").attr(\"tabindex\",0),State.turns>1&&Save.browser.auto.isEnabled()&&Save.browser.auto.save(),jQuery.event.trigger({content:passageEl,passage:passage,type:\":passageend\",detail:{content:passageEl,passage:passage}}),_state=States.Idle,_lastPlay=now(),passageEl}return Object.preventExtensions(Object.create(null,{States:{value:States},DOM_DELAY:{get:()=>DOM_DELAY},init:{value:function(){if(_state!==States.Init)return;jQuery(\"#init-no-js,#init-lacking\").remove();const $main=jQuery('<div id=\"story\" role=\"main\"></div>'),markup=Story.has(\"StoryInterface\")&&Story.get(\"StoryInterface\").text.trim();if(markup){if(Config.ui.updateStoryElements=!1,UIBar.destroy(),jQuery(document.head).find(\"#style-core-display\").remove(),$main.append(markup),$main.find(\"#story\").length>0)throw new Error('element with ID \"story\" found within \"StoryInterface\" special passage');const $passages=$main.find(\"#passages\");if(0===$passages.length)throw new Error('no element with ID \"passages\" found within \"StoryInterface\" special passage');$passages.empty().not(\"[aria-live]\").attr(\"aria-live\",\"polite\").end();const $dataInitPassages=$main.find(\"[data-init-passage]\"),$dataPassages=$main.find(\"[data-passage]\");$dataInitPassages.each(((i,el)=>{if(\"passages\"===el.id)throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} id=\"passages\"> must not contain a \"data-init-passage\" content attribute`);const passage=el.getAttribute(\"data-init-passage\").trim();if(el.hasAttribute(\"data-passage\"))throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} data-init-passage=\"${passage}\"> must not contain a \"data-passage\" content attribute`);if(null!==el.firstElementChild)throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} data-init-passage=\"${passage}\"> contains child elements`);Story.has(passage)&&jQuery(document).one(\":uiupdate.engine\",(()=>{const frag=document.createDocumentFragment();new Wikifier(frag,Story.get(passage).processText().trim()),jQuery(el).empty().append(frag)}))})),$dataPassages.each(((i,el)=>{if(\"passages\"===el.id)throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} id=\"passages\"> must not contain a \"data-passage\" content attribute`);const passage=el.getAttribute(\"data-passage\").trim();if(null!==el.firstElementChild)throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} data-passage=\"${passage}\"> contains child elements`);Story.has(passage)&&jQuery(document).on(\":uiupdate.engine\",(()=>{const frag=document.createDocumentFragment();new Wikifier(frag,Story.get(passage).processText().trim()),jQuery(el).empty().append(frag)}))}))}else $main.append('<div id=\"passages\" aria-live=\"polite\"></div>');$main.insertBefore(\"body>script#script-sugarcube\")}},runUserScripts:{value:function(){_state===States.Init&&((()=>{const storyStyle=document.createElement(\"style\");new StyleWrapper(storyStyle).add(Story.getStyles().map((style=>style.text.trim())).join(\"\\n\")),jQuery(storyStyle).appendTo(document.head).attr({id:\"style-story\",type:\"text/css\"})})(),Story.getScripts().forEach((script=>{try{Scripting.evalJavaScript(script.text)}catch(ex){console.error(ex),Alert.error(script.name,getErrorMessage(ex))}})),Story.getWidgets().forEach((widget=>{try{Wikifier.wikifyEval(widget.processText())}catch(ex){console.error(ex),Alert.error(widget.name,getErrorMessage(ex))}})))}},runUserInit:{value:function(){if(_state===States.Init&&(Story.getInits().forEach((passage=>{try{const debugBuffer=Wikifier.wikifyEval(passage.text);if(Config.debug){const debugView=new DebugView(document.createDocumentFragment(),\"special\",`${passage.name} [init-tagged]`,`${passage.name} [init-tagged]`);debugView.modes({hidden:!0}),debugView.append(debugBuffer),_initDebugViews.push(debugView.output)}}catch(ex){console.error(ex),Alert.error(`${passage.name} [init-tagged]`,getErrorMessage(ex))}})),Story.has(\"StoryInit\")))try{const debugBuffer=Wikifier.wikifyEval(Story.get(\"StoryInit\").text);if(Config.debug){const debugView=new DebugView(document.createDocumentFragment(),\"special\",\"StoryInit\",\"StoryInit\");debugView.modes({hidden:!0}),debugView.append(debugBuffer),_initDebugViews.push(debugView.output)}}catch(ex){console.error(ex),Alert.error(\"StoryInit\",getErrorMessage(ex))}}},start:{value:function(){if(_state===States.Init){if(null==Config.passages.start)throw new Error(\"starting passage not selected\");if(!Story.has(Config.passages.start))throw new Error(`starting passage (\"${Config.passages.start}\") not found`);if(_state=States.Idle,document.documentElement.focus(),State.restore())engineShow();else{const autoloadType=typeof Config.saves._internal_autoload_;\"string\"===autoloadType?\"prompt\"===Config.saves._internal_autoload_&&(UI.buildAutoload(),Dialog.open()):new Promise(((resolve,reject)=>{if(Save.browser.size>0&&(\"boolean\"===autoloadType&&Config.saves._internal_autoload_||\"function\"===autoloadType&&Config.saves._internal_autoload_()))return resolve();reject()})).then((()=>{Save.browser.continue(),engineShow()})).catch((()=>{enginePlay(Config.passages.start)}))}}}},restart:{value:function(){LoadScreen.show(),window.scroll(0,0),State.reset(),triggerEvent(\":enginerestart\"),window.location.reload()}},state:{get:function(){return _state}},isIdle:{value:function(){return _state===States.Idle}},isPlaying:{value:function(){return _state!==States.Idle}},isRendering:{value:function(){return _state===States.Rendering}},lastPlay:{get:function(){return _lastPlay}},goTo:{value:function(index){const succeeded=State.goTo(index);return succeeded&&engineShow(),succeeded}},go:{value:engineGo},backward:{value:function(){return engineGo(-1)}},forward:{value:function(){return engineGo(1)}},show:{value:engineShow},play:{value:enginePlay},display:{value:function(title,link,option){console.warn(\"[DEPRECATED] Engine.display() is deprecated.\");let noHistory=!1;switch(option){case undefined:break;case\"replace\":case\"back\":noHistory=!0;break;default:throw new Error(`Engine.display option parameter called with obsolete value \"${option}\"; please notify the developer`)}enginePlay(title,noHistory)}},minDomActionDelay:{get:()=>DOM_DELAY}}))})();const idb=(()=>{if(null==window.indexedDB)return Object.freeze({lock:!0,init:()=>!1,get active(){return!1},set active(_){},get footerHTML(){return!1},set footerHTML(_){}});let lock=!0,active=!0,dbName=\"idb\",migrationNeeded=!1,open=!1,settings={};updateSettings();let db,saveDetails=[],openRequest=null;function openDB(name=dbName){return new Promise(((resolve,reject)=>{dbName=name,openRequest=indexedDB.open(idb.dbName),openRequest.onupgradeneeded=event=>{if(console.log(\"updating idb\",event.oldVersion),0===event.oldVersion)openRequest.result.createObjectStore(\"saves\",{keyPath:\"slot\"}),openRequest.result.createObjectStore(\"details\",{keyPath:\"slot\"}),migrationNeeded=!0},openRequest.onerror=()=>{console.log(\"error opening idb\",openRequest.error),reject(openRequest.error)},openRequest.onsuccess=()=>{db=openRequest.result,lock=!1,open=!0,getSaveDetails().then((d=>saveDetails=d)),console.log(\"idbOpen success\"),navigator.storage&&\"function\"==typeof navigator.storage.persist&&navigator.storage.persist(),db.onclose=ev=>{open=!1,active=!1,console.log(\"idb connection closed, this shouldn't happen\",ev),Errors?Errors.report(\"ERROR: idb connection closed unexpectedly\",ev):alert(\"ERROR: idb connection closed unexpectedly\")},db.onerror=ev=>{console.error(`Database error: ${ev.target.errorCode}`),active=!1},migrationNeeded&&(importFromLocalStorage(),migrationNeeded=!1),resolve(db)},openRequest.onblocked=()=>{console.log(\"something went wrong\",openRequest.error),reject(openRequest.error)}}))}function updateSettings(setting,value){settings=Serial.parse(localStorage.getItem(\"idb-settings\"))||{warnSave:!1,warnLoad:!1,warnDelete:!0,active:!window.FCHostPersistent,useDelta:!1},setting&&(settings[setting]=value),active=settings.active,localStorage.setItem(\"idb-settings\",Serial.stringify(settings))}updateSettings();const baddies=[];function funNuke(target,path=\"\",verbose=!0){if(!target)return console.log(\"no target specified\");for(const key in target){const value=target[key],newPath=`${path}['${key}']`;null==value||(\"function\"==typeof value||value.toJSON?(verbose&&V.idbTest&&console.log(`Warn: ${newPath} of type ${typeof value} shouldn't be in STORY variables!!!`),target[key]=Serial.stringify(value),baddies.push(newPath)):\"object\"==typeof value&&funNuke(value,newPath,verbose))}}function ekuNnuf(target=V,paths){function revive(target,path){if(\"string\"!=typeof path||\"\"===path)return console.log(\"Warn: invalid path\",clone(path));const accessors=path.slice(2,-2).split(\"']['\");let ref=target;for(let i=0,destination=accessors.length-1;i<=destination;i++)i===destination?ref[accessors[i]]=Serial.parse(ref[accessors[i]]):ref=ref[accessors[i]];return!0}let path=paths.shift();for(;path;){try{revive(target,path)}catch(ex){console.log(\"WARN: couldn't restore story var function\",path)}path=paths.shift()}}async function importFromLocalStorage(){function processSave(saveObj){const save=saveObj.state;save.delta&&(save.history=State.deltaDecode(save.delta)),delete save.delta,window.DoLSave&&DoLSave.decompressIfNeeded({state:save});const vars=save.history[save.index].variables;if(!vars.saveId){const saveId=Math.floor(9e4*Math.random())+1e4;save.history.forEach((s=>s.variables.saveId=saveId))}return[save,{date:saveObj.date,id:saveObj.id,title:saveObj.title,metadata:saveObj.metadata||{saveId:vars.saveId,saveName:vars.saveName}}]}const autoSaves=Save.browser.auto.entries();if(autoSaves.length>0){const saveData=processSave(Save.browser.auto.getFull(autoSaves[0].index));await setItem(0,saveData[0],{slot:0,data:saveData[1]})}const oldSaves=Save.browser.slot.entries();for(let i=0;i<oldSaves.length;i++){const saveData=processSave(Save.browser.slot.getFull(oldSaves[i].index));await setItem(i+1,saveData[0],{slot:i+1,data:saveData[1]})}return await getSaveDetails().then((d=>saveDetails=d)),console.log(\"idb migration successful\"),!0}function makePromise(transaction){return new Promise(((resolve,reject)=>{transaction.onsuccess=()=>(lock=!1,resolve(transaction.result)),transaction.oncomplete=()=>(lock=!1,resolve(transaction.result)),transaction.onerror=ev=>(lock=!1,active=!1,console.log(transaction.error,ev,\"error\"),reject(transaction.error)),transaction.onabort=()=>(lock=!1,console.log(\"aborted\",transaction.error),reject(transaction.error))}))}async function getItem(slot){open||await openDB();return makePromise(db.transaction(\"saves\",\"readonly\").objectStore(\"saves\").get(slot))}async function setItem(slot,saveObj,details={}){if(lock)return;if(null==saveObj||!saveObj.hasOwnProperty(\"history\"))return!1;lock=!0;const savesItem={slot:slot,data:saveObj},saveVars=saveObj.history[saveObj.index].variables,metadata={saveId:saveVars.saveId,saveName:saveVars.saveName};details=clone(details),details.slot??=slot,details.data??={},details.data.id??=Story.id,details.data.title??=Config.saves.descriptions(Save.Type.Slot),details.data.date??=Date.now(),details.data.metadata=metadata;try{open||await openDB();let counter=0;saveObj.history.forEach((s=>{baddies.splice(0),funNuke(s.variables,\"\",!counter++),baddies.length&&(s.baddies=clone(baddies))})),settings.useDelta&&(saveObj.delta=State.deltaEncode(saveObj.history),delete saveObj.history);const transactionRequest=db.transaction([\"saves\",\"details\"],\"readwrite\");return transactionRequest.objectStore(\"saves\").delete(slot),transactionRequest.objectStore(\"saves\").add(savesItem),transactionRequest.objectStore(\"details\").delete(slot),transactionRequest.objectStore(\"details\").add(details),makePromise(transactionRequest)}catch(ex){return window.Errors?Errors.report(`idb.setItem failure unknown. Couldn't complete the save in slot ${slot}`):alert(`idb.setItem failure unknown. Couldn't complete the save in slot ${slot}`),lock=!1,new Promise((resolve=>resolve(!1)))}}async function deleteItem(slot){if(lock)return;open||await openDB(),lock=!0;const transactionRequest=db.transaction([\"saves\",\"details\"],\"readwrite\");return transactionRequest.objectStore(\"saves\").delete(slot),transactionRequest.objectStore(\"details\").delete(slot),makePromise(transactionRequest).then(await getSaveDetails().then((d=>saveDetails=d)))}function loadState(slot){if(!lock)return getItem(slot).then((value=>{if(null==value)return!1;value.data.delta&&(value.data.history=State.deltaDecode(value.data.delta),delete value.data.delta),value.data.history.forEach((s=>{s.baddies&&(ekuNnuf(s.variables,s.baddies),delete s.baddies)})),Save.onLoad.handlers.forEach((fn=>fn({state:value.data}))),State.unmarshalForSave(value.data),Engine.show()}))}async function saveState(slot,title){if(lock)return;const saveObj=State.marshalForSave();if(!V.saveId){const saveId=Math.floor(9e4*Math.random())+1e4;V.saveId=saveId,State.history.forEach((s=>s.variables.saveId=saveId)),saveObj.history.forEach((s=>s.variables.saveId=saveId))}return Save.onSave.handlers.forEach((fn=>fn({state:saveObj,date:Date.now()},{type:slot<=0?\"autosave\":\"slot\"}))),null!=saveObj&&(await setItem(slot,saveObj,{data:{title:title}}),await getSaveDetails().then((d=>saveDetails=d)),!0)}async function getSaveDetails(){open||await openDB();return makePromise(db.transaction([\"details\"],\"readonly\").objectStore(\"details\").getAll())}async function clearAll(){if(lock)return;open||await openDB();const transactionRequest=db.transaction([\"saves\",\"details\"],\"readwrite\");return transactionRequest.objectStore(\"saves\").clear(),transactionRequest.objectStore(\"details\").clear(),saveDetails=[],makePromise(transactionRequest)}function savesAllowed(){return\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed()}let listLength,listPage;const listLengthMax=20,listPageMax=20;let extraSaveWarn,latestSave={slot:1,date:0},footerHTML=\"\";function generateSavesPage(page=listPage-1,length=listLength){const listContainer=document.createElement(\"div\");listContainer.id=\"saves-list\",listContainer.classList.add(\"idb-saves-list\"),listContainer.appendChild(function(){const frag=document.createDocumentFragment(),saveListHeader=document.createElement(\"div\");saveListHeader.className=\"savesListRow\",frag.appendChild(saveListHeader);const headerSaveGroup=document.createElement(\"div\");headerSaveGroup.className=\"saveGroup\",saveListHeader.appendChild(headerSaveGroup);const headerSaveId=document.createElement(\"div\");headerSaveId.className=\"saveId\",headerSaveId.innerText=\"#\",headerSaveGroup.appendChild(headerSaveId);const headerSaveButton=document.createElement(\"div\");headerSaveButton.className=\"saveButton\",headerSaveButton.innerText=L10n.get(\"savesHeaderSaveLoad\"),headerSaveGroup.appendChild(headerSaveButton);const headerSaveName=document.createElement(\"div\");headerSaveName.className=\"saveName\",headerSaveName.innerText=L10n.get(\"savesHeaderIDName\"),headerSaveGroup.appendChild(headerSaveName);const headerSaveDetails=document.createElement(\"div\");headerSaveDetails.className=\"saveDetails\",headerSaveDetails.innerText=L10n.get(\"savesHeaderDetails\"),headerSaveGroup.appendChild(headerSaveDetails);const headerDeleteButton=document.createElement(\"div\");return headerDeleteButton.className=\"deleteButton\",headerSaveGroup.appendChild(headerDeleteButton),frag}());const saveUnlock=savesAllowed();let autoSaveDate;if(latestSave={slot:1,date:0},saveDetails.forEach((d=>{0===d.slot?autoSaveDate=d.data.date:d.data.date>latestSave.date&&(latestSave.slot=d.slot,latestSave.date=d.data.date)})),!listLength){const slot=saveDetails.length?saveDetails.last().slot:0;for(listLength=10;slot>listLength*listPageMax&&listLength<listLengthMax;listLength++);length=listLength}if(!Number.isInteger(page)){const latestSlot=saveDetails.find((d=>d.slot===latestSave.slot));if(latestSlot){const autoSaveExists=0===saveDetails[0].slot,ignoreAutoSave=latestSlot.data.date>autoSaveDate||latestSlot.data.metadata.saveId===saveDetails[0].data.metadata.saveId;page=!autoSaveExists||ignoreAutoSave?Math.floor((latestSave.slot-1)/length):0}else page=0;listPage=page+1}const pageField=document.getElementById(\"pageNum\");null!=pageField&&(pageField.value=listPage);const lengthField=document.getElementById(\"pageLen\");null!=lengthField&&(lengthField.value=listLength);const defaultDetailsObj={date:\"\",title:\"\",metadata:{saveId:\"\",saveName:\"\"}},autoDetailsObj=saveDetails[0]&&0===saveDetails[0].slot?saveDetails[0].data:clone(defaultDetailsObj);autoSaveDate>latestSave.date&&(autoDetailsObj.latestSlot=!0),autoDetailsObj.slot=0,Save.browser.auto.isEnabled()&&listContainer.appendChild(generateSaveRow(autoDetailsObj));for(let slot=length*page+1;slot<length*(page+1)+1;slot++){let detailsObj=clone(defaultDetailsObj);const detailsIndex=saveDetails.findIndex((d=>d.slot===slot));-1!==detailsIndex&&(detailsObj=saveDetails[detailsIndex].data,Number(latestSave.slot)===slot&&(detailsObj.latestSlot=!0)),detailsObj.slot=slot,detailsObj.saveUnlock=saveUnlock,listContainer.appendChild(generateSaveRow(detailsObj))}return listContainer}function createActionItem(id,classNames,text,label,callback){const $btn=jQuery(document.createElement(\"button\")).attr(\"id\",`saves-${id}`).text(text);return classNames&&$btn.addClass(classNames),callback?$btn.ariaClick({label:label},callback):$btn.ariaDisabled(!0),jQuery(document.createElement(\"li\")).append($btn)}function generateFooterRow(){const $diskButtons=jQuery(document.createElement(\"ul\")).addClass(\"buttons slots\");if(Has.fileAPI){const diskLoadInput=function(id,callback){const input=document.createElement(\"input\");return jQuery(input).attr({id:id,type:\"file\",tabindex:-1,\"aria-hidden\":!0}).css({display:\"block\",visibility:\"hidden\",position:\"fixed\",left:\"-16128px\",top:\"-16128px\",width:\"1px\",height:\"1px\"}).on(\"change\",callback),input}(\"saves-disk-load-handler\",(ev=>{jQuery(document).one(\":dialogclosed\",(()=>{Save.disk.load(ev).then(Engine.show,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))})),Dialog.close()}));$diskButtons.append(createActionItem(\"disk-save\",null,`${L10n.get(\"textSave\")}…`,L10n.get(\"savesLabelDiskSave\"),\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Disk)?()=>Save.disk.save(Story.name):null)).append(createActionItem(\"disk-load\",null,`${L10n.get(\"textLoad\")}…`,L10n.get(\"savesLabelDiskLoad\"),(()=>diskLoadInput.click()))),jQuery(diskLoadInput).appendTo($diskButtons)}return $diskButtons.append(createActionItem(\"clipboard-save\",\"ui-close\",`${L10n.get(\"savesLabelToClipboard\")}…`,L10n.get(\"savesLabelToClipboard\"),\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Disk)?()=>Save.toClipboard():null)),$diskButtons.append(createActionItem(\"clear\",null,L10n.get(\"textClear\"),L10n.get(\"savesLabelBrowserClear\"),(()=>saveList(\"confirm clear\")))),$diskButtons}function createButton(id,classNames,kind,index,callback){let text;switch(id){case\"delete\":text=L10n.get(\"textDelete\");break;case\"load\":text=L10n.get(\"textLoad\");break;case\"save\":text=L10n.get(\"textSave\");break;default:throw new Error(`buildSaves unknown ID \"${id}\"`)}const $btn=jQuery(document.createElement(\"button\")).attr(\"id\",`saves-${id}-${index}`).addClass(id);return classNames&&$btn.addClass(classNames),callback?$btn.ariaClick({label:`${text} ${kind} ${index>0?index:\"Autosave\"}`},(()=>{try{callback(index)}catch(ex){openAlert(`${ex.message}.</p><p>${L10n.get(\"textAborting\")}.`)}})):$btn.ariaDisabled(!0),$btn}function generateSaveRow(details){const row=document.createElement(\"div\");details.latestSlot&&0!==details.slot&&(row.id=\"latestSaveRow\"),row.className=\"savesListRow\";const group=document.createElement(\"div\");group.className=\"saveGroup\";const saveId=document.createElement(\"div\");saveId.className=\"saveId\",saveId.innerText=0===details.slot?\"A\":details.slot,(details.slot>listPageMax*listLengthMax||details.slot<0)&&saveId.classList.add(\"red\");const saveLoad=document.createElement(\"div\");saveLoad.className=\"saveButton\";const $saveButton=createButton(\"save\",null,L10n.get(\"savesTextBrowserSlot\"),details.slot,details.saveUnlock?()=>saveList(\"confirm save\",details):null),$loadButton=createButton(\"load\",null,L10n.get(\"savesTextBrowserSlot\"),details.slot,details.date?()=>saveList(\"confirm load\",details):null);0!==details.slot&&$saveButton.appendTo(saveLoad),$loadButton.appendTo(saveLoad);const saveName=document.createElement(\"div\");saveName.className=\"saveName\",V.saveId===details.metadata.saveId&&saveName.classList.add(\"gold\"),saveName.innerText=details.metadata.saveName?details.metadata.saveName.slice(0,10):details.metadata.saveId;const saveDetails=document.createElement(\"div\");saveDetails.className=\"saveDetails\";const description=document.createElement(\"span\");description.innerText=details.title||\" \";const date=document.createElement(\"span\");date.className=\"datestamp\",details.date?(details.latestSlot?date.classList.add(\"green\"):details.date>Date.now()-18e5&&date.classList.add(\"gold\"),date.innerText=new Date(details.date).toLocaleString()):date.innerText=\" \",saveDetails.appendChild(description),saveDetails.appendChild(date);const $deleteButton=createButton(\"delete\",null,L10n.get(\"savesTextBrowserSlot\"),details.slot,details.date?()=>saveList(\"confirm delete\",details):null);return group.append(saveId,saveLoad,saveName,saveDetails),row.appendChild(group),$deleteButton.appendTo(row),row}const replaceChildren=!!document.body.replaceChildren;async function saveList(mode,details){open||await openDB(),active&&!settings.active&&updateSettings(\"active\",!0),mode||(await getSaveDetails().then((d=>saveDetails=d)),mode=\"show saves\"),await new Promise((r=>setTimeout((()=>r(!0)),0)));const savesDiv=document.getElementById(\"saveList\")||document.getElementsByClassName(\"saveList\")[0]||document.getElementsByClassName(\"saves\")[0],list=document.createDocumentFragment(),cancelButton=document.createElement(\"button\");function generateOldSaveDescription(details){const oldSaveDescription=document.createDocumentFragment();if(!details||!details.date)return oldSaveDescription;const oldSaveTitle=document.createElement(\"p\");oldSaveTitle.innerText=`${L10n.get(\"savesDescTitle\")} ${details.title}`;const oldSaveData=document.createElement(\"p\");return oldSaveData.innerText=`${details.metadata.saveName?L10n.get(\"savesDescName\")+details.metadata.saveName:L10n.get(\"savesDescId\")+details.metadata.saveId} ${L10n.get(\"savesDescDate\")} ${new Date(details.date).toLocaleString()}`,oldSaveDescription.append(oldSaveTitle,oldSaveData),oldSaveDescription}switch(cancelButton.className=\"saveMenuButton saveMenuConfirm\",cancelButton.innerText=L10n.get(\"textCancel\"),cancelButton.onclick=()=>saveList(\"show saves\"),mode){case\"show saves\":{if(!savesAllowed()){const notAllowedWarning=document.createElement(\"h3\");notAllowedWarning.className=\"red\",notAllowedWarning.innerText=V.replayScene?L10n.get(\"savesDisallowedReplay\"):L10n.get(\"savesDisallowed\"),list.appendChild(notAllowedWarning)}const exportReminder=document.createElement(\"p\");if(exportReminder.id=\"saves-export-reminder\",exportReminder.innerText=L10n.get(\"savesExportReminder\"),list.appendChild(exportReminder),extraSaveWarn){const lostSaves=document.createElement(\"p\");lostSaves.innerHTML='<i class=\"description\"><u>Where are my saves?</u></i> ';const lostSavesTooltip=document.createElement(\"mouse\");lostSavesTooltip.classList.add(\"tooltip\",\"linkBlue\"),lostSavesTooltip.innerText=\"(?)\",lostSavesTooltip.appendChild(document.createElement(\"span\")),lostSavesTooltip.lastChild.innerText=\"If you can't find your saves, it's possible you saved them using a different storage method. Try toggling the \\\"Use old legacy storage\\\" option below the saves list.\",lostSaves.appendChild(lostSavesTooltip),list.appendChild(lostSaves)}list.appendChild(generateSavesPage()),generateFooterRow().appendTo(list),footerHTML&&list.appendChild(function(){if(!footerHTML)return null;const container=document.createElement(\"ul\");return container.className=\"buttons\",container.innerHTML=footerHTML,container}()),list.appendChild(function(){const container=document.createElement(\"ul\");let li;container.className=\"buttons slots\",li=document.createElement(\"li\"),li.append(L10n.get(\"savesPagerPage\")),container.appendChild(li);const prevPage=document.createElement(\"button\");prevPage.append(\"<\"),listPage>1?(prevPage.classList.add(\"saveMenuButton\"),prevPage.onclick=()=>{--listPage,saveList(\"show saves\")}):prevPage.disabled=!0,li=document.createElement(\"li\"),li.appendChild(prevPage),container.appendChild(li);const pageNum=document.createElement(\"input\");Object.assign(pageNum,{id:\"pageNum\",type:\"number\",value:listPage,style:\"width: 3em\",min:1,max:listPageMax,onchange:()=>{listPage=Math.clamp(Math.round(pageNum.value),1,listPageMax),saveList(\"show saves\")}}),container.appendChild(pageNum);const nextPage=document.createElement(\"button\");nextPage.append(\">\"),listPage<listPageMax?(nextPage.classList.add(\"saveMenuButton\"),nextPage.onclick=()=>{++listPage,saveList(\"show saves\")}):nextPage.disabled=!0,nextPage.onclick=()=>{listPage<listPageMax&&listPage++,saveList(\"show saves\")},li=document.createElement(\"li\"),li.appendChild(nextPage),container.appendChild(li),li=document.createElement(\"li\"),li.append(L10n.get(\"savesPagerSavesPerPage\")),container.appendChild(li);const pageLen=document.createElement(\"input\");Object.assign(pageLen,{id:\"pageLen\",type:\"number\",value:listLength,style:\"width: 3em\",min:1,max:listLengthMax,onchange:()=>{listLength=Math.clamp(pageLen.value,1,listLengthMax),saveList(\"show saves\")}}),li=document.createElement(\"li\"),li.append(pageLen),container.appendChild(li);const jumpToLatest=document.createElement(\"button\");return jumpToLatest.className=\"saveMenuButton\",jumpToLatest.innerText=L10n.get(\"savesPagerJump\"),jumpToLatest.onclick=()=>{listPage=Math.floor((latestSave.slot-1)/listLength+1),saveList(\"show saves\"),setTimeout((()=>{const el=document.getElementById(\"latestSaveRow\");null!=el&&(el.classList.remove(\"jumpToSaveTransition\"),el.classList.add(\"jumpToSaveTransition\"))}),Engine.minDomActionDelay+100)},li=document.createElement(\"li\"),li.appendChild(jumpToLatest),container.appendChild(li),container}());const ul=document.createElement(\"ul\");let li;ul.className=\"buttons slots\",li=document.createElement(\"li\"),li.append(L10n.get(\"savesOptionsConfirmOn\")),ul.appendChild(li);const reqSaveLabel=document.createElement(\"label\");reqSaveLabel.innerText=`${L10n.get(\"savesOptionsOverwrite\")} `;const reqSave=document.createElement(\"input\");reqSave.type=\"checkbox\",reqSave.checked=settings.warnSave,reqSave.onchange=()=>updateSettings(\"warnSave\",reqSave.checked),reqSaveLabel.appendChild(reqSave),li=document.createElement(\"li\"),li.appendChild(reqSaveLabel),ul.appendChild(li);const reqLoadLabel=document.createElement(\"label\");reqLoadLabel.innerText=`${L10n.get(\"textLoad\")} `;const reqLoad=document.createElement(\"input\");reqLoad.type=\"checkbox\",reqLoad.checked=settings.warnLoad,reqLoad.onchange=()=>updateSettings(\"warnLoad\",reqLoad.checked),reqLoadLabel.appendChild(reqLoad),li=document.createElement(\"li\"),li.appendChild(reqLoadLabel),ul.append(\"|\",li);const reqDeleteLabel=document.createElement(\"label\");reqDeleteLabel.innerText=`${L10n.get(\"textDelete\")} `;const reqDelete=document.createElement(\"input\");reqDelete.type=\"checkbox\",reqDelete.checked=settings.warnDelete,reqDelete.onchange=()=>updateSettings(\"warnDelete\",reqDelete.checked),reqDeleteLabel.appendChild(reqDelete),li=document.createElement(\"li\"),li.appendChild(reqDeleteLabel),ul.append(\"|\",li),ul.append(document.createElement(\"li\"));const idbtoggle=document.createElement(\"button\");idbtoggle.id=\"saves-idb-toggle\",idbtoggle.className=\"saveMenuButton\",idbtoggle.innerText=L10n.get(\"savesOptionsUseLegacy\"),idbtoggle.onclick=()=>{updateSettings(\"active\",!1),window.DoLSave?$.wiki(\"<<replace #saveList>><<saveList>><</replace>>\"):UI.buildSaves()},li=document.createElement(\"li\"),li.appendChild(idbtoggle),ul.appendChild(li),list.appendChild(ul),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list));const pageField=document.getElementById(\"pageNum\");null!=pageField&&(pageField.value=listPage);const lengthField=document.getElementById(\"pageLen\");null!=lengthField&&(lengthField.value=listLength),Dialog.resize()}),Engine.minDomActionDelay);break}case\"confirm save\":{if(!details.date||!settings.warnSave&&details.metadata.saveId===V.saveId)return saveState(details.slot).then(window.closeOverlay());const confirmSaveWarning=document.createElement(\"div\");confirmSaveWarning.className=\"saveBorder\";const confirmSaveWarningTitle=document.createElement(\"h3\");if(confirmSaveWarningTitle.className=\"red\",confirmSaveWarningTitle.innerText=`${\"\"===details.date?L10n.get(\"savesWarningSaveOnSlot\"):L10n.get(\"savesWarningOverwriteSlot\")} ${details.slot}?`,details.date&&V.saveId!==details.metadata.saveId){const overwriteWarning=document.createElement(\"span\");overwriteWarning.className=\"red\",overwriteWarning.innerText=L10n.get(\"savesWarningOverwriteID\")}const saveButton=document.createElement(\"input\");Object.assign(saveButton,{type:\"button\",className:\"saveMenuButton saveMenuConfirm\",value:L10n.get(\"textSave\"),onclick:()=>saveState(details.slot).then((()=>window.closeOverlay()))}),confirmSaveWarning.append(confirmSaveWarningTitle,generateOldSaveDescription(details),saveButton,cancelButton),list.appendChild(confirmSaveWarning),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list))}),Engine.minDomActionDelay);break}case\"confirm delete\":{if(!settings.warnDelete)return deleteItem(details.slot).then((()=>saveList(\"show saves\")));const confirmDeleteWarning=document.createElement(\"div\");confirmDeleteWarning.className=\"saveBorder\";const confirmDeleteWarningTitle=document.createElement(\"h3\");confirmDeleteWarningTitle.className=\"red\",confirmDeleteWarningTitle.innerText=`${L10n.get(\"savesWarningDeleteInSlot\")+(0===details.slot?\"auto\":details.slot)}?`;const deleteButton=document.createElement(\"input\");Object.assign(deleteButton,{type:\"button\",className:\"saveMenuButton saveMenuConfirm\",value:L10n.get(\"textDelete\"),onclick:()=>deleteItem(details.slot).then((()=>saveList(\"show saves\")))}),confirmDeleteWarning.append(confirmDeleteWarningTitle,generateOldSaveDescription(details),deleteButton,cancelButton),list.appendChild(confirmDeleteWarning),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list))}),Engine.minDomActionDelay);break}case\"confirm load\":{if(!settings.warnLoad)return Dialog.close(),loadState(details.slot).then((()=>window.closeOverlay()));const confirmLoad=document.createElement(\"div\");confirmLoad.className=\"saveBorder\";const confirmLoadTitle=document.createElement(\"h3\");confirmLoadTitle.className=\"red\",confirmLoadTitle.innerText=`${L10n.get(\"savesWarningLoad\")+(0===details.slot?\"auto\":details.slot)}?`;const loadButton=document.createElement(\"input\");Object.assign(loadButton,{type:\"button\",className:\"saveMenuButton saveMenuConfirm\",value:L10n.get(\"textLoad\"),onclick:()=>{Dialog.close(),idb.loadState(details.slot).then((()=>window.closeOverlay()))}}),confirmLoad.append(confirmLoadTitle,generateOldSaveDescription(details),loadButton,cancelButton),list.appendChild(confirmLoad),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list))}),Engine.minDomActionDelay);break}case\"confirm clear\":{const confirmClear=document.createElement(\"div\");confirmClear.className=\"saveBorder\";const confirmClearTitle=document.createElement(\"h2\");confirmClearTitle.className=\"red\",confirmClearTitle.innerText=L10n.get(\"savesWarningDeleteAll\");const clearButton=document.createElement(\"input\");Object.assign(clearButton,{type:\"button\",className:\"saveMenuButton saveMenuConfirm\",value:L10n.get(\"textClear\"),onclick:()=>clearAll().then((()=>saveList(\"show saves\")))}),confirmClear.append(confirmClearTitle,clearButton,cancelButton),list.appendChild(confirmClear),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list))}),Engine.minDomActionDelay);break}}}return void 0===window.closeOverlay&&(window.closeOverlay=Dialog.close),Object.freeze({get dbName(){return dbName},set dbName(val){dbName=val},get lock(){return lock},set lock(val){lock=Boolean(val)},get active(){return active},set active(val){active=val},get listLength(){return listLength},set listLength(val){listLength=val},get listPage(){return listPage},set listPage(val){listPage=val},getItem:getItem,setItem:setItem,deleteItem:deleteItem,clearAll:clearAll,getSaveDetails:getSaveDetails,getAllSaves:async function(){return open||await openDB(),makePromise(db.transaction([\"saves\"],\"readonly\").objectStore(\"saves\").getAll())},saveState:saveState,loadState:loadState,importFromLocalStorage:importFromLocalStorage,saveList:saveList,get footerHTML(){return footerHTML},set footerHTML(val){footerHTML=val},init:dbName=>openDB(dbName),close:function(){db.close(),open=!1},updateSettings:updateSettings,baddies:baddies,funNuke:funNuke,ekuNnuf:ekuNnuf})})();window.idb=idb;var Passage=(()=>{let tagsToSkip,decodePassageText;tagsToSkip=/^(?:debug|nobr|passage|widget|twine\\..*)$/i,decodePassageText=(()=>{const encodedRE=/\\r/g,hasEncodedRE=new RegExp(encodedRE.source);return function(str){if(null==str)return\"\";const val=String(str);return val&&hasEncodedRE.test(val)?val.replace(encodedRE,\"\"):val}})();return class{constructor(name,el){Object.defineProperties(this,{name:{value:decodeEntities(name)},element:{value:el||null},tags:{value:Object.freeze(el&&el.hasAttribute(\"tags\")?Array.from(new Set(el.getAttribute(\"tags\").trim().splitOrEmpty(/\\s+/))):[])}}),Object.defineProperties(this,{id:{value:`passage-${createSlug(this.name)}`},classes:{value:Object.freeze(0===this.tags.length?[]:(()=>this.tags.filter((tag=>!tagsToSkip.test(tag))).map((tag=>createSlug(tag))))())},domId:{get(){return this.id}},title:{get(){return this.name}}})}get className(){return this.classes.join(\" \")}get text(){if(null==this.element){const passage=encodeMarkup(this.name);return`<div class=\"error-view\"><span class=\"error\">${`${L10n.get(\"errorViewTitle\")}: ${L10n.get(\"errorNonexistentPassage\",{passage:passage})}`}</span></div>`}return decodePassageText(this.element.textContent)}processText(){if(null==this.element)return this.text;if(this.tags.includes(\"Twine.image\"))return`[img[${this.text}]]`;let processed=this.text;return Config.passages.onProcess&&(processed=Config.passages.onProcess.call(null,{title:this.name,tags:this.tags,text:processed})),(Config.passages.nobr||this.tags.includes(\"nobr\"))&&(processed=processed.replace(/^\\n+|\\n+$/g,\"\").replace(/\\n+/g,\" \")),processed}render(options){const frag=document.createDocumentFragment();return new Wikifier(frag,this.processText(),options),frag}description(){return`${L10n.get(\"textTurn\")} ${State.turns}`}}})(),Save=(()=>{const Type=enumFrom({Unknown:0,Auto:1,Slot:2,Disk:3,Base64:4,Autosave:1,Serialize:4}),MAX_INDEX=15,INDEX_DELIMITER=\":\",AUTO_SUBKEY=\"save.auto.\",AUTO_DATA_SUBKEY=`${AUTO_SUBKEY}data${INDEX_DELIMITER}`,AUTO_INFO_SUBKEY=`${AUTO_SUBKEY}info${INDEX_DELIMITER}`,SLOT_SUBKEY=\"save.slot.\",SLOT_DATA_SUBKEY=`${SLOT_SUBKEY}data${INDEX_DELIMITER}`,SLOT_INFO_SUBKEY=`${SLOT_SUBKEY}info${INDEX_DELIMITER}`,onLoadHandlers=new Set,onSaveHandlers=new Set;function createDetails(saveType,description,metadata){const metadataType=typeof metadata;if(\"object\"!==metadataType&&\"undefined\"!==metadataType)throw new TypeError(\"metadata parameter must be an object or null/undefined\");const cfgMetadata=Config.saves.metadata?Config.saves.metadata(saveType):undefined,cfgMetadataType=typeof cfgMetadata;if(\"object\"!==cfgMetadataType&&\"undefined\"!==cfgMetadataType)throw new TypeError(\"Config.saves.metadata function must return an object or null/undefined\");const details={type:saveType};let desc;null!=description&&(desc=String(description).trim()),desc||\"function\"!=typeof Config.saves.descriptions||(desc=Config.saves.descriptions(saveType),\"string\"==typeof desc&&(desc=desc.trim())),details.desc=desc||`${L10n.get(\"textTurn\")} ${State.turns}`;const fullMetadata=Object.assign({},cfgMetadata,metadata);return Object.keys(fullMetadata).length>0&&(details.metadata=fullMetadata),details}function findNewest(saveType){let keys;switch(saveType){case Type.Auto:keys=getKeys(isAutoInfoKey);break;case Type.Slot:keys=getKeys(isSlotInfoKey);break;default:keys=getKeys(isInfoKey)}switch(keys.length){case 0:return{index:-1};case 1:return{index:getIndexFromKey(keys[0]),type:getTypeFromKey(keys[0])}}return keys.map((key=>({value:{index:getIndexFromKey(key),type:getTypeFromKey(key)},date:storage.get(key).date}))).sort(((a,b)=>b.date-a.date)).first().value}function getIndexFromKey(key){const pos=key.lastIndexOf(INDEX_DELIMITER);if(-1===pos)throw new Error(`unable to get index from save key (received: ${key})`);return Number(key.slice(pos+1))}function getAutoInfoKeyFromIndex(index){return`${AUTO_INFO_SUBKEY}${index}`}function getAutoDataKeyFromIndex(index){return`${AUTO_DATA_SUBKEY}${index}`}function getSlotInfoKeyFromIndex(index){return`${SLOT_INFO_SUBKEY}${index}`}function getSlotDataKeyFromIndex(index){return`${SLOT_DATA_SUBKEY}${index}`}function getKeys(predicate){return storage.keys().filter(predicate)}function getTypeFromKey(key){return isAutoKey(key)?Type.Auto:Type.Slot}function isInfoKey(key){return key.startsWith(AUTO_INFO_SUBKEY)||key.startsWith(SLOT_INFO_SUBKEY)}function isAutoKey(key){return key.startsWith(AUTO_SUBKEY)}function isAutoInfoKey(key){return key.startsWith(AUTO_INFO_SUBKEY)}function isSlotKey(key){return key.startsWith(SLOT_SUBKEY)}function isSlotInfoKey(key){return key.startsWith(SLOT_INFO_SUBKEY)}function saveBlobToDiskAs(data,filename,extension){if(\"string\"!=typeof filename)throw new Error(\"filename parameter must be a string\");const baseName=createFilename(filename);if(\"\"===baseName)throw new Error(\"filename parameter must not consist solely of illegal characters\");const datestamp=function(date){if(!(date instanceof Date))throw new TypeError(\"createDatestamp date parameter must be a Date object\");let MM=date.getMonth()+1,DD=date.getDate(),hh=date.getHours(),mm=date.getMinutes(),ss=date.getSeconds();return MM<10&&(MM=`0${MM}`),DD<10&&(DD=`0${DD}`),hh<10&&(hh=`0${hh}`),mm<10&&(mm=`0${mm}`),ss<10&&(ss=`0${ss}`),`${date.getFullYear()}${MM}${DD}-${hh}${mm}${ss}`}(new Date);let saveName=`${baseName}-${datestamp}`;if(\"free-cities\"===Story.id&&\"save\"===extension)try{const vars=State.top.variables,arcologyName=vars.arcologies===undefined||0===vars.arcologies.length?\"New_Game_Setup\":vars.arcologies[0].name.replaceAll(\" \",\"_\").substring(0,20),week=String(vars.week||0).padStart(5,\"0\"),slaveCount=String(vars.slaves?.length||0).padStart(5,\"0\");saveName=`${baseName}-${arcologyName}-W${week}-S${slaveCount}-R${String(vars.releaseID||\"\").padStart(5,\"0\")}-${datestamp}`}catch(ex){console.error(ex),console.error(\"Could not find required data in V for the new naming scheme, falling back to the legacy naming scheme. See error above for details\")}const fileExt=createFilename(extension)||\"save\";saveAs(new Blob([data],{type:\"text/plain;charset=UTF-8\"}),`${saveName}.${fileExt}`)}function saveToBrowserStorage(saveData,compression=!0){const{data:data,dataKey:dataKey,info:info,infoKey:infoKey}=saveData;try{storage.set(dataKey,data,compression)&&(storage.set(infoKey,info)||storage.delete(dataKey))}catch(ex){throw storage.delete(dataKey),storage.delete(infoKey),ex}}function browserClear(){return autoClear(),slotClear(),!0}function browserIsEnabled(){return autoIsEnabled()||slotIsEnabled()}function autoClear(){return getKeys(isAutoKey).forEach((key=>storage.delete(key))),!0}function autoDelete(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.delete(getAutoInfoKeyFromIndex(index)),storage.delete(getAutoDataKeyFromIndex(index)),!0}function autoGet(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.get(getAutoInfoKeyFromIndex(index))}function autoHas(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.has(getAutoInfoKeyFromIndex(index))}function autoIsEnabled(){return\"cookie\"!==storage.name&&Config.saves.maxAutoSaves>0}function autoLoad(index){return new Promise((resolve=>{if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);if(Engine.state===Engine.States.Init)throw new Error(L10n.get(\"saveErrorLoadTooEarly\"));const info=storage.get(getAutoInfoKeyFromIndex(index)),data=storage.get(getAutoDataKeyFromIndex(index));if(!info||!data)throw new Error(L10n.get(\"saveErrorNonexistent\"));unmarshal(Object.assign(info,data)),resolve(!0)}))}function autoSave(desc,metadata){if(!autoIsEnabled()||\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed(Type.Auto))return!1;if(idb.active)return idb.saveState(0,desc),!0;const index=(findNewest(Type.Auto).index+1)%Config.saves.maxAutoSaves,infoKey=getAutoInfoKeyFromIndex(index),dataKey=getAutoDataKeyFromIndex(index),{info:info,data:data}=splitSave(marshal(createDetails(Type.Auto,desc,metadata)));saveToBrowserStorage({data:data,dataKey:dataKey,info:info,infoKey:infoKey},!1)}function slotClear(){return getKeys(isSlotKey).forEach((key=>storage.delete(key))),!0}function slotDelete(index){if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`slot save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.delete(getSlotInfoKeyFromIndex(index)),storage.delete(getSlotDataKeyFromIndex(index)),!0}function slotGet(index){if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`slot save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.get(getSlotInfoKeyFromIndex(index))}function slotHas(index){if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`slot save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.has(getSlotInfoKeyFromIndex(index))}function slotIsEnabled(){return\"cookie\"!==storage.name&&Config.saves.maxSlotSaves>0}function slotLoad(index){return new Promise((resolve=>{if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`slot save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);if(Engine.state===Engine.States.Init)throw new Error(L10n.get(\"saveErrorLoadTooEarly\"));const info=storage.get(getSlotInfoKeyFromIndex(index)),data=storage.get(getSlotDataKeyFromIndex(index));if(!info||!data)throw new Error(L10n.get(\"saveErrorNonexistent\"));unmarshal(Object.assign(info,data)),resolve(!0)}))}function slotSave(index,desc,metadata){if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>=Config.saves.maxSlotSaves)throw new RangeError(`slot save index out of bounds (range: 0–${Config.saves.maxSlotSaves-1}; received: ${index})`);if(!slotIsEnabled()||\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed(Type.Slot))throw new Error(L10n.get(\"saveErrorDisallowed\"));const infoKey=getSlotInfoKeyFromIndex(index),dataKey=getSlotDataKeyFromIndex(index),{info:info,data:data}=splitSave(marshal(createDetails(Type.Slot,desc,metadata)));saveToBrowserStorage({data:data,dataKey:dataKey,info:info,infoKey:infoKey})}function slotSize(){return getKeys(isSlotInfoKey).length}function diskLoad(event){return new Promise(((resolve,reject)=>{const reader=new FileReader;jQuery(reader).on(\"loadend\",(()=>{try{if(Engine.state===Engine.States.Init)throw new Error(L10n.get(\"saveErrorLoadTooEarly\"));if(reader.error)throw new Error(`${L10n.get(\"saveErrorDiskLoadFail\")}: ${reader.error}`);let save;try{save=Serial.parse(LZString.decompressFromBase64(reader.result))}catch(ex){throw new Error(L10n.get(\"saveErrorDecodeFail\"))}unmarshal(save),resolve(save.metadata)}catch(ex){reject(ex)}})),reader.readAsText(event.target.files[0])}))}function diskSave(filename,metadata){if(null==filename)throw new Error(\"Save.disk.save filename parameter is required\");if(\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed(Type.Disk))throw new Error(L10n.get(\"saveErrorDisallowed\"));const details=createDetails(Type.Disk,filename,metadata);saveBlobToDiskAs(LZString.compressToBase64(Serial.stringify(marshal(details))),filename,\"save\")}function base64Load(base64){return new Promise((resolve=>{if(Engine.state===Engine.States.Init)throw new Error(L10n.get(\"saveErrorLoadTooEarly\"));let save;try{save=Serial.parse(LZString.decompressFromBase64(base64))}catch(ex){throw new Error(L10n.get(\"saveErrorDecodeFail\"))}unmarshal(save),resolve(save.metadata)}))}function base64Save(metadata){if(\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed(Type.Base64))throw new Error(L10n.get(\"saveErrorDisallowed\"));const details=createDetails(Type.Base64,null,metadata);return LZString.compressToBase64(Serial.stringify(marshal(details)))}function marshal(details){const save=Object.assign({},details,{date:Date.now(),id:Config.saves.id,state:State.marshalForSave()});return null!=Config.saves.version&&(save.version=Config.saves.version),onSaveHandlers.forEach((fn=>fn(save,function(save){switch(save.type){case Type.Auto:return{type:\"autosave\"};case Type.Slot:return{type:\"slot\"};case Type.Disk:return{type:\"disk\"};case Type.Base64:return{type:\"serialize\"}}throw new Error(`save.type must be an integer (received: ${typeof save.type})`)}(save)))),save.state.delta=State.deltaEncode(save.state.history),delete save.state.history,save}function splitSave(save){const{state:state,...info}=save;return{info:info,data:{state:state}}}function unmarshal(save){if(null==save||\"object\"!=typeof save||!Object.hasOwn(save,\"id\")||!Object.hasOwn(save,\"state\")||\"object\"!=typeof save.state||!Object.hasOwn(save.state,\"delta\"))throw new Error(L10n.get(\"saveErrorInvalidData\"));if(save.id!==Config.saves.id)throw new Error(L10n.get(\"saveErrorIdMismatch\"));if(save.state.history=State.deltaDecode(save.state.delta),delete save.state.delta,\"string\"==typeof save.type){switch(save.type){case\"auto\":case\"autosave\":save.type=Type.Auto;break;case\"slot\":save.type=Type.Slot;break;case\"disk\":save.type=Type.Disk;break;case\"base64\":case\"serialize\":save.type=Type.Base64}if(\"number\"!=typeof save.type)throw new Error(\"save.type is unknown\")}onLoadHandlers.forEach((fn=>fn(save))),State.unmarshalForSave(save.state)}return Object.preventExtensions(Object.create(null,{Type:{value:Type},MAX_INDEX:{get:()=>MAX_INDEX},init:{value:function(){return function(){const oldSaves=storage.get(\"saves\");if(null===oldSaves)return;if(autoClear(),slotClear(),oldSaves.autosave){const{info:info,data:data}=splitSave(oldSaves.autosave);info.desc=info.title,delete info.title,info.type=Type.Auto;const infoKey=getAutoInfoKeyFromIndex(0),dataKey=getAutoDataKeyFromIndex(0);storage.set(dataKey,data)&&(storage.set(infoKey,info)||storage.delete(dataKey))}oldSaves.slots.forEach(((save,index)=>{if(!save)return;const{info:info,data:data}=splitSave(save);info.desc=info.title,delete info.title,info.type=Type.Slot;const infoKey=getSlotInfoKeyFromIndex(index),dataKey=getSlotDataKeyFromIndex(index);storage.set(dataKey,data)&&(storage.set(infoKey,info)||storage.delete(dataKey))})),storage.delete(\"saves\")}(),function(){const index=storage.get(\"index\");if(storage.delete(\"index\"),null===index)return;if(null!==index.autosave){const autosave=storage.get(\"autosave\");storage.delete(\"autosave\");const{info:info,data:data}=splitSave(autosave);info.desc=info.title,delete info.title,info.type=Type.Auto;const infoKey=getAutoInfoKeyFromIndex(0),dataKey=getAutoDataKeyFromIndex(0);storage.set(dataKey,data)&&(storage.set(infoKey,info)||storage.delete(dataKey))}for(const[i,slot]of index.slots.entries()){if(null===slot)continue;const save=storage.get(`slot${i}`);storage.delete(`slot${i}`);const{info:info,data:data}=splitSave(save);info.desc=info.title,delete info.title,info.type=Type.Slot;const infoKey=getSlotInfoKeyFromIndex(i),dataKey=getSlotDataKeyFromIndex(i);storage.set(dataKey,data)&&(storage.set(infoKey,info)||storage.delete(dataKey))}}(),!0}},browser:{value:Object.preventExtensions(Object.create(null,{clear:{value:browserClear},continue:{value:function(){const newest=findNewest();return-1===newest.index?Promise.reject(new Error(L10n.get(\"saveErrorNonexistent\"))):newest.type===Type.Auto?autoLoad(newest.index):slotLoad(newest.index)}},isEnabled:{value:browserIsEnabled},size:{get:function(){return getKeys(isInfoKey).length}},auto:{value:Object.preventExtensions(Object.create(null,{clear:{value:autoClear},delete:{value:autoDelete},entries:{value:function(){return getKeys(isAutoInfoKey).map((key=>({index:getIndexFromKey(key),info:storage.get(key)}))).sort(((a,b)=>b.info.date-a.info.date))}},get:{value:autoGet},getFull:{value:function(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);const info=storage.get(getAutoInfoKeyFromIndex(index)),data=storage.get(getAutoDataKeyFromIndex(index));if(!info||!data)throw new Error(L10n.get(\"saveErrorNonexistent\"));return Object.assign(info,data)}},has:{value:autoHas},isEnabled:{value:autoIsEnabled},load:{value:autoLoad},save:{value:autoSave},size:{get:function(){return getKeys(isAutoInfoKey).length}}}))},slot:{value:Object.preventExtensions(Object.create(null,{clear:{value:slotClear},delete:{value:slotDelete},entries:{value:function(){return getKeys(isSlotInfoKey).map((key=>({index:getIndexFromKey(key),info:storage.get(key)}))).sort(((a,b)=>a.index-b.index))}},get:{value:slotGet},getFull:{value:function(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);const info=storage.get(getSlotInfoKeyFromIndex(index)),data=storage.get(getSlotDataKeyFromIndex(index));if(!info||!data)throw new Error(L10n.get(\"saveErrorNonexistent\"));return Object.assign(info,data)}},has:{value:slotHas},isEnabled:{value:slotIsEnabled},load:{value:slotLoad},save:{value:slotSave},size:{get:slotSize}}))}}))},disk:{value:Object.preventExtensions(Object.create(null,{export:{value:function(filename){if(null==filename)throw new Error(\"Save.browser.export filename parameter is required\");const auto=getKeys(isAutoInfoKey).map((infoKey=>{const index=getIndexFromKey(infoKey),info=storage.get(infoKey),data=storage.get(getAutoDataKeyFromIndex(index));if(!info||!data)throw new Error(\"during saves export auto save info or data nonexistent\");return{index:index,info:info,data:data}})),slot=getKeys(isSlotInfoKey).map((infoKey=>{const index=getIndexFromKey(infoKey),info=storage.get(infoKey),data=storage.get(getSlotDataKeyFromIndex(index));if(!info||!data)throw new Error(\"during saves export slot save info or data nonexistent\");return{index:index,info:info,data:data}}));saveBlobToDiskAs(LZString.compressToBase64(Serial.stringify({auto:auto,slot:slot})),filename,\"savesbundle\")}},import:{value:function(event){return new Promise(((resolve,reject)=>{const reader=new FileReader;jQuery(reader).on(\"loadend\",(()=>{try{if(reader.error)throw new Error(`${L10n.get(\"saveErrorDiskLoadFail\")}: ${reader.error}`);const badSave=O=>!Object.hasOwn(O,\"index\")||!Object.hasOwn(O,\"info\")||!Object.hasOwn(O,\"data\");let bundle;try{bundle=Serial.parse(LZString.decompressFromBase64(reader.result))}catch(ex){throw new Error(L10n.get(\"saveErrorDecodeFail\"))}if(null==bundle||\"object\"!=typeof bundle||!Object.hasOwn(bundle,\"auto\")||!(bundle.auto instanceof Array)||bundle.auto.some(badSave)||!Object.hasOwn(bundle,\"slot\")||!(bundle.slot instanceof Array)||bundle.slot.some(badSave))throw new Error(L10n.get(\"saveErrorInvalidData\"));autoClear(),slotClear(),bundle.auto.forEach((save=>saveToBrowserStorage({data:save.data,dataKey:getAutoDataKeyFromIndex(save.index),info:save.info,infoKey:getAutoInfoKeyFromIndex(save.index)},!1))),bundle.slot.forEach((save=>saveToBrowserStorage({data:save.data,dataKey:getSlotDataKeyFromIndex(save.index),info:save.info,infoKey:getSlotInfoKeyFromIndex(save.index)}))),resolve(!0)}catch(ex){reject(ex)}})),reader.readAsText(event.target.files[0])}))}},load:{value:diskLoad},save:{value:diskSave}}))},base64:{value:Object.preventExtensions(Object.create(null,{export:{value:function(){const auto=getKeys(isAutoInfoKey).map((infoKey=>{const index=getIndexFromKey(infoKey),info=storage.get(infoKey),data=storage.get(getAutoDataKeyFromIndex(index));if(!info||!data)throw new Error(\"during saves export auto save info or data nonexistent\");return{index:index,info:info,data:data}})),slot=getKeys(isSlotInfoKey).map((infoKey=>{const index=getIndexFromKey(infoKey),info=storage.get(infoKey),data=storage.get(getSlotDataKeyFromIndex(index));if(!info||!data)throw new Error(\"during saves export slot save info or data nonexistent\");return{index:index,info:info,data:data}}));return LZString.compressToBase64(Serial.stringify({auto:auto,slot:slot}))}},import:{value:function(base64){return new Promise((resolve=>{const badSave=O=>!Object.hasOwn(O,\"index\")||!Object.hasOwn(O,\"info\")||!Object.hasOwn(O,\"data\");let bundle;try{bundle=Serial.parse(LZString.decompressFromBase64(base64))}catch(ex){throw new Error(L10n.get(\"saveErrorDecodeFail\"))}if(null==bundle||\"object\"!=typeof bundle||!Object.hasOwn(bundle,\"auto\")||!(bundle.auto instanceof Array)||bundle.auto.some(badSave)||!Object.hasOwn(bundle,\"slot\")||!(bundle.slot instanceof Array)||bundle.slot.some(badSave))throw new Error(L10n.get(\"saveErrorInvalidData\"));autoClear(),slotClear(),bundle.auto.forEach((save=>saveToBrowserStorage({data:save.data,dataKey:getAutoDataKeyFromIndex(save.index),info:save.info,infoKey:getAutoInfoKeyFromIndex(save.index)},!1))),bundle.slot.forEach((save=>saveToBrowserStorage({data:save.data,dataKey:getSlotDataKeyFromIndex(save.index),info:save.info,infoKey:getSlotInfoKeyFromIndex(save.index)}))),resolve(!0)}))}},load:{value:base64Load},save:{value:base64Save}}))},toClipboard:{value:function(){if(\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed())return void(Dialog.isOpen()?$(document).one(\":dialogclosed\",(()=>UI.alert(L10n.get(\"savesDisallowed\")))):UI.alert(L10n.get(\"savesDisallowed\")));const details=createDetails(Type.Disk);!function(text){navigator.clipboard?navigator.clipboard.writeText(text).then((()=>console.log(\"Async: Copying save data to clipboard was successful!\")),(err=>console.error(\"Async: Could not copy save data: \",err))):function(text){const textArea=document.createElement(\"textarea\");textArea.value=text,textArea.style.top=\"0\",textArea.style.left=\"0\",textArea.style.position=\"fixed\",document.body.appendChild(textArea),textArea.focus(),textArea.select();try{const msg=document.execCommand(\"copy\")?\"successful\":\"unsuccessful\";console.log(\"Fallback: Copying save data was\",msg)}catch(err){console.error(\"Fallback: Oops, unable to copy save data\",err)}document.body.removeChild(textArea)}(text)}(LZString.compressToBase64(Serial.stringify(marshal(details))))}},onLoad:{value:Object.preventExtensions(Object.create(null,{add:{value:function(handler){const valueType=getTypeOf(handler);if(\"function\"!==valueType)throw new TypeError(`Save.onLoad.add handler parameter must be a function (received: ${valueType})`);onLoadHandlers.add(handler)}},clear:{value:function(){onLoadHandlers.clear()}},delete:{value:function(handler){return onLoadHandlers.delete(handler)}},size:{get:function(){return onLoadHandlers.size}},handlers:{get:()=>onLoadHandlers}}))},onSave:{value:Object.preventExtensions(Object.create(null,{add:{value:function(handler){const valueType=getTypeOf(handler);if(\"function\"!==valueType)throw new TypeError(`Save.onSave.add handler parameter must be a function (received: ${valueType})`);onSaveHandlers.add(handler)}},clear:{value:function(){onSaveHandlers.clear()}},delete:{value:function(handler){return onSaveHandlers.delete(handler)}},size:{get:function(){return onSaveHandlers.size}},handlers:{get:()=>onSaveHandlers}}))},get:{value(){throw new Error(\"[REMOVED] Save.get() has been removed.\")}},clear:{value:()=>(console.warn(\"[DEPRECATED] Save.clear() is deprecated.\"),browserClear())},ok:{value:()=>(console.warn(\"[DEPRECATED] Save.ok() is deprecated.\"),browserIsEnabled())},autosave:{value:Object.preventExtensions(Object.create(null,{ok:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.ok() is deprecated.\"),autoIsEnabled())},has:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.has() is deprecated.\"),autoHas(0))},get:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.get() is deprecated.\"),autoGet(0))},load:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.load() is deprecated.\"),autoLoad(0))},save:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.autosave.save() is deprecated.\"),autoSave(...args))},delete:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.delete() is deprecated.\"),autoDelete(0))}}))},slots:{value:Object.preventExtensions(Object.create(null,{ok:{value:()=>(console.warn(\"[DEPRECATED] Save.slots.ok() is deprecated.\"),slotIsEnabled())},length:{get:()=>(console.warn(\"[DEPRECATED] Save.slots.length is deprecated.\"),Config.saves.maxSlotSaves)},isEmpty:{value:()=>(console.warn(\"[DEPRECATED] Save.slots.isEmpty() is deprecated.\"),0===slotSize())},count:{value:()=>(console.warn(\"[DEPRECATED] Save.slots.count() is deprecated.\"),slotSize())},has:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.has() is deprecated.\"),slotHas(...args))},get:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.get() is deprecated.\"),slotGet(...args))},load:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.load() is deprecated.\"),slotLoad(...args))},save:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.save() is deprecated.\"),slotSave(...args))},delete:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.delete() is deprecated.\"),slotDelete(...args))}}))},export:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.export() is deprecated.\"),diskSave(...args))},import:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.import() is deprecated.\"),diskLoad(...args))},serialize:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.serialize() is deprecated.\"),base64Save(...args))},deserialize:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.deserialize() is deprecated.\"),base64Load(...args))}}))})(),Setting=(()=>{const Types=enumFrom({Header:0,Toggle:1,List:2,Range:3,Value:4}),_definitions=[];function updateSettingsObject(value){window.SugarCube.settings=settings=value}function createResultObject(def){const result={name:def.name,value:settings[def.name],default:def.default};return Object.hasOwn(def,\"list\")&&(result.list=def.list),Object.hasOwn(def,\"min\")&&(result.min=def.min),Object.hasOwn(def,\"max\")&&(result.max=def.max),Object.hasOwn(def,\"step\")&&(result.step=def.step),result}function clear(){return updateSettingsObject(create()),storage.delete(\"settings\"),!0}function create(){return Object.create(null)}function load(){const defaultSettings=create(),loadedSettings=storage.get(\"settings\")||create();_definitions.filter((def=>def.type!==Types.Header)).forEach((def=>defaultSettings[def.name]=def.default)),updateSettingsObject(Object.assign(defaultSettings,loadedSettings))}function save(){const savedSettings=create();return Object.keys(settings).length>0&&_definitions.filter((def=>def.type!==Types.Header&&settings[def.name]!==def.default)).forEach((def=>savedSettings[def.name]=settings[def.name])),0===Object.keys(savedSettings).length?(storage.delete(\"settings\"),!0):storage.set(\"settings\",savedSettings)}function add(type,name,def){if(arguments.length<2){const errors=[];throw arguments.length<1&&errors.push(\"type\"),arguments.length<2&&errors.push(\"name\"),new Error(`missing parameters, no ${errors.join(\" or \")} specified`)}if(null==def)def={};else if(\"object\"!=typeof def)throw new TypeError(\"definition parameter must be an object\");if(has(name))throw new Error(`cannot clobber existing setting \"${name}\"`);const definition={type:type,name:name};if(type!==Types.Value&&(definition.label=\"string\"==typeof def.label?def.label.trim():\"\"),\"string\"==typeof def.desc){const desc=def.desc.trim();\"\"!==desc&&(definition.desc=desc)}switch(type){case Types.Header:break;case Types.List:if(!Object.hasOwn(def,\"list\"))throw new Error(\"no list specified\");if(!Array.isArray(def.list))throw new TypeError(\"list must be an array\");if(0===def.list.length)throw new Error(\"list must not be empty\");if(definition.list=Object.freeze(def.list),null==def.default)definition.default=def.list[0];else{const defaultIndex=def.list.indexOf(def.default);if(-1===defaultIndex)throw new Error(\"list does not contain default\");definition.default=def.list[defaultIndex]}break;case Types.Range:if(!Object.hasOwn(def,\"min\"))throw new Error(\"no min specified\");if(\"number\"!=typeof def.min||Number.isNaN(def.min)||!Number.isFinite(def.min))throw new TypeError(\"min must be a finite number\");if(!Object.hasOwn(def,\"max\"))throw new Error(\"no max specified\");if(\"number\"!=typeof def.max||Number.isNaN(def.max)||!Number.isFinite(def.max))throw new TypeError(\"max must be a finite number\");if(!Object.hasOwn(def,\"step\"))throw new Error(\"no step specified\");if(\"number\"!=typeof def.step||Number.isNaN(def.step)||!Number.isFinite(def.step)||def.step<=0)throw new TypeError(\"step must be a finite number greater than zero\");{const fracDigits=(()=>{const str=String(def.step),pos=str.lastIndexOf(\".\");return-1===pos?0:str.length-pos-1})();function stepValidate(value){if(fracDigits>0){const ma=Number(`${def.min}e${fracDigits}`),sa=Number(`${def.step}e${fracDigits}`),va=Number(`${value}e${fracDigits}`)-ma;return Number(`${va-va%sa+ma}e-${fracDigits}`)}const va=value-def.min;return va-va%def.step+def.min}if(stepValidate(def.max)!==def.max)throw new RangeError(`max (${def.max}) is not a multiple of the step (${def.step}) plus the min (${def.min})`)}if(definition.max=def.max,definition.min=def.min,definition.step=def.step,null==def.default)definition.default=def.max;else{if(\"number\"!=typeof def.default||Number.isNaN(def.default)||!Number.isFinite(def.default))throw new TypeError(\"default must be a finite number\");if(def.default<def.min)throw new RangeError(`default (${def.default}) is less than min (${def.min})`);if(def.default>def.max)throw new RangeError(`default (${def.default}) is greater than max (${def.max})`);definition.default=def.default}break;case Types.Toggle:definition.default=Boolean(def.default);break;case Types.Value:definition.default=def.default;break;default:throw new Error(`unknown Setting type: ${type}`)}\"function\"==typeof def.onInit&&(definition.onInit=Object.freeze(def.onInit)),\"function\"==typeof def.onChange&&(definition.onChange=Object.freeze(def.onChange)),_definitions.push(Object.freeze(definition))}function get(name){return _definitions.find((definition=>definition.name===name))}function has(name){return _definitions.some((definition=>definition.name===name))}return Object.preventExtensions(Object.create(null,{Types:{value:Types},init:{value:function(){load(),_definitions.forEach((def=>{if(Object.hasOwn(def,\"onInit\")){const data=createResultObject(def);def.onInit.call(data,data)}}))}},clear:{value:clear},create:{value:create},load:{value:load},reset:{value:function(name){if(0===arguments.length)clear(),load();else{if(null==name||!has(name))throw new Error(`nonexistent setting \"${name}\"`);const def=get(name);def.type!==Types.Header&&(settings[name]=def.default)}return save()}},save:{value:save},add:{value:add},addHeader:{value:function(name,desc){add(Types.Header,name,{desc:desc})}},addList:{value:function(...args){add(Types.List,...args)}},addRange:{value:function(...args){add(Types.Range,...args)}},addToggle:{value:function(...args){add(Types.Toggle,...args)}},addValue:{value:function(...args){add(Types.Value,...args)}},delete:{value:function(name){for(let i=0;i<_definitions.length;++i)if(_definitions[i].name===name){_definitions.splice(i,1);break}Object.hasOwn(settings,name)&&delete settings[name]}},forEach:{value:function(callback,thisArg){_definitions.forEach(callback,thisArg)}},get:{value:get},has:{value:has},isEmpty:{value:function(){return 0===_definitions.length}},getValue:{value:function(name){return settings[name]}},setValue:{value:function(name,value){if(!has(name))throw new Error(\"no such setting\");settings[name]=value,save();const def=get(name);if(Object.hasOwn(def,\"onChange\")){const data=createResultObject(def);def.onChange.call(data,data)}return!0}}}))})(),Story=(()=>{let _ifId=\"\",_id=\"\",_name=\"\";const _passages=createPassageStore(),_inits=[],_scripts=[],_styles=[],_widgets=[],codePassageNames=[\"PassageDone\",\"PassageFooter\",\"PassageHeader\",\"PassageReady\",\"StoryAuthor\",\"StoryBanner\",\"StoryCaption\",\"StoryDisplayTitle\",\"StoryInit\",\"StoryInterface\",\"StoryMenu\",\"StoryShare\",\"StorySubtitle\"],codeTagNames=[\"init\",\"widget\"];function createPassageStore(passages){const store=Object.create(null);return passages?Object.assign(store,passages):store}function generateName(rawName){if(null==rawName)throw new Error(\"story name must not be null or undefined\");const name=decodeEntities(String(rawName)).trim();if(\"\"===name)throw new Error(\"story name must not be empty or consist solely of whitespace\");return name}function getId(){return _id}function getName(){return _name}function filter(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"Story.filter() predicate parameter must be a function\");const results=[];for(let i=0,keys=Object.keys(_passages);i<keys.length;++i){const passage=_passages[keys[i]];predicate.call(void 0===thisArg?this:thisArg,passage)&&results.push(passage)}return results}return Object.preventExtensions(Object.create(null,{init:{value:function(){function assertNoCodeTags(passage,desc){if(passage.tags.includesAny(codeTagNames))throw new Error(`${desc} passage \"${passage.name}\" includes code tags; invalid: \"${passage.tags.filter((tag=>codeTagNames.includes(tag))).sort().join('\", \"')}\"`)}function assertValidCodeTagUsage(passage){const found=passage.tags.filter((tag=>codeTagNames.includes(tag))).sort();if(found.length>1)throw new Error(`passage \"${passage.name}\" includes multiple code tags; invalid: \"${found.join('\", \"')}\"`)}{const $storydata=jQuery(\"tw-storydata\"),startNode=$storydata.attr(\"startnode\")||\"\";Config.passages.start=null,Config.debug=/\\bdebug\\b/.test($storydata.attr(\"options\")),$storydata.children(\"style\").each((function(i){_styles.push(new Passage(`tw-user-style-${i}`,this))})),$storydata.children(\"script\").each((function(i){_scripts.push(new Passage(`tw-user-script-${i}`,this))})),$storydata.children('tw-passagedata:not([tags~=\"Twine.private\"],[tags~=\"annotation\"])').each((function(){const $this=jQuery(this),pid=$this.attr(\"pid\")||\"\",passage=new Passage($this.attr(\"name\"),this);pid===startNode&&\"\"!==startNode?(Config.passages.start=passage.name,assertNoCodeTags(passage,\"starting\"),_passages[passage.name]=passage):codePassageNames.includes(passage.name)?(assertNoCodeTags(passage,\"code\"),_passages[passage.name]=passage):passage.tags.includes(\"init\")?(assertValidCodeTagUsage(passage),_inits.push(passage)):passage.tags.includes(\"widget\")?(assertValidCodeTagUsage(passage),_widgets.push(passage)):_passages[passage.name]=passage})),_ifId=$storydata.attr(\"ifid\"),_name=generateName(\"{{STORY_NAME}}\")}_id=function(name){let id=createSlug(name);if(\"\"===id)if(\"\"!==_ifId)id=_ifId;else for(let i=0;i<name.length;++i){const{char:char,start:start,end:end}=charAndPosAt(name,i);id+=char.codePointAt(0).toString(16),i+=end-start}return id}(_name),Config.saves.id=_id,document.title=_name}},id:{get:getId},ifId:{get:function(){return _ifId}},name:{get:getName},add:{value:function(descriptor){if(\"Object\"!==getTypeOf(descriptor))throw new TypeError(\"Story.add() descriptor parameter must be a generic object\");if(Object.hasOwn(_passages,descriptor.name))return!1;const elem=document.createElement(\"div\");elem.setAttribute(\"name\",descriptor.name),elem.setAttribute(\"tags\",descriptor.tags),elem.textContent=descriptor.text;const passage=new Passage(descriptor.name,elem);if(codePassageNames.includes(passage.name))throw new Error(`Story.add() passage descriptor object \"${passage.name}\" must not be a code passage`);if(passage.tags.includesAny(codeTagNames))throw new Error(`Story.add() passage descriptor object \"${passage.name}\" must not include code tags`);return _passages[passage.name]=passage,!0}},addDirect:{value:function(passage){return _passages[passage.name]=passage,!0}},delete:{value:function(name){let type=typeof name;switch(type){case\"number\":case\"string\":{const key=String(name);if(!Object.hasOwn(_passages,key))return!1;if(key===Config.passages.start||codePassageNames.includes(key))throw new Error(`Story.delete() passage \"${key}\" must not be a code passage`);if(_passages[key].tags.includesAny(codeTagNames))throw new Error(`Story.delete() passage \"${key}\" must not include code tags`);return delete _passages[key],!0}case\"undefined\":break;case\"object\":type=null===name?\"null\":\"an object\";break;default:type=`a ${type}`}throw new TypeError(`Story.delete() name parameter cannot be ${type}`)}},filter:{value:filter},find:{value:function(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"Story.find() predicate parameter must be a function\");for(let i=0,keys=Object.keys(_passages);i<keys.length;++i){const passage=_passages[keys[i]];if(predicate.call(void 0===thisArg?this:thisArg,passage))return passage}}},get:{value:function(name){let type=typeof name;switch(type){case\"number\":case\"string\":{const key=String(name);return Object.hasOwn(_passages,key)?_passages[key]:new Passage(key||\"(unknown)\")}case\"undefined\":break;case\"object\":type=null===name?\"null\":\"an object\";break;default:type=`a ${type}`}throw new TypeError(`Story.get() name parameter cannot be ${type}`)}},getInits:{value:function(){return Object.freeze(Array.from(_inits))}},getNormals:{value:function(){return Object.freeze(createPassageStore(_passages))}},getScripts:{value:function(){return Object.freeze(Array.from(_scripts))}},getStyles:{value:function(){return Object.freeze(Array.from(_styles))}},getWidgets:{value:function(){return Object.freeze(Array.from(_widgets))}},has:{value:function(name){let type=typeof name;switch(type){case\"number\":case\"string\":return Object.hasOwn(_passages,String(name));case\"undefined\":break;case\"object\":type=null===name?\"null\":\"an object\";break;default:type=`a ${type}`}throw new TypeError(`Story.has name parameter cannot be ${type}`)}},domId:{get:()=>(console.warn(\"[DEPRECATED] Story.domId is deprecated.\"),getId())},title:{get:()=>(console.warn(\"[DEPRECATED] Story.title is deprecated.\"),getName())},lookup:{value:function(key,value,sortKey=\"name\"){return console.warn(\"[DEPRECATED] Story.lookup() is deprecated.\"),filter((passage=>\"object\"==typeof passage[key]&&null!==passage[key]?passage[key]instanceof Array&&passage[key].some((m=>sameValueZero(m,value))):sameValueZero(passage[key],value))).sort(((a,b)=>a[sortKey]==b[sortKey]?0:a[sortKey]<b[sortKey]?-1:1))}},lookupWith:{value:function(predicate,sortKey=\"name\"){if(console.warn(\"[DEPRECATED] Story.lookupWith() is deprecated.\"),\"function\"!=typeof predicate)throw new TypeError(\"Story.lookupWith() predicate parameter must be a function\");return filter(predicate).sort(((a,b)=>a[sortKey]==b[sortKey]?0:a[sortKey]<b[sortKey]?-1:1))}}}))})(),UI=(()=>{function assembleLinkList(passage,listEl){let list=listEl;const debugState=Config.debug;Config.debug=!1;try{null==list&&(list=document.createElement(\"ul\"));const frag=document.createDocumentFragment();new Wikifier(frag,Story.get(passage).processText().trim(),{cleanup:!1});const errors=Array.from(frag.querySelectorAll(\".error\")).map((errEl=>errEl.textContent.replace(errorPrologRegExp,\"\")));if(errors.length>0)throw new Error(errors.join(\"; \"));for(;frag.hasChildNodes();){const node=frag.firstChild;if(node.nodeType===Node.ELEMENT_NODE&&\"A\"===node.nodeName.toUpperCase()){const li=document.createElement(\"li\");list.appendChild(li),li.appendChild(node)}else frag.removeChild(node)}}finally{Config.debug=debugState}return list}function buildRestart(){return Dialog.create(L10n.get(\"restartTitle\"),\"restart\").append(`<p>${L10n.get(\"restartMesgPrompt\")}</p><ul class=\"buttons\"><li><button id=\"restart-ok\">${L10n.get([\"restartTextOk\",\"textOk\"])}</button></li><li><button id=\"restart-cancel\" class=\"ui-close\">${L10n.get([\"restartTextCancel\",\"textCancel\"])}</button></li></ul>`),jQuery(Dialog.body()).find(\"#restart-ok\").ariaClick({one:!0},(()=>{jQuery(document).one(\":dialogclosed\",(()=>Engine.restart())),Dialog.close()})),!0}function buildSaves(){function createFileInput(id,callback){const input=document.createElement(\"input\");return jQuery(input).attr({id:id,type:\"file\",tabindex:-1,\"aria-hidden\":!0}).css({display:\"block\",visibility:\"hidden\",position:\"fixed\",left:\"-16128px\",top:\"-16128px\",width:\"1px\",height:\"1px\"}).on(\"change\",callback),input}function createActionItem(id,classNames,text,label,callback){const $btn=jQuery(document.createElement(\"button\")).attr(\"id\",`saves-${id}`).text(text);return classNames&&$btn.addClass(classNames),callback?$btn.ariaClick({label:label},callback):$btn.ariaDisabled(!0),jQuery(document.createElement(\"li\")).append($btn)}const browserEnabled=Save.browser.isEnabled();if(!browserEnabled&&!Has.fileAPI)return openAlert(L10n.get(\"warningNoSaves\")),!1;Dialog.create(L10n.get(\"savesTitle\"),\"saves\");const $dialogBody=jQuery(Dialog.body());if(browserEnabled){jQuery(document.createElement(\"h2\")).text(L10n.get(\"savesHeaderBrowser\")).appendTo($dialogBody),$dialogBody.append(function(){function createButton(id,classNames,kind,index,callback){let text;switch(id){case\"delete\":text=L10n.get(\"textDelete\");break;case\"load\":text=L10n.get(\"textLoad\");break;case\"save\":text=L10n.get(\"textSave\");break;default:throw new Error(`buildSaves unknown ID \"${id}\"`)}const $btn=jQuery(document.createElement(\"button\")).attr(\"id\",`saves-${id}-${index}`).addClass(id);return classNames&&$btn.addClass(classNames),callback?$btn.ariaClick({label:`${text} ${kind} ${index+1}`},(()=>{try{callback(index)}catch(ex){openAlert(`${ex.message}.</p><p>${L10n.get(\"textAborting\")}.`)}})):$btn.ariaDisabled(!0),$btn}const $tbody=jQuery(document.createElement(\"tbody\"));Save.browser.auto.entries().forEach((({index:index,info:info})=>{const $tdSlot=jQuery(document.createElement(\"td\")),$tdLoad=jQuery(document.createElement(\"td\")),$tdDesc=jQuery(document.createElement(\"td\")),$tdDele=jQuery(document.createElement(\"td\"));jQuery(document.createElement(\"div\")).text(info.desc).appendTo($tdDesc),jQuery(document.createElement(\"div\")).addClass(\"details\").addClass(\"datestamp\").text(`${L10n.get(\"savesTextBrowserAuto\")} ${index+1}  •  `).append(info.date?`${new Date(info.date).toLocaleString()}`:`<em>${L10n.get(\"savesTextNoDate\")}</em>`).appendTo($tdDesc),$tdLoad.append(createButton(\"load\",\"ui-close\",L10n.get(\"savesTextBrowserAuto\"),index,(index=>{jQuery(document).one(\":dialogclosed\",(()=>{Save.browser.auto.load(index).then(Engine.show,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))}))}))),$tdDele.append(createButton(\"delete\",null,L10n.get(\"savesTextBrowserAuto\"),index,(index=>{Save.browser.auto.delete(index),buildSaves()}))),jQuery(document.createElement(\"tr\")).append($tdSlot).append($tdLoad).append($tdDesc).append($tdDele).appendTo($tbody)}));const slotAllowed=\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Slot);return Save.browser.slot.entries().reduce(((slots,entry)=>(slots[entry.index]=entry,slots)),Array.from({length:Config.saves.maxSlotSaves},((_,i)=>({index:i})))).forEach((({index:index,info:info})=>{const $tdSlot=jQuery(document.createElement(\"td\")),$tdLoad=jQuery(document.createElement(\"td\")),$tdDesc=jQuery(document.createElement(\"td\")),$tdDele=jQuery(document.createElement(\"td\"));info?(jQuery(document.createElement(\"div\")).text(info.desc).appendTo($tdDesc),jQuery(document.createElement(\"div\")).addClass(\"details\").addClass(\"datestamp\").text(`${L10n.get(\"savesTextBrowserSlot\")} ${index+1}  •  `).append(info.date?`${new Date(info.date).toLocaleString()}`:`<em>${L10n.get(\"savesTextNoDate\")}</em>`).appendTo($tdDesc),$tdLoad.append(createButton(\"save\",null,L10n.get(\"savesTextBrowserSlot\"),index,index<Config.saves.maxSlotSaves&&slotAllowed?index=>{Save.browser.slot.save(index),buildSaves()}:null)),$tdLoad.append(createButton(\"load\",\"ui-close\",L10n.get(\"savesTextBrowserSlot\"),index,(index=>{jQuery(document).one(\":dialogclosed\",(()=>{Save.browser.slot.load(index).then(Engine.show,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))}))}))),$tdDele.append(createButton(\"delete\",null,L10n.get(\"savesTextBrowserSlot\"),index,(index=>{Save.browser.slot.delete(index),buildSaves()})))):($tdDesc.addClass(\"empty\"),jQuery(document.createElement(\"div\")).text(\" \").appendTo($tdDesc),jQuery(document.createElement(\"div\")).addClass(\"details\").addClass(\"datestamp\").text(`${L10n.get(\"savesTextBrowserSlot\")} ${index+1}`).appendTo($tdDesc),$tdLoad.append(createButton(\"save\",null,L10n.get(\"savesTextBrowserSlot\"),index,index<Config.saves.maxSlotSaves&&slotAllowed?index=>{Save.browser.slot.save(index),buildSaves()}:null)),$tdLoad.append(createButton(\"load\",\"ui-close\",L10n.get(\"savesTextBrowserSlot\"),index,null)),$tdDele.append(createButton(\"delete\",null,L10n.get(\"savesTextBrowserSlot\"),index))),jQuery(document.createElement(\"tr\")).append($tdSlot).append($tdLoad).append($tdDesc).append($tdDele).appendTo($tbody)})),jQuery(document.createElement(\"table\")).attr(\"id\",\"saves-list\").append($tbody)}());const $slotButtons=jQuery(document.createElement(\"ul\")).addClass(\"buttons slots\").appendTo($dialogBody);if(Has.fileAPI){const slotImportInput=createFileInput(\"saves-import-handler\",(ev=>{Save.disk.import(ev).then(buildSaves,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))}));$slotButtons.append(createActionItem(\"export\",null,`${L10n.get(\"textExport\")}…`,L10n.get(\"savesLabelBrowserExport\"),(()=>Save.disk.export(`saves-export-${Story.name}`)))).append(createActionItem(\"import\",null,`${L10n.get(\"textImport\")}…`,L10n.get(\"savesLabelBrowserImport\"),(()=>slotImportInput.click()))),jQuery(slotImportInput).appendTo($dialogBody)}idb.lock||$slotButtons.append(createActionItem(\"change-mode\",null,L10n.get(\"savesEnableIdb\"),L10n.get(\"savesEnableIdb\"),(()=>{Dialog.create(\"saves\",\"saves\").append($(document.createElement(\"h3\")).addClass(\"saves-loading\").text(\"Loading the save list, please wait...\")),idb.updateSettings(\"active\",!0),idb.saveList()}))),$slotButtons.append(createActionItem(\"clear\",null,L10n.get(\"textClear\"),L10n.get(\"savesLabelBrowserClear\"),Save.browser.size>0?()=>{Save.browser.clear(),buildSaves()}:null))}jQuery(document.createElement(\"h2\")).text(L10n.get(\"savesHeaderDisk\")).appendTo($dialogBody);const $diskButtons=jQuery(document.createElement(\"ul\")).addClass(\"buttons\").appendTo($dialogBody);if(Has.fileAPI){const diskLoadInput=createFileInput(\"saves-disk-load-handler\",(ev=>{jQuery(document).one(\":dialogclosed\",(()=>{Save.disk.load(ev).then(Engine.show,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))})),Dialog.close()}));$diskButtons.append(createActionItem(\"disk-save\",null,`${L10n.get(\"textSave\")}…`,L10n.get(\"savesLabelDiskSave\"),\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Disk)?()=>Save.disk.save(Story.name):null)).append(createActionItem(\"disk-load\",null,`${L10n.get(\"textLoad\")}…`,L10n.get(\"savesLabelDiskLoad\"),(()=>diskLoadInput.click()))),jQuery(diskLoadInput).appendTo($dialogBody)}return $diskButtons.append(createActionItem(\"clipboard-save\",\"ui-close\",`${L10n.get(\"savesLabelToClipboard\")}…`,L10n.get(\"savesLabelToClipboard\"),\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Disk)?()=>Save.toClipboard():null)),!0}function buildSettings(){Dialog.create(L10n.get(\"settingsTitle\"),\"settings\");const $dialogBody=jQuery(Dialog.body());return Setting.forEach((control=>{switch(control.type){case Setting.Types.Header:{const name=control.name,id=createSlug(name),$header=jQuery(document.createElement(\"div\")),$heading=jQuery(document.createElement(\"h2\"));return $header.attr(\"id\",`header-body-${id}`).append($heading).appendTo($dialogBody),$heading.attr(\"id\",`header-heading-${id}`).wikiWithOptions({cleanup:!1},name),void(control.desc&&jQuery(document.createElement(\"p\")).attr(\"id\",`header-desc-${id}`).wikiWithOptions({cleanup:!1},control.desc).appendTo($header))}case Setting.Types.Value:return}const name=control.name,id=createSlug(name),$setting=jQuery(document.createElement(\"div\")),$label=jQuery(document.createElement(\"label\")),$controlBox=jQuery(document.createElement(\"div\"));let $control;switch(jQuery(document.createElement(\"div\")).append($label).append($controlBox).appendTo($setting),control.desc&&jQuery(document.createElement(\"p\")).attr(\"id\",`setting-desc-${id}`).wikiWithOptions({cleanup:!1},control.desc).appendTo($setting),$label.attr({id:`setting-label-${id}`,for:`setting-control-${id}`}).wikiWithOptions({cleanup:!1},control.label),null==Setting.getValue(name)&&Setting.setValue(name,control.default),control.type){case Setting.Types.List:$control=jQuery(document.createElement(\"select\"));for(let i=0,iend=control.list.length;i<iend;++i)jQuery(document.createElement(\"option\")).val(i).text(control.list[i]).appendTo($control);$control.val(control.list.indexOf(Setting.getValue(name))).attr(\"tabindex\",0).on(\"change\",(function(){Setting.setValue(name,control.list[Number(this.value)])}));break;case Setting.Types.Range:$control=jQuery(document.createElement(\"input\")),$control.attr({type:\"range\",min:control.min,max:control.max,step:control.step,value:Setting.getValue(name),tabindex:0}).on(\"change input\",(function(){Setting.setValue(name,Number(this.value))})).on(\"keypress\",(ev=>{13===ev.which&&(ev.preventDefault(),triggerEvent(\"change\",$control))}));break;case Setting.Types.Toggle:$control=jQuery(document.createElement(\"button\")),Setting.getValue(name)?$control.addClass(\"enabled\").text(L10n.get(\"textOn\")):$control.text(L10n.get(\"textOff\")),$control.ariaClick((function(){const status=Setting.getValue(name);status?jQuery(this).removeClass(\"enabled\").text(L10n.get(\"textOff\")):jQuery(this).addClass(\"enabled\").text(L10n.get(\"textOn\")),Setting.setValue(name,!status)}))}$control.attr(\"id\",`setting-control-${id}`).appendTo($controlBox),$setting.attr(\"id\",`setting-body-${id}`).appendTo($dialogBody)})),$dialogBody.append(`<ul class=\"buttons\"><li><button id=\"settings-ok\" class=\"ui-close\">${L10n.get([\"settingsTextOk\",\"textOk\"])}</button></li><li><button id=\"settings-reset\">${L10n.get(\"settingsTextReset\")}</button></li></ul>`).find(\"#settings-reset\").ariaClick({one:!0},(()=>{jQuery(document).one(\":dialogclosed\",(()=>{Setting.reset(),window.location.reload()})),Dialog.close()})),!0}function openAlert(message,...args){Dialog.create(L10n.get(\"alertTitle\"),\"alert\").append(`<p>${message}</p><ul class=\"buttons\"><li><button id=\"alert-ok\" class=\"ui-close\">${L10n.get([\"alertTextOk\",\"textOk\"])}</button></li></ul>`).open(...args)}function buildJumpto(){console.warn(\"[DEPRECATED] UI.buildJumpto() is deprecated.\");const list=document.createElement(\"ul\");Dialog.create(L10n.get(\"jumptoTitle\"),\"jumpto list\").append(list);const expired=State.expired.length;for(let i=State.size-1;i>=0;--i){if(i===State.activeIndex)continue;const passage=Story.get(State.history[i].title);passage&&passage.tags.includes(\"bookmark\")&&jQuery(document.createElement(\"li\")).append(jQuery(document.createElement(\"a\")).ariaClick({one:!0},function(index){return()=>jQuery(document).one(\":dialogclosed\",(()=>Engine.goTo(index)))}(i)).addClass(\"ui-close\").text(`${L10n.get(\"textTurn\")} ${expired+i+1}`)).appendTo(list)}list.hasChildNodes()||jQuery(list).append(`<li><a><em>${L10n.get(\"jumptoMesgUnavailable\")}</em></a></li>`)}function buildShare(){console.warn(\"[DEPRECATED] UI.buildShare() is deprecated.\");try{Dialog.create(L10n.get(\"shareTitle\"),\"share list\").append(assembleLinkList(\"StoryShare\"))}catch(ex){return console.error(ex),Alert.error(\"StoryShare\",ex.message),!1}return!0}return Object.preventExtensions(Object.create(null,{assembleLinkList:{value:assembleLinkList},buildRestart:{value:buildRestart},buildSaves:{value:buildSaves},buildSettings:{value:buildSettings},update:{value:function(){triggerEvent(\":uiupdate\")}},alert:{value:openAlert},restart:{value:function(...args){buildRestart(),Dialog.open(...args)}},saves:{value:function(...args){idb.active?(Dialog.create(\"saves\",\"saves\").append($(document.createElement(\"h3\")).addClass(\"saves-loading\").text(\"Loading the save list, please wait...\")),idb.saveList()):buildSaves(),Dialog.open(...args)}},settings:{value:function(...args){buildSettings(),Dialog.open(...args)}},buildAutoload:{value:function(){return console.warn(\"[DEPRECATED] UI.buildAutoload() is deprecated.\"),Dialog.create(L10n.get(\"autoloadTitle\"),\"autoload\").append(`<p>${L10n.get(\"autoloadMesgPrompt\")}</p><ul class=\"buttons\"><li><button id=\"autoload-ok\" class=\"ui-close\">${L10n.get([\"autoloadTextOk\",\"textOk\"])}</button></li><li><button id=\"autoload-cancel\" class=\"ui-close\">${L10n.get([\"autoloadTextCancel\",\"textCancel\"])}</button></li></ul>`),jQuery(document).one(\"click.autoload\",\".ui-close\",(ev=>{const isAutoloadOk=\"autoload-ok\"===ev.target.id;jQuery(document).one(\":dialogclosed\",(()=>{new Promise(((resolve,reject)=>{isAutoloadOk&&resolve(),reject()})).then((()=>Save.browser.continue())).catch((()=>{Engine.play(Config.passages.start)}))}))})),!0}},buildJumpto:{value:buildJumpto},buildShare:{value:buildShare},jumpto:{value:function(...args){buildJumpto(),Dialog.open(...args)}},share:{value:function(...args){buildShare(),Dialog.open(...args)}}}))})(),UIBar=(()=>{let _$uiBar=null;function stow(noAnimation){if(_$uiBar&&!_$uiBar.hasClass(\"stowed\")){let $story;noAnimation&&($story=jQuery(\"#story\"),$story.addClass(\"no-transition\"),_$uiBar.addClass(\"no-transition\")),_$uiBar.addClass(\"stowed\"),noAnimation&&setTimeout((()=>{$story.removeClass(\"no-transition\"),_$uiBar.removeClass(\"no-transition\")}),Engine.DOM_DELAY)}return UIBar}function update(){if(console.warn(\"[DEPRECATED] UIBar.update() is deprecated.\"),_$uiBar)return UI.update(),UIBar}return Object.preventExtensions(Object.create(null,{init:{value:function(){if(document.getElementById(\"ui-bar\"))return;const $elems=(()=>{const toggleLabel=L10n.get(\"uiBarLabelToggle\"),backwardLabel=L10n.get(\"uiBarLabelBackward\"),jumptoLabel=L10n.get(\"uiBarLabelJumpto\"),forwardLabel=L10n.get(\"uiBarLabelForward\");return jQuery(document.createDocumentFragment()).append(`<div id=\"ui-bar\" aria-live=\"polite\"><div id=\"ui-bar-tray\"><button id=\"ui-bar-toggle\" tabindex=\"0\" title=\"${toggleLabel}\" aria-label=\"${toggleLabel}\"></button><div id=\"ui-bar-history\"><button id=\"history-backward\" tabindex=\"0\" title=\"${backwardLabel}\" aria-label=\"${backwardLabel}\"></button><button id=\"history-jumpto\" tabindex=\"0\" title=\"${jumptoLabel}\" aria-label=\"${jumptoLabel}\"></button><button id=\"history-forward\" tabindex=\"0\" title=\"${forwardLabel}\" aria-label=\"${forwardLabel}\"></button></div></div><div id=\"ui-bar-body\"><header id=\"title\" role=\"banner\"><div id=\"story-banner\"></div><h1 id=\"story-title\"></h1><div id=\"story-subtitle\"></div><div id=\"story-title-separator\"></div><p id=\"story-author\"></p></header><div id=\"story-caption\"></div><nav id=\"menu\" role=\"navigation\"><ul id=\"menu-story\"></ul><ul id=\"menu-core\"><li id=\"menu-item-continue\"><a tabindex=\"0\">${L10n.get(\"continueTitle\")}</a></li><li id=\"menu-item-saves\"><a tabindex=\"0\">${L10n.get(\"savesTitle\")}</a></li><li id=\"menu-item-settings\"><a tabindex=\"0\">${L10n.get(\"settingsTitle\")}</a></li><li id=\"menu-item-restart\"><a tabindex=\"0\">${L10n.get(\"restartTitle\")}</a></li><li id=\"menu-item-share\"><a tabindex=\"0\">${L10n.get(\"shareTitle\")}</a></li></ul></nav></div></div>`)})();var $backward,$forward;_$uiBar=jQuery($elems.find(\"#ui-bar\").get(0)),$elems.insertBefore(\"body>script#script-sugarcube\"),jQuery(document).on(\":historyupdate.ui-bar\",($backward=jQuery(\"#history-backward\"),$forward=jQuery(\"#history-forward\"),()=>{$backward.ariaDisabled(State.length<2),$forward.ariaDisabled(State.length===State.size)}))}},destroy:{value:function(){_$uiBar&&(_$uiBar.hide(),jQuery(document).off(\".ui-bar\"),jQuery(document.head).find(\"#style-ui-bar\").remove(),_$uiBar.remove(),_$uiBar=null)}},hide:{value:function(){return _$uiBar&&_$uiBar.hide(),UIBar}},isHidden:{value:function(){return _$uiBar&&\"none\"===_$uiBar.css(\"display\")}},isStowed:{value:function(){return _$uiBar&&_$uiBar.hasClass(\"stowed\")}},show:{value:function(){return _$uiBar&&_$uiBar.show(),UIBar}},start:{value:function(){if(!_$uiBar)return;(\"boolean\"==typeof Config.ui.stowBarInitially?Config.ui.stowBarInitially:jQuery(window).width()<=Config.ui.stowBarInitially)&&stow(!0),jQuery(\"#ui-bar-toggle\").ariaClick({label:L10n.get(\"uiBarLabelToggle\")},(()=>_$uiBar.toggleClass(\"stowed\"))),Config.history.controls?(jQuery(\"#history-backward\").ariaDisabled(State.length<2).ariaClick({label:L10n.get(\"uiBarLabelBackward\")},(()=>Engine.backward())),Story.filter((passage=>passage.tags.includes(\"bookmark\"))).length>0?jQuery(\"#history-jumpto\").ariaClick({label:L10n.get(\"uiBarLabelJumpto\")},(()=>UI.jumpto())):jQuery(\"#history-jumpto\").remove(),jQuery(\"#history-forward\").ariaDisabled(State.length===State.size).ariaClick({label:L10n.get(\"uiBarLabelForward\")},(()=>Engine.forward()))):jQuery(\"#ui-bar-history\").remove();const addUiUpdateHandler=handler=>jQuery(document)[Config.ui.updateStoryElements?\"on\":\"one\"](\":uiupdate.ui-bar\",handler),addUpdaterOrRemove=(selector,passageName)=>{const $el=jQuery(selector);Story.has(passageName)?addUiUpdateHandler((()=>{$el.empty().append(Story.get(passageName).render())})):$el.remove()};{let storyTitleHandler;storyTitleHandler=Story.has(\"StoryDisplayTitle\")?()=>setDisplayTitle(Story.get(\"StoryDisplayTitle\").processText()):()=>setDisplayTitle(Story.name,!0),addUiUpdateHandler(storyTitleHandler)}if(addUpdaterOrRemove(\"#story-banner\",\"StoryBanner\"),addUpdaterOrRemove(\"#story-subtitle\",\"StorySubtitle\"),addUpdaterOrRemove(\"#story-author\",\"StoryAuthor\"),addUpdaterOrRemove(\"#story-caption\",\"StoryCaption\"),Story.has(\"StoryMenu\")){const $menuStory=jQuery(\"#menu-story\");jQuery(document).on(\":uiupdate.ui-bar\",(()=>{try{const frag=UI.assembleLinkList(\"StoryMenu\",document.createDocumentFragment());$menuStory.empty().append(frag)}catch(ex){console.error(ex),Alert.error(\"StoryMenu\",ex.message)}}))}else jQuery(\"#menu-story\").remove();Save.browser.size>0?(jQuery(\"#menu-item-continue a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),Save.browser.continue().then((()=>{jQuery(document).off(\".menu-item-continue\"),jQuery(\"#menu-item-continue\").remove(),Engine.show()}),(ex=>UI.alert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))})).text(L10n.get(\"continueTitle\")),jQuery(document).on(\":passagestart.menu-item-continue\",(()=>{State.turns>1&&(jQuery(document).off(\".menu-item-continue\"),jQuery(\"#menu-item-continue\").remove())}))):jQuery(\"#menu-item-continue\").remove(),jQuery(\"#menu-item-saves a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),idb.active?(Dialog.create(\"saves\",\"saves\").append($(document.createElement(\"h3\")).addClass(\"saves-loading\").text(\"Loading the save list, please wait...\")),idb.saveList()):UI.buildSaves(),Dialog.open()})).text(L10n.get(\"savesTitle\")),Setting.isEmpty()?jQuery(\"#menu-item-settings\").remove():jQuery(\"#menu-item-settings a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),UI.buildSettings(),Dialog.open()})).text(L10n.get(\"settingsTitle\")),jQuery(\"#menu-item-restart a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),UI.buildRestart(),Dialog.open()})).text(L10n.get(\"restartTitle\")),Story.has(\"StoryShare\")?jQuery(\"#menu-item-share a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),UI.buildShare(),Dialog.open()})).text(L10n.get(\"shareTitle\")):jQuery(\"#menu-item-share\").remove()}},stow:{value:stow},unstow:{value:function(noAnimation){if(_$uiBar&&_$uiBar.hasClass(\"stowed\")){let $story;noAnimation&&($story=jQuery(\"#story\"),$story.addClass(\"no-transition\"),_$uiBar.addClass(\"no-transition\")),_$uiBar.removeClass(\"stowed\"),noAnimation&&setTimeout((()=>{$story.removeClass(\"no-transition\"),_$uiBar.removeClass(\"no-transition\")}),Engine.DOM_DELAY)}return UIBar}},setStoryElements:{value:update},update:{value:update}}))})(),DebugBar=(()=>{const STORAGE_KEY=\"debug.state\",WATCH_LIST_DELAY=200,VAR_LIST_DELAY=500,variableRE=new RegExp(`^${Patterns.variable}$`),numericKeyRE=/^\\d+$/,watchList=[];let varList=[],watchTimerId=null,listTimerId=null,stowed=!0,$debugBar=null,$watchBody=null,$varDataList=null,$turnSelect=null,$passageDataList=null;function debugBarStow(){disableWatchUpdates(),disableVarListUpdates(),$debugBar.css(\"right\",`-${$debugBar.outerWidth()}px`),stowed=!0,updateSession()}function debugBarUnstow(){debugBarWatchIsEnabled()&&enableWatchUpdates(),enableVarListUpdates(),$debugBar.css(\"right\",0),stowed=!1,updateSession()}function debugBarToggle(){stowed?debugBarUnstow():debugBarStow()}function debugBarWatchAdd(varName){variableRE.test(varName)&&(watchList.pushUnique(varName),watchList.sort(),updateWatchBody(),updateVarList(),updateSession())}function debugBarWatchAddAll(){Object.keys(State.variables).map((name=>watchList.pushUnique(`$${name}`))),Object.keys(State.temporary).map((name=>watchList.pushUnique(`_${name}`))),watchList.sort(),updateWatchBody(),updateVarList(),updateSession()}function debugBarWatchClear(){watchList.length=0,$watchBody.empty().append(`<div>— ${L10n.get(\"debugBarMesgNoWatches\")} —</div>`),updateWatchBody(),updateVarList(),updateSession()}function debugBarWatchDelete(varName){watchList.deleteFirst(varName),$watchBody.find(`tr[data-name=\"${varName}\"]`).remove(),updateWatchBody(),updateVarList(),updateSession()}function debugBarWatchDisable(){disableWatchUpdates(),disableWatch(),updateSession()}function debugBarWatchEnable(){enableWatchUpdates(),enableWatch(),updateSession()}function debugBarWatchIsEnabled(){return!$watchBody.attr(\"hidden\")}function debugBarWatchToggle(){$watchBody.attr(\"hidden\")?debugBarWatchEnable():debugBarWatchDisable()}function disableWatch(){$watchBody.attr({\"aria-hidden\":!0,hidden:\"hidden\"})}function disableWatchUpdates(){null!==watchTimerId&&(clearInterval(watchTimerId),watchTimerId=null)}function enableWatch(){$watchBody.removeAttr(\"aria-hidden hidden\")}function enableWatchUpdates(){null===watchTimerId&&(watchTimerId=setInterval((()=>updateWatchBody()),WATCH_LIST_DELAY))}function disableVarListUpdates(){null!==listTimerId&&(clearInterval(listTimerId),listTimerId=null)}function enableVarListUpdates(){null===listTimerId&&(listTimerId=setInterval((()=>updateVarList()),VAR_LIST_DELAY))}function clearSession(){session.delete(STORAGE_KEY)}function updateSession(){session.set(STORAGE_KEY,{stowed:stowed,watchList:watchList,watchEnabled:debugBarWatchIsEnabled(),viewsEnabled:DebugView.isEnabled()})}function updateWatchBody(){if(0===watchList.length)return;const $rowMap=new Map;let $tbody,$table=jQuery($watchBody.children(\"table\"));$table.length>0?($tbody=jQuery($table.children(\"tbody\")),$tbody.children(\"tr\").each(((_,el)=>$rowMap.set(el.getAttribute(\"data-name\"),jQuery(el))))):($table=jQuery(document.createElement(\"table\")),$tbody=jQuery(document.createElement(\"tbody\")),$table.append($tbody),$watchBody.empty().append($table));const delLabel=L10n.get(\"debugBarLabelWatchDelete\");let cursor=$rowMap.size>0?$tbody.children(\"tr\").get(0):null;watchList.forEach((varName=>{const varKey=varName.slice(1),value=toWatchString((\"$\"===varName[0]?State.variables:State.temporary)[varKey]);let $row=$rowMap.get(varName);if($row){const $code=$row.children().children(\"code\");value!==$code.text()&&$code.text(value)}else $row=function(varName,value){const $row=jQuery(document.createElement(\"tr\")),$delBtn=jQuery(document.createElement(\"button\")),$code=jQuery(document.createElement(\"code\"));return $row.attr(\"data-name\",varName),$delBtn.addClass(\"watch-delete\").ariaClick({one:!0,label:delLabel},(()=>debugBarWatchDelete(varName))),$code.text(value),jQuery(document.createElement(\"td\")).append($delBtn).appendTo($row),jQuery(document.createElement(\"td\")).text(varName).appendTo($row),jQuery(document.createElement(\"td\")).append($code).appendTo($row),$row}(varName,value),cursor?$row.insertAfter(cursor):$row.appendTo($tbody);cursor=$row.get(0)}))}function updateVarList(){const names=[].concat(Object.keys(State.variables).map((name=>`$${name}`)),Object.keys(State.temporary).map((name=>`_${name}`)));if(0===names.length)return varList.length=0,void $varDataList.empty();if(names.sort().deleteAll(watchList),names.length===varList.length&&names.every(((m,i)=>m===varList[i])))return;varList=names;const options=document.createDocumentFragment();varList.forEach((name=>{jQuery(document.createElement(\"option\")).val(name).appendTo(options)})),$varDataList.empty().append(options)}function updateTurnSelect(){const histLen=State.size,expLen=State.expired.length,options=document.createDocumentFragment();for(let i=0;i<histLen;++i)jQuery(document.createElement(\"option\")).val(i).text(`${expLen+i+1}. ${State.history[i].title}`).appendTo(options);$turnSelect.empty().ariaDisabled(histLen<2).append(options).val(State.activeIndex)}function updatePassageList(){const passages=Object.keys(Story.getNormals()).sort(),options=document.createDocumentFragment();passages.forEach((name=>{jQuery(document.createElement(\"option\")).val(name).appendTo(options)})),$passageDataList.empty().append(options)}function toWatchString(O){if(null===O)return\"null\";switch(typeof O){case\"bigint\":case\"boolean\":case\"number\":case\"symbol\":case\"undefined\":return String(O);case\"string\":return JSON.stringify(O);case\"function\":return\"Function\"}const objType=getToStringTag(O);if(\"Date\"===objType)return`Date {${O.toLocaleString()}}`;if(\"RegExp\"===objType)return`RegExp ${O.toString()}`;const result=[];if(O instanceof Array||O instanceof Set){const list=O instanceof Array?O:Array.from(O);for(let i=0,len=list.length;i<len;++i)result.push(Object.hasOwn(list,i)?toWatchString(list[i]):\"<empty>\");return Object.keys(list).filter((key=>!numericKeyRE.test(key))).forEach((key=>result.push(`${toWatchString(key)}: ${toWatchString(list[key])}`))),`${objType}(${list.length}) [${result.join(\", \")}]`}return O instanceof Map?(O.forEach(((val,key)=>result.push(`${toWatchString(key)} → ${toWatchString(val)}`))),`${objType}(${O.size}) {${result.join(\", \")}}`):(Object.keys(O).forEach((key=>result.push(`${toWatchString(key)}: ${toWatchString(O[key])}`))),`${objType} {${result.join(\", \")}}`)}return Object.preventExtensions(Object.create(null,{init:{value:function(){if(!Config.debug)return void jQuery(document.head).find('[id|=\"style-ui-debug\"]').remove();const barToggleLabel=L10n.get(\"debugBarLabelToggle\"),watchAddLabel=L10n.get(\"debugBarLabelWatchAdd\"),watchAllLabel=L10n.get(\"debugBarLabelWatchAll\"),watchClearLabel=L10n.get(\"debugBarLabelWatchClear\"),watchToggleLabel=L10n.get(\"debugBarLabelWatchToggle\"),viewsToggleLabel=L10n.get(\"debugBarLabelViewsToggle\"),passagePlayLabel=L10n.get(\"debugBarLabelPassagePlay\");jQuery(document.createDocumentFragment()).append(`<div id=\"debug-bar\"><div id=\"debug-bar-watch\"><div>— ${L10n.get(\"debugBarMesgNoWatches\")} —</div></div><div><label id=\"debug-bar-watch-label\" for=\"debug-bar-watch-input\">${L10n.get(\"debugBarTextWatch\")}</label><input id=\"debug-bar-watch-input\" name=\"debug-bar-watch-input\" type=\"text\" placeholder=\"${L10n.get(\"debugBarLabelWatchPlaceholder\")}\" list=\"debug-bar-var-list\" tabindex=\"0\"><datalist id=\"debug-bar-var-list\" aria-hidden=\"true\" hidden=\"hidden\"></datalist><button id=\"debug-bar-watch-add\" tabindex=\"0\" title=\"${watchAddLabel}\" aria-label=\"${watchAddLabel}\"></button><button id=\"debug-bar-watch-all\" tabindex=\"0\" title=\"${watchAllLabel}\" aria-label=\"${watchAllLabel}\"></button><button id=\"debug-bar-watch-clear\" tabindex=\"0\" title=\"${watchClearLabel}\" aria-label=\"${watchClearLabel}\"></button></div><div><label id=\"debug-bar-turn-label\" for=\"debug-bar-turn-select\">${L10n.get(\"textTurn\")}</label><select id=\"debug-bar-turn-select\" tabindex=\"0\"></select></div><div><label id=\"debug-bar-passage-label\" for=\"debug-bar-passage-input\">${L10n.get(\"debugBarTextPassage\")}</label><input id=\"debug-bar-passage-input\" name=\"debug-bar-passage-input\" type=\"text\" placeholder=\"${L10n.get(\"debugBarLabelPassagePlaceholder\")}\" list=\"debug-bar-passage-list\" tabindex=\"0\"><datalist id=\"debug-bar-passage-list\" aria-hidden=\"true\" hidden=\"hidden\"></datalist><button id=\"debug-bar-passage-play\" tabindex=\"0\" title=\"${passagePlayLabel}\" aria-label=\"${passagePlayLabel}\"></button></div><div><button id=\"debug-bar-views-toggle\" tabindex=\"0\" title=\"${viewsToggleLabel}\" aria-label=\"${viewsToggleLabel}\">${L10n.get(\"debugBarTextViews\")}</button><button id=\"debug-bar-watch-toggle\" tabindex=\"0\" title=\"${watchToggleLabel}\" aria-label=\"${watchToggleLabel}\">${L10n.get(\"debugBarTextWatch\")}</button></div><button id=\"debug-bar-toggle\" tabindex=\"0\" title=\"${barToggleLabel}\" aria-label=\"${barToggleLabel}\"></button></div><div id=\"debug-bar-hint\"></div>`).appendTo(\"body\"),$debugBar=jQuery(\"#debug-bar\"),$watchBody=jQuery($debugBar.find(\"#debug-bar-watch\").get(0)),$varDataList=jQuery($debugBar.find(\"#debug-bar-var-list\").get(0)),$turnSelect=jQuery($debugBar.find(\"#debug-bar-turn-select\").get(0)),$passageDataList=jQuery($debugBar.find(\"#debug-bar-passage-list\").get(0));const $watchInput=jQuery($debugBar.find(\"#debug-bar-watch-input\").get(0)),$watchAdd=jQuery($debugBar.find(\"#debug-bar-watch-add\").get(0)),$watchAll=jQuery($debugBar.find(\"#debug-bar-watch-all\").get(0)),$watchClear=jQuery($debugBar.find(\"#debug-bar-watch-clear\").get(0)),$passageInput=jQuery($debugBar.find(\"#debug-bar-passage-input\").get(0)),$passagePlay=jQuery($debugBar.find(\"#debug-bar-passage-play\").get(0)),$viewsToggle=jQuery($debugBar.find(\"#debug-bar-views-toggle\").get(0)),$watchToggle=jQuery($debugBar.find(\"#debug-bar-watch-toggle\").get(0)),$barToggle=jQuery($debugBar.find(\"#debug-bar-toggle\").get(0));$watchInput.on(\"sc:debug-watch-add\",(function(){debugBarWatchAdd(this.value.trim()),this.value=\"\"})).on(\"keypress\",(ev=>{13===ev.which&&(ev.preventDefault(),triggerEvent(\"sc:debug-watch-add\",$watchInput))})),$watchAdd.ariaClick((()=>triggerEvent(\"sc:debug-watch-add\",$watchInput))),$watchAll.ariaClick(debugBarWatchAddAll),$watchClear.ariaClick(debugBarWatchClear),$turnSelect.on(\"change\",(function(){Engine.goTo(Number(this.value))})),$passageInput.on(\"sc:debug-passage-play\",(function(){Engine.play(this.value.trim()),this.value=\"\"})).on(\"keypress\",(ev=>{13===ev.which&&(ev.preventDefault(),triggerEvent(\"sc:debug-passage-play\",$passageInput))})).on(\"focus\",updatePassageList),$passagePlay.ariaClick((()=>triggerEvent(\"sc:debug-passage-play\",$passageInput))),$viewsToggle.ariaClick((()=>{DebugView.toggle(),updateSession()})),$watchToggle.ariaClick(debugBarWatchToggle),$barToggle.ariaClick(debugBarToggle),jQuery(document).on(\":passageend.debug-bar\",(()=>{updateWatchBody(),updateVarList()})).on(\":historyupdate.debug-bar\",updateTurnSelect).on(\":enginerestart.debug-bar\",clearSession)}},isStowed:{value:function(){return stowed}},start:{value:function(){Config.debug&&(function(){if(!session.has(STORAGE_KEY))return!1;const debugState=session.get(STORAGE_KEY);watchList.push(...debugState.watchList),debugState.watchEnabled?(stowed?disableWatchUpdates():enableWatchUpdates(),enableWatch()):(disableWatchUpdates(),disableWatch());debugState.viewsEnabled?DebugView.enable():DebugView.disable();stowed=debugState.stowed,stowed?(disableVarListUpdates(),debugBarStow()):(enableVarListUpdates(),debugBarUnstow());return!0}()||(debugBarStow(),DebugView.enable(),enableWatchUpdates(),enableWatch()),updateVarList(),updateTurnSelect())}},stow:{value:debugBarStow},toggle:{value:debugBarToggle},unstow:{value:debugBarUnstow},watch:{value:Object.preventExtensions(Object.create(null,{add:{value:debugBarWatchAdd},all:{value:debugBarWatchAddAll},clear:{value:debugBarWatchClear},delete:{value:debugBarWatchDelete},disable:{value:debugBarWatchDisable},enable:{value:debugBarWatchEnable},isEnabled:{value:debugBarWatchIsEnabled},toggle:{value:debugBarWatchToggle}}))}}))})(),LoadScreen=(()=>{const _locks=new Set;let _autoId=0;function loadScreenHide(){jQuery(document.documentElement).removeAttr(\"data-init\")}function loadScreenShow(){jQuery(document.documentElement).attr(\"data-init\",\"loading\")}return Object.preventExtensions(Object.create(null,{init:{value:function(){jQuery(document).on(\"readystatechange.SugarCube\",(()=>{_locks.size>0||(\"complete\"===document.readyState?\"loading\"===jQuery(document.documentElement).attr(\"data-init\")&&(Config.loadDelay>0?setTimeout((()=>{0===_locks.size&&loadScreenHide()}),Math.max(Engine.DOM_DELAY,Config.loadDelay)):loadScreenHide()):loadScreenShow())}))}},clear:{value:function(){jQuery(document).off(\"readystatechange.SugarCube\"),_locks.clear(),loadScreenHide()}},hide:{value:loadScreenHide},show:{value:loadScreenShow},lock:{value:function(){return++_autoId,_locks.add(_autoId),loadScreenShow(),_autoId}},unlock:{value:function(id){if(null==id)throw new Error(\"LoadScreen.unlock called with a null or undefined ID\");_locks.has(id)&&_locks.delete(id),0===_locks.size&&triggerEvent(\"readystatechange\")}},size:{get:function(){return _locks.size}}}))})(),Util=Object.preventExtensions(Object.create(null,{charAndPosAt:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.charAndPosAt() is deprecated.\"),charAndPosAt(...args))},escape:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.escape() is deprecated.\"),encodeEntities(...args))},escapeMarkup:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.escapeMarkup() is deprecated.\"),encodeMarkup(...args))},fromCssProperty:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.fromCssProperty() is deprecated.\"),cssPropToDOMProp(...args))},fromCssTime:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.fromCssTime() is deprecated.\"),cssTimeToMS(...args))},getType:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.getType() is deprecated.\"),getTypeOf(...args))},hasMediaQuery:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.hasMediaQuery() is deprecated.\"),hasMediaQuery(...args))},newExceptionFrom:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.newExceptionFrom() is deprecated.\"),exceptionFrom(...args))},now:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.now() is deprecated.\"),now(...args))},parseUrl:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.parseUrl() is deprecated.\"),parseURL(...args))},sameValueZero:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.sameValueZero() is deprecated.\"),sameValueZero(...args))},sanitizeFilename:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.sanitizeFilename() is deprecated.\"),createFilename(...args))},scrubEventKey:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.scrubEventKey() is deprecated.\"),scrubEventKey(...args))},slugify:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.slugify() is deprecated.\"),createSlug(...args))},toCssTime:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.toCssTime() is deprecated.\"),msToCSSTime(...args))},toEnum:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.toEnum() is deprecated.\"),enumFrom(...args))},toStringTag:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.toStringTag() is deprecated.\"),getToStringTag(...args))},unescape:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.unescape() is deprecated.\"),decodeEntities(...args))}})),version=(()=>{const semVerRE=/^[Vv]?(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?)?)?$/;return Object.preventExtensions(Object.create(null,{name:{value:\"SugarCube\"},major:{value:2},minor:{value:37},patch:{value:3},prerelease:{value:\"\"},build:{value:18},date:{value:new Date(\"2024-09-27T10:05:49.567Z\")},isOk:{value(semver){if(\"string\"!=typeof semver)throw new Error(`version.isOk semver parameter must be a string (received: ${typeof semver})`);const trimmed=semver.trim();if(\"\"===trimmed)throw new Error(\"version.isOk semver parameter must not be empty\");const match=semVerRE.exec(trimmed);if(!match)throw new Error(`version.isOk semver parameter is invalid (format: [v]MAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]; received: ${trimmed}`);const major=Number(match[1]),minor=Number(match[2])||0,patch=Number(match[3])||0;return major===this.major&&(minor<this.minor||minor===this.minor&&patch<=this.patch)}},long:{value(){return`${this.name} v${this.toString()} (${this.date.toUTCString()})`}},short:{value(){const prerelease=this.prerelease?`-${this.prerelease}`:\"\";return`${this.name} (v${this.major}.${this.minor}.${this.patch}${prerelease})`}},toString:{value(){const prerelease=this.prerelease?`-${this.prerelease}`:\"\";return`${this.major}.${this.minor}.${this.patch}${prerelease}+${this.build}`}},title:{value:\"SugarCube\"}}))})(),TempState={},session=null,settings=Setting.create(),setup={},storage=null,macros={},postdisplay={},postrender={},predisplay={},prehistory={},prerender={};Object.defineProperty(window,\"SugarCube\",{value:Object.seal(Object.assign(Object.create(null),{Browser:Browser,Config:Config,Dialog:Dialog,Engine:Engine,Fullscreen:Fullscreen,Has:Has,L10n:L10n,Macro:Macro,Passage:Passage,Save:Save,Scripting:Scripting,Setting:Setting,SimpleAudio:SimpleAudio,State:State,Story:Story,UI:UI,UIBar:UIBar,DebugBar:DebugBar,Util:Util,Visibility:Visibility,Wikifier:Wikifier,session:session,settings:settings,setup:setup,storage:storage,version:version}))}),jQuery((()=>{const lockId=LoadScreen.lock();LoadScreen.init(),document.normalize&&document.normalize(),new Promise((resolve=>{Story.init();try{SugarCube.storage=storage=SimpleStore.create(Story.id,!0),SugarCube.session=session=SimpleStore.create(Story.id,!1)}catch(ex){throw new Error(L10n.get(\"warningNoStorage\"))}Dialog.init(),UIBar.init(),Engine.init(),Outliner.init(),Engine.runUserScripts(),L10n.init(),session.has(\"rcWarn\")||\"cookie\"!==storage.name||(session.set(\"rcWarn\",1),window.alert(L10n.get(\"warningNoWebStorage\"))),Save.init(),Setting.init(),idb.init(Story.id),Macro.init(),DebugBar.init();const $window=jQuery(window),vpReadyId=setInterval((()=>{$window.width()&&LoadScreen.size<=1&&(clearInterval(vpReadyId),resolve())}),Engine.DOM_DELAY)})).then((()=>{Engine.runUserInit(),UIBar.start(),Engine.start(),DebugBar.start(),triggerEvent(\":storyready\"),setTimeout((()=>LoadScreen.unlock(lockId)),2*Engine.DOM_DELAY)})).catch((ex=>(console.error(ex),LoadScreen.clear(),Alert.fatal(null,ex.message,ex))))}))})(window,window.document,jQuery);}\n\t</script>\n</body>\n</html>\n"}); \ No newline at end of file +window.storyFormat({"name":"SugarCube","version":"2.37.3","description":"A full featured, highly customizable story format. See its <a href=\"http://www.motoslave.net/sugarcube/2/#documentation\" target=\"_blank\">documentation</a>.","author":"Thomas Michael Edwards","image":"icon.svg","url":"http://www.motoslave.net/sugarcube/","license":"BSD-2-Clause","proofing":false,"source":"<!DOCTYPE html>\n<html data-init=\"no-js\">\n<head>\n<meta charset=\"UTF-8\" />\n<title>{{STORY_NAME}}</title>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n<meta name=\"application-name\" content=\"SugarCube\" />\n<meta name=\"version\" content=\"2.37.3\" />\n<!--\n\nSugarCube (v2.37.3): A free (gratis and libre) story format.\n\nCopyright © 2013–2021 Thomas Michael Edwards <thomasmedwards@gmail.com>.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n-->\n<script id=\"script-libraries\" type=\"text/javascript\">\nif(document.head&&document.addEventListener&&document.querySelector&&Object.create&&Object.freeze&&JSON){document.documentElement.setAttribute(\"data-init\", \"loading\");\n/*! @source http://purl.eligrey.com/github/classList.js/blob/1.2.20171210/classList.js */\n\"document\"in self&&(\"classList\"in document.createElement(\"_\")&&(!document.createElementNS||\"classList\"in document.createElementNS(\"http://www.w3.org/2000/svg\",\"g\"))||!function(t){\"use strict\";if(\"Element\"in t){var e=\"classList\",n=\"prototype\",i=t.Element[n],s=Object,r=String[n].trim||function(){return this.replace(/^\\s+|\\s+$/g,\"\")},o=Array[n].indexOf||function(t){for(var e=0,n=this.length;n>e;e++)if(e in this&&this[e]===t)return e;return-1},c=function(t,e){this.name=t,this.code=DOMException[t],this.message=e},a=function(t,e){if(\"\"===e)throw new c(\"SYNTAX_ERR\",\"The token must not be empty.\");if(/\\s/.test(e))throw new c(\"INVALID_CHARACTER_ERR\",\"The token must not contain space characters.\");return o.call(t,e)},l=function(t){for(var e=r.call(t.getAttribute(\"class\")||\"\"),n=e?e.split(/\\s+/):[],i=0,s=n.length;s>i;i++)this.push(n[i]);this._updateClassName=function(){t.setAttribute(\"class\",this.toString())}},u=l[n]=[],h=function(){return new l(this)};if(c[n]=Error[n],u.item=function(t){return this[t]||null},u.contains=function(t){return~a(this,t+\"\")},u.add=function(){var t,e=arguments,n=0,i=e.length,s=!1;do t=e[n]+\"\",~a(this,t)||(this.push(t),s=!0);while(++n<i);s&&this._updateClassName()},u.remove=function(){var t,e,n=arguments,i=0,s=n.length,r=!1;do for(t=n[i]+\"\",e=a(this,t);~e;)this.splice(e,1),r=!0,e=a(this,t);while(++i<s);r&&this._updateClassName()},u.toggle=function(t,e){var n=this.contains(t),i=n?e!==!0&&\"remove\":e!==!1&&\"add\";return i&&this[i](t),e===!0||e===!1?e:!n},u.replace=function(t,e){var n=a(t+\"\");~n&&(this.splice(n,1,e),this._updateClassName())},u.toString=function(){return this.join(\" \")},s.defineProperty){var f={get:h,enumerable:!0,configurable:!0};try{s.defineProperty(i,e,f)}catch(p){void 0!==p.number&&-2146823252!==p.number||(f.enumerable=!1,s.defineProperty(i,e,f))}}else s[n].__defineGetter__&&i.__defineGetter__(e,h)}}(self),function(){\"use strict\";var t=document.createElement(\"_\");if(t.classList.add(\"c1\",\"c2\"),!t.classList.contains(\"c2\")){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var n,i=arguments.length;for(n=0;i>n;n++)t=arguments[n],e.call(this,t)}};e(\"add\"),e(\"remove\")}if(t.classList.toggle(\"c3\",!1),t.classList.contains(\"c3\")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(t,e){return 1 in arguments&&!this.contains(t)==!e?e:n.call(this,t)}}\"replace\"in document.createElement(\"_\").classList||(DOMTokenList.prototype.replace=function(t,e){var n=this.toString().split(\" \"),i=n.indexOf(t+\"\");~i&&(n=n.slice(i),this.remove.apply(this,n),this.add(e),this.add.apply(this,n.slice(1)))}),t=null}());\n/*!\n * https://github.com/es-shims/es5-shim\n * @license es5-shim Copyright 2009-2020 by contributors, MIT License\n * see https://github.com/es-shims/es5-shim/blob/v4.5.14/LICENSE\n */\n(function(t,r){\"use strict\";if(typeof define===\"function\"&&define.amd){define(r)}else if(typeof exports===\"object\"){module.exports=r()}else{t.returnExports=r()}})(this,function(){var t=Array;var r=t.prototype;var e=Object;var n=e.prototype;var i=Function;var a=i.prototype;var o=String;var f=o.prototype;var u=Number;var l=u.prototype;var s=r.slice;var c=r.splice;var v=r.push;var h=r.unshift;var p=r.concat;var y=r.join;var d=a.call;var g=a.apply;var w=Math.max;var b=Math.min;var T=n.toString;var m=typeof Symbol===\"function\"&&typeof Symbol.toStringTag===\"symbol\";var D;var S=Function.prototype.toString,x=/^\\s*class /,O=function isES6ClassFn(t){try{var r=S.call(t);var e=r.replace(/\\/\\/.*\\n/g,\"\");var n=e.replace(/\\/\\*[.\\s\\S]*\\*\\//g,\"\");var i=n.replace(/\\n/gm,\" \").replace(/ {2}/g,\" \");return x.test(i)}catch(a){return false}},E=function tryFunctionObject(t){try{if(O(t)){return false}S.call(t);return true}catch(r){return false}},j=\"[object Function]\",I=\"[object GeneratorFunction]\",D=function isCallable(t){if(!t){return false}if(typeof t!==\"function\"&&typeof t!==\"object\"){return false}if(m){return E(t)}if(O(t)){return false}var r=T.call(t);return r===j||r===I};var M;var U=RegExp.prototype.exec,$=function tryRegexExec(t){try{U.call(t);return true}catch(r){return false}},F=\"[object RegExp]\";M=function isRegex(t){if(typeof t!==\"object\"){return false}return m?$(t):T.call(t)===F};var N;var C=String.prototype.valueOf,k=function tryStringObject(t){try{C.call(t);return true}catch(r){return false}},A=\"[object String]\";N=function isString(t){if(typeof t===\"string\"){return true}if(typeof t!==\"object\"){return false}return m?k(t):T.call(t)===A};var R=e.defineProperty&&function(){try{var t={};e.defineProperty(t,\"x\",{enumerable:false,value:t});for(var r in t){return false}return t.x===t}catch(n){return false}}();var P=function(t){var r;if(R){r=function(t,r,n,i){if(!i&&r in t){return}e.defineProperty(t,r,{configurable:true,enumerable:false,writable:true,value:n})}}else{r=function(t,r,e,n){if(!n&&r in t){return}t[r]=e}}return function defineProperties(e,n,i){for(var a in n){if(t.call(n,a)){r(e,a,n[a],i)}}}}(n.hasOwnProperty);var J=function isPrimitive(t){var r=typeof t;return t===null||r!==\"object\"&&r!==\"function\"};var Y=u.isNaN||function isActualNaN(t){return t!==t};var z={ToInteger:function ToInteger(t){var r=+t;if(Y(r)){r=0}else if(r!==0&&r!==1/0&&r!==-(1/0)){r=(r>0||-1)*Math.floor(Math.abs(r))}return r},ToPrimitive:function ToPrimitive(t){var r,e,n;if(J(t)){return t}e=t.valueOf;if(D(e)){r=e.call(t);if(J(r)){return r}}n=t.toString;if(D(n)){r=n.call(t);if(J(r)){return r}}throw new TypeError},ToObject:function(t){if(t==null){throw new TypeError(\"can't convert \"+t+\" to object\")}return e(t)},ToUint32:function ToUint32(t){return t>>>0}};var Z=function Empty(){};P(a,{bind:function bind(t){var r=this;if(!D(r)){throw new TypeError(\"Function.prototype.bind called on incompatible \"+r)}var n=s.call(arguments,1);var a;var o=function(){if(this instanceof a){var i=g.call(r,this,p.call(n,s.call(arguments)));if(e(i)===i){return i}return this}else{return g.call(r,t,p.call(n,s.call(arguments)))}};var f=w(0,r.length-n.length);var u=[];for(var l=0;l<f;l++){v.call(u,\"$\"+l)}a=i(\"binder\",\"return function (\"+y.call(u,\",\")+\"){ return binder.apply(this, arguments); }\")(o);if(r.prototype){Z.prototype=r.prototype;a.prototype=new Z;Z.prototype=null}return a}});var G=d.bind(n.hasOwnProperty);var H=d.bind(n.toString);var W=d.bind(s);var B=g.bind(s);if(typeof document===\"object\"&&document&&document.documentElement){try{W(document.documentElement.childNodes)}catch(X){var L=W;var q=B;W=function arraySliceIE(t){var r=[];var e=t.length;while(e-- >0){r[e]=t[e]}return q(r,L(arguments,1))};B=function arraySliceApplyIE(t,r){return q(W(t),r)}}}var K=d.bind(f.slice);var Q=d.bind(f.split);var V=d.bind(f.indexOf);var _=d.bind(v);var tt=d.bind(n.propertyIsEnumerable);var rt=d.bind(r.sort);var et=t.isArray||function isArray(t){return H(t)===\"[object Array]\"};var nt=[].unshift(0)!==1;P(r,{unshift:function(){h.apply(this,arguments);return this.length}},nt);P(t,{isArray:et});var it=e(\"a\");var at=it[0]!==\"a\"||!(0 in it);var ot=function properlyBoxed(t){var r=true;var e=true;var n=false;if(t){try{t.call(\"foo\",function(t,e,n){if(typeof n!==\"object\"){r=false}});t.call([1],function(){\"use strict\";e=typeof this===\"string\"},\"x\")}catch(i){n=true}}return!!t&&!n&&r&&e};P(r,{forEach:function forEach(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=-1;var i=z.ToUint32(e.length);var a;if(arguments.length>1){a=arguments[1]}if(!D(t)){throw new TypeError(\"Array.prototype.forEach callback must be a function\")}while(++n<i){if(n in e){if(typeof a===\"undefined\"){t(e[n],n,r)}else{t.call(a,e[n],n,r)}}}}},!ot(r.forEach));P(r,{map:function map(r){var e=z.ToObject(this);var n=at&&N(this)?Q(this,\"\"):e;var i=z.ToUint32(n.length);var a=t(i);var o;if(arguments.length>1){o=arguments[1]}if(!D(r)){throw new TypeError(\"Array.prototype.map callback must be a function\")}for(var f=0;f<i;f++){if(f in n){if(typeof o===\"undefined\"){a[f]=r(n[f],f,e)}else{a[f]=r.call(o,n[f],f,e)}}}return a}},!ot(r.map));P(r,{filter:function filter(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);var i=[];var a;var o;if(arguments.length>1){o=arguments[1]}if(!D(t)){throw new TypeError(\"Array.prototype.filter callback must be a function\")}for(var f=0;f<n;f++){if(f in e){a=e[f];if(typeof o===\"undefined\"?t(a,f,r):t.call(o,a,f,r)){_(i,a)}}}return i}},!ot(r.filter));P(r,{every:function every(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);var i;if(arguments.length>1){i=arguments[1]}if(!D(t)){throw new TypeError(\"Array.prototype.every callback must be a function\")}for(var a=0;a<n;a++){if(a in e&&!(typeof i===\"undefined\"?t(e[a],a,r):t.call(i,e[a],a,r))){return false}}return true}},!ot(r.every));P(r,{some:function some(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);var i;if(arguments.length>1){i=arguments[1]}if(!D(t)){throw new TypeError(\"Array.prototype.some callback must be a function\")}for(var a=0;a<n;a++){if(a in e&&(typeof i===\"undefined\"?t(e[a],a,r):t.call(i,e[a],a,r))){return true}}return false}},!ot(r.some));var ft=false;if(r.reduce){ft=typeof r.reduce.call(\"es5\",function(t,r,e,n){return n})===\"object\"}P(r,{reduce:function reduce(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);if(!D(t)){throw new TypeError(\"Array.prototype.reduce callback must be a function\")}if(n===0&&arguments.length===1){throw new TypeError(\"reduce of empty array with no initial value\")}var i=0;var a;if(arguments.length>=2){a=arguments[1]}else{do{if(i in e){a=e[i++];break}if(++i>=n){throw new TypeError(\"reduce of empty array with no initial value\")}}while(true)}for(;i<n;i++){if(i in e){a=t(a,e[i],i,r)}}return a}},!ft);var ut=false;if(r.reduceRight){ut=typeof r.reduceRight.call(\"es5\",function(t,r,e,n){return n})===\"object\"}P(r,{reduceRight:function reduceRight(t){var r=z.ToObject(this);var e=at&&N(this)?Q(this,\"\"):r;var n=z.ToUint32(e.length);if(!D(t)){throw new TypeError(\"Array.prototype.reduceRight callback must be a function\")}if(n===0&&arguments.length===1){throw new TypeError(\"reduceRight of empty array with no initial value\")}var i;var a=n-1;if(arguments.length>=2){i=arguments[1]}else{do{if(a in e){i=e[a--];break}if(--a<0){throw new TypeError(\"reduceRight of empty array with no initial value\")}}while(true)}if(a<0){return i}do{if(a in e){i=t(i,e[a],a,r)}}while(a--);return i}},!ut);var lt=r.indexOf&&[0,1].indexOf(1,2)!==-1;P(r,{indexOf:function indexOf(t){var r=at&&N(this)?Q(this,\"\"):z.ToObject(this);var e=z.ToUint32(r.length);if(e===0){return-1}var n=0;if(arguments.length>1){n=z.ToInteger(arguments[1])}n=n>=0?n:w(0,e+n);for(;n<e;n++){if(n in r&&r[n]===t){return n}}return-1}},lt);var st=r.lastIndexOf&&[0,1].lastIndexOf(0,-3)!==-1;P(r,{lastIndexOf:function lastIndexOf(t){var r=at&&N(this)?Q(this,\"\"):z.ToObject(this);var e=z.ToUint32(r.length);if(e===0){return-1}var n=e-1;if(arguments.length>1){n=b(n,z.ToInteger(arguments[1]))}n=n>=0?n:e-Math.abs(n);for(;n>=0;n--){if(n in r&&t===r[n]){return n}}return-1}},st);var ct=function(){var t=[1,2];var r=t.splice();return t.length===2&&et(r)&&r.length===0}();P(r,{splice:function splice(t,r){if(arguments.length===0){return[]}else{return c.apply(this,arguments)}}},!ct);var vt=function(){var t={};r.splice.call(t,0,0,1);return t.length===1}();P(r,{splice:function splice(t,r){if(arguments.length===0){return[]}var e=arguments;this.length=w(z.ToInteger(this.length),0);if(arguments.length>0&&typeof r!==\"number\"){e=W(arguments);if(e.length<2){_(e,this.length-t)}else{e[1]=z.ToInteger(r)}}return c.apply(this,e)}},!vt);var ht=function(){var r=new t(1e5);r[8]=\"x\";r.splice(1,1);return r.indexOf(\"x\")===7}();var pt=function(){var t=256;var r=[];r[t]=\"a\";r.splice(t+1,0,\"b\");return r[t]===\"a\"}();P(r,{splice:function splice(t,r){var e=z.ToObject(this);var n=[];var i=z.ToUint32(e.length);var a=z.ToInteger(t);var f=a<0?w(i+a,0):b(a,i);var u=arguments.length===0?0:arguments.length===1?i-f:b(w(z.ToInteger(r),0),i-f);var l=0;var s;while(l<u){s=o(f+l);if(G(e,s)){n[l]=e[s]}l+=1}var c=W(arguments,2);var v=c.length;var h;if(v<u){l=f;var p=i-u;while(l<p){s=o(l+u);h=o(l+v);if(G(e,s)){e[h]=e[s]}else{delete e[h]}l+=1}l=i;var y=i-u+v;while(l>y){delete e[l-1];l-=1}}else if(v>u){l=i-u;while(l>f){s=o(l+u-1);h=o(l+v-1);if(G(e,s)){e[h]=e[s]}else{delete e[h]}l-=1}}l=f;for(var d=0;d<c.length;++d){e[l]=c[d];l+=1}e.length=i-u+v;return n}},!ht||!pt);var yt=r.join;var dt;try{dt=Array.prototype.join.call(\"123\",\",\")!==\"1,2,3\"}catch(X){dt=true}if(dt){P(r,{join:function join(t){var r=typeof t===\"undefined\"?\",\":t;return yt.call(N(this)?Q(this,\"\"):this,r)}},dt)}var gt=[1,2].join(undefined)!==\"1,2\";if(gt){P(r,{join:function join(t){var r=typeof t===\"undefined\"?\",\":t;return yt.call(this,r)}},gt)}var wt=function push(t){var r=z.ToObject(this);var e=z.ToUint32(r.length);var n=0;while(n<arguments.length){r[e+n]=arguments[n];n+=1}r.length=e+n;return e+n};var bt=function(){var t={};var r=Array.prototype.push.call(t,undefined);return r!==1||t.length!==1||typeof t[0]!==\"undefined\"||!G(t,0)}();P(r,{push:function push(t){if(et(this)){return v.apply(this,arguments)}return wt.apply(this,arguments)}},bt);var Tt=function(){var t=[];var r=t.push(undefined);return r!==1||t.length!==1||typeof t[0]!==\"undefined\"||!G(t,0)}();P(r,{push:wt},Tt);P(r,{slice:function(t,r){var e=N(this)?Q(this,\"\"):this;return B(e,arguments)}},at);var mt=function(){try{[1,2].sort(null)}catch(t){try{[1,2].sort({})}catch(r){return false}}return true}();var Dt=function(){try{[1,2].sort(/a/);return false}catch(t){}return true}();var St=function(){try{[1,2].sort(undefined);return true}catch(t){}return false}();P(r,{sort:function sort(t){if(typeof t===\"undefined\"){return rt(this)}if(!D(t)){throw new TypeError(\"Array.prototype.sort callback must be a function\")}return rt(this,t)}},mt||!St||!Dt);var xt=!tt({toString:null},\"toString\");var Ot=tt(function(){},\"prototype\");var Et=!G(\"x\",\"0\");var jt=function(t){var r=t.constructor;return r&&r.prototype===t};var It={$applicationCache:true,$console:true,$external:true,$frame:true,$frameElement:true,$frames:true,$innerHeight:true,$innerWidth:true,$onmozfullscreenchange:true,$onmozfullscreenerror:true,$outerHeight:true,$outerWidth:true,$pageXOffset:true,$pageYOffset:true,$parent:true,$scrollLeft:true,$scrollTop:true,$scrollX:true,$scrollY:true,$self:true,$webkitIndexedDB:true,$webkitStorageInfo:true,$window:true,$width:true,$height:true,$top:true,$localStorage:true};var Mt=function(){if(typeof window===\"undefined\"){return false}for(var t in window){try{if(!It[\"$\"+t]&&G(window,t)&&window[t]!==null&&typeof window[t]===\"object\"){jt(window[t])}}catch(r){return true}}return false}();var Ut=function(t){if(typeof window===\"undefined\"||!Mt){return jt(t)}try{return jt(t)}catch(r){return false}};var $t=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"];var Ft=$t.length;var Nt=function isArguments(t){return H(t)===\"[object Arguments]\"};var Ct=function isArguments(t){return t!==null&&typeof t===\"object\"&&typeof t.length===\"number\"&&t.length>=0&&!et(t)&&D(t.callee)};var kt=Nt(arguments)?Nt:Ct;P(e,{keys:function keys(t){var r=D(t);var e=kt(t);var n=t!==null&&typeof t===\"object\";var i=n&&N(t);if(!n&&!r&&!e){throw new TypeError(\"Object.keys called on a non-object\")}var a=[];var f=Ot&&r;if(i&&Et||e){for(var u=0;u<t.length;++u){_(a,o(u))}}if(!e){for(var l in t){if(!(f&&l===\"prototype\")&&G(t,l)){_(a,o(l))}}}if(xt){var s=Ut(t);for(var c=0;c<Ft;c++){var v=$t[c];if(!(s&&v===\"constructor\")&&G(t,v)){_(a,v)}}}return a}});var At=e.keys&&function(){return e.keys(arguments).length===2}(1,2);var Rt=e.keys&&function(){var t=e.keys(arguments);return arguments.length!==1||t.length!==1||t[0]!==1}(1);var Pt=e.keys;P(e,{keys:function keys(t){if(kt(t)){return Pt(W(t))}else{return Pt(t)}}},!At||Rt);var Jt=new Date(-0xc782b5b342b24).getUTCMonth()!==0;var Yt=new Date(-0x55d318d56a724);var zt=new Date(14496624e5);var Zt=Yt.toUTCString()!==\"Mon, 01 Jan -45875 11:59:59 GMT\";var Gt;var Ht;var Wt=Yt.getTimezoneOffset();if(Wt<-720){Gt=Yt.toDateString()!==\"Tue Jan 02 -45875\";Ht=!/^Thu Dec 10 2015 \\d\\d:\\d\\d:\\d\\d GMT[-+]\\d\\d\\d\\d(?: |$)/.test(String(zt))}else{Gt=Yt.toDateString()!==\"Mon Jan 01 -45875\";Ht=!/^Wed Dec 09 2015 \\d\\d:\\d\\d:\\d\\d GMT[-+]\\d\\d\\d\\d(?: |$)/.test(String(zt))}var Bt=d.bind(Date.prototype.getFullYear);var Xt=d.bind(Date.prototype.getMonth);var Lt=d.bind(Date.prototype.getDate);var qt=d.bind(Date.prototype.getUTCFullYear);var Kt=d.bind(Date.prototype.getUTCMonth);var Qt=d.bind(Date.prototype.getUTCDate);var Vt=d.bind(Date.prototype.getUTCDay);var _t=d.bind(Date.prototype.getUTCHours);var tr=d.bind(Date.prototype.getUTCMinutes);var rr=d.bind(Date.prototype.getUTCSeconds);var er=d.bind(Date.prototype.getUTCMilliseconds);var nr=[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"];var ir=[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];var ar=function daysInMonth(t,r){return Lt(new Date(r,t,0))};P(Date.prototype,{getFullYear:function getFullYear(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=Bt(this);if(t<0&&Xt(this)>11){return t+1}return t},getMonth:function getMonth(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=Bt(this);var r=Xt(this);if(t<0&&r>11){return 0}return r},getDate:function getDate(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=Bt(this);var r=Xt(this);var e=Lt(this);if(t<0&&r>11){if(r===12){return e}var n=ar(0,t+1);return n-e+1}return e},getUTCFullYear:function getUTCFullYear(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=qt(this);if(t<0&&Kt(this)>11){return t+1}return t},getUTCMonth:function getUTCMonth(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=qt(this);var r=Kt(this);if(t<0&&r>11){return 0}return r},getUTCDate:function getUTCDate(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=qt(this);var r=Kt(this);var e=Qt(this);if(t<0&&r>11){if(r===12){return e}var n=ar(0,t+1);return n-e+1}return e}},Jt);P(Date.prototype,{toUTCString:function toUTCString(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=Vt(this);var r=Qt(this);var e=Kt(this);var n=qt(this);var i=_t(this);var a=tr(this);var o=rr(this);return nr[t]+\", \"+(r<10?\"0\"+r:r)+\" \"+ir[e]+\" \"+n+\" \"+(i<10?\"0\"+i:i)+\":\"+(a<10?\"0\"+a:a)+\":\"+(o<10?\"0\"+o:o)+\" GMT\"}},Jt||Zt);P(Date.prototype,{toDateString:function toDateString(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=this.getDay();var r=this.getDate();var e=this.getMonth();var n=this.getFullYear();return nr[t]+\" \"+ir[e]+\" \"+(r<10?\"0\"+r:r)+\" \"+n}},Jt||Gt);if(Jt||Ht){Date.prototype.toString=function toString(){if(!this||!(this instanceof Date)){throw new TypeError(\"this is not a Date object.\")}var t=this.getDay();var r=this.getDate();var e=this.getMonth();var n=this.getFullYear();var i=this.getHours();var a=this.getMinutes();var o=this.getSeconds();var f=this.getTimezoneOffset();var u=Math.floor(Math.abs(f)/60);var l=Math.floor(Math.abs(f)%60);return nr[t]+\" \"+ir[e]+\" \"+(r<10?\"0\"+r:r)+\" \"+n+\" \"+(i<10?\"0\"+i:i)+\":\"+(a<10?\"0\"+a:a)+\":\"+(o<10?\"0\"+o:o)+\" GMT\"+(f>0?\"-\":\"+\")+(u<10?\"0\"+u:u)+(l<10?\"0\"+l:l)};if(R){e.defineProperty(Date.prototype,\"toString\",{configurable:true,enumerable:false,writable:true})}}var or=-621987552e5;var fr=\"-000001\";var ur=Date.prototype.toISOString&&new Date(or).toISOString().indexOf(fr)===-1;var lr=Date.prototype.toISOString&&new Date(-1).toISOString()!==\"1969-12-31T23:59:59.999Z\";var sr=d.bind(Date.prototype.getTime);P(Date.prototype,{toISOString:function toISOString(){if(!isFinite(this)||!isFinite(sr(this))){throw new RangeError(\"Date.prototype.toISOString called on non-finite value.\")}var t=qt(this);var r=Kt(this);t+=Math.floor(r/12);r=(r%12+12)%12;var e=[r+1,Qt(this),_t(this),tr(this),rr(this)];t=(t<0?\"-\":t>9999?\"+\":\"\")+K(\"00000\"+Math.abs(t),0<=t&&t<=9999?-4:-6);for(var n=0;n<e.length;++n){e[n]=K(\"00\"+e[n],-2)}return t+\"-\"+W(e,0,2).join(\"-\")+\"T\"+W(e,2).join(\":\")+\".\"+K(\"000\"+er(this),-3)+\"Z\"}},ur||lr);var cr=function(){try{return Date.prototype.toJSON&&new Date(NaN).toJSON()===null&&new Date(or).toJSON().indexOf(fr)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return true}})}catch(t){return false}}();if(!cr){Date.prototype.toJSON=function toJSON(t){var r=e(this);var n=z.ToPrimitive(r);if(typeof n===\"number\"&&!isFinite(n)){return null}var i=r.toISOString;if(!D(i)){throw new TypeError(\"toISOString property is not callable\")}return i.call(r)}}var vr=Date.parse(\"+033658-09-27T01:46:40.000Z\")===1e15;var hr=!isNaN(Date.parse(\"2012-04-04T24:00:00.500Z\"))||!isNaN(Date.parse(\"2012-11-31T23:59:59.000Z\"))||!isNaN(Date.parse(\"2012-12-31T23:59:60.000Z\"));var pr=isNaN(Date.parse(\"2000-01-01T00:00:00.000Z\"));if(pr||hr||!vr){var yr=Math.pow(2,31)-1;var dr=Y(new Date(1970,0,1,0,0,0,yr+1).getTime());Date=function(t){var r=function Date(e,n,i,a,f,u,l){var s=arguments.length;var c;if(this instanceof t){var v=u;var h=l;if(dr&&s>=7&&l>yr){var p=Math.floor(l/yr)*yr;var y=Math.floor(p/1e3);v+=y;h-=y*1e3}c=s===1&&o(e)===e?new t(r.parse(e)):s>=7?new t(e,n,i,a,f,v,h):s>=6?new t(e,n,i,a,f,v):s>=5?new t(e,n,i,a,f):s>=4?new t(e,n,i,a):s>=3?new t(e,n,i):s>=2?new t(e,n):s>=1?new t(e instanceof t?+e:e):new t}else{c=t.apply(this,arguments)}if(!J(c)){P(c,{constructor:r},true)}return c};var e=new RegExp(\"^\"+\"(\\\\d{4}|[+-]\\\\d{6})\"+\"(?:-(\\\\d{2})\"+\"(?:-(\\\\d{2})\"+\"(?:\"+\"T(\\\\d{2})\"+\":(\\\\d{2})\"+\"(?:\"+\":(\\\\d{2})\"+\"(?:(\\\\.\\\\d{1,}))?\"+\")?\"+\"(\"+\"Z|\"+\"(?:\"+\"([-+])\"+\"(\\\\d{2})\"+\":(\\\\d{2})\"+\")\"+\")?)?)?)?\"+\"$\");var n=[0,31,59,90,120,151,181,212,243,273,304,334,365];var i=function dayFromMonth(t,r){var e=r>1?1:0;return n[r]+Math.floor((t-1969+e)/4)-Math.floor((t-1901+e)/100)+Math.floor((t-1601+e)/400)+365*(t-1970)};var a=function toUTC(r){var e=0;var n=r;if(dr&&n>yr){var i=Math.floor(n/yr)*yr;var a=Math.floor(i/1e3);e+=a;n-=a*1e3}return u(new t(1970,0,1,0,0,e,n))};for(var f in t){if(G(t,f)){r[f]=t[f]}}P(r,{now:t.now,UTC:t.UTC},true);r.prototype=t.prototype;P(r.prototype,{constructor:r},true);var l=function parse(r){var n=e.exec(r);if(n){var o=u(n[1]),f=u(n[2]||1)-1,l=u(n[3]||1)-1,s=u(n[4]||0),c=u(n[5]||0),v=u(n[6]||0),h=Math.floor(u(n[7]||0)*1e3),p=Boolean(n[4]&&!n[8]),y=n[9]===\"-\"?1:-1,d=u(n[10]||0),g=u(n[11]||0),w;var b=c>0||v>0||h>0;if(s<(b?24:25)&&c<60&&v<60&&h<1e3&&f>-1&&f<12&&d<24&&g<60&&l>-1&&l<i(o,f+1)-i(o,f)){w=((i(o,f)+l)*24+s+d*y)*60;w=((w+c+g*y)*60+v)*1e3+h;if(p){w=a(w)}if(-864e13<=w&&w<=864e13){return w}}return NaN}return t.parse.apply(this,arguments)};P(r,{parse:l});return r}(Date)}if(!Date.now){Date.now=function now(){return(new Date).getTime()}}var gr=l.toFixed&&(8e-5.toFixed(3)!==\"0.000\"||.9.toFixed(0)!==\"1\"||1.255.toFixed(2)!==\"1.25\"||(1000000000000000128).toFixed(0)!==\"1000000000000000128\");var wr={base:1e7,size:6,data:[0,0,0,0,0,0],multiply:function multiply(t,r){var e=-1;var n=r;while(++e<wr.size){n+=t*wr.data[e];wr.data[e]=n%wr.base;n=Math.floor(n/wr.base)}},divide:function divide(t){var r=wr.size;var e=0;while(--r>=0){e+=wr.data[r];wr.data[r]=Math.floor(e/t);e=e%t*wr.base}},numToString:function numToString(){var t=wr.size;var r=\"\";while(--t>=0){if(r!==\"\"||t===0||wr.data[t]!==0){var e=o(wr.data[t]);if(r===\"\"){r=e}else{r+=K(\"0000000\",0,7-e.length)+e}}}return r},pow:function pow(t,r,e){return r===0?e:r%2===1?pow(t,r-1,e*t):pow(t*t,r/2,e)},log:function log(t){var r=0;var e=t;while(e>=4096){r+=12;e/=4096}while(e>=2){r+=1;e/=2}return r}};var br=function toFixed(t){var r,e,n,i,a,f,l,s;r=u(t);r=Y(r)?0:Math.floor(r);if(r<0||r>20){throw new RangeError(\"Number.toFixed called with invalid number of decimals\")}e=u(this);if(Y(e)){return\"NaN\"}if(e<=-1e21||e>=1e21){return o(e)}n=\"\";if(e<0){n=\"-\";e=-e}i=\"0\";if(e>1e-21){a=wr.log(e*wr.pow(2,69,1))-69;f=a<0?e*wr.pow(2,-a,1):e/wr.pow(2,a,1);f*=4503599627370496;a=52-a;if(a>0){wr.multiply(0,f);l=r;while(l>=7){wr.multiply(1e7,0);l-=7}wr.multiply(wr.pow(10,l,1),0);l=a-1;while(l>=23){wr.divide(1<<23);l-=23}wr.divide(1<<l);wr.multiply(1,1);wr.divide(2);i=wr.numToString()}else{wr.multiply(0,f);wr.multiply(1<<-a,0);i=wr.numToString()+K(\"0.00000000000000000000\",2,2+r)}}if(r>0){s=i.length;if(s<=r){i=n+K(\"0.0000000000000000000\",0,r-s+2)+i}else{i=n+K(i,0,s-r)+\".\"+K(i,s-r)}}else{i=n+i}return i};P(l,{toFixed:br},gr);var Tr=function(){try{return 1..toPrecision(undefined)===\"1\"}catch(t){return true}}();var mr=l.toPrecision;P(l,{toPrecision:function toPrecision(t){return typeof t===\"undefined\"?mr.call(this):mr.call(this,t)}},Tr);if(\"ab\".split(/(?:ab)*/).length!==2||\".\".split(/(.?)(.?)/).length!==4||\"tesst\".split(/(s)*/)[1]===\"t\"||\"test\".split(/(?:)/,-1).length!==4||\"\".split(/.?/).length||\".\".split(/()()/).length>1){(function(){var t=typeof/()??/.exec(\"\")[1]===\"undefined\";var r=Math.pow(2,32)-1;f.split=function(e,n){var i=String(this);if(typeof e===\"undefined\"&&n===0){return[]}if(!M(e)){return Q(this,e,n)}var a=[];var o=(e.ignoreCase?\"i\":\"\")+(e.multiline?\"m\":\"\")+(e.unicode?\"u\":\"\")+(e.sticky?\"y\":\"\"),f=0,u,l,s,c;var h=new RegExp(e.source,o+\"g\");if(!t){u=new RegExp(\"^\"+h.source+\"$(?!\\\\s)\",o)}var p=typeof n===\"undefined\"?r:z.ToUint32(n);l=h.exec(i);while(l){s=l.index+l[0].length;if(s>f){_(a,K(i,f,l.index));if(!t&&l.length>1){l[0].replace(u,function(){for(var t=1;t<arguments.length-2;t++){if(typeof arguments[t]===\"undefined\"){l[t]=void 0}}})}if(l.length>1&&l.index<i.length){v.apply(a,W(l,1))}c=l[0].length;f=s;if(a.length>=p){break}}if(h.lastIndex===l.index){h.lastIndex++}l=h.exec(i)}if(f===i.length){if(c||!h.test(\"\")){_(a,\"\")}}else{_(a,K(i,f))}return a.length>p?W(a,0,p):a}})()}else if(\"0\".split(void 0,0).length){f.split=function split(t,r){if(typeof t===\"undefined\"&&r===0){return[]}return Q(this,t,r)}}var Dr=f.replace;var Sr=function(){var t=[];\"x\".replace(/x(.)?/g,function(r,e){_(t,e)});return t.length===1&&typeof t[0]===\"undefined\"}();if(!Sr){f.replace=function replace(t,r){var e=D(r);var n=M(t)&&/\\)[*?]/.test(t.source);if(!e||!n){return Dr.call(this,t,r)}else{var i=function(e){var n=arguments.length;var i=t.lastIndex;t.lastIndex=0;var a=t.exec(e)||[];t.lastIndex=i;_(a,arguments[n-2],arguments[n-1]);return r.apply(this,a)};return Dr.call(this,t,i)}}}var xr=f.substr;var Or=\"\".substr&&\"0b\".substr(-1)!==\"b\";P(f,{substr:function substr(t,r){var e=t;if(t<0){e=w(this.length+t,0)}return xr.call(this,e,r)}},Or);var Er=\"\\t\\n\\x0B\\f\\r \\xa0\\u1680\\u2000\\u2001\\u2002\\u2003\"+\"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\"+\"\\u2029\\ufeff\";var jr=\"\\u200b\";var Ir=\"[\"+Er+\"]\";var Mr=new RegExp(\"^\"+Ir+Ir+\"*\");var Ur=new RegExp(Ir+Ir+\"*$\");var $r=f.trim&&(Er.trim()||!jr.trim());P(f,{trim:function trim(){if(typeof this===\"undefined\"||this===null){throw new TypeError(\"can't convert \"+this+\" to object\")}return o(this).replace(Mr,\"\").replace(Ur,\"\")}},$r);var Fr=d.bind(String.prototype.trim);var Nr=f.lastIndexOf&&\"abc\\u3042\\u3044\".lastIndexOf(\"\\u3042\\u3044\",2)!==-1;P(f,{lastIndexOf:function lastIndexOf(t){if(typeof this===\"undefined\"||this===null){throw new TypeError(\"can't convert \"+this+\" to object\")}var r=o(this);var e=o(t);var n=arguments.length>1?u(arguments[1]):NaN;var i=Y(n)?Infinity:z.ToInteger(n);var a=b(w(i,0),r.length);var f=e.length;var l=a+f;while(l>0){l=w(0,l-f);var s=V(K(r,l,a+f),e);if(s!==-1){return l+s}}return-1}},Nr);var Cr=f.lastIndexOf;P(f,{lastIndexOf:function lastIndexOf(t){return Cr.apply(this,arguments)}},f.lastIndexOf.length!==1);if(parseInt(Er+\"08\")!==8||parseInt(Er+\"0x16\")!==22){parseInt=function(t){var r=/^[-+]?0[xX]/;return function parseInt(e,n){if(typeof e===\"symbol\"){\"\"+e}var i=Fr(String(e));var a=u(n)||(r.test(i)?16:10);return t(i,a)}}(parseInt)}if(1/parseFloat(\"-0\")!==-Infinity){parseFloat=function(t){return function parseFloat(r){var e=Fr(String(r));var n=t(e);return n===0&&K(e,0,1)===\"-\"?-0:n}}(parseFloat)}if(String(new RangeError(\"test\"))!==\"RangeError: test\"){var kr=function toString(){if(typeof this===\"undefined\"||this===null){throw new TypeError(\"can't convert \"+this+\" to object\")}var t=this.name;if(typeof t===\"undefined\"){t=\"Error\"}else if(typeof t!==\"string\"){t=o(t)}var r=this.message;if(typeof r===\"undefined\"){r=\"\"}else if(typeof r!==\"string\"){r=o(r)}if(!t){return r}if(!r){return t}return t+\": \"+r};Error.prototype.toString=kr}if(R){var Ar=function(t,r){if(tt(t,r)){var e=Object.getOwnPropertyDescriptor(t,r);if(e.configurable){e.enumerable=false;Object.defineProperty(t,r,e)}}};Ar(Error.prototype,\"message\");if(Error.prototype.message!==\"\"){Error.prototype.message=\"\"}Ar(Error.prototype,\"name\")}if(String(/a/gim)!==\"/a/gim\"){var Rr=function toString(){var t=\"/\"+this.source+\"/\";if(this.global){t+=\"g\"}if(this.ignoreCase){t+=\"i\"}if(this.multiline){t+=\"m\"}return t};RegExp.prototype.toString=Rr}});\n/*!\n * https://github.com/paulmillr/es6-shim\n * @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)\n * and contributors, MIT License\n * es6-shim: v0.35.4\n * see https://github.com/paulmillr/es6-shim/blob/0.35.4/LICENSE\n * Details and documentation:\n * https://github.com/paulmillr/es6-shim/\n */\n(function(e,t){if(typeof define===\"function\"&&define.amd){define(t)}else if(typeof exports===\"object\"){module.exports=t()}else{e.returnExports=t()}})(this,function(){\"use strict\";var e=Function.call.bind(Function.apply);var t=Function.call.bind(Function.call);var r=Array.isArray;var n=Object.keys;var o=function notThunker(t){return function notThunk(){return!e(t,this,arguments)}};var i=function(e){try{e();return false}catch(t){return true}};var a=function valueOrFalseIfThrows(e){try{return e()}catch(t){return false}};var u=o(i);var f=function(){return!i(function(){return Object.defineProperty({},\"x\",{get:function(){}})})};var s=!!Object.defineProperty&&f();var c=function foo(){}.name===\"foo\";var l=Function.call.bind(Array.prototype.forEach);var p=Function.call.bind(Array.prototype.reduce);var v=Function.call.bind(Array.prototype.filter);var y=Function.call.bind(Array.prototype.some);var h=function(e,t,r,n){if(!n&&t in e){return}if(s){Object.defineProperty(e,t,{configurable:true,enumerable:false,writable:true,value:r})}else{e[t]=r}};var b=function(e,t,r){l(n(t),function(n){var o=t[n];h(e,n,o,!!r)})};var g=Function.call.bind(Object.prototype.toString);var d=typeof/abc/===\"function\"?function IsCallableSlow(e){return typeof e===\"function\"&&g(e)===\"[object Function]\"}:function IsCallableFast(e){return typeof e===\"function\"};var m={getter:function(e,t,r){if(!s){throw new TypeError(\"getters require true ES5 support\")}Object.defineProperty(e,t,{configurable:true,enumerable:false,get:r})},proxy:function(e,t,r){if(!s){throw new TypeError(\"getters require true ES5 support\")}var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,{configurable:n.configurable,enumerable:n.enumerable,get:function getKey(){return e[t]},set:function setKey(r){e[t]=r}})},redefine:function(e,t,r){if(s){var n=Object.getOwnPropertyDescriptor(e,t);n.value=r;Object.defineProperty(e,t,n)}else{e[t]=r}},defineByDescriptor:function(e,t,r){if(s){Object.defineProperty(e,t,r)}else if(\"value\"in r){e[t]=r.value}},preserveToString:function(e,t){if(t&&d(t.toString)){h(e,\"toString\",t.toString.bind(t),true)}}};var O=Object.create||function(e,t){var r=function Prototype(){};r.prototype=e;var o=new r;if(typeof t!==\"undefined\"){n(t).forEach(function(e){m.defineByDescriptor(o,e,t[e])})}return o};var w=function(e,t){if(!Object.setPrototypeOf){return false}return a(function(){var r=function Subclass(t){var r=new e(t);Object.setPrototypeOf(r,Subclass.prototype);return r};Object.setPrototypeOf(r,e);r.prototype=O(e.prototype,{constructor:{value:r}});return t(r)})};var j=function(){if(typeof self!==\"undefined\"){return self}if(typeof window!==\"undefined\"){return window}if(typeof global!==\"undefined\"){return global}throw new Error(\"unable to locate global object\")};var S=j();var T=S.isFinite;var I=Function.call.bind(String.prototype.indexOf);var E=Function.apply.bind(Array.prototype.indexOf);var P=Function.call.bind(Array.prototype.concat);var C=Function.call.bind(String.prototype.slice);var M=Function.call.bind(Array.prototype.push);var x=Function.apply.bind(Array.prototype.push);var N=Function.call.bind(Array.prototype.shift);var A=Math.max;var R=Math.min;var _=Math.floor;var k=Math.abs;var L=Math.exp;var F=Math.log;var D=Math.sqrt;var z=Function.call.bind(Object.prototype.hasOwnProperty);var q;var W=function(){};var G=S.Map;var H=G&&G.prototype[\"delete\"];var V=G&&G.prototype.get;var B=G&&G.prototype.has;var U=G&&G.prototype.set;var $=S.Symbol||{};var J=$.species||\"@@species\";var X=Number.isNaN||function isNaN(e){return e!==e};var K=Number.isFinite||function isFinite(e){return typeof e===\"number\"&&T(e)};var Z=d(Math.sign)?Math.sign:function sign(e){var t=Number(e);if(t===0){return t}if(X(t)){return t}return t<0?-1:1};var Y=function log1p(e){var t=Number(e);if(t<-1||X(t)){return NaN}if(t===0||t===Infinity){return t}if(t===-1){return-Infinity}return 1+t-1===0?t:t*(F(1+t)/(1+t-1))};var Q=function isArguments(e){return g(e)===\"[object Arguments]\"};var ee=function isArguments(e){return e!==null&&typeof e===\"object\"&&typeof e.length===\"number\"&&e.length>=0&&g(e)!==\"[object Array]\"&&g(e.callee)===\"[object Function]\"};var te=Q(arguments)?Q:ee;var re={primitive:function(e){return e===null||typeof e!==\"function\"&&typeof e!==\"object\"},string:function(e){return g(e)===\"[object String]\"},regex:function(e){return g(e)===\"[object RegExp]\"},symbol:function(e){return typeof S.Symbol===\"function\"&&typeof e===\"symbol\"}};var ne=function overrideNative(e,t,r){var n=e[t];h(e,t,r,true);m.preserveToString(e[t],n)};var oe=typeof $===\"function\"&&typeof $[\"for\"]===\"function\"&&re.symbol($());var ie=re.symbol($.iterator)?$.iterator:\"_es6-shim iterator_\";if(S.Set&&typeof(new S.Set)[\"@@iterator\"]===\"function\"){ie=\"@@iterator\"}if(!S.Reflect){h(S,\"Reflect\",{},true)}var ae=S.Reflect;var ue=String;var fe=typeof document===\"undefined\"||!document?null:document.all;var se=fe==null?function isNullOrUndefined(e){return e==null}:function isNullOrUndefinedAndNotDocumentAll(e){return e==null&&e!==fe};var ce={Call:function Call(t,r){var n=arguments.length>2?arguments[2]:[];if(!ce.IsCallable(t)){throw new TypeError(t+\" is not a function\")}return e(t,r,n)},RequireObjectCoercible:function(e,t){if(se(e)){throw new TypeError(t||\"Cannot call method on \"+e)}return e},TypeIsObject:function(e){if(e===void 0||e===null||e===true||e===false){return false}return typeof e===\"function\"||typeof e===\"object\"||e===fe},ToObject:function(e,t){return Object(ce.RequireObjectCoercible(e,t))},IsCallable:d,IsConstructor:function(e){return ce.IsCallable(e)},ToInt32:function(e){return ce.ToNumber(e)>>0},ToUint32:function(e){return ce.ToNumber(e)>>>0},ToNumber:function(e){if(g(e)===\"[object Symbol]\"){throw new TypeError(\"Cannot convert a Symbol value to a number\")}return+e},ToInteger:function(e){var t=ce.ToNumber(e);if(X(t)){return 0}if(t===0||!K(t)){return t}return(t>0?1:-1)*_(k(t))},ToLength:function(e){var t=ce.ToInteger(e);if(t<=0){return 0}if(t>Number.MAX_SAFE_INTEGER){return Number.MAX_SAFE_INTEGER}return t},SameValue:function(e,t){if(e===t){if(e===0){return 1/e===1/t}return true}return X(e)&&X(t)},SameValueZero:function(e,t){return e===t||X(e)&&X(t)},IsIterable:function(e){return ce.TypeIsObject(e)&&(typeof e[ie]!==\"undefined\"||te(e))},GetIterator:function(e){if(te(e)){return new q(e,\"value\")}var t=ce.GetMethod(e,ie);if(!ce.IsCallable(t)){throw new TypeError(\"value is not an iterable\")}var r=ce.Call(t,e);if(!ce.TypeIsObject(r)){throw new TypeError(\"bad iterator\")}return r},GetMethod:function(e,t){var r=ce.ToObject(e)[t];if(se(r)){return void 0}if(!ce.IsCallable(r)){throw new TypeError(\"Method not callable: \"+t)}return r},IteratorComplete:function(e){return!!e.done},IteratorClose:function(e,t){var r=ce.GetMethod(e,\"return\");if(r===void 0){return}var n,o;try{n=ce.Call(r,e)}catch(i){o=i}if(t){return}if(o){throw o}if(!ce.TypeIsObject(n)){throw new TypeError(\"Iterator's return method returned a non-object.\")}},IteratorNext:function(e){var t=arguments.length>1?e.next(arguments[1]):e.next();if(!ce.TypeIsObject(t)){throw new TypeError(\"bad iterator\")}return t},IteratorStep:function(e){var t=ce.IteratorNext(e);var r=ce.IteratorComplete(t);return r?false:t},Construct:function(e,t,r,n){var o=typeof r===\"undefined\"?e:r;if(!n&&ae.construct){return ae.construct(e,t,o)}var i=o.prototype;if(!ce.TypeIsObject(i)){i=Object.prototype}var a=O(i);var u=ce.Call(e,a,t);return ce.TypeIsObject(u)?u:a},SpeciesConstructor:function(e,t){var r=e.constructor;if(r===void 0){return t}if(!ce.TypeIsObject(r)){throw new TypeError(\"Bad constructor\")}var n=r[J];if(se(n)){return t}if(!ce.IsConstructor(n)){throw new TypeError(\"Bad @@species\")}return n},CreateHTML:function(e,t,r,n){var o=ce.ToString(e);var i=\"<\"+t;if(r!==\"\"){var a=ce.ToString(n);var u=a.replace(/\"/g,\""\");i+=\" \"+r+'=\"'+u+'\"'}var f=i+\">\";var s=f+o;return s+\"</\"+t+\">\"},IsRegExp:function IsRegExp(e){if(!ce.TypeIsObject(e)){return false}var t=e[$.match];if(typeof t!==\"undefined\"){return!!t}return re.regex(e)},ToString:function ToString(e){return ue(e)}};if(s&&oe){var le=function defineWellKnownSymbol(e){if(re.symbol($[e])){return $[e]}var t=$[\"for\"](\"Symbol.\"+e);Object.defineProperty($,e,{configurable:false,enumerable:false,writable:false,value:t});return t};if(!re.symbol($.search)){var pe=le(\"search\");var ve=String.prototype.search;h(RegExp.prototype,pe,function search(e){return ce.Call(ve,e,[this])});var ye=function search(e){var t=ce.RequireObjectCoercible(this);if(!se(e)){var r=ce.GetMethod(e,pe);if(typeof r!==\"undefined\"){return ce.Call(r,e,[t])}}return ce.Call(ve,t,[ce.ToString(e)])};ne(String.prototype,\"search\",ye)}if(!re.symbol($.replace)){var he=le(\"replace\");var be=String.prototype.replace;h(RegExp.prototype,he,function replace(e,t){return ce.Call(be,e,[this,t])});var ge=function replace(e,t){var r=ce.RequireObjectCoercible(this);if(!se(e)){var n=ce.GetMethod(e,he);if(typeof n!==\"undefined\"){return ce.Call(n,e,[r,t])}}return ce.Call(be,r,[ce.ToString(e),t])};ne(String.prototype,\"replace\",ge)}if(!re.symbol($.split)){var de=le(\"split\");var me=String.prototype.split;h(RegExp.prototype,de,function split(e,t){return ce.Call(me,e,[this,t])});var Oe=function split(e,t){var r=ce.RequireObjectCoercible(this);if(!se(e)){var n=ce.GetMethod(e,de);if(typeof n!==\"undefined\"){return ce.Call(n,e,[r,t])}}return ce.Call(me,r,[ce.ToString(e),t])};ne(String.prototype,\"split\",Oe)}var we=re.symbol($.match);var je=we&&function(){var e={};e[$.match]=function(){return 42};return\"a\".match(e)!==42}();if(!we||je){var Se=le(\"match\");var Te=String.prototype.match;h(RegExp.prototype,Se,function match(e){return ce.Call(Te,e,[this])});var Ie=function match(e){var t=ce.RequireObjectCoercible(this);if(!se(e)){var r=ce.GetMethod(e,Se);if(typeof r!==\"undefined\"){return ce.Call(r,e,[t])}}return ce.Call(Te,t,[ce.ToString(e)])};ne(String.prototype,\"match\",Ie)}}var Ee=function wrapConstructor(e,t,r){m.preserveToString(t,e);if(Object.setPrototypeOf){Object.setPrototypeOf(e,t)}if(s){l(Object.getOwnPropertyNames(e),function(n){if(n in W||r[n]){return}m.proxy(e,n,t)})}else{l(Object.keys(e),function(n){if(n in W||r[n]){return}t[n]=e[n]})}t.prototype=e.prototype;m.redefine(e.prototype,\"constructor\",t)};var Pe=function(){return this};var Ce=function(e){if(s&&!z(e,J)){m.getter(e,J,Pe)}};var Me=function(e,t){var r=t||function iterator(){return this};h(e,ie,r);if(!e[ie]&&re.symbol(ie)){e[ie]=r}};var xe=function createDataProperty(e,t,r){if(s){Object.defineProperty(e,t,{configurable:true,enumerable:true,writable:true,value:r})}else{e[t]=r}};var Ne=function createDataPropertyOrThrow(e,t,r){xe(e,t,r);if(!ce.SameValue(e[t],r)){throw new TypeError(\"property is nonconfigurable\")}};var Ae=function(e,t,r,n){if(!ce.TypeIsObject(e)){throw new TypeError(\"Constructor requires `new`: \"+t.name)}var o=t.prototype;if(!ce.TypeIsObject(o)){o=r}var i=O(o);for(var a in n){if(z(n,a)){var u=n[a];h(i,a,u,true)}}return i};if(String.fromCodePoint&&String.fromCodePoint.length!==1){var Re=String.fromCodePoint;ne(String,\"fromCodePoint\",function fromCodePoint(e){return ce.Call(Re,this,arguments)})}var _e={fromCodePoint:function fromCodePoint(e){var t=[];var r;for(var n=0,o=arguments.length;n<o;n++){r=Number(arguments[n]);if(!ce.SameValue(r,ce.ToInteger(r))||r<0||r>1114111){throw new RangeError(\"Invalid code point \"+r)}if(r<65536){M(t,String.fromCharCode(r))}else{r-=65536;M(t,String.fromCharCode((r>>10)+55296));M(t,String.fromCharCode(r%1024+56320))}}return t.join(\"\")},raw:function raw(e){var t=ce.ToObject(e,\"bad callSite\");var r=ce.ToObject(t.raw,\"bad raw value\");var n=r.length;var o=ce.ToLength(n);if(o<=0){return\"\"}var i=[];var a=0;var u,f,s,c;while(a<o){u=ce.ToString(a);s=ce.ToString(r[u]);M(i,s);if(a+1>=o){break}f=a+1<arguments.length?arguments[a+1]:\"\";c=ce.ToString(f);M(i,c);a+=1}return i.join(\"\")}};if(String.raw&&String.raw({raw:{0:\"x\",1:\"y\",length:2}})!==\"xy\"){ne(String,\"raw\",_e.raw)}b(String,_e);var ke=function repeat(e,t){if(t<1){return\"\"}if(t%2){return repeat(e,t-1)+e}var r=repeat(e,t/2);return r+r};var Le=Infinity;var Fe={repeat:function repeat(e){var t=ce.ToString(ce.RequireObjectCoercible(this));var r=ce.ToInteger(e);if(r<0||r>=Le){throw new RangeError(\"repeat count must be less than infinity and not overflow maximum string size\")}return ke(t,r)},startsWith:function startsWith(e){var t=ce.ToString(ce.RequireObjectCoercible(this));if(ce.IsRegExp(e)){throw new TypeError('Cannot call method \"startsWith\" with a regex')}var r=ce.ToString(e);var n;if(arguments.length>1){n=arguments[1]}var o=A(ce.ToInteger(n),0);return C(t,o,o+r.length)===r},endsWith:function endsWith(e){var t=ce.ToString(ce.RequireObjectCoercible(this));if(ce.IsRegExp(e)){throw new TypeError('Cannot call method \"endsWith\" with a regex')}var r=ce.ToString(e);var n=t.length;var o;if(arguments.length>1){o=arguments[1]}var i=typeof o===\"undefined\"?n:ce.ToInteger(o);var a=R(A(i,0),n);return C(t,a-r.length,a)===r},includes:function includes(e){if(ce.IsRegExp(e)){throw new TypeError('\"includes\" does not accept a RegExp')}var t=ce.ToString(e);var r;if(arguments.length>1){r=arguments[1]}return I(this,t,r)!==-1},codePointAt:function codePointAt(e){var t=ce.ToString(ce.RequireObjectCoercible(this));var r=ce.ToInteger(e);var n=t.length;if(r>=0&&r<n){var o=t.charCodeAt(r);var i=r+1===n;if(o<55296||o>56319||i){return o}var a=t.charCodeAt(r+1);if(a<56320||a>57343){return o}return(o-55296)*1024+(a-56320)+65536}}};if(String.prototype.includes&&\"a\".includes(\"a\",Infinity)!==false){ne(String.prototype,\"includes\",Fe.includes)}if(String.prototype.startsWith&&String.prototype.endsWith){var De=i(function(){return\"/a/\".startsWith(/a/)});var ze=a(function(){return\"abc\".startsWith(\"a\",Infinity)===false});if(!De||!ze){ne(String.prototype,\"startsWith\",Fe.startsWith);ne(String.prototype,\"endsWith\",Fe.endsWith)}}if(oe){var qe=a(function(){var e=/a/;e[$.match]=false;return\"/a/\".startsWith(e)});if(!qe){ne(String.prototype,\"startsWith\",Fe.startsWith)}var We=a(function(){var e=/a/;e[$.match]=false;return\"/a/\".endsWith(e)});if(!We){ne(String.prototype,\"endsWith\",Fe.endsWith)}var Ge=a(function(){var e=/a/;e[$.match]=false;return\"/a/\".includes(e)});if(!Ge){ne(String.prototype,\"includes\",Fe.includes)}}b(String.prototype,Fe);var He=[\"\\t\\n\\x0B\\f\\r \\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\",\"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\",\"\\u2029\\ufeff\"].join(\"\");var Ve=new RegExp(\"(^[\"+He+\"]+)|([\"+He+\"]+$)\",\"g\");var Be=function trim(){return ce.ToString(ce.RequireObjectCoercible(this)).replace(Ve,\"\")};var Ue=[\"\\x85\",\"\\u200b\",\"\\ufffe\"].join(\"\");var $e=new RegExp(\"[\"+Ue+\"]\",\"g\");var Je=/^[-+]0x[0-9a-f]+$/i;var Xe=Ue.trim().length!==Ue.length;h(String.prototype,\"trim\",Be,Xe);var Ke=function(e){return{value:e,done:arguments.length===0}};var Ze=function(e){ce.RequireObjectCoercible(e);this._s=ce.ToString(e);this._i=0};Ze.prototype.next=function(){var e=this._s;var t=this._i;if(typeof e===\"undefined\"||t>=e.length){this._s=void 0;return Ke()}var r=e.charCodeAt(t);var n,o;if(r<55296||r>56319||t+1===e.length){o=1}else{n=e.charCodeAt(t+1);o=n<56320||n>57343?1:2}this._i=t+o;return Ke(e.substr(t,o))};Me(Ze.prototype);Me(String.prototype,function(){return new Ze(this)});var Ye={from:function from(e){var r=this;var n;if(arguments.length>1){n=arguments[1]}var o,i;if(typeof n===\"undefined\"){o=false}else{if(!ce.IsCallable(n)){throw new TypeError(\"Array.from: when provided, the second argument must be a function\")}if(arguments.length>2){i=arguments[2]}o=true}var a=typeof(te(e)||ce.GetMethod(e,ie))!==\"undefined\";var u,f,s;if(a){f=ce.IsConstructor(r)?Object(new r):[];var c=ce.GetIterator(e);var l,p;s=0;while(true){l=ce.IteratorStep(c);if(l===false){break}p=l.value;try{if(o){p=typeof i===\"undefined\"?n(p,s):t(n,i,p,s)}f[s]=p}catch(v){ce.IteratorClose(c,true);throw v}s+=1}u=s}else{var y=ce.ToObject(e);u=ce.ToLength(y.length);f=ce.IsConstructor(r)?Object(new r(u)):new Array(u);var h;for(s=0;s<u;++s){h=y[s];if(o){h=typeof i===\"undefined\"?n(h,s):t(n,i,h,s)}Ne(f,s,h)}}f.length=u;return f},of:function of(){var e=arguments.length;var t=this;var n=r(t)||!ce.IsCallable(t)?new Array(e):ce.Construct(t,[e]);for(var o=0;o<e;++o){Ne(n,o,arguments[o])}n.length=e;return n}};b(Array,Ye);Ce(Array);q=function(e,t){this.i=0;this.array=e;this.kind=t};b(q.prototype,{next:function(){var e=this.i;var t=this.array;if(!(this instanceof q)){throw new TypeError(\"Not an ArrayIterator\")}if(typeof t!==\"undefined\"){var r=ce.ToLength(t.length);for(;e<r;e++){var n=this.kind;var o;if(n===\"key\"){o=e}else if(n===\"value\"){o=t[e]}else if(n===\"entry\"){o=[e,t[e]]}this.i=e+1;return Ke(o)}}this.array=void 0;return Ke()}});Me(q.prototype);var Qe=Array.of===Ye.of||function(){var e=function Foo(e){this.length=e};e.prototype=[];var t=Array.of.apply(e,[1,2]);return t instanceof e&&t.length===2}();if(!Qe){ne(Array,\"of\",Ye.of)}var et={copyWithin:function copyWithin(e,t){var r=ce.ToObject(this);var n=ce.ToLength(r.length);var o=ce.ToInteger(e);var i=ce.ToInteger(t);var a=o<0?A(n+o,0):R(o,n);var u=i<0?A(n+i,0):R(i,n);var f;if(arguments.length>2){f=arguments[2]}var s=typeof f===\"undefined\"?n:ce.ToInteger(f);var c=s<0?A(n+s,0):R(s,n);var l=R(c-u,n-a);var p=1;if(u<a&&a<u+l){p=-1;u+=l-1;a+=l-1}while(l>0){if(u in r){r[a]=r[u]}else{delete r[a]}u+=p;a+=p;l-=1}return r},fill:function fill(e){var t;if(arguments.length>1){t=arguments[1]}var r;if(arguments.length>2){r=arguments[2]}var n=ce.ToObject(this);var o=ce.ToLength(n.length);t=ce.ToInteger(typeof t===\"undefined\"?0:t);r=ce.ToInteger(typeof r===\"undefined\"?o:r);var i=t<0?A(o+t,0):R(t,o);var a=r<0?o+r:r;for(var u=i;u<o&&u<a;++u){n[u]=e}return n},find:function find(e){var r=ce.ToObject(this);var n=ce.ToLength(r.length);if(!ce.IsCallable(e)){throw new TypeError(\"Array#find: predicate must be a function\")}var o=arguments.length>1?arguments[1]:null;for(var i=0,a;i<n;i++){a=r[i];if(o){if(t(e,o,a,i,r)){return a}}else if(e(a,i,r)){return a}}},findIndex:function findIndex(e){var r=ce.ToObject(this);var n=ce.ToLength(r.length);if(!ce.IsCallable(e)){throw new TypeError(\"Array#findIndex: predicate must be a function\")}var o=arguments.length>1?arguments[1]:null;for(var i=0;i<n;i++){if(o){if(t(e,o,r[i],i,r)){return i}}else if(e(r[i],i,r)){return i}}return-1},keys:function keys(){return new q(this,\"key\")},values:function values(){return new q(this,\"value\")},entries:function entries(){return new q(this,\"entry\")}};if(Array.prototype.keys&&!ce.IsCallable([1].keys().next)){delete Array.prototype.keys}if(Array.prototype.entries&&!ce.IsCallable([1].entries().next)){delete Array.prototype.entries}if(Array.prototype.keys&&Array.prototype.entries&&!Array.prototype.values&&Array.prototype[ie]){b(Array.prototype,{values:Array.prototype[ie]});if(re.symbol($.unscopables)){Array.prototype[$.unscopables].values=true}}if(c&&Array.prototype.values&&Array.prototype.values.name!==\"values\"){var tt=Array.prototype.values;ne(Array.prototype,\"values\",function values(){return ce.Call(tt,this,arguments)});h(Array.prototype,ie,Array.prototype.values,true)}b(Array.prototype,et);if(1/[true].indexOf(true,-0)<0){h(Array.prototype,\"indexOf\",function indexOf(e){var t=E(this,arguments);if(t===0&&1/t<0){return 0}return t},true)}Me(Array.prototype,function(){return this.values()});if(Object.getPrototypeOf){Me(Object.getPrototypeOf([].values()))}var rt=function(){return a(function(){return Array.from({length:-1}).length===0})}();var nt=function(){var e=Array.from([0].entries());return e.length===1&&r(e[0])&&e[0][0]===0&&e[0][1]===0}();if(!rt||!nt){ne(Array,\"from\",Ye.from)}var ot=function(){return a(function(){return Array.from([0],void 0)})}();if(!ot){var it=Array.from;ne(Array,\"from\",function from(e){if(arguments.length>1&&typeof arguments[1]!==\"undefined\"){return ce.Call(it,this,arguments)}else{return t(it,this,e)}})}var at=-(Math.pow(2,32)-1);var ut=function(e,r){var n={length:at};n[r?(n.length>>>0)-1:0]=true;return a(function(){t(e,n,function(){throw new RangeError(\"should not reach here\")},[]);return true})};if(!ut(Array.prototype.forEach)){var ft=Array.prototype.forEach;ne(Array.prototype,\"forEach\",function forEach(e){return ce.Call(ft,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.map)){var st=Array.prototype.map;ne(Array.prototype,\"map\",function map(e){return ce.Call(st,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.filter)){var ct=Array.prototype.filter;ne(Array.prototype,\"filter\",function filter(e){return ce.Call(ct,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.some)){var lt=Array.prototype.some;ne(Array.prototype,\"some\",function some(e){return ce.Call(lt,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.every)){var pt=Array.prototype.every;ne(Array.prototype,\"every\",function every(e){return ce.Call(pt,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.reduce)){var vt=Array.prototype.reduce;ne(Array.prototype,\"reduce\",function reduce(e){return ce.Call(vt,this.length>=0?this:[],arguments)},true)}if(!ut(Array.prototype.reduceRight,true)){var yt=Array.prototype.reduceRight;ne(Array.prototype,\"reduceRight\",function reduceRight(e){return ce.Call(yt,this.length>=0?this:[],arguments)},true)}var ht=Number(\"0o10\")!==8;var bt=Number(\"0b10\")!==2;var gt=y(Ue,function(e){return Number(e+0+e)===0});if(ht||bt||gt){var dt=Number;var mt=/^0b[01]+$/i;var Ot=/^0o[0-7]+$/i;var wt=mt.test.bind(mt);var jt=Ot.test.bind(Ot);var St=function(e){var t;if(typeof e.valueOf===\"function\"){t=e.valueOf();if(re.primitive(t)){return t}}if(typeof e.toString===\"function\"){t=e.toString();if(re.primitive(t)){return t}}throw new TypeError(\"No default value\")};var Tt=$e.test.bind($e);var It=Je.test.bind(Je);var Et=function(){var e=function Number(t){var r;if(arguments.length>0){r=re.primitive(t)?t:St(t,\"number\")}else{r=0}if(typeof r===\"string\"){r=ce.Call(Be,r);if(wt(r)){r=parseInt(C(r,2),2)}else if(jt(r)){r=parseInt(C(r,2),8)}else if(Tt(r)||It(r)){r=NaN}}var n=this;var o=a(function(){dt.prototype.valueOf.call(n);return true});if(n instanceof e&&!o){return new dt(r)}return dt(r)};return e}();Ee(dt,Et,{});b(Et,{NaN:dt.NaN,MAX_VALUE:dt.MAX_VALUE,MIN_VALUE:dt.MIN_VALUE,NEGATIVE_INFINITY:dt.NEGATIVE_INFINITY,POSITIVE_INFINITY:dt.POSITIVE_INFINITY});Number=Et;m.redefine(S,\"Number\",Et)}var Pt=Math.pow(2,53)-1;b(Number,{MAX_SAFE_INTEGER:Pt,MIN_SAFE_INTEGER:-Pt,EPSILON:2.220446049250313e-16,parseInt:S.parseInt,parseFloat:S.parseFloat,isFinite:K,isInteger:function isInteger(e){return K(e)&&ce.ToInteger(e)===e},isSafeInteger:function isSafeInteger(e){return Number.isInteger(e)&&k(e)<=Number.MAX_SAFE_INTEGER},isNaN:X});h(Number,\"parseInt\",S.parseInt,Number.parseInt!==S.parseInt);if([,1].find(function(){return true})===1){ne(Array.prototype,\"find\",et.find)}if([,1].findIndex(function(){return true})!==0){ne(Array.prototype,\"findIndex\",et.findIndex)}var Ct=Function.bind.call(Function.bind,Object.prototype.propertyIsEnumerable);var Mt=function ensureEnumerable(e,t){if(s&&Ct(e,t)){Object.defineProperty(e,t,{enumerable:false})}};var xt=function sliceArgs(){var e=Number(this);var t=arguments.length;var r=t-e;var n=new Array(r<0?0:r);for(var o=e;o<t;++o){n[o-e]=arguments[o]}return n};var Nt=function assignTo(e){return function assignToSource(t,r){t[r]=e[r];return t}};var At=function(e,t){var r=n(Object(t));var o;if(ce.IsCallable(Object.getOwnPropertySymbols)){o=v(Object.getOwnPropertySymbols(Object(t)),Ct(t))}return p(P(r,o||[]),Nt(t),e)};var Rt={assign:function(e,t){var r=ce.ToObject(e,\"Cannot convert undefined or null to object\");return p(ce.Call(xt,1,arguments),At,r)},is:function is(e,t){return ce.SameValue(e,t)}};var _t=Object.assign&&Object.preventExtensions&&function(){var e=Object.preventExtensions({1:2});try{Object.assign(e,\"xy\")}catch(t){return e[1]===\"y\"}}();if(_t){ne(Object,\"assign\",Rt.assign)}b(Object,Rt);if(s){var kt={setPrototypeOf:function(e,r){var n;var o=function(e,t){if(!ce.TypeIsObject(e)){throw new TypeError(\"cannot set prototype on a non-object\")}if(!(t===null||ce.TypeIsObject(t))){throw new TypeError(\"can only set prototype to an object or null\"+t)}};var i=function(e,r){o(e,r);t(n,e,r);return e};try{n=e.getOwnPropertyDescriptor(e.prototype,r).set;t(n,{},null)}catch(a){if(e.prototype!=={}[r]){return}n=function(e){this[r]=e};i.polyfill=i(i({},null),e.prototype)instanceof e}return i}(Object,\"__proto__\")};b(Object,kt)}if(Object.setPrototypeOf&&Object.getPrototypeOf&&Object.getPrototypeOf(Object.setPrototypeOf({},null))!==null&&Object.getPrototypeOf(Object.create(null))===null){(function(){var e=Object.create(null);var t=Object.getPrototypeOf;var r=Object.setPrototypeOf;Object.getPrototypeOf=function(r){var n=t(r);return n===e?null:n};Object.setPrototypeOf=function(t,n){var o=n===null?e:n;return r(t,o)};Object.setPrototypeOf.polyfill=false})()}var Lt=!i(function(){return Object.keys(\"foo\")});if(!Lt){var Ft=Object.keys;ne(Object,\"keys\",function keys(e){return Ft(ce.ToObject(e))});n=Object.keys}var Dt=i(function(){return Object.keys(/a/g)});if(Dt){var zt=Object.keys;ne(Object,\"keys\",function keys(e){if(re.regex(e)){var t=[];for(var r in e){if(z(e,r)){M(t,r)}}return t}return zt(e)});n=Object.keys}if(Object.getOwnPropertyNames){var qt=!i(function(){return Object.getOwnPropertyNames(\"foo\")});if(!qt){var Wt=typeof window===\"object\"?Object.getOwnPropertyNames(window):[];var Gt=Object.getOwnPropertyNames;ne(Object,\"getOwnPropertyNames\",function getOwnPropertyNames(e){var t=ce.ToObject(e);if(g(t)===\"[object Window]\"){try{return Gt(t)}catch(r){return P([],Wt)}}return Gt(t)})}}if(Object.getOwnPropertyDescriptor){var Ht=!i(function(){return Object.getOwnPropertyDescriptor(\"foo\",\"bar\")});if(!Ht){var Vt=Object.getOwnPropertyDescriptor;ne(Object,\"getOwnPropertyDescriptor\",function getOwnPropertyDescriptor(e,t){return Vt(ce.ToObject(e),t)})}}if(Object.seal){var Bt=!i(function(){return Object.seal(\"foo\")});if(!Bt){var Ut=Object.seal;ne(Object,\"seal\",function seal(e){if(!ce.TypeIsObject(e)){return e}return Ut(e)})}}if(Object.isSealed){var $t=!i(function(){return Object.isSealed(\"foo\")});if(!$t){var Jt=Object.isSealed;ne(Object,\"isSealed\",function isSealed(e){if(!ce.TypeIsObject(e)){return true}return Jt(e)})}}if(Object.freeze){var Xt=!i(function(){return Object.freeze(\"foo\")});if(!Xt){var Kt=Object.freeze;ne(Object,\"freeze\",function freeze(e){if(!ce.TypeIsObject(e)){return e}return Kt(e)})}}if(Object.isFrozen){var Zt=!i(function(){return Object.isFrozen(\"foo\")});if(!Zt){var Yt=Object.isFrozen;ne(Object,\"isFrozen\",function isFrozen(e){if(!ce.TypeIsObject(e)){return true}return Yt(e)})}}if(Object.preventExtensions){var Qt=!i(function(){return Object.preventExtensions(\"foo\")});if(!Qt){var er=Object.preventExtensions;ne(Object,\"preventExtensions\",function preventExtensions(e){if(!ce.TypeIsObject(e)){return e}return er(e)})}}if(Object.isExtensible){var tr=!i(function(){return Object.isExtensible(\"foo\")});if(!tr){var rr=Object.isExtensible;ne(Object,\"isExtensible\",function isExtensible(e){if(!ce.TypeIsObject(e)){return false}return rr(e)})}}if(Object.getPrototypeOf){var nr=!i(function(){return Object.getPrototypeOf(\"foo\")});if(!nr){var or=Object.getPrototypeOf;ne(Object,\"getPrototypeOf\",function getPrototypeOf(e){return or(ce.ToObject(e))})}}var ir=s&&function(){var e=Object.getOwnPropertyDescriptor(RegExp.prototype,\"flags\");return e&&ce.IsCallable(e.get)}();if(s&&!ir){var ar=function flags(){if(!ce.TypeIsObject(this)){throw new TypeError(\"Method called on incompatible type: must be an object.\")}var e=\"\";if(this.global){e+=\"g\"}if(this.ignoreCase){e+=\"i\"}if(this.multiline){e+=\"m\"}if(this.unicode){e+=\"u\"}if(this.sticky){e+=\"y\"}return e};m.getter(RegExp.prototype,\"flags\",ar)}var ur=s&&a(function(){return String(new RegExp(/a/g,\"i\"))===\"/a/i\"});var fr=oe&&s&&function(){var e=/./;e[$.match]=false;return RegExp(e)===e}();var sr=a(function(){return RegExp.prototype.toString.call({source:\"abc\"})===\"/abc/\"});var cr=sr&&a(function(){return RegExp.prototype.toString.call({source:\"a\",flags:\"b\"})===\"/a/b\"});if(!sr||!cr){var lr=RegExp.prototype.toString;h(RegExp.prototype,\"toString\",function toString(){var e=ce.RequireObjectCoercible(this);if(re.regex(e)){return t(lr,e)}var r=ue(e.source);var n=ue(e.flags);return\"/\"+r+\"/\"+n},true);m.preserveToString(RegExp.prototype.toString,lr)}if(s&&(!ur||fr)){var pr=Object.getOwnPropertyDescriptor(RegExp.prototype,\"flags\").get;var vr=Object.getOwnPropertyDescriptor(RegExp.prototype,\"source\")||{};var yr=function(){return this.source};var hr=ce.IsCallable(vr.get)?vr.get:yr;var br=RegExp;var gr=function(){return function RegExp(e,t){var r=ce.IsRegExp(e);var n=this instanceof RegExp;if(!n&&r&&typeof t===\"undefined\"&&e.constructor===RegExp){return e}var o=e;var i=t;if(re.regex(e)){o=ce.Call(hr,e);i=typeof t===\"undefined\"?ce.Call(pr,e):t;return new RegExp(o,i)}else if(r){o=e.source;i=typeof t===\"undefined\"?e.flags:t}return new br(e,t)}}();Ee(br,gr,{$input:true});RegExp=gr;m.redefine(S,\"RegExp\",gr)}if(s){var dr={input:\"$_\",lastMatch:\"$&\",lastParen:\"$+\",leftContext:\"$`\",rightContext:\"$'\"};l(n(dr),function(e){if(e in RegExp&&!(dr[e]in RegExp)){m.getter(RegExp,dr[e],function get(){return RegExp[e]})}})}Ce(RegExp);var mr=1/Number.EPSILON;var Or=function roundTiesToEven(e){return e+mr-mr};var wr=Math.pow(2,-23);var jr=Math.pow(2,127)*(2-wr);var Sr=Math.pow(2,-126);var Tr=Math.E;var Ir=Math.LOG2E;var Er=Math.LOG10E;var Pr=Number.prototype.clz;delete Number.prototype.clz;var Cr={acosh:function acosh(e){var t=Number(e);if(X(t)||e<1){return NaN}if(t===1){return 0}if(t===Infinity){return t}var r=1/(t*t);if(t<2){return Y(t-1+D(1-r)*t)}var n=t/2;return Y(n+D(1-r)*n-1)+1/Ir},asinh:function asinh(e){var t=Number(e);if(t===0||!T(t)){return t}var r=k(t);var n=r*r;var o=Z(t);if(r<1){return o*Y(r+n/(D(n+1)+1))}return o*(Y(r/2+D(1+1/n)*r/2-1)+1/Ir)},atanh:function atanh(e){var t=Number(e);if(t===0){return t}if(t===-1){return-Infinity}if(t===1){return Infinity}if(X(t)||t<-1||t>1){return NaN}var r=k(t);return Z(t)*Y(2*r/(1-r))/2},cbrt:function cbrt(e){var t=Number(e);if(t===0){return t}var r=t<0;var n;if(r){t=-t}if(t===Infinity){n=Infinity}else{n=L(F(t)/3);n=(t/(n*n)+2*n)/3}return r?-n:n},clz32:function clz32(e){var t=Number(e);var r=ce.ToUint32(t);if(r===0){return 32}return Pr?ce.Call(Pr,r):31-_(F(r+.5)*Ir)},cosh:function cosh(e){var t=Number(e);if(t===0){return 1}if(X(t)){return NaN}if(!T(t)){return Infinity}var r=L(k(t)-1);return(r+1/(r*Tr*Tr))*(Tr/2)},expm1:function expm1(e){var t=Number(e);if(t===-Infinity){return-1}if(!T(t)||t===0){return t}if(k(t)>.5){return L(t)-1}var r=t;var n=0;var o=1;while(n+r!==n){n+=r;o+=1;r*=t/o}return n},hypot:function hypot(e,t){var r=0;var n=0;for(var o=0;o<arguments.length;++o){var i=k(Number(arguments[o]));if(n<i){r*=n/i*(n/i);r+=1;n=i}else{r+=i>0?i/n*(i/n):i}}return n===Infinity?Infinity:n*D(r)},log2:function log2(e){return F(e)*Ir},log10:function log10(e){return F(e)*Er},log1p:Y,sign:Z,sinh:function sinh(e){var t=Number(e);if(!T(t)||t===0){return t}var r=k(t);if(r<1){var n=Math.expm1(r);return Z(t)*n*(1+1/(n+1))/2}var o=L(r-1);return Z(t)*(o-1/(o*Tr*Tr))*(Tr/2)},tanh:function tanh(e){var t=Number(e);if(X(t)||t===0){return t}if(t>=20){return 1}if(t<=-20){return-1}return(Math.expm1(t)-Math.expm1(-t))/(L(t)+L(-t))},trunc:function trunc(e){var t=Number(e);return t<0?-_(-t):_(t)},imul:function imul(e,t){var r=ce.ToUint32(e);var n=ce.ToUint32(t);var o=r>>>16&65535;var i=r&65535;var a=n>>>16&65535;var u=n&65535;return i*u+(o*u+i*a<<16>>>0)|0},fround:function fround(e){var t=Number(e);if(t===0||t===Infinity||t===-Infinity||X(t)){return t}var r=Z(t);var n=k(t);if(n<Sr){return r*Or(n/Sr/wr)*Sr*wr}var o=(1+wr/Number.EPSILON)*n;var i=o-(o-n);if(i>jr||X(i)){return r*Infinity}return r*i}};var Mr=function withinULPDistance(e,t,r){return k(1-e/t)/Number.EPSILON<(r||8)};b(Math,Cr);h(Math,\"sinh\",Cr.sinh,Math.sinh(710)===Infinity);h(Math,\"cosh\",Cr.cosh,Math.cosh(710)===Infinity);h(Math,\"log1p\",Cr.log1p,Math.log1p(-1e-17)!==-1e-17);h(Math,\"asinh\",Cr.asinh,Math.asinh(-1e7)!==-Math.asinh(1e7));h(Math,\"asinh\",Cr.asinh,Math.asinh(1e300)===Infinity);h(Math,\"atanh\",Cr.atanh,Math.atanh(1e-300)===0);h(Math,\"tanh\",Cr.tanh,Math.tanh(-2e-17)!==-2e-17);\nh(Math,\"acosh\",Cr.acosh,Math.acosh(Number.MAX_VALUE)===Infinity);h(Math,\"acosh\",Cr.acosh,!Mr(Math.acosh(1+Number.EPSILON),Math.sqrt(2*Number.EPSILON)));h(Math,\"cbrt\",Cr.cbrt,!Mr(Math.cbrt(1e-300),1e-100));h(Math,\"sinh\",Cr.sinh,Math.sinh(-2e-17)!==-2e-17);var xr=Math.expm1(10);h(Math,\"expm1\",Cr.expm1,xr>22025.465794806718||xr<22025.465794806718);var Nr=Math.round;var Ar=Math.round(.5-Number.EPSILON/4)===0&&Math.round(-.5+Number.EPSILON/3.99)===1;var Rr=mr+1;var _r=2*mr-1;var kr=[Rr,_r].every(function(e){return Math.round(e)===e});h(Math,\"round\",function round(e){var t=_(e);var r=t===-1?-0:t+1;return e-t<.5?t:r},!Ar||!kr);m.preserveToString(Math.round,Nr);var Lr=Math.imul;if(Math.imul(4294967295,5)!==-5){Math.imul=Cr.imul;m.preserveToString(Math.imul,Lr)}if(Math.imul.length!==2){ne(Math,\"imul\",function imul(e,t){return ce.Call(Lr,Math,arguments)})}var Fr=function(){var e=S.setTimeout;if(typeof e!==\"function\"&&typeof e!==\"object\"){return}ce.IsPromise=function(e){if(!ce.TypeIsObject(e)){return false}if(typeof e._promise===\"undefined\"){return false}return true};var r=function(e){if(!ce.IsConstructor(e)){throw new TypeError(\"Bad promise constructor\")}var t=this;var r=function(e,r){if(t.resolve!==void 0||t.reject!==void 0){throw new TypeError(\"Bad Promise implementation!\")}t.resolve=e;t.reject=r};t.resolve=void 0;t.reject=void 0;t.promise=new e(r);if(!(ce.IsCallable(t.resolve)&&ce.IsCallable(t.reject))){throw new TypeError(\"Bad promise constructor\")}};var n;if(typeof window!==\"undefined\"&&ce.IsCallable(window.postMessage)){n=function(){var e=[];var t=\"zero-timeout-message\";var r=function(r){M(e,r);window.postMessage(t,\"*\")};var n=function(r){if(r.source===window&&r.data===t){r.stopPropagation();if(e.length===0){return}var n=N(e);n()}};window.addEventListener(\"message\",n,true);return r}}var o=function(){var e=S.Promise;var t=e&&e.resolve&&e.resolve();return t&&function(e){return t.then(e)}};var i=ce.IsCallable(S.setImmediate)?S.setImmediate:typeof process===\"object\"&&process.nextTick?process.nextTick:o()||(ce.IsCallable(n)?n():function(t){e(t,0)});var a=function(e){return e};var u=function(e){throw e};var f=0;var s=1;var c=2;var l=0;var p=1;var v=2;var y={};var h=function(e,t,r){i(function(){g(e,t,r)})};var g=function(e,t,r){var n,o;if(t===y){return e(r)}try{n=e(r);o=t.resolve}catch(i){n=i;o=t.reject}o(n)};var d=function(e,t){var r=e._promise;var n=r.reactionLength;if(n>0){h(r.fulfillReactionHandler0,r.reactionCapability0,t);r.fulfillReactionHandler0=void 0;r.rejectReactions0=void 0;r.reactionCapability0=void 0;if(n>1){for(var o=1,i=0;o<n;o++,i+=3){h(r[i+l],r[i+v],t);e[i+l]=void 0;e[i+p]=void 0;e[i+v]=void 0}}}r.result=t;r.state=s;r.reactionLength=0};var m=function(e,t){var r=e._promise;var n=r.reactionLength;if(n>0){h(r.rejectReactionHandler0,r.reactionCapability0,t);r.fulfillReactionHandler0=void 0;r.rejectReactions0=void 0;r.reactionCapability0=void 0;if(n>1){for(var o=1,i=0;o<n;o++,i+=3){h(r[i+p],r[i+v],t);e[i+l]=void 0;e[i+p]=void 0;e[i+v]=void 0}}}r.result=t;r.state=c;r.reactionLength=0};var O=function(e){var t=false;var r=function(r){var n;if(t){return}t=true;if(r===e){return m(e,new TypeError(\"Self resolution\"))}if(!ce.TypeIsObject(r)){return d(e,r)}try{n=r.then}catch(o){return m(e,o)}if(!ce.IsCallable(n)){return d(e,r)}i(function(){j(e,r,n)})};var n=function(r){if(t){return}t=true;return m(e,r)};return{resolve:r,reject:n}};var w=function(e,r,n,o){if(e===I){t(e,r,n,o,y)}else{t(e,r,n,o)}};var j=function(e,t,r){var n=O(e);var o=n.resolve;var i=n.reject;try{w(r,t,o,i)}catch(a){i(a)}};var T,I;var E=function(){var e=function Promise(t){if(!(this instanceof e)){throw new TypeError('Constructor Promise requires \"new\"')}if(this&&this._promise){throw new TypeError(\"Bad construction\")}if(!ce.IsCallable(t)){throw new TypeError(\"not a valid resolver\")}var r=Ae(this,e,T,{_promise:{result:void 0,state:f,reactionLength:0,fulfillReactionHandler0:void 0,rejectReactionHandler0:void 0,reactionCapability0:void 0}});var n=O(r);var o=n.reject;try{t(n.resolve,o)}catch(i){o(i)}return r};return e}();T=E.prototype;var P=function(e,t,r,n){var o=false;return function(i){if(o){return}o=true;t[e]=i;if(--n.count===0){var a=r.resolve;a(t)}}};var C=function(e,t,r){var n=e.iterator;var o=[];var i={count:1};var a,u;var f=0;while(true){try{a=ce.IteratorStep(n);if(a===false){e.done=true;break}u=a.value}catch(s){e.done=true;throw s}o[f]=void 0;var c=t.resolve(u);var l=P(f,o,r,i);i.count+=1;w(c.then,c,l,r.reject);f+=1}if(--i.count===0){var p=r.resolve;p(o)}return r.promise};var x=function(e,t,r){var n=e.iterator;var o,i,a;while(true){try{o=ce.IteratorStep(n);if(o===false){e.done=true;break}i=o.value}catch(u){e.done=true;throw u}a=t.resolve(i);w(a.then,a,r.resolve,r.reject)}return r.promise};b(E,{all:function all(e){var t=this;if(!ce.TypeIsObject(t)){throw new TypeError(\"Promise is not object\")}var n=new r(t);var o,i;try{o=ce.GetIterator(e);i={iterator:o,done:false};return C(i,t,n)}catch(a){var u=a;if(i&&!i.done){try{ce.IteratorClose(o,true)}catch(f){u=f}}var s=n.reject;s(u);return n.promise}},race:function race(e){var t=this;if(!ce.TypeIsObject(t)){throw new TypeError(\"Promise is not object\")}var n=new r(t);var o,i;try{o=ce.GetIterator(e);i={iterator:o,done:false};return x(i,t,n)}catch(a){var u=a;if(i&&!i.done){try{ce.IteratorClose(o,true)}catch(f){u=f}}var s=n.reject;s(u);return n.promise}},reject:function reject(e){var t=this;if(!ce.TypeIsObject(t)){throw new TypeError(\"Bad promise constructor\")}var n=new r(t);var o=n.reject;o(e);return n.promise},resolve:function resolve(e){var t=this;if(!ce.TypeIsObject(t)){throw new TypeError(\"Bad promise constructor\")}if(ce.IsPromise(e)){var n=e.constructor;if(n===t){return e}}var o=new r(t);var i=o.resolve;i(e);return o.promise}});b(T,{\"catch\":function(e){return this.then(null,e)},then:function then(e,t){var n=this;if(!ce.IsPromise(n)){throw new TypeError(\"not a promise\")}var o=ce.SpeciesConstructor(n,E);var i;var b=arguments.length>2&&arguments[2]===y;if(b&&o===E){i=y}else{i=new r(o)}var g=ce.IsCallable(e)?e:a;var d=ce.IsCallable(t)?t:u;var m=n._promise;var O;if(m.state===f){if(m.reactionLength===0){m.fulfillReactionHandler0=g;m.rejectReactionHandler0=d;m.reactionCapability0=i}else{var w=3*(m.reactionLength-1);m[w+l]=g;m[w+p]=d;m[w+v]=i}m.reactionLength+=1}else if(m.state===s){O=m.result;h(g,i,O)}else if(m.state===c){O=m.result;h(d,i,O)}else{throw new TypeError(\"unexpected Promise state\")}return i.promise}});y=new r(E);I=T.then;return E}();if(S.Promise){delete S.Promise.accept;delete S.Promise.defer;delete S.Promise.prototype.chain}if(typeof Fr===\"function\"){b(S,{Promise:Fr});var Dr=w(S.Promise,function(e){return e.resolve(42).then(function(){})instanceof e});var zr=!i(function(){return S.Promise.reject(42).then(null,5).then(null,W)});var qr=i(function(){return S.Promise.call(3,W)});var Wr=function(e){var t=e.resolve(5);t.constructor={};var r=e.resolve(t);try{r.then(null,W).then(null,W)}catch(n){return true}return t===r}(S.Promise);var Gr=s&&function(){var e=0;var t=Object.defineProperty({},\"then\",{get:function(){e+=1}});Promise.resolve(t);return e===1}();var Hr=function BadResolverPromise(e){var t=new Promise(e);e(3,function(){});this.then=t.then;this.constructor=BadResolverPromise};Hr.prototype=Promise.prototype;Hr.all=Promise.all;var Vr=a(function(){return!!Hr.all([1,2])});if(!Dr||!zr||!qr||Wr||!Gr||Vr){Promise=Fr;ne(S,\"Promise\",Fr)}if(Promise.all.length!==1){var Br=Promise.all;ne(Promise,\"all\",function all(e){return ce.Call(Br,this,arguments)})}if(Promise.race.length!==1){var Ur=Promise.race;ne(Promise,\"race\",function race(e){return ce.Call(Ur,this,arguments)})}if(Promise.resolve.length!==1){var $r=Promise.resolve;ne(Promise,\"resolve\",function resolve(e){return ce.Call($r,this,arguments)})}if(Promise.reject.length!==1){var Jr=Promise.reject;ne(Promise,\"reject\",function reject(e){return ce.Call(Jr,this,arguments)})}Mt(Promise,\"all\");Mt(Promise,\"race\");Mt(Promise,\"resolve\");Mt(Promise,\"reject\");Ce(Promise)}var Xr=function(e){var t=n(p(e,function(e,t){e[t]=true;return e},{}));return e.join(\":\")===t.join(\":\")};var Kr=Xr([\"z\",\"a\",\"bb\"]);var Zr=Xr([\"z\",1,\"a\",\"3\",2]);if(s){var Yr=function fastkey(e,t){if(!t&&!Kr){return null}if(se(e)){return\"^\"+ce.ToString(e)}else if(typeof e===\"string\"){return\"$\"+e}else if(typeof e===\"number\"){if(!Zr){return\"n\"+e}return e}else if(typeof e===\"boolean\"){return\"b\"+e}return null};var Qr=function emptyObject(){return Object.create?Object.create(null):{}};var en=function addIterableToMap(e,n,o){if(r(o)||re.string(o)){l(o,function(e){if(!ce.TypeIsObject(e)){throw new TypeError(\"Iterator value \"+e+\" is not an entry object\")}n.set(e[0],e[1])})}else if(o instanceof e){t(e.prototype.forEach,o,function(e,t){n.set(t,e)})}else{var i,a;if(!se(o)){a=n.set;if(!ce.IsCallable(a)){throw new TypeError(\"bad map\")}i=ce.GetIterator(o)}if(typeof i!==\"undefined\"){while(true){var u=ce.IteratorStep(i);if(u===false){break}var f=u.value;try{if(!ce.TypeIsObject(f)){throw new TypeError(\"Iterator value \"+f+\" is not an entry object\")}t(a,n,f[0],f[1])}catch(s){ce.IteratorClose(i,true);throw s}}}}};var tn=function addIterableToSet(e,n,o){if(r(o)||re.string(o)){l(o,function(e){n.add(e)})}else if(o instanceof e){t(e.prototype.forEach,o,function(e){n.add(e)})}else{var i,a;if(!se(o)){a=n.add;if(!ce.IsCallable(a)){throw new TypeError(\"bad set\")}i=ce.GetIterator(o)}if(typeof i!==\"undefined\"){while(true){var u=ce.IteratorStep(i);if(u===false){break}var f=u.value;try{t(a,n,f)}catch(s){ce.IteratorClose(i,true);throw s}}}}};var rn={Map:function(){var e={};var r=function MapEntry(e,t){this.key=e;this.value=t;this.next=null;this.prev=null};r.prototype.isRemoved=function isRemoved(){return this.key===e};var n=function isMap(e){return!!e._es6map};var o=function requireMapSlot(e,t){if(!ce.TypeIsObject(e)||!n(e)){throw new TypeError(\"Method Map.prototype.\"+t+\" called on incompatible receiver \"+ce.ToString(e))}};var i=function MapIterator(e,t){o(e,\"[[MapIterator]]\");this.head=e._head;this.i=this.head;this.kind=t};i.prototype={isMapIterator:true,next:function next(){if(!this.isMapIterator){throw new TypeError(\"Not a MapIterator\")}var e=this.i;var t=this.kind;var r=this.head;if(typeof this.i===\"undefined\"){return Ke()}while(e.isRemoved()&&e!==r){e=e.prev}var n;while(e.next!==r){e=e.next;if(!e.isRemoved()){if(t===\"key\"){n=e.key}else if(t===\"value\"){n=e.value}else{n=[e.key,e.value]}this.i=e;return Ke(n)}}this.i=void 0;return Ke()}};Me(i.prototype);var a;var u=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires \"new\"')}if(this&&this._es6map){throw new TypeError(\"Bad construction\")}var e=Ae(this,Map,a,{_es6map:true,_head:null,_map:G?new G:null,_size:0,_storage:Qr()});var t=new r(null,null);t.next=t.prev=t;e._head=t;if(arguments.length>0){en(Map,e,arguments[0])}return e};a=u.prototype;m.getter(a,\"size\",function(){if(typeof this._size===\"undefined\"){throw new TypeError(\"size method called on incompatible Map\")}return this._size});b(a,{get:function get(e){o(this,\"get\");var t;var r=Yr(e,true);if(r!==null){t=this._storage[r];if(t){return t.value}else{return}}if(this._map){t=V.call(this._map,e);if(t){return t.value}else{return}}var n=this._head;var i=n;while((i=i.next)!==n){if(ce.SameValueZero(i.key,e)){return i.value}}},has:function has(e){o(this,\"has\");var t=Yr(e,true);if(t!==null){return typeof this._storage[t]!==\"undefined\"}if(this._map){return B.call(this._map,e)}var r=this._head;var n=r;while((n=n.next)!==r){if(ce.SameValueZero(n.key,e)){return true}}return false},set:function set(e,t){o(this,\"set\");var n=this._head;var i=n;var a;var u=Yr(e,true);if(u!==null){if(typeof this._storage[u]!==\"undefined\"){this._storage[u].value=t;return this}else{a=this._storage[u]=new r(e,t);i=n.prev}}else if(this._map){if(B.call(this._map,e)){V.call(this._map,e).value=t}else{a=new r(e,t);U.call(this._map,e,a);i=n.prev}}while((i=i.next)!==n){if(ce.SameValueZero(i.key,e)){i.value=t;return this}}a=a||new r(e,t);if(ce.SameValue(-0,e)){a.key=+0}a.next=this._head;a.prev=this._head.prev;a.prev.next=a;a.next.prev=a;this._size+=1;return this},\"delete\":function(t){o(this,\"delete\");var r=this._head;var n=r;var i=Yr(t,true);if(i!==null){if(typeof this._storage[i]===\"undefined\"){return false}n=this._storage[i].prev;delete this._storage[i]}else if(this._map){if(!B.call(this._map,t)){return false}n=V.call(this._map,t).prev;H.call(this._map,t)}while((n=n.next)!==r){if(ce.SameValueZero(n.key,t)){n.key=e;n.value=e;n.prev.next=n.next;n.next.prev=n.prev;this._size-=1;return true}}return false},clear:function clear(){o(this,\"clear\");this._map=G?new G:null;this._size=0;this._storage=Qr();var t=this._head;var r=t;var n=r.next;while((r=n)!==t){r.key=e;r.value=e;n=r.next;r.next=r.prev=t}t.next=t.prev=t},keys:function keys(){o(this,\"keys\");return new i(this,\"key\")},values:function values(){o(this,\"values\");return new i(this,\"value\")},entries:function entries(){o(this,\"entries\");return new i(this,\"key+value\")},forEach:function forEach(e){o(this,\"forEach\");var r=arguments.length>1?arguments[1]:null;var n=this.entries();for(var i=n.next();!i.done;i=n.next()){if(r){t(e,r,i.value[1],i.value[0],this)}else{e(i.value[1],i.value[0],this)}}}});Me(a,a.entries);return u}(),Set:function(){var e=function isSet(e){return e._es6set&&typeof e._storage!==\"undefined\"};var r=function requireSetSlot(t,r){if(!ce.TypeIsObject(t)||!e(t)){throw new TypeError(\"Set.prototype.\"+r+\" called on incompatible receiver \"+ce.ToString(t))}};var o;var i=function Set(){if(!(this instanceof Set)){throw new TypeError('Constructor Set requires \"new\"')}if(this&&this._es6set){throw new TypeError(\"Bad construction\")}var e=Ae(this,Set,o,{_es6set:true,\"[[SetData]]\":null,_storage:Qr()});if(!e._es6set){throw new TypeError(\"bad set\")}if(arguments.length>0){tn(Set,e,arguments[0])}return e};o=i.prototype;var a=function(e){var t=e;if(t===\"^null\"){return null}else if(t===\"^undefined\"){return void 0}else{var r=t.charAt(0);if(r===\"$\"){return C(t,1)}else if(r===\"n\"){return+C(t,1)}else if(r===\"b\"){return t===\"btrue\"}}return+t};var u=function ensureMap(e){if(!e[\"[[SetData]]\"]){var t=new rn.Map;e[\"[[SetData]]\"]=t;l(n(e._storage),function(e){var r=a(e);t.set(r,r)});e[\"[[SetData]]\"]=t}e._storage=null};m.getter(i.prototype,\"size\",function(){r(this,\"size\");if(this._storage){return n(this._storage).length}u(this);return this[\"[[SetData]]\"].size});b(i.prototype,{has:function has(e){r(this,\"has\");var t;if(this._storage&&(t=Yr(e))!==null){return!!this._storage[t]}u(this);return this[\"[[SetData]]\"].has(e)},add:function add(e){r(this,\"add\");var t;if(this._storage&&(t=Yr(e))!==null){this._storage[t]=true;return this}u(this);this[\"[[SetData]]\"].set(e,e);return this},\"delete\":function(e){r(this,\"delete\");var t;if(this._storage&&(t=Yr(e))!==null){var n=z(this._storage,t);return delete this._storage[t]&&n}u(this);return this[\"[[SetData]]\"][\"delete\"](e)},clear:function clear(){r(this,\"clear\");if(this._storage){this._storage=Qr()}if(this[\"[[SetData]]\"]){this[\"[[SetData]]\"].clear()}},values:function values(){r(this,\"values\");u(this);return new f(this[\"[[SetData]]\"].values())},entries:function entries(){r(this,\"entries\");u(this);return new f(this[\"[[SetData]]\"].entries())},forEach:function forEach(e){r(this,\"forEach\");var n=arguments.length>1?arguments[1]:null;var o=this;u(o);this[\"[[SetData]]\"].forEach(function(r,i){if(n){t(e,n,i,i,o)}else{e(i,i,o)}})}});h(i.prototype,\"keys\",i.prototype.values,true);Me(i.prototype,i.prototype.values);var f=function SetIterator(e){this.it=e};f.prototype={isSetIterator:true,next:function next(){if(!this.isSetIterator){throw new TypeError(\"Not a SetIterator\")}return this.it.next()}};Me(f.prototype);return i}()};var nn=S.Set&&!Set.prototype[\"delete\"]&&Set.prototype.remove&&Set.prototype.items&&Set.prototype.map&&Array.isArray((new Set).keys);if(nn){S.Set=rn.Set}if(S.Map||S.Set){var on=a(function(){return new Map([[1,2]]).get(1)===2});if(!on){S.Map=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires \"new\"')}var e=new G;if(arguments.length>0){en(Map,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,S.Map.prototype);return e};S.Map.prototype=O(G.prototype);h(S.Map.prototype,\"constructor\",S.Map,true);m.preserveToString(S.Map,G)}var an=new Map;var un=function(){var e=new Map([[1,0],[2,0],[3,0],[4,0]]);e.set(-0,e);return e.get(0)===e&&e.get(-0)===e&&e.has(0)&&e.has(-0)}();var fn=an.set(1,2)===an;if(!un||!fn){ne(Map.prototype,\"set\",function set(e,r){t(U,this,e===0?0:e,r);return this})}if(!un){b(Map.prototype,{get:function get(e){return t(V,this,e===0?0:e)},has:function has(e){return t(B,this,e===0?0:e)}},true);m.preserveToString(Map.prototype.get,V);m.preserveToString(Map.prototype.has,B)}var sn=new Set;var cn=Set.prototype[\"delete\"]&&Set.prototype.add&&Set.prototype.has&&function(e){e[\"delete\"](0);e.add(-0);return!e.has(0)}(sn);var ln=sn.add(1)===sn;if(!cn||!ln){var pn=Set.prototype.add;Set.prototype.add=function add(e){t(pn,this,e===0?0:e);return this};m.preserveToString(Set.prototype.add,pn)}if(!cn){var vn=Set.prototype.has;Set.prototype.has=function has(e){return t(vn,this,e===0?0:e)};m.preserveToString(Set.prototype.has,vn);var yn=Set.prototype[\"delete\"];Set.prototype[\"delete\"]=function SetDelete(e){return t(yn,this,e===0?0:e)};m.preserveToString(Set.prototype[\"delete\"],yn)}var hn=w(S.Map,function(e){var t=new e([]);t.set(42,42);return t instanceof e});var bn=Object.setPrototypeOf&&!hn;var gn=function(){try{return!(S.Map()instanceof S.Map)}catch(e){return e instanceof TypeError}}();if(S.Map.length!==0||bn||!gn){S.Map=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires \"new\"')}var e=new G;if(arguments.length>0){en(Map,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,Map.prototype);return e};S.Map.prototype=G.prototype;h(S.Map.prototype,\"constructor\",S.Map,true);m.preserveToString(S.Map,G)}var dn=w(S.Set,function(e){var t=new e([]);t.add(42,42);return t instanceof e});var mn=Object.setPrototypeOf&&!dn;var On=function(){try{return!(S.Set()instanceof S.Set)}catch(e){return e instanceof TypeError}}();if(S.Set.length!==0||mn||!On){var wn=S.Set;S.Set=function Set(){if(!(this instanceof Set)){throw new TypeError('Constructor Set requires \"new\"')}var e=new wn;if(arguments.length>0){tn(Set,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,Set.prototype);return e};S.Set.prototype=wn.prototype;h(S.Set.prototype,\"constructor\",S.Set,true);m.preserveToString(S.Set,wn)}var jn=new S.Map;var Sn=!a(function(){return jn.keys().next().done});if(typeof S.Map.prototype.clear!==\"function\"||(new S.Set).size!==0||jn.size!==0||typeof S.Map.prototype.keys!==\"function\"||typeof S.Set.prototype.keys!==\"function\"||typeof S.Map.prototype.forEach!==\"function\"||typeof S.Set.prototype.forEach!==\"function\"||u(S.Map)||u(S.Set)||typeof jn.keys().next!==\"function\"||Sn||!hn){b(S,{Map:rn.Map,Set:rn.Set},true)}if(S.Set.prototype.keys!==S.Set.prototype.values){h(S.Set.prototype,\"keys\",S.Set.prototype.values,true)}Me(Object.getPrototypeOf((new S.Map).keys()));Me(Object.getPrototypeOf((new S.Set).keys()));if(c&&S.Set.prototype.has.name!==\"has\"){var Tn=S.Set.prototype.has;ne(S.Set.prototype,\"has\",function has(e){return t(Tn,this,e)})}}b(S,rn);Ce(S.Map);Ce(S.Set)}var In=function throwUnlessTargetIsObject(e){if(!ce.TypeIsObject(e)){throw new TypeError(\"target must be an object\")}};var En={apply:function apply(){return ce.Call(ce.Call,null,arguments)},construct:function construct(e,t){if(!ce.IsConstructor(e)){throw new TypeError(\"First argument must be a constructor.\")}var r=arguments.length>2?arguments[2]:e;if(!ce.IsConstructor(r)){throw new TypeError(\"new.target must be a constructor.\")}return ce.Construct(e,t,r,\"internal\")},deleteProperty:function deleteProperty(e,t){In(e);if(s){var r=Object.getOwnPropertyDescriptor(e,t);if(r&&!r.configurable){return false}}return delete e[t]},has:function has(e,t){In(e);return t in e}};if(Object.getOwnPropertyNames){Object.assign(En,{ownKeys:function ownKeys(e){In(e);var t=Object.getOwnPropertyNames(e);if(ce.IsCallable(Object.getOwnPropertySymbols)){x(t,Object.getOwnPropertySymbols(e))}return t}})}var Pn=function ConvertExceptionToBoolean(e){return!i(e)};if(Object.preventExtensions){Object.assign(En,{isExtensible:function isExtensible(e){In(e);return Object.isExtensible(e)},preventExtensions:function preventExtensions(e){In(e);return Pn(function(){return Object.preventExtensions(e)})}})}if(s){var Cn=function get(e,t,r){var n=Object.getOwnPropertyDescriptor(e,t);if(!n){var o=Object.getPrototypeOf(e);if(o===null){return void 0}return Cn(o,t,r)}if(\"value\"in n){return n.value}if(n.get){return ce.Call(n.get,r)}return void 0};var Mn=function set(e,r,n,o){var i=Object.getOwnPropertyDescriptor(e,r);if(!i){var a=Object.getPrototypeOf(e);if(a!==null){return Mn(a,r,n,o)}i={value:void 0,writable:true,enumerable:true,configurable:true}}if(\"value\"in i){if(!i.writable){return false}if(!ce.TypeIsObject(o)){return false}var u=Object.getOwnPropertyDescriptor(o,r);if(u){return ae.defineProperty(o,r,{value:n})}else{return ae.defineProperty(o,r,{value:n,writable:true,enumerable:true,configurable:true})}}if(i.set){t(i.set,o,n);return true}return false};Object.assign(En,{defineProperty:function defineProperty(e,t,r){In(e);return Pn(function(){return Object.defineProperty(e,t,r)})},getOwnPropertyDescriptor:function getOwnPropertyDescriptor(e,t){In(e);return Object.getOwnPropertyDescriptor(e,t)},get:function get(e,t){In(e);var r=arguments.length>2?arguments[2]:e;return Cn(e,t,r)},set:function set(e,t,r){In(e);var n=arguments.length>3?arguments[3]:e;return Mn(e,t,r,n)}})}if(Object.getPrototypeOf){var xn=Object.getPrototypeOf;En.getPrototypeOf=function getPrototypeOf(e){In(e);return xn(e)}}if(Object.setPrototypeOf&&En.getPrototypeOf){var Nn=function(e,t){var r=t;while(r){if(e===r){return true}r=En.getPrototypeOf(r)}return false};Object.assign(En,{setPrototypeOf:function setPrototypeOf(e,t){In(e);if(t!==null&&!ce.TypeIsObject(t)){throw new TypeError(\"proto must be an object or null\")}if(t===ae.getPrototypeOf(e)){return true}if(ae.isExtensible&&!ae.isExtensible(e)){return false}if(Nn(e,t)){return false}Object.setPrototypeOf(e,t);return true}})}var An=function(e,t){if(!ce.IsCallable(S.Reflect[e])){h(S.Reflect,e,t)}else{var r=a(function(){S.Reflect[e](1);S.Reflect[e](NaN);S.Reflect[e](true);return true});if(r){ne(S.Reflect,e,t)}}};Object.keys(En).forEach(function(e){An(e,En[e])});var Rn=S.Reflect.getPrototypeOf;if(c&&Rn&&Rn.name!==\"getPrototypeOf\"){ne(S.Reflect,\"getPrototypeOf\",function getPrototypeOf(e){return t(Rn,S.Reflect,e)})}if(S.Reflect.setPrototypeOf){if(a(function(){S.Reflect.setPrototypeOf(1,{});return true})){ne(S.Reflect,\"setPrototypeOf\",En.setPrototypeOf)}}if(S.Reflect.defineProperty){if(!a(function(){var e=!S.Reflect.defineProperty(1,\"test\",{value:1});var t=typeof Object.preventExtensions!==\"function\"||!S.Reflect.defineProperty(Object.preventExtensions({}),\"test\",{});return e&&t})){ne(S.Reflect,\"defineProperty\",En.defineProperty)}}if(S.Reflect.construct){if(!a(function(){var e=function F(){};return S.Reflect.construct(function(){},[],e)instanceof e})){ne(S.Reflect,\"construct\",En.construct)}}if(String(new Date(NaN))!==\"Invalid Date\"){var _n=Date.prototype.toString;var kn=function toString(){var e=+this;if(e!==e){return\"Invalid Date\"}return ce.Call(_n,this)};ne(Date.prototype,\"toString\",kn)}var Ln={anchor:function anchor(e){return ce.CreateHTML(this,\"a\",\"name\",e)},big:function big(){return ce.CreateHTML(this,\"big\",\"\",\"\")},blink:function blink(){return ce.CreateHTML(this,\"blink\",\"\",\"\")},bold:function bold(){return ce.CreateHTML(this,\"b\",\"\",\"\")},fixed:function fixed(){return ce.CreateHTML(this,\"tt\",\"\",\"\")},fontcolor:function fontcolor(e){return ce.CreateHTML(this,\"font\",\"color\",e)},fontsize:function fontsize(e){return ce.CreateHTML(this,\"font\",\"size\",e)},italics:function italics(){return ce.CreateHTML(this,\"i\",\"\",\"\")},link:function link(e){return ce.CreateHTML(this,\"a\",\"href\",e)},small:function small(){return ce.CreateHTML(this,\"small\",\"\",\"\")},strike:function strike(){return ce.CreateHTML(this,\"strike\",\"\",\"\")},sub:function sub(){return ce.CreateHTML(this,\"sub\",\"\",\"\")},sup:function sub(){return ce.CreateHTML(this,\"sup\",\"\",\"\")}};l(Object.keys(Ln),function(e){var r=String.prototype[e];var n=false;if(ce.IsCallable(r)){var o=t(r,\"\",' \" ');var i=P([],o.match(/\"/g)).length;n=o!==o.toLowerCase()||i>2}else{n=true}if(n){ne(String.prototype,e,Ln[e])}});var Fn=function(){if(!oe){return false}var e=typeof JSON===\"object\"&&typeof JSON.stringify===\"function\"?JSON.stringify:null;if(!e){return false}if(typeof e($())!==\"undefined\"){return true}if(e([$()])!==\"[null]\"){return true}var t={a:$()};t[$()]=true;if(e(t)!==\"{}\"){return true}return false}();var Dn=a(function(){if(!oe){return true}return JSON.stringify(Object($()))===\"{}\"&&JSON.stringify([Object($())])===\"[{}]\"});if(Fn||!Dn){var zn=JSON.stringify;ne(JSON,\"stringify\",function stringify(e){if(typeof e===\"symbol\"){return}var n;if(arguments.length>1){n=arguments[1]}var o=[e];if(!r(n)){var i=ce.IsCallable(n)?n:null;var a=function(e,r){var n=i?t(i,this,e,r):r;if(typeof n!==\"symbol\"){if(re.symbol(n)){return Nt({})(n)}else{return n}}};o.push(a)}else{o.push(n)}if(arguments.length>2){o.push(arguments[2])}return zn.apply(this,o)})}return S});\n/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */\n!function(e,t){\"use strict\";\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(ie,e){\"use strict\";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return\"function\"==typeof e&&\"number\"!=typeof e.nodeType&&\"function\"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement(\"script\");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?n[i.call(e)]||\"object\":typeof e}var t=\"3.7.1\",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&\"length\"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&0<t&&t-1 in e)}function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}ce.fn=ce.prototype={jquery:t,constructor:ce,length:0,toArray:function(){return ae.call(this)},get:function(e){return null==e?ae.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=ce.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return ce.each(this,e)},map:function(n){return this.pushStack(ce.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(ae.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ce.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(ce.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:oe.sort,splice:oe.splice},ce.extend=ce.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||v(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],\"__proto__\"!==t&&a!==r&&(l&&r&&(ce.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||ce.isPlainObject(n)?n:{},i=!1,a[t]=ce.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},ce.extend({expando:\"jQuery\"+(t+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==i.call(e))&&(!(t=r(e))||\"function\"==typeof(n=ue.call(t,\"constructor\")&&t.constructor)&&o.call(n)===a)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){m(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(c(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},text:function(e){var t,n=\"\",r=0,i=e.nodeType;if(!i)while(t=e[r++])n+=ce.text(t);return 1===i||11===i?e.textContent:9===i?e.documentElement.textContent:3===i||4===i?e.nodeValue:n},makeArray:function(e,t){var n=t||[];return null!=e&&(c(Object(e))?ce.merge(n,\"string\"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},isXMLDoc:function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!l.test(t||n&&n.nodeName||\"HTML\")},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(c(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:le}),\"function\"==typeof Symbol&&(ce.fn[Symbol.iterator]=oe[Symbol.iterator]),ce.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){n[\"[object \"+t+\"]\"]=t.toLowerCase()});var pe=oe.pop,de=oe.sort,he=oe.splice,ge=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",ve=new RegExp(\"^\"+ge+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ge+\"+$\",\"g\");ce.contains=function(e,t){var n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(e.contains?e.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))};var f=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g;function p(e,t){return t?\"\\0\"===e?\"\\ufffd\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e}ce.escapeSelector=function(e){return(e+\"\").replace(f,p)};var ye=C,me=s;!function(){var e,b,w,o,a,T,r,C,d,i,k=me,S=ce.expando,E=0,n=0,s=W(),c=W(),u=W(),h=W(),l=function(e,t){return e===t&&(a=!0),0},f=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",t=\"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\"+ge+\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",p=\"\\\\[\"+ge+\"*(\"+t+\")(?:\"+ge+\"*([*^$|!~]?=)\"+ge+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+t+\"))|)\"+ge+\"*\\\\]\",g=\":(\"+t+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+p+\")*)|.*)\\\\)|)\",v=new RegExp(ge+\"+\",\"g\"),y=new RegExp(\"^\"+ge+\"*,\"+ge+\"*\"),m=new RegExp(\"^\"+ge+\"*([>+~]|\"+ge+\")\"+ge+\"*\"),x=new RegExp(ge+\"|>\"),j=new RegExp(g),A=new RegExp(\"^\"+t+\"$\"),D={ID:new RegExp(\"^#(\"+t+\")\"),CLASS:new RegExp(\"^\\\\.(\"+t+\")\"),TAG:new RegExp(\"^(\"+t+\"|[*])\"),ATTR:new RegExp(\"^\"+p),PSEUDO:new RegExp(\"^\"+g),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ge+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ge+\"*(?:([+-]|)\"+ge+\"*(\\\\d+)|))\"+ge+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+f+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ge+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ge+\"*((?:-\\\\d)?\\\\d*)\"+ge+\"*\\\\)|)(?=[^-]|$)\",\"i\")},N=/^(?:input|select|textarea|button)$/i,q=/^h\\d$/i,L=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,H=/[+~]/,O=new RegExp(\"\\\\\\\\[\\\\da-fA-F]{1,6}\"+ge+\"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\",\"g\"),P=function(e,t){var n=\"0x\"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,\"fieldset\")},{dir:\"parentNode\",next:\"legend\"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],\"string\"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+\" \"]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute(\"id\"))?s=ce.escapeSelector(s):e.setAttribute(\"id\",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?\"#\"+s:\":scope\")+\" \"+Q(l[o]);c=l.join(\",\")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute(\"id\")}}}return re(t.replace(ve,\"$1\"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+\" \")>b.cacheLength&&delete e[r.shift()],e[t+\" \"]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,\"input\")&&e.type===t}}function _(t){return function(e){return(fe(e,\"input\")||fe(e,\"button\"))&&e.type===t}}function z(t){return function(e){return\"form\"in e?e.parentNode&&!1===e.disabled?\"label\"in e?\"label\"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:\"label\"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener(\"unload\",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,\"*\")}),le.scope=$(function(){return T.querySelectorAll(\":scope\")}),le.cssHas=$(function(){try{return T.querySelector(\":has(*,:jqfake)\"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute(\"id\")===t}},b.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return t&&t.value===n}},b.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML=\"<a id='\"+S+\"' href='' disabled='disabled'></a><select id='\"+S+\"-\\r\\\\' disabled='disabled'><option selected=''></option></select>\",e.querySelectorAll(\"[selected]\").length||d.push(\"\\\\[\"+ge+\"*(?:value|\"+f+\")\"),e.querySelectorAll(\"[id~=\"+S+\"-]\").length||d.push(\"~=\"),e.querySelectorAll(\"a#\"+S+\"+*\").length||d.push(\".#.+[+~]\"),e.querySelectorAll(\":checked\").length||d.push(\":checked\"),(t=T.createElement(\"input\")).setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&d.push(\":enabled\",\":disabled\"),(t=T.createElement(\"input\")).setAttribute(\"name\",\"\"),e.appendChild(t),e.querySelectorAll(\"[name='']\").length||d.push(\"\\\\[\"+ge+\"*name\"+ge+\"*=\"+ge+\"*(?:''|\\\"\\\")\")}),le.cssHas||d.push(\":has\"),d=d.length&&new RegExp(d.join(\"|\")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+\" \"]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0<I(t,T,null,[e]).length},I.contains=function(e,t){return(e.ownerDocument||e)!=T&&V(e),ce.contains(e,t)},I.attr=function(e,t){(e.ownerDocument||e)!=T&&V(e);var n=b.attrHandle[t.toLowerCase()],r=n&&ue.call(b.attrHandle,t.toLowerCase())?n(e,t,!C):void 0;return void 0!==r?r:e.getAttribute(t)},I.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},ce.uniqueSort=function(e){var t,n=[],r=0,i=0;if(a=!le.sortStable,o=!le.sortStable&&ae.call(e,0),de.call(e,l),a){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)he.call(e,n[r],1)}return o=null,e},ce.fn.uniqueSort=function(){return this.pushStack(ce.uniqueSort(ae.apply(this)))},(b=ce.expr={cacheLength:50,createPseudo:F,match:D,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||\"\").replace(O,P),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+\" \"];return t||(t=new RegExp(\"(^|\"+ge+\")\"+e+\"(\"+ge+\"|$)\"))&&s(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?\"!=\"===r:!r||(t+=\"\",\"=\"===r?t===i:\"!=\"===r?t!==i:\"^=\"===r?i&&0===t.indexOf(i):\"*=\"===r?i&&-1<t.indexOf(i):\"$=\"===r?i&&t.slice(-i.length)===i:\"~=\"===r?-1<(\" \"+t.replace(v,\" \")+\" \").indexOf(i):\"|=\"===r&&(t===i||t.slice(0,i.length+1)===i+\"-\"))}},CHILD:function(d,e,t,h,g){var v=\"nth\"!==d.slice(0,3),y=\"last\"!==d.slice(-4),m=\"of-type\"===e;return 1===h&&0===g?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u=v!==y?\"nextSibling\":\"previousSibling\",l=e.parentNode,c=m&&e.nodeName.toLowerCase(),f=!n&&!m,p=!1;if(l){if(v){while(u){o=e;while(o=o[u])if(m?fe(o,c):1===o.nodeType)return!1;s=u=\"only\"===d&&!s&&\"nextSibling\"}return!0}if(s=[y?l.firstChild:l.lastChild],y&&f){p=(a=(r=(i=l[S]||(l[S]={}))[d]||[])[0]===E&&r[1])&&r[2],o=a&&l.childNodes[a];while(o=++a&&o&&o[u]||(p=a=0)||s.pop())if(1===o.nodeType&&++p&&o===e){i[d]=[E,a,p];break}}else if(f&&(p=a=(r=(i=e[S]||(e[S]={}))[d]||[])[0]===E&&r[1]),!1===p)while(o=++a&&o&&o[u]||(p=a=0)||s.pop())if((m?fe(o,c):1===o.nodeType)&&++p&&(f&&((i=o[S]||(o[S]={}))[d]=[E,p]),o===e))break;return(p-=g)===h||p%h==0&&0<=p/h}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||I.error(\"unsupported pseudo: \"+e);return a[S]?a(o):1<a.length?(t=[e,e,\"\",o],b.setFilters.hasOwnProperty(e.toLowerCase())?F(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=se.call(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:F(function(e){var r=[],i=[],s=ne(e.replace(ve,\"$1\"));return s[S]?F(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:F(function(t){return function(e){return 0<I(t,e).length}}),contains:F(function(t){return t=t.replace(O,P),function(e){return-1<(e.textContent||ce.text(e)).indexOf(t)}}),lang:F(function(n){return A.test(n||\"\")||I.error(\"unsupported lang: \"+n),n=n.replace(O,P).toLowerCase(),function(e){var t;do{if(t=C?e.lang:e.getAttribute(\"xml:lang\")||e.getAttribute(\"lang\"))return(t=t.toLowerCase())===n||0===t.indexOf(n+\"-\")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=ie.location&&ie.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===r},focus:function(e){return e===function(){try{return T.activeElement}catch(e){}}()&&T.hasFocus()&&!!(e.type||e.href||~e.tabIndex)},enabled:z(!1),disabled:z(!0),checked:function(e){return fe(e,\"input\")&&!!e.checked||fe(e,\"option\")&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return q.test(e.nodeName)},input:function(e){return N.test(e.nodeName)},button:function(e){return fe(e,\"input\")&&\"button\"===e.type||fe(e,\"button\")},text:function(e){var t;return fe(e,\"input\")&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:X(function(){return[0]}),last:X(function(e,t){return[t-1]}),eq:X(function(e,t,n){return[n<0?n+t:n]}),even:X(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:X(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:X(function(e,t,n){var r;for(r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:X(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=B(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=_(e);function G(){}function Y(e,t){var n,r,i,o,a,s,u,l=c[e+\" \"];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=y.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=m.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(ve,\" \")}),a=a.slice(n.length)),b.filter)!(r=D[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?I.error(e):c(e,s).slice(0)}function Q(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function J(a,e,t){var s=e.dir,u=e.next,l=u||s,c=t&&\"parentNode\"===l,f=n++;return e.first?function(e,t,n){while(e=e[s])if(1===e.nodeType||c)return a(e,t,n);return!1}:function(e,t,n){var r,i,o=[E,f];if(n){while(e=e[s])if((1===e.nodeType||c)&&a(e,t,n))return!0}else while(e=e[s])if(1===e.nodeType||c)if(i=e[S]||(e[S]={}),u&&fe(e,u))e=e[s]||e;else{if((r=i[l])&&r[0]===E&&r[1]===f)return o[2]=r[2];if((i[l]=o)[2]=a(e,t,n))return!0}return!1}}function K(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Z(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function ee(d,h,g,v,y,e){return v&&!v[S]&&(v=ee(v)),y&&!y[S]&&(y=ee(y,e)),F(function(e,t,n,r){var i,o,a,s,u=[],l=[],c=t.length,f=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)I(e,t[r],n);return n}(h||\"*\",n.nodeType?[n]:n,[]),p=!d||!e&&h?f:Z(f,u,d,n,r);if(g?g(p,s=y||(e?d:c||v)?[]:t,n,r):s=p,v){i=Z(s,l),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(s[l[o]]=!(p[l[o]]=a))}if(e){if(y||d){if(y){i=[],o=s.length;while(o--)(a=s[o])&&i.push(p[o]=a);y(null,s=[],i,r)}o=s.length;while(o--)(a=s[o])&&-1<(i=y?se.call(e,a):u[o])&&(e[i]=!(t[i]=a))}}else s=Z(s===t?s.splice(c,s.length):s),y?y(null,t,s,r):k.apply(t,s)})}function te(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[\" \"],s=o?1:0,u=J(function(e){return e===i},a,!0),l=J(function(e){return-1<se.call(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!=w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[J(K(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return ee(1<s&&K(c),1<s&&Q(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace(ve,\"$1\"),t,s<n&&te(e.slice(s,n)),n<r&&te(e=e.slice(n)),n<r&&Q(e))}c.push(t)}return K(c)}function ne(e,t){var n,v,y,m,x,r,i=[],o=[],a=u[e+\" \"];if(!a){t||(t=Y(e)),n=t.length;while(n--)(a=te(t[n]))[S]?i.push(a):o.push(a);(a=u(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l=\"0\",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG(\"*\",i),h=E+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==T||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==T||(V(o),n=!C);while(s=v[a++])if(s(o,t||T,n)){k.call(r,o);break}i&&(E=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=pe.call(r));f=Z(f)}k.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&ce.uniqueSort(r)}return i&&(E=h,w=p),c},m?F(r):r))).selector=e}return a}function re(e,t,n,r){var i,o,a,s,u,l=\"function\"==typeof e&&e,c=!r&&Y(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&\"ID\"===(a=o[0]).type&&9===t.nodeType&&C&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(O,P),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=D.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(O,P),H.test(o[0].type)&&U(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&Q(o)))return k.apply(n,r),n;break}}}return(l||ne(e,c))(r,t,!C,n,!t||H.test(e)&&U(t.parentNode)||t),n}G.prototype=b.filters=b.pseudos,b.setFilters=new G,le.sortStable=S.split(\"\").sort(l).join(\"\")===S,V(),le.sortDetached=$(function(e){return 1&e.compareDocumentPosition(T.createElement(\"fieldset\"))}),ce.find=I,ce.expr[\":\"]=ce.expr.pseudos,ce.unique=ce.uniqueSort,I.compile=ne,I.select=re,I.setDocument=V,I.tokenize=Y,I.escape=ce.escapeSelector,I.getText=ce.text,I.isXML=ce.isXMLDoc,I.selectors=ce.expr,I.support=ce.support,I.uniqueSort=ce.uniqueSort}();var d=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&ce(e).is(n))break;r.push(e)}return r},h=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},b=ce.expr.match.needsContext,w=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):\"string\"!=typeof n?ce.grep(e,function(e){return-1<se.call(n,e)!==r}):ce.filter(n,e,r)}ce.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?ce.find.matchesSelector(r,e)?[r]:[]:ce.find.matches(e,ce.grep(t,function(e){return 1===e.nodeType}))},ce.fn.extend({find:function(e){var t,n,r=this.length,i=this;if(\"string\"!=typeof e)return this.pushStack(ce(e).filter(function(){for(t=0;t<r;t++)if(ce.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)ce.find(e,i[t],n);return 1<r?ce.uniqueSort(n):n},filter:function(e){return this.pushStack(T(this,e||[],!1))},not:function(e){return this.pushStack(T(this,e||[],!0))},is:function(e){return!!T(this,\"string\"==typeof e&&b.test(e)?ce(e):e||[],!1).length}});var k,S=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,\"string\"==typeof e){if(!(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(ce.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a=\"string\"!=typeof e&&ce(e);if(!b.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&ce.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?ce.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?se.call(ce(e),this[0]):se.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(ce.uniqueSort(ce.merge(this.get(),ce(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),ce.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return d(e,\"parentNode\")},parentsUntil:function(e,t,n){return d(e,\"parentNode\",n)},next:function(e){return A(e,\"nextSibling\")},prev:function(e){return A(e,\"previousSibling\")},nextAll:function(e){return d(e,\"nextSibling\")},prevAll:function(e){return d(e,\"previousSibling\")},nextUntil:function(e,t,n){return d(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return d(e,\"previousSibling\",n)},siblings:function(e){return h((e.parentNode||{}).firstChild,e)},children:function(e){return h(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(fe(e,\"template\")&&(e=e.content||e),ce.merge([],e.childNodes))}},function(r,i){ce.fn[r]=function(e,t){var n=ce.map(this,i,e);return\"Until\"!==r.slice(-5)&&(t=e),t&&\"string\"==typeof t&&(n=ce.filter(t,n)),1<this.length&&(j[r]||ce.uniqueSort(n),E.test(r)&&n.reverse()),this.pushStack(n)}});var D=/[^\\x20\\t\\r\\n\\f]+/g;function N(e){return e}function q(e){throw e}function L(e,t,n,r){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(n):e&&v(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}ce.Callbacks=function(r){var e,n;r=\"string\"==typeof r?(e=r,n={},ce.each(e.match(D)||[],function(e,t){n[t]=!0}),n):ce.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:\"\")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){ce.each(e,function(e,t){v(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&\"string\"!==x(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return ce.each(arguments,function(e,t){var n;while(-1<(n=ce.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<ce.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t=\"\",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=\"\"),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},ce.extend({Deferred:function(e){var o=[[\"notify\",\"progress\",ce.Callbacks(\"memory\"),ce.Callbacks(\"memory\"),2],[\"resolve\",\"done\",ce.Callbacks(\"once memory\"),ce.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",ce.Callbacks(\"once memory\"),ce.Callbacks(\"once memory\"),1,\"rejected\"]],i=\"pending\",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},\"catch\":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return ce.Deferred(function(r){ce.each(o,function(e,t){var n=v(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&v(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+\"With\"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError(\"Thenable self-resolution\");t=e&&(\"object\"==typeof e||\"function\"==typeof e)&&e.then,v(t)?s?t.call(e,l(u,o,N,s),l(u,o,q,s)):(u++,t.call(e,l(u,o,N,s),l(u,o,q,s),l(u,o,N,o.notifyWith))):(a!==N&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){ce.Deferred.exceptionHook&&ce.Deferred.exceptionHook(e,t.error),u<=i+1&&(a!==q&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(ce.Deferred.getErrorHook?t.error=ce.Deferred.getErrorHook():ce.Deferred.getStackHook&&(t.error=ce.Deferred.getStackHook()),ie.setTimeout(t))}}return ce.Deferred(function(e){o[0][3].add(l(0,e,v(r)?r:N,e.notifyWith)),o[1][3].add(l(0,e,v(t)?t:N)),o[2][3].add(l(0,e,v(n)?n:q))}).promise()},promise:function(e){return null!=e?ce.extend(e,a):a}},s={};return ce.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+\"With\"](this===s?void 0:this,arguments),this},s[t[0]+\"With\"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=ae.call(arguments),o=ce.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?ae.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(L(e,o.done(a(t)).resolve,o.reject,!n),\"pending\"===o.state()||v(i[t]&&i[t].then)))return o.then();while(t--)L(i[t],a(t),o.reject);return o.promise()}});var H=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;ce.Deferred.exceptionHook=function(e,t){ie.console&&ie.console.warn&&e&&H.test(e.name)&&ie.console.warn(\"jQuery.Deferred exception: \"+e.message,e.stack,t)},ce.readyException=function(e){ie.setTimeout(function(){throw e})};var O=ce.Deferred();function P(){C.removeEventListener(\"DOMContentLoaded\",P),ie.removeEventListener(\"load\",P),ce.ready()}ce.fn.ready=function(e){return O.then(e)[\"catch\"](function(e){ce.readyException(e)}),this},ce.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--ce.readyWait:ce.isReady)||(ce.isReady=!0)!==e&&0<--ce.readyWait||O.resolveWith(C,[ce])}}),ce.ready.then=O.then,\"complete\"===C.readyState||\"loading\"!==C.readyState&&!C.documentElement.doScroll?ie.setTimeout(ce.ready):(C.addEventListener(\"DOMContentLoaded\",P),ie.addEventListener(\"load\",P));var M=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===x(n))for(s in i=!0,n)M(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,v(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(ce(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},R=/^-ms-/,I=/-([a-z])/g;function W(e,t){return t.toUpperCase()}function F(e){return e.replace(R,\"ms-\").replace(I,W)}var $=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function B(){this.expando=ce.expando+B.uid++}B.uid=1,B.prototype={cache:function(e){var t=e[this.expando];return t||(t={},$(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if(\"string\"==typeof t)i[F(t)]=n;else for(r in t)i[F(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][F(t)]},access:function(e,t,n){return void 0===t||t&&\"string\"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(F):(t=F(t))in r?[t]:t.match(D)||[]).length;while(n--)delete r[t[n]]}(void 0===t||ce.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!ce.isEmptyObject(t)}};var _=new B,z=new B,X=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,U=/[A-Z]/g;function V(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r=\"data-\"+t.replace(U,\"-$&\").toLowerCase(),\"string\"==typeof(n=e.getAttribute(r))){try{n=\"true\"===(i=n)||\"false\"!==i&&(\"null\"===i?null:i===+i+\"\"?+i:X.test(i)?JSON.parse(i):i)}catch(e){}z.set(e,t,n)}else n=void 0;return n}ce.extend({hasData:function(e){return z.hasData(e)||_.hasData(e)},data:function(e,t,n){return z.access(e,t,n)},removeData:function(e,t){z.remove(e,t)},_data:function(e,t,n){return _.access(e,t,n)},_removeData:function(e,t){_.remove(e,t)}}),ce.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=z.get(o),1===o.nodeType&&!_.get(o,\"hasDataAttrs\"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf(\"data-\")&&(r=F(r.slice(5)),V(o,r,i[r]));_.set(o,\"hasDataAttrs\",!0)}return i}return\"object\"==typeof n?this.each(function(){z.set(this,n)}):M(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=z.get(o,n))?t:void 0!==(t=V(o,n))?t:void 0;this.each(function(){z.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){z.remove(this,e)})}}),ce.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=_.get(e,t),n&&(!r||Array.isArray(n)?r=_.access(e,t,ce.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=ce.queue(e,t),r=n.length,i=n.shift(),o=ce._queueHooks(e,t);\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,function(){ce.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return _.get(e,n)||_.access(e,n,{empty:ce.Callbacks(\"once memory\").add(function(){_.remove(e,[t+\"queue\",n])})})}}),ce.fn.extend({queue:function(t,n){var e=2;return\"string\"!=typeof t&&(n=t,t=\"fx\",e--),arguments.length<e?ce.queue(this[0],t):void 0===n?this:this.each(function(){var e=ce.queue(this,t,n);ce._queueHooks(this,t),\"fx\"===t&&\"inprogress\"!==e[0]&&ce.dequeue(this,t)})},dequeue:function(e){return this.each(function(){ce.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=ce.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";while(a--)(n=_.get(o[a],e+\"queueHooks\"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var G=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,Y=new RegExp(\"^(?:([+-])=|)(\"+G+\")([a-z%]*)$\",\"i\"),Q=[\"Top\",\"Right\",\"Bottom\",\"Left\"],J=C.documentElement,K=function(e){return ce.contains(e.ownerDocument,e)},Z={composed:!0};J.getRootNode&&(K=function(e){return ce.contains(e.ownerDocument,e)||e.getRootNode(Z)===e.ownerDocument});var ee=function(e,t){return\"none\"===(e=t||e).style.display||\"\"===e.style.display&&K(e)&&\"none\"===ce.css(e,\"display\")};function te(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return ce.css(e,t,\"\")},u=s(),l=n&&n[3]||(ce.cssNumber[t]?\"\":\"px\"),c=e.nodeType&&(ce.cssNumber[t]||\"px\"!==l&&+u)&&Y.exec(ce.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)ce.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,ce.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ne={};function re(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?(\"none\"===n&&(l[c]=_.get(r,\"display\")||null,l[c]||(r.style.display=\"\")),\"\"===r.style.display&&ee(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ne[s])||(o=a.body.appendChild(a.createElement(s)),u=ce.css(o,\"display\"),o.parentNode.removeChild(o),\"none\"===u&&(u=\"block\"),ne[s]=u)))):\"none\"!==n&&(l[c]=\"none\",_.set(r,\"display\",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}ce.fn.extend({show:function(){return re(this,!0)},hide:function(){return re(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){ee(this)?ce(this).show():ce(this).hide()})}});var xe,be,we=/^(?:checkbox|radio)$/i,Te=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i,Ce=/^$|^module$|\\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement(\"div\")),(be=C.createElement(\"input\")).setAttribute(\"type\",\"radio\"),be.setAttribute(\"checked\",\"checked\"),be.setAttribute(\"name\",\"t\"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML=\"<textarea>x</textarea>\",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML=\"<option></option>\",le.option=!!xe.lastChild;var ke={thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};function Se(e,t){var n;return n=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n<r;n++)_.set(e[n],\"globalEval\",!t||_.get(t[n],\"globalEval\"))}ke.tbody=ke.tfoot=ke.colgroup=ke.caption=ke.thead,ke.th=ke.td,le.option||(ke.optgroup=ke.option=[1,\"<select multiple='multiple'>\",\"</select>\"]);var je=/<|&#?\\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if(\"object\"===x(o))ce.merge(p,o.nodeType?[o]:o);else if(je.test(o)){a=a||f.appendChild(t.createElement(\"div\")),s=(Te.exec(o)||[\"\",\"\"])[1].toLowerCase(),u=ke[s]||ke._default,a.innerHTML=u[1]+ce.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;ce.merge(p,a.childNodes),(a=f.firstChild).textContent=\"\"}else p.push(t.createTextNode(o));f.textContent=\"\",d=0;while(o=p[d++])if(r&&-1<ce.inArray(o,r))i&&i.push(o);else if(l=K(o),a=Se(f.appendChild(o),\"script\"),l&&Ee(a),n){c=0;while(o=a[c++])Ce.test(o.type||\"\")&&n.push(o)}return f}var De=/^([^.]*)(?:\\.(.+)|)/;function Ne(){return!0}function qe(){return!1}function Le(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){for(s in\"string\"!=typeof n&&(r=r||n,n=void 0),t)Le(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=qe;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return ce().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=ce.guid++)),e.each(function(){ce.event.add(this,t,i,r,n)})}function He(e,r,t){t?(_.set(e,r,!1),ce.event.add(e,r,{namespace:!1,handler:function(e){var t,n=_.get(this,r);if(1&e.isTrigger&&this[r]){if(n)(ce.event.special[r]||{}).delegateType&&e.stopPropagation();else if(n=ae.call(arguments),_.set(this,r,n),this[r](),t=_.get(this,r),_.set(this,r,!1),n!==t)return e.stopImmediatePropagation(),e.preventDefault(),t}else n&&(_.set(this,r,ce.event.trigger(n[0],n.slice(1),this)),e.stopPropagation(),e.isImmediatePropagationStopped=Ne)}})):void 0===_.get(e,r)&&ce.event.add(e,r,Ne)}ce.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=_.get(t);if($(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&ce.find.matchesSelector(J,i),n.guid||(n.guid=ce.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return\"undefined\"!=typeof ce&&ce.event.triggered!==e.type?ce.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||\"\").match(D)||[\"\"]).length;while(l--)d=g=(s=De.exec(e[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d&&(f=ce.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=ce.event.special[d]||{},c=ce.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&ce.expr.match.needsContext.test(i),namespace:h.join(\".\")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),ce.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=_.hasData(e)&&_.get(e);if(v&&(u=v.events)){l=(t=(t||\"\").match(D)||[\"\"]).length;while(l--)if(d=g=(s=De.exec(t[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d){f=ce.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&(\"**\"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||ce.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)ce.event.remove(e,d+t[l],n,r,!0);ce.isEmptyObject(u)&&_.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=ce.event.fix(e),l=(_.get(this,\"events\")||Object.create(null))[u.type]||[],c=ce.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=ce.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((ce.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!(\"click\"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(\"click\"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+\" \"]&&(a[i]=r.needsContext?-1<ce(i,this).index(l):ce.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(ce.Event.prototype,t,{enumerable:!0,configurable:!0,get:v(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[ce.expando]?e:new ce.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return we.test(t.type)&&t.click&&fe(t,\"input\")&&He(t,\"click\",!0),!1},trigger:function(e){var t=this||e;return we.test(t.type)&&t.click&&fe(t,\"input\")&&He(t,\"click\"),!0},_default:function(e){var t=e.target;return we.test(t.type)&&t.click&&fe(t,\"input\")&&_.get(t,\"click\")||fe(t,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},ce.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},ce.Event=function(e,t){if(!(this instanceof ce.Event))return new ce.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ne:qe,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&ce.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[ce.expando]=!0},ce.Event.prototype={constructor:ce.Event,isDefaultPrevented:qe,isPropagationStopped:qe,isImmediatePropagationStopped:qe,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ne,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ne,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ne,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},ce.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,\"char\":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},ce.event.addProp),ce.each({focus:\"focusin\",blur:\"focusout\"},function(r,i){function o(e){if(C.documentMode){var t=_.get(this,\"handle\"),n=ce.event.fix(e);n.type=\"focusin\"===e.type?\"focus\":\"blur\",n.isSimulated=!0,t(e),n.target===n.currentTarget&&t(n)}else ce.event.simulate(i,e.target,ce.event.fix(e))}ce.event.special[r]={setup:function(){var e;if(He(this,r,!0),!C.documentMode)return!1;(e=_.get(this,i))||this.addEventListener(i,o),_.set(this,i,(e||0)+1)},trigger:function(){return He(this,r),!0},teardown:function(){var e;if(!C.documentMode)return!1;(e=_.get(this,i)-1)?_.set(this,i,e):(this.removeEventListener(i,o),_.remove(this,i))},_default:function(e){return _.get(e.target,r)},delegateType:i},ce.event.special[i]={setup:function(){var e=this.ownerDocument||this.document||this,t=C.documentMode?this:e,n=_.get(t,i);n||(C.documentMode?this.addEventListener(i,o):e.addEventListener(r,o,!0)),_.set(t,i,(n||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=C.documentMode?this:e,n=_.get(t,i)-1;n?_.set(t,i,n):(C.documentMode?this.removeEventListener(i,o):e.removeEventListener(r,o,!0),_.remove(t,i))}}}),ce.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,i){ce.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||ce.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),ce.fn.extend({on:function(e,t,n,r){return Le(this,e,t,n,r)},one:function(e,t,n,r){return Le(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,ce(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&\"function\"!=typeof t||(n=t,t=void 0),!1===n&&(n=qe),this.each(function(){ce.event.remove(this,e,n,t)})}});var Oe=/<script|<style|<link/i,Pe=/checked\\s*(?:[^=]|=\\s*.checked.)/i,Me=/^\\s*<!\\[CDATA\\[|\\]\\]>\\s*$/g;function Re(e,t){return fe(e,\"table\")&&fe(11!==t.nodeType?t:t.firstChild,\"tr\")&&ce(e).children(\"tbody\")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function We(e){return\"true/\"===(e.type||\"\").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute(\"type\"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,\"handle events\"),s)for(n=0,r=s[i].length;n<r;n++)ce.event.add(t,i,s[i][n]);z.hasData(e)&&(o=z.access(e),a=ce.extend({},o),z.set(t,a))}}function $e(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=v(d);if(h||1<f&&\"string\"==typeof d&&!le.checkClone&&Pe.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),$e(t,r,i,o)});if(f&&(t=(e=Ae(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=ce.map(Se(e,\"script\"),Ie)).length;c<f;c++)u=e,c!==p&&(u=ce.clone(u,!0,!0),s&&ce.merge(a,Se(u,\"script\"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,ce.map(a,We),c=0;c<s;c++)u=a[c],Ce.test(u.type||\"\")&&!_.access(u,\"globalEval\")&&ce.contains(l,u)&&(u.src&&\"module\"!==(u.type||\"\").toLowerCase()?ce._evalUrl&&!u.noModule&&ce._evalUrl(u.src,{nonce:u.nonce||u.getAttribute(\"nonce\")},l):m(u.textContent.replace(Me,\"\"),u,l))}return n}function Be(e,t,n){for(var r,i=t?ce.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||ce.cleanData(Se(r)),r.parentNode&&(n&&K(r)&&Ee(Se(r,\"script\")),r.parentNode.removeChild(r));return e}ce.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=K(e);if(!(le.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||ce.isXMLDoc(e)))for(a=Se(c),r=0,i=(o=Se(e)).length;r<i;r++)s=o[r],u=a[r],void 0,\"input\"===(l=u.nodeName.toLowerCase())&&we.test(s.type)?u.checked=s.checked:\"input\"!==l&&\"textarea\"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||Se(e),a=a||Se(c),r=0,i=o.length;r<i;r++)Fe(o[r],a[r]);else Fe(e,c);return 0<(a=Se(c,\"script\")).length&&Ee(a,!f&&Se(e,\"script\")),c},cleanData:function(e){for(var t,n,r,i=ce.event.special,o=0;void 0!==(n=e[o]);o++)if($(n)){if(t=n[_.expando]){if(t.events)for(r in t.events)i[r]?ce.event.remove(n,r):ce.removeEvent(n,r,t.handle);n[_.expando]=void 0}n[z.expando]&&(n[z.expando]=void 0)}}}),ce.fn.extend({detach:function(e){return Be(this,e,!0)},remove:function(e){return Be(this,e)},text:function(e){return M(this,function(e){return void 0===e?ce.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return $e(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Re(this,e).appendChild(e)})},prepend:function(){return $e(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Re(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return $e(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return $e(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(ce.cleanData(Se(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return ce.clone(this,e,t)})},html:function(e){return M(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!Oe.test(e)&&!ke[(Te.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=ce.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(ce.cleanData(Se(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return $e(this,arguments,function(e){var t=this.parentNode;ce.inArray(this,n)<0&&(ce.cleanData(Se(this)),t&&t.replaceChild(e,this))},n)}}),ce.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,a){ce.fn[e]=function(e){for(var t,n=[],r=ce(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),ce(r[o])[a](t),s.apply(n,t.get());return this.pushStack(n)}});var _e=new RegExp(\"^(\"+G+\")(?!px)[a-z%]+$\",\"i\"),ze=/^--/,Xe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=ie),t.getComputedStyle(e)},Ue=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Ve=new RegExp(Q.join(\"|\"),\"i\");function Ge(e,t,n){var r,i,o,a,s=ze.test(t),u=e.style;return(n=n||Xe(e))&&(a=n.getPropertyValue(t)||n[t],s&&a&&(a=a.replace(ve,\"$1\")||void 0),\"\"!==a||K(e)||(a=ce.style(e,t)),!le.pixelBoxStyles()&&_e.test(a)&&Ve.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=n.width,u.width=r,u.minWidth=i,u.maxWidth=o)),void 0!==a?a+\"\":a}function Ye(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText=\"position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0\",l.style.cssText=\"position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%\",J.appendChild(u).appendChild(l);var e=ie.getComputedStyle(l);n=\"1%\"!==e.top,s=12===t(e.marginLeft),l.style.right=\"60%\",o=36===t(e.right),r=36===t(e.width),l.style.position=\"absolute\",i=12===t(l.offsetWidth/3),J.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=C.createElement(\"div\"),l=C.createElement(\"div\");l.style&&(l.style.backgroundClip=\"content-box\",l.cloneNode(!0).style.backgroundClip=\"\",le.clearCloneStyle=\"content-box\"===l.style.backgroundClip,ce.extend(le,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=C.createElement(\"table\"),t=C.createElement(\"tr\"),n=C.createElement(\"div\"),e.style.cssText=\"position:absolute;left:-11111px;border-collapse:separate\",t.style.cssText=\"box-sizing:content-box;border:1px solid\",t.style.height=\"1px\",n.style.height=\"9px\",n.style.display=\"block\",J.appendChild(e).appendChild(t).appendChild(n),r=ie.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,J.removeChild(e)),a}}))}();var Qe=[\"Webkit\",\"Moz\",\"ms\"],Je=C.createElement(\"div\").style,Ke={};function Ze(e){var t=ce.cssProps[e]||Ke[e];return t||(e in Je?e:Ke[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Qe.length;while(n--)if((e=Qe[n]+t)in Je)return e}(e)||e)}var et=/^(none|table(?!-c[ea]).+)/,tt={position:\"absolute\",visibility:\"hidden\",display:\"block\"},nt={letterSpacing:\"0\",fontWeight:\"400\"};function rt(e,t,n){var r=Y.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||\"px\"):t}function it(e,t,n,r,i,o){var a=\"width\"===t?1:0,s=0,u=0,l=0;if(n===(r?\"border\":\"content\"))return 0;for(;a<4;a+=2)\"margin\"===n&&(l+=ce.css(e,n+Q[a],!0,i)),r?(\"content\"===n&&(u-=ce.css(e,\"padding\"+Q[a],!0,i)),\"margin\"!==n&&(u-=ce.css(e,\"border\"+Q[a]+\"Width\",!0,i))):(u+=ce.css(e,\"padding\"+Q[a],!0,i),\"padding\"!==n?u+=ce.css(e,\"border\"+Q[a]+\"Width\",!0,i):s+=ce.css(e,\"border\"+Q[a]+\"Width\",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e[\"offset\"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u+l}function ot(e,t,n){var r=Xe(e),i=(!le.boxSizingReliable()||n)&&\"border-box\"===ce.css(e,\"boxSizing\",!1,r),o=i,a=Ge(e,t,r),s=\"offset\"+t[0].toUpperCase()+t.slice(1);if(_e.test(a)){if(!n)return a;a=\"auto\"}return(!le.boxSizingReliable()&&i||!le.reliableTrDimensions()&&fe(e,\"tr\")||\"auto\"===a||!parseFloat(a)&&\"inline\"===ce.css(e,\"display\",!1,r))&&e.getClientRects().length&&(i=\"border-box\"===ce.css(e,\"boxSizing\",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+it(e,t,n||(i?\"border\":\"content\"),o,r,a)+\"px\"}function at(e,t,n,r,i){return new at.prototype.init(e,t,n,r,i)}ce.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Ge(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=F(t),u=ze.test(t),l=e.style;if(u||(t=Ze(s)),a=ce.cssHooks[t]||ce.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];\"string\"===(o=typeof n)&&(i=Y.exec(n))&&i[1]&&(n=te(e,t,i),o=\"number\"),null!=n&&n==n&&(\"number\"!==o||u||(n+=i&&i[3]||(ce.cssNumber[s]?\"\":\"px\")),le.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(l[t]=\"inherit\"),a&&\"set\"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=F(t);return ze.test(t)||(t=Ze(s)),(a=ce.cssHooks[t]||ce.cssHooks[s])&&\"get\"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Ge(e,t,r)),\"normal\"===i&&t in nt&&(i=nt[t]),\"\"===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),ce.each([\"height\",\"width\"],function(e,u){ce.cssHooks[u]={get:function(e,t,n){if(t)return!et.test(ce.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?ot(e,u,n):Ue(e,tt,function(){return ot(e,u,n)})},set:function(e,t,n){var r,i=Xe(e),o=!le.scrollboxSize()&&\"absolute\"===i.position,a=(o||n)&&\"border-box\"===ce.css(e,\"boxSizing\",!1,i),s=n?it(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e[\"offset\"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-it(e,u,\"border\",!1,i)-.5)),s&&(r=Y.exec(t))&&\"px\"!==(r[3]||\"px\")&&(e.style[u]=t,t=ce.css(e,u)),rt(0,t,s)}}}),ce.cssHooks.marginLeft=Ye(le.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Ge(e,\"marginLeft\"))||e.getBoundingClientRect().left-Ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+\"px\"}),ce.each({margin:\"\",padding:\"\",border:\"Width\"},function(i,o){ce.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r=\"string\"==typeof e?e.split(\" \"):[e];t<4;t++)n[i+Q[t]+o]=r[t]||r[t-2]||r[0];return n}},\"margin\"!==i&&(ce.cssHooks[i+o].set=rt)}),ce.fn.extend({css:function(e,t){return M(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Xe(e),i=t.length;a<i;a++)o[t[a]]=ce.css(e,t[a],!1,r);return o}return void 0!==n?ce.style(e,t,n):ce.css(e,t)},e,t,1<arguments.length)}}),((ce.Tween=at).prototype={constructor:at,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||ce.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(ce.cssNumber[n]?\"\":\"px\")},cur:function(){var e=at.propHooks[this.prop];return e&&e.get?e.get(this):at.propHooks._default.get(this)},run:function(e){var t,n=at.propHooks[this.prop];return this.options.duration?this.pos=t=ce.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):at.propHooks._default.set(this),this}}).init.prototype=at.prototype,(at.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=ce.css(e.elem,e.prop,\"\"))&&\"auto\"!==t?t:0},set:function(e){ce.fx.step[e.prop]?ce.fx.step[e.prop](e):1!==e.elem.nodeType||!ce.cssHooks[e.prop]&&null==e.elem.style[Ze(e.prop)]?e.elem[e.prop]=e.now:ce.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=at.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},ce.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},ce.fx=at.prototype.init,ce.fx.step={};var st,ut,lt,ct,ft=/^(?:toggle|show|hide)$/,pt=/queueHooks$/;function dt(){ut&&(!1===C.hidden&&ie.requestAnimationFrame?ie.requestAnimationFrame(dt):ie.setTimeout(dt,ce.fx.interval),ce.fx.tick())}function ht(){return ie.setTimeout(function(){st=void 0}),st=Date.now()}function gt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i[\"margin\"+(n=Q[r])]=i[\"padding\"+n]=e;return t&&(i.opacity=i.width=e),i}function vt(e,t,n){for(var r,i=(yt.tweeners[t]||[]).concat(yt.tweeners[\"*\"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function yt(o,e,t){var n,a,r=0,i=yt.prefilters.length,s=ce.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=st||ht(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:ce.extend({},e),opts:ce.extend(!0,{specialEasing:{},easing:ce.easing._default},t),originalProperties:e,originalOptions:t,startTime:st||ht(),duration:t.duration,tweens:[],createTween:function(e,t){var n=ce.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=F(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=ce.cssHooks[r])&&\"expand\"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=yt.prefilters[r].call(l,o,c,l.opts))return v(n.stop)&&(ce._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return ce.map(c,vt,l),v(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),ce.fx.timer(ce.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}ce.Animation=ce.extend(yt,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return te(n.elem,e,Y.exec(t),n),n}]},tweener:function(e,t){v(e)?(t=e,e=[\"*\"]):e=e.match(D);for(var n,r=0,i=e.length;r<i;r++)n=e[r],yt.tweeners[n]=yt.tweeners[n]||[],yt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f=\"width\"in t||\"height\"in t,p=this,d={},h=e.style,g=e.nodeType&&ee(e),v=_.get(e,\"fxshow\");for(r in n.queue||(null==(a=ce._queueHooks(e,\"fx\")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,ce.queue(e,\"fx\").length||a.empty.fire()})})),t)if(i=t[r],ft.test(i)){if(delete t[r],o=o||\"toggle\"===i,i===(g?\"hide\":\"show\")){if(\"show\"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||ce.style(e,r)}if((u=!ce.isEmptyObject(t))||!ce.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=_.get(e,\"display\")),\"none\"===(c=ce.css(e,\"display\"))&&(l?c=l:(re([e],!0),l=e.style.display||l,c=ce.css(e,\"display\"),re([e]))),(\"inline\"===c||\"inline-block\"===c&&null!=l)&&\"none\"===ce.css(e,\"float\")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l=\"none\"===c?\"\":c)),h.display=\"inline-block\")),n.overflow&&(h.overflow=\"hidden\",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?\"hidden\"in v&&(g=v.hidden):v=_.access(e,\"fxshow\",{display:l}),o&&(v.hidden=!g),g&&re([e],!0),p.done(function(){for(r in g||re([e]),_.remove(e,\"fxshow\"),d)ce.style(e,r,d[r])})),u=vt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?yt.prefilters.unshift(e):yt.prefilters.push(e)}}),ce.speed=function(e,t,n){var r=e&&\"object\"==typeof e?ce.extend({},e):{complete:n||!n&&t||v(e)&&e,duration:e,easing:n&&t||t&&!v(t)&&t};return ce.fx.off?r.duration=0:\"number\"!=typeof r.duration&&(r.duration in ce.fx.speeds?r.duration=ce.fx.speeds[r.duration]:r.duration=ce.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){v(r.old)&&r.old.call(this),r.queue&&ce.dequeue(this,r.queue)},r},ce.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ee).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=ce.isEmptyObject(t),o=ce.speed(e,n,r),a=function(){var e=yt(this,ce.extend({},t),o);(i||_.get(this,\"finish\"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return\"string\"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||\"fx\",[]),this.each(function(){var e=!0,t=null!=i&&i+\"queueHooks\",n=ce.timers,r=_.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&pt.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||ce.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||\"fx\"),this.each(function(){var e,t=_.get(this),n=t[a+\"queue\"],r=t[a+\"queueHooks\"],i=ce.timers,o=n?n.length:0;for(t.finish=!0,ce.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),ce.each([\"toggle\",\"show\",\"hide\"],function(e,r){var i=ce.fn[r];ce.fn[r]=function(e,t,n){return null==e||\"boolean\"==typeof e?i.apply(this,arguments):this.animate(gt(r,!0),e,t,n)}}),ce.each({slideDown:gt(\"show\"),slideUp:gt(\"hide\"),slideToggle:gt(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,r){ce.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),ce.timers=[],ce.fx.tick=function(){var e,t=0,n=ce.timers;for(st=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||ce.fx.stop(),st=void 0},ce.fx.timer=function(e){ce.timers.push(e),ce.fx.start()},ce.fx.interval=13,ce.fx.start=function(){ut||(ut=!0,dt())},ce.fx.stop=function(){ut=null},ce.fx.speeds={slow:600,fast:200,_default:400},ce.fn.delay=function(r,e){return r=ce.fx&&ce.fx.speeds[r]||r,e=e||\"fx\",this.queue(e,function(e,t){var n=ie.setTimeout(e,r);t.stop=function(){ie.clearTimeout(n)}})},lt=C.createElement(\"input\"),ct=C.createElement(\"select\").appendChild(C.createElement(\"option\")),lt.type=\"checkbox\",le.checkOn=\"\"!==lt.value,le.optSelected=ct.selected,(lt=C.createElement(\"input\")).value=\"t\",lt.type=\"radio\",le.radioValue=\"t\"===lt.value;var mt,xt=ce.expr.attrHandle;ce.fn.extend({attr:function(e,t){return M(this,ce.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){ce.removeAttr(this,e)})}}),ce.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return\"undefined\"==typeof e.getAttribute?ce.prop(e,t,n):(1===o&&ce.isXMLDoc(e)||(i=ce.attrHooks[t.toLowerCase()]||(ce.expr.match.bool.test(t)?mt:void 0)),void 0!==n?null===n?void ce.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:null==(r=ce.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!le.radioValue&&\"radio\"===t&&fe(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(D);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),mt={set:function(e,t,n){return!1===t?ce.removeAttr(e,n):e.setAttribute(n,n),n}},ce.each(ce.expr.match.bool.source.match(/\\w+/g),function(e,t){var a=xt[t]||ce.find.attr;xt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=xt[o],xt[o]=r,r=null!=a(e,t,n)?o:null,xt[o]=i),r}});var bt=/^(?:input|select|textarea|button)$/i,wt=/^(?:a|area)$/i;function Tt(e){return(e.match(D)||[]).join(\" \")}function Ct(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function kt(e){return Array.isArray(e)?e:\"string\"==typeof e&&e.match(D)||[]}ce.fn.extend({prop:function(e,t){return M(this,ce.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[ce.propFix[e]||e]})}}),ce.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&ce.isXMLDoc(e)||(t=ce.propFix[t]||t,i=ce.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=ce.find.attr(e,\"tabindex\");return t?parseInt(t,10):bt.test(e.nodeName)||wt.test(e.nodeName)&&e.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),le.optSelected||(ce.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),ce.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){ce.propFix[this.toLowerCase()]=this}),ce.fn.extend({addClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){ce(this).addClass(t.call(this,e,Ct(this)))}):(e=kt(t)).length?this.each(function(){if(r=Ct(this),n=1===this.nodeType&&\" \"+Tt(r)+\" \"){for(o=0;o<e.length;o++)i=e[o],n.indexOf(\" \"+i+\" \")<0&&(n+=i+\" \");a=Tt(n),r!==a&&this.setAttribute(\"class\",a)}}):this},removeClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){ce(this).removeClass(t.call(this,e,Ct(this)))}):arguments.length?(e=kt(t)).length?this.each(function(){if(r=Ct(this),n=1===this.nodeType&&\" \"+Tt(r)+\" \"){for(o=0;o<e.length;o++){i=e[o];while(-1<n.indexOf(\" \"+i+\" \"))n=n.replace(\" \"+i+\" \",\" \")}a=Tt(n),r!==a&&this.setAttribute(\"class\",a)}}):this:this.attr(\"class\",\"\")},toggleClass:function(t,n){var e,r,i,o,a=typeof t,s=\"string\"===a||Array.isArray(t);return v(t)?this.each(function(e){ce(this).toggleClass(t.call(this,e,Ct(this),n),n)}):\"boolean\"==typeof n&&s?n?this.addClass(t):this.removeClass(t):(e=kt(t),this.each(function(){if(s)for(o=ce(this),i=0;i<e.length;i++)r=e[i],o.hasClass(r)?o.removeClass(r):o.addClass(r);else void 0!==t&&\"boolean\"!==a||((r=Ct(this))&&_.set(this,\"__className__\",r),this.setAttribute&&this.setAttribute(\"class\",r||!1===t?\"\":_.get(this,\"__className__\")||\"\"))}))},hasClass:function(e){var t,n,r=0;t=\" \"+e+\" \";while(n=this[r++])if(1===n.nodeType&&-1<(\" \"+Tt(Ct(n))+\" \").indexOf(t))return!0;return!1}});var St=/\\r/g;ce.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=v(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,ce(this).val()):n)?t=\"\":\"number\"==typeof t?t+=\"\":Array.isArray(t)&&(t=ce.map(t,function(e){return null==e?\"\":e+\"\"})),(r=ce.valHooks[this.type]||ce.valHooks[this.nodeName.toLowerCase()])&&\"set\"in r&&void 0!==r.set(this,t,\"value\")||(this.value=t))})):t?(r=ce.valHooks[t.type]||ce.valHooks[t.nodeName.toLowerCase()])&&\"get\"in r&&void 0!==(e=r.get(t,\"value\"))?e:\"string\"==typeof(e=t.value)?e.replace(St,\"\"):null==e?\"\":e:void 0}}),ce.extend({valHooks:{option:{get:function(e){var t=ce.find.attr(e,\"value\");return null!=t?t:Tt(ce.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a=\"select-one\"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!fe(n.parentNode,\"optgroup\"))){if(t=ce(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=ce.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<ce.inArray(ce.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),ce.each([\"radio\",\"checkbox\"],function(){ce.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<ce.inArray(ce(e).val(),t)}},le.checkOn||(ce.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Et=ie.location,jt={guid:Date.now()},At=/\\?/;ce.parseXML=function(e){var t,n;if(!e||\"string\"!=typeof e)return null;try{t=(new ie.DOMParser).parseFromString(e,\"text/xml\")}catch(e){}return n=t&&t.getElementsByTagName(\"parsererror\")[0],t&&!n||ce.error(\"Invalid XML: \"+(n?ce.map(n.childNodes,function(e){return e.textContent}).join(\"\\n\"):e)),t};var Dt=/^(?:focusinfocus|focusoutblur)$/,Nt=function(e){e.stopPropagation()};ce.extend(ce.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||C],d=ue.call(e,\"type\")?e.type:e,h=ue.call(e,\"namespace\")?e.namespace.split(\".\"):[];if(o=f=a=n=n||C,3!==n.nodeType&&8!==n.nodeType&&!Dt.test(d+ce.event.triggered)&&(-1<d.indexOf(\".\")&&(d=(h=d.split(\".\")).shift(),h.sort()),u=d.indexOf(\":\")<0&&\"on\"+d,(e=e[ce.expando]?e:new ce.Event(d,\"object\"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join(\".\"),e.rnamespace=e.namespace?new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:ce.makeArray(t,[e]),c=ce.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!y(n)){for(s=c.delegateType||d,Dt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||C)&&p.push(a.defaultView||a.parentWindow||ie)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(_.get(o,\"events\")||Object.create(null))[e.type]&&_.get(o,\"handle\"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&$(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!$(n)||u&&v(n[d])&&!y(n)&&((a=n[u])&&(n[u]=null),ce.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,Nt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,Nt),ce.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=ce.extend(new ce.Event,n,{type:e,isSimulated:!0});ce.event.trigger(r,null,t)}}),ce.fn.extend({trigger:function(e,t){return this.each(function(){ce.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return ce.event.trigger(e,t,n,!0)}});var qt=/\\[\\]$/,Lt=/\\r?\\n/g,Ht=/^(?:submit|button|image|reset|file)$/i,Ot=/^(?:input|select|textarea|keygen)/i;function Pt(n,e,r,i){var t;if(Array.isArray(e))ce.each(e,function(e,t){r||qt.test(n)?i(n,t):Pt(n+\"[\"+(\"object\"==typeof t&&null!=t?e:\"\")+\"]\",t,r,i)});else if(r||\"object\"!==x(e))i(n,e);else for(t in e)Pt(n+\"[\"+t+\"]\",e[t],r,i)}ce.param=function(e,t){var n,r=[],i=function(e,t){var n=v(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(null==e)return\"\";if(Array.isArray(e)||e.jquery&&!ce.isPlainObject(e))ce.each(e,function(){i(this.name,this.value)});else for(n in e)Pt(n,e[n],t,i);return r.join(\"&\")},ce.fn.extend({serialize:function(){return ce.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=ce.prop(this,\"elements\");return e?ce.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!ce(this).is(\":disabled\")&&Ot.test(this.nodeName)&&!Ht.test(e)&&(this.checked||!we.test(e))}).map(function(e,t){var n=ce(this).val();return null==n?null:Array.isArray(n)?ce.map(n,function(e){return{name:t.name,value:e.replace(Lt,\"\\r\\n\")}}):{name:t.name,value:n.replace(Lt,\"\\r\\n\")}}).get()}});var Mt=/%20/g,Rt=/#.*$/,It=/([?&])_=[^&]*/,Wt=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Ft=/^(?:GET|HEAD)$/,$t=/^\\/\\//,Bt={},_t={},zt=\"*/\".concat(\"*\"),Xt=C.createElement(\"a\");function Ut(o){return function(e,t){\"string\"!=typeof e&&(t=e,e=\"*\");var n,r=0,i=e.toLowerCase().match(D)||[];if(v(t))while(n=i[r++])\"+\"===n[0]?(n=n.slice(1)||\"*\",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Vt(t,i,o,a){var s={},u=t===_t;function l(e){var r;return s[e]=!0,ce.each(t[e]||[],function(e,t){var n=t(i,o,a);return\"string\"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s[\"*\"]&&l(\"*\")}function Gt(e,t){var n,r,i=ce.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&ce.extend(!0,e,r),e}Xt.href=Et.href,ce.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:\"GET\",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":zt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":ce.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Gt(Gt(e,ce.ajaxSettings),t):Gt(ce.ajaxSettings,e)},ajaxPrefilter:Ut(Bt),ajaxTransport:Ut(_t),ajax:function(e,t){\"object\"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=ce.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?ce(y):ce.event,x=ce.Deferred(),b=ce.Callbacks(\"once memory\"),w=v.statusCode||{},a={},s={},u=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Wt.exec(p))n[t[1].toLowerCase()+\" \"]=(n[t[1].toLowerCase()+\" \"]||[]).concat(t[2])}t=n[e.toLowerCase()+\" \"]}return null==t?null:t.join(\", \")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Et.href)+\"\").replace($t,Et.protocol+\"//\"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||\"*\").toLowerCase().match(D)||[\"\"],null==v.crossDomain){r=C.createElement(\"a\");try{r.href=v.url,r.href=r.href,v.crossDomain=Xt.protocol+\"//\"+Xt.host!=r.protocol+\"//\"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&\"string\"!=typeof v.data&&(v.data=ce.param(v.data,v.traditional)),Vt(Bt,v,t,T),h)return T;for(i in(g=ce.event&&v.global)&&0==ce.active++&&ce.event.trigger(\"ajaxStart\"),v.type=v.type.toUpperCase(),v.hasContent=!Ft.test(v.type),f=v.url.replace(Rt,\"\"),v.hasContent?v.data&&v.processData&&0===(v.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(v.data=v.data.replace(Mt,\"+\")):(o=v.url.slice(f.length),v.data&&(v.processData||\"string\"==typeof v.data)&&(f+=(At.test(f)?\"&\":\"?\")+v.data,delete v.data),!1===v.cache&&(f=f.replace(It,\"$1\"),o=(At.test(f)?\"&\":\"?\")+\"_=\"+jt.guid+++o),v.url=f+o),v.ifModified&&(ce.lastModified[f]&&T.setRequestHeader(\"If-Modified-Since\",ce.lastModified[f]),ce.etag[f]&&T.setRequestHeader(\"If-None-Match\",ce.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader(\"Content-Type\",v.contentType),T.setRequestHeader(\"Accept\",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+(\"*\"!==v.dataTypes[0]?\", \"+zt+\"; q=0.01\":\"\"):v.accepts[\"*\"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u=\"abort\",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Vt(_t,v,t,T)){if(T.readyState=1,g&&m.trigger(\"ajaxSend\",[T,v]),h)return T;v.async&&0<v.timeout&&(d=ie.setTimeout(function(){T.abort(\"timeout\")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,\"No Transport\");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&ie.clearTimeout(d),c=void 0,p=r||\"\",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while(\"*\"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+\" \"+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<ce.inArray(\"script\",v.dataTypes)&&ce.inArray(\"json\",v.dataTypes)<0&&(v.converters[\"text script\"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(!(a=l[u+\" \"+o]||l[\"* \"+o]))for(i in l)if((s=i.split(\" \"))[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e[\"throws\"])t=a(t);else try{t=a(t)}catch(e){return{state:\"parsererror\",error:a?e:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader(\"Last-Modified\"))&&(ce.lastModified[f]=u),(u=T.getResponseHeader(\"etag\"))&&(ce.etag[f]=u)),204===e||\"HEAD\"===v.type?l=\"nocontent\":304===e?l=\"notmodified\":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l=\"error\",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+\"\",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?\"ajaxSuccess\":\"ajaxError\",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger(\"ajaxComplete\",[T,v]),--ce.active||ce.event.trigger(\"ajaxStop\")))}return T},getJSON:function(e,t,n){return ce.get(e,t,n,\"json\")},getScript:function(e,t){return ce.get(e,void 0,t,\"script\")}}),ce.each([\"get\",\"post\"],function(e,i){ce[i]=function(e,t,n,r){return v(t)&&(r=r||n,n=t,t=void 0),ce.ajax(ce.extend({url:e,type:i,dataType:r,data:t,success:n},ce.isPlainObject(e)&&e))}}),ce.ajaxPrefilter(function(e){var t;for(t in e.headers)\"content-type\"===t.toLowerCase()&&(e.contentType=e.headers[t]||\"\")}),ce._evalUrl=function(e,t,n){return ce.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,converters:{\"text script\":function(){}},dataFilter:function(e){ce.globalEval(e,t,n)}})},ce.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=ce(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return v(n)?this.each(function(e){ce(this).wrapInner(n.call(this,e))}):this.each(function(){var e=ce(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=v(t);return this.each(function(e){ce(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not(\"body\").each(function(){ce(this).replaceWith(this.childNodes)}),this}}),ce.expr.pseudos.hidden=function(e){return!ce.expr.pseudos.visible(e)},ce.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},ce.ajaxSettings.xhr=function(){try{return new ie.XMLHttpRequest}catch(e){}};var Yt={0:200,1223:204},Qt=ce.ajaxSettings.xhr();le.cors=!!Qt&&\"withCredentials\"in Qt,le.ajax=Qt=!!Qt,ce.ajaxTransport(function(i){var o,a;if(le.cors||Qt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e[\"X-Requested-With\"]||(e[\"X-Requested-With\"]=\"XMLHttpRequest\"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,\"abort\"===e?r.abort():\"error\"===e?\"number\"!=typeof r.status?t(0,\"error\"):t(r.status,r.statusText):t(Yt[r.status]||r.status,r.statusText,\"text\"!==(r.responseType||\"text\")||\"string\"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o(\"error\"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&ie.setTimeout(function(){o&&a()})},o=o(\"abort\");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),ce.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),ce.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return ce.globalEval(e),e}}}),ce.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")}),ce.ajaxTransport(\"script\",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=ce(\"<script>\").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on(\"load error\",i=function(e){r.remove(),i=null,e&&t(\"error\"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\\?(?=&|$)|\\?\\?/;ce.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=Kt.pop()||ce.expando+\"_\"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter(\"json jsonp\",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?\"url\":\"string\"==typeof e.data&&0===(e.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Zt.test(e.data)&&\"data\");if(a||\"jsonp\"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,\"$1\"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?\"&\":\"?\")+e.jsonp+\"=\"+r),e.converters[\"script json\"]=function(){return o||ce.error(r+\" was not called\"),o[0]},e.dataTypes[0]=\"json\",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),\"script\"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument(\"\").body).innerHTML=\"<form></form><form></form>\",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return\"string\"!=typeof e?[]:(\"boolean\"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument(\"\")).createElement(\"base\")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(\" \");return-1<s&&(r=Tt(e.slice(s)),e=e.slice(0,s)),v(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(i=\"POST\"),0<a.length&&ce.ajax({url:e,type:i||\"GET\",dataType:\"html\",data:t}).done(function(e){o=arguments,a.html(r?ce(\"<div>\").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,\"position\"),c=ce(e),f={};\"static\"===l&&(e.style.position=\"relative\"),s=c.offset(),o=ce.css(e,\"top\"),u=ce.css(e,\"left\"),(\"absolute\"===l||\"fixed\"===l)&&-1<(o+u).indexOf(\"auto\")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),\"using\"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if(\"fixed\"===ce.css(r,\"position\"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&\"static\"===ce.css(e,\"position\"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,\"borderTopWidth\",!0),i.left+=ce.css(e,\"borderLeftWidth\",!0))}return{top:t.top-i.top-ce.css(r,\"marginTop\",!0),left:t.left-i.left-ce.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&\"static\"===ce.css(e,\"position\"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(t,i){var o=\"pageYOffset\"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each([\"top\",\"left\"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+\"px\":t})}),ce.each({Height:\"height\",Width:\"width\"},function(a,s){ce.each({padding:\"inner\"+a,content:s,\"\":\"outer\"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||\"boolean\"!=typeof e),i=r||(!0===e||!0===t?\"margin\":\"border\");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf(\"outer\")?e[\"inner\"+a]:e.document.documentElement[\"client\"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body[\"scroll\"+a],r[\"scroll\"+a],e.body[\"offset\"+a],r[\"offset\"+a],r[\"client\"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)},hover:function(e,t){return this.on(\"mouseenter\",e).on(\"mouseleave\",t||e)}}),ce.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,n){ce.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var en=/^[\\s\\uFEFF\\xA0]+|([^\\s\\uFEFF\\xA0])[\\s\\uFEFF\\xA0]+$/g;ce.proxy=function(e,t){var n,r,i;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),v(e))return r=ae.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(ae.call(arguments)))}).guid=e.guid=e.guid||ce.guid++,i},ce.holdReady=function(e){e?ce.readyWait++:ce.ready(!0)},ce.isArray=Array.isArray,ce.parseJSON=JSON.parse,ce.nodeName=fe,ce.isFunction=v,ce.isWindow=y,ce.camelCase=F,ce.type=x,ce.now=Date.now,ce.isNumeric=function(e){var t=ce.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},ce.trim=function(e){return null==e?\"\":(e+\"\").replace(en,\"$1\")},\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return ce});var tn=ie.jQuery,nn=ie.$;return ce.noConflict=function(e){return ie.$===ce&&(ie.$=nn),e&&ie.jQuery===ce&&(ie.jQuery=tn),ce},\"undefined\"==typeof e&&(ie.jQuery=ie.$=ce),ce});\n/*\n * jQuery throttle / debounce - v1.1 - 3/7/2010\n * http://benalman.com/projects/jquery-throttle-debounce-plugin/\n * \n * Copyright (c) 2010 \"Cowboy\" Ben Alman\n * Dual licensed under the MIT and GPL licenses.\n * http://benalman.com/about/license/\n */\n(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!==\"boolean\"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);\n/*!\n * imagesLoaded PACKAGED v4.1.4\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n!function(e,t){\"function\"==typeof define&&define.amd?define(\"ev-emitter/ev-emitter\",t):\"object\"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}(\"undefined\"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o<i.length;o++){var r=i[o],s=n&&n[r];s&&(this.off(e,r),delete n[r]),r.apply(this,t)}return this}},t.allOff=function(){delete this._events,delete this._onceEvents},e}),function(e,t){\"use strict\";\"function\"==typeof define&&define.amd?define([\"ev-emitter/ev-emitter\"],function(i){return t(e,i)}):\"object\"==typeof module&&module.exports?module.exports=t(e,require(\"ev-emitter\")):e.imagesLoaded=t(e,e.EvEmitter)}(\"undefined\"!=typeof window?window:this,function(e,t){function i(e,t){for(var i in t)e[i]=t[i];return e}function n(e){if(Array.isArray(e))return e;var t=\"object\"==typeof e&&\"number\"==typeof e.length;return t?d.call(e):[e]}function o(e,t,r){if(!(this instanceof o))return new o(e,t,r);var s=e;return\"string\"==typeof e&&(s=document.querySelectorAll(e)),s?(this.elements=n(s),this.options=i({},this.options),\"function\"==typeof t?r=t:i(this.options,t),r&&this.on(\"always\",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(this.check.bind(this))):void a.error(\"Bad element for imagesLoaded \"+(s||e))}function r(e){this.img=e}function s(e,t){this.url=e,this.element=t,this.img=new Image}var h=e.jQuery,a=e.console,d=Array.prototype.slice;o.prototype=Object.create(t.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)},o.prototype.addElementImages=function(e){\"IMG\"==e.nodeName&&this.addImage(e),this.options.background===!0&&this.addElementBackgroundImages(e);var t=e.nodeType;if(t&&u[t]){for(var i=e.querySelectorAll(\"img\"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if(\"string\"==typeof this.options.background){var r=e.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var u={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(e){var t=getComputedStyle(e);if(t)for(var i=/url\\((['\"])?(.*?)\\1\\)/gi,n=i.exec(t.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,e),n=i.exec(t.backgroundImage)}},o.prototype.addImage=function(e){var t=new r(e);this.images.push(t)},o.prototype.addBackground=function(e,t){var i=new s(e,t);this.images.push(i)},o.prototype.check=function(){function e(e,i,n){setTimeout(function(){t.progress(e,i,n)})}var t=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(t){t.once(\"progress\",e),t.check()}):void this.complete()},o.prototype.progress=function(e,t,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded,this.emitEvent(\"progress\",[this,e,t]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,e),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log(\"progress: \"+i,e,t)},o.prototype.complete=function(){var e=this.hasAnyBroken?\"fail\":\"done\";if(this.isComplete=!0,this.emitEvent(e,[this]),this.emitEvent(\"always\",[this]),this.jqDeferred){var t=this.hasAnyBroken?\"reject\":\"resolve\";this.jqDeferred[t](this)}},r.prototype=Object.create(t.prototype),r.prototype.check=function(){var e=this.getIsImageComplete();return e?void this.confirm(0!==this.img.naturalWidth,\"naturalWidth\"):(this.proxyImage=new Image,this.proxyImage.addEventListener(\"load\",this),this.proxyImage.addEventListener(\"error\",this),this.img.addEventListener(\"load\",this),this.img.addEventListener(\"error\",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},r.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent(\"progress\",[this,this.img,t])},r.prototype.handleEvent=function(e){var t=\"on\"+e.type;this[t]&&this[t](e)},r.prototype.onload=function(){this.confirm(!0,\"onload\"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,\"onerror\"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener(\"load\",this),this.proxyImage.removeEventListener(\"error\",this),this.img.removeEventListener(\"load\",this),this.img.removeEventListener(\"error\",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener(\"load\",this),this.img.addEventListener(\"error\",this),this.img.src=this.url;var e=this.getIsImageComplete();e&&(this.confirm(0!==this.img.naturalWidth,\"naturalWidth\"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener(\"load\",this),this.img.removeEventListener(\"error\",this)},s.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent(\"progress\",[this,this.element,t])},o.makeJQueryPlugin=function(t){t=t||e.jQuery,t&&(h=t,h.fn.imagesLoaded=function(e,t){var i=new o(this,e,t);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o});\n/*! lz-string.min.js v1.5.0 | (c) 2023 Pieroxy | MIT license */\nvar LZString=function(){var r=String.fromCharCode,o=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\",n=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$\",e={};function t(r,o){if(!e[r]){e[r]={};for(var n=0;n<r.length;n++)e[r][r.charAt(n)]=n}return e[r][o]}var i={compressToBase64:function(r){if(null==r)return\"\";var n=i._compress(r,6,function(r){return o.charAt(r)});switch(n.length%4){default:case 0:return n;case 1:return n+\"===\";case 2:return n+\"==\";case 3:return n+\"=\"}},decompressFromBase64:function(r){return null==r?\"\":\"\"==r?null:i._decompress(r.length,32,function(n){return t(o,r.charAt(n))})},compressToUTF16:function(o){return null==o?\"\":i._compress(o,15,function(o){return r(o+32)})+\" \"},decompressFromUTF16:function(r){return null==r?\"\":\"\"==r?null:i._decompress(r.length,16384,function(o){return r.charCodeAt(o)-32})},compressToUint8Array:function(r){for(var o=i.compress(r),n=new Uint8Array(2*o.length),e=0,t=o.length;e<t;e++){var s=o.charCodeAt(e);n[2*e]=s>>>8,n[2*e+1]=s%256}return n},decompressFromUint8Array:function(o){if(null==o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;e<t;e++)n[e]=256*o[2*e]+o[2*e+1];var s=[];return n.forEach(function(o){s.push(r(o))}),i.decompress(s.join(\"\"))},compressToEncodedURIComponent:function(r){return null==r?\"\":i._compress(r,6,function(r){return n.charAt(r)})},decompressFromEncodedURIComponent:function(r){return null==r?\"\":\"\"==r?null:(r=r.replace(/ /g,\"+\"),i._decompress(r.length,32,function(o){return t(n,r.charAt(o))}))},compress:function(o){return i._compress(o,16,function(o){return r(o)})},_compress:function(r,o,n){if(null==r)return\"\";var e,t,i,s={},u={},a=\"\",p=\"\",c=\"\",l=2,f=3,h=2,d=[],m=0,v=0;for(i=0;i<r.length;i+=1)if(a=r.charAt(i),Object.prototype.hasOwnProperty.call(s,a)||(s[a]=f++,u[a]=!0),p=c+a,Object.prototype.hasOwnProperty.call(s,p))c=p;else{if(Object.prototype.hasOwnProperty.call(u,c)){if(c.charCodeAt(0)<256){for(e=0;e<h;e++)m<<=1,v==o-1?(v=0,d.push(n(m)),m=0):v++;for(t=c.charCodeAt(0),e=0;e<8;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;e<h;e++)m=m<<1|t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=c.charCodeAt(0),e=0;e<16;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;0==--l&&(l=Math.pow(2,h),h++),s[p]=f++,c=String(a)}if(\"\"!==c){if(Object.prototype.hasOwnProperty.call(u,c)){if(c.charCodeAt(0)<256){for(e=0;e<h;e++)m<<=1,v==o-1?(v=0,d.push(n(m)),m=0):v++;for(t=c.charCodeAt(0),e=0;e<8;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;e<h;e++)m=m<<1|t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=c.charCodeAt(0),e=0;e<16;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;0==--l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;for(;;){if(m<<=1,v==o-1){d.push(n(m));break}v++}return d.join(\"\")},decompress:function(r){return null==r?\"\":\"\"==r?null:i._decompress(r.length,32768,function(o){return r.charCodeAt(o)})},_decompress:function(o,n,e){var t,i,s,u,a,p,c,l=[],f=4,h=4,d=3,m=\"\",v=[],g={val:e(0),position:n,index:1};for(t=0;t<3;t+=1)l[t]=t;for(s=0,a=Math.pow(2,2),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 2:return\"\"}for(l[3]=c,i=c,v.push(c);;){if(g.index>o)return\"\";for(s=0,a=Math.pow(2,d),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(c=s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 2:return v.join(\"\")}if(0==f&&(f=Math.pow(2,d),d++),l[c])m=l[c];else{if(c!==h)return null;m=i+i.charAt(0)}v.push(m),l[h++]=i+m.charAt(0),i=m,0==--f&&(f=Math.pow(2,d),d++)}}};return i}();\"function\"==typeof define&&define.amd?define(function(){return LZString}):\"undefined\"!=typeof module&&null!=module?module.exports=LZString:\"undefined\"!=typeof angular&&null!=angular&&angular.module(\"LZString\",[]).factory(\"LZString\",function(){return LZString});\n/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/dist/FileSaver.js */\n(function(a,b){if(\"function\"==typeof define&&define.amd)define([],b);else if(\"undefined\"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){\"use strict\";function b(a,b){return\"undefined\"==typeof b?b={autoBom:!1}:\"object\"!=typeof b&&(console.warn(\"Deprecated: Expected third argument to be a object\"),b={autoBom:!b}),b.autoBom&&/^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(a.type)?new Blob([\"\\uFEFF\",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open(\"GET\",a),d.responseType=\"blob\",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error(\"could not download file\")},d.send()}function d(a){var b=new XMLHttpRequest;b.open(\"HEAD\",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent(\"click\"))}catch(c){var b=document.createEvent(\"MouseEvents\");b.initMouseEvent(\"click\",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f=\"object\"==typeof window&&window.window===window?window:\"object\"==typeof self&&self.self===self?self:\"object\"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||(\"object\"!=typeof window||window!==f?function(){}:\"download\"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement(\"a\");g=g||b.name||\"download\",j.download=g,j.rel=\"noopener\",\"string\"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target=\"_blank\")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:\"msSaveOrOpenBlob\"in navigator?function(f,g,h){if(g=g||f.name||\"download\",\"string\"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement(\"a\");i.href=f,i.target=\"_blank\",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open(\"\",\"_blank\"),g&&(g.document.title=g.document.body.innerText=\"downloading...\"),\"string\"==typeof b)return c(b,d,e);var h=\"application/octet-stream\"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\\/[\\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&\"undefined\"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,\"data:attachment/file;\"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,\"undefined\"!=typeof module&&(module.exports=g)});\n/*! seedrandom.js v3.0.5 | Copyright 2019 David Bau. | MIT license */\n!function(f,a,c){var s,l=256,p=\"random\",d=c.pow(l,6),g=c.pow(2,52),y=2*g,h=l-1;function n(n,t,r){function e(){for(var n=u.g(6),t=d,r=0;n<g;)n=(n+r)*l,t*=l,r=u.g(1);for(;y<=n;)n/=2,t/=2,r>>>=1;return(n+r)/t}var o=[],i=j(function n(t,r){var e,o=[],i=typeof t;if(r&&\"object\"==i)for(e in t)try{o.push(n(t[e],r-1))}catch(n){}return o.length?o:\"string\"==i?t:t+\"\\0\"}((t=1==t?{entropy:!0}:t||{}).entropy?[n,S(a)]:null==n?function(){try{var n;return s&&(n=s.randomBytes)?n=n(l):(n=new Uint8Array(l),(f.crypto||f.msCrypto).getRandomValues(n)),S(n)}catch(n){var t=f.navigator,r=t&&t.plugins;return[+new Date,f,r,f.screen,S(a)]}}():n,3),o),u=new m(o);return e.int32=function(){return 0|u.g(4)},e.quick=function(){return u.g(4)/4294967296},e.double=e,j(S(u.S),a),(t.pass||r||function(n,t,r,e){return e&&(e.S&&v(e,u),n.state=function(){return v(u,{})}),r?(c[p]=n,t):n})(e,i,\"global\"in t?t.global:this==c,t.state)}function m(n){var t,r=n.length,u=this,e=0,o=u.i=u.j=0,i=u.S=[];for(r||(n=[r++]);e<l;)i[e]=e++;for(e=0;e<l;e++)i[e]=i[o=h&o+n[e%r]+(t=i[e])],i[o]=t;(u.g=function(n){for(var t,r=0,e=u.i,o=u.j,i=u.S;n--;)t=i[e=h&e+1],r=r*l+i[h&(i[e]=i[o=h&o+t])+(i[o]=t)];return u.i=e,u.j=o,r})(l)}function v(n,t){return t.i=n.i,t.j=n.j,t.S=n.S.slice(),t}function j(n,t){for(var r,e=n+\"\",o=0;o<e.length;)t[h&o]=h&(r^=19*t[h&o])+e.charCodeAt(o++);return S(t)}function S(n){return String.fromCharCode.apply(0,n)}if(j(c.random(),a),\"object\"==typeof module&&module.exports){module.exports=n;try{s=require(\"crypto\")}catch(n){}}else\"function\"==typeof define&&define.amd?define(function(){return n}):c[\"seed\"+p]=n}(\"undefined\"!=typeof self?self:this,[],Math);\n/*! console_hack.js | (c) 2015 Thomas Michael Edwards | Licensed under SugarCube's Simple BSD license */\n!function(){for(var methods=[\"assert\",\"clear\",\"count\",\"debug\",\"dir\",\"dirxml\",\"error\",\"exception\",\"group\",\"groupCollapsed\",\"groupEnd\",\"info\",\"log\",\"markTimeline\",\"profile\",\"profileEnd\",\"table\",\"time\",\"timeEnd\",\"timeline\",\"timelineEnd\",\"timeStamp\",\"trace\",\"warn\"],length=methods.length,noop=function(){},console=window.console=window.console||{};length--;){var method=methods[length];console[method]||(console[method]=noop)}}();\n}else{document.documentElement.setAttribute(\"data-init\", \"lacking\");}\n</script>\n<style id=\"style-normalize\" type=\"text/css\">/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}</style>\n<style id=\"style-init-screen\" type=\"text/css\">@-webkit-keyframes init-loading-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes init-loading-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes init-loading-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}#init-screen{display:none;z-index:500000;position:fixed;top:0;left:0;height:100%;width:100%;font:28px/1 Helmet,Freesans,sans-serif;font-weight:700;color:#eee;background-color:#111;text-align:center}#init-screen>div{display:none;position:relative;margin:0 auto;max-width:1136px;top:25%}html[data-init=lacking] #init-screen,html[data-init=loading] #init-screen,html[data-init=no-js] #init-screen{display:block}html[data-init=lacking] #init-lacking,html[data-init=no-js] #init-no-js{display:block;padding:0 1em}html[data-init=no-js] #init-no-js{color:red}html[data-init=loading] #init-loading{-webkit-animation:init-loading-spin 2s linear infinite;-o-animation:init-loading-spin 2s linear infinite;animation:init-loading-spin 2s linear infinite;border:12px solid transparent;border-bottom-color:#7f7f7f;border-radius:50%;border-top-color:#7f7f7f;display:block;height:100px;width:100px}html[data-init=loading] #init-loading>div{text-indent:16128px;overflow:hidden;white-space:nowrap}html[data-init=loading] #story,html[data-init=loading] #ui-bar{display:none!important}</style>\n<style id=\"style-font-icons\" type=\"text/css\">@font-face{font-family:sc-icons;font-display:block;src:url(\"data:application/octet-stream;base64,d09GRgABAAAAAFRoAAsAAAAAVBwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgD1IUnWNtYXAAAAFoAAACdAAAAnQzsxFSZ2FzcAAAA9wAAAAIAAAACAAAABBnbHlmAAAD5AAASzgAAEs4ynuL3WhlYWQAAE8cAAAANgAAADYc3WiNaGhlYQAAT1QAAAAkAAAAJAiCBP1obXR4AABPeAAAAfAAAAHwyjAFu2xvY2EAAFFoAAAA+gAAAPpXLER0bWF4cAAAUmQAAAAgAAAAIACEAIVuYW1lAABShAAAAcIAAAHCiTu08nBvc3QAAFRIAAAAIAAAACAAAwAAAAMDyQGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA+CoDgP+AAIADgACAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEAlgAAACSAIAABgASAAEAIPAC8AXwDvAR8BPwFfAZ8CPwKPAu8E7wWvBe8GPwaPBq8G7wcfB48InwjfCT8JzwoPDC8MfwyfDQ8Nrw5/Dr8P7xDvEQ8SfxOvE+8ULxRPFG8UrxUvGG8YjxkfGr8d3x4PH48gXyRPKL8o3y6vLt8vHy+fMe813zgvQQ9Vr1b/V09cD2qfeM99n4Kv/9//8AAAAAACDwAvAE8AzwEPAT8BXwGfAj8CbwLvBI8FDwXvBg8GXwavBu8HDwd/CJ8I3wk/Cc8KDwwfDH8Mnw0PDX8Ofw6/D+8Q3xEPEn8TfxPvFB8UTxRvFK8VDxhfGI8ZHxq/Hd8eDx+PIE8kDyi/KN8ury7fLx8vnzHvNd84H0EPVa9W31dPXA9qn3jPfZ+Cn//f//AAH/4xACEAEP+w/6D/kP+A/1D+wP6g/lD8wPyw/ID8cPxg/FD8IPwQ+8D6wPqQ+kD5wPmQ95D3UPdA9uD2gPXA9ZD0cPOQ84DyIPEw8QDw4PDQ8MDwkPBA7SDtEOyQ6wDn8OfQ5mDlsOIQ3bDdoNfg18DXkNcg1ODRAM7QxgCxcLBQsBCrYJzgjsCKAIUQADAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAIAAP+OA/IDgAArAEcAACUWFA8BBiIvAS4BPQEOASMiJy4BJyY1NDc+ATc2MzIXHgEXFhUUBgczMhYXJTI3PgE3NjU0Jy4BJyYjIgcOAQcGFRQXHgEXFgPyDg45DigOxwcHNYNIVkxMcSAhISBxTExWVkxMcSAhLykhCRIH/nU1Ly5GFBQUFEYuLzU1Ly5GFBQUFEYuLwsOKA45Dg7HBxIJISkvISBxTExWVkxMcSAhISBxTExWSIM1BwcOFBRGLi81NS8uRhQUFBRGLi81NS8uRhQUAAAAAAEAEv/TA+4DNQAjAAABFhceAQcGBwEGIicBJicmNjc2NzY3NhYXFh8BNzY3PgEXFhcDnS8YGQUUFCr+fRM1Ev59KxMUBRkYLyoxMWUvMCYnJyYwL2UxMikDAyg2NnI3Nyz+cBMTAZAsNzdyNjYoIw8OCBYWJykpJxYWCA4PIwAAAQA8/4cERANcABgAAAE2MhcTBR4BDwETFgYnJQUGJjcTJyY2NyUCBxFQEYMBJCgYHNQyB0Ej/vv++yNBBzLUHBknASQDXCQk/vgrBksczv7dKC4SiooSLigBI84cSwYrAAAAAAEADwARA/EC7wAVAAAlASY0PwE2Mh8BATYyHwEWFAcBBiInAVz+sw8PSA8rD+AB4A8rD0gPD/2zDyoPEQFNDyoPSQ8P4AHgDw9JDyoP/bMPDwAAAAEAEgAyAq4CzgAjAAABFxYUDwEGIi8BBwYiLwEmND8BJyY0PwE2Mh8BNzYyHwEWFAcB5ckSEi0SNBPIyBM0Ei0SEsnJEhItEjQTyMgTNBItEhIBgMgTNBItEhLJyRISLRI0E8jIEzQSLRISyckSEi0SNBMAAwAA/44D8gOAACMAUABsAAABFRQGKwEVFAYrASImPQEjIiY9ATQ2OwE1NDY7ATIWHQEzMhYBBwYiLwEuAT0BDgEjIicuAScmNTQ3PgE3NjMyFx4BFxYVFAYHMzIWHwEWFAcBNCcuAScmIyIHDgEHBhUUFx4BFxYzMjc+ATc2AmAOCnAOCkAKDnAKDg4KcA4KQAoOcAoOAZI5DicOyAcHNYNIVkxMcSAhISBxTExWVkxMcSAhLykhCRIHxw4O/r4VFkkyMjg4MjFKFhUVFkkyMjg4MjFKFhUCAEAKDnAKDg4KcA4KQAoOcAoODgpwDv29OQ4OxwcSCSEpLyEgcUxMVlZMTHEgISEgcUxMVkiDNQcHxw4oDgIZODIxShYVFRZJMjI4ODIxShYVFRZJMjIAAAMAAP+OA/IDgAAPADwAWAAAARUUBiMhIiY9ATQ2MyEyFgEHBiIvAS4BPQEOASMiJy4BJyY1NDc+ATc2MzIXHgEXFhUUBgczMhYfARYUBwE0Jy4BJyYjIgcOAQcGFRQXHgEXFjMyNz4BNzYCYA4K/rAKDg4KAVAKDgGSOQ4nDsgHBzWDSFZMTHEgISEgcUxMVlZMTHEgIS8pIQkSB8cODv6+FRZJMjI4ODIxShYVFRZJMjI4ODIxShYVAgBACg4OCkAKDg79vTkODscHEgkhKS8hIHFMTFZWTExxICEhIHFMTFZIgzUHB8cOKA4CGTgyMUoWFRUWSTIyODgyMUoWFRUWSTIyAAAAAAIAEP+QA/ADgAA+AE4AAAEWFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzY3NhYfARYGBw4BFRQXHgEXFjMyNz4BNzY1NCYnLgE/AT4BFwMUBisBIiY1ETQ2OwEyFhUDIC8nJjYPDycnhlpaZ2ZbWocoJw8ONyYmMBEqCx8JBw8+ShoaWz49RkU9PVwbGkdBDwcJHwsqEdAcFEAUHBwUQBQcAxQiLCxnOjs+Z1pahycnJyeGWltmPzo6aCwsIgwJEzgQIwsujVNFPT1cGhsaGlw9PkdOjjALIxA4EwkM/lwUHBwUAeAUHBwUAAAAAgAm/5wD2gNkAFMAXwAAAR4BBw4BBw4BLwEOAQcVFAYHBiInLgE9AS4BJwcGJicuAScmNj8BJjQ3Jy4BNz4BNz4BHwE+ATc1NDY3PgEXHgEdAR4BFzc2FhceARcWBg8BFhQHBTI2NTQmIyIGFRQWA88HBgIRNyUGEQdVGz4hCgk0bzcICyE+GlYHEQUlOBECBgdWBwdWBwYCETglBREHVRs+IQsING83CAshPhtVBxEFJTgRAgYHVQYG/oZCXl5CQl5eAQkFDwk1YCgGAwUxFyQLYwgNAgwMAg0IYwskFzEFAwYoYDUJDwQyIkcjMQQQCDZfKAcCBDEXIwxiCQ0CCwEMAg0JYgwjFzEEAgYpXzYIDwUxI0YjWl5CQl5eQkJeAAAAAAIAAP/ABIADQAAjAFcAAAE+ATMyFhcBERQGIyciJjU4ATE1NCYrASIGHQEUBiMHIiY1ESUeARUUBg8BDgEjIiYnAS4BIyIGBwEOASMiJi8BLgE1NDY3AT4BMzIWHwE1NDY7ATIWFRECMQMIBAQIAwFxEw3gDRMTDYANExMN4A0TA7cEBQMCMwQJBgQIA/4pAwgEBAgD/ikDCAQGCQQzAgMFBAH6DCARESAMsw4KcAoOAlcDAwMD/tH+uA0TARIOvw0TEw2/DhIBEw0BSGEDCgYECAM+BAUDAwGDAwMDA/59AwMFBD4DCAUFCgMBoQoMDAqTkQoODgr+6wAAAAQAAP+ABAADgAAWAC0AOQBFAAABMzIWFREzMhYHAQYiJwEmNjsBETQ2MwEVFAYjISImPQE0NjMhFxYyPwEhMhYVBzQmIyIGFRQWMzI2NzQmIyIGFRQWMzI2AbCgFByvGxQS/s8LIAv+zxMVGrAcFAJQHBT8YBQcHBQBJWIfVB9iASUUHPgXERAYFxEQGIAXERAYFxEQGAOAHBT+sDET/s8LCwExEzEBUBQc/RDgFBwcFOAUHGIeHmIcFLAQGBcREBgXERAYFxEQGBcAAAIAAP+AA4ADgAAgACkAAAEyFhURFAYjISImNRE0NjsBNTQ3PgE3NjMyFx4BFxYdASM1NCYjIgYdAQMgKDg4KP1AKDg4KDAYGFI4Nz8/NzhSGBigVDw8VAHAOCj+gCg4OCgBgCg4kD83OFIYGBgYUjg3P5CQPFRUPJAAAAABAAAADgIAAvIAEQAAATYWFREUBi8BIyImNRE0NjsBAa4WPDsXsswUHBwUzALyFhgg/WAgGBayHBQBIBQcAAAAAgAAAAwDAALwABEAKgAAATYWFREUBi8BIyImNRE0NjsBBR4BFRQGBwYmJyY2Nz4BNTQmJy4BNz4BFwGuFzs7F7LMFBwcFMwBqCsxMSsRJgoJCxEUFhYUEQsJCiYRAvAWGCD9YCAYFrIcFAEgFBwmGFIwMFIYCQsREiYJCyUWFiULCSYSEQsJAAQAAP+oBIADWAARADoAWwB0AAABNhYVERQGLwEjIiY1ETQ2OwEBFhceARcWFRQHDgEHBgcGJicmNjc2Nz4BNzY1NCcuAScmJy4BNz4BFxMUBw4BBwYHBiYnJjY3PgE1NCYnLgE3PgEXFhceARcWFSUeARUUBgcGJicmNjc+ATU0JicuATc+ARcBrhc7OxeyzBQcHBTMAoU8Ly9CEhEREkIvLzwSJwoLCBExKCc2Dw4ODzYnKDERCAsLJxE/DAstHyApEiYKCggRPENDPBEICgsnECkgHy0LDP7kKzExKxEmCgkLERQWFhQRCwkKJhEC8hYYIP1gIBgWshwUASAUHAEYJzQ0ekRER0dERHo0NCcLCRARJwsgKytlODk7Ozk4ZSsrIAsnEREIC/4oMC0tUCMiGQwLDxEnCyZ7RkZ7JgsnERAJCxkiI1AtLTCaGFIwMFIYCQsREiYJCyUWFiULCSYSEQsJAAAAAAEAAP+AAwADgAAKAAAXETQ2MyEyFhURJQA4KAJAKDj+gIADoCg4OCj8YOAAAQCA/8ADAANAABkAABcRNDY7ATIWFREBNhYVERQGJwERFAYrASImgA4KYAoOAYcfSkof/nkOCmAKDigDUAoODgr+nwFqGiIp/QApIhoBaP6hCg4OAAAAAAEAAAAABAADAAAkAAA3ETQ2OwEyFhURATYWFREBNhYVERQGJwERFAYnAREUBisBIiY1AA4KUAoOAVcfSgFXH0pKH/6pSh/+qQ4KUAoOGALQCg4OCv7QATkaIin++AE5GiIp/YApIhoBNv77KSIaATb+0woODgoAAAIAFwAPBAAC8QALABcAABMmNDcBNhYVERQGJxMmNDcBNhYVERQGJxcXFwGAH0pKH4AXFwGAH0pKHwFPEzwTAUAaIin9gCkiGgFAEzwTAUAaIin9gCkiGgABAAD/jQNRA3MACwAAARYUBwEGJjURNDYXA1EvL/1AMGFmKwHTHG4c/mAcNzgDQD8tGQAAAgAA/8IDgANCAA8AHwAABSMiJjURNDY7ATIWFREUBiUUBisBIiY1ETQ2OwEyFhUBIMAoODgowCg4OAI4OCjAKDg4KMAoOD44KALAKDg4KP1AKDhgKDg4KALAKDg4KAAAAQAA/8ADgANAAA8AAAEyFhURFAYjISImNRE0NjMDICg4OCj9QCg4OCgDQDgo/UAoODgoAsAoOAACAAAADwPpAvEACwAXAAABFhQHAQYmNRE0NhcDFhQHAQYmNRE0NhcD6RcX/oAfSkofgBcX/oAfSkofAbETPBP+wBoiKQKAKSIa/sATPBP+wBoiKQKAKSIaAAAAAAEAAAAABAADAAAjAAABERQGKwEiJjURAQYmNREBBiY1ETQ2FwERNDYXARE0NjsBMhYEAA4KUAoO/qkfSv6pH0pKHwFXSh8BVw4KUAoOAuj9MAoODgoBMP7HGiIpAQj+xxoiKQKAKSIa/skBBikiGv7JAS4KDg4AAAEAgP/AAwADQAAZAAABERQGKwEiJjURAQYmNRE0NhcBETQ2OwEyFgMADgpgCg7+eR9KSh8Bhw4KYAoOAyj8sAoODgoBYf6WGiIpAwApIhr+mAFfCg4OAAACAAD/wAOAAyEADwAcAAAlFRQGIyEiJj0BNDYzITIWJSImNwE2MhcBFgYjIQOAJRv9ABslJRsDABsl/OA+MyoBYB1UHQFgKjM+/UCAgBslJRuAGyUlZXMuAYAfH/6ALnMAAAAAAQBF/9kCOwMnABUAABMBNjIfARYUBwkBFhQPAQYiJwEmNDdFAYUOKA4tDg7+zAE0Dg4tDigO/nsODgGiAYUODi4OJw/+y/7LDycOLg4OAYUOKA4AAQBF/9kCOwMnABUAAAkBBiIvASY0NwkBJjQ/ATYyFwEWFAcCO/57DigOLQ4OATT+zA4OLQ4oDgGFDg4BXv57Dg4uDicPATUBNQ8nDi4ODv57DigOAAAAAAIAEP+QA/ADcAAbAD8AAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzYBNTQmKwE1NCYrASIGHQEjIgYdARQWOwEVFBY7ATI2PQEzMjYCAGdaWocnJycnh1paZ2daWocnJycnh1paAYcOCrgOCnAKDrgKDg4KuA4KcAoOuAoOA3AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf92HAKDrgKDg4KuA4KcAoOuAoODgq4DgAAAAIAEP+QA/ADcAAbACsAAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzYDITI2PQE0JiMhIgYdARQWAgBnWlqHJycnJ4daWmdnWlqHJycnJ4daWqECEAoODgr98AoODgNwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/cAOCnAKDg4KcAoOAAACABD/kAPwA3AAGwBAAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2ASc3NjQvASYiDwEnJiIPAQYUHwEHBhQfARYyPwEXFjI/ATY0JwIAZ1pahycnJyeHWlpnZ1pahycnJyeHWloBWoODBwdPBxQHgoIHFAdPBweDgwcHTwcUB4KCBxQHTwcHA3AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf9joKCBxQHTwcHg4MHB08HFAeCggcUB08HB4ODBwdPBxQHAAIAEP+QA/ADcAAbADEAAAEUBw4BBwYjIicuAScmNTQ3PgE3NjMyFx4BFxYJATY0LwEmIgcBJyYiDwEGFB8BFjI3A/AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf91wFwCQkuCRsJ/tSMCRsJLgkJ0AoaCgGAZ1pahycnJyeHWlpnZ1pahycnJyeHWlr+kgFwChoKLQkJ/tSMCQktChoK0AkJAAAAAwAQ/5AD8ANwABsASQBVAAABFAcOAQcGIyInLgEnJjU0Nz4BNzYzMhceARcWJSIGBwYWHwEWNjc+ATMyFhUUBgcOAR0BFBY7ATI2PQE0Nz4BNzY1NCcuAScmIwMiBhUUFjMyNjU0JgPwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/h1RbykFAwhFCBMGGy8pHzwiHyNKDgpwCg4aGj4aGhQVQiopKw0mNjYmJjY2AYBnWlqHJycnJ4daWmdnWlqHJycnJ4daWuVCPgcTBjUGAwgiJSQeFh0REzw+CAoODgoDFQ4PKCEgOiwlJTcPEP4QNiYmNjYmJjYAAAAAAwAQ/5AD8ANwABsAJwBGAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2FyIGFRQWMzI2NTQmEzU0JisBNTQmKwEiBh0BFBY7ARUjIgYdARQWOwEyNgIAZ1pahycnJyeHWlpnZ1pahycnJyeHWlpnIzExIyMxMU0OChgOCoAKDg4KGBgKDg4KsAoOA3AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyfcMSMjMTEjIzH+BDAKDsgKDg4KMAoOgA4KMAoODgAAAAADABD/kAPwA3AAGwArADsAAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzYFJicuAQcGBwE2NzYmJyYnARYXHgE3NjcBBgcGFhcWFwIAZ1pahycnJyeHWlpnZ1pahycnJyeHWloBazE8PH4+PTUCASUQEQoaGzH9+DE8PH4+PTX9/yUQEQoaGzEDcCcnh1paZ2daWocnJycnh1paZ2daWocnJ+wxGxoKERAl/f81PT5+PDwx/fgxGxoKERAlAgE1PT5+PDwxAAEADv/ZA4ADJwAeAAAlBwYiJwEmNDcBNjIfARYUDwEhMhYdARQGIyEXFhQHAgMsDigO/nsODgGFDigOLA4P8QI/FBwcFP3B8Q8OBi0ODgGFDigOAYUODi0OKA7mHBRAFBzmDigOAAAAAQAA/9kDcgMnAB4AAAE3NjIXARYUBwEGIi8BJjQ/ASEiJj0BNDYzIScmNDcBfSwOKA4BhQ4O/nsOKA4sDg/x/cEUHBwUAj/xDw4C+i0ODv57DigO/nsODi0OKA7mHBRAFBzmDigOAAABABn/wANmAzIAHgAAEycmNDcBNjIXARYUDwEGIi8BERQGKwEiJjURBwYiJ0YtDg4BhQ4oDgGEDw8sDikO5RwUQBQc5g4oDgE9LA4oDgGFDg7+ew4nDi0OD/H9wRQcHBQCP/EPDgAAAAEAGf/OA2cDQAAeAAABFxYUBwEGIicBJjQ/ATYyHwERNDY7ATIWFRE3NjIXAzotDg7+ew4oDv57Dg4tDigO5hwUQBQc5g4oDgHDLA4oDv57Dg4BhQ4oDiwOD/ECPxQcHBT9wfEPDgAABAAA/8ADgANAABQAKQA+AFMAABM1NDY7ATIWHQEUBisBFRQGKwEiJgE0NjsBMhYdARQGKwEiJj0BIyImNQEyFh0BFAYrASImPQE0NjsBNTQ2MwEUBisBIiY9ATQ2OwEyFh0BMzIWFQAcFPgKDg4KqA4KUAoOAkAOCvgUHA4KUAoOqAoOASgKDhwU+AoODgqoDgr+KA4K+BQcDgpQCg6oCg4CGPgUHA4KUAoOqAoODgEaCg4cFPgKDg4KqA4K/igOCvgUHA4KUAoOqAoO/tgKDhwU+AoODgqoDgoAAAQAAP/AA4ADQAAUACkAPgBTAAABIyImPQE0NjsBMhYdATMyFh0BFAYlFAYrASImPQE0NjsBNTQ2OwEyFhURFAYrASImPQEjIiY9ATQ2OwEyFhUFFAYrASImPQE0NjsBMhYdARQGKwEDaPgUHA4KUAoOqAoODv3OHBT4Cg4OCqgOClAKDg4KUAoOqAoODgr4FBwBgA4KUAoOHBT4Cg4OCqgCABwU+AoODgqoDgpQCg4wFBwOClAKDqgKDg4K/LAKDg4KqA4KUAoOHBT4Cg4OCvgUHA4KUAoOAAEAAP/AA4ADQAAjAAABMhYdARQGIyERFAYrASImNREhIiY9ATQ2MyERNDY7ATIWFREDQBslJRv+4CUbQBsl/uAbJSUbASAlG0AbJQHgJRtAGyX+4BslJRsBICUbQBslASAbJSUb/uAAAQAAASADgAHgAA8AAAEyFh0BFAYjISImPQE0NjMDQBslJRv9ABslJRsB4CUbQBslJRtAGyUAAAADABD/kAPwA3AAGwAnADcAAAEUBw4BBwYjIicuAScmNTQ3PgE3NjMyFx4BFxYFIgYVFBYzMjY1NCYDEx4BOwEyNjcTNiYrASIGA/AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf+ECY2NiYmNjZ9DgEOCWIJDgEOAQ4LfgsOAYBnWlqHJycnJ4daWmdnWlqHJycnJ4daWss2JiY2NiYmNgFL/vAKDQ0KARAKDw8AAwAAAAAEgAMAACgASQBlAAABHgEVFAYHBgcOAQcGIyInLgEnJicuATU0Njc2Nz4BNzYzMhceARcWFwE4ATEyNz4BNzY1MTQnLgEnJiMiBw4BBwYVFBceARcWMxE4ATEyFhUUBiMiJjU0NjceATMyNjU0Jic+ATMEeQMEBAMpOzuTVlVcXFVWkzs7KQMEBAMpOzuTVlVcXFVWkzs7Kf3HPDQ1ThYXFxZONTQ8PDQ1ThYXFxZONTQ8UHBwUE9wAwQLHRAoOAoJDBoNAZ0GDwgIDwZQQUFeGRoaGV5BQVAGDwgIDwZQQUFeGRoaGV5BQVD+wxcWTjU0PDw0NU4WFxcWTjU0PDw0NU4WFwHgcFBPcHBPDRoMCQo4KBAdCwQEAAAAAwAA/4AFAAOAAB8ATwB0AAAlMjY3Fw4BIyInLgEnJicuATU0Njc+ATcXFhceARcWMwUeARUUBg8BDgEjIiYnAS4BNTQ2PwE+ATMyFh8BPgEzMhceARcWFx4BFRQGBw4BByc+ATU4ATE0Jy4BJyYjMSIGBxc+ATU0Jic+ATMyFhUcARUUBgcCgA0aDWgmTihcVVaTOzspAwQEAw8mFNIEGBhNMjI5AnQFBwQDJwQOBwYKBPtnBQcEAycEDgcGCgT+QpVQXFVWkzs7KQMEBAMeUjKTDQ8XFk41NDw0XSWTAQIKCQ0bDU9vBgRgAwJQCgsaGV5BQVAGDwgIDwYeNxqiODAxSBQVdAUNBwYKBDMFBwQDA40FDQcGCgQzBQcEA8QjKBoZXkFBUAYPCAgPBjtnKnEbPSA8NDVOFhcjH3IFCgUQHQsEBG9OAQEBEB0OAAAAAwAN/4AEcwNQAAsAFwAnAAAlFgYjISImNwE2MhcDIgYVFBYzMjY1NCYDEx4BOwEyNjcTNiYrASIGBHMcODf8QDc4HAHgHG8bUyY2NiYmNjZ9DgEOCWIJDgEOAQ4LfgsOEDBgYDADQDAw/Ww2JiY2NiYmNgFL/vAKDQ0KARAKDw8AAAAAAQAZAIUDZwJ7ABUAAAkBFhQPAQYiJwkBBiIvASY0NwE2MhcB4gGFDg4uDicP/sv+yw8nDi4ODgGFDigOAnv+ew4oDi0ODgE0/swODi0OKA4BhQ4OAAAAAAEAGQCFA2cCewAVAAAlASY0PwE2MhcJATYyHwEWFAcBBiInAZ7+ew4OLg4nDwE1ATUPJw4uDg7+ew4oDoUBhQ4oDi0ODv7MATQODi0OKA7+ew4OAAEAPP+IAkADgAAPAAABEQUGJjcTJyY2NyUTPgEzAkD++yNBBzLUHBknASSDCCARA4D8kYkTLycBI84cSwYrAQgSEgAAAQAA/4kDAAOAAC0AAAEeARUUBiMhFRQGDwEGIi8BLgE9ASEiJjU0Nj8BIyImPQE0NjMhMhYdARQGKwECVEhkHBT+8AEBMAQUBDABAf7wFBxjSRhUFBwcFAIgFBwcFFQB0yF1TRQc0AIEAWAJCWABBALQHBRMdiHtHBRgFBwcFGAUHAAABAAA/4AEAAN1ABYAMAA8AEgAACUjIiY1ESMiJjcBNjIXARYGKwERFAYjJRUUBiMhIiY9ATQ2MyEVFBY7ATI2PQEhMhYHNCYjIgYVFBYzMjY3NCYjIgYVFBYzMjYCUKAUHK8bFBIBMQsgCwExExUbrxwUAbAcFPxgFBwcFAEQQi6gLkIBEBQc+BcREBgXERAYgBcREBgXERAYgBwUAVAxEwExCwv+zxMx/rAUHBDgFBwcFOAUHBAuQkIuEBzEEBgXERAYFxEQGBcREBgXAAAAAAEAAP+AA4ADgAAwAAABMhYVERQGIyEiJjURNDY7ATU0Nz4BNzYzMhceARcWHQEUBisBIiY9ATQmBw4BHQEhAyAoODgo/UAoODgoMBgXUzc3Pz84N1MYGBwUQBQcVTw8UwHwAYA4KP7AKDg4KAFAKDjNPzg4UxgZGBdTODc/IBQcHBQgPFUBAVU8zgAABAAAAAAEgAMAAA8AJAAwADwAAAEVFAYjISImPQE0NjMhMhYnITgBMSIGBxM+ATMhMhYXEy4BIzEHIgYVFBYzMjY1NCYjIgYVFBYzMjY1NCYEgDgo/EAoODgoA8AoOGD8QBEeD8IMKhkCGhkqDMIPHxBgGyUlGxslJdsbJSUbGyUlASDAKDg4KMAoODh4BgYBIRQXFxT+3wYGwCUbGyUlGxslJRsbJSUbGyUAAAIAFv+WA+oDagA+AH0AAAEWFxYUBwYHMAYxBwYHBiInJicmJyY0NzY/ATYWFx4BFxYGDwEOARcWMj8BNjQnLgEnLgE1JjY/AT4BFx4BFwEWFxYUBwYPAQYmJy4BJyY2PwE+AScmIg8BBhQXHgEXHgEVFgYPAQ4BJy4BJyYnJjQ3NjcwNjE3Njc2MhcWFwKNLRYWFhYsAYYtODh1ODgsLRYWFhYtSg8nAQEJCQMEBhsqAioqeCuGKioFCwUGBwELDSoIGAkLFQkBGi0WFhYWLUoPJwEBCQkDBAYbKgIqKngrhioqBQsFBgcBCw0qCBgJCxUJLRYWFhYsAYYtODh1ODgsAg0tODh0ODgsAYYtFhYWFi0sODh1ODgtSg8PFRs1GggSBxoqdysrKoYrdyoGCAMEDgcQIAwqCAIGCBEKARosODh1ODgtSg8PFRs1GggSBxoqdysrKoYrdyoGCAMEDgcQIAwqCAIGCBEKLTg4dDg4LAGGLRYWFhYtAAAAAQAA/8AFAANAADcAAAEWFx4BFxYVFAcOAQcGIyEiJy4BJyY1NDc+ATc2NzwBNTQ3PgE3NjMyFx4BFxYXPgEzMhYVFAYHBDMsJSY3DxAUFEYuLzX9IDw0NU4WFw4PMyMjKhkZVzo7QiwqKUcdHhQXNh5PcQcGAbsJFxdCKiouNS8uRhQUFxZONTQ8LysrRxobDwQIBEI7OlcZGQwLKh4dJA8RcU8SIxAAAwAA/8ADgANAABMAHwA0AAABHgEVERQGIyEiJjURNDYzITIWFwMyNjU0JiMiBhUUFhM0Ji8BLgEjISIGHQEUFjMhMjY9AQNkDQ84KP1AKDg4KAIYFCMN/DVLSzU1S0v1BAMHAwkF/jcKDg4KAdAKDgJ8DSMU/egoODgoAsAoOA8N/RxLNTVLSzU1SwJhBQkDBwMEDgrQCg4OCskAAwAA//gDgAMIAA8AHwAvAAATIiY9ATQ2MyEyFh0BFAYjASImPQE0NjMhMhYdARQGIwEiJj0BNDYzITIWHQEUBiMgDRMTDQNADRMTDfzADRMTDQNADRMTDfzADRMTDQNADRMTDQJ4Ew1QDRMTDVANE/7AEw1QDRMTDVANE/7AEw1QDRMTDVANEwAAAAAFAAD/gAQAA4AABwAPABcALQAxAAABLwE/AR8BBwUvAT8BHwEHAR8BDwEvATcTFhQHAQ4BIyImLwEmNDcBPgEzMhYXAzcnBwHAIEBAICBAQP7ANWtrNTVrawKLNWtrNTVra8ITE/0qCRgMDRcKqRMTAtYJGAwNFwp1rWatAsBAICBAQCAgwGs1NWtrNTX+lWs1NWtrNTUB7xM1E/0qCgkJCqkTNRMC1goJCQr+fK1mrQAAAAABACIAugJdAgAADAAAEyEyFgcBBiInASY2Mz8CAhsUE/7/DCEL/v4TFRsCADET/v4LCwECEzEAAAEAIgDAAl4CBgALAAAlISImNwE2MhcBFgYCQf3+GxUTAQILIgsBAhMVwDETAQILC/7+EzEAAAAAAQA6AGIBgAKeAAwAAAERFAYnASY0NwE2FhUBgDET/v4LCwECEzECgf3+GxUTAQILIgsBAhMVGwABAAAAYgFGAp4ADAAANxE0NhcBFhQHAQYmNQAxEwECCwv+/hMxfwICGxUT/v4LIgv+/hMVGwAAAAEAAP+AAnkDgAAZAAABMhYHAQ4BIyImNxMjIiY3Ez4BMyEyFgcDMwJQHBsO/qAGFwwXHQVc7RYcAkADGxIBIBgcBlXnAkAwGP2gCw0kFwGFIRUB4BIYJhb+/AAAAwAA/4ACwAOAABIANABKAAAXNSEVFAYPAQ4BKwEiJi8BLgE1AzQ3PgE3NjMyFx4BFxYVFAYHDgEHHAExITA0NS4BJy4BNSUyNjU0JiMiBw4BBwYVFBYzMjY1NDbAAUAGBSIJHBB8EBwJIgUGwBoaXkBATUlAQV8cHC4pGUEP/sAPQRkpLgFgDRMTDS4pKT0REhMNDRNeDU1NCRIIMw0QEA0zCBIJAi1GP0BhHR0bHGBAQElDdi8caTEBAQEBMWkcL3ZDoBMNDRMSET0pKS4NExMNQl4AAAAAAgAA/8ADgANAAA8AMwAAATIWFREUBiMhIiY1ETQ2MwE1NCYrATU0JisBIgYdASMiBh0BFBY7ARUUFjsBMjY9ATMyNgMgKDg4KP1AKDg4KAKADgq4DgpwCg64Cg4OCrgOCnAKDrgKDgNAOCj9QCg4OCgCwCg4/ghwCg64Cg4OCrgOCnAKDrgKDg4KuA4AAAAAAgAA/8AEAANAACAAQQAAATIWFREUBiMhIiY1ETQ3PgE3NjsBMhYdARQGKwEiBh0BITIWFREUBiMhIiY1ETQ3PgE3NjsBMhYdARQGKwEiBh0BA6AoODgo/wAoOBkZVzo7QhAUHBwUEDVL/mAoODgo/wAoOBkZVzo7QhAUHBwUEDVLAYA4KP8AKDg4KAHgQjs6VxkZHBRgFBxLNYA4KP8AKDg4KAHgQjs6VxkZHBRgFBxLNYAAAgAA/8AEAANAACAAQQAAATIWFREUBw4BBwYrASImPQE0NjsBMjY9ASMiJjURNDYzITIWFREUBw4BBwYrASImPQE0NjsBMjY9ASMiJjURNDYzA6AoOBkZVzo7QhAUHBwUEDVLoCg4OCj+wCg4GRlXOjtCEBQcHBQQNUugKDg4KANAOCj+IEI7OlcZGRwUYBQcSzWAOCgBACg4OCj+IEI7OlcZGRwUYBQcSzWAOCgBACg4AAAABwAA/4AEAAOAAAsAFwAjAC8AOwBHAFMAAAEUBiMiJjU0NjMyFgMyFhUUBiMiJjU0NgEyFhUUBiMiJjU0NgUUBiMiJjU0NjMyFhcyFhUUBiMiJjU0NiEyFhUUBiMiJjU0NgEyFhUUBiMiJjU0NgJgOCgoODgoKDhgKDg4KCg4OAHIKDg4KCg4OP1IOCgoODgoKDgaKDg4KCg4OAJ0KDg4KCg4OP3cKDg4KCg4OAMgKDg4KCg4OPz4OCgoODgoKDgBoDgoKDg4KCg4YCg4OCgoODjuOCgoODgoKDg4KCg4OCgoOAJMOCgoODgoKDgAAAAAAwAO/44D8gNyACUATABcAAAlFhQPAQYHBiInJicmJyY0NzY/ATYyHwEWFA8BBhQXFjI/ATYyFwMnJjQ/ATY3NjIXFhcWFxYUBwYPAQYiLwEmND8BNjQnJiIPAQYiJwEGIicBJjQ/ATYyFwEWFAcCYAcHWS04OHU4OCwtFhYWFi1ZBxQHTwcHWSoqKngqWQcUByJPBwdZLTg4dTg4LC0WFhYWLVkHFAdPBwdZKioqeCpZBxQHAdYOKA78jQ4OLQ4oDgNzDg5UBxQHWS0WFhYWLSw4OHU4OC1ZBwdPBxQHWSp4KioqWQcHAbpPBxQHWS0WFhYWLSw4OHU4OC1ZBwdPBxQHWSp4KioqWQcH/TEODgNzDigOLQ4O/I0OKA4AAAAAAgAQ/5AD8ANwABsAMQAABSInLgEnJjU0Nz4BNzYzMhceARcWFRQHDgEHBgkBFjI/ATY0LwE3NjQvASYiBwEGFBcCAGdaWocnJycnh1paZ2daWocnJycnh1pa/rUBDw4oDiIODsvLDg4iDigO/vEODnAnJ4daWmdnWlqHJycnJ4daWmdnWlqHJycBzv7xDg4iDigOy8sOKA4iDg7+8Q4oDgAAAAACABD/kAPwA3AAGwAxAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2CQEmIg8BBhQfAQcGFB8BFjI3ATY0JwIAZ1pahycnJyeHWlpnZ1pahycnJyeHWloBS/7xDigOIg4Oy8sODiIOKA4BDw4OA3AnJ4daWmdnWlqHJycnJ4daWmdnWlqHJyf+MgEPDg4iDigOy8sOKA4iDg4BDw4oDgAAAAIAEP+QA/ADcAAbADEAABM0Nz4BNzYzMhceARcWFRQHDgEHBiMiJy4BJyYJAQYUHwEWMj8BFxYyPwE2NCcBJiIHECcnh1paZ2daWocnJycnh1paZ2daWocnJwHO/vEODiIOKA7Lyw4oDiIODv7xDigOAYBnWlqHJycnJ4daWmdnWlqHJycnJ4daWgFL/vEOKA4iDg7Lyw4OIg4oDgEPDg4AAAAAAgAQ/5AD8ANwABsAMQAAARQHDgEHBiMiJy4BJyY1NDc+ATc2MzIXHgEXFgkBNjQvASYiDwEnJiIPAQYUFwEWMjcD8Ccnh1paZ2daWocnJycnh1paZ2daWocnJ/4yAQ8ODiIOKA7Lyw4oDiIODgEPDigOAYBnWlqHJycnJ4daWmdnWlqHJycnJ4daWv61AQ8OKA4iDg7Lyw4OIg4oDv7xDg4AAAACAAD/gAOAA4AAMAA+AAABMhYVERQGIyEiJjURNDY7ATU0Nz4BNzYzMhceARcWHQEUBisBIiY9ATQmBw4BHQEhATU0JiMiBh0BFBYzMjYDICg4OCj9QCg4OCgwGBdTNzc/Pzg3UxgYHBRAFBxVPDxTAfD+8C8hIS8vISEvAYA4KP7AKDg4KAFAKDjNPzg4UxgZGBdTODc/IBQcHBQgPFUBAVU8zv7QYCEvLyFgIS8vAAMAEADwA/ACEAALABcAIwAAARQGIyImNTQ2MzIWNzIWFRQGIyImNTQ2ITIWFRQGIyImNTQ2ApBUPDxUVDw8VNA8VFQ8PFRU/Xw8VFQ8PFRUAYA8VFQ8PFRUVFQ8PFRUPDxUVDw8VFQ8PFQAAAMAMP+QAVADcAALABcAIwAAEzIWFRQGIyImNTQ2JzQ2MzIWFRQGIyImETQ2MzIWFRQGIyImwDxUVDw8VFRUVDw8VFQ8PFRUPDxUVDw8VAIQVDw8VFQ8PFTQPFRUPDxUVP18PFRUPDxUVAAAAAIAEP+QA/ADcAAbACcAAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzYBNjQnJSYGFREUFjcCAGdaWocnJycnh1paZ2daWocnJycnh1paAU4ZGf6gFzAwFwNwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/eAOOA7WDRsc/mAcGw0AAAIAAP/AA4ADQAAPAB8AAAEyFhURFAYjISImNRE0NjMTITI2PQE0JiMhIgYdARQWAyAoODgo/UAoODgoWAIQCg4OCv3wCg4OA0A4KP1AKDg4KALAKDj98A4KcAoODgpwCg4AAAACAAD/wAOAA0AADwAlAAAFISImNRE0NjMhMhYVERQGJQE2NC8BJiIHAScmIg8BBhQfARYyNwMg/UAoODgoAsAoODj+PwFwCQkuCRsJ/tSMCRsJLgkJ0AoaCkA4KALAKDg4KP1AKDjEAXAJGwkuCQn+1IwJCS4JGwnQCQkAAgAA/8ADgANAAA8AGwAAAREUBiMhIiY1ETQ2MyEyFgEXFjI/ATYmIyEiBgOAOCj9QCg4OCgCwCg4/Tn2BxQH9gsMEP4UEAwC4P1AKDg4KALAKDg4/r/2Bwf2Cx4eAAAAAgAA/8ADgANAAA8AHAAANxE0NjMhMhYVERQGIyEiJgEnJiIPAQYWMyEyNicAOCgCwCg4OCj9QCg4Asf2BxQH9gsMEAHsEAwLIALAKDg4KP1AKDg4AUH2Bwf2Cx4eCwAAAgAA/8ADgANAAA8AHAAAEyEyFhURFAYjISImNRE0NgE3NjQvASYGFREUFjdgAsAoODgo/UAoODgBQfYHB/YLHh4LA0A4KP1AKDg4KALAKDj9OfYHFAf2CwwQ/hQQDAsAAwAT/5MD7QNtAAsAMwBPAAABMhYVFAYjIiY1NDYFFhQPARcWBi8BBwYiLwEHBiY/AScmND8BJyY2HwE3NjIfATc2Fg8BAzY3NjQnJicmJyYiBwYHBgcGFBcWFxYXFjI3NgIAT3FxT09xcQI8ExS9QwceFcleCisJX8kUHgdDvhMTvkMHHhTJXwoqCl/JFB4HQ3olExMTEyUlMC9iLzAlJRMTExMlJTAvYi8wAkBxT09xcU9PcaEKKgpfyRQeB0O+ExO+QwceFMlfCioKX8kUHgdDvhMTvkMHHhXI/s0lMC9iLzAlJRMTExMlJTAvYi8wJSUTExMTAAABADb/gAPEA4AALAAABSInLgEnJjU0Nz4BNzYzMhYXHgEHBgcOAQcGFRQXHgEXFjc2FgcGBw4BBwYjAjZqXV2LKCkpKItdXWoYLxcQBg8vJSY0Dg8oKIRWVl0QEgskLC1lODg8gCgpi11dampdXosoKAQFAyEIGyUmWjM0Nl5QUG0YGBEDHA0tIyMxDQ0AAAACAAD/kwQAA4AASgBZAAABDgErARUUBgcXFhQHBiIvAQ4BIxE0JisBIgYVESImJwcGIicmND8BLgE9ASMiJicmNjsBNScmNDc2Mh8BITc2MhcWFA8BFTMyFgcBMhceARcWFSE0Nz4BNzYEAAEmGm8ODXgTExI2Em4lXDQOCjAKDjRcJW4SNhITE3gNDm8aJgEBJhtwXRMTEjYSbgHKbhI2EhMTXXAbJgH+Ai4pKT0REv5AEhE9KSkBPhokICE9HHkSNhITE20eIgHoCg4OCv4YIh5tExMSNhJ5HD0hICQaGyd1XhI2EhMTbW0TExI2El51JxsCQhIRPSkpLi4pKT0REgAAAAIAAP/AA4ADQAAPABwAAAUhIiY1ETQ2MyEyFhURFAYBBwYUHwEWNjURNCYHAyD9QCg4OCgCwCg4OP6/9gcH9gseHgtAOCgCwCg4OCj9QCg4Asf2BxQH9gsMEAHsEAwLAAUAAABABQACwAAKABQAXgBoAIIAAAEXIzc+ATEzMBYXATIWFREUBiMhEQU1NCYrATU0JisBIgYdASMiBh0BFBY7AQ4BBy4BJy4BDwIOARceARcOAQcOAR8BHgE3PgE3HgEXFjY/ATYmJy4BJz4BNzMyNjUlNDYzIREhIiY1NwYWOwEyNj8BMxceATsBMjYnAy4BKwEiBgcBMBZMFgULAQoFA6AUHBwU/dACAA4KgA4KIAoOgAoODgrlCh4UChIHBhIIDw0JBAYJFQwMGg4JBQUQBRQIEyQQESMTCRMFEAUFCA0bDB8sChcKDvtgHBQCMP3QFBx2BA4NLQgNAhN4EwINCC4MDgRzAg0HQQgNAgGoS0sSMDASARgcFP3gFBwCgPAgCg4gCg4OCiAOCiAKDhUsFQoVCggEBQgIBRUIDRoNCRIJBRMIHAkFBQwZDQ0ZDAUFCRwIEwUIEwkiRyMOCsAUHP2AHBRwDBQKB0BABwoUDAFSBwkJBwABAED/wAOAA0AAKgAAARUUBisBERQGKwEiJjURIxEUBisBIiY9ASMiJy4BJyY1NDc+ATc2MyEyFgOAEw1gEw1ADRNAEw1ADRNAQjs6VxkZGRlXOjtCAeANEwMgQA0T/SANExMNAuD9IA0TEw3gGRlXOjtCQjs6VxkZEwAAAQAA/4ADgAOAADYAAAEyFhUUBiMiJjU4ATE0NjcnDgEjIiY1NDYzMhYXNy4BNTQ2MzIWFRQGIyImJwceARUUBgcXPgECwFBwcFBQcAIDzRk9IlBwcFAiPRnNAwJwUFBwcFAiPRnNAwICA80ZPQEAcFBQcHBQCxUKgBQWcFBQcBYUgAoVC1BwcFBQcBYUgAoVCwsVCoAUFgACAAD/gAOAA4AAHQAoAAABMhYdARQGIyEiJj0BNDY7ATc+ATsBOAExMhYfATMBAyEDDgEjISImJwNgDRMTDfzADRMTDfATBhYO5Q4XBhPw/QoqAwAqAzcm/hQmNwMDQBMNQA0TEw1ADRMlDA8PDCX8mgKm/VomNDQmAAAAAwAAAAAEgAMAAB0AOQBQAAABMhceARcWFRQHDgEHBiMhIicuAScmNTQ3PgE3NjMBFBceARcWMzI3PgE3NjU0Jy4BJyYjIgcOAQcGATI3PgE3NjU0Jy4BJyYrARYXFhQHBgcDAFBFRmkeHh4eaUZFUP6AUEVGaR4eHh5pRkVQ/wAUFEYuLzU1Ly5GFBQUFEYuLzU1Ly5GFBQCgDUvLkYUFBQURi4vNWIxGRgYGTEDAB4eaUZFUFBFRmkeHh4eaUZFUFBFRmkeHv6ANS8uRhQUFBRGLi81NS8uRhQUFBRGLi/+yxQURi4vNTUvLkYUFDdCQopCQjcAAAACAAAAAASAAwAAHQA5AAABMhceARcWFRQHDgEHBiMhIicuAScmNTQ3PgE3NjMBMjc+ATc2NTQnLgEnJiMiBw4BBwYVFBceARcWAwBPRkZpHh4eHmlGRVD+gE9GRmkeHh4eaUZFUAGANS8uRhQUFBRGLi81NS8uRhQUFBRGLi8DAB4eaUZFUE9GRmkeHh4eaUZFUE9GRmkeHv2AFBRGLi81NS8uRhQUFBRGLi81NS8uRhQUAAADAAAAQAUAAsAABwAhACUAAAEhESE1MzUjEzIWHQEzMhYVERQGKwEVFAYjISImNRE0NjMFESERBED8QAPAQEAgKDgQFBwcFBA4KPwAKDg4KAOg/MACQP6AgIABADgoIBwU/uAUHCAoODgoAcAoOMD/AAEAAAMAAABABQACwAAHACEAJQAAASERITUzNSMTMhYdATMyFhURFAYrARUUBiMhIiY1ETQ2MwURIREEQPxAA8BAQCAoOBAUHBwUEDgo/AAoODgoAuD9gAJA/oCAgAEAOCggHBT+4BQcICg4OCgBwCg4wP8AAQAAAwAAAEAFAALAAAcAIQAlAAABIREhNTM1IxMyFh0BMzIWFREUBisBFRQGIyEiJjURNDYzBREhEQRA/EADwEBAICg4EBQcHBQQOCj8ACg4OCgCIP5AAkD+gICAAQA4KCAcFP7gFBwgKDg4KAHAKDjA/wABAAADAAAAQAUAAsAABwAhACUAAAEhESE1MzUjEzIWHQEzMhYVERQGKwEVFAYjISImNRE0NjMFESERBED8QAPAQEAgKDgQFBwcFBA4KPwAKDg4KAFg/wACQP6AgIABADgoIBwU/uAUHCAoODgoAcAoOMD/AAEAAAIAAABABQACwAAHACEAAAEhESE1MzUjEzIWHQEzMhYVERQGKwEVFAYjISImNRE0NjMEQPxAA8BAQCAoOBAUHBwUEDgo/AAoODgoAkD+gICAAQA4KCAcFP7gFBwgKDg4KAHAKDgAAAAAAwAQ/5AD8ANwABsAKwA7AAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2ExE0JisBIgYVERQWOwEyNjcRNCYrASIGFREUFjsBMjYCAGdaWocnJycnh1paZ2daWocnJycnh1paRxMNYA0TEw1gDRPgEw1gDRMTDWANEwNwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/XABQA0TEw3+wA0TEw0BQA0TEw3+wA0TEwACABD/kAPwA3AAGwArAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2ARE0JiMhIgYVERQWMyEyNgIAZ1pahycnJyeHWlpnZ1pahycnJyeHWloBJxMN/sANExMNAUANEwNwJyeHWlpnZ1pahycnJyeHWlpnZ1pahycn/XABQA0TEw3+wA0TEwAAAAEAEP+QA/ADcABEAAABMhceARcWFRQHDgEHBiMiJy4BJyYnLgE/ATYyFx4BMzI3PgE3Njc2Jy4BJyYHDgEHFxYGIyEiJjURNDYfATY3PgE3NjMB/2daW4cnJycnh1paZzAtLlQmJiEIAQhPBxMHLnE+Rj0+WhoaAQEbG10+PkVAdC5TFxkg/vQUHDsXRyInJ1YvLzIDcCcnh1paZ2daWocnJwkJIRcYHgcUCE8HBigrGxpbPTxESD4+XBoaAQEuLFMXOxwUAQwgGRdHHxoZJAkKAAAABQAA/4ADgAOAAAkAFwAlADMAUQAAFxEhERQGIyEiJgERFBYzMjY1ETQmIyIGBxEUFjMyNjURNCYjIgYHERQWMzI2NRE0JiMiBgEyFh0BFAYjISImPQE0NjsBNz4BOwE4ATEyFh8BM0ADADgo/cAoOAIgEw0NExMNDRPAEw0NExMNDRPAEw0NExMNDRMCgA0TEw38wA0TEw3wEwYWDuUOFwYT8CACoP1gKDg4Aij+QA0TEw0BwA0TEw3+QA0TEw0BwA0TEw3+QA0TEw0BwA0TEwFTEw1ADRMTDUANEyUMDw8MJQAAAgAQ/5AD8ANwACsAWAAAAS4BIyIHDgEHBgcOASsBIiY3Njc+ATc2MzIXHgEXFhc3NhYVERQGIyEiJjcFITIWDwEeATMyNz4BNzY3PgE7ATIWBwYHDgEHBiMiJy4BJyYnBwYmNRE0NjMC5S53QDo1NVYfHw4CDQhzCw4CECwsgVJRWzIvL1cnJyJHFzscFP70IBkX/a4BDCAZF1Mud0A6NTVWHx8OAg0IcwsOAhAsLIFSUVsyLy9XJyciRxc7HBQCdSwvExNDLy44CAoRC1dJSmwfHwkKJBkZIEcXGSD+9BQcOxfyOxdTLC8TE0MvLjgIChELV0lKbB8fCQokGRkgRxcZIAEMFBwAAQAQ/5AD8ANwAEQAAAEyFx4BFxYXNzYWFREUBiMhIiY/AS4BJyYHDgEHBhcWFx4BFxYzMjY3NjIfARYGBwYHDgEHBiMiJy4BJyY1NDc+ATc2MwIBMi8vVicnIkcXOxwU/vQgGRdTLnRART4+XRsbAQEaGlo+PUY+cS4HEwdPCAEIISYmVC4tMGdaWocnJycnh1taZwNwCgkkGRofRxcZIP70FBw7F1MsLgEBGhpcPj5IRDw9WxobKygGB08IFAceGBchCQknJ4daWmdnWlqHJycAAAABAAD/wAOAA0AASAAAJRUUBiM4ATEjIiY/AScHFxYGKwEiJjU4ATE1NDYfATcnBwYmPQE0NjM4ATEzMhYPARc3JyY2OwEyFhU4ATEVFAYvAQcXNzYWFQOAHBTgIBkXSNbWSBcZIOAUHDsXSNfXSBc7HBTgIBkXSNbWSBcZIOAUHDsXSNfXSBc70OAUHDsXSNfXSBc7HBTgIBkXSNbXSRcZIOAUHDsXSNfXSBc7HBTgIBkXSNbXSRcZIAAAAAIAAP+ABAADgAAeADoAAAEyFhURFAYjISImNRE0NjMhMhYdARQGIyERITU0NjMTMhYVERQGLwEBDgEjIiYvAS4BNTQ2NwEnJjYzA2ANEzgo/UAoODgoAUANExMN/uACgBMNsBQcOxdH/hgGEgoKEQctBwcHBwHnRxcZIAEAEw3/ACg4OCgCwCg4Ew1ADRP9gOANEwKAHBT/ACAYFkf+GQcHBwctBxEKChIGAehHFzsAAgAA/8AFAANAADcATQAAARYXHgEXFhUUBw4BBwYjISInLgEnJjU0Nz4BNzY3PAE1NDc+ATc2MzIXHgEXFhc+ATMyFhUUBgcFNiYrATU0JisBIgYdASMiBh8BFjI3BDMsJSY3DxAUFEYuLzX9IDw0NU4WFw4PMyMjKhkZVzo7QiwqKUcdHhQXNh5PcQcG/vYQERWDEw1gDRODFREQ0goaCgG7CRcXQioqLjUvLkYUFBcWTjU0PC8rK0caGw8ECARCOzpXGRkMCyoeHSQPEXFPEiMQshAn4A0TEw3gJxDSCgoAAAAAAgAA/8AFAANAADcATgAAARYXHgEXFhUUBw4BBwYjISInLgEnJjU0Nz4BNzY3PAE1NDc+ATc2MzIXHgEXFhc+ATMyFhUUBgcFMjYvASYiDwEGFjsBFRQWOwEyNj0BMwQzLCUmNw8QFBRGLi81/SA8NDVOFhcODzMjIyoZGVc6O0IsKilHHR4UFzYeT3EHBv7gFREQ0goaCtIQERWDEw1gDRODAbsJFxdCKiouNS8uRhQUFxZONTQ8LysrRxobDwQIBEI7OlcZGQwLKh4dJA8RcU8SIxB7JxDSCgrSECfgDRMTDeAAAgAA/8AEAANAAA8ANAAAATIWFREUBiMhIiY1ETQ2MwEnNzY0LwEmIg8BJyYiDwEGFB8BBwYUHwEWMj8BFxYyPwE2NCcDoCg4OCj8wCg4OCgCmYaGBwdRBxUHhYUHFQdRBweGhgcHUQcVB4WFBxUHUQcHA0A4KP1AKDg4KALAKDj9u4WFBxUHUQcHhoYHB1EHFQeFhQcVB1EHB4aGBwdRBxUHAAACABMAAAUAAwAAFAA5AAABMhYVERQGIyEiJicBJjQ3AT4BMyEDJzc2NC8BJiIPAScmIg8BBhQfAQcGFB8BFjI/ARcWMj8BNjQnBIA1S0s1/RsaLxL+0xMTAS0RLxoC5ql8fAkJLgkbCXx8CRsJLgkJfX0JCS4JGwl8fAkbCS4JCQMASzX+ADVLExIBLhI2EgEtEhT+BHx8CRsJLgkJfX0JCS4JGwl8fAkbCS4JCXx8CQkuCRsJAAAAAwAA/4ADAAOAABEAJwAyAAABFBYzIREUBiMhIiY1ETQ2MyETNiYrATU0JisBIgYdASMiBh8BFjI3AR4BHQEhETMyFhcBwBwUARAcFP1gFBwcFAGQmQ8QFoITDUANE4IWEA/BChwKAVoHB/8ADAoRBwJwFBz9cBQcHBQDoBQc/UkPKKANExMNoCgPvwoKAqQHEQoMAQAHBwADAAD/gAR2A4AACgAaADYAAAEVIREzMhYfAR4BARYUDwEGJj0BIzUzNTQ2FwUUFjMhERQGIyEiJjURNDYzIREUFjMhESEiBhUDAP8ADAoRB8QHBwF2Cgq/ECeAgCcQ/ckTDQFgHBT9YBQcHBQBkBwUARD+oA0TAowMAQAHB8QHEf6CChwKwQ8QFoKAghYQD/kNE/7wFBwcFAOgFBz+8BQc/wATDQAAAAADAAD/gAQAA4AACQAUADcAABMzFSMiJj0BNDYBHgEdASERMzIWFwMUFjMhERQGIyEiJjURIRUUFj8BNjQvASYGHQEhETQ2MyERIODgDRMTA98HB/8ADAoRB24cFAEQHBT9YBQcAQAnEL8KCr8PKP8AHBQBkAFAgBMNQA0TAW4HEQoMAQAHB/7+FBz9cBQcHBQBEIIWEA/BChwKwQ8QFoICEBQc/vAAAAADAAD/gAMAA4AAEQAoADMAAAEUFjMhERQGIyEiJjURNDYzIRMyNi8BJiIPAQYWOwEVFBY7ATI2PQEzEx4BHQEhETMyFhcBwBwUARAcFP1gFBwcFAGQghYQD8EKHArBDxAWghMNQA0TgrAHB/8ADAoRBwJwFBz9cBQcHBQDoBQc/UAoD78KCr8PKKANExMNoAHuBxEKDAEABwcAAAACABP/gAQdA4AAIQAoAAABHgEPARMWBiMiJiclBQ4BIyImNxMnJjY3JRM+ATMyFhcTEzclJxEXAwP5Jxkc1DIFKRwHDwf++v76Bw8IHCgFMtQcGScBJYMIIBERIAmCMqX+6Xz5MAIpBksczv7dHywEA4qJBAQsHwEjzhxLBisBCBISEhL++P7foCn8/YWCARQAAAAAAgAAAA4D9wLyABEANQAAATYWFREUBi8BIyImNRE0NjsBBRcWFA8BBiIvAQcGIi8BJjQ/AScmND8BNjIfATc2Mh8BFhQHAa4XOzsXsswUHBwUzAKfXAkJLgoaCltbChoKLgkJXFwJCS4KGgpbWwoaCi4JCQLyFhgg/WAgGBayHBQBIBQcwFsKGgouCQlcXAkJLgoaCltbChoKLgkJXFwJCS4KGgoAAAAABAAJ/4kD9wN3ABYALABCAFgAAAEyFh0BFAYvAQcGIi8BJjQ/AScmNjsBNyImPQE0Nh8BNzYyHwEWFA8BFxYGIwMXFhQPAQYiLwEHBiY9ATQ2OwEyFgcBNhYdARQGKwEiJj8BJyY0PwE2Mh8BAZAUHDsXPscJGwkzCQnHQhcZIODgFBw7Fz7HCRsJMwkJx0IXGSAgxwkJMwkbCcc+FzscFOAgGRf9/Bc7HBTgIBkXQscJCTMJGwnHAUAcFOAgGRdCxwkJMwkbCcc+FzuAHBTgIBkXQscJCTMJGwnHPhc7/vDHCRsJMwkJx0IXGSDgFBw7FwIEFhgg4BQcOxc+xwkaCjMJCccAAAAABAAA/5YD9wOAABUANABAAEwAACUWFA8BBiIvAS4BNycjAzcFFRc2FhcnIgYHJyY2Nz4BFx4BDwEfATc2FhcWBgcOAQcnLgEjBwYWFwcGIicmNDcBAzI2NTQmIyIGFRQWA+oWFmkWPhbqIg4U1XzAgAEA1SpeI2kMGQykASgrOJJHDggKlReHlQobAxImNxQsGCceTSvPCAYM+CVqJiUlATHWFBwcFBQcHGkWPhZpFhbqI14q1QEAgMB81RQOImsDA6Q5bCs3JhIDGwqViBaVCggNR5M4Ex0LJx4gpCBAHfglJSZqJQEx/kUcFBQcHBQUHAAAAAMAAP+AA4ADgAAKACMAQQAAFwMhAw4BIyEiJicTBhY7ARUUFjsBMjY9ATMyNi8BLgEjIgYHATIWHQEUBiMhIiY9ATQ2OwE3PgE7ATgBMTIWHwEzaioDACoDNyb+FCY3A40PEBVzEw1ADRNzFREQsgULBwcLBQG3DRMTDfzADRMTDfATBhYO5Q4XBhPwJgKm/VomNDQmAWAQKuANExMN4CoQvAUFBQUBShMNQA0TEw1ADRMlDA8PDCUAAAAAAwAA/4ADgAOAAAkAIgBAAAAXESERFAYjISImEwYWOwEVFBY7ATI2PQEzMjYvAS4BIyIGBwEyFh0BFAYjISImPQE0NjsBNz4BOwE4ATEyFh8BM0ADADgo/cAoOLcPEBVzEw1ADRNzFREQsgULBwcLBQG3DRMTDfzADRMTDfATBhYO5Q4XBhPwIAKg/WAoODgBghAq4A0TEw3gKhC8BQUFBQFKEw1ADRMTDUANEyUMDw8MJQAAAQAAAAEAAII1aM1fDzz1AAsEAAAAAADcXxJIAAAAANxfEkgAAP+ABQADgAAAAAgAAgAAAAAAAAABAAADgP+AAAAFAAAAAAAFAAABAAAAAAAAAAAAAAAAAAAAfAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAEgSAADwEAAAPAsAAEgQAAAAEAAAABAAAEAQAACYEgAAABAAAAAOAAAACAAAAAwAAAASAAAADAAAAA4AAgAQAAAAEAAAXA4AAAAOAAAADgAAABAAAAAQAAAADgACAA4AAAAKAAEUCgABFBAAAEAQAABAEAAAQBAAAEAQAABAEAAAQBAAAEAOAAA4DgAAAA4AAGQOAABkDgAAAA4AAAAOAAAADgAAABAAAEASAAAAFAAAABIAADQOAABkDgAAZBIAAPAMAAAAEAAAAA4AAAASAAAAEAAAWBQAAAAOAAAADgAAABAAAAAKAACICgAAiAYAAOgGAAAACgAAAAsAAAAOAAAAEAAAABAAAAAQAAAAEAAAOBAAAEAQAABAEAAAQBAAAEAOAAAAEAAAQAYAAMAQAABADgAAAA4AAAAOAAAADgAAAA4AAAAQAABMEAAA2BAAAAAOAAAAFAAAAA4AAQAOAAAADgAAABIAAAASAAAAFAAAABQAAAAUAAAAFAAAABQAAAAQAABAEAAAQBAAAEAOAAAAEAAAQBAAAEAOAAAAEAAAABQAAAAUAAAAEAAAABQAAEwMAAAAEgAAABAAAAAMAAAAEMAATBAAAAAQAAAkEAAAAA4AAAAOAAAAAAAAAAAoAFAAeAIoAygD8ASYBYAH4AnwC8gOEBAIEaASmBMYFCgW+BdQGAAY8BmgGggayBs4G/Ac4B2QHlgfAB+wIRgiKCO4JQAm+CiIKhgq6Cu4LIgtWC8QMMAxkDIAM1g1mDg4OUA58DqYOyA8KD3IPuBAOEMwRIBFuEbQSDhIqEkYSYhJ+EqwTGBNgE7oUFBSMFRwVbhXAFhIWZBa8FvIXKBdqF5wX2hgKGDoYahjmGS4ZsBngGpwa2hsmG2Qb4Bw6HHQcrhzoHSIdVh2uHfQeXh7QH1QfviAcIHQg5iFYIaoiBiJSIqYi+iNII5Ij5iRqJOQlQiWcAAAAAQAAAHwAgwAHAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAwAAAABAAAAAAACAAcAjQABAAAAAAADAAwARQABAAAAAAAEAAwAogABAAAAAAAFAAsAJAABAAAAAAAGAAwAaQABAAAAAAAKABoAxgADAAEECQABABgADAADAAEECQACAA4AlAADAAEECQADABgAUQADAAEECQAEABgArgADAAEECQAFABYALwADAAEECQAGABgAdQADAAEECQAKADQA4HNjLWljb25zLTkwMABzAGMALQBpAGMAbwBuAHMALQA5ADAAMFZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMHNjLWljb25zLTkwMABzAGMALQBpAGMAbwBuAHMALQA5ADAAMHNjLWljb25zLTkwMABzAGMALQBpAGMAbwBuAHMALQA5ADAAMFJlZ3VsYXIAUgBlAGcAdQBsAGEAcnNjLWljb25zLTkwMABzAGMALQBpAGMAbwBuAHMALQA5ADAAMEZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\") format(\"woff\")}</style>\n<style id=\"style-font-emoji\" type=\"text/css\">@font-face{font-family:color-emoji;src:local(\"Twemoji Mozilla\"),local(\"Apple Color Emoji\"),local(\"Segoe UI Emoji\"),local(\"Segoe UI Symbol\"),local(\"Noto Color Emoji\"),local(\"EmojiOne Color\"),local(\"Android Emoji\")}</style>\n<style id=\"style-core\" type=\"text/css\">#store-area,tw-storydata{display:none!important;z-index:0}::-webkit-scrollbar{height:8px;width:8px}::-webkit-scrollbar-corner,::-webkit-scrollbar-track{background-color:#111}::-webkit-scrollbar-thumb{background-color:#333;border:1px solid #111}*{scrollbar-color:#333 #111;scrollbar-width:thin}:-webkit-full-screen{height:100%;width:100%}:-ms-fullscreen{height:100%;width:100%}:fullscreen{height:100%;width:100%}body::-ms-backdrop{background:0 0}:focus{outline:thin dotted}:disabled{cursor:not-allowed!important}html{font-family:-apple-system,system-ui,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen-Sans,Cantarell,Ubuntu,\"Helvetica Neue\",Helvetica,Arial,sans-serif,color-emoji;font-size:16px;line-height:1}body{color:#eee;background-color:#111;overflow:auto}a{cursor:pointer;color:#68d;text-decoration:none;-webkit-transition-duration:.2s;-o-transition-duration:.2s;transition-duration:.2s}a:hover,html[data-outlines] a:focus{color:#8af;text-decoration:underline}a.link-broken{color:#c22}a.link-broken:hover,html[data-outlines] a.link-broken:focus{color:#e44}a[disabled],span.link-disabled{color:#aaa;cursor:not-allowed!important;text-decoration:none}a.link-internal{-webkit-touch-callout:none}area{cursor:pointer}button{cursor:pointer;color:#eee;background-color:#35a;border:1px solid #57c;line-height:normal;padding:.4em;-webkit-transition-duration:.2s;-o-transition-duration:.2s;transition-duration:.2s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}button:hover,html[data-outlines] button:focus{background-color:#57c;border-color:#79e}button:disabled{background-color:#444;border:1px solid #666}code,kbd,pre,samp,var{font-family:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Lucida Console\",\"Courier New\",Courier,monospace,monospace}pre{overflow:auto}input,select,textarea{color:#eee;background-color:transparent;border:1px solid #444;padding:.4em}select{padding:.34em .4em}input[type=text]{min-width:18em}textarea{min-width:30em;resize:vertical}input[type=checkbox],input[type=file],input[type=radio],select{cursor:pointer}input[type=range]{-webkit-appearance:none;min-height:1.2em}input[type=range]:focus{outline:0}input[type=range]::-webkit-slider-runnable-track{background:#222;border:1px solid #444;border-radius:0;cursor:pointer;height:10px;width:100%}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:#35a;border:1px solid #57c;border-radius:0;cursor:pointer;height:18px;margin-top:-5px;width:33px}input[type=range]:focus::-webkit-slider-runnable-track{background:#222}input[type=range]::-moz-range-track{background:#222;border:1px solid #444;border-radius:0;cursor:pointer;height:10px;width:100%}input[type=range]::-moz-range-thumb{background:#35a;border:1px solid #57c;border-radius:0;cursor:pointer;height:18px;width:33px}input[type=range]::-ms-track{background:0 0;border-color:transparent;color:transparent;cursor:pointer;height:10px;width:calc(100% - 1px)}input[type=range]::-ms-fill-lower{background:#222;border:1px solid #444;border-radius:0}input[type=range]::-ms-fill-upper{background:#222;border:1px solid #444;border-radius:0}input[type=range]::-ms-thumb{background:#35a;border:1px solid #57c;border-radius:0;cursor:pointer;height:16px;width:33px}html[data-outlines] input:focus,html[data-outlines] select:focus,html[data-outlines] textarea:focus,input:hover,select:hover,textarea:hover{background-color:#333;border-color:#eee}input:disabled,select:disabled,textarea:disabled{color:#333;background-color:transparent;border-color:#111}hr{display:block;height:1px;border:none;border-top:1px solid #eee;margin:1em 0;padding:0}audio,canvas,progress,video{max-width:100%;vertical-align:middle}.no-transition{-webkit-transition:none!important;-o-transition:none!important;transition:none!important}.error-view{background-color:#511;border-left:.5em solid #c22;display:inline-block;margin:.1em;max-width:100%;padding:0 .25em;position:relative}.error-view>.error-toggle{background-color:transparent;border:none;line-height:inherit;left:0;padding:0;position:absolute;top:0;width:1.75em}.error-view>.error-toggle:hover,html[data-outlines] .error-view>.error-toggle:focus{background-color:transparent}.error-view>.error{display:inline-block;margin-left:.25em}.error-view>.error-toggle+.error{margin-left:1.5em}.error-view>.error-source[hidden]{display:none}.error-view>.error-source:not([hidden]){background-color:rgba(0,0,0,.2);display:block;margin:0 0 .25em;overflow-x:auto;padding:.25em}.highlight,.marked{color:#ff0;font-weight:700;font-style:italic}.nobr{white-space:nowrap}.error-view>.error-toggle::before,.error-view>.error::before,[data-icon-after]::after,[data-icon-before]::before,[data-icon]::before,a.link-external::after{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}[data-icon]::before{content:attr(data-icon)}[data-icon-before]::before{content:attr(data-icon-before);margin-right:.35em}[data-icon-after]::after{content:attr(data-icon-after);margin-left:.35em}.error-view>.error-toggle::before{content:\"\\f0da\"}.error-view>.error-toggle.enabled::before{content:\"\\f0d7\"}.error-view>.error::before{content:\"\\f071\";margin-right:.35em}a.link-external::after{content:\"\\f35d\";margin-left:.25em}</style>\n<style id=\"style-core-display\" type=\"text/css\">#story{z-index:10;margin:2.5em}@media screen and (max-width:1136px){#story{margin-right:1.5em}}#passages{max-width:54em;margin:0 auto}</style>\n<style id=\"style-core-passage\" type=\"text/css\">.passage{line-height:1.75;text-align:left;-webkit-transition:opacity .4s ease-in;-o-transition:opacity .4s ease-in;transition:opacity .4s ease-in}.passage-in{opacity:0}.passage ol,.passage ul{margin-left:.5em;padding-left:1.5em}.passage table{margin:1em 0;border-collapse:collapse;font-size:100%}.passage caption,.passage td,.passage th,.passage tr{padding:3px}@media (prefers-reduced-motion:reduce){.passage{-webkit-transition:opacity 0s;-o-transition:opacity 0s;transition:opacity 0s}}</style>\n<style id=\"style-core-macro\" type=\"text/css\">@-webkit-keyframes cursor-blink{0%{opacity:1}50%{opacity:0}100%{opacity:1}}@-o-keyframes cursor-blink{0%{opacity:1}50%{opacity:0}100%{opacity:1}}@keyframes cursor-blink{0%{opacity:1}50%{opacity:0}100%{opacity:1}}.macro-append-insert,.macro-linkappend-insert,.macro-linkprepend-insert,.macro-linkreplace-insert,.macro-prepend-insert,.macro-repeat-insert,.macro-replace-insert,.macro-timed-insert{-webkit-transition:opacity .4s ease-in;-o-transition:opacity .4s ease-in;transition:opacity .4s ease-in}.macro-append-in,.macro-linkappend-in,.macro-linkprepend-in,.macro-linkreplace-in,.macro-prepend-in,.macro-repeat-in,.macro-replace-in,.macro-timed-in{opacity:0}.macro-type-cursor::after{-webkit-animation:cursor-blink 1s infinite;-o-animation:cursor-blink 1s infinite;animation:cursor-blink 1s infinite;content:\"\\2590\";opacity:1}</style>\n<style id=\"style-ui-dialog\" type=\"text/css\">html[data-dialog] body{overflow:hidden}#ui-overlay{background-color:#000;height:200%;left:-50%;opacity:0;position:fixed;top:-50%;-webkit-transition:visibility .2s step-end,opacity .2s ease-in;-o-transition:visibility .2s step-end,opacity .2s ease-in;transition:visibility .2s step-end,opacity .2s ease-in;visibility:hidden;width:200%;z-index:100000}#ui-overlay.open{opacity:.8;-webkit-transition:visibility 0s;-o-transition:visibility 0s;transition:visibility 0s;visibility:visible}#ui-dialog{display:none;margin:0;max-width:66em;opacity:0;padding:0;position:fixed;top:50px;z-index:100100}#ui-dialog.open{display:block;opacity:1;-webkit-transition:opacity .2s ease-in;-o-transition:opacity .2s ease-in;transition:opacity .2s ease-in}#ui-dialog>*{-webkit-box-sizing:border-box;box-sizing:border-box}#ui-dialog-titlebar{background-color:#444;min-height:24px;position:relative}#ui-dialog-title{font-size:1.5em;margin:0;padding:.2em 3.5em .2em .5em;text-align:center;text-transform:uppercase}#ui-dialog-close{background-color:transparent;border:1px solid transparent;cursor:pointer;display:block;font-size:120%;height:92%;margin:0;padding:0;position:absolute;right:0;top:0;-webkit-transition-duration:.2s;-o-transition-duration:.2s;transition-duration:.2s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;width:3.6em;font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#ui-dialog-close:hover{background-color:#b44;border-color:#d66}#ui-dialog-body{background-color:#111;border:1px solid #444;height:calc(100% - 2.1em);line-height:1.5;min-width:300px;overflow:auto;padding:1em;text-align:left}#ui-dialog-body>:first-child{margin-top:0}#ui-dialog-body hr{background-color:#444}#ui-dialog-body ul.buttons{margin:0;padding:0;list-style:none}#ui-dialog-body ul.buttons li{display:inline-block;margin:0;padding:.4em .4em 0 0}#ui-dialog-body ul.buttons>li+li>button{margin-left:1em}@media (prefers-reduced-motion:reduce){#ui-overlay{-webkit-transition:opacity 0s;-o-transition:opacity 0s;transition:opacity 0s}#ui-overlay.open{-webkit-transition:opacity 0s;-o-transition:opacity 0s;transition:opacity 0s}#ui-dialog.open{-webkit-transition:opacity 0s;-o-transition:opacity 0s;transition:opacity 0s}}</style>\n<style id=\"style-ui-dialog-saves\" type=\"text/css\">#ui-dialog-body.saves{padding:0 0 1px}#ui-dialog-body.saves>:not(:first-child){border-top:1px solid #444}#ui-dialog-body.saves>h2{background-color:#222;font-size:inherit;margin:0;padding:.1em 0 .1em .4em}#ui-dialog-body.saves table{border-spacing:0;width:100%}#ui-dialog-body.saves tr:not(:first-child){border-top:1px solid #444}#ui-dialog-body.saves td{padding:.33em}#ui-dialog-body.saves td:first-child{display:none!important}#ui-dialog-body.saves td:nth-child(2){min-width:calc(2.237em * 2 + 1px)}#ui-dialog-body.saves td:nth-child(3){line-height:1.2;width:100%}#ui-dialog-body.saves td:last-child{text-align:right}#ui-dialog-body.saves .empty{color:#999;speak:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#ui-dialog-body.saves .details{font-size:75%;margin-left:.25em}#ui-dialog-body.saves #saves-list button{color:#eee;background-color:transparent;border:1px solid #444;height:2.237em;width:2.237em}#ui-dialog-body.saves #saves-list button:disabled{color:#444;border-color:#444}#ui-dialog-body.saves #saves-list button:not(:disabled):hover{background-color:#222;border-color:#ddd}#ui-dialog-body.saves #saves-list button.delete:not(:disabled),#ui-dialog-body.saves button[id=saves-clear]:not(:disabled){background-color:#911;border-color:#b33}#ui-dialog-body.saves #saves-list button.delete:not(:disabled):hover,#ui-dialog-body.saves button[id=saves-clear]:not(:disabled):hover{background-color:#b33;border-color:#d55}#ui-dialog-body.saves #saves-list button.load:not(:disabled){background-color:#161;border-color:#383}#ui-dialog-body.saves #saves-list button.load:not(:disabled):hover{background-color:#383;border-color:#5a5}#ui-dialog-body.saves .buttons li{padding:.4em}#ui-dialog-body.saves .buttons>li+li>button{margin-left:.2em}#ui-dialog-body.saves .buttons.slots>li:last-child{float:right}#ui-dialog-body.saves #saves-list button::before,#ui-dialog-body.saves .buttons button::before{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#ui-dialog-body.saves .buttons button::before{margin-right:.35em}#ui-dialog-body.saves button.delete::before{content:\"\\f2ed\"}#ui-dialog-body.saves button.delete:disabled::before{content:\"\\f1f8\"}#ui-dialog-body.saves button.load::before{content:\"\\f04b\"}#ui-dialog-body.saves button.save::before{content:\"\\f0c7\"}#ui-dialog-body.saves button[id=saves-export]::before{content:\"\\f56e\"}#ui-dialog-body.saves button[id=saves-import]::before{content:\"\\f56f\"}#ui-dialog-body.saves button[id=saves-clear]::before{content:\"\\f2ed\"}#ui-dialog-body.saves button[id=saves-clear]:disabled::before{content:\"\\f1f8\"}#ui-dialog-body.saves button[id=saves-disk-save]::before{content:\"\\f56d\"}#ui-dialog-body.saves button[id=saves-disk-load]::before{content:\"\\f574\"}#ui-dialog-body.saves button[id=saves-clipboard-save]::before{content:\"\\f019\"}</style>\n<style id=\"style-ui-dialog-settings\" type=\"text/css\">#ui-dialog-body.settings [id|=setting-body]>div:first-child{display:table;width:100%}#ui-dialog-body.settings [id|=setting-label]{display:table-cell;padding:.4em 2em .4em 0}#ui-dialog-body.settings [id|=setting-label]+div{display:table-cell;min-width:8em;text-align:right;vertical-align:middle;white-space:nowrap}#ui-dialog-body.settings div[id|=header-body]{margin:1em 0}#ui-dialog-body.settings div[id|=header-body]:first-child{margin-top:0}#ui-dialog-body.settings div[id|=header-body]:not(:first-child){border-top:1px solid #444;padding-top:1em}#ui-dialog-body.settings div[id|=header-body]>*{margin:0}#ui-dialog-body.settings h2[id|=header-heading]{font-size:1.375em}#ui-dialog-body.settings p[id|=header-desc],#ui-dialog-body.settings p[id|=setting-desc]{font-size:87.5%;margin:0 0 0 .5em}#ui-dialog-body.settings div[id|=setting-body]+div[id|=setting-body]{margin:1em 0}#ui-dialog-body.settings [id|=setting-control]{white-space:nowrap}#ui-dialog-body.settings button[id|=setting-control]{color:#eee;background-color:transparent;border:1px solid #444;padding:.4em}#ui-dialog-body.settings button[id|=setting-control]:hover{background-color:#333;border-color:#eee}#ui-dialog-body.settings button[id|=setting-control].enabled{background-color:#282;border-color:#4a4}#ui-dialog-body.settings button[id|=setting-control].enabled:hover{background-color:#4a4;border-color:#6c6}#ui-dialog-body.settings input[type=range][id|=setting-control]{max-width:35vw}#ui-dialog-body.settings span[id|=setting-input]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#ui-dialog-body.settings button[id|=setting-control].enabled::after,#ui-dialog-body.settings button[id|=setting-control]::after{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin-left:.35em}#ui-dialog-body.settings button[id|=setting-control]::after{content:\"\\f204\"}#ui-dialog-body.settings button[id|=setting-control].enabled::after{content:\"\\f205\"}</style>\n<style id=\"style-ui-dialog-legacy\" type=\"text/css\">#ui-dialog-body.list{padding:0}#ui-dialog-body.list ul{margin:0;padding:0;list-style:none;border:1px solid transparent}#ui-dialog-body.list li{margin:0}#ui-dialog-body.list li:not(:first-child){border-top:1px solid #444}#ui-dialog-body.list li a{display:block;padding:.25em .75em;border:1px solid transparent;color:#eee;text-decoration:none}#ui-dialog-body.list li a:hover{background-color:#333;border-color:#eee}#ui-dialog-body.list a{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}</style>\n<style id=\"style-ui-bar\" type=\"text/css\">#story{margin-left:20em;-webkit-transition:margin-left .2s ease-in;-o-transition:margin-left .2s ease-in;transition:margin-left .2s ease-in}#ui-bar.stowed~#story{margin-left:4.5em}@media screen and (max-width:1136px){#story{margin-left:19em}#ui-bar.stowed~#story{margin-left:3.5em}}@media screen and (max-width:768px){#story{margin-left:3.5em}}#ui-bar{background-color:#222;border-right:1px solid #444;height:100%;left:0;margin:0;padding:0;position:fixed;text-align:center;top:0;-webkit-transition:left .2s ease-in;-o-transition:left .2s ease-in;transition:left .2s ease-in;width:17.5em;z-index:50}#ui-bar.stowed{left:-15.5em}#ui-bar-tray{position:absolute;top:.2em;left:0;right:0}#ui-bar-body{height:calc(100% - 2.5em);line-height:1.5;margin:2.5em 0;overflow:auto;padding:0 1.5em}#ui-bar.stowed #ui-bar-body,#ui-bar.stowed #ui-bar-history{visibility:hidden;-webkit-transition:visibility .2s step-end;-o-transition:visibility .2s step-end;transition:visibility .2s step-end}#ui-bar a{text-decoration:none}#ui-bar hr{border-color:#444}#ui-bar-tray button{color:#eee;background-color:transparent;border:1px solid #444}#ui-bar-tray button:hover{background-color:#444;border-color:#eee}#ui-bar-tray button:disabled{color:#444;background-color:transparent;border-color:#444}button#ui-bar-toggle{border-right:none;position:absolute;right:0;top:0}#ui-bar-history{margin:0 auto}#ui-bar-history button:not(:first-child){margin-left:1.2em}#ui-bar-body>:not(:first-child){margin-top:2em}#story-title{margin:0;font-size:162.5%}#story-author{margin-top:2em;font-weight:700}#menu ul{margin:1em 0 0;padding:0;list-style:none;border:1px solid #444}#menu ul:empty{display:none}#menu li{margin:0}#menu li:not(:first-child){border-top:1px solid #444}#menu li a{display:block;padding:.25em .75em;border:1px solid transparent;color:#eee;text-transform:uppercase}#menu li a:hover{background-color:#444;border-color:#eee}#menu a,#ui-bar-tray button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#menu-core li[id|=menu-item] a::before,#ui-bar-tray button::before{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#ui-bar-tray button::before{display:block;font-size:1.1em;width:1em}#ui-bar-toggle::before{content:\"\\f053\"}#ui-bar.stowed #ui-bar-toggle::before{content:\"\\f054\"}#ui-bar-tray #history-backward::before{content:\"\\f060\"}#ui-bar-tray #history-jumpto::before{content:\"\\f0e7\"}#ui-bar-tray #history-forward::before{content:\"\\f061\"}#menu-item-continue a::before,#menu-item-restart a::before,#menu-item-saves a::before,#menu-item-settings a::before,#menu-item-share a::before{margin-right:.35em}#menu-item-continue a::before{content:\"\\f04b\"}#menu-item-saves a::before{content:\"\\f0c7\"}#menu-item-settings a::before{content:\"\\f013\"}#menu-item-restart a::before{content:\"\\f011\"}#menu-item-share a::before{content:\"\\f1e0\"}@media (prefers-reduced-motion:reduce){#story{-webkit-transition:margin-left 0s;-o-transition:margin-left 0s;transition:margin-left 0s}#ui-bar{-webkit-transition:left 0s;-o-transition:left 0s;transition:left 0s}}</style>\n<style id=\"style-idb-backend\" type=\"text/css\">#saves-export-reminder{padding:.5em 1em 0}.idb-saves-list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.idb-saves-list .savesListRow{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;border-top:1px solid #444;padding:4px}@media (min-width:40rem){.idb-saves-list .savesListRow{max-height:2.4em}}.idb-saves-list .savesListRow .saveGroup{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;min-width:0}.idb-saves-list .savesListRow .saveGroup>div{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;margin:0 10px;-webkit-box-flex:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.idb-saves-list .savesListRow .saveGroup .saveId{min-width:2em;margin-left:4px;margin-right:-6px}.idb-saves-list .savesListRow .saveGroup .saveButton{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;min-width:110px;margin:0 10px}.idb-saves-list .savesListRow .saveGroup .saveName{width:5em}.idb-saves-list .savesListRow .saveGroup .saveButton input{margin:3px 0}.idb-saves-list .savesListRow .saveGroup>.saveDetails{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-pack:stretch;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch;min-width:100px}.idb-saves-list .savesListRow .saveGroup>.saveDetails span{max-height:80px;white-space:nowrap;overflow-x:clip}.jumpToSaveTransition{background-color:#444;-webkit-transition-duration:1s;-o-transition-duration:1s;transition-duration:1s}#savesListFooter{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:0!important;line-height:normal}#savesListFooter div{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:stretch;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch}.datestamp{font-size:.8em}.listMargin{display:inline-block;margin:1px 0}.right{float:right}.saveMenuButton{background-color:#35a!important}.saveMenuButton:hover{background-color:#35a!important}.saveMenuConfirm{margin-top:20px;margin-left:150px}.green{color:#38b20a}.gold{color:gold}.red{color:#ec3535}.saveBorder{max-width:700px;margin:10px 2px;padding:5px 2px 30px;border:1px solid var(--200)}#saveList ul.buttons{margin:0;padding:0;list-style:none;border-top:1px solid var(--750)}#saveList ul.buttons li{padding:.4em;display:inline-block;margin:0}#saveList ul.buttons li:last-child{float:right}#saveList button[id=saves-export]:before{content:\"\\e829\\00a0\"}#saveList button[id=saves-toClipboard]:before{content:\"\\e82b\\00a0\"}#saveList button[id=saves-import]:before{content:\"\\e82a\\00a0\"}#saveList button[id=saves-clear]:before{content:\"\\e827\\00a0\"}.saves-loading .saves{text-align:center;margin-top:1em}</style>\n<style id=\"style-ui-debug-bar\" type=\"text/css\">#debug-bar{background-color:#222;border-left:1px solid #444;border-top:1px solid #444;bottom:0;margin:0;max-height:95%;max-width:66em;min-width:300px;padding:.5em;position:fixed;right:0;z-index:99900}#debug-bar>div:not([id])+div{margin-top:.5em}#debug-bar>div>label{margin-right:.5em}#debug-bar>div>input[type=text]{min-width:8em;width:14em}#debug-bar>div>select{width:22em}#debug-bar-toggle{color:#eee;background-color:#222;border:1px solid #444;height:calc(100% + 1px);left:calc(-2em - 1px);position:absolute;top:-1px;width:2em}#debug-bar-toggle:hover{background-color:#333;border-color:#eee}#debug-bar-hint{bottom:.75em;font-size:4.5em;opacity:.33;pointer-events:none;position:fixed;right:.6em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap}#debug-bar-watch{background-color:#222;border-left:1px solid #444;border-top:1px solid #444;bottom:calc(100% + 1px);font-size:.9em;left:-1px;max-height:280%;max-height:calc(95vh - 100%);position:absolute;overflow-x:hidden;overflow-y:scroll;right:0;z-index:99800}#debug-bar-watch[hidden]{display:none}#debug-bar-watch div{color:#999;font-style:italic;margin:1em auto;text-align:center}#debug-bar-watch table{width:100%}#debug-bar-watch tr:nth-child(2n){background-color:rgba(127,127,127,.15)}#debug-bar-watch td{padding:.2em 0}#debug-bar-watch td:first-child+td{padding:.2em .3em .2em .1em}#debug-bar-watch .watch-delete{background-color:transparent;border:none;color:#c00}#debug-bar-watch-all,#debug-bar-watch-clear{margin-left:.5em}#debug-bar-views-toggle,#debug-bar-watch-toggle{color:#eee;background-color:transparent;border:1px solid #444;margin-right:1em;padding:.4em}#debug-bar-views-toggle:hover,#debug-bar-watch-toggle:hover{background-color:#333;border-color:#eee}#debug-bar-watch:not([hidden])~div #debug-bar-watch-toggle,html[data-debug-view] #debug-bar-views-toggle{background-color:#282;border-color:#4a4}#debug-bar-watch:not([hidden])~div #debug-bar-watch-toggle:hover,html[data-debug-view] #debug-bar-views-toggle:hover{background-color:#4a4;border-color:#6c6}#debug-bar-hint::after,#debug-bar-passage-play::before,#debug-bar-toggle::before,#debug-bar-views-toggle::after,#debug-bar-watch .watch-delete::before,#debug-bar-watch-add::before,#debug-bar-watch-all::before,#debug-bar-watch-clear::before,#debug-bar-watch-toggle::after{font-family:sc-icons!important;font-style:normal;font-weight:400;font-variant:normal;line-height:1;speak:never;text-rendering:auto;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#debug-bar-toggle::before{content:\"\\f188\"}#debug-bar-hint::after{content:\"\\f188\\202f\\f061\"}#debug-bar-watch .watch-delete::before{content:\"\\f00d\"}#debug-bar-watch-add::before{content:\"\\f067\"}#debug-bar-watch-all::before{content:\"\\f0d0\"}#debug-bar-watch-clear::before{content:\"\\f2ed\"}#debug-bar-views-toggle::after,#debug-bar-watch-toggle::after{content:\"\\f204\";margin-left:.35em}#debug-bar-watch:not([hidden])~div #debug-bar-watch-toggle::after,html[data-debug-view] #debug-bar-views-toggle::after{content:\"\\f205\"}#debug-bar-passage-play::before{content:\"\\f04b\"}</style>\n<style id=\"style-ui-debug-views\" type=\"text/css\">html[data-debug-view] .debug{padding:.25em;background-color:#234}html[data-debug-view] .debug[title]{cursor:help}html[data-debug-view] .debug.block{display:inline-block;vertical-align:middle}html[data-debug-view] .debug.invalid{text-decoration:line-through}html[data-debug-view] .debug.hidden,html[data-debug-view] .debug.hidden .debug{background-color:#555}html:not([data-debug-view]) .debug.hidden{display:none}html[data-debug-view] .debug[data-name][data-type].nonvoid::after,html[data-debug-view] .debug[data-name][data-type]::before{background-color:rgba(0,0,0,.25);font-family:monospace,monospace;white-space:pre}html[data-debug-view] .debug[data-name][data-type]::before{content:attr(data-name)}html[data-debug-view] .debug[data-name][data-type|=macro]::before{content:\"<<\" attr(data-name) \">>\"}html[data-debug-view] .debug[data-name][data-type|=macro].nonvoid::after{content:\"<</\" attr(data-name) \">>\"}html[data-debug-view] .debug[data-name][data-type|=html]::before{content:\"<\" attr(data-name) \">\"}html[data-debug-view] .debug[data-name][data-type|=html].nonvoid::after{content:\"</\" attr(data-name) \">\"}html[data-debug-view] .debug[data-name][data-type]:not(:empty)::before{margin-right:.25em}html[data-debug-view] .debug[data-name][data-type].nonvoid:not(:empty)::after{margin-left:.25em}html[data-debug-view] .debug[data-name][data-type|=special],html[data-debug-view] .debug[data-name][data-type|=special]::before{display:block}</style>\n</head>\n<body>\n\t<div id=\"init-screen\">\n\t\t<div id=\"init-no-js\"><noscript>JavaScript must be enabled to play.</noscript></div>\n\t\t<div id=\"init-lacking\"><p>Browser lacks capabilities required to play.</p><p>Upgrade or switch to another browser.</p></div>\n\t\t<div id=\"init-loading\"><div>Loading…</div></div>\n\t</div>\n\t{{STORY_DATA}}\n\t<script id=\"script-sugarcube\" type=\"text/javascript\">\n\t/*! SugarCube JS */\n\tif(document.documentElement.getAttribute(\"data-init\")===\"loading\"){(function(window,document,jQuery,undefined){\"use strict\";var errorPrologRegExp=/^(?:(?:uncaught\\s+(?:exception:\\s+)?)?\\w*(?:error|exception|_err):\\s+)+/i,Alert=(()=>{function mesg(where,error,isFatal,isUncaught){let mesg=\"Error\",nice=`A${isFatal?\" fatal\":\"n\"} error has occurred.`;nice+=isFatal?\" Aborting.\":\" You may be able to continue, but some parts may not work properly.\";const isObject=null!==error&&\"object\"==typeof error;null!=where&&(mesg+=` [${where}]`),mesg+=`: ${(isObject&&\"message\"in error?String(error.message).replace(errorPrologRegExp,\"\"):String(error)).trim()||\"unknown error\"}.`,isObject&&\"stack\"in error&&(mesg+=`\\n\\nStack Trace:\\n${error.stack}`),mesg&&(nice+=`\\n\\n${mesg}`),isUncaught||console[isFatal?\"error\":\"warn\"](mesg),window.alert(nice)}var origOnError;return origOnError=window.onerror,window.onerror=function(what,source,lineNum,colNum,error){\"complete\"===document.readyState?mesg(null,null!=error?error:what,!1,!0):(mesg(null,null!=error?error:what,!0,!0),window.onerror=origOnError,\"function\"==typeof window.onerror&&window.onerror.apply(this,arguments))},Object.preventExtensions(Object.create(null,{error:{value:function(where,error){mesg(where,error)}},fatal:{value:function(where,error){mesg(where,error,!0)}}}))})(),Patterns=(()=>{const space=(()=>{const wsMap=new Map([[\" \",\"\\\\u0020\"],[\"\\f\",\"\\\\f\"],[\"\\n\",\"\\\\n\"],[\"\\r\",\"\\\\r\"],[\"\\t\",\"\\\\t\"],[\"\\v\",\"\\\\v\"],[\" \",\"\\\\u00a0\"],[\" \",\"\\\\u1680\"],[\"á Ž\",\"\\\\u180e\"],[\" \",\"\\\\u2000\"],[\"â€\",\"\\\\u2001\"],[\" \",\"\\\\u2002\"],[\" \",\"\\\\u2003\"],[\" \",\"\\\\u2004\"],[\" \",\"\\\\u2005\"],[\" \",\"\\\\u2006\"],[\" \",\"\\\\u2007\"],[\" \",\"\\\\u2008\"],[\" \",\"\\\\u2009\"],[\" \",\"\\\\u200a\"],[\"\\u2028\",\"\\\\u2028\"],[\"\\u2029\",\"\\\\u2029\"],[\" \",\"\\\\u202f\"],[\"âŸ\",\"\\\\u205f\"],[\" \",\"\\\\u3000\"],[\"\\ufeff\",\"\\\\ufeff\"]]),wsRe=/^\\s$/;let missing=\"\";return wsMap.forEach(((pat,char)=>{wsRe.test(char)||(missing+=pat)})),missing?`[\\\\s${missing}]`:\"\\\\s\"})(),spaceNoTerminator=\"[\\\\u0020\\\\f\\\\t\\\\v\\\\u00a0\\\\u1680\\\\u180e\\\\u2000-\\\\u200a\\\\u202f\\\\u205f\\\\u3000\\\\ufeff]\",notSpace=\"\\\\s\"===space?\"\\\\S\":space.replace(/^\\[/,\"[^\"),anyLetter=\"[0-9A-Z_a-z\\\\-\\\\u00c0-\\\\u00d6\\\\u00d8-\\\\u00f6\\\\u00f8-\\\\u00ff\\\\u0150\\\\u0170\\\\u0151\\\\u0171]\",anyLetterStrict=anyLetter.replace(\"\\\\-\",\"\"),htmlTagName=(()=>{const cENChar=\"(?:[\\\\x2D.0-9A-Z_a-z\\\\xB7\\\\xC0-\\\\xD6\\\\xD8-\\\\xF6\\\\xF8-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C\\\\u200D\\\\u203F\\\\u2040\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD]|[\\\\uD800-\\\\uDB7F][\\\\uDC00-\\\\uDFFF])\";return`[A-Za-z](?:${cENChar}*-${cENChar}*|[0-9A-Za-z]*)`})(),inlineCss=`(${anyLetter}+)\\\\(([^\\\\)\\\\|\\\\n]+)\\\\):|${spaceNoTerminator}*(${anyLetter}+)${spaceNoTerminator}*:([^;\\\\|\\\\n]+);|${spaceNoTerminator}*((?:[#.]${anyLetter}+${spaceNoTerminator}*)+);`,url=\"(?:file|https?|mailto|ftp|javascript|irc|news|data):[^\\\\s'\\\"]+\",externalUrl=url.replace(/\\|javascript|\\|data/g,\"\");return Object.freeze(Object.assign(Object.create(null),{space:space,spaceNoTerminator:spaceNoTerminator,lineTerminator:\"[\\\\n\\\\r\\\\u2028\\\\u2029]\",notSpace:notSpace,anyChar:\"(?:.|[\\\\n\\\\r\\\\u2028\\\\u2029])\",anyLetter:anyLetter,anyLetterStrict:anyLetterStrict,identifierFirstChar:\"[$A-Z_a-z]\",identifierNextChar:\"[$0-9A-Z_a-z]\",identifier:\"[$A-Z_a-z][$0-9A-Z_a-z]*\",variableSigil:\"[$_]\",variable:\"[$_][$A-Z_a-z][$0-9A-Z_a-z]*\",macroName:\"[A-Za-z][\\\\w-]*|[=-]\",templateName:\"[A-Za-z][\\\\w-]*\",htmlTagName:htmlTagName,cssIdOrClassSigil:\"[#.]\",cssImage:\"\\\\[[<>]?[Ii][Mm][Gg]\\\\[(?:\\\\s|\\\\S)*?\\\\]\\\\]+\",inlineCss:inlineCss,url:url,externalUrl:externalUrl}))})();(()=>{const _trimString=(()=>{const startWSRe=new RegExp(`^${Patterns.space}${Patterns.space}*`),endWSRe=new RegExp(`${Patterns.space}${Patterns.space}*$`);return function(str,where){const val=String(str);if(!val)return val;switch(where){case\"start\":return startWSRe.test(val)?val.replace(startWSRe,\"\"):val;case\"end\":return endWSRe.test(val)?val.replace(endWSRe,\"\"):val;default:throw new Error(`_trimString called with incorrect where parameter value: \"${where}\"`)}}})();function _createPadString(length,padding){const targetLength=Number.parseInt(length,10)||0;if(targetLength<1)return\"\";let padString=void 0===padding?\"\":String(padding);for(\"\"===padString&&(padString=\" \");padString.length<targetLength;){const curPadLength=padString.length,remainingLength=targetLength-curPadLength;padString+=curPadLength>remainingLength?padString.slice(0,remainingLength):padString}return padString.length>targetLength&&(padString=padString.slice(0,targetLength)),padString}if(Array.prototype.flat||Object.defineProperty(Array.prototype,\"flat\",{configurable:!0,writable:!0,value:function flat(){if(null==this)throw new TypeError(\"Array.prototype.flat called on null or undefined\");const depth=0===arguments.length?1:Number(arguments[0])||0;if(depth<1)return Array.prototype.slice.call(this);const push=Array.prototype.push;return Array.prototype.reduce.call(this,((acc,cur)=>(cur instanceof Array?push.apply(acc,flat.call(cur,depth-1)):acc.push(cur),acc)),[])}}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,\"flatMap\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.flatMap called on null or undefined\");return Array.prototype.map.apply(this,arguments).flat()}}),Array.prototype.includes||Object.defineProperty(Array.prototype,\"includes\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.includes called on null or undefined\");if(0===arguments.length)return!1;const length=this.length>>>0;if(0===length)return!1;const needle=arguments[0];let i=Number(arguments[1])||0;for(i<0&&(i=Math.max(0,length+i));i<length;++i){const value=this[i];if(value===needle||value!=value&&needle!=needle)return!0}return!1}}),Object.entries||Object.defineProperty(Object,\"entries\",{configurable:!0,writable:!0,value(obj){if(\"object\"!=typeof obj||null===obj)throw new TypeError(\"Object.entries object parameter must be an object\");return Object.keys(obj).map((key=>[key,obj[key]]))}}),Object.fromEntries||Object.defineProperty(Object,\"fromEntries\",{configurable:!0,writable:!0,value:iter=>Array.from(iter).reduce(((acc,pair)=>{if(Object(pair)!==pair)throw new TypeError(\"Object.fromEntries iterable parameter must yield objects\");return pair[0]in acc?Object.defineProperty(acc,pair[0],{configurable:!0,enumerable:!0,writable:!0,value:pair[1]}):acc[pair[0]]=pair[1],acc}),{})}),Object.getOwnPropertyDescriptors||Object.defineProperty(Object,\"getOwnPropertyDescriptors\",{configurable:!0,writable:!0,value(obj){if(null==obj)throw new TypeError(\"Object.getOwnPropertyDescriptors object parameter is null or undefined\");const O=Object(obj);return Reflect.ownKeys(O).reduce(((acc,key)=>{const desc=Object.getOwnPropertyDescriptor(O,key);return void 0!==desc&&(key in acc?Object.defineProperty(acc,key,{configurable:!0,enumerable:!0,writable:!0,value:desc}):acc[key]=desc),acc}),{})}}),!Object.hasOwn){const hasOwnProperty=Object.prototype.hasOwnProperty;Object.defineProperty(Object,\"hasOwn\",{configurable:!0,writable:!0,value:(O,P)=>hasOwnProperty.call(Object(O),P)})}Object.values||Object.defineProperty(Object,\"values\",{configurable:!0,writable:!0,value(obj){if(\"object\"!=typeof obj||null===obj)throw new TypeError(\"Object.values object parameter must be an object\");return Object.keys(obj).map((key=>obj[key]))}}),String.prototype.padStart||Object.defineProperty(String.prototype,\"padStart\",{configurable:!0,writable:!0,value(length,padding){if(null==this)throw new TypeError(\"String.prototype.padStart called on null or undefined\");const baseString=String(this),baseLength=baseString.length,targetLength=Number.parseInt(length,10);return targetLength<=baseLength?baseString:_createPadString(targetLength-baseLength,padding)+baseString}}),String.prototype.padEnd||Object.defineProperty(String.prototype,\"padEnd\",{configurable:!0,writable:!0,value(length,padding){if(null==this)throw new TypeError(\"String.prototype.padEnd called on null or undefined\");const baseString=String(this),baseLength=baseString.length,targetLength=Number.parseInt(length,10);return targetLength<=baseLength?baseString:baseString+_createPadString(targetLength-baseLength,padding)}}),String.prototype.trimStart||Object.defineProperty(String.prototype,\"trimStart\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.trimStart called on null or undefined\");return _trimString(this,\"start\")}}),String.prototype.trimLeft||Object.defineProperty(String.prototype,\"trimLeft\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.trimLeft called on null or undefined\");return _trimString(this,\"start\")}}),String.prototype.trimEnd||Object.defineProperty(String.prototype,\"trimEnd\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.trimEnd called on null or undefined\");return _trimString(this,\"end\")}}),String.prototype.trimRight||Object.defineProperty(String.prototype,\"trimRight\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.trimRight called on null or undefined\");return _trimString(this,\"end\")}})})(),(()=>{const _nativeMathRandom=Math.random;function _random(){let min,max;switch(arguments.length){case 0:throw new Error(\"_random called with insufficient parameters\");case 1:min=0,max=arguments[0];break;default:min=arguments[0],max=arguments[1]}return min>max&&([min,max]=[max,min]),Math.floor(_nativeMathRandom()*(max-min+1))+min}function _randomIndex(length,boundsArgs){let min,max;switch(boundsArgs.length){case 1:min=0,max=length-1;break;case 2:min=0,max=Math.trunc(boundsArgs[1]);break;default:min=Math.trunc(boundsArgs[1]),max=Math.trunc(boundsArgs[2])}return Number.isNaN(min)?min=0:!Number.isFinite(min)||min>=length?min=length-1:min<0&&(min=length+min,min<0&&(min=0)),Number.isNaN(max)?max=0:!Number.isFinite(max)||max>=length?max=length-1:max<0&&(max=length+max,max<0&&(max=length-1)),_random(min,max)}function _getCodePointStartAndEnd(str,pos){const code=str.charCodeAt(pos);if(Number.isNaN(code))return{char:\"\",start:-1,end:-1};if(code<55296||code>57343)return{char:str.charAt(pos),start:pos,end:pos};if(code>=55296&&code<=56319){const nextPos=pos+1;if(nextPos>=str.length)throw new Error(\"high surrogate without trailing low surrogate\");const nextCode=str.charCodeAt(nextPos);if(nextCode<56320||nextCode>57343)throw new Error(\"high surrogate without trailing low surrogate\");return{char:str.charAt(pos)+str.charAt(nextPos),start:pos,end:nextPos}}if(0===pos)throw new Error(\"low surrogate without leading high surrogate\");const prevPos=pos-1,prevCode=str.charCodeAt(prevPos);if(prevCode<55296||prevCode>56319)throw new Error(\"low surrogate without leading high surrogate\");return{char:str.charAt(prevPos)+str.charAt(pos),start:prevPos,end:pos}}Object.defineProperty(Array.prototype,\"concatUnique\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.concatUnique called on null or undefined\");const result=Array.from(this);if(0===arguments.length)return result;const items=Array.prototype.reduce.call(arguments,((prev,cur)=>prev.concat(cur)),[]),addSize=items.length;if(0===addSize)return result;const indexOf=Array.prototype.indexOf,push=Array.prototype.push;for(let i=0;i<addSize;++i){const value=items[i];-1===indexOf.call(result,value)&&push.call(result,value)}return result}}),Object.defineProperty(Array.prototype,\"count\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.count called on null or undefined\");const indexOf=Array.prototype.indexOf,needle=arguments[0];let pos=Number(arguments[1])||0,count=0;for(;-1!==(pos=indexOf.call(this,needle,pos));)++count,++pos;return count}}),Object.defineProperty(Array.prototype,\"countWith\",{configurable:!0,writable:!0,value(predicate,thisArg){if(null==this)throw new TypeError(\"Array.prototype.countWith called on null or undefined\");if(\"function\"!=typeof predicate)throw new Error(\"Array.prototype.countWith predicate parameter must be a function\");const length=this.length>>>0;if(0===length)return 0;let count=0;for(let i=0;i<length;++i)predicate.call(thisArg,this[i],i,this)&&++count;return count}}),Object.defineProperty(Array.prototype,\"deleteAll\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.deleteAll called on null or undefined\");if(0===arguments.length)return[];const length=this.length>>>0;if(0===length)return[];const needles=Array.prototype.concat.apply([],arguments),needlesLength=needles.length,indices=[];for(let i=0;i<length;++i){const value=this[i];for(let j=0;j<needlesLength;++j){const needle=needles[j];if(value===needle||value!=value&&needle!=needle){indices.push(i);break}}}const result=[];for(let i=0,iend=indices.length;i<iend;++i)result[i]=this[indices[i]];const splice=Array.prototype.splice;for(let i=indices.length-1;i>=0;--i)splice.call(this,indices[i],1);return result}}),Object.defineProperty(Array.prototype,\"deleteAt\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.deleteAt called on null or undefined\");if(0===arguments.length)return[];const length=this.length>>>0;if(0===length)return[];const splice=Array.prototype.splice,cpyIndices=Array.from(new Set(Array.from(arguments).map((x=>x<0?Math.max(0,length+x):x))).values()),delIndices=Array.from(cpyIndices).sort(((a,b)=>b-a)),result=[];for(let i=0,iend=cpyIndices.length;i<iend;++i)result[i]=this[cpyIndices[i]];for(let i=0,iend=delIndices.length;i<iend;++i)splice.call(this,delIndices[i],1);return result}}),Object.defineProperty(Array.prototype,\"deleteFirst\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.deleteFirst called on null or undefined\");if(0===arguments.length)return;const length=this.length>>>0;if(0===length)return;const splice=Array.prototype.splice,needles=Array.prototype.concat.apply([],arguments),result=[];for(let i=0;i<length&&needles.length>0;++i){const value=this[i];for(let j=0;j<needles.length;++j){const needle=needles[j];if(value===needle||value!=value&&needle!=needle){result.push(value),splice.call(this,i--,1),needles.splice(j--,1);break}}}return result}}),Object.defineProperty(Array.prototype,\"deleteLast\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.deleteLast called on null or undefined\");if(0===arguments.length)return;const length=this.length>>>0;if(0===length)return;const splice=Array.prototype.splice,needles=Array.prototype.concat.apply([],arguments),result=[];for(let i=length-1;i>=0&&needles.length>0;--i){const value=this[i];for(let j=0;j<needles.length;++j){const needle=needles[j];if(value===needle||value!=value&&needle!=needle){result.push(value),splice.call(this,i++,1),needles.splice(j--,1);break}}}return result}}),Object.defineProperty(Array.prototype,\"deleteWith\",{configurable:!0,writable:!0,value(predicate,thisArg){if(null==this)throw new TypeError(\"Array.prototype.deleteWith called on null or undefined\");if(\"function\"!=typeof predicate)throw new Error(\"Array.prototype.deleteWith predicate parameter must be a function\");const length=this.length>>>0;if(0===length)return[];const splice=Array.prototype.splice,indices=[],result=[];for(let i=0;i<length;++i)predicate.call(thisArg,this[i],i,this)&&(result.push(this[i]),indices.push(i));for(let i=indices.length-1;i>=0;--i)splice.call(this,indices[i],1);return result}}),Object.defineProperty(Array.prototype,\"first\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.first called on null or undefined\");if(0!==this.length>>>0)return this[0]}}),Object.defineProperty(Array.prototype,\"includesAll\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.includesAll called on null or undefined\");if(1===arguments.length)return Array.isArray(arguments[0])?Array.prototype.includesAll.apply(this,arguments[0]):Array.prototype.includes.apply(this,arguments);for(let i=0,iend=arguments.length;i<iend;++i)if(!Array.prototype.some.call(this,(function(val){return val===this.val||val!=val&&this.val!=this.val}),{val:arguments[i]}))return!1;return!0}}),Object.defineProperty(Array.prototype,\"includesAny\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.includesAny called on null or undefined\");if(1===arguments.length)return Array.isArray(arguments[0])?Array.prototype.includesAny.apply(this,arguments[0]):Array.prototype.includes.apply(this,arguments);for(let i=0,iend=arguments.length;i<iend;++i)if(Array.prototype.some.call(this,(function(val){return val===this.val||val!=val&&this.val!=this.val}),{val:arguments[i]}))return!0;return!1}}),Object.defineProperty(Array.prototype,\"last\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.last called on null or undefined\");const length=this.length>>>0;if(0!==length)return this[length-1]}}),Object.defineProperty(Array.prototype,\"pluck\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.pluck called on null or undefined\");const length=this.length>>>0;if(0===length)return;const index=0===arguments.length?_random(0,length-1):_randomIndex(length,Array.from(arguments));return Array.prototype.splice.call(this,index,1)[0]}}),Object.defineProperty(Array.prototype,\"pluckMany\",{configurable:!0,writable:!0,value(wantSize){if(null==this)throw new TypeError(\"Array.prototype.pluckMany called on null or undefined\");const length=this.length>>>0;if(0===length)return[];let want=Math.trunc(wantSize);if(!Number.isInteger(want))throw new Error(\"Array.prototype.pluckMany want parameter must be an integer\");if(want<1)return[];want>length&&(want=length);const splice=Array.prototype.splice,result=[];let max=length-1;do{result.push(splice.call(this,_random(0,max--),1)[0])}while(result.length<want);return result}}),Object.defineProperty(Array.prototype,\"pushUnique\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.pushUnique called on null or undefined\");const addSize=arguments.length;if(0===addSize)return this.length>>>0;const indexOf=Array.prototype.indexOf,push=Array.prototype.push;for(let i=0;i<addSize;++i){const value=arguments[i];-1===indexOf.call(this,value)&&push.call(this,value)}return this.length>>>0}}),Object.defineProperty(Array.prototype,\"random\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.random called on null or undefined\");const length=this.length>>>0;if(0===length)return;return this[0===arguments.length?_random(0,length-1):_randomIndex(length,Array.from(arguments))]}}),Object.defineProperty(Array.prototype,\"randomMany\",{configurable:!0,writable:!0,value(wantSize){if(null==this)throw new TypeError(\"Array.prototype.randomMany called on null or undefined\");const length=this.length>>>0;if(0===length)return[];let want=Math.trunc(wantSize);if(!Number.isInteger(want))throw new Error(\"Array.prototype.randomMany want parameter must be an integer\");if(want<1)return[];want>length&&(want=length);const picked=new Map,result=[],max=length-1;do{let i;do{i=_random(0,max)}while(picked.has(i));picked.set(i,!0),result.push(this[i])}while(result.length<want);return result}}),Object.defineProperty(Array.prototype,\"shuffle\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.shuffle called on null or undefined\");const length=this.length>>>0;if(0===length)return this;for(let i=length-1;i>0;--i){const j=Math.floor(_nativeMathRandom()*(i+1));if(i===j)continue;const swap=this[i];this[i]=this[j],this[j]=swap}return this}}),Object.defineProperty(Array.prototype,\"toShuffled\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.toShuffled called on null or undefined\");return Array.from(this).shuffle()}}),Object.defineProperty(Array.prototype,\"toUnique\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.toUnique called on null or undefined\");return Array.from(new Set(this))}}),Object.defineProperty(Array.prototype,\"unshiftUnique\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Array.prototype.unshiftUnique called on null or undefined\");const addSize=arguments.length;if(0===addSize)return this.length>>>0;const indexOf=Array.prototype.indexOf,unshift=Array.prototype.unshift;for(let i=0;i<addSize;++i){const value=arguments[i];-1===indexOf.call(this,value)&&unshift.call(this,value)}return this.length>>>0}}),Object.defineProperty(Function.prototype,\"partial\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"Function.prototype.partial called on null or undefined\");const slice=Array.prototype.slice,fn=this,bound=slice.call(arguments,0);return function(){const applied=[];let argc=0;for(let i=0;i<bound.length;++i)applied.push(bound[i]===undefined?arguments[argc++]:bound[i]);return fn.apply(this,applied.concat(slice.call(arguments,argc)))}}}),Object.defineProperty(Math,\"clamp\",{configurable:!0,writable:!0,value(num,min,max){if(3!==arguments.length)throw new Error(`Math.clamp called with an incorrect number of parameters (want: 3, received: ${arguments.length})`);const value=Number(num);let minVal=Number(min),maxVal=Number(max);return minVal>maxVal&&([minVal,maxVal]=[maxVal,minVal]),Math.min(Math.max(value,minVal),maxVal)}}),RegExp.escape||(()=>{const _regExpMetaCharsRe=/[\\\\^$*+?.()|[\\]{}]/g,_hasRegExpMetaCharsRe=new RegExp(_regExpMetaCharsRe.source);Object.defineProperty(RegExp,\"escape\",{configurable:!0,writable:!0,value(str){const val=String(str);return val&&_hasRegExpMetaCharsRe.test(val)?val.replace(_regExpMetaCharsRe,\"\\\\$&\"):val}})})(),(()=>{const _formatRegExp=/{(\\d+)(?:,([+-]?\\d+))?}/g,_hasFormatRegExp=new RegExp(_formatRegExp.source);Object.defineProperty(String,\"format\",{configurable:!0,writable:!0,value(format){if(arguments.length<2)return 0===arguments.length?\"\":format;const args=2===arguments.length&&Array.isArray(arguments[1])?Array.from(arguments[1]):Array.prototype.slice.call(arguments,1);return 0===args.length?format:_hasFormatRegExp.test(format)?(_formatRegExp.lastIndex=0,format.replace(_formatRegExp,((match,index,align)=>{let retval=args[index];if(null==retval)return\"\";for(;\"function\"==typeof retval;)retval=retval();switch(typeof retval){case\"string\":break;case\"object\":retval=JSON.stringify(retval);break;default:retval=String(retval)}return function(str,align,pad){if(!align)return str;const plen=Math.abs(align)-str.length;if(plen<1)return str;const padding=String(pad).repeat(plen);return align<0?str+padding:padding+str}(retval,align?Number.parseInt(align,10):0,\" \")}))):format}})})(),Object.defineProperty(String.prototype,\"count\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.count called on null or undefined\");const needle=String(arguments[0]||\"\");if(\"\"===needle)return 0;const indexOf=String.prototype.indexOf,step=needle.length;let pos=Number(arguments[1])||0,count=0;for(;-1!==(pos=indexOf.call(this,needle,pos));)++count,pos+=step;return count}}),Object.defineProperty(String.prototype,\"first\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.first called on null or undefined\");const str=String(this),{char:char}=_getCodePointStartAndEnd(str,0);return char}}),Object.defineProperty(String.prototype,\"last\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.last called on null or undefined\");const str=String(this),{char:char}=_getCodePointStartAndEnd(str,str.length-1);return char}}),Object.defineProperty(String.prototype,\"splice\",{configurable:!0,writable:!0,value(startAt,delCount,replacement){if(null==this)throw new TypeError(\"String.prototype.splice called on null or undefined\");const length=this.length>>>0;if(0===length)return\"\";let start=Number(startAt);Number.isSafeInteger(start)?start<0&&(start+=length,start<0&&(start=0)):start=0,start>length&&(start=length);let count=Number(delCount);(!Number.isSafeInteger(count)||count<0)&&(count=0);let res=this.slice(0,start);return void 0!==replacement&&(res+=replacement),start+count<length&&(res+=this.slice(start+count)),res}}),Object.defineProperty(String.prototype,\"splitOrEmpty\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.splitOrEmpty called on null or undefined\");return\"\"===String(this)?[]:String.prototype.split.apply(this,arguments)}}),Object.defineProperty(String.prototype,\"toLocaleUpperFirst\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.toLocaleUpperFirst called on null or undefined\");const str=String(this),{char:char,end:end}=_getCodePointStartAndEnd(str,0);return-1===end?\"\":char.toLocaleUpperCase()+str.slice(end+1)}}),Object.defineProperty(String.prototype,\"toUpperFirst\",{configurable:!0,writable:!0,value(){if(null==this)throw new TypeError(\"String.prototype.toUpperFirst called on null or undefined\");const str=String(this),{char:char,end:end}=_getCodePointStartAndEnd(str,0);return-1===end?\"\":char.toUpperCase()+str.slice(end+1)}}),Object.defineProperty(Array.prototype,\"delete\",{configurable:!0,writable:!0,value(){if(console.warn(\"[DEPRECATED] <Array>.delete() is deprecated.\"),null==this)throw new TypeError(\"Array.prototype.delete called on null or undefined\");return Array.prototype.deleteAll.apply(this,arguments)}}),Object.defineProperty(JSON,\"reviveWrapper\",{configurable:!0,writable:!0,value(code,data){if(console.warn(\"[DEPRECATED] JSON.reviveWrapper() is deprecated.\"),\"string\"!=typeof code)throw new TypeError(\"JSON.reviveWrapper code parameter must be a string\");return Serial.createReviver(code,data)}}),Object.defineProperty(Math,\"easeInOut\",{configurable:!0,writable:!0,value:num=>(console.warn(\"[DEPRECATED] Math.easeInOut() is deprecated.\"),1-(Math.cos(Number(num)*Math.PI)+1)/2)}),Object.defineProperty(Number.prototype,\"clamp\",{configurable:!0,writable:!0,value(){if(console.warn(\"[DEPRECATED] <Number>.clamp() is deprecated.\"),null==this)throw new TypeError(\"Number.prototype.clamp called on null or undefined\");if(2!==arguments.length)throw new Error(`Number.prototype.clamp called with an incorrect number of parameters (want: 2, received: ${arguments.length})`);return Math.clamp(this,arguments[0],arguments[1])}})})(),(()=>{function onKeypressFn(ev){13!==ev.which&&32!==ev.which||(ev.preventDefault(),triggerEvent(\"click\",getActiveElement()||this))}function onClickFnWrapper(fn){return function(){const $this=jQuery(this),dataPassage=$this.attr(\"data-passage\"),initialDataPassage=window&&window.SugarCube&&window.SugarCube.State&&window.SugarCube.State.passage,savedYOffset=window.pageYOffset;$this.is(\"[aria-pressed]\")&&$this.attr(\"aria-pressed\",\"true\"===$this.attr(\"aria-pressed\")?\"false\":\"true\"),fn.apply(this,arguments);!dataPassage||window.lastDataPassageLink!==dataPassage&&initialDataPassage!==dataPassage||window.scrollTo(0,savedYOffset),window.lastDataPassageLink=dataPassage}}function disableTabindex(el){if(!el.hasAttribute(\"data-last-tabindex\")){const tabindex=el.getAttribute(\"tabindex\");el.setAttribute(\"data-last-tabindex\",null!==tabindex?tabindex.trim():\"\")}el.setAttribute(\"tabindex\",-1)}function restoreTabindex(el){const lastTabindex=el.getAttribute(\"data-last-tabindex\");null!==lastTabindex&&(el.removeAttribute(\"data-last-tabindex\"),\"\"===lastTabindex?el.removeAttribute(\"tabindex\"):el.setAttribute(\"tabindex\",lastTabindex))}jQuery.fn.extend({ariaClick(options,handler){if(0===this.length||0===arguments.length)return this;let opts=options,fn=handler;return null==fn&&(fn=opts,opts=undefined),opts=jQuery.extend({namespace:undefined,one:!1,selector:undefined,data:undefined,role:undefined,tabindex:0,controls:undefined,pressed:undefined,label:undefined},opts),\"string\"!=typeof opts.namespace?opts.namespace=\"\":\".\"!==opts.namespace[0]&&(opts.namespace=`.${opts.namespace}`),\"boolean\"==typeof opts.pressed&&(opts.pressed=opts.pressed?\"true\":\"false\"),this.filter(\"button\").prop(\"type\",\"button\"),null!=opts.role?this.attr(\"role\",opts.role):this.not(\"[role]\").filter(\"a,[data-passage]\").attr(\"role\",\"link\").end().not(\"a\").not(\"[data-passage]\").attr(\"role\",\"button\").end().end().end(),this.attr(\"tabindex\",opts.tabindex),null!=opts.controls&&this.attr(\"aria-controls\",opts.controls),null!=opts.pressed&&this.attr(\"aria-pressed\",opts.pressed),null!=opts.label&&this.attr({\"aria-label\":opts.label,title:opts.label}),this.not(\"button\").on(`keypress.aria-clickable${opts.namespace}`,opts.selector,onKeypressFn),this.on(`click.aria-clickable${opts.namespace}`,opts.selector,opts.data,opts.one?function(fn){return onClickFnWrapper((function(){jQuery(this).off(\".aria-clickable\").removeAttr(\"role tabindex aria-controls aria-pressed\").filter(\"button\").prop(\"disabled\",!0),fn.apply(this,arguments)}))}(fn):onClickFnWrapper(fn)),this},ariaDisabled(disable){if(0===this.length||0===arguments.length)return this;const $nonDisableable=this.not(\"button,fieldset,input,menuitem,optgroup,option,select,textarea\"),$disableable=this.filter(\"button,fieldset,input,menuitem,optgroup,option,select,textarea\");return disable?($nonDisableable.each((function(){this.setAttribute(\"disabled\",\"disabled\"),this.setAttribute(\"aria-disabled\",\"true\"),disableTabindex(this)})),$disableable.each((function(){this.disabled=!0,this.setAttribute(\"aria-disabled\",\"true\"),disableTabindex(this)}))):($nonDisableable.each((function(){this.removeAttribute(\"disabled\"),this.removeAttribute(\"aria-disabled\"),restoreTabindex(this)})),$disableable.each((function(){this.disabled=!1,this.removeAttribute(\"aria-disabled\"),restoreTabindex(this)}))),this},ariaIsDisabled(){return this.is(\"[disabled]\")}})})(),jQuery.fn.extend({getForbiddenInteractiveContentTagNames(){if(0===this.length)return[];const forbidden=new Set;return this.find(\"a,button,fieldset,form,input,menuitem,optgroup,option,select,textarea\").each(((_,el)=>forbidden.add(el.nodeName.toLowerCase()))),Array.from(forbidden)}}),jQuery.extend({wikiWithOptions(options,...sources){if(0===sources.length)return;const frag=document.createDocumentFragment();sources.forEach((content=>new Wikifier(frag,content,options)));const errors=Array.from(frag.querySelectorAll(\".error\")).map((errEl=>errEl.textContent.replace(errorPrologRegExp,\"\")));if(errors.length>0)throw new Error(errors.join(\"; \"))},wiki(...sources){this.wikiWithOptions(undefined,...sources)},wikiPassage(name){this.wikiWithOptions(undefined,Story.get(name).processText())}}),jQuery.fn.extend({wikiWithOptions(options,...sources){if(0===this.length||0===sources.length)return this;const frag=document.createDocumentFragment();return sources.forEach((content=>new Wikifier(frag,content,options))),this.append(frag),this},wiki(...sources){return this.wikiWithOptions(undefined,...sources)},wikiPassage(name){return this.wikiWithOptions(undefined,Story.get(name).processText())}});var Browser=(()=>{const userAgent=navigator.userAgent.toLowerCase(),winPhone=userAgent.includes(\"windows phone\"),isMobile=Object.freeze({Android:!winPhone&&userAgent.includes(\"android\"),BlackBerry:/blackberry|bb10/.test(userAgent),iOS:!winPhone&&/ip(?:hone|ad|od)/.test(userAgent),Opera:!winPhone&&(\"object\"==typeof window.operamini||userAgent.includes(\"opera mini\")),Windows:winPhone||/iemobile|wpdesktop/.test(userAgent),any:()=>isMobile.Android||isMobile.BlackBerry||isMobile.iOS||isMobile.Opera||isMobile.Windows}),isGecko=!isMobile.Windows&&!/khtml|trident|edge/.test(userAgent)&&userAgent.includes(\"gecko\"),isIE=!userAgent.includes(\"opera\")&&/msie|trident/.test(userAgent),ieVersion=isIE?(()=>{const ver=/(?:msie\\s+|rv:)(\\d+\\.\\d)/.exec(userAgent);return ver?Number(ver[1]):0})():null,isOpera=userAgent.includes(\"opera\")||userAgent.includes(\" opr/\"),operaVersion=isOpera?(()=>{const ver=new RegExp((/khtml|chrome/.test(userAgent)?\"opr\":\"version\")+\"\\\\/(\\\\d+\\\\.\\\\d+)\").exec(userAgent);return ver?Number(ver[1]):0})():null,isVivaldi=userAgent.includes(\"vivaldi\");return Object.freeze(Object.assign(Object.create(null),{userAgent:userAgent,isMobile:isMobile,isGecko:isGecko,isIE:isIE,ieVersion:ieVersion,isOpera:isOpera,operaVersion:operaVersion,isVivaldi:isVivaldi}))})(),Has=(()=>{const hasAudioElement=(()=>{try{return\"function\"==typeof document.createElement(\"audio\").canPlayType}catch(ex){}return!1})(),hasFile=(()=>{try{return\"Blob\"in window&&\"File\"in window&&\"FileList\"in window&&\"FileReader\"in window&&(!Browser.isOpera||Browser.operaVersion>=15)}catch(ex){}return!1})(),hasGeolocation=(()=>{try{return\"geolocation\"in navigator&&\"function\"==typeof navigator.geolocation.getCurrentPosition&&\"function\"==typeof navigator.geolocation.watchPosition}catch(ex){}return!1})(),hasMutationObserver=(()=>{try{return\"MutationObserver\"in window&&\"function\"==typeof window.MutationObserver}catch(ex){}return!1})(),hasPerformance=(()=>{try{return\"performance\"in window&&\"function\"==typeof window.performance.now}catch(ex){}return!1})(),hasTouch=(()=>{try{return\"ontouchstart\"in window||!!window.DocumentTouch&&document instanceof window.DocumentTouch||!!navigator.maxTouchPoints||!!navigator.msMaxTouchPoints}catch(ex){}return!1})(),hasTransitionEndEvent=(()=>{try{const teMap=new Map([[\"transition\",\"transitionend\"],[\"MSTransition\",\"msTransitionEnd\"],[\"WebkitTransition\",\"webkitTransitionEnd\"],[\"MozTransition\",\"transitionend\"]]),teKeys=Array.from(teMap.keys()),el=document.createElement(\"div\");for(let i=0;i<teKeys.length;++i)if(el.style[teKeys[i]]!==undefined)return teMap.get(teKeys[i])}catch(ex){}return!1})();return Object.freeze(Object.assign(Object.create(null),{audio:hasAudioElement,fileAPI:hasFile,geolocation:hasGeolocation,mutationObserver:hasMutationObserver,performance:hasPerformance,touch:hasTouch,transitionEndEvent:hasTransitionEndEvent}))})(),Fullscreen=(()=>{const vendor=(()=>{try{return Object.freeze([{isEnabled:\"fullscreenEnabled\",element:\"fullscreenElement\",requestFn:\"requestFullscreen\",exitFn:\"exitFullscreen\",changeEvent:\"fullscreenchange\",errorEvent:\"fullscreenerror\"},{isEnabled:\"webkitFullscreenEnabled\",element:\"webkitFullscreenElement\",requestFn:\"webkitRequestFullscreen\",exitFn:\"webkitExitFullscreen\",changeEvent:\"webkitfullscreenchange\",errorEvent:\"webkitfullscreenerror\"},{isEnabled:\"mozFullScreenEnabled\",element:\"mozFullScreenElement\",requestFn:\"mozRequestFullScreen\",exitFn:\"mozCancelFullScreen\",changeEvent:\"mozfullscreenchange\",errorEvent:\"mozfullscreenerror\"},{isEnabled:\"msFullscreenEnabled\",element:\"msFullscreenElement\",requestFn:\"msRequestFullscreen\",exitFn:\"msExitFullscreen\",changeEvent:\"MSFullscreenChange\",errorEvent:\"MSFullscreenError\"}].find((vnd=>vnd.isEnabled in document)))}catch(ex){}return undefined})(),_returnsPromise=function(){let _hasPromise=null;return function(){if(null!==_hasPromise)return _hasPromise;if(_hasPromise=!1,vendor)try{const value=document.exitFullscreen();value.catch((()=>{})),_hasPromise=value instanceof Promise}catch(ex){}return _hasPromise}}();function _selectElement(requestedEl){let selectedEl=requestedEl||document.documentElement;return selectedEl===document.documentElement&&(\"msRequestFullscreen\"===vendor.requestFn||Browser.isOpera&&Browser.operaVersion<15)&&(selectedEl=document.body),selectedEl}function isFullscreen(){return Boolean(vendor&&document[vendor.element])}function requestFullscreen(options,requestedEl){if(!vendor)return Promise.reject(new Error(\"fullscreen not supported\"));const element=_selectElement(requestedEl);if(\"function\"!=typeof element[vendor.requestFn])return Promise.reject(new Error(\"fullscreen not supported\"));if(isFullscreen())return Promise.resolve();if(_returnsPromise())return element[vendor.requestFn](options);{const namespace=\".Fullscreen_requestFullscreen\";return new Promise(((resolve,reject)=>{const $element=jQuery(element);$element.off(namespace).one(`${vendor.errorEvent}${namespace} ${vendor.changeEvent}${namespace}`,(ev=>{$element.off(namespace),ev.type===vendor.errorEvent?reject(new Error(\"unknown fullscreen request error\")):resolve()})),element[vendor.requestFn](options)}))}}function exitFullscreen(){if(!vendor||\"function\"!=typeof document[vendor.exitFn])return Promise.reject(new TypeError(\"fullscreen not supported\"));if(!isFullscreen())return Promise.reject(new TypeError(\"fullscreen mode not active\"));if(_returnsPromise())return document[vendor.exitFn]();{const namespace=\".Fullscreen_exitFullscreen\";return new Promise(((resolve,reject)=>{const $document=jQuery(document);$document.off(namespace).one(`${vendor.errorEvent}${namespace} ${vendor.changeEvent}${namespace}`,(ev=>{$document.off(namespace),ev.type===vendor.errorEvent?reject(new Error(\"unknown fullscreen exit error\")):resolve()})),document[vendor.exitFn]()}))}}return Object.preventExtensions(Object.create(null,{vendor:{get:function(){return vendor}},element:{get:function(){return vendor?document[vendor.element]:null}},isEnabled:{value:function(){return Boolean(vendor&&document[vendor.isEnabled])}},isFullscreen:{value:isFullscreen},request:{value:requestFullscreen},exit:{value:exitFullscreen},toggle:{value:function(options,requestedEl){return isFullscreen()?exitFullscreen():requestFullscreen(options,requestedEl)}},onChange:{value:function(handlerFn,requestedEl){if(!vendor)return;const element=_selectElement(requestedEl);jQuery(element).on(vendor.changeEvent,handlerFn)}},offChange:{value:function(handlerFn,requestedEl){if(!vendor)return;const element=_selectElement(requestedEl);handlerFn?jQuery(element).off(vendor.changeEvent,handlerFn):jQuery(element).off(vendor.changeEvent)}},onError:{value:function(handlerFn,requestedEl){if(!vendor)return;const element=_selectElement(requestedEl);jQuery(element).on(vendor.errorEvent,handlerFn)}},offError:{value:function(handlerFn,requestedEl){if(!vendor)return;const element=_selectElement(requestedEl);handlerFn?jQuery(element).off(vendor.errorEvent,handlerFn):jQuery(element).off(vendor.errorEvent)}}}))})(),Outliner=(()=>{let lastEvent,styleEl=null;function outlinerHide(){document.documentElement.removeAttribute(\"data-outlines\"),styleEl.styleSheet?styleEl.styleSheet.cssText=\"*:focus{outline:none;}\":styleEl.textContent=\"*:focus{outline:none;}\"}function outlinerShow(){document.documentElement.setAttribute(\"data-outlines\",\"\"),styleEl.styleSheet?styleEl.styleSheet.cssText=\"\":styleEl.textContent=\"\"}return Object.preventExtensions(Object.create(null,{init:{value:function(){styleEl||(styleEl=document.createElement(\"style\"),jQuery(styleEl).attr({id:\"style-outliner\",type:\"text/css\"}).appendTo(document.head),jQuery(document).on(\"mousedown.style-outliner keydown.style-outliner\",(ev=>{ev.type!==lastEvent&&(lastEvent=ev.type,\"keydown\"===ev.type?outlinerShow():outlinerHide())})),lastEvent=\"mousedown\",outlinerHide())}},hide:{value:outlinerHide},show:{value:outlinerShow}}))})(),Serial=(()=>{const supportedTypes=Object.freeze([{id:\"Date\",get reference(){return Date.prototype},method(){return[\"(revive:date)\",this.toISOString()]}},{id:\"Function\",get reference(){return Function.prototype},method(){return[\"(revive:)\",[`(${this.toString()})`]]}},{id:\"Map\",get reference(){return Map.prototype},method(){return[\"(revive:map)\",Array.from(this)]}},{id:\"RegExp\",get reference(){return RegExp.prototype},method(){return[\"(revive:)\",[this.toString()]]}},{id:\"Set\",get reference(){return Set.prototype},method(){return[\"(revive:set)\",Array.from(this)]}}]);function createReviver(code,data){if(\"string\"!=typeof code)throw new TypeError(\"Serial.createReviver code parameter must be a string\");return[\"(revive:)\",[code,data]]}function parse(text,reviver){return JSON.parse(text,((key,val)=>{let value=val;if(value instanceof Array&&2===value.length)switch(value[0]){case\"(revive:set)\":value=new Set(value[1]);break;case\"(revive:map)\":value=new Map(value[1]);break;case\"(revive:date)\":value=new Date(value[1]);break;case\"(revive:eval)\":case\"(revive:)\":try{const $ReviveData$=value[1][1];value=eval(value[1][0])}catch(ex){}}if(\"function\"==typeof reviver)try{value=reviver(key,value)}catch(ex){}return value}))}function stringify(value,replacer,space){const origMethodCache=new Map;supportedTypes.forEach((({id:id,reference:reference,method:method})=>{Object.hasOwn(reference,\"toJSON\")&&origMethodCache.set(id,reference.toJSON),Object.defineProperty(reference,\"toJSON\",{configurable:!0,writable:!0,value:method})}));const notation=JSON.stringify(value,((key,val)=>{let value=val;if(\"function\"==typeof replacer)try{value=replacer(key,value)}catch(ex){}switch(value){case undefined:value=[\"(revive:)\",[\"undefined\"]];break;case 1/0:value=[\"(revive:)\",[\"Infinity\"]]}return value}),space);return supportedTypes.forEach((({id:id,reference:reference})=>{origMethodCache.has(id)?(Object.defineProperty(reference,\"toJSON\",{configurable:!0,writable:!0,value:origMethodCache.get(id)}),origMethodCache.delete(id)):delete reference.toJSON})),notation}return Object.preventExtensions(Object.create(null,{createReviver:{value:createReviver},parse:{value:parse},stringify:{value:stringify}}))})(),Visibility=(()=>{const vendor=(()=>{try{return Object.freeze([{hiddenProperty:\"hidden\",stateProperty:\"visibilityState\",changeEvent:\"visibilitychange\"},{hiddenProperty:\"webkitHidden\",stateProperty:\"webkitVisibilityState\",changeEvent:\"webkitvisibilitychange\"},{hiddenProperty:\"mozHidden\",stateProperty:\"mozVisibilityState\",changeEvent:\"mozvisibilitychange\"},{hiddenProperty:\"msHidden\",stateProperty:\"msVisibilityState\",changeEvent:\"msvisibilitychange\"}].find((vnd=>vnd.hiddenProperty in document)))}catch(ex){}return undefined})();return Object.preventExtensions(Object.create(null,{vendor:{get:function(){return vendor}},state:{get:function(){return vendor&&document[vendor.stateProperty]||\"visible\"}},isEnabled:{value:function(){return Boolean(vendor)}},isHidden:{value:function(){return Boolean(vendor&&document[vendor.hiddenProperty])}},hiddenProperty:{value:vendor&&vendor.hiddenProperty},stateProperty:{value:vendor&&vendor.stateProperty},changeEvent:{value:vendor&&vendor.changeEvent}}))})();function appendError(output,message,source,stack){const $wrapper=jQuery(document.createElement(\"div\")),$toggle=jQuery(document.createElement(\"button\")),$source=jQuery(document.createElement(\"pre\")),mesg=`${L10n.get(\"errorViewTitle\")}: ${message||\"unknown error\"} ${Config.saves.version}`;if($toggle.addClass(\"error-toggle\").ariaClick({label:L10n.get(\"errorViewLabelToggle\")},(()=>{$toggle.hasClass(\"enabled\")?($toggle.removeClass(\"enabled\"),$source.attr({\"aria-hidden\":!0,hidden:\"hidden\"})):($toggle.addClass(\"enabled\"),$source.removeAttr(\"aria-hidden hidden\"))})).appendTo($wrapper),jQuery(document.createElement(\"span\")).addClass(\"error\").text(mesg).appendTo($wrapper),jQuery(document.createElement(\"code\")).text(source).appendTo($source),$source.addClass(\"error-source\").attr({\"aria-hidden\":!0,hidden:\"hidden\"}).appendTo($wrapper),stack){const lines=stack.split(\"\\n\");for(const ll of lines){const div=document.createElement(\"div\");div.append(ll.replace(/file:.*\\//,\"<path>/\")),$source.append(div)}}return $wrapper.addClass(\"error-view\").appendTo(output),console.warn(`${mesg}\\n\\t${source.replace(/\\n/g,\"\\n\\t\")}`),!1}var throwError=appendError;function charAndPosAt(string,position){const str=String(string),pos=Math.trunc(position),code=str.charCodeAt(pos);if(Number.isNaN(code))return{char:\"\",start:-1,end:-1};const retval={char:str.charAt(pos),start:pos,end:pos};if(code<55296||code>57343)return retval;if(code>=55296&&code<=56319){const nextPos=pos+1;if(nextPos>=str.length)return retval;const nextCode=str.charCodeAt(nextPos);return nextCode<56320||nextCode>57343||(retval.char=retval.char+str.charAt(nextPos),retval.end=nextPos),retval}if(0===pos)return retval;const prevPos=pos-1,prevCode=str.charCodeAt(prevPos);return prevCode<55296||prevCode>56319||(retval.char=str.charAt(prevPos)+retval.char,retval.start=prevPos),retval}function clone(O){if(\"object\"!=typeof O||null===O)return O;if(\"function\"==typeof O.clone)return O.clone(!0);let copy;if(O instanceof Array)copy=new Array(O.length);else if(O instanceof Date)copy=new Date(O.getTime());else if(O instanceof Map)copy=new Map,O.forEach(((val,key)=>copy.set(clone(key),clone(val))));else if(O instanceof RegExp)copy=new RegExp(O);else if(O instanceof Set)copy=new Set,O.forEach((val=>copy.add(clone(val))));else{const type=getTypeOf(O);if(\"Object\"!==type)throw new TypeError(`attempted to clone unsupported type: ${type}`);copy=Object.create(Object.getPrototypeOf(O))}return Object.keys(O).forEach((P=>copy[P]=clone(O[P]))),copy}var convertBreaks=(()=>{const isNotSpaceRE=new RegExp(Patterns.notSpace);function isParagraphEmpty(para){if(!para.hasChildNodes())return!0;const nodes=para.childNodes,length=nodes.length;for(let i=0;i<length;++i){const node=nodes[i];switch(node.nodeType){case Node.TEXT_NODE:if(isNotSpaceRE.test(node.nodeValue))return!1;break;case Node.COMMENT_NODE:break;default:return!1}}return!0}return function(source){const output=document.createDocumentFragment();let node,para=document.createElement(\"p\");for(;null!==(node=source.firstChild);){if(node.nodeType===Node.ELEMENT_NODE){switch(node.nodeName.toUpperCase()){case\"BR\":if(null!==node.nextSibling&&node.nextSibling.nodeType===Node.ELEMENT_NODE&&\"BR\"===node.nextSibling.nodeName.toUpperCase()){source.removeChild(node.nextSibling),source.removeChild(node),isParagraphEmpty(para)||output.appendChild(para),para=document.createElement(\"p\");continue}if(isParagraphEmpty(para)){source.removeChild(node);continue}break;case\"ADDRESS\":case\"ARTICLE\":case\"ASIDE\":case\"BLOCKQUOTE\":case\"CENTER\":case\"DIV\":case\"DL\":case\"FIGURE\":case\"FOOTER\":case\"FORM\":case\"H1\":case\"H2\":case\"H3\":case\"H4\":case\"H5\":case\"H6\":case\"HEADER\":case\"HR\":case\"MAIN\":case\"NAV\":case\"OL\":case\"P\":case\"PRE\":case\"SECTION\":case\"TABLE\":case\"UL\":isParagraphEmpty(para)||(output.appendChild(para),para=document.createElement(\"p\")),output.appendChild(node);continue}}para.appendChild(node)}isParagraphEmpty(para)||output.appendChild(para),source.appendChild(output)}})(),createFilename=(()=>{const illegalCharsRE=/[\\x00-\\x1f\"#$%&'*+,/:;<=>?\\\\^`|\\x7f-\\x9f]+/g;return function(str){return String(str).trim().replace(illegalCharsRE,\"\")}})(),createSlug=(()=>{const illegalCharsRE=/[\\x00-\\x20!-/:-@[-^`{-\\x9f]+/g,isInvalidSlugRE=/^-*$/,storySigilRE=/^\\$/,tempSigilRE=/^_/;return function(str){const base=String(str).trim(),legacy=base.replace(/[^\\w\\s\\u2013\\u2014-]+/g,\"\").replace(/[_\\s\\u2013\\u2014-]+/g,\"-\").toLocaleLowerCase();return isInvalidSlugRE.test(legacy)?base.replace(storySigilRE,\"\").replace(tempSigilRE,\"-\").replace(illegalCharsRE,\"\"):legacy}})();function cssPropToDOMProp(cssName){if(!cssName.includes(\"-\"))switch(cssName){case\"bgcolor\":return\"backgroundColor\";case\"float\":return\"cssFloat\";default:return cssName}return(\"-ms-\"===cssName.slice(0,4)?cssName.slice(1):cssName).split(\"-\").map(((part,i)=>0===i?part:part.toUpperFirst())).join(\"\")}const cssTimeToMS=(()=>{const cssTimeRE=/^([+-]?(?:\\d*\\.)?\\d+)([Mm]?[Ss])$/;return function(cssTime){const match=cssTimeRE.exec(String(cssTime));if(null===match)throw new SyntaxError(`invalid time value syntax: \"${cssTime}\"`);let msec=Number(match[1]);if(1===match[2].length&&(msec*=1e3),Number.isNaN(msec)||!Number.isFinite(msec))throw new RangeError(`invalid time value: \"${cssTime}\"`);return msec}})();var decodeEntities=(()=>{const escapedHtmlRE=/&(?:amp|#38|#x26|lt|#60|#x3c|gt|#62|#x3e|quot|#34|#x22|apos|#39|#x27|#96|#x60);/gi,hasEscapedHtmlRE=new RegExp(escapedHtmlRE.source,\"i\"),escapedHtmlTable=enumFrom({\"&\":\"&\",\"&\":\"&\",\"&\":\"&\",\"<\":\"<\",\"<\":\"<\",\"<\":\"<\",\">\":\">\",\">\":\">\",\">\":\">\",\""\":'\"',\""\":'\"',\""\":'\"',\"'\":\"'\",\"'\":\"'\",\"'\":\"'\",\"`\":\"`\",\"`\":\"`\"});return function(str){if(null==str)return\"\";const val=String(str);return val&&hasEscapedHtmlRE.test(val)?val.replace(escapedHtmlRE,(entity=>escapedHtmlTable[entity.toLowerCase()])):val}})(),encodeEntities=(()=>{const htmlCharsRE=/[&<>\"'`]/g,hasHtmlCharsRE=new RegExp(htmlCharsRE.source),htmlCharsTable=enumFrom({\"&\":\"&\",\"<\":\"<\",\">\":\">\",'\"':\""\",\"'\":\"'\",\"`\":\"`\"});return function(str){if(null==str)return\"\";const val=String(str);return val&&hasHtmlCharsRE.test(val)?val.replace(htmlCharsRE,(ch=>htmlCharsTable[ch])):val}})(),encodeMarkup=(()=>{const markupCharsRE=/[!\"#$&'*\\-/<=>?@[\\\\\\]^_`{|}~]/g,hasMarkupCharsRE=new RegExp(markupCharsRE.source),markupCharsTable=enumFrom({\"!\":\"!\",'\"':\""\",\"#\":\"#\",$:\"$\",\"&\":\"&\",\"'\":\"'\",\"*\":\"*\",\"-\":\"-\",\"/\":\"/\",\"<\":\"<\",\"=\":\"=\",\">\":\">\",\"?\":\"?\",\"@\":\"@\",\"[\":\"[\",\"\\\\\":\"\\",\"]\":\"]\",\"^\":\"^\",_:\"_\",\"`\":\"`\",\"{\":\"{\",\"|\":\"|\",\"}\":\"}\",\"~\":\"~\"});return function(str){if(null==str)return\"\";const val=String(str);return val&&hasMarkupCharsRE.test(val)?val.replace(markupCharsRE,(ch=>markupCharsTable[ch])):val}})(),enquote=(()=>{const unescapedDQuoteRE=/(^|[^\\\\])(\")/g,unescapedSQuoteRE=/(^|[^\\\\])(')/g;return function(string){let dqCount=0,sqCount=0;for(let i=0;i<string.length;++i)switch(string[i]){case\"\\\\\":++i;break;case'\"':++dqCount;break;case\"'\":++sqCount}if(0===dqCount)return`\"${string}\"`;if(0===sqCount)return`'${string}'`;const quote=dqCount<=sqCount?'\"':\"'\";return`${quote}${string.replace('\"'===quote?unescapedDQuoteRE:unescapedSQuoteRE,\"$1\\\\$2\")}${quote}`}})();function enumFrom(O){const pEnum=Object.create(null);if(O instanceof Array)O.forEach(((val,i)=>pEnum[String(val)]=i));else if(O instanceof Set)Array.from(O).forEach(((val,i)=>pEnum[String(val)]=i));else if(O instanceof Map)O.forEach(((val,key)=>pEnum[String(key)]=val));else{if(null===O||\"object\"!=typeof O||Object.getPrototypeOf(O)!==Object.prototype)throw new TypeError(\"enumFrom object parameter must be an Array, Map, Set, or generic object\");Object.assign(pEnum,O)}return Object.freeze(Object.defineProperties(pEnum,{nameFrom:{value(needle){const entry=Object.entries(this).find((entry=>entry[1]===needle));return entry?entry[0]:undefined}}}))}var exceptionFrom=(()=>{const extraProps=Object.freeze([\"code\",\"data\",\"result\",\"stack\",\"columnNumber\",\"fileName\",\"lineNumber\",\"description\",\"number\"]);return function(original,exceptionType,override){if(null===original||\"object\"!=typeof original)throw new Error(\"exceptionFrom original parameter must be an object\");if(\"function\"!=typeof exceptionType)throw new Error(\"exceptionFrom exceptionType parameter must be an error type constructor\");const overrideType=typeof override;if(\"undefined\"!==overrideType&&\"string\"!==overrideType&&\"object\"!==overrideType)throw new Error(\"exceptionFrom override parameter must be an object or string\");const propValues=new Map;extraProps.forEach((name=>{void 0!==original[name]&&propValues.set(name,original[name])})),\"string\"===overrideType?propValues.set(\"message\",override):\"object\"===overrideType&&null!==override&&Object.getOwnPropertyNames(override).forEach((name=>{void 0!==override[name]&&propValues.set(name,override[name])}));const ex=new exceptionType(propValues.get(\"message\"));return propValues.delete(\"message\"),propValues.forEach(((value,name)=>{void 0===ex[name]?Object.defineProperty(ex,name,{value:value,configurable:!0,writable:!0}):ex[name]=value})),ex}})();function getActiveElement(){try{return document.activeElement||null}catch(ex){return null}}function getErrorMessage(O){return null==O?\"unknown error\":\"object\"==typeof O&&\"message\"in O?`${O.name||\"NoErrorName\"}: ${O.message}`:String(O)}var getToStringTag=(()=>{const toString=Object.prototype.toString,slice=String.prototype.slice;return\"[object Object]\"===toString.call(new Map)?function(O){return O instanceof Map?\"Map\":O instanceof Set?\"Set\":slice.call(toString.call(O),8,-1)}:function(O){return slice.call(toString.call(O),8,-1)}})(),getTypeOf=(()=>{const toString=Object.prototype.toString,slice=String.prototype.slice;return function(O){if(null===O)return\"null\";const baseType=typeof O;return\"object\"===baseType?slice.call(toString.call(O),8,-1):baseType}})(),hasMediaQuery=\"function\"!=typeof window.matchMedia?function(){return!1}:function(mediaQuery){return window.matchMedia(mediaQuery).matches},isExternalLink=(()=>{const externalUrlRE=new RegExp(`^${Patterns.externalUrl}`,\"gim\"),fingerprintRE=/[/\\\\?]/;return function(link){return!Story.has(link)&&(externalUrlRE.test(link)||fingerprintRE.test(link))}})();function msToCSSTime(msec){if(\"number\"!=typeof msec||Number.isNaN(msec)||!Number.isFinite(msec)){let what;switch(typeof msec){case\"string\":what=`\"${msec}\"`;break;case\"number\":what=String(msec);break;default:what=getTypeOf(msec)}throw new TypeError(`invalid milliseconds value: ${what}`)}return`${msec}ms`}var now=(()=>{const clock=Has.performance?performance:Date;return function(){return clock.now()}})(),onUserActivation=(()=>{const uaEvents=Object.freeze([\"keydown\",\"mousedown\",\"pointerdown\",\"pointerup\",\"touchend\"]);return function(namespace,callback){jQuery(document).off(namespace).on(uaEvents.map((name=>`${name}${namespace}`)).join(\" \"),(ev=>{callback(ev).then((()=>jQuery(document).off(namespace)),(ex=>{if(\"NotAllowedError\"!==ex.name)throw jQuery(document).off(namespace),ex}))}))}})();function parseURL(url){const parser=document.createElement(\"a\"),searchParams=Object.create(null);parser.href=url,parser.search&&parser.search.replace(/^\\?/,\"\").splitOrEmpty(/(?:&(?:amp;)?|;)/).forEach((query=>{const[key,value]=query.split(\"=\");Object.hasOwn(searchParams,key)?searchParams[key].push(value):searchParams[key]=[value]}));const pathname=parser.host&&\"/\"!==parser.pathname[0]?`/${parser.pathname}`:parser.pathname;return Object.freeze(Object.assign(Object.create(null),{href:parser.href,protocol:parser.protocol,host:parser.host,hostname:parser.hostname,port:parser.port,path:`${pathname}${parser.search}`,pathname:pathname,search:parser.search,searchParams:Object.freeze(searchParams),hash:parser.hash}))}function sameValueZero(a,b){return a===b||a!=a&&b!=b}var scrubEventKey=(()=>{let separatorKey,decimalKey;if(\"undefined\"!=typeof Intl&&\"function\"==typeof Intl.NumberFormat){const match=(new Intl.NumberFormat).format(111111.5).match(/(\\D*)\\d+(\\D*)\\d$/);match&&(separatorKey=match[1],decimalKey=match[2])}return separatorKey||decimalKey||(separatorKey=\",\",decimalKey=\".\"),function(key){switch(key){case\"Scroll\":return\"ScrollLock\";case\"Spacebar\":return\" \";case\"Left\":return\"ArrowLeft\";case\"Right\":return\"ArrowRight\";case\"Up\":return\"ArrowUp\";case\"Down\":return\"ArrowDown\";case\"Del\":return\"Delete\";case\"Crsel\":return\"CrSel\";case\"Exsel\":return\"ExSel\";case\"Esc\":return\"Escape\";case\"Apps\":return\"ContextMenu\";case\"Nonconvert\":return\"NonConvert\";case\"MediaNextTrack\":return\"MediaTrackNext\";case\"MediaPreviousTrack\":return\"MediaTrackPrevious\";case\"VolumeUp\":return\"AudioVolumeUp\";case\"VolumeDown\":return\"AudioVolumeDown\";case\"VolumeMute\":return\"AudioVolumeMute\";case\"Zoom\":return\"ZoomToggle\";case\"SelectMedia\":case\"MediaSelect\":return\"LaunchMediaPlayer\";case\"Add\":return\"+\";case\"Divide\":return\"/\";case\"Multiply\":return\"*\";case\"Subtract\":return\"-\";case\"Decimal\":return decimalKey;case\"Separator\":return separatorKey}return key}})(),setDisplayTitle=function(title,isPlainText){if(\"string\"!=typeof title)throw new TypeError(`title parameter must be a string (received: ${getTypeOf(title)})`);let render,text;isPlainText?(render=title.trim(),text=render):(render=document.createDocumentFragment(),new Wikifier(render,title,{noCleanup:!0}),text=function(source){const copy=source.cloneNode(!0),frag=document.createDocumentFragment();let node;for(;null!==(node=copy.firstChild);){if(node.nodeType===Node.ELEMENT_NODE)switch(node.nodeName.toUpperCase()){case\"BR\":case\"DIV\":case\"P\":frag.appendChild(document.createTextNode(\" \"))}frag.appendChild(node)}return frag.textContent}(render).trim()),document.title=Config.passages.displayTitles&&\"\"!==State.passage&&State.passage!==Config.passages.start?`${State.passage} | ${text}`:text,jQuery(\"#story-title\").empty().append(render)};function setPageElement(idOrElement,titles,defaultText){const el=\"object\"==typeof idOrElement?idOrElement:document.getElementById(idOrElement);if(null==el)return null;const ids=titles instanceof Array?titles:[titles];jQuery(el).empty();for(let i=0;i<ids.length;++i)if(Story.has(ids[i]))return new Wikifier(el,Story.get(ids[i]).processText().trim()),el;if(null!=defaultText){const text=String(defaultText).trim();\"\"!==text&&new Wikifier(el,text)}return el}function stringFrom(value){switch(typeof value){case\"function\":return\"[function]\";case\"number\":if(Number.isNaN(value))return\"[number NaN]\";break;case\"object\":if(null===value)return\"[null]\";if(value instanceof Array)return value.map((val=>stringFrom(val))).join(\", \");if(value instanceof Set)return Array.from(value).map((val=>stringFrom(val))).join(\", \");if(value instanceof Map){return`{ ${Array.from(value).map((([key,val])=>`${stringFrom(key)} → ${stringFrom(val)}`)).join(\", \")} }`}if(value instanceof Date)return value.toLocaleString();if(value instanceof Element){if(value===document.documentElement||value===document.head||value===document.body)throw new Error(\"illegal operation; attempting to convert the <html>, <head>, or <body> tags to string is not allowed\");return value.outerHTML}if(value instanceof Node)return value.textContent;break;case\"symbol\":return`[symbol${void 0!==value.description?` \"${value.description}\"`:\"\"}]`;case\"undefined\":return\"[undefined]\"}return String(value)}var triggerEvent=(()=>{const createEvent=(()=>{try{return new CustomEvent(\"click\",{bubbles:!0}),function(name,options){const{bubbles:bubbles,cancelable:cancelable,composed:composed,detail:detail,...custom}=Object.assign({bubbles:!0,cancelable:!0,composed:!1},options),event=new CustomEvent(name,{bubbles:bubbles,cancelable:cancelable,composed:composed,detail:detail});for(let i=0,keys=Object.keys(custom);i<keys.length;++i){const key=keys[i];void 0!==custom[key]&&(event[key]=options[key])}return event}}catch(ex){return function(name,options){const{bubbles:bubbles,cancelable:cancelable,...custom}=Object.assign({bubbles:!0,cancelable:!0},options),event=document.createEvent(\"Event\");for(let i=0,keys=Object.keys(custom);i<keys.length;++i){const key=keys[i];void 0!==custom[key]&&(event[key]=options[key])}return event.initEvent(name,bubbles,cancelable),event}}})();return function(name,targets,options){const event=createEvent(name,options),elems=[];if(targets)if(targets instanceof jQuery||targets instanceof NodeList||targets instanceof Array)for(let i=0;i<targets.length;++i)elems.push(targets[i]);else elems.push(targets);else elems.push(document);for(let i=0;i<elems.length;++i)elems[i].dispatchEvent(event)}})(),SimpleStore=(()=>{const _adapters=[];let _initialized=null;return Object.preventExtensions(Object.create(null,{adapters:{value:_adapters},create:{value:function(storageId,persistent){if(_initialized)return _initialized.create(storageId,persistent);for(let i=0;i<_adapters.length;++i)if(_adapters[i].init(storageId,persistent))return _initialized=_adapters[i],_initialized.create(storageId,persistent);throw new Error(\"No valid storage adapters found\")}}}))})();SimpleStore.adapters.push((()=>{let _ok=!1;class _FCHostStorageAdapter{constructor(persistent){let engine=null,name=null;persistent?(engine=window.FCHostPersistent,name=\"FCHostPersistent\"):(engine=window.FCHostSession,name=\"FCHostSession\"),Object.defineProperties(this,{_engine:{value:engine},name:{value:name},persistent:{value:!!persistent}})}get length(){return this._engine.size()}size(){return this._engine.size()}keys(){return this._engine.keys()}has(key){return!(\"string\"!=typeof key||!key)&&this._engine.has(key)}get(key){if(\"string\"!=typeof key||!key)return null;const value=this._engine.get(key);return null==value?null:_FCHostStorageAdapter._deserialize(value)}set(key,value){return!(\"string\"!=typeof key||!key)&&(this._engine.set(key,_FCHostStorageAdapter._serialize(value)),!0)}delete(key){return!(\"string\"!=typeof key||!key)&&(this._engine.remove(key),!0)}clear(){return this._engine.clear(),!0}static _serialize(obj){return Serial.stringify(obj)}static _deserialize(str){return Serial.parse(str)}}return Object.freeze(Object.defineProperties({},{init:{value:function(){return _ok=function(){try{if(void 0!==window.FCHostPersistent)return!0}catch(ex){}return!1}(),_ok}},create:{value:function(storageId,persistent){if(!_ok)throw new Error(\"adapter not initialized\");return new _FCHostStorageAdapter(persistent)}}}))})()),SimpleStore.adapters.push((()=>{let _ok=!1;class WebStorageAdapter{constructor(storageId,persistent){const prefix=`${storageId}.`;let engine=null,name=null;persistent?(engine=window.localStorage,name=\"localStorage\"):(engine=window.sessionStorage,name=\"sessionStorage\"),Object.defineProperties(this,{_engine:{value:engine},_prefix:{value:prefix},_prefixRe:{value:new RegExp(`^${RegExp.escape(prefix)}`)},name:{value:name},id:{value:storageId},persistent:{value:Boolean(persistent)}})}get size(){return this.keys().length}keys(){const keys=[];for(let i=0;i<this._engine.length;++i){const key=this._engine.key(i);this._prefixRe.test(key)&&keys.push(key.replace(this._prefixRe,\"\"))}return keys}has(key){return!(\"string\"!=typeof key||!key)&&Object.hasOwn(this._engine,this._prefix+key)}get(key){if(\"string\"!=typeof key||!key)return null;const value=this._engine.getItem(this._prefix+key);return null==value?null:WebStorageAdapter._deserialize(value)}set(key,value,compression=!0){if(\"string\"!=typeof key||!key)return!1;try{this._engine.setItem(this._prefix+key,WebStorageAdapter._serialize(value,this.persistent&&compression))}catch(ex){if(isQuotaDOMException(ex))throw exceptionFrom(ex,Error,{cause:{origin:ex},message:`${this.name} quota exceeded`});throw ex}return!0}delete(key){return!(\"string\"!=typeof key||!key)&&(this._engine.removeItem(this._prefix+key),!0)}clear(){const keys=this.keys();for(let i=0,length=keys.length;i<length;++i)this.delete(keys[i]);return!0}static _serialize(obj,compression){return compression?LZString.compressToUTF16(Serial.stringify(obj)):Serial.stringify(obj)}static _deserialize(str){return Serial.parse(str&&\"{\"!==str[0]?LZString.decompressFromUTF16(str):str)}}const isQuotaErrorRE=/quota.?(?:exceeded|reached)/i;function isQuotaDOMException(ex){return ex instanceof DOMException&&(22===ex.code||1014===ex.code||isQuotaErrorRE.test(ex.name)||isQuotaErrorRE.test(ex.message))}return Object.preventExtensions(Object.create(null,{init:{value:function(){function hasWebStorage(storeId){let store;try{store=window[storeId];const val=`_sc_${String(Date.now())}`;store.setItem(val,val);const result=store.getItem(val)===val;return store.removeItem(val),result}catch(ex){return store&&0!==store.length&&isQuotaDOMException(ex)}}return _ok=hasWebStorage(\"localStorage\")&&hasWebStorage(\"sessionStorage\"),_ok}},create:{value:function(storageId,persistent){if(!_ok)throw new Error(\"adapter not initialized\");return new WebStorageAdapter(storageId,persistent)}}}))})()),SimpleStore.adapters.push((()=>{const _MAX_EXPIRY=\"Tue, 19 Jan 2038 03:14:07 GMT\",_MIN_EXPIRY=\"Thu, 01 Jan 1970 00:00:00 GMT\";let _ok=!1;class CookieAdapter{constructor(storageId,persistent){const prefix=`${storageId}${persistent?\"!\":\"*\"}.`;Object.defineProperties(this,{_prefix:{value:prefix},_prefixRe:{value:new RegExp(`^${RegExp.escape(prefix)}`)},name:{value:\"cookie\"},id:{value:storageId},persistent:{value:Boolean(persistent)}})}get size(){return this.keys().length}keys(){if(\"\"===document.cookie)return[];const cookies=document.cookie.split(/;\\s*/),keys=[];for(let i=0;i<cookies.length;++i){const kvPair=cookies[i].split(\"=\"),key=decodeURIComponent(kvPair[0]);if(this._prefixRe.test(key)){\"\"!==decodeURIComponent(kvPair[1])&&keys.push(key.replace(this._prefixRe,\"\"))}}return keys}has(key){return!(\"string\"!=typeof key||!key)&&null!==CookieAdapter._getCookie(this._prefix+key)}get(key){if(\"string\"!=typeof key||!key)return null;const value=CookieAdapter._getCookie(this._prefix+key);return null===value?null:CookieAdapter._deserialize(value)}set(key,value){if(\"string\"!=typeof key||!key)return!1;try{if(CookieAdapter._setCookie(this._prefix+key,CookieAdapter._serialize(value),this.persistent?_MAX_EXPIRY:undefined),!this.has(key))throw new Error(\"unknown validation error during set\")}catch(ex){throw exceptionFrom(ex,Error,{cause:{origin:ex},message:`cookie error: ${ex.message}`})}return!0}delete(key){if(\"string\"!=typeof key||!key||!this.has(key))return!1;try{if(CookieAdapter._setCookie(this._prefix+key,undefined,_MIN_EXPIRY),this.has(key))throw new Error(\"unknown validation error during delete\")}catch(ex){throw exceptionFrom(ex,Error,{cause:{origin:ex},message:`cookie error: ${ex.message}`})}return!0}clear(){const keys=this.keys();for(let i=0,length=keys.length;i<length;++i)this.delete(keys[i]);return!0}static _getCookie(prefixedKey){if(!prefixedKey||\"\"===document.cookie)return null;const cookies=document.cookie.split(/;\\s*/);for(let i=0;i<cookies.length;++i){const kvPair=cookies[i].split(\"=\");if(prefixedKey===decodeURIComponent(kvPair[0])){return decodeURIComponent(kvPair[1])||null}}return null}static _setCookie(prefixedKey,value,expiry){if(!prefixedKey)return;let payload=`${encodeURIComponent(prefixedKey)}=`;null!=value&&(payload+=encodeURIComponent(value)),null!=expiry&&(payload+=`; expires=${expiry}`),payload+=\"; path=/\",document.cookie=payload}static _serialize(obj){return LZString.compressToBase64(Serial.stringify(obj))}static _deserialize(str){return Serial.parse(LZString.decompressFromBase64(str))}}return Object.preventExtensions(Object.create(null,{init:{value:function(storageId){try{const tid=`_sc_${String(Date.now())}`;CookieAdapter._setCookie(tid,CookieAdapter._serialize(tid),undefined),_ok=CookieAdapter._deserialize(CookieAdapter._getCookie(tid))===tid,CookieAdapter._setCookie(tid,undefined,_MIN_EXPIRY)}catch(ex){_ok=!1}return _ok&&function(storageId){if(\"\"===document.cookie)return;const oldPrefix=`${storageId}.`,oldPrefixRe=new RegExp(`^${RegExp.escape(oldPrefix)}`),persistPrefix=`${storageId}!.`,sessionPrefix=`${storageId}*.`,sessionTestRe=/\\.(?:state|rcWarn)$/,cookies=document.cookie.split(/;\\s*/);for(let i=0;i<cookies.length;++i){const kvPair=cookies[i].split(\"=\"),key=decodeURIComponent(kvPair[0]);if(oldPrefixRe.test(key)){const value=decodeURIComponent(kvPair[1]);if(\"\"!==value){const persist=!sessionTestRe.test(key);CookieAdapter._setCookie(key,undefined,_MIN_EXPIRY),CookieAdapter._setCookie(key.replace(oldPrefixRe,(()=>persist?persistPrefix:sessionPrefix)),value,persist?_MAX_EXPIRY:undefined)}}}}(storageId),_ok}},create:{value:function(storageId,persistent){if(!_ok)throw new Error(\"adapter not initialized\");return new CookieAdapter(storageId,persistent)}}}))})());var DebugView=(()=>{class DebugView{constructor(parent,type,name,title){Object.defineProperties(this,{parent:{value:parent},view:{value:document.createElement(\"span\")},break:{value:document.createElement(\"wbr\")}}),jQuery(this.view).attr({title:title,\"aria-label\":title,\"data-type\":null!=type?type:\"\",\"data-name\":null!=name?name:\"\"}).addClass(\"debug\"),jQuery(this.break).addClass(\"debug hidden\"),this.parent.appendChild(this.view),this.parent.appendChild(this.break)}get output(){return this.view}get type(){return this.view.getAttribute(\"data-type\")}set type(type){this.view.setAttribute(\"data-type\",null!=type?type:\"\")}get name(){return this.view.getAttribute(\"data-name\")}set name(name){this.view.setAttribute(\"data-name\",null!=name?name:\"\")}get title(){return this.view.title}set title(title){this.view.title=title}append(el){return jQuery(this.view).append(el),this}modes(options){if(null==options){const current={};return this.view.className.splitOrEmpty(/\\s+/).forEach((name=>{\"debug\"!==name&&(current[name]=!0)})),current}if(\"object\"==typeof options)return Object.keys(options).forEach((function(name){this[options[name]?\"addClass\":\"removeClass\"](name)}),jQuery(this.view)),this;throw new Error(\"DebugView.prototype.modes options parameter must be an object or null/undefined\")}remove(){const $view=jQuery(this.view);this.view.hasChildNodes()&&$view.contents().appendTo(this.parent),$view.remove(),jQuery(this.break).remove()}static isEnabled(){return\"enabled\"===jQuery(document.documentElement).attr(\"data-debug-view\")}static enable(){jQuery(document.documentElement).attr(\"data-debug-view\",\"enabled\"),triggerEvent(\":debugviewupdate\")}static disable(){jQuery(document.documentElement).removeAttr(\"data-debug-view\"),triggerEvent(\":debugviewupdate\")}static toggle(){DebugView.isEnabled()?DebugView.disable():DebugView.enable()}}return DebugView})(),NodeTyper=(()=>{class NodeTyper{constructor(config){if(\"object\"!=typeof config||null===config)throw new Error(`config parameter must be an object (received: ${getTypeOf(config)})`);if(!(Object.hasOwn(config,\"targetNode\")&&config.targetNode instanceof Node))throw new Error('config parameter object \"targetNode\" property must be a node');Object.defineProperties(this,{node:{value:config.targetNode},childNodes:{value:[]},nodeValue:{writable:!0,value:\"\"},appendTo:{writable:!0,value:config.parentNode||null},classNames:{writable:!0,value:config.classNames||null},finished:{writable:!0,value:!1}});const node=this.node;let childNode;for(node.nodeValue&&(this.nodeValue=node.nodeValue,node.nodeValue=\"\");null!==(childNode=node.firstChild);)this.childNodes.push(new NodeTyper({targetNode:childNode,parentNode:node,classNames:this.classNames})),node.removeChild(childNode)}finish(){for(;this.type(!0););return!1}type(flush){if(this.finished)return!1;if(this.appendTo){if(this.appendTo.appendChild(this.node),this.appendTo=null,this.node.nodeType!==Node.ELEMENT_NODE&&this.node.nodeType!==Node.TEXT_NODE||\"none\"===jQuery(this.node.parentNode).css(\"display\"))return this.finish();this.node.parentNode&&this.classNames&&jQuery(this.node.parentNode).addClass(this.classNames)}if(this.nodeValue){if(flush)this.node.nodeValue+=this.nodeValue,this.nodeValue=\"\";else{const{char:char,start:start,end:end}=charAndPosAt(this.nodeValue,0);this.node.nodeValue+=char,this.nodeValue=this.nodeValue.slice(1+end-start)}return!0}this.classNames&&(jQuery(this.node.parentNode).removeClass(this.classNames),this.classNames=null);const childNodes=this.childNodes;for(;childNodes.length>0;){if(childNodes[0].type())return!0;childNodes.shift()}return this.finished=!0,!1}}return NodeTyper})(),StyleWrapper=(()=>{const _imageMarkupRe=new RegExp(Patterns.cssImage,\"g\"),_hasImageMarkupRe=new RegExp(Patterns.cssImage);return class{constructor(style){if(null==style)throw new TypeError(\"StyleWrapper style parameter must be an HTMLStyleElement object\");Object.defineProperties(this,{style:{value:style}})}isEmpty(){return 0===this.style.cssRules.length}set(rawCss){this.clear(),this.add(rawCss)}add(rawCss){let css=rawCss;_hasImageMarkupRe.test(css)&&(_imageMarkupRe.lastIndex=0,css=css.replace(_imageMarkupRe,(wikiImage=>{const markup=Wikifier.helpers.parseSquareBracketedMarkup({source:wikiImage,matchStart:0});if(Object.hasOwn(markup,\"error\")||markup.pos<wikiImage.length)return wikiImage;let source=markup.source;if(\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);passage.tags.includes(\"Twine.image\")&&(source=passage.text.trim())}return`url(\"${source.replace(/\"/g,\"%22\")}\")`}))),this.style.styleSheet?this.style.styleSheet.cssText+=css:this.style.appendChild(document.createTextNode(css))}clear(){this.style.styleSheet?this.style.styleSheet.cssText=\"\":jQuery(this.style).empty()}}})(),Diff=(()=>{const Op=enumFrom({Delete:0,SpliceArray:1,Copy:2,CopyDate:3});function isNumeric(O){let num;switch(typeof O){case\"number\":num=O;break;case\"string\":num=Number(O);break;default:return!1}return!Number.isNaN(num)&&Number.isFinite(num)}return Object.preventExtensions(Object.create(null,{Op:{value:Op},diff:{value:function diff(a,b){const toString=Object.prototype.toString,aIsArray=a instanceof Array,delta=Object.create(null),keys=[...Object.keys(a),...Object.keys(b)].sort().filter(((val,i,arr)=>0===i||arr[i-1]!==val));let aOpKey;const isAOpKey=key=>key===aOpKey;for(let i=0,klen=keys.length;i<klen;++i){const key=keys[i],aVal=a[key],bVal=b[key];if(Object.hasOwn(a,key))if(Object.hasOwn(b,key)){if(aVal===bVal)continue;if(typeof aVal==typeof bVal)if(\"function\"==typeof aVal)aVal.toString()!==bVal.toString()&&(delta[key]=[Op.Copy,bVal]);else if(\"object\"!=typeof aVal||null===aVal)delta[key]=[Op.Copy,bVal];else{const aValType=toString.call(aVal);if(aValType===toString.call(bVal))if(aVal instanceof Date)aVal.getTime()!==bVal.getTime()&&(delta[key]=[Op.Copy,clone(bVal)]);else if(aVal instanceof Map)delta[key]=[Op.Copy,clone(bVal)];else if(aVal instanceof RegExp)aVal.toString()!==bVal.toString()&&(delta[key]=[Op.Copy,clone(bVal)]);else if(aVal instanceof Set)delta[key]=[Op.Copy,clone(bVal)];else if(aVal instanceof Array||\"[object Object]\"===aValType){const subDelta=diff(aVal,bVal);null!==subDelta&&(delta[key]=subDelta)}else delta[key]=[Op.Copy,clone(bVal)];else delta[key]=[Op.Copy,clone(bVal)]}else delta[key]=[Op.Copy,\"object\"!=typeof bVal||null===bVal?bVal:clone(bVal)]}else if(aIsArray&&isNumeric(key)){const index=Number(key);if(!aOpKey){aOpKey=\"\";do{aOpKey+=\"~\"}while(keys.some(isAOpKey));delta[aOpKey]=[Op.SpliceArray,index,index]}index<delta[aOpKey][1]&&(delta[aOpKey][1]=index),index>delta[aOpKey][2]&&(delta[aOpKey][2]=index)}else delta[key]=Op.Delete;else delta[key]=[Op.Copy,\"object\"!=typeof bVal||null===bVal?bVal:clone(bVal)]}return Object.keys(delta).length>0?delta:null}},patch:{value:function patch(orig,delta){const keys=delta?Object.keys(delta):[],patched=clone(orig);for(let i=0,klen=keys.length;i<klen;++i){const key=keys[i],value=delta[key];if(value===Op.Delete)delete patched[key];else if(value instanceof Array)switch(value[0]){case Op.SpliceArray:patched.splice(value[1],value[2]-value[1]+1);break;case Op.Copy:patched[key]=clone(value[1]);break;case Op.CopyDate:patched[key]=new Date(value[1])}else patched[key]=patch(patched[key],value)}return patched}}}))})(),L10n=(()=>{const replaceRE=/\\{\\w+\\}/g,hasReplaceRE=new RegExp(replaceRE.source);return Object.preventExtensions(Object.create(null,{init:{value:function(){}},get:{value:function(ids,overrides){if(!ids)return\"\";const id=(Array.isArray(ids)?ids:[ids]).find((id=>Object.hasOwn(l10nStrings,id)));if(!id)return\"\";let value=l10nStrings[id],i=0;for(;hasReplaceRE.test(value);){if(++i>50)throw new Error(\"L10n.get exceeded maximum replacement depth, probable infinite loop\");replaceRE.lastIndex=0,value=value.replace(replaceRE,(replacement=>{const rid=replacement.slice(1,-1);return overrides&&Object.hasOwn(overrides,rid)?overrides[rid]:Object.hasOwn(l10nStrings,rid)?l10nStrings[rid]:void 0}))}return value}}}))})(),l10nStrings={textAbort:\"Abort\",textAborting:\"Aborting\",textCancel:\"Cancel\",textClear:\"Clear\",textClose:\"Close\",textDelete:\"Delete\",textExport:\"Export\",textIdentity:\"game\",textImport:\"Import\",textLoad:\"Load\",textOff:\"Off\",textOk:\"OK\",textOn:\"On\",textSave:\"Save\",textTurn:\"Turn\",savesEnableIdb:\"Enable indexedDB\",savesDisallowedReplay:\"The scene viewer is currently in use, preventing the use of the save system.\",savesExportReminder:\"Warning: If your browser cache is cleared, saves here will be lost! Consider saving to file every so often!\",savesHeaderSaveLoad:\"Save/Load\",savesHeaderIDName:\"ID/Name\",savesHeaderDetails:\"Details\",savesDescTitle:\"Title:\",savesDescName:\"Save Name:\",savesDescId:\"Save Id:\",savesDescDate:\"Date:\",savesPagerJump:\"Jump to most recent manual save\",savesPagerPage:\"Page:\",savesPagerSavesPerPage:\"Saves per page:\",savesOptionsConfirmOn:\"Require confirmation on:\",savesOptionsOverwrite:\"Overwrite\",savesOptionsUseLegacy:\"Switch to legacy save storage\",savesWarningSaveOnSlot:\"Save on slot\",savesWarningOverwriteSlot:\"Overwrite save in slot\",savesWarningOverwriteID:\"Save ID does not match, continue with overwrite?\",savesWarningDeleteInSlot:\"Delete save in slot\",savesWarningLoad:\"Load slot\",savesWarningDeleteAll:\"WARNING - DO YOU REALLY WANT TO DELETE ALL SAVES?\",errorNonexistentPassage:'the passage \"{passage}\" does not exist',warningNoStorage:\"All usable storage APIs are missing. Possible causes are a disabled third-party cookie setting, which also affects Web Storage, or a private browsing mode.\",warningNoWebStorage:\"The Web Storage API is missing, so this {textIdentity} is running in a degraded mode. You may be able to continue, however, some parts may not work properly.\",warningDegraded:\"Some capabilities required to support this {textIdentity} are missing, so it is running in a degraded mode. You may be able to continue, however, some parts may not work properly.\",warningNoSaves:\"Some capabilities required to support saves are missing, so saves have been disabled for this session.\",saveErrorDisallowed:\"Saving is currently disallowed.\",saveErrorDecodeFail:\"unable to decode save, likely due to corruption\",saveErrorDiskLoadFail:\"failed to load save file from disk\",saveErrorIdMismatch:\"save is from the wrong {textIdentity}\",saveErrorInvalidData:\"save is missing required data, likely due to corruption\",saveErrorLoadTooEarly:\"cannot load save this early\",saveErrorNonexistent:\"save does not exist\",uiBarLabelToggle:\"Toggle the UI bar\",uiBarLabelBackward:\"Go backward within the {textIdentity} history\",uiBarLabelForward:\"Go forward within the {textIdentity} history\",uiBarLabelJumpto:\"Jump to a specific point within the {textIdentity} history\",alertTitle:\"Alert\",restartTitle:\"Restart\",restartMesgPrompt:\"All unsaved progress will be lost. Are you sure that you want to restart?\",continueTitle:\"Continue\",savesTitle:\"Saves\",savesHeaderBrowser:\"In Browser\",savesHeaderDisk:\"On Disk\",savesLabelBrowserClear:\"Clear all browser saves\",savesLabelBrowserExport:\"Export browser saves to bundle\",savesLabelBrowserImport:\"Import browser saves from bundle\",savesLabelDiskLoad:\"Load from disk\",savesLabelDiskSave:\"Save to disk\",savesLabelToClipboard:\"Save to Clipboard\",savesTextBrowserAuto:\"Auto\",savesTextBrowserSlot:\"Slot\",savesTextNoDate:\"unknown date\",settingsTitle:\"Settings\",settingsTextReset:\"Reset to Defaults\",errorViewTitle:\"Error\",errorViewLabelToggle:\"Toggle the error view\",debugBarLabelToggle:\"Toggle the debug bar\",debugBarLabelViewsToggle:\"Toggle the debug views\",debugBarLabelWatchAdd:\"Add a new watch\",debugBarLabelWatchAll:\"Watch all\",debugBarLabelWatchClear:\"Clear all watches\",debugBarLabelWatchDelete:\"Delete this watch\",debugBarLabelWatchPlaceholder:\"variable name\",debugBarLabelPassagePlaceholder:\"passage name\",debugBarLabelPassagePlay:\"Play passage\",debugBarLabelWatchToggle:\"Toggle the watch panel\",debugBarMesgNoWatches:\"No watches set\",debugBarTextAdd:\"Add\",debugBarTextPassage:\"Passage\",debugBarTextViews:\"Views\",debugBarTextWatch:\"Watch\",macroBackText:\"Back\",macroReturnText:\"Return\",autoloadTitle:\"Autoload\",autoloadMesgPrompt:\"An autosave exists. Load it now or go to the start?\",autoloadTextCancel:\"Go to start\",autoloadTextOk:\"Load autosave\",jumptoTitle:\"Jump To\",jumptoMesgUnavailable:\"No jump points currently available…\",shareTitle:\"Share\"},Config=(()=>{let _navigationOverride,_passagesStart,_passagesOnProcess,_passagesTransitionOut,_savesDescriptions,_savesId,_savesIsAllowed,_savesMetadata,_savesVersion,_savesAutoload,_addVisitedLinkClass=!1,_cleanupWikifierOutput=!1,_debug=!1,_enableOptionalDebugging=!1,_loadDelay=0,_audioPauseOnFadeToZero=!0,_audioPreloadMetadata=!0,_historyControls=!0,_historyMaxStates=40,_macrosMaxLoopIterations=1e3,_macrosTypeSkipKey=\" \",_macrosTypeVisitedPassages=!0,_passagesDisplayTitles=!1,_passagesNobr=!1,_savesMaxAuto=0,_savesMaxSlot=8,_uiStowBarInitially=800,_uiUpdateStoryElements=!0;const errPassagesDescriptionsDeprecated=\"[DEPRECATED] Config.passages.descriptions has been deprecated, see Config.saves.descriptions instead\",errSavesAutoloadDeprecated=\"[DEPRECATED] Config.saves.autoload has been deprecated, see the Save.browser.continue API instead\",_baseSavesAutosaveDeprecated=\"[DEPRECATED] Config.saves.autosave has been deprecated\",errSavesOnLoadDeprecated=\"[DEPRECATED] Config.saves.onLoad has been deprecated, see the Save.onLoad API instead\",errSavesOnSaveDeprecated=\"[DEPRECATED] Config.saves.onSave has been deprecated, see the Save.onSave API instead\",errSavesSlotsDeprecated=\"[DEPRECATED] Config.saves.slots has been deprecated, see Config.saves.maxSlotSaves instead\";return Object.freeze({get addVisitedLinkClass(){return _addVisitedLinkClass},set addVisitedLinkClass(value){_addVisitedLinkClass=Boolean(value)},get cleanupWikifierOutput(){return _cleanupWikifierOutput},set cleanupWikifierOutput(value){_cleanupWikifierOutput=Boolean(value)},get debug(){return _debug},set debug(value){_debug=Boolean(value)},get enableOptionalDebugging(){return _enableOptionalDebugging},set enableOptionalDebugging(value){_enableOptionalDebugging=Boolean(value)},get loadDelay(){return _loadDelay},set loadDelay(value){if(!Number.isSafeInteger(value)||value<0)throw new RangeError(\"Config.loadDelay must be a non-negative integer\");_loadDelay=value},audio:Object.freeze({get pauseOnFadeToZero(){return _audioPauseOnFadeToZero},set pauseOnFadeToZero(value){_audioPauseOnFadeToZero=Boolean(value)},get preloadMetadata(){return _audioPreloadMetadata},set preloadMetadata(value){_audioPreloadMetadata=Boolean(value)}}),history:Object.freeze({get controls(){return _historyControls},set controls(value){const controls=Boolean(value);if(1===_historyMaxStates&&controls)throw new Error(\"Config.history.controls must be false when Config.history.maxStates is 1\");_historyControls=controls},get maxStates(){return _historyMaxStates},set maxStates(value){if(!Number.isSafeInteger(value)||value<1)throw new RangeError(\"Config.history.maxStates must be a positive integer\");_historyMaxStates=value,_historyControls&&1===value&&(_historyControls=!1)}}),macros:Object.freeze({get maxLoopIterations(){return _macrosMaxLoopIterations},set maxLoopIterations(value){if(!Number.isSafeInteger(value)||value<1)throw new RangeError(\"Config.macros.maxLoopIterations must be a positive integer\");_macrosMaxLoopIterations=value},get typeSkipKey(){return _macrosTypeSkipKey},set typeSkipKey(value){_macrosTypeSkipKey=String(value)},get typeVisitedPassages(){return _macrosTypeVisitedPassages},set typeVisitedPassages(value){_macrosTypeVisitedPassages=Boolean(value)},get ifAssignmentError(){throw new Error(\"[DEPRECATED] Config.macros.ifAssignmentError has been deprecated, see Config.enableOptionalDebugging instead\")},set ifAssignmentError(value){console.warn(\"[DEPRECATED] Config.macros.ifAssignmentError has been deprecated, see Config.enableOptionalDebugging instead\"),Config.enableOptionalDebugging=value}}),navigation:Object.freeze({get override(){return _navigationOverride},set override(value){if(!(null==value||value instanceof Function))throw new TypeError(`Config.navigation.override must be a function or null/undefined (received: ${getTypeOf(value)})`);_navigationOverride=value}}),passages:Object.freeze({get displayTitles(){return _passagesDisplayTitles},set displayTitles(value){_passagesDisplayTitles=Boolean(value)},get nobr(){return _passagesNobr},set nobr(value){_passagesNobr=Boolean(value)},get onProcess(){return _passagesOnProcess},set onProcess(value){if(null!=value){const valueType=getTypeOf(value);if(\"function\"!==valueType)throw new TypeError(`Config.passages.onProcess must be a function or null/undefined (received: ${valueType})`)}_passagesOnProcess=value},get start(){return _passagesStart},set start(value){if(null!=value){const valueType=getTypeOf(value);if(\"string\"!==valueType)throw new TypeError(`Config.passages.start must be a string or null/undefined (received: ${valueType})`)}_passagesStart=value},get transitionOut(){return _passagesTransitionOut},set transitionOut(value){if(null!=value){const valueType=getTypeOf(value);if(\"string\"!==valueType&&(\"number\"!==valueType||!Number.isSafeInteger(value)||value<0))throw new TypeError(`Config.passages.transitionOut must be a string, non-negative integer, or null/undefined (received: ${valueType})`)}_passagesTransitionOut=value},get descriptions(){throw new Error(errPassagesDescriptionsDeprecated)},set descriptions(value){switch(console.warn(errPassagesDescriptionsDeprecated),typeof value){case\"boolean\":value&&!Config.saves.descriptions&&(Config.saves.descriptions=function(){return State.passage});break;case\"function\":Config.saves.descriptions||(Config.saves.descriptions=value);break;case\"undefined\":case\"object\":if(value&&!Config.saves.descriptions){const dict=value;Config.saves.descriptions=function(){return Object.hasOwn(dict,State.passage)&&dict[State.passage]}}break;default:throw new TypeError(`Config.passages.descriptions must be a boolean, object, function, or null/undefined (received: ${getTypeOf(value)})`)}}}),saves:Object.freeze({get descriptions(){return _savesDescriptions},set descriptions(value){if(!(null==value||value instanceof Function))throw new TypeError(`Config.saves.descriptions must be a function or null/undefined (received: ${getTypeOf(value)})`);_savesDescriptions=value},get id(){return _savesId},set id(value){if(\"string\"!=typeof value||\"\"===value)throw new TypeError(`Config.saves.id must be a non-empty string (received: ${getTypeOf(value)})`);_savesId=value},get isAllowed(){return _savesIsAllowed},set isAllowed(value){if(!(null==value||value instanceof Function))throw new TypeError(`Config.saves.isAllowed must be a function or null/undefined (received: ${getTypeOf(value)})`);_savesIsAllowed=value},get maxAutoSaves(){return _savesMaxAuto},set maxAutoSaves(value){if(!Number.isInteger(value))throw new TypeError(\"Config.saves.maxAutoSaves must be an integer\");if(value<0||value>Save.MAX_INDEX+1)throw new RangeError(`Config.saves.maxAutoSaves out of bounds (range: 0–${Save.MAX_INDEX+1}; received: ${value})`);_savesMaxAuto=value},get maxSlotSaves(){return _savesMaxSlot},set maxSlotSaves(value){if(!Number.isInteger(value))throw new TypeError(\"Config.saves.maxSlotSaves must be an integer\");if(value<0||value>Save.MAX_INDEX+1)throw new RangeError(`Config.saves.maxSlotSaves out of bounds (range: 0–${Save.MAX_INDEX+1}; received: ${value})`);_savesMaxSlot=value},get metadata(){return _savesMetadata},set metadata(value){if(!(null==value||value instanceof Function))throw new TypeError(`Config.saves.metadata must be a function or null/undefined (received: ${getTypeOf(value)})`);_savesMetadata=value},get version(){return _savesVersion},set version(value){_savesVersion=value},get _internal_autoload_(){return _savesAutoload},get autoload(){return console.warn(errSavesAutoloadDeprecated),_savesAutoload},set autoload(value){if(console.warn(errSavesAutoloadDeprecated),null!=value){const valueType=getTypeOf(value);if(\"boolean\"!==valueType&&(\"string\"!==valueType||\"prompt\"!==value)&&\"function\"!==valueType)throw new TypeError(`Config.saves.autoload must be a boolean, string ('prompt'), function, or null/undefined (received: ${valueType})`)}_savesAutoload=value},get autosave(){throw new Error(`${_baseSavesAutosaveDeprecated}, see Config.saves.maxAutoSaves and Config.saves.isAllowed instead`)},set autosave(value){switch(typeof value){case\"boolean\":console.warn(`${_baseSavesAutosaveDeprecated}, for boolean usage see Config.saves.maxAutoSaves instead`);break;case\"function\":if(console.warn(`${_baseSavesAutosaveDeprecated}, for function usage see Config.saves.isAllowed instead`),!Config.saves.isAllowed){const callback=value;Config.saves.isAllowed=function(saveType){return saveType!==Save.Type.Auto||callback(saveType)}}break;default:if(console.warn(`${_baseSavesAutosaveDeprecated}, for tag usage see Config.saves.isAllowed instead`),!(value instanceof Array)||0===value.length||value.some((tag=>\"string\"!=typeof tag))){const valueType=getTypeOf(value);throw new TypeError(`Config.saves.autosave must be a boolean, Array<string>, function, or null/undefined (received: ${valueType}${\"Array\"===valueType?\"<any>\":\"\"})`)}if(!Config.saves.isAllowed){const userTags=value;Config.saves.isAllowed=function(saveType){return saveType!==Save.Type.Auto||userTags.includesAny(Story.get(State.passage).tags)}}}0===Config.saves.maxAutoSaves&&(Config.saves.maxAutoSaves=1)},get onLoad(){throw new Error(errSavesOnLoadDeprecated)},set onLoad(value){console.warn(errSavesOnLoadDeprecated),Save.onLoad.add(value)},get onSave(){throw new Error(errSavesOnSaveDeprecated)},set onSave(value){console.warn(errSavesOnSaveDeprecated),Save.onSave.add(value)},get slots(){throw new Error(errSavesSlotsDeprecated)},set slots(value){console.warn(errSavesSlotsDeprecated),Config.saves.maxSlotSaves=value},get tryDiskOnMobile(){return console.warn(\"[DEPRECATED] Config.saves.tryDiskOnMobile has been deprecated\"),!0},set tryDiskOnMobile(value){console.warn(\"[DEPRECATED] Config.saves.tryDiskOnMobile has been deprecated\")}}),ui:Object.freeze({get stowBarInitially(){return _uiStowBarInitially},set stowBarInitially(value){const valueType=getTypeOf(value);if(\"boolean\"!==valueType&&(\"number\"!==valueType||!Number.isSafeInteger(value)||value<0))throw new TypeError(`Config.ui.stowBarInitially must be a boolean or non-negative integer (received: ${valueType})`);_uiStowBarInitially=value},get updateStoryElements(){return _uiUpdateStoryElements},set updateStoryElements(value){_uiUpdateStoryElements=Boolean(value)}})})})(),SimpleAudio=(()=>{const _specialIds=Object.freeze([\":not\",\":all\",\":looped\",\":muted\",\":paused\",\":playing\",\":stopped\"]),_formatSpecRe=/^([\\w-]+)\\s*\\|\\s*(\\S.*)$/,_badIdRe=/[:\\s]/,_tracks=new Map,_groups=new Map,_lists=new Map,_subscribers=new Map;let _masterRate=1,_masterVolume=1,_masterMute=!1,_masterMuteOnHidden=!1;const _playReturnsPromise=function(){let _hasPromise=null;return function(){if(null!==_hasPromise)return _hasPromise;if(_hasPromise=!1,Has.audio)try{const audio=document.createElement(\"audio\");audio.muted=!0;const value=audio.play();value.catch((()=>{})),_hasPromise=value instanceof Promise}catch(ex){}return _hasPromise}}();class AudioTrack{constructor(obj){if(obj instanceof Array)this._create(obj);else{if(!(obj instanceof AudioTrack))throw new Error(\"sources parameter must be either an array, of URIs or source objects, or an AudioTrack instance\");this._copy(obj)}}_create(sourceList){const dataUriRe=/^data:\\s*audio\\/(?:x-)?([^;,]+)\\s*[;,]/i,extRe=/\\.([^./\\\\]+)$/,formats=AudioTrack.formats,usedSources=[],audio=document.createElement(\"audio\");audio.preload=\"none\",sourceList.forEach((src=>{let srcUri=null;switch(typeof src){case\"string\":{let match;if(\"data:\"===src.slice(0,5)){if(match=dataUriRe.exec(src),null===match)throw new Error(\"source data URI missing media type\")}else if(match=extRe.exec(parseURL(src).pathname),null===match)throw new Error(\"source URL missing file extension\");formats[match[1]]&&(srcUri=src);break}case\"object\":if(null===src)throw new Error(\"source object cannot be null\");if(!Object.hasOwn(src,\"src\"))throw new Error('source object missing required \"src\" property');if(!Object.hasOwn(src,\"format\"))throw new Error('source object missing required \"format\" property');formats[src.format]&&(srcUri=src.src);break;default:throw new Error(`invalid source value (type: ${typeof src})`)}if(null!==srcUri){const source=document.createElement(\"source\");source.src=srcUri,audio.appendChild(source),usedSources.push(srcUri)}})),audio.hasChildNodes()&&Config.audio.preloadMetadata&&(audio.preload=\"metadata\"),this._finalize(audio,usedSources,clone(sourceList))}_copy(obj){this._finalize(obj.audio.cloneNode(!0),clone(obj.sources),clone(obj.originals))}_finalize(audio,sources,originals){Object.defineProperties(this,{audio:{configurable:!0,value:audio},sources:{value:Object.freeze(sources)},originals:{value:Object.freeze(originals)},_error:{writable:!0,value:!1},_faderId:{writable:!0,value:null},_mute:{writable:!0,value:!1},_rate:{writable:!0,value:1},_volume:{writable:!0,value:1}}),jQuery(this.audio).on(\"loadstart.AudioTrack\",(()=>this._error=!1)).on(\"error.AudioTrack\",(()=>this._error=!0)).find(\"source:last-of-type\").on(\"error.AudioTrack\",(()=>this._trigger(\"error\"))),function(id,callback){if(\"function\"!=typeof callback)throw new Error(\"callback parameter must be a function\");_subscribers.set(id,callback)}(this,(mesg=>{if(this.audio)switch(mesg){case\"loadwithscreen\":if(this.hasSource()){const lockId=LoadScreen.lock();this.off(\".AudioTrack_loadwithscreen\").one(\"canplaythrough.AudioTrack_loadwithscreen error.AudioTrack_loadwithscreen\",(function(){jQuery(this).off(\".AudioTrack_loadwithscreen\"),LoadScreen.unlock(lockId)})).load()}break;case\"load\":this.load();break;case\"mute\":this._updateAudioMute();break;case\"rate\":this._updateAudioRate();break;case\"stop\":this.stop();break;case\"volume\":this._updateAudioVolume();break;case\"unload\":this.unload()}else unsubscribe(this)})),this._updateAudioMute(),this._updateAudioRate(),this._updateAudioVolume()}_trigger(eventName){triggerEvent(eventName,this.audio,{bubbles:!1})}_destroy(){unsubscribe(this),this.audio&&(jQuery(this.audio).off(),this.unload(),this._error=!0,delete this.audio)}clone(){return new AudioTrack(this)}load(){if(this.fadeStop(),this.audio.pause(),!this.audio.hasChildNodes()){if(0===this.sources.length)return;this.sources.forEach((srcUri=>{const source=document.createElement(\"source\");source.src=srcUri,this.audio.appendChild(source)}))}\"auto\"!==this.audio.preload&&(this.audio.preload=\"auto\"),this.isLoading()||this.audio.load()}unload(){this.fadeStop(),this.stop();const audio=this.audio;for(audio.preload=\"none\";audio.hasChildNodes();)audio.removeChild(audio.firstChild);audio.load()}play(){if(!this.hasSource())return Promise.reject(new Error(\"none of the candidate sources were acceptable\"));if(this.isUnloaded())return Promise.reject(new Error(\"no sources are loaded\"));if(this.isFailed())return Promise.reject(new Error(\"failed to load any of the sources\"));\"auto\"!==this.audio.preload&&(this.audio.preload=\"auto\");const namespace=\".AudioTrack_play\";return _playReturnsPromise()?this.audio.play():new Promise(((resolve,reject)=>{this.isPlaying()?resolve():(jQuery(this.audio).off(namespace).one(`error${namespace} playing${namespace} timeupdate${namespace}`,(ev=>{jQuery(this.audio).off(namespace),\"error\"===ev.type?reject(new Error(\"unknown audio play error\")):resolve()})),this.audio.play())}))}playWhenAllowed(){return this.play().catch((ex=>{if(\"NotAllowedError\"!==ex.name)throw ex;onUserActivation(\".AudioTrack_playWhenAllowed\",(()=>this.audio.play()))}))}pause(){this.audio.pause()}stop(){this.audio.pause(),this.time(0),this._trigger(\":stopped\")}fade(duration,toVol,fromVol){if(\"number\"!=typeof duration)throw new TypeError(\"duration parameter must be a number\");if(\"number\"!=typeof toVol)throw new TypeError(\"toVolume parameter must be a number\");if(null!=fromVol&&\"number\"!=typeof fromVol)throw new TypeError(\"fromVolume parameter must be a number\");if(!this.hasSource())return Promise.reject(new Error(\"none of the candidate sources were acceptable\"));if(this.isUnloaded())return Promise.reject(new Error(\"no sources are loaded\"));if(this.isFailed())return Promise.reject(new Error(\"failed to load any of the sources\"));this.fadeStop();const from=Math.clamp(null==fromVol?this.volume():fromVol,0,1),to=Math.clamp(toVol,0,1);return from!==to?(this.volume(from),jQuery(this.audio).off(\"timeupdate.AudioTrack_fade\").one(\"timeupdate.AudioTrack_fade\",(()=>{let min,max;from<to?(min=from,max=to):(min=to,max=from);const time=Math.max(duration,1),delta=(to-from)/(time/.025);this._trigger(\":fading\"),this._faderId=setInterval((()=>{this.isPlaying()?(this.volume(Math.clamp(this.volume()+delta,min,max)),Config.audio.pauseOnFadeToZero&&0===this.volume()&&this.pause(),this.volume()===to&&(this.fadeStop(),this._trigger(\":faded\"))):this.fadeStop()}),25)})),this.play()):void 0}fadeIn(duration,fromVol){return this.fade(duration,1,fromVol)}fadeOut(duration,fromVol){return this.fade(duration,0,fromVol)}fadeStop(){null!==this._faderId&&(clearInterval(this._faderId),this._faderId=null)}loop(loop){return null==loop?this.audio.loop:(this.audio.loop=!!loop,this)}mute(mute){return null==mute?this._mute:(this._mute=!!mute,this._updateAudioMute(),this)}_updateAudioMute(){this.audio.muted=this._mute||_masterMute}rate(rate){if(null==rate)return this._rate;if(\"number\"!=typeof rate)throw new TypeError(\"rate parameter must be a number\");return this._rate=Math.clamp(rate,.2,5),this._updateAudioRate(),this}_updateAudioRate(){this.audio.playbackRate=Math.clamp(this._rate*_masterRate,.2,5)}time(time){if(null==time)return this.audio.currentTime;if(\"number\"!=typeof time)throw new TypeError(\"time parameter must be a number\");return this.hasMetadata()?this.audio.currentTime=time:jQuery(this.audio).off(\"loadedmetadata.AudioTrack_time\").one(\"loadedmetadata.AudioTrack_time\",(()=>this.audio.currentTime=time)),this}volume(volume){if(null==volume)return this._volume;if(\"number\"!=typeof volume)throw new TypeError(\"volume parameter must be a number\");return this._volume=Math.clamp(volume,0,1),this._updateAudioVolume(),this}_updateAudioVolume(){this.audio.volume=Math.clamp(this._volume*_masterVolume,0,1)}duration(){return this.audio.duration}remaining(){return this.audio.duration-this.audio.currentTime}isFailed(){return this._error}isLoading(){return this.audio.networkState===HTMLMediaElement.NETWORK_LOADING}isUnloaded(){return!this.audio.hasChildNodes()}isUnavailable(){return!this.hasSource()||this.isUnloaded()||this.isFailed()}isPlaying(){return!this.audio.paused&&this.hasSomeData()}isPaused(){return this.audio.paused&&(this.audio.duration===1/0||this.audio.currentTime>0)&&!this.audio.ended}isStopped(){return this.audio.paused&&0===this.audio.currentTime}isEnded(){return this.audio.ended}isFading(){return null!==this._faderId}isSeeking(){return this.audio.seeking}hasSource(){return this.sources.length>0}hasNoData(){return this.audio.readyState===HTMLMediaElement.HAVE_NOTHING}hasMetadata(){return this.audio.readyState>=HTMLMediaElement.HAVE_METADATA}hasSomeData(){return this.audio.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA}hasData(){return this.audio.readyState===HTMLMediaElement.HAVE_ENOUGH_DATA}on(...args){return jQuery.fn.on.apply(jQuery(this.audio),args),this}one(...args){return jQuery.fn.one.apply(jQuery(this.audio),args),this}off(...args){return jQuery.fn.off.apply(jQuery(this.audio),args),this}}Object.defineProperties(AudioTrack,{formats:{value:(()=>{const audio=document.createElement(\"audio\"),types=new Map;function canPlay(mimeType){return types.has(mimeType)||types.set(mimeType,\"\"!==audio.canPlayType(mimeType).replace(/^no$/i,\"\")),types.get(mimeType)}return Object.assign(Object.create(null),{aac:canPlay(\"audio/aac\"),caf:canPlay(\"audio/x-caf\")||canPlay(\"audio/caf\"),flac:canPlay(\"audio/x-flac\")||canPlay(\"audio/flac\"),mp3:canPlay('audio/mpeg; codecs=\"mp3\"')||canPlay(\"audio/mpeg\")||canPlay(\"audio/mp3\")||canPlay(\"audio/mpa\"),mpeg:canPlay(\"audio/mpeg\"),m4a:canPlay(\"audio/x-m4a\")||canPlay(\"audio/m4a\")||canPlay(\"audio/aac\"),mp4:canPlay(\"audio/x-mp4\")||canPlay(\"audio/mp4\")||canPlay(\"audio/aac\"),ogg:canPlay(\"audio/ogg\"),oga:canPlay(\"audio/ogg\"),opus:canPlay('audio/ogg; codecs=\"opus\"')||canPlay(\"audio/opus\"),wav:canPlay('audio/wave; codecs=\"1\"')||canPlay('audio/wav; codecs=\"1\"')||canPlay(\"audio/wave\")||canPlay(\"audio/wav\"),wave:canPlay('audio/wave; codecs=\"1\"')||canPlay('audio/wav; codecs=\"1\"')||canPlay(\"audio/wave\")||canPlay(\"audio/wav\"),weba:canPlay(\"audio/webm\"),webm:canPlay(\"audio/webm\")})})()}});class AudioList{constructor(obj){if(obj instanceof Array)this._create(obj);else{if(!(obj instanceof AudioList))throw new Error(\"tracks parameter must be either an array, of track objects, or an AudioTrack instance\");this._copy(obj)}}_create(trackList){this._finalize(trackList.map((trackObj=>{if(\"object\"!=typeof trackObj)throw new Error(\"tracks parameter array members must be objects\");let own,rate,track,volume;if(trackObj instanceof AudioTrack)own=!0,rate=trackObj.rate(),track=trackObj.clone(),volume=trackObj.volume();else{if(!Object.hasOwn(trackObj,\"track\"))throw new Error('track object missing required \"track\" property');if(!(trackObj.track instanceof AudioTrack))throw new Error('track object\\'s \"track\" property must be an AudioTrack object');own=Object.hasOwn(trackObj,\"own\")&&trackObj.own,rate=Object.hasOwn(trackObj,\"rate\")?trackObj.rate:trackObj.track.rate(),track=trackObj.track,volume=Object.hasOwn(trackObj,\"volume\")?trackObj.volume:trackObj.track.volume()}return track.stop(),track.loop(!1),track.mute(!1),track.rate(rate),track.volume(volume),track.on(\"ended.AudioList\",(()=>this._onEnd())),{own:own,track:track,volume:volume,rate:rate}})))}_copy(obj){this._finalize(clone(obj.tracks))}_finalize(tracks){Object.defineProperties(this,{tracks:{configurable:!0,value:Object.freeze(tracks)},queue:{configurable:!0,value:[]},current:{writable:!0,value:null},_rate:{writable:!0,value:1},_volume:{writable:!0,value:1},_mute:{writable:!0,value:!1},_loop:{writable:!0,value:!1},_shuffle:{writable:!0,value:!1}})}_destroy(){this.stop(),this.tracks.filter((trackObj=>trackObj.own)).forEach((trackObj=>trackObj.track._destroy())),delete this.tracks,delete this.queue}load(){this.tracks.forEach((trackObj=>trackObj.track.load()))}unload(){this.stop(),this.tracks.forEach((trackObj=>trackObj.track.unload()))}play(){return null!==this.current&&!this.current.track.isUnavailable()&&!this.current.track.isEnded()||(0===this.queue.length&&this._fillQueue(),this._next())?this.current.track.play():Promise.reject(new Error(\"no tracks were available\"))}playWhenAllowed(){return this.play().catch((ex=>{if(\"NotAllowedError\"!==ex.name)throw ex;onUserActivation(\".AudioList_playWhenAllowed\",(()=>this.play()))}))}pause(){null!==this.current&&this.current.track.pause()}stop(){null!==this.current&&(this.current.track.stop(),this.current=null),this._drainQueue()}skip(){this._next()?this.current.track.play():this._loop&&this.play()}fade(duration,toVol,fromVol){if(\"number\"!=typeof duration)throw new TypeError(\"duration parameter must be a number\");if(\"number\"!=typeof toVol)throw new TypeError(\"toVolume parameter must be a number\");if(null!=fromVol&&\"number\"!=typeof fromVol)throw new TypeError(\"fromVolume parameter must be a number\");if(0===this.queue.length&&this._fillQueue(),(null===this.current||this.current.track.isUnavailable()||this.current.track.isEnded())&&!this._next())return;const adjToVol=Math.clamp(toVol,0,1)*this.current.volume;let adjFromVol;return null!=fromVol&&(adjFromVol=Math.clamp(fromVol,0,1)*this.current.volume),this._volume=toVol,this.current.track.fade(duration,adjToVol,adjFromVol)}fadeIn(duration,fromVol){return this.fade(duration,1,fromVol)}fadeOut(duration,fromVol){return this.fade(duration,0,fromVol)}fadeStop(){null!==this.current&&this.current.track.fadeStop()}loop(loop){return null==loop?this._loop:(this._loop=!!loop,this)}mute(mute){return null==mute?this._mute:(this._mute=!!mute,null!==this.current&&this.current.track.mute(this._mute),this)}rate(rate){if(null==rate)return this._rate;if(\"number\"!=typeof rate)throw new TypeError(\"rate parameter must be a number\");return this._rate=Math.clamp(rate,.2,5),null!==this.current&&this.current.track.rate(this._rate*this.current.rate),this}shuffle(shuffle){if(null==shuffle)return this._shuffle;if(this._shuffle=!!shuffle,this.queue.length>0&&(this._fillQueue(),!this._shuffle&&null!==this.current&&this.queue.length>1)){const firstIndex=this.queue.findIndex((trackObj=>trackObj===this.current));-1!==firstIndex&&this.queue.push(...this.queue.splice(0,firstIndex+1))}return this}volume(volume){if(null==volume)return this._volume;if(\"number\"!=typeof volume)throw new TypeError(\"volume parameter must be a number\");return this._volume=Math.clamp(volume,0,1),null!==this.current&&this.current.track.volume(this._volume*this.current.volume),this}duration(){if(arguments.length>0)throw new Error(\"duration takes no parameters\");return this.tracks.map((trackObj=>trackObj.track.duration())).reduce(((prev,cur)=>prev+cur),0)}remaining(){if(arguments.length>0)throw new Error(\"remaining takes no parameters\");let remainingTime=this.queue.map((trackObj=>trackObj.track.duration())).reduce(((prev,cur)=>prev+cur),0);return null!==this.current&&(remainingTime+=this.current.track.remaining()),remainingTime}time(){if(arguments.length>0)throw new Error(\"time takes no parameters\");return this.duration()-this.remaining()}isPlaying(){return null!==this.current&&this.current.track.isPlaying()}isPaused(){return null===this.current||this.current.track.isPaused()}isStopped(){return 0===this.queue.length&&null===this.current}isEnded(){return 0===this.queue.length&&(null===this.current||this.current.track.isEnded())}isFading(){return null!==this.current&&this.current.track.isFading()}_next(){let nextTrack;for(null!==this.current&&(this.current.track.stop(),this.current=null);nextTrack=this.queue.shift();)if(!nextTrack.track.isUnavailable()){this.current=nextTrack;break}return null!==this.current&&(this.current.track.mute(this._mute),this.current.track.rate(this._rate*this.current.rate),this.current.track.volume(this._volume*this.current.volume),this.current.track.loop(!1),!0)}_onEnd(){if(0===this.queue.length){if(!this._loop)return;this._fillQueue()}this._next()&&this.current.track.play()}_drainQueue(){this.queue.splice(0)}_fillQueue(){this._drainQueue(),this.queue.push(...this.tracks.filter((trackObj=>!trackObj.track.isUnavailable()))),0!==this.queue.length&&this._shuffle&&(this.queue.shuffle(),this.queue.length>1&&this.queue[0]===this.current&&this.queue.push(this.queue.shift()))}}class AudioRunner{constructor(list){if(!(list instanceof Set||list instanceof AudioRunner))throw new TypeError(\"list parameter must be a Set or a AudioRunner instance\");Object.defineProperties(this,{trackIds:{value:new Set(list instanceof AudioRunner?list.trackIds:list)}})}load(){AudioRunner._run(this.trackIds,AudioTrack.prototype.load)}unload(){AudioRunner._run(this.trackIds,AudioTrack.prototype.unload)}play(){AudioRunner._run(this.trackIds,AudioTrack.prototype.play)}playWhenAllowed(){AudioRunner._run(this.trackIds,AudioTrack.prototype.playWhenAllowed)}pause(){AudioRunner._run(this.trackIds,AudioTrack.prototype.pause)}stop(){AudioRunner._run(this.trackIds,AudioTrack.prototype.stop)}fade(duration,toVol,fromVol){if(null==duration||null==toVol)throw new Error(\"fade requires parameters\");AudioRunner._run(this.trackIds,AudioTrack.prototype.fade,duration,toVol,fromVol)}fadeIn(duration,fromVol){if(null==duration)throw new Error(\"fadeIn requires a parameter\");AudioRunner._run(this.trackIds,AudioTrack.prototype.fadeIn,duration,fromVol)}fadeOut(duration,fromVol){if(null==duration)throw new Error(\"fadeOut requires a parameter\");AudioRunner._run(this.trackIds,AudioTrack.prototype.fadeOut,duration,fromVol)}fadeStop(){AudioRunner._run(this.trackIds,AudioTrack.prototype.fadeStop)}loop(loop){if(null==loop)throw new Error(\"loop requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.loop,loop),this}mute(mute){if(null==mute)throw new Error(\"mute requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.mute,mute),this}rate(rate){if(null==rate)throw new Error(\"rate requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.rate,rate),this}time(time){if(null==time)throw new Error(\"time requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.time,time),this}volume(volume){if(null==volume)throw new Error(\"volume requires a parameter\");return AudioRunner._run(this.trackIds,AudioTrack.prototype.volume,volume),this}on(...args){return AudioRunner._run(this.trackIds,AudioTrack.prototype.on,...args),this}one(...args){return AudioRunner._run(this.trackIds,AudioTrack.prototype.one,...args),this}off(...args){return AudioRunner._run(this.trackIds,AudioTrack.prototype.off,...args),this}static _run(ids,fn,...args){ids.forEach((id=>{const track=_tracks.get(id);track&&fn.apply(track,args)}))}}const _runnerParseSelector=(()=>{const notWsRe=/\\S/g,parenRe=/[()]/g;function processNegation(str,startPos){let match;if(notWsRe.lastIndex=startPos,match=notWsRe.exec(str),null===match||\"(\"!==match[0])throw new Error('invalid \":not()\" syntax: missing parenthesis');parenRe.lastIndex=notWsRe.lastIndex;const start=notWsRe.lastIndex,result={str:\"\",nextMatch:-1};let depth=1;for(;null!==(match=parenRe.exec(str));)if(\"(\"===match[0]?++depth:--depth,depth<1){result.nextMatch=parenRe.lastIndex,result.str=str.slice(start,result.nextMatch-1);break}return result}return function parseSelector(idArg){const ids=[],idRe=/:?[^\\s:()]+/g;let match;for(;null!==(match=idRe.exec(idArg));){const id=match[0];if(\":not\"===id){if(0===ids.length)throw new Error('invalid negation: no group ID preceded \":not()\"');const parent=ids[ids.length-1];if(!parent.id.startsWith(\":\"))throw new Error(`invalid negation of track \"${parent.id}\": only groups may be negated with \":not()\"`);const negation=processNegation(idArg,idRe.lastIndex);if(-1===negation.nextMatch)throw new Error('unknown error parsing \":not()\"');idRe.lastIndex=negation.nextMatch,parent.not=parseSelector(negation.str)}else ids.push({id:id})}return ids}})();function masterMute(mute){if(null==mute)return _masterMute;_masterMute=!!mute,publish(\"mute\",_masterMute)}function unsubscribe(id){_subscribers.delete(id)}function publish(mesg,data){_subscribers.forEach((fn=>fn(mesg,data)))}function _newTrack(sources){return new AudioTrack(sources.map((source=>{if(\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);if(passage.tags.includes(\"Twine.audio\"))return passage.text.trim()}const match=_formatSpecRe.exec(source);return null===match?source:{format:match[1],src:match[2]}})))}return Object.preventExtensions(Object.create(null,{tracks:{value:Object.preventExtensions(Object.create(null,{add:{value:function(){if(arguments.length<2){const errors=[];throw arguments.length<1&&errors.push(\"track ID\"),arguments.length<2&&errors.push(\"sources\"),new Error(`no ${errors.join(\" or \")} specified`)}const id=String(arguments[0]).trim(),what=`track ID \"${id}\"`;if(_badIdRe.test(id))throw new Error(`invalid ${what}: track IDs must not contain colons or whitespace`);const sources=Array.isArray(arguments[1])?Array.from(arguments[1]):Array.from(arguments).slice(1);let track;try{track=_newTrack(sources)}catch(ex){throw new Error(`${what}: error during track initialization: ${ex.message}`)}if(Config.debug&&!track.hasSource())throw new Error(`${what}: no supported audio sources found`);_tracks.has(id)&&_tracks.get(id)._destroy(),_tracks.set(id,track)}},delete:{value:function(id){return _tracks.has(id)&&_tracks.get(id)._destroy(),_tracks.delete(id)}},clear:{value:function(){_tracks.forEach((track=>track._destroy())),_tracks.clear()}},has:{value:function(id){return _tracks.has(id)}},get:{value:function(id){return _tracks.get(id)||null}}}))},groups:{value:Object.preventExtensions(Object.create(null,{add:{value:function(){if(arguments.length<2){const errors=[];throw arguments.length<1&&errors.push(\"group ID\"),arguments.length<2&&errors.push(\"track IDs\"),new Error(`no ${errors.join(\" or \")} specified`)}const id=String(arguments[0]).trim(),what=`group ID \"${id}\"`;if(!id.startsWith(\":\")||_badIdRe.test(id.slice(1)))throw new Error(`invalid ${what}: group IDs must start with a colon and must not contain colons or whitespace`);if(_specialIds.includes(id))throw new Error(`cannot clobber special ${what}`);const trackIds=Array.isArray(arguments[1])?Array.from(arguments[1]):Array.from(arguments).slice(1);let group;try{group=new Set(trackIds.map((trackId=>{if(!_tracks.has(trackId))throw new Error(`track \"${trackId}\" does not exist`);return trackId})))}catch(ex){throw new Error(`${what}: error during group initialization: ${ex.message}`)}_groups.set(id,Object.freeze(Array.from(group)))}},delete:{value:function(id){return _groups.delete(id)}},clear:{value:function(){_groups.clear()}},has:{value:function(id){return _groups.has(id)}},get:{value:function(id){return _groups.get(id)||null}}}))},lists:{value:Object.preventExtensions(Object.create(null,{add:{value:function(){if(arguments.length<2){const errors=[];throw arguments.length<1&&errors.push(\"list ID\"),arguments.length<2&&errors.push(\"track IDs\"),new Error(`no ${errors.join(\" or \")} specified`)}const id=String(arguments[0]).trim(),what=`list ID \"${id}\"`;if(_badIdRe.test(id))return this.error(`invalid ${what}: list IDs must not contain colons or whitespace`);const descriptors=Array.isArray(arguments[1])?Array.from(arguments[1]):Array.from(arguments).slice(1);let list;try{list=new AudioList(descriptors.map((desc=>{if(null===desc)throw new Error(\"track descriptor must be a string or object (type: null)\");switch(typeof desc){case\"string\":desc={id:desc};break;case\"object\":if(!Object.hasOwn(desc,\"id\")&&!Object.hasOwn(desc,\"sources\"))throw new Error('track descriptor must contain one of either an \"id\" or a \"sources\" property');if(Object.hasOwn(desc,\"id\")&&Object.hasOwn(desc,\"sources\"))throw new Error('track descriptor must contain either an \"id\" or a \"sources\" property, not both');break;default:throw new Error(`track descriptor must be a string or object (type: ${typeof desc})`)}let own,track,volume;if(Object.hasOwn(desc,\"id\")){if(\"string\"!=typeof desc.id)throw new Error('\"id\" property must be a string');if(!_tracks.has(desc.id))throw new Error(`track \"${desc.id}\" does not exist`);track=_tracks.get(desc.id)}else if(Object.hasOwn(desc,\"sources\")){if(!Array.isArray(desc.sources)||0===desc.sources.length)throw new Error('\"sources\" property must be a non-empty array');if(Object.hasOwn(desc,\"own\"))throw new Error('\"own\" property is not allowed with the \"sources\" property');try{track=_newTrack(desc.sources),own=!0}catch(ex){throw new Error(`error during track initialization: ${ex.message}`)}if(Config.debug&&!track.hasSource())throw new Error(\"no supported audio sources found\")}if(Object.hasOwn(desc,\"own\")){if(\"boolean\"!=typeof desc.own)throw new Error('\"own\" property must be a boolean');own=desc.own,own&&(track=track.clone())}if(Object.hasOwn(desc,\"volume\")){if(\"number\"!=typeof desc.volume||Number.isNaN(desc.volume)||!Number.isFinite(desc.volume)||desc.volume<0)throw new Error('\"volume\" property must be a non-negative finite number');volume=desc.volume}return{own:null!=own&&own,track:track,volume:null!=volume?volume:track.volume()}})))}catch(ex){throw new Error(`${what}: error during playlist initialization: ${ex.message}`)}_lists.has(id)&&_lists.get(id)._destroy(),_lists.set(id,list)}},delete:{value:function(id){return _lists.has(id)&&_lists.get(id)._destroy(),_lists.delete(id)}},clear:{value:function(){_lists.forEach((list=>list._destroy())),_lists.clear()}},has:{value:function(id){return _lists.has(id)}},get:{value:function(id){return _lists.get(id)||null}}}))},select:{value:function(){if(0===arguments.length)throw new Error(\"no track selector specified\");const selector=String(arguments[0]).trim(),trackIds=new Set;try{const allIds=Array.from(_tracks.keys());function renderIds(idObj){const id=idObj.id;let ids;switch(id){case\":all\":ids=allIds;break;case\":looped\":ids=allIds.filter((id=>_tracks.get(id).loop()));break;case\":muted\":ids=allIds.filter((id=>_tracks.get(id).mute()));break;case\":paused\":ids=allIds.filter((id=>_tracks.get(id).isPaused()));break;case\":playing\":ids=allIds.filter((id=>_tracks.get(id).isPlaying()));break;case\":stopped\":ids=allIds.filter((id=>_tracks.get(id).isStopped()));break;default:if(id.startsWith(\":\")){const group=_groups.get(id);if(!group)throw new Error(`group \"${id}\" does not exist`);ids=group}else ids=[id]}if(Object.hasOwn(idObj,\"not\")){const negated=idObj.not.map((idObj=>renderIds(idObj))).flat(1/0);ids=ids.filter((id=>!negated.includes(id)))}return ids}_runnerParseSelector(selector).forEach((idObj=>renderIds(idObj).forEach((id=>{if(!_tracks.has(id))throw new Error(`track \"${id}\" does not exist`);trackIds.add(id)}))))}catch(ex){throw new Error(`error during runner initialization: ${ex.message}`)}return new AudioRunner(trackIds)}},load:{value:function(){publish(\"load\")}},loadWithScreen:{value:function(){publish(\"loadwithscreen\")}},mute:{value:masterMute},muteOnHidden:{value:function(mute){if(!Visibility.isEnabled())return!1;if(null==mute)return _masterMuteOnHidden;_masterMuteOnHidden=!!mute;const namespace=\".SimpleAudio_masterMuteOnHidden\";if(_masterMuteOnHidden){const visibilityChange=`${Visibility.changeEvent}${namespace}`;jQuery(document).off(namespace).on(visibilityChange,(()=>masterMute(Visibility.isHidden()))),Visibility.isHidden()&&masterMute(!0)}else jQuery(document).off(namespace)}},rate:{value:function(rate){if(null==rate)return _masterRate;if(\"number\"!=typeof rate||Number.isNaN(rate)||!Number.isFinite(rate))throw new Error(\"rate must be a finite number\");_masterRate=Math.clamp(rate,.2,5),publish(\"rate\",_masterRate)}},stop:{value:function(){publish(\"stop\")}},unload:{value:function(){publish(\"unload\")}},volume:{value:function(volume){if(null==volume)return _masterVolume;if(\"number\"!=typeof volume||Number.isNaN(volume)||!Number.isFinite(volume))throw new Error(\"volume must be a finite number\");_masterVolume=Math.clamp(volume,0,1),publish(\"volume\",_masterVolume)}}}))})(),State=(()=>{let _history=[],_active=momentCreate(),_activeIndex=-1,_prng=null,_temporary=Object.create(null);function stateMarshal(noDelta){const state={index:_activeIndex};return noDelta?state.history=clone(_history):state.delta=historyDeltaEncode(_history),null!==_prng&&(state.seed=_prng.seed),state}function stateUnmarshal(state,noDelta){if(null==state)throw new Error(\"state object is null or undefined\");if(!Object.hasOwn(state,noDelta?\"history\":\"delta\")||0===state[noDelta?\"history\":\"delta\"].length)throw new Error(\"state object has no history or history is empty\");if(!Object.hasOwn(state,\"index\"))throw new Error(\"state object has no index\");if(null!==_prng&&!Object.hasOwn(state,\"seed\"))throw new Error(\"state object has no seed, but PRNG is enabled\");if(null===_prng&&Object.hasOwn(state,\"seed\"))throw new Error(\"state object has seed, but PRNG is disabled\");_history=noDelta?clone(state.history):historyDeltaDecode(state.delta),_activeIndex=state.index,Object.hasOwn(state,\"seed\")&&(_prng.seed=state.seed),momentActivate(_activeIndex)}function momentCreate(title,variables){return{title:null==title?\"\":String(title),variables:null==variables?{}:variables}}function momentActivate(moment){if(null==moment)throw new Error(\"moment activation attempted with null or undefined\");switch(typeof moment){case\"object\":_active=clone(moment);break;case\"number\":if(historyIsEmpty())throw new Error(\"moment activation attempted with index on empty history\");if(moment<0||moment>=historySize())throw new RangeError(`moment activation attempted with out-of-bounds index; need [0, ${historySize()-1}], got ${moment}`);_active=clone(_history[moment]);break;default:throw new TypeError(`moment activation attempted with a \"${typeof moment}\"; must be an object or valid history stack index`)}return null!==_prng&&(_prng=function(state){const prng=prngCreate(state.seed);for(let i=state.pull;i>0;--i)prng.random();return prng}({seed:_prng.seed,pull:_active.pull})),session.set(\"state\",stateMarshal()),triggerEvent(\":historyupdate\"),_active}function historyLength(){return _activeIndex+1}function historySize(){return _history.length}function historyIsEmpty(){return 0===_history.length}function historyTop(){return _history.length>0?_history[_history.length-1]:null}function historyGoTo(index){return!(null==index||index<0||index>=historySize()||index===_activeIndex)&&(_activeIndex=index,momentActivate(_activeIndex),!0)}function historyDeltaEncode(historyArr){if(!Array.isArray(historyArr))return null;if(0===historyArr.length)return[];const delta=[historyArr[0]];for(let i=1,iend=historyArr.length;i<iend;++i)delta.push(Diff.diff(historyArr[i-1],historyArr[i]));return delta}function historyDeltaDecode(delta){if(!Array.isArray(delta))return null;if(0===delta.length)return[];const historyArr=[clone(delta[0])];for(let i=1,iend=delta.length;i<iend;++i)historyArr.push(Diff.patch(historyArr[i-1],delta[i]));return historyArr}function prngCreate(seedBase,mixEntropy){return new Math.seedrandom(seedBase,{entropy:Boolean(mixEntropy),pass:(prng,seed)=>Object.create(null,{prng:{value:prng},seed:{writable:!0,value:seed},pull:{writable:!0,value:0},random:{value(){return++this.pull,this.prng()}}})})}function tempVariablesClear(){_temporary=Object.create(null)}const _METADATA_STORE=\"metadata\";function metadataDelete(key){if(\"string\"!=typeof key)throw new TypeError(`State.metadata.delete key parameter must be a string (received: ${typeof key})`);const store=storage.get(_METADATA_STORE);store&&Object.hasOwn(store,key)&&(1===Object.keys(store).length?storage.delete(_METADATA_STORE):(delete store[key],storage.set(_METADATA_STORE,store)))}return Object.preventExtensions(Object.create(null,{reset:{value:function(){session.delete(\"state\"),_history=[],_active=momentCreate(),_activeIndex=-1,_prng=null===_prng?null:prngCreate(_prng.seed),tempVariablesClear()}},restore:{value:function(){const state=session.get(\"state\");return null!=state&&(stateUnmarshal(state),!0)}},marshalForSave:{value:function(){return stateMarshal(!0)}},unmarshalForSave:{value:function(state){return stateUnmarshal(state,!0)}},expired:{get:function(){return[]}},turns:{get:function(){return historyLength()}},passages:{get:function(){return _history.slice(0,historyLength()).map((moment=>moment.title))}},hasPlayed:{value:function(title){return null!=title&&\"\"!==title&&!!_history.slice(0,historyLength()).some((moment=>moment.title===title))}},active:{get:function(){return _active}},activeIndex:{get:function(){return _activeIndex}},passage:{get:function(){return _active.title}},variables:{get:function(){return _active.variables}},history:{get:function(){return _history}},length:{get:historyLength},size:{get:historySize},isEmpty:{value:historyIsEmpty},current:{get:function(){return _history.length>0?_history[_activeIndex]:null}},top:{get:historyTop},bottom:{get:function(){return _history.length>0?_history[0]:null}},index:{value:function(index){return historyIsEmpty()||index<0||index>_activeIndex?null:_history[index]}},peek:{value:function(offset){if(historyIsEmpty())return null;const lengthOffset=1+(offset?Math.abs(offset):0);return lengthOffset>historyLength()?null:_history[historyLength()-lengthOffset]}},has:{value:function(title){if(historyIsEmpty()||null==title||\"\"===title)return!1;for(let i=_activeIndex;i>=0;--i)if(_history[i].title===title)return!0;return!1}},create:{value:function(title){for(0,historyLength()<historySize()&&_history.splice(historyLength(),historySize()-historyLength()),_history.push(momentCreate(title,_active.variables)),_prng&&(historyTop().pull=_prng.pull);historySize()>Config.history.maxStates;)_history.shift();return _activeIndex=historySize()-1,momentActivate(_activeIndex),historyLength()}},goTo:{value:historyGoTo},go:{value:function(offset){return null!=offset&&0!==offset&&historyGoTo(_activeIndex+offset)}},deltaEncode:{value:historyDeltaEncode},deltaDecode:{value:historyDeltaDecode},prng:{value:Object.preventExtensions(Object.create(null,{init:{value:function(seedBase,mixEntropy){if(!historyIsEmpty()){let what;throw what=\"the story JavaScript section\",new Error(`State.prng.init must be called during initialization, within either ${what} or the StoryInit special passage`)}_prng=prngCreate(seedBase,Boolean(mixEntropy)),_active.pull=_prng.pull}},isEnabled:{value:function(){return null!==_prng}},pull:{get:function(){return null!==_prng?_prng.pull:NaN}},seed:{get:function(){return null!==_prng?_prng.seed:null}}}))},random:{value:function(){return null!==_prng?_prng.random():Math.random()}},clearTemporary:{value:tempVariablesClear},temporary:{get:function(){return _temporary}},getVar:{value:function(varExpression){try{return Scripting.evalTwineScript(varExpression)}catch(ex){}}},setVar:{value:function(varExpression,value){try{return Scripting.evalTwineScript(`${varExpression} = SCRIPT$DATA$`,null,value),!0}catch(ex){}return!1}},metadata:{value:Object.preventExtensions(Object.create(null,{clear:{value:function(){storage.delete(_METADATA_STORE)}},delete:{value:metadataDelete},entries:{value:function(){const store=storage.get(_METADATA_STORE);return store&&Object.entries(store)}},get:{value:function(key){if(\"string\"!=typeof key)throw new TypeError(`State.metadata.get key parameter must be a string (received: ${typeof key})`);const store=storage.get(_METADATA_STORE);return store&&Object.hasOwn(store,key)?store[key]:undefined}},has:{value:function(key){if(\"string\"!=typeof key)throw new TypeError(`State.metadata.has key parameter must be a string (received: ${typeof key})`);const store=storage.get(_METADATA_STORE);return store&&Object.hasOwn(store,key)}},keys:{value:function(){const store=storage.get(_METADATA_STORE);return store&&Object.keys(store)}},set:{value:function(key,value){if(\"string\"!=typeof key)throw new TypeError(`State.metadata.set key parameter must be a string (received: ${typeof key})`);if(void 0===value)metadataDelete(key);else{const store=storage.get(_METADATA_STORE)||{};store[key]=value,storage.set(_METADATA_STORE,store)}}},size:{get:function(){const store=storage.get(_METADATA_STORE);return store?Object.keys(store).length:0}}}))}}))})(),Scripting=(()=>{function toStringOrDefault(value){return console.warn(\"[DEPRECATED] toStringOrDefault() is deprecated.\"),stringFrom(value)}function either(){if(0!==arguments.length)return Array.prototype.concat.apply([],arguments).random()}function forget(key){if(\"string\"!=typeof key)throw new TypeError(`forget key parameter must be a string (received: ${getTypeOf(key)})`);State.metadata.delete(key)}function hasVisited(){if(0===arguments.length)throw new Error(\"hasVisited called with insufficient parameters\");if(State.isEmpty())return!1;const needles=Array.prototype.concat.apply([],arguments),played=State.passages;for(let i=0;i<needles.length;++i)if(!played.includes(needles[i]))return!1;return!0}function lastVisited(){if(0===arguments.length)throw new Error(\"lastVisited called with insufficient parameters\");if(State.isEmpty())return-1;const needles=Array.prototype.concat.apply([],arguments),played=State.passages,uBound=played.length-1;let turns=State.turns;for(let i=0;i<needles.length&&turns>-1;++i){const lastIndex=played.lastIndexOf(needles[i]);turns=Math.min(turns,-1===lastIndex?-1:uBound-lastIndex)}return turns}function memorize(key,value){if(\"string\"!=typeof key)throw new TypeError(`memorize key parameter must be a string (received: ${getTypeOf(key)})`);State.metadata.set(key,value)}function passage(){return State.passage}function previous(){const passages=State.passages;if(arguments.length>0){const offset=Number(arguments[0]);if(!Number.isSafeInteger(offset)||offset<1)throw new RangeError(\"previous offset parameter must be a positive integer greater than zero\");return passages.length>offset?passages[passages.length-1-offset]:\"\"}for(let i=passages.length-2;i>=0;--i)if(passages[i]!==State.passage)return passages[i];return\"\"}function random(){let min,max;switch(arguments.length){case 0:throw new Error(\"random called with insufficient parameters\");case 1:min=0,max=Math.trunc(arguments[0]);break;default:min=Math.trunc(arguments[0]),max=Math.trunc(arguments[1])}if(!Number.isInteger(min))throw new TypeError(\"random min parameter must be an integer\");if(!Number.isInteger(max))throw new TypeError(\"random max parameter must be an integer\");return min>max&&([min,max]=[max,min]),Math.floor(State.random()*(max-min+1))+min}function randomFloat(){let min,max;switch(arguments.length){case 0:throw new Error(\"randomFloat called with insufficient parameters\");case 1:min=0,max=Number(arguments[0]);break;default:min=Number(arguments[0]),max=Number(arguments[1])}if(Number.isNaN(min)||!Number.isFinite(min))throw new TypeError(\"randomFloat min parameter must be a number\");if(Number.isNaN(max)||!Number.isFinite(max))throw new TypeError(\"randomFloat max parameter must be a number\");return min>max&&([min,max]=[max,min]),State.random()*(max-min)+min}function recall(key,defaultValue){if(\"string\"!=typeof key)throw new TypeError(`recall key parameter must be a string (received: ${getTypeOf(key)})`);return State.metadata.has(key)?State.metadata.get(key):defaultValue}function tags(){if(0===arguments.length)return Story.get(State.passage).tags;const passages=Array.prototype.concat.apply([],arguments);let tags=[];for(let i=0;i<passages.length;++i)tags=tags.concat(Story.get(passages[i]).tags);return tags}function temporary(){return State.temporary}function time(){return null===Engine.lastPlay?0:now()-Engine.lastPlay}function turns(){return State.turns}function variables(){return State.variables}function visited(){if(State.isEmpty())return 0;const needles=Array.prototype.concat.apply([],0===arguments.length?[State.passage]:arguments),played=State.passages;let count=State.turns;for(let i=0;i<needles.length&&count>0;++i)count=Math.min(count,played.count(needles[i]));return count}function visitedTags(){if(0===arguments.length)throw new Error(\"visitedTags called with insufficient parameters\");if(State.isEmpty())return 0;const needles=Array.prototype.concat.apply([],arguments),nLength=needles.length,played=State.passages,seen=new Map;let count=0;for(let i=0;i<played.length;++i){const title=played[i];if(seen.has(title))seen.get(title)&&++count;else{const tags=Story.get(title).tags;if(tags.length>0){let found=0;for(let j=0;j<nLength;++j)tags.includes(needles[j])&&++found;found===nLength?(++count,seen.set(title,!0)):seen.set(title,!1)}}}return count}var{importScripts:importScripts,importStyles:importStyles}=(()=>{function slugifyUrl(url){return parseURL(url).path.replace(/^[^\\w]+|[^\\w]+$/g,\"\").replace(/[^\\w]+/g,\"-\").toLocaleLowerCase()}function addScript(url){return new Promise(((resolve,reject)=>{let kind,src;if(\"string\"==typeof url)kind=url.trim().toLowerCase().endsWith(\".mjs\")?\"module\":\"text/javascript\",src=url;else{if(\"object\"!=typeof url)throw new Error(\"importScripts url parameter must be a string or object\");kind=url.type,src=url.src}jQuery(document.createElement(\"script\")).one(\"load abort error\",(ev=>{jQuery(ev.target).off(),\"load\"===ev.type?resolve(ev.target):reject(new Error(`importScripts failed to load the script \"${src}\"`))})).appendTo(document.head).attr({id:`script-imported-${slugifyUrl(src)}`,type:kind,src:src})}))}function addStyle(url){return new Promise(((resolve,reject)=>{if(\"string\"!=typeof url)throw new Error(\"importStyles url parameter must be a string\");jQuery(document.createElement(\"link\")).one(\"load abort error\",(ev=>{jQuery(ev.target).off(),\"load\"===ev.type?resolve(ev.target):reject(new Error(`importStyles failed to load the stylesheet \"${url}\"`))})).appendTo(document.head).attr({id:`style-imported-${slugifyUrl(url)}`,rel:\"stylesheet\",href:url})}))}function sequence(callbacks){return callbacks.reduce(((seq,fn)=>seq.then(fn)),Promise.resolve())}return{importScripts:function(...urls){return Promise.all(urls.map((oneOrSeries=>Array.isArray(oneOrSeries)?sequence(oneOrSeries.map((url=>()=>addScript(url)))):addScript(oneOrSeries))))},importStyles:function(...urls){return Promise.all(urls.map((oneOrSeries=>Array.isArray(oneOrSeries)?sequence(oneOrSeries.map((url=>()=>addStyle(url)))):addStyle(oneOrSeries))))}}})();const desugar=(()=>{const tokenTable=enumFrom({$:\"State.variables.\",_:\"State.temporary.\",to:\"=\",eq:\"==\",neq:\"!=\",is:\"===\",isnot:\"!==\",gt:\">\",gte:\">=\",lt:\"<\",lte:\"<=\",and:\"&&\",or:\"||\",not:\"!\",def:'\"undefined\" !== typeof',ndef:'\"undefined\" === typeof'}),desugarRE=new RegExp([\"(?:\\\"\\\"|''|``)\",'(?:\"(?:\\\\\\\\.|[^\"\\\\\\\\])+\")',\"(?:'(?:\\\\\\\\.|[^'\\\\\\\\])+')\",\"(`(?:\\\\\\\\.|[^`\\\\\\\\])+`)\",\"(?:[=+\\\\-*\\\\/%<>&\\\\|\\\\^~!?:,;\\\\(\\\\)\\\\[\\\\]{}]+)\",\"(?:\\\\.{3})\",\"([^\\\"'=+\\\\-*\\\\/%<>&\\\\|\\\\^~!?:,;\\\\(\\\\)\\\\[\\\\]{}\\\\s]+)\"].join(\"|\"),\"g\"),varTest=new RegExp(`^${Patterns.variable}`);function desugar(sugaredCode){desugarRE.lastIndex=0;let match,code=sugaredCode;for(;null!==(match=desugarRE.exec(code));)if(match[1]){const sugaredTemplate=match[1],template=desugarTemplate(sugaredTemplate);template!==sugaredTemplate&&(code=code.splice(match.index,sugaredTemplate.length,template),desugarRE.lastIndex+=template.length-sugaredTemplate.length)}else if(match[2]){let token=match[2];if(\"$\"===token||\"_\"===token)continue;varTest.test(token)&&(token=token[0]),tokenTable[token]&&(code=code.splice(match.index,token.length,tokenTable[token]),desugarRE.lastIndex+=tokenTable[token].length-token.length)}return code}const templateGroupStartRE=/\\$\\{/g,templateGroupParseRE=new RegExp([\"(?:\\\"\\\"|'')\",'(?:\"(?:\\\\\\\\.|[^\"\\\\\\\\])+\")',\"(?:'(?:\\\\\\\\.|[^'\\\\\\\\])+')\",\"(\\\\{)\",\"(\\\\})\"].join(\"|\"),\"g\");function desugarTemplate(sugaredLiteral){templateGroupStartRE.lastIndex=0;let startMatch,template=sugaredLiteral;for(;null!==(startMatch=templateGroupStartRE.exec(template));){const startIndex=startMatch.index+2;let endMatch,endIndex=startIndex,depth=1;for(templateGroupParseRE.lastIndex=startIndex;null!==(endMatch=templateGroupParseRE.exec(template));)if(endMatch[1]?++depth:endMatch[2]&&--depth,0===depth){endIndex=endMatch.index;break}if(endIndex>startIndex){const desugarREIndex=desugarRE.lastIndex,sugaredGroup=template.slice(startIndex,endIndex),group=desugar(sugaredGroup);desugarRE.lastIndex=desugarREIndex,template=template.splice(startIndex,sugaredGroup.length,group),templateGroupStartRE.lastIndex+=group.length-sugaredGroup.length}}return template}return desugar})();function evalJavaScript(code,output,data){return function(code,output,SCRIPT$DATA$){return eval(code)}.call(output?{output:output}:null,String(code),output,data)}function evalTwineScript(code,output,data){return function(code,output,SCRIPT$DATA$){return eval(code)}.call(output?{output:output}:null,desugar(String(code)),output,data)}return Object.preventExtensions(Object.create(null,{desugar:{value:desugar},evalJavaScript:{value:evalJavaScript},evalTwineScript:{value:evalTwineScript},parse:{value:desugar}}))})(),{EOF:EOF,Lexer:Lexer}={EOF:-1,Lexer:class{constructor(source,initialState){if(arguments.length<2)throw new Error(\"Lexer constructor called with too few parameters (source:string , initialState:function)\");Object.defineProperties(this,{source:{value:source},initial:{value:initialState},state:{writable:!0,value:initialState},start:{writable:!0,value:0},pos:{writable:!0,value:0},depth:{writable:!0,value:0},items:{writable:!0,value:[]},data:{writable:!0,value:{}}})}reset(){this.state=this.initial,this.start=0,this.pos=0,this.depth=0,this.items=[],this.data={}}run(){for(;null!==this.state;)this.state=this.state(this);return this.items}nextItem(){for(;0===this.items.length&&null!==this.state;)this.state=this.state(this);return this.items.shift()}next(){return this.pos>=this.source.length?-1:this.source[this.pos++]}peek(){return this.pos>=this.source.length?-1:this.source[this.pos]}backup(num){this.pos-=num||1}forward(num){this.pos+=num||1}ignore(){this.start=this.pos}accept(valid){const ch=this.next();return!(-1===ch||!valid.includes(ch)&&(this.backup(),1))}acceptRe(validRe){const ch=this.next();return!(-1===ch||!validRe.test(ch)&&(this.backup(),1))}acceptRun(valid){for(;;){const ch=this.next();if(-1===ch)return;if(!valid.includes(ch))break}this.backup()}acceptRunRe(validRe){for(;;){const ch=this.next();if(-1===ch)return;if(!validRe.test(ch))break}this.backup()}emit(type){this.items.push({type:type,text:this.source.slice(this.start,this.pos),start:this.start,pos:this.pos}),this.start=this.pos}error(type,message){if(arguments.length<2)throw new Error(\"Lexer.prototype.error called with too few parameters (type:number , message:string)\");return this.items.push({type:type,message:message,text:this.source.slice(this.start,this.pos),start:this.start,pos:this.pos}),null}static enumFromNames(names){const obj=names.reduce(((obj,name,i)=>(obj[name]=i,obj)),{});return Object.freeze(Object.assign(Object.create(null),obj))}}},Wikifier=(()=>{let _callDepth=0;class Wikifier{constructor(destination,source,options){Wikifier.Parser.Profile.isEmpty()&&Wikifier.Parser.Profile.compile(),Object.defineProperties(this,{source:{value:String(source)},options:{writable:!0,value:Object.assign({profile:\"all\"},options)},nextMatch:{writable:!0,value:0},output:{writable:!0,value:null},_rawArgs:{writable:!0,value:\"\"}}),this.output=null==destination?document.createDocumentFragment():destination instanceof jQuery?destination[0]:destination;try{++_callDepth,this.subWikify(this.output),1===_callDepth&&(Object.hasOwn(this.options,\"cleanup\")&&null!=this.options.cleanup?this.options.cleanup:Config.cleanupWikifierOutput)&&convertBreaks(this.output)}finally{--_callDepth}}subWikify(output,terminator,options){const oldOutput=this.output;let newOptions,oldOptions;this.output=output,Wikifier.Option.length>0&&(newOptions=Object.assign(newOptions||{},Wikifier.Option.options)),null!==options&&\"object\"==typeof options&&(newOptions=Object.assign(newOptions||{},options)),newOptions&&(oldOptions=this.options,this.options=Object.assign({},this.options,newOptions));const parsersProfile=Wikifier.Parser.Profile.get(this.options.profile),terminatorRegExp=terminator?new RegExp(`(?:${terminator})`,this.options.ignoreTerminatorCase?\"gim\":\"gm\"):null;let terminatorMatch,parserMatch;do{if(parsersProfile.parserRegExp.lastIndex=this.nextMatch,terminatorRegExp&&(terminatorRegExp.lastIndex=this.nextMatch),parserMatch=parsersProfile.parserRegExp.exec(this.source),terminatorMatch=terminatorRegExp?terminatorRegExp.exec(this.source):null,terminatorMatch&&(!parserMatch||terminatorMatch.index<=parserMatch.index))return terminatorMatch.index>this.nextMatch&&this.outputText(this.output,this.nextMatch,terminatorMatch.index),this.matchStart=terminatorMatch.index,this.matchLength=terminatorMatch[0].length,this.matchText=terminatorMatch[0],this.nextMatch=terminatorRegExp.lastIndex,this.output=oldOutput,void(oldOptions&&(this.options=oldOptions));if(parserMatch){let matchingParser;parserMatch.index>this.nextMatch&&this.outputText(this.output,this.nextMatch,parserMatch.index),this.matchStart=parserMatch.index,this.matchLength=parserMatch[0].length,this.matchText=parserMatch[0],this.nextMatch=parsersProfile.parserRegExp.lastIndex;for(let i=1,iend=parserMatch.length;i<iend;++i)if(parserMatch[i]){matchingParser=i-1;break}if(parsersProfile.parsers[matchingParser].handler(this),null!=TempState.break)break}}while(terminatorMatch||parserMatch);null==TempState.break?this.nextMatch<this.source.length&&(this.outputText(this.output,this.nextMatch,this.source.length),this.nextMatch=this.source.length):this.output.lastChild&&this.output.lastChild.nodeType===Node.ELEMENT_NODE&&\"BR\"===this.output.lastChild.nodeName.toUpperCase()&&jQuery(this.output.lastChild).remove(),this.output=oldOutput,oldOptions&&(this.options=oldOptions)}outputText(destination,startPos,endPos){destination.appendChild(document.createTextNode(this.source.substring(startPos,endPos)))}rawArgs(){return console.warn(\"[DEPRECATED] Wikifier.rawArgs() is deprecated.\"),this._rawArgs}fullArgs(){return console.warn(\"[DEPRECATED] Wikifier.fullArgs() is deprecated.\"),Scripting.desugar(this._rawArgs)}static wikifyEval(text){const output=document.createDocumentFragment();new Wikifier(output,text);const errors=output.querySelector(\".error\");if(null!==errors)throw new Error(errors.textContent.replace(errorPrologRegExp,\"\"));return output}static createInternalLink(destination,passage,text,callback){const $link=jQuery(document.createElement(\"a\"));return null!=passage&&($link.attr(\"data-passage\",passage),Story.has(passage)?($link.addClass(\"link-internal\"),Config.addVisitedLinkClass&&State.hasPlayed(passage)&&$link.addClass(\"link-visited\")):$link.addClass(\"link-broken\"),$link.ariaClick({one:!0},(()=>{\"function\"==typeof callback&&callback(),Engine.play(passage)}))),text&&$link.append(document.createTextNode(text)),destination&&$link.appendTo(destination),$link[0]}static createExternalLink(destination,url,text){const $link=jQuery(document.createElement(\"a\")).attr(\"target\",\"_blank\").addClass(\"link-external\").text(text).appendTo(destination);return null!=url&&$link.attr({href:url,tabindex:0}),$link[0]}}return Object.defineProperty(Wikifier,\"Option\",{value:(()=>{let _optionsStack=[];return Object.preventExtensions(Object.create(null,{length:{get:function(){return _optionsStack.length}},options:{get:function(){return Object.assign({},..._optionsStack)}},clear:{value:function(){_optionsStack=[]}},get:{value:function(index){return _optionsStack[index]}},pop:{value:function(){return _optionsStack.pop()}},push:{value:function(options){if(\"object\"!=typeof options||null===options)throw new TypeError(`Wikifier.Option.push options parameter must be an object (received: ${getTypeOf(options)})`);return _optionsStack.push(options)}}}))})()}),Object.defineProperty(Wikifier,\"Parser\",{value:(()=>{const _parsers=[];let _profiles;function parsersHas(name){return!!_parsers.find((parser=>parser.name===name))}return Object.preventExtensions(Object.create(null,{parsers:{get:function(){return _parsers}},add:{value:function(parser){if(\"object\"!=typeof parser)throw new Error(\"Wikifier.Parser.add parser parameter must be an object\");if(!Object.hasOwn(parser,\"name\"))throw new Error('parser object missing required \"name\" property');if(\"string\"!=typeof parser.name)throw new Error('parser object \"name\" property must be a string');if(!Object.hasOwn(parser,\"match\"))throw new Error('parser object missing required \"match\" property');if(\"string\"!=typeof parser.match)throw new Error('parser object \"match\" property must be a string');if(!Object.hasOwn(parser,\"handler\"))throw new Error('parser object missing required \"handler\" property');if(\"function\"!=typeof parser.handler)throw new Error('parser object \"handler\" property must be a function');if(Object.hasOwn(parser,\"profiles\")&&!Array.isArray(parser.profiles))throw new Error('parser object \"profiles\" property must be an array');if(parsersHas(parser.name))throw new Error(`cannot clobber existing parser \"${parser.name}\"`);_parsers.push(parser)}},delete:{value:function(name){const parser=_parsers.find((parser=>parser.name===name));parser&&_parsers.delete(parser)}},isEmpty:{value:function(){return 0===_parsers.length}},has:{value:parsersHas},get:{value:function(name){return _parsers.find((parser=>parser.name===name))||null}},Profile:{value:Object.preventExtensions(Object.create(null,{profiles:{get:function(){return _profiles}},compile:{value:function(){const all=_parsers,core=all.filter((parser=>!Array.isArray(parser.profiles)||parser.profiles.includes(\"core\")));return _profiles=Object.freeze({all:{parsers:all,parserRegExp:new RegExp(all.map((parser=>`(${parser.match})`)).join(\"|\"),\"gm\")},core:{parsers:core,parserRegExp:new RegExp(core.map((parser=>`(${parser.match})`)).join(\"|\"),\"gm\")}}),_profiles}},isEmpty:{value:function(){return\"object\"!=typeof _profiles||0===Object.keys(_profiles).length}},has:{value:function(profile){return\"object\"==typeof _profiles&&Object.hasOwn(_profiles,profile)}},get:{value:function(profile){if(\"object\"!=typeof _profiles||!Object.hasOwn(_profiles,profile))throw new Error(`nonexistent parser profile \"${profile}\"`);return _profiles[profile]}}}))}}))})()}),Object.defineProperties(Wikifier,{helpers:{value:{}},isExternalLink:{value:isExternalLink},getValue:{value:State.getVar},setValue:{value:State.setVar},parse:{value:Scripting.desugar},evalExpression:{value:Scripting.evalTwineScript},evalStatements:{value:Scripting.evalTwineScript},textPrimitives:{value:Patterns}}),Object.defineProperties(Wikifier.helpers,{inlineCss:{value:(()=>{const lookaheadRe=new RegExp(Patterns.inlineCss,\"gm\"),idOrClassRe=new RegExp(`(${Patterns.cssIdOrClassSigil})(${Patterns.anyLetter}+)`,\"g\");return function(w){const css={classes:[],id:\"\",styles:{}};let matched;do{lookaheadRe.lastIndex=w.nextMatch;const match=lookaheadRe.exec(w.source);if(matched=match&&match.index===w.nextMatch,matched){if(match[1])css.styles[cssPropToDOMProp(match[1])]=match[2].trim();else if(match[3])css.styles[cssPropToDOMProp(match[3])]=match[4].trim();else if(match[5]){let subMatch;for(idOrClassRe.lastIndex=0;null!==(subMatch=idOrClassRe.exec(match[5]));)\".\"===subMatch[1]?css.classes.push(subMatch[2]):css.id=subMatch[2]}w.nextMatch=lookaheadRe.lastIndex}}while(matched);return css}})()},evalText:{value(text){let result;try{switch(result=Scripting.evalTwineScript(text),typeof result){case\"string\":\"\"===result.trim()&&(result=text);break;case\"number\":result=String(result);break;default:result=text}}catch(ex){result=text}return result}},evalPassageId:{value:passage=>null==passage||Story.has(passage)?passage:Wikifier.helpers.evalText(passage)},hasBlockContext:{value(nodes){const hasGCS=\"function\"==typeof window.getComputedStyle;for(let i=nodes.length-1;i>=0;--i){const node=nodes[i];switch(node.nodeType){case Node.ELEMENT_NODE:{const tagName=node.nodeName.toUpperCase();if(\"BR\"===tagName)return!0;const styles=hasGCS?window.getComputedStyle(node,null):node.currentStyle;if(styles&&styles.display){if(\"none\"===styles.display)continue;return\"block\"===styles.display}switch(tagName){case\"ADDRESS\":case\"ARTICLE\":case\"ASIDE\":case\"BLOCKQUOTE\":case\"CENTER\":case\"DIV\":case\"DL\":case\"FIGURE\":case\"FOOTER\":case\"FORM\":case\"H1\":case\"H2\":case\"H3\":case\"H4\":case\"H5\":case\"H6\":case\"HEADER\":case\"HR\":case\"MAIN\":case\"NAV\":case\"OL\":case\"P\":case\"PRE\":case\"SECTION\":case\"TABLE\":case\"UL\":return!0}return!1}case Node.COMMENT_NODE:continue;default:return!1}}return!0}},shadowHandler:{value:(()=>{let macroParser=null;return function(code){const shadowStore=Object.create(null);return macroParser||function(){if(!macroParser&&(macroParser=Wikifier.Parser.get(\"macro\"),!macroParser))throw new Error('cannot find \"macro\" parser')}(),macroParser.context&¯oParser.context.shadowView.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;shadowStore[varName]=store[varKey]})),function(){const shadowNames=Object.keys(shadowStore),valueCache=shadowNames.length>0?{}:null;try{return shadowNames.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;Object.hasOwn(store,varKey)&&(valueCache[varKey]=store[varKey]),store[varKey]=shadowStore[varName]})),Scripting.evalJavaScript(code)}finally{shadowNames.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;shadowStore[varName]=store[varKey],Object.hasOwn(valueCache,varKey)?store[varKey]=valueCache[varKey]:delete store[varKey]}))}}}})()},parseSquareBracketedMarkup:{value:(()=>{const Item=Lexer.enumFromNames([\"Error\",\"DelimLTR\",\"DelimRTL\",\"InnerMeta\",\"ImageMeta\",\"LinkMeta\",\"Link\",\"RightMeta\",\"Setter\",\"Source\",\"Text\"]),Delim=Lexer.enumFromNames([\"None\",\"LTR\",\"RTL\"]);function slurpQuote(lexer,endQuote){loop:for(;;)switch(lexer.next()){case\"\\\\\":{const ch=lexer.next();if(ch!==EOF&&\"\\n\"!==ch)break}case EOF:case\"\\n\":return EOF;case endQuote:break loop}return lexer.pos}function lexLeftMeta(lexer){if(!lexer.accept(\"[\"))return lexer.error(Item.Error,\"malformed square-bracketed markup\");if(lexer.accept(\"[\"))lexer.data.isLink=!0,lexer.emit(Item.LinkMeta);else{if(lexer.accept(\"<>\"),!(lexer.accept(\"Ii\")&&lexer.accept(\"Mm\")&&lexer.accept(\"Gg\")&&lexer.accept(\"[\")))return lexer.error(Item.Error,\"malformed square-bracketed markup\");lexer.data.isLink=!1,lexer.emit(Item.ImageMeta)}return lexer.depth=2,lexCoreComponents}function lexCoreComponents(lexer){const what=lexer.data.isLink?\"link\":\"image\";let delim=Delim.None;for(;;)switch(lexer.next()){case EOF:case\"\\n\":return lexer.error(Item.Error,`unterminated ${what} markup`);case'\"':if(slurpQuote(lexer,'\"')===EOF)return lexer.error(Item.Error,`unterminated double quoted string in ${what} markup`);break;case\"|\":delim===Delim.None&&(delim=Delim.LTR,lexer.backup(),lexer.emit(Item.Text),lexer.forward(),lexer.emit(Item.DelimLTR));break;case\"-\":delim===Delim.None&&\">\"===lexer.peek()&&(delim=Delim.LTR,lexer.backup(),lexer.emit(Item.Text),lexer.forward(2),lexer.emit(Item.DelimLTR));break;case\"<\":delim===Delim.None&&\"-\"===lexer.peek()&&(delim=Delim.RTL,lexer.backup(),lexer.emit(lexer.data.isLink?Item.Link:Item.Source),lexer.forward(2),lexer.emit(Item.DelimRTL));break;case\"[\":++lexer.depth;break;case\"]\":if(--lexer.depth,1===lexer.depth)switch(lexer.peek()){case\"[\":return++lexer.depth,lexer.backup(),delim===Delim.RTL?lexer.emit(Item.Text):lexer.emit(lexer.data.isLink?Item.Link:Item.Source),lexer.forward(2),lexer.emit(Item.InnerMeta),lexer.data.isLink?lexSetter:lexImageLink;case\"]\":return--lexer.depth,lexer.backup(),delim===Delim.RTL?lexer.emit(Item.Text):lexer.emit(lexer.data.isLink?Item.Link:Item.Source),lexer.forward(2),lexer.emit(Item.RightMeta),null;default:return lexer.error(Item.Error,`malformed ${what} markup`)}}}function lexImageLink(lexer){const what=lexer.data.isLink?\"link\":\"image\";for(;;)switch(lexer.next()){case EOF:case\"\\n\":return lexer.error(Item.Error,`unterminated ${what} markup`);case'\"':if(slurpQuote(lexer,'\"')===EOF)return lexer.error(Item.Error,`unterminated double quoted string in ${what} markup link component`);break;case\"[\":++lexer.depth;break;case\"]\":if(--lexer.depth,1===lexer.depth)switch(lexer.peek()){case\"[\":return++lexer.depth,lexer.backup(),lexer.emit(Item.Link),lexer.forward(2),lexer.emit(Item.InnerMeta),lexSetter;case\"]\":return--lexer.depth,lexer.backup(),lexer.emit(Item.Link),lexer.forward(2),lexer.emit(Item.RightMeta),null;default:return lexer.error(Item.Error,`malformed ${what} markup`)}}}function lexSetter(lexer){const what=lexer.data.isLink?\"link\":\"image\";for(;;)switch(lexer.next()){case EOF:case\"\\n\":return lexer.error(Item.Error,`unterminated ${what} markup`);case'\"':if(slurpQuote(lexer,'\"')===EOF)return lexer.error(Item.Error,`unterminated double quoted string in ${what} markup setter component`);break;case\"'\":if(slurpQuote(lexer,\"'\")===EOF)return lexer.error(Item.Error,`unterminated single quoted string in ${what} markup setter component`);break;case\"[\":++lexer.depth;break;case\"]\":if(--lexer.depth,1===lexer.depth)return\"]\"!==lexer.peek()?lexer.error(Item.Error,`malformed ${what} markup`):(--lexer.depth,lexer.backup(),lexer.emit(Item.Setter),lexer.forward(2),lexer.emit(Item.RightMeta),null)}}return function(w){const lexer=new Lexer(w.source,lexLeftMeta);lexer.start=lexer.pos=w.matchStart;const markup={},items=lexer.run(),last=items.last();return last&&last.type===Item.Error?markup.error=last.message:items.forEach((item=>{const text=item.text.trim();switch(item.type){case Item.ImageMeta:markup.isImage=!0,\"<\"===text[1]?markup.align=\"left\":\">\"===text[1]&&(markup.align=\"right\");break;case Item.LinkMeta:markup.isLink=!0;break;case Item.Link:\"~\"===text[0]?(markup.forceInternal=!0,markup.link=text.slice(1)):markup.link=text;break;case Item.Setter:markup.setter=text;break;case Item.Source:markup.source=text;break;case Item.Text:markup.text=text}})),markup.pos=lexer.pos,markup}})()}}),Wikifier})();(()=>{function _verbatimTagHandler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);match&&match.index===w.matchStart&&(w.nextMatch=this.lookahead.lastIndex,jQuery(document.createDocumentFragment()).append(match[1]).appendTo(w.output))}Wikifier.Parser.add({name:\"quoteByBlock\",profiles:[\"block\"],match:\"^<<<\\\\n\",terminator:\"^<<<\\\\n\",handler(w){Wikifier.helpers.hasBlockContext(w.output.childNodes)?w.subWikify(jQuery(document.createElement(\"blockquote\")).appendTo(w.output).get(0),this.terminator):jQuery(w.output).append(document.createTextNode(w.matchText))}}),Wikifier.Parser.add({name:\"quoteByLine\",profiles:[\"block\"],match:\"^>+\",lookahead:/^>+/gm,terminator:\"\\\\n\",handler(w){if(!Wikifier.helpers.hasBlockContext(w.output.childNodes))return void jQuery(w.output).append(document.createTextNode(w.matchText));const destStack=[w.output];let matched,i,curLevel=0,newLevel=w.matchLength;do{if(newLevel>curLevel)for(i=curLevel;i<newLevel;++i)destStack.push(jQuery(document.createElement(\"blockquote\")).appendTo(destStack[destStack.length-1]).get(0));else if(newLevel<curLevel)for(i=curLevel;i>newLevel;--i)destStack.pop();curLevel=newLevel,w.subWikify(destStack[destStack.length-1],this.terminator),jQuery(document.createElement(\"br\")).appendTo(destStack[destStack.length-1]),this.lookahead.lastIndex=w.nextMatch;const match=this.lookahead.exec(w.source);matched=match&&match.index===w.nextMatch,matched&&(newLevel=match[0].length,w.nextMatch+=match[0].length)}while(matched)}}),Wikifier.Parser.add({name:\"macro\",profiles:[\"core\"],match:\"<<\",lookahead:new RegExp(`<<(/?${Patterns.macroName})(?:\\\\s*)((?:(?:/\\\\*[^*]*\\\\*+(?:[^/*][^*]*\\\\*+)*/)|(?://.*\\\\n)|(?:\\`(?:\\\\\\\\.|[^\\`\\\\\\\\])*\\`)|(?:\"(?:\\\\\\\\.|[^\"\\\\\\\\])*\")|(?:'(?:\\\\\\\\.|[^'\\\\\\\\])*')|(?:\\\\[(?:[<>]?[Ii][Mm][Gg])?\\\\[[^\\\\r\\\\n]*?\\\\]\\\\]+)|[^>]|(?:>(?!>)))*)>>`,\"gm\"),working:{source:\"\",name:\"\",arguments:\"\",index:0},context:null,handler(w){const matchStart=this.lookahead.lastIndex=w.matchStart;if(this.parseTag(w)){const nextMatch=w.nextMatch,name=this.working.name,rawArgs=this.working.arguments;let macro;try{if(macro=Macro.get(name),!macro){if(Macro.tags.has(name)){const tags=Macro.tags.get(name);return appendError(w.output,`child tag <<${name}>> was found outside of a call to its parent macro${1===tags.length?\"\":\"s\"} <<${tags.join(\">>, <<\")}>>`,w.source.slice(matchStart,w.nextMatch))}return appendError(w.output,`macro <<${name}>> does not exist`,w.source.slice(matchStart,w.nextMatch))}{let payload=null;if(void 0!==macro.tags&&(payload=this.parseBody(w,macro),!payload))return w.nextMatch=nextMatch,appendError(w.output,`cannot find a closing tag for macro <<${name}>>`,`${w.source.slice(matchStart,w.nextMatch)}…`);if(\"function\"!=typeof macro.handler)return appendError(w.output,`macro <<${name}>> handler function ${void 0===macro.handler?\"does not exist\":\"is not a function\"}`,w.source.slice(matchStart,w.nextMatch));{const args=payload?payload[0].args:this.createArgs(rawArgs,this.skipArgs(macro,macro.name));if(void 0!==macro._MACRO_API){this.context=new MacroContext({macro:macro,name:name,args:args,payload:payload,source:w.source.slice(matchStart,w.nextMatch),parent:this.context,parser:w});try{macro.handler.call(this.context)}finally{this.context=this.context.parent}}else{console.warn(`[DEPRECATED] The legacy macro API, used by <<${name}>>, is deprecated.`);const prevRawArgs=w._rawArgs;w._rawArgs=rawArgs;try{macro.handler(w.output,name,args,w,payload)}finally{w._rawArgs=prevRawArgs}}}}}catch(ex){return appendError(w.output,`cannot execute ${macro&¯o.isWidget?\"widget\":\"macro\"} <<${name}>>: ${ex.message}`,w.source.slice(matchStart,w.nextMatch))}finally{this.working.source=\"\",this.working.name=\"\",this.working.arguments=\"\",this.working.index=0}}else w.outputText(w.output,w.matchStart,w.nextMatch)},parseTag(w){const match=this.lookahead.exec(w.source);return!(!match||match.index!==w.matchStart||!match[1])&&(w.nextMatch=this.lookahead.lastIndex,this.working.source=w.source.slice(match.index,this.lookahead.lastIndex),this.working.name=match[1],this.working.arguments=match[2],this.working.index=match.index,!0)},parseBody(w,macro){const openTag=this.working.name,closeTag=`/${openTag}`,closeAlt=`end${openTag}`,bodyTags=!!Array.isArray(macro.tags)&¯o.tags,payload=[];let end=-1,opened=1,curSource=this.working.source,curTag=this.working.name,curArgument=this.working.arguments,contentStart=w.nextMatch;for(;-1!==(w.matchStart=w.source.indexOf(this.match,w.nextMatch));){if(!this.parseTag(w)){this.lookahead.lastIndex=w.nextMatch=w.matchStart+this.match.length;continue}const tagSource=this.working.source,tagName=this.working.name,tagArgs=this.working.arguments,tagBegin=this.working.index,tagEnd=w.nextMatch,hasArgs=\"\"!==tagArgs.trim();switch(tagName){case openTag:++opened;break;case closeAlt:case closeTag:if(hasArgs)throw w.nextMatch=tagBegin+2+tagName.length,new Error(`malformed closing tag: \"${tagSource}\"`);--opened;break;default:if(hasArgs&&(tagName.startsWith(\"/\")||tagName.startsWith(\"end\"))){this.lookahead.lastIndex=w.nextMatch=tagBegin+2+tagName.length;continue}if(1===opened&&bodyTags)for(let i=0,iend=bodyTags.length;i<iend;++i)tagName===bodyTags[i]&&(payload.push({source:curSource,name:curTag,arguments:curArgument,args:this.createArgs(curArgument,this.skipArgs(macro,curTag)),contents:w.source.slice(contentStart,tagBegin)}),curSource=tagSource,curTag=tagName,curArgument=tagArgs,contentStart=tagEnd)}if(0===opened){payload.push({source:curSource,name:curTag,arguments:curArgument,args:this.createArgs(curArgument,this.skipArgs(macro,curTag)),contents:w.source.slice(contentStart,tagBegin)}),end=tagEnd;break}}return-1!==end?(w.nextMatch=end,payload):null},createArgs(rawArgsString,skipArgs){const args=skipArgs?[]:this.parseArgs(rawArgsString);return Object.defineProperties(args,{raw:{value:rawArgsString},full:{value:Scripting.desugar(rawArgsString)}}),args},skipArgs(macro,tagName){if(void 0!==macro.skipArgs){const sa=macro.skipArgs;return\"boolean\"==typeof sa&&sa||Array.isArray(sa)&&sa.includes(tagName)}return void 0!==macro.skipArg0&&(macro.skipArg0&¯o.name===tagName)},parseArgs:(()=>{const Item=Lexer.enumFromNames([\"Error\",\"Bareword\",\"Expression\",\"String\",\"SquareBracket\"]),spaceRe=new RegExp(Patterns.space),notSpaceRe=new RegExp(Patterns.notSpace),varTest=new RegExp(`^${Patterns.variable}`);function slurpQuote(lexer,endQuote){loop:for(;;)switch(lexer.next()){case\"\\\\\":{const ch=lexer.next();if(ch!==EOF&&\"\\n\"!==ch)break}case EOF:case\"\\n\":return EOF;case endQuote:break loop}return lexer.pos}function lexSpace(lexer){const offset=lexer.source.slice(lexer.pos).search(notSpaceRe);if(offset===EOF)return null;switch(0!==offset&&(lexer.pos+=offset,lexer.ignore()),lexer.next()){case\"`\":return lexExpression;case'\"':return lexDoubleQuote;case\"'\":return lexSingleQuote;case\"[\":return lexSquareBracket;default:return lexBareword}}function lexExpression(lexer){return slurpQuote(lexer,\"`\")===EOF?lexer.error(Item.Error,\"unterminated backquote expression\"):(lexer.emit(Item.Expression),lexSpace)}function lexDoubleQuote(lexer){return slurpQuote(lexer,'\"')===EOF?lexer.error(Item.Error,\"unterminated double quoted string\"):(lexer.emit(Item.String),lexSpace)}function lexSingleQuote(lexer){return slurpQuote(lexer,\"'\")===EOF?lexer.error(Item.Error,\"unterminated single quoted string\"):(lexer.emit(Item.String),lexSpace)}function lexSquareBracket(lexer){let what;if(lexer.accept(\"<>IiMmGg\")?(what=\"image\",lexer.acceptRun(\"<>IiMmGg\")):what=\"link\",!lexer.accept(\"[\"))return lexer.error(Item.Error,`malformed ${what} markup`);lexer.depth=2;loop:for(;;)switch(lexer.next()){case\"\\\\\":{const ch=lexer.next();if(ch!==EOF&&\"\\n\"!==ch)break}case EOF:case\"\\n\":return lexer.error(Item.Error,`unterminated ${what} markup`);case\"[\":++lexer.depth;break;case\"]\":if(--lexer.depth,lexer.depth<0)return lexer.error(Item.Error,\"unexpected right square bracket ']'\");if(1===lexer.depth){if(\"]\"===lexer.next()){--lexer.depth;break loop}lexer.backup()}}return lexer.emit(Item.SquareBracket),lexSpace}function lexBareword(lexer){const offset=lexer.source.slice(lexer.pos).search(spaceRe);return lexer.pos=offset===EOF?lexer.source.length:lexer.pos+offset,lexer.emit(Item.Bareword),offset===EOF?null:lexSpace}return function(rawArgsString){const lexer=new Lexer(rawArgsString,lexSpace),args=[];return lexer.run().forEach((item=>{let arg=item.text;switch(item.type){case Item.Error:throw new Error(`unable to parse macro argument \"${arg}\": ${item.message}`);case Item.Bareword:if(varTest.test(arg))arg=State.getVar(arg);else if(/^(?:settings|setup)[.[]/.test(arg))try{arg=Scripting.evalTwineScript(arg)}catch(ex){throw new Error(`unable to parse macro argument \"${arg}\": ${ex.message}`)}else if(\"null\"===arg)arg=null;else if(\"undefined\"===arg)arg=undefined;else if(\"true\"===arg)arg=!0;else if(\"false\"===arg)arg=!1;else if(\"NaN\"===arg)arg=NaN;else{const argAsNum=Number(arg);Number.isNaN(argAsNum)||(arg=argAsNum)}break;case Item.Expression:if(arg=arg.slice(1,-1).trim(),\"\"===arg)arg=undefined;else try{arg=Scripting.evalTwineScript(`(${arg})`)}catch(ex){throw new Error(`unable to parse macro argument expression \"${arg}\": ${ex.message}`)}break;case Item.String:try{arg=Scripting.evalJavaScript(arg)}catch(ex){throw new Error(`unable to parse macro argument string \"${arg}\": ${ex.message}`)}break;case Item.SquareBracket:{const markup=Wikifier.helpers.parseSquareBracketedMarkup({source:arg,matchStart:0});if(Object.hasOwn(markup,\"error\"))throw new Error(`unable to parse macro argument \"${arg}\": ${markup.error}`);if(markup.pos<arg.length)throw new Error(`unable to parse macro argument \"${arg}\": unexpected character(s) \"${arg.slice(markup.pos)}\" (pos: ${markup.pos})`);markup.isLink?(arg={isLink:!0},arg.count=Object.hasOwn(markup,\"text\")?2:1,arg.link=Wikifier.helpers.evalPassageId(markup.link),arg.text=Object.hasOwn(markup,\"text\")?Wikifier.helpers.evalText(markup.text):arg.link,arg.external=!markup.forceInternal&&Wikifier.isExternalLink(arg.link),arg.setFn=Object.hasOwn(markup,\"setter\")?Wikifier.helpers.shadowHandler(Scripting.desugar(markup.setter)):null):markup.isImage&&(arg=(source=>{const imgObj={source:source,isImage:!0};if(\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);passage.tags.includes(\"Twine.image\")&&(imgObj.source=passage.text,imgObj.passage=passage.name)}return imgObj})(Wikifier.helpers.evalPassageId(markup.source)),Object.hasOwn(markup,\"align\")&&(arg.align=markup.align),Object.hasOwn(markup,\"text\")&&(arg.title=Wikifier.helpers.evalText(markup.text)),Object.hasOwn(markup,\"link\")&&(arg.link=Wikifier.helpers.evalPassageId(markup.link),arg.external=!markup.forceInternal&&Wikifier.isExternalLink(arg.link)),arg.setFn=Object.hasOwn(markup,\"setter\")?Wikifier.helpers.shadowHandler(Scripting.desugar(markup.setter)):null);break}}args.push(arg)})),args}})()}),Wikifier.Parser.add({name:\"link\",profiles:[\"core\"],match:\"\\\\[\\\\[[^[]\",handler(w){const markup=Wikifier.helpers.parseSquareBracketedMarkup(w);if(Object.hasOwn(markup,\"error\"))return void w.outputText(w.output,w.matchStart,w.nextMatch);w.nextMatch=markup.pos;const link=Wikifier.helpers.evalPassageId(markup.link),text=Object.hasOwn(markup,\"text\")?Wikifier.helpers.evalText(markup.text):link,setFn=Object.hasOwn(markup,\"setter\")?Wikifier.helpers.shadowHandler(Scripting.desugar(markup.setter)):null,output=(Config.debug?new DebugView(w.output,\"link-markup\",\"[[link]]\",w.source.slice(w.matchStart,w.nextMatch)):w).output;markup.forceInternal||!Wikifier.isExternalLink(link)?Wikifier.createInternalLink(output,link,text,setFn):Wikifier.createExternalLink(output,link,text)}}),Wikifier.Parser.add({name:\"urlLink\",profiles:[\"core\"],match:Patterns.url,handler(w){w.outputText(Wikifier.createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch)}}),Wikifier.Parser.add({name:\"image\",profiles:[\"core\"],match:\"\\\\[[<>]?[Ii][Mm][Gg]\\\\[\",handler(w){const markup=Wikifier.helpers.parseSquareBracketedMarkup(w);if(Object.hasOwn(markup,\"error\"))return void w.outputText(w.output,w.matchStart,w.nextMatch);let debugView;w.nextMatch=markup.pos,Config.debug&&(debugView=new DebugView(w.output,\"image-markup\",Object.hasOwn(markup,\"link\")?\"[img[][link]]\":\"[img[]]\",w.source.slice(w.matchStart,w.nextMatch)),debugView.modes({block:!0}));const setFn=Object.hasOwn(markup,\"setter\")?Wikifier.helpers.shadowHandler(Scripting.desugar(markup.setter)):null;let source,el=(Config.debug?debugView:w).output;if(Object.hasOwn(markup,\"link\")){const link=Wikifier.helpers.evalPassageId(markup.link);el=markup.forceInternal||!Wikifier.isExternalLink(link)?Wikifier.createInternalLink(el,link,null,setFn):Wikifier.createExternalLink(el,link),el.classList.add(\"link-image\")}if(el=jQuery(document.createElement(\"img\")).appendTo(el).get(0),source=Wikifier.helpers.evalPassageId(markup.source),\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);passage.tags.includes(\"Twine.image\")&&(el.setAttribute(\"data-passage\",passage.name),source=passage.text.trim())}el.src=source,Object.hasOwn(markup,\"text\")&&(el.title=Wikifier.helpers.evalText(markup.text)),Object.hasOwn(markup,\"align\")&&(el.align=markup.align)}}),Wikifier.Parser.add({name:\"monospacedByBlock\",profiles:[\"block\"],match:\"^\\\\{\\\\{\\\\{\\\\n\",lookahead:/^\\{\\{\\{\\n((?:^[^\\n]*\\n)+?)(^\\}\\}\\}$\\n?)/gm,handler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);if(match&&match.index===w.matchStart){const pre=jQuery(document.createElement(\"pre\"));jQuery(document.createElement(\"code\")).text(match[1]).appendTo(pre),pre.appendTo(w.output),w.nextMatch=this.lookahead.lastIndex}}}),Wikifier.Parser.add({name:\"formatByChar\",profiles:[\"core\"],match:\"''|//|__|\\\\^\\\\^|~~|==|\\\\{\\\\{\\\\{\",handler(w){switch(w.matchText){case\"''\":w.subWikify(jQuery(document.createElement(\"strong\")).appendTo(w.output).get(0),\"''\");break;case\"//\":w.subWikify(jQuery(document.createElement(\"em\")).appendTo(w.output).get(0),\"//\");break;case\"__\":w.subWikify(jQuery(document.createElement(\"u\")).appendTo(w.output).get(0),\"__\");break;case\"^^\":w.subWikify(jQuery(document.createElement(\"sup\")).appendTo(w.output).get(0),\"\\\\^\\\\^\");break;case\"~~\":w.subWikify(jQuery(document.createElement(\"sub\")).appendTo(w.output).get(0),\"~~\");break;case\"==\":w.subWikify(jQuery(document.createElement(\"s\")).appendTo(w.output).get(0),\"==\");break;case\"{{{\":{const lookahead=/\\{\\{\\{((?:.|\\n)*?)\\}\\}\\}/gm;lookahead.lastIndex=w.matchStart;const match=lookahead.exec(w.source);match&&match.index===w.matchStart&&(jQuery(document.createElement(\"code\")).text(match[1]).appendTo(w.output),w.nextMatch=lookahead.lastIndex);break}}}}),Wikifier.Parser.add({name:\"customStyle\",profiles:[\"core\"],match:\"@@\",terminator:\"@@\",blockRe:/\\s*\\n/gm,handler(w){const css=Wikifier.helpers.inlineCss(w);this.blockRe.lastIndex=w.nextMatch;const blockMatch=this.blockRe.exec(w.source),blockLevel=blockMatch&&blockMatch.index===w.nextMatch,$el=jQuery(document.createElement(blockLevel?\"div\":\"span\")).appendTo(w.output);0===css.classes.length&&\"\"===css.id&&0===Object.keys(css.styles).length?$el.addClass(\"marked\"):(css.classes.forEach((className=>$el.addClass(className))),\"\"!==css.id&&$el.attr(\"id\",css.id),$el.css(css.styles)),blockLevel?(w.nextMatch+=blockMatch[0].length,w.subWikify($el[0],`\\\\n?${this.terminator}`)):w.subWikify($el[0],this.terminator)}}),Wikifier.Parser.add({name:\"verbatimText\",profiles:[\"core\"],match:'\"{3}|<[Nn][Oo][Ww][Ii][Kk][Ii]>',lookahead:/(?:\"{3}((?:.|\\n)*?)\"{3})|(?:<[Nn][Oo][Ww][Ii][Kk][Ii]>((?:.|\\n)*?)<\\/[Nn][Oo][Ww][Ii][Kk][Ii]>)/gm,handler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);match&&match.index===w.matchStart&&(w.nextMatch=this.lookahead.lastIndex,jQuery(document.createElement(\"span\")).addClass(\"verbatim\").text(match[1]||match[2]).appendTo(w.output))}}),Wikifier.Parser.add({name:\"horizontalRule\",profiles:[\"core\"],match:\"^----+\\\\s*$\",handler(w){jQuery(document.createElement(\"hr\")).appendTo(w.output)}}),Wikifier.Parser.add({name:\"emdash\",profiles:[\"core\"],match:\"--\",handler(w){jQuery(document.createTextNode(\"—\")).appendTo(w.output)}}),Wikifier.Parser.add({name:\"doubleDollarSign\",profiles:[\"core\"],match:\"\\\\${2}\",handler(w){jQuery(document.createTextNode(\"$\")).appendTo(w.output)}}),Wikifier.Parser.add({name:\"nakedVariable\",profiles:[\"core\"],match:`${Patterns.variable}(?:(?:\\\\.${Patterns.identifier})|(?:\\\\[\\\\d+\\\\])|(?:\\\\[\"(?:\\\\\\\\.|[^\"\\\\\\\\])+\"\\\\])|(?:\\\\['(?:\\\\\\\\.|[^'\\\\\\\\])+'\\\\])|(?:\\\\[${Patterns.variable}\\\\]))*`,handler(w){const result=State.getVar(w.matchText);null==result?jQuery(document.createTextNode(w.matchText)).appendTo(w.output):new Wikifier((Config.debug?new DebugView(w.output,\"variable\",w.matchText,w.matchText):w).output,stringFrom(result))}}),Wikifier.Parser.add({name:\"template\",profiles:[\"core\"],match:`\\\\?${Patterns.templateName}`,handler(w){const name=w.matchText.slice(1);let template=Template.get(name),result=null;switch(template instanceof Array&&(template=template.random()),typeof template){case\"function\":try{result=stringFrom(template.call({name:name}))}catch(ex){return appendError(w.output,`cannot execute function template ?${name}: ${ex.message}`,w.source.slice(w.matchStart,w.nextMatch))}break;case\"string\":result=template}null===result?jQuery(document.createTextNode(w.matchText)).appendTo(w.output):new Wikifier((Config.debug?new DebugView(w.output,\"template\",w.matchText,w.matchText):w).output,result)}}),Wikifier.Parser.add({name:\"heading\",profiles:[\"block\"],match:\"^!{1,6}\",terminator:\"\\\\n\",handler(w){Wikifier.helpers.hasBlockContext(w.output.childNodes)?w.subWikify(jQuery(document.createElement(`h${w.matchLength}`)).appendTo(w.output).get(0),this.terminator):jQuery(w.output).append(document.createTextNode(w.matchText))}}),Wikifier.Parser.add({name:\"table\",profiles:[\"block\"],match:\"^\\\\|(?:[^\\\\n]*)\\\\|(?:[fhck]?)$\",lookahead:/^\\|([^\\n]*)\\|([fhck]?)$/gm,rowTerminator:\"\\\\|(?:[cfhk]?)$\\\\n?\",cellPattern:\"(?:\\\\|([^\\\\n\\\\|]*)\\\\|)|(\\\\|[cfhk]?$\\\\n?)\",cellTerminator:\"(?:\\\\u0020*)\\\\|\",rowTypes:{c:\"caption\",f:\"tfoot\",h:\"thead\",\"\":\"tbody\"},handler(w){if(!Wikifier.helpers.hasBlockContext(w.output.childNodes))return void jQuery(w.output).append(document.createTextNode(w.matchText));const table=jQuery(document.createElement(\"table\")).appendTo(w.output).get(0),prevColumns=[];let matched,curRowType=null,$rowContainer=null,rowCount=0;w.nextMatch=w.matchStart;do{this.lookahead.lastIndex=w.nextMatch;const match=this.lookahead.exec(w.source);if(matched=match&&match.index===w.nextMatch,matched){const nextRowType=match[2];\"k\"===nextRowType?(table.className=match[1],w.nextMatch+=match[0].length+1):(nextRowType!==curRowType&&(curRowType=nextRowType,$rowContainer=jQuery(document.createElement(this.rowTypes[nextRowType])).appendTo(table)),\"c\"===curRowType?($rowContainer.css(\"caption-side\",0===rowCount?\"top\":\"bottom\"),w.nextMatch+=1,w.subWikify($rowContainer[0],this.rowTerminator)):this.rowHandler(w,jQuery(document.createElement(\"tr\")).appendTo($rowContainer).get(0),prevColumns),++rowCount)}}while(matched)},rowHandler(w,rowEl,prevColumns){const cellRe=new RegExp(this.cellPattern,\"gm\");let matched,col=0,curColCount=1;do{cellRe.lastIndex=w.nextMatch;const cellMatch=cellRe.exec(w.source);if(matched=cellMatch&&cellMatch.index===w.nextMatch,matched){if(\"~\"===cellMatch[1]){const last=prevColumns[col];last&&(++last.rowCount,last.$element.attr(\"rowspan\",last.rowCount).css(\"vertical-align\",\"middle\")),w.nextMatch=cellMatch.index+cellMatch[0].length-1}else if(\">\"===cellMatch[1])++curColCount,w.nextMatch=cellMatch.index+cellMatch[0].length-1;else{if(cellMatch[2]){w.nextMatch=cellMatch.index+cellMatch[0].length;break}{++w.nextMatch;const css=Wikifier.helpers.inlineCss(w);let $cell,spaceLeft=!1,spaceRight=!1;for(;\" \"===w.source.substr(w.nextMatch,1);)spaceLeft=!0,++w.nextMatch;\"!\"===w.source.substr(w.nextMatch,1)?($cell=jQuery(document.createElement(\"th\")).appendTo(rowEl),++w.nextMatch):$cell=jQuery(document.createElement(\"td\")).appendTo(rowEl),prevColumns[col]={rowCount:1,$element:$cell},curColCount>1&&($cell.attr(\"colspan\",curColCount),curColCount=1),w.subWikify($cell[0],this.cellTerminator),\" \"===w.matchText.substr(w.matchText.length-2,1)&&(spaceRight=!0),css.classes.forEach((className=>$cell.addClass(className))),\"\"!==css.id&&$cell.attr(\"id\",css.id),spaceLeft&&spaceRight?css.styles[\"text-align\"]=\"center\":spaceLeft?css.styles[\"text-align\"]=\"right\":spaceRight&&(css.styles[\"text-align\"]=\"left\"),$cell.css(css.styles),w.nextMatch=w.nextMatch-1}}++col}}while(matched)}}),Wikifier.Parser.add({name:\"list\",profiles:[\"block\"],match:\"^(?:(?:\\\\*+)|(?:#+))\",lookahead:/^(?:(\\*+)|(#+))/gm,terminator:\"\\\\n\",handler(w){if(!Wikifier.helpers.hasBlockContext(w.output.childNodes))return void jQuery(w.output).append(document.createTextNode(w.matchText));w.nextMatch=w.matchStart;const destStack=[w.output];let matched,i,curType=null,curLevel=0;do{this.lookahead.lastIndex=w.nextMatch;const match=this.lookahead.exec(w.source);if(matched=match&&match.index===w.nextMatch,matched){const newType=match[2]?\"ol\":\"ul\",newLevel=match[0].length;if(w.nextMatch+=match[0].length,newLevel>curLevel)for(i=curLevel;i<newLevel;++i)destStack.push(jQuery(document.createElement(newType)).appendTo(destStack[destStack.length-1]).get(0));else if(newLevel<curLevel)for(i=curLevel;i>newLevel;--i)destStack.pop();else newLevel===curLevel&&newType!==curType&&(destStack.pop(),destStack.push(jQuery(document.createElement(newType)).appendTo(destStack[destStack.length-1]).get(0)));curLevel=newLevel,curType=newType,w.subWikify(jQuery(document.createElement(\"li\")).appendTo(destStack[destStack.length-1]).get(0),this.terminator)}}while(matched)}}),Wikifier.Parser.add({name:\"commentByBlock\",profiles:[\"core\"],match:\"(?:/(?:%|\\\\*))|(?:\\x3c!--)\",lookahead:/(?:\\/(%|\\*)(?:(?:.|\\n)*?)\\1\\/)|(?:<!--(?:(?:.|\\n)*?)-->)/gm,handler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);match&&match.index===w.matchStart&&(w.nextMatch=this.lookahead.lastIndex)}}),Wikifier.Parser.add({name:\"lineContinuation\",profiles:[\"core\"],match:`\\\\\\\\${Patterns.spaceNoTerminator}*\\\\n|\\\\n${Patterns.spaceNoTerminator}*\\\\\\\\|\\\\n?\\\\\\\\${Patterns.spaceNoTerminator}*$|^${Patterns.spaceNoTerminator}*\\\\\\\\\\\\n?`,handler(w){w.nextMatch=w.matchStart+w.matchLength}}),Wikifier.Parser.add({name:\"lineBreak\",profiles:[\"core\"],match:\"\\\\n\",handler(w){w.options.nobr||jQuery(document.createElement(\"br\")).appendTo(w.output)}}),Wikifier.Parser.add({name:\"htmlCharacterReference\",profiles:[\"core\"],match:\"(?:(?:&#?[0-9A-Za-z]{2,8};|.)(?:&#?(?:x0*(?:3[0-6][0-9A-Fa-f]|1D[C-Fc-f][0-9A-Fa-f]|20[D-Fd-f][0-9A-Fa-f]|FE2[0-9A-Fa-f])|0*(?:76[89]|7[7-9][0-9]|8[0-7][0-9]|761[6-9]|76[2-7][0-9]|84[0-3][0-9]|844[0-7]|6505[6-9]|6506[0-9]|6507[0-1]));)+|&#?[0-9A-Za-z]{2,8};)\",handler(w){jQuery(document.createDocumentFragment()).append(w.matchText).appendTo(w.output)}}),Wikifier.Parser.add({name:\"xmlProlog\",profiles:[\"core\"],match:\"<\\\\?[Xx][Mm][Ll][^>]*\\\\?>\",handler(w){w.nextMatch=w.matchStart+w.matchLength}}),Wikifier.Parser.add({name:\"verbatimHtml\",profiles:[\"core\"],match:\"<[Hh][Tt][Mm][Ll]>\",lookahead:/<[Hh][Tt][Mm][Ll]>((?:.|\\n)*?)<\\/[Hh][Tt][Mm][Ll]>/gm,handler:_verbatimTagHandler}),Wikifier.Parser.add({name:\"verbatimScriptTag\",profiles:[\"core\"],match:\"<[Ss][Cc][Rr][Ii][Pp][Tt][^>]*>\",lookahead:/(<[Ss][Cc][Rr][Ii][Pp][Tt][^>]*>(?:.|\\n)*?<\\/[Ss][Cc][Rr][Ii][Pp][Tt]>)/gm,handler:_verbatimTagHandler}),Wikifier.Parser.add({name:\"styleTag\",profiles:[\"core\"],match:\"<[Ss][Tt][Yy][Ll][Ee][^>]*>\",lookahead:/(<[Ss][Tt][Yy][Ll][Ee][^>]*>)((?:.|\\n)*?)(<\\/[Ss][Tt][Yy][Ll][Ee]>)/gm,imageMarkup:new RegExp(Patterns.cssImage,\"g\"),hasImageMarkup:new RegExp(Patterns.cssImage),handler(w){this.lookahead.lastIndex=w.matchStart;const match=this.lookahead.exec(w.source);if(match&&match.index===w.matchStart){w.nextMatch=this.lookahead.lastIndex;let css=match[2];this.hasImageMarkup.test(css)&&(this.imageMarkup.lastIndex=0,css=css.replace(this.imageMarkup,(wikiImage=>{const markup=Wikifier.helpers.parseSquareBracketedMarkup({source:wikiImage,matchStart:0});if(Object.hasOwn(markup,\"error\")||markup.pos<wikiImage.length)return wikiImage;let source=Wikifier.helpers.evalPassageId(markup.source);if(\"data:\"!==source.slice(0,5)&&Story.has(source)){const passage=Story.get(source);passage.tags.includes(\"Twine.image\")&&(source=passage.text)}return`url(\"${source.replace(/\"/g,\"%22\")}\")`}))),jQuery(document.createDocumentFragment()).append(match[1]+css+match[3]).appendTo(w.output)}}}),Wikifier.Parser.add({name:\"svgTag\",profiles:[\"core\"],match:\"<[Ss][Vv][Gg][^>]*>\",lookahead:/<(\\/?)[Ss][Vv][Gg][^>]*>/gm,namespace:\"http://www.w3.org/2000/svg\",handler(w){this.lookahead.lastIndex=w.nextMatch;let match,depth=1;for(;depth>0&&null!==(match=this.lookahead.exec(w.source));)depth+=\"/\"===match[1]?-1:1;if(0===depth){w.nextMatch=this.lookahead.lastIndex;const svgTag=w.source.slice(w.matchStart,this.lookahead.lastIndex),$frag=jQuery(document.createDocumentFragment()).append(svgTag);$frag.find(\"a[data-passage],image[data-passage]\").each(((_,el)=>{const tagName=el.tagName.toLowerCase();try{this.processAttributeDirectives(el)}catch(ex){return appendError(w.output,`svg|<${tagName}>: ${ex.message}`,`${w.matchText}…`)}el.hasAttribute(\"data-passage\")&&this.processDataAttributes(el,tagName)})),$frag.appendTo(w.output)}},processAttributeDirectives(el){Array.from(el.attributes).forEach((({name:name,value:value})=>{const evalShorthand=\"@\"===name[0];if(evalShorthand||name.startsWith(\"sc-eval:\")){const newName=name.slice(evalShorthand?1:8);if(\"data-setter\"===newName)throw new Error(`evaluation directive is not allowed on the data-setter attribute: \"${name}\"`);let result;try{result=Scripting.evalTwineScript(value)}catch(ex){throw new Error(`bad evaluation from attribute directive \"${name}\": ${ex.message}`)}try{el.setAttribute(newName,result),el.removeAttribute(name)}catch(ex){throw new Error(`cannot transform attribute directive \"${name}\" into attribute \"${newName}\"`)}}}))},processDataAttributes(el,tagName){let passage=el.getAttribute(\"data-passage\");if(null==passage)return;const evaluated=Wikifier.helpers.evalPassageId(passage);if(evaluated!==passage&&(passage=evaluated,el.setAttribute(\"data-passage\",evaluated)),\"\"!==passage)if(\"image\"===tagName)\"data:\"!==passage.slice(0,5)&&Story.has(passage)&&(passage=Story.get(passage),passage.tags.includes(\"Twine.image\")&&el.setAttribute(\"href\",passage.text.trim()));else{let setFn,setter=el.getAttribute(\"data-setter\");null!=setter&&(setter=String(setter).trim(),\"\"!==setter&&(setFn=Wikifier.helpers.shadowHandler(Scripting.desugar(setter)))),Story.has(passage)?(el.classList.add(\"link-internal\"),Config.addVisitedLinkClass&&State.hasPlayed(passage)&&el.classList.add(\"link-visited\")):el.classList.add(\"link-broken\"),jQuery(el).ariaClick({one:!0},(function(){\"function\"==typeof setFn&&setFn.call(this),Engine.play(passage)}))}}}),Wikifier.Parser.add({name:\"htmlTag\",profiles:[\"core\"],match:`<${Patterns.htmlTagName}(?:\\\\s+[^\\\\u0000-\\\\u001F\\\\u007F-\\\\u009F\\\\s\"'>\\\\/=]+(?:\\\\s*=\\\\s*(?:\"[^\"]*?\"|'[^']*?'|[^\\\\s\"'=<>\\`]+))?)*\\\\s*\\\\/?>`,tagRe:new RegExp(`^<(${Patterns.htmlTagName})`),mediaTags:[\"audio\",\"img\",\"source\",\"track\",\"video\"],nobrTags:[\"audio\",\"colgroup\",\"datalist\",\"dl\",\"figure\",\"meter\",\"ol\",\"optgroup\",\"picture\",\"progress\",\"ruby\",\"select\",\"table\",\"tbody\",\"tfoot\",\"thead\",\"tr\",\"ul\",\"video\"],voidTags:[\"area\",\"base\",\"br\",\"col\",\"embed\",\"hr\",\"img\",\"input\",\"keygen\",\"link\",\"menuitem\",\"meta\",\"param\",\"source\",\"track\",\"wbr\"],handler(w){const tagMatch=this.tagRe.exec(w.matchText),tag=tagMatch&&tagMatch[1],tagName=tag&&tag.toLowerCase();if(tagName){const isVoid=this.voidTags.includes(tagName)||w.matchText.endsWith(\"/>\"),isNobr=this.nobrTags.includes(tagName);let terminator,terminatorMatch;if(!isVoid){terminator=`<\\\\/${tagName}\\\\s*>`;const terminatorRe=new RegExp(terminator,\"gim\");terminatorRe.lastIndex=w.matchStart,terminatorMatch=terminatorRe.exec(w.source)}if(!isVoid&&!terminatorMatch)return appendError(w.output,`cannot find a closing tag for HTML <${tag}>`,`${w.matchText}…`);{let debugView,output=w.output,el=document.createElement(w.output.tagName);for(el.innerHTML=w.matchText;el.firstChild;)el=el.firstChild;try{this.processAttributeDirectives(el)}catch(ex){return appendError(w.output,`<${tagName}>: ${ex.message}`,`${w.matchText}…`)}if(el.hasAttribute(\"data-passage\")){if(el.hasAttribute(\"href\"))return appendError(w.output,`<${tagName}>: elements may not include both \"data-passage\" and \"href\" atttributes`,`${w.matchText}…`);this.processDataAttributes(el,tagName),Config.debug&&(debugView=new DebugView(w.output,`html-${tagName}`,tagName,w.matchText),debugView.modes({block:\"img\"===tagName,nonvoid:terminatorMatch}),output=debugView.output)}else el.hasAttribute(\"href\")&&Wikifier.isExternalLink(el.getAttribute(\"href\"))&&el.classList.add(\"link-external\");if(terminatorMatch){try{Wikifier.Option.push({nobr:isNobr}),w.subWikify(el,terminator,{ignoreTerminatorCase:!0})}finally{Wikifier.Option.pop()}debugView&&jQuery(el).find(\".debug.block\").length>0&&debugView.modes({block:!0})}output.appendChild(\"track\"===tagName?el.cloneNode(!0):el)}}},processAttributeDirectives(el){Array.from(el.attributes).forEach((({name:name,value:value})=>{const evalShorthand=\"@\"===name[0];if(evalShorthand||name.startsWith(\"sc-eval:\")){const newName=name.slice(evalShorthand?1:8);if(\"data-setter\"===newName)throw new Error(`evaluation directive is not allowed on the data-setter attribute: \"${name}\"`);let result;try{result=Scripting.evalTwineScript(value)}catch(ex){throw new Error(`bad evaluation from attribute directive \"${name}\": ${ex.message}`)}try{el.setAttribute(newName,result),el.removeAttribute(name)}catch(ex){throw new Error(`cannot transform attribute directive \"${name}\" into attribute \"${newName}\"`)}}}))},processDataAttributes(el,tagName){let passage=el.getAttribute(\"data-passage\");if(null==passage)return;const evaluated=Wikifier.helpers.evalPassageId(passage);if(evaluated!==passage&&(passage=evaluated,el.setAttribute(\"data-passage\",evaluated)),\"\"!==passage)if(this.mediaTags.includes(tagName)){if(\"data:\"!==passage.slice(0,5)&&Story.has(passage)){let parentName,twineTag;switch(passage=Story.get(passage),tagName){case\"audio\":case\"video\":twineTag=`Twine.${tagName}`;break;case\"img\":twineTag=\"Twine.image\";break;case\"track\":twineTag=\"Twine.vtt\";break;case\"source\":{const $parent=$(el).closest(\"audio,picture,video\");$parent.length>0&&(parentName=$parent.get(0).tagName.toLowerCase(),twineTag=`Twine.${\"picture\"===parentName?\"image\":parentName}`);break}}passage.tags.includes(twineTag)&&(el[\"picture\"===parentName?\"srcset\":\"src\"]=passage.text.trim())}}else{let setFn,setter=el.getAttribute(\"data-setter\");null!=setter&&(setter=String(setter).trim(),\"\"!==setter&&(setFn=Wikifier.helpers.shadowHandler(Scripting.desugar(setter)))),Story.has(passage)?(el.classList.add(\"link-internal\"),Config.addVisitedLinkClass&&State.hasPlayed(passage)&&el.classList.add(\"link-visited\")):el.classList.add(\"link-broken\"),jQuery(el).ariaClick({one:!0},(function(){\"function\"==typeof setFn&&setFn.call(this),Engine.play(passage)}))}}})})();var Template=(()=>{const _templates=new Map,_validNameRe=new RegExp(`^(?:${Patterns.templateName})$`),_validType=template=>{const templateType=typeof template;return\"function\"===templateType||\"string\"===templateType};return Object.preventExtensions(Object.create(null,{add:{value:function(name,template){if(!(_validType(template)||template instanceof Array&&template.length>0&&template.every(_validType)))throw new TypeError(`invalid template type (${name}); templates must be: functions, strings, or an array of either`);(name instanceof Array?name:[name]).forEach((name=>{if(!_validNameRe.test(name))throw new Error(`invalid template name \"${name}\"`);if(_templates.has(name))throw new Error(`cannot clobber existing template ?${name}`);_templates.set(name,template)}))}},delete:{value:function(name){(name instanceof Array?name:[name]).forEach((name=>_templates.delete(name)))}},get:{value:function(name){return _templates.has(name)?_templates.get(name):null}},has:{value:function(name){return _templates.has(name)}},size:{get:function(){return _templates.size}}}))})(),Macro=(()=>{const _macros={},_tags={},_validNameRe=new RegExp(`^(?:${Patterns.macroName})$`);function macrosHas(name){return Object.hasOwn(_macros,name)}function tagsRegister(parent,bodyTags){if(!parent)throw new Error(\"no parent specified\");const allTags=[].concat([`/${parent}`,`end${parent}`],Array.isArray(bodyTags)?bodyTags:[]);for(let i=0;i<allTags.length;++i){const tag=allTags[i];if(macrosHas(tag))throw new Error(\"cannot register tag for an existing macro\");tagsHas(tag)?_tags[tag].includes(parent)||(_tags[tag].push(parent),_tags[tag].sort()):_tags[tag]=[parent]}}function tagsUnregister(parent){if(!parent)throw new Error(\"no parent specified\");Object.keys(_tags).forEach((tag=>{const i=_tags[tag].indexOf(parent);-1!==i&&(1===_tags[tag].length?delete _tags[tag]:_tags[tag].splice(i,1))}))}function tagsHas(name){return Object.hasOwn(_tags,name)}return Object.preventExtensions(Object.create(null,{add:{value:function macrosAdd(name,def){if(Array.isArray(name))name.forEach((name=>macrosAdd(name,def)));else{if(!_validNameRe.test(name))throw new Error(`invalid macro name \"${name}\"`);if(macrosHas(name))throw new Error(`cannot clobber existing macro <<${name}>>`);if(tagsHas(name))throw new Error(`cannot clobber child tag <<${name}>> of parent macro${1===_tags[name].length?\"\":\"s\"} <<${_tags[name].join(\">>, <<\")}>>`);try{if(\"object\"==typeof def)_macros[name]=Object.assign(Object.create(null),def,{_MACRO_API:!0});else{if(!macrosHas(def))throw new Error(`cannot create alias of nonexistent macro <<${def}>>`);_macros[name]=Object.create(_macros[def],{_ALIAS_OF:{enumerable:!0,value:def}})}Object.defineProperty(_macros,name,{writable:!1})}catch(ex){throw\"TypeError\"===ex.name?new Error(`cannot clobber protected macro <<${name}>>`):new Error(`unknown error when attempting to add macro <<${name}>>: [${ex.name}] ${ex.message}`)}if(void 0!==_macros[name].tags)if(null==_macros[name].tags)tagsRegister(name);else{if(!Array.isArray(_macros[name].tags))throw new Error(`bad value for \"tags\" property of macro <<${name}>>`);tagsRegister(name,_macros[name].tags)}}}},delete:{value:function macrosDelete(name){if(Array.isArray(name))name.forEach((name=>macrosDelete(name)));else if(macrosHas(name)){void 0!==_macros[name].tags&&tagsUnregister(name);try{Object.defineProperty(_macros,name,{writable:!0}),delete _macros[name]}catch(ex){throw new Error(`unknown error removing macro <<${name}>>: ${ex.message}`)}}else if(tagsHas(name))throw new Error(`cannot remove child tag <<${name}>> of parent macro <<${_tags[name]}>>`)}},isEmpty:{value:function(){return 0===Object.keys(_macros).length}},has:{value:macrosHas},get:{value:function(name){let macro=null;return macrosHas(name)&&\"function\"==typeof _macros[name].handler?macro=_macros[name]:Object.hasOwn(macros,name)&&\"function\"==typeof macros[name].handler&&(macro=macros[name]),macro}},init:{value:function(handler=\"init\"){Object.keys(_macros).forEach((name=>{\"function\"==typeof _macros[name][handler]&&_macros[name][handler](name)})),Object.keys(macros).forEach((name=>{\"function\"==typeof macros[name][handler]&¯os[name][handler](name)}))}},tags:{value:Object.preventExtensions(Object.create(null,{register:{value:tagsRegister},unregister:{value:tagsUnregister},has:{value:tagsHas},get:{value:function(name){return tagsHas(name)?_tags[name]:null}}}))},evalStatements:{value:(...args)=>Scripting.evalJavaScript(...args)}}))})(),MacroContext=(()=>{class MacroContext{constructor(contextData){const context=Object.assign({parent:null,macro:null,name:\"\",displayName:\"\",args:null,payload:null,parser:null,source:\"\"},contextData);if(null===context.macro||\"\"===context.name||null===context.parser)throw new TypeError(\"context object missing required properties\");Object.defineProperties(this,{self:{value:context.macro},name:{value:void 0===context.macro._ALIAS_OF?context.name:context.macro._ALIAS_OF},displayName:{value:context.name},args:{value:context.args},payload:{value:context.payload},source:{value:context.source},parent:{value:context.parent},parser:{value:context.parser},_output:{value:context.parser.output},_shadows:{writable:!0,value:null},_debugView:{writable:!0,value:null},_debugViewEnabled:{writable:!0,value:Config.debug}})}get output(){return this._debugViewEnabled?this.debugView.output:this._output}get shadows(){return Array.from(this._shadows)}get shadowView(){const view=new Set;for(let context=this;null!==context;context=context.parent)context._shadows&&context._shadows.forEach((name=>view.add(name)));return Array.from(view)}get debugView(){return this._debugViewEnabled?null!==this._debugView?this._debugView:this.createDebugView():null}contextFilter(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"<MacroContext>.contextFilter() predicate parameter must be a function\");const result=[];for(let context=this.parent;null!==context;context=context.parent)predicate.call(void 0===thisArg?this:thisArg,context)&&result.push(context);return result}contextFind(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"<MacroContext>.contextFind() predicate parameter must be a function\");for(let context=this.parent;null!==context;context=context.parent)if(predicate.call(void 0===thisArg?this:thisArg,context))return context}contextSome(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"<MacroContext>.contextSome() predicate parameter must be a function\");for(let context=this.parent;null!==context;context=context.parent)if(predicate.call(void 0===thisArg?this:thisArg,context))return!0;return!1}addShadow(...names){this._shadows||(this._shadows=new Set);const varRe=new RegExp(`^${Patterns.variable}$`);names.flat(1/0).forEach((name=>{if(\"string\"!=typeof name)throw new TypeError(\"variable name must be a string; type: \"+typeof name);if(!varRe.test(name))throw new Error(`invalid variable name \"${name}\"`);this._shadows.add(name)}))}shadowHandler(callback,doneCallback,startCallback){const shadowContext=this;let shadowStore;return\"function\"==typeof callback&&(shadowStore=Object.create(null),this.shadowView.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;shadowStore[varName]=store[varKey]}))),function(...args){if(\"function\"==typeof startCallback&&startCallback.apply(this,args),\"function\"==typeof callback){const shadowNames=Object.keys(shadowStore),valueCache=shadowNames.length>0?{}:null,macroParser=Wikifier.Parser.get(\"macro\");let contextCache;try{shadowNames.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;Object.hasOwn(store,varKey)&&(valueCache[varKey]=store[varKey]),store[varKey]=shadowStore[varName]})),contextCache=macroParser.context,macroParser.context=shadowContext,callback.apply(this,args)}finally{contextCache!==undefined&&(macroParser.context=contextCache),shadowNames.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;shadowStore[varName]=store[varKey],Object.hasOwn(valueCache,varKey)?store[varKey]=valueCache[varKey]:delete store[varKey]}))}}\"function\"==typeof doneCallback&&doneCallback.apply(this,args)}}createDebugView(name,title){return this._debugView=new DebugView(this._output,\"macro\",name||this.displayName,title||this.source),null!==this.payload&&this.payload.length>0&&this._debugView.modes({nonvoid:!0}),this._debugViewEnabled=!0,this._debugView}removeDebugView(){null!==this._debugView&&(this._debugView.remove(),this._debugView=null),this._debugViewEnabled=!1}error(message,source,stack){return appendError(this._output,`<<${this.displayName}>>: ${message}`,source||this.source,stack)}}return Object.defineProperties(MacroContext.prototype,{contextHas:{value(...args){return console.warn(\"[DEPRECATED] <MacroContext>.contextHas() is deprecated.\"),MacroContext.prototype.contextSome.apply(this,args)}},contextSelect:{value(...args){return console.warn(\"[DEPRECATED] <MacroContext>.contextSelect() is deprecated.\"),MacroContext.prototype.contextFind.apply(this,args)}},contextSelectAll:{value(...args){return console.warn(\"[DEPRECATED] <MacroContext>.contextSelectAll() is deprecated.\"),MacroContext.prototype.contextFilter.apply(this,args)}},createShadowWrapper:{value(...args){return console.warn(\"[DEPRECATED] <MacroContext>.createShadowWrapper() is deprecated.\"),MacroContext.prototype.shadowHandler.apply(this,args)}}}),MacroContext})();Macro.add([\"addclass\",\"toggleclass\"],{handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"selector\"),this.args.length<2&&errors.push(\"class names\"),this.error(`no ${errors.join(\" or \")} specified`)}const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);switch(this.name){case\"addclass\":$targets.addClass(this.args[1].trim());break;case\"toggleclass\":$targets.toggleClass(this.args[1].trim())}Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add([\"append\",\"prepend\",\"replace\"],{tags:null,t8nRe:/^(?:transition|t8n)$/,handler(){if(0===this.args.length)return this.error(\"no selector specified\");const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);if(\"\"!==this.payload[0].contents){let $insert;switch(this.args.length>1&&this.self.t8nRe.test(this.args[1])?($insert=jQuery(document.createElement(\"span\")),$insert.addClass(`macro-${this.name}-insert macro-${this.name}-in`),setTimeout((()=>$insert.removeClass(`macro-${this.name}-in`)),Engine.DOM_DELAY)):$insert=jQuery(document.createDocumentFragment()),$insert.wiki(this.payload[0].contents),this.name){case\"replace\":$targets.empty();case\"append\":$targets.append($insert);break;case\"prepend\":$targets.prepend($insert)}}else\"replace\"===this.name&&$targets.empty();Config.debug&&this.debugView.modes({hidden:!0})}}),(()=>{if(Has.audio){const errorOnePlaybackAction=(cur,prev)=>`only one playback action allowed per invocation, \"${cur}\" cannot be combined with \"${prev}\"`;Macro.add(\"audio\",{handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"track and/or group IDs\"),this.args.length<2&&errors.push(\"actions\"),this.error(`no ${errors.join(\" or \")} specified`)}let selected;try{selected=SimpleAudio.select(this.args[0])}catch(ex){return this.error(ex.message)}const args=this.args.slice(1);let action,fadeTo,loop,mute,passage,time,volume,fadeOver=5;for(;args.length>0;){const arg=args.shift();let raw;switch(arg){case\"load\":case\"pause\":case\"play\":case\"stop\":case\"unload\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=arg;break;case\"fadein\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=\"fade\",fadeTo=1;break;case\"fadeout\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=\"fade\",fadeTo=0;break;case\"fadeto\":if(action)return this.error(errorOnePlaybackAction(arg,action));if(0===args.length)return this.error(\"fadeto missing required level value\");if(action=\"fade\",raw=args.shift(),fadeTo=Number.parseFloat(raw),Number.isNaN(fadeTo)||!Number.isFinite(fadeTo))return this.error(`cannot parse fadeto: ${raw}`);break;case\"fadeoverto\":if(action)return this.error(errorOnePlaybackAction(arg,action));if(args.length<2){const errors=[];return args.length<1&&errors.push(\"seconds\"),args.length<2&&errors.push(\"level\"),this.error(`fadeoverto missing required ${errors.join(\" and \")} value${errors.length>1?\"s\":\"\"}`)}if(action=\"fade\",raw=args.shift(),fadeOver=Number.parseFloat(raw),Number.isNaN(fadeOver)||!Number.isFinite(fadeOver))return this.error(`cannot parse fadeoverto: ${raw}`);if(raw=args.shift(),fadeTo=Number.parseFloat(raw),Number.isNaN(fadeTo)||!Number.isFinite(fadeTo))return this.error(`cannot parse fadeoverto: ${raw}`);break;case\"volume\":if(0===args.length)return this.error(\"volume missing required level value\");if(raw=args.shift(),volume=Number.parseFloat(raw),Number.isNaN(volume)||!Number.isFinite(volume))return this.error(`cannot parse volume: ${raw}`);break;case\"mute\":case\"unmute\":mute=\"mute\"===arg;break;case\"time\":if(0===args.length)return this.error(\"time missing required seconds value\");if(raw=args.shift(),time=Number.parseFloat(raw),Number.isNaN(time)||!Number.isFinite(time))return this.error(`cannot parse time: ${raw}`);break;case\"loop\":case\"unloop\":loop=\"loop\"===arg;break;case\"goto\":if(0===args.length)return this.error(\"goto missing required passage title\");if(raw=args.shift(),passage=\"object\"==typeof raw?raw.link:raw,!Story.has(passage))return this.error(`passage \"${passage}\" does not exist`);break;default:return this.error(`unknown action: ${arg}`)}}try{if(null!=volume&&selected.volume(volume),null!=time&&selected.time(time),null!=mute&&selected.mute(mute),null!=loop&&selected.loop(loop),null!=passage){const nsEnded=`ended.macros.macro-${this.name}_goto`;selected.off(nsEnded).one(nsEnded,(()=>{selected.off(nsEnded),Engine.play(passage)}))}switch(action){case\"fade\":selected.fade(fadeOver,fadeTo);break;case\"load\":selected.load();break;case\"pause\":selected.pause();break;case\"play\":selected.playWhenAllowed();break;case\"stop\":selected.stop();break;case\"unload\":selected.unload()}Config.debug&&this.debugView.modes({hidden:!0})}catch(ex){return this.error(`error executing action: ${ex.message}`)}}}),Macro.add(\"cacheaudio\",{handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"track ID\"),this.args.length<2&&errors.push(\"sources\"),this.error(`no ${errors.join(\" or \")} specified`)}const id=String(this.args[0]).trim();try{SimpleAudio.tracks.add(id,this.args.slice(1))}catch(ex){return this.error(ex.message)}if(Config.debug&&!SimpleAudio.tracks.get(id).hasSource())return this.error(`track ID \"${id}\": no supported audio sources found`);Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"createaudiogroup\",{tags:[\"track\"],handler(){if(0===this.args.length)return this.error(\"no group ID specified\");if(1===this.payload.length)return this.error(\"no tracks defined via <<track>>\");Config.debug&&this.debugView.modes({nonvoid:!1,hidden:!0});const groupId=String(this.args[0]).trim(),trackIds=[];for(let i=1,len=this.payload.length;i<len;++i){if(this.payload[i].args.length<1)return this.error(\"no track ID specified\");trackIds.push(String(this.payload[i].args[0]).trim()),Config.debug&&this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1,hidden:!0})}try{SimpleAudio.groups.add(groupId,trackIds)}catch(ex){return this.error(ex.message)}Config.debug&&this.createDebugView(`/${this.name}`,`<</${this.name}>>`).modes({nonvoid:!1,hidden:!0})}}),Macro.add(\"createplaylist\",{tags:[\"track\"],handler(){if(0===this.args.length)return this.error(\"no list ID specified\");if(1===this.payload.length)return this.error(\"no tracks defined via <<track>>\");Config.debug&&this.debugView.modes({nonvoid:!1,hidden:!0});const listId=String(this.args[0]).trim(),trackObjs=[];for(let i=1,len=this.payload.length;i<len;++i){if(0===this.payload[i].args.length)return this.error(\"no track ID specified\");const trackObj={id:String(this.payload[i].args[0]).trim()},args=this.payload[i].args.slice(1);for(;args.length>0;){const arg=args.shift();let raw,parsed;switch(arg){case\"own\":trackObj.own=!0;break;case\"rate\":args.length>0&&args.shift();break;case\"volume\":if(0===args.length)return this.error(\"volume missing required level value\");if(raw=args.shift(),parsed=Number.parseFloat(raw),Number.isNaN(parsed)||!Number.isFinite(parsed))return this.error(`cannot parse volume: ${raw}`);trackObj.volume=parsed;break;default:return this.error(`unknown action: ${arg}`)}}trackObjs.push(trackObj),Config.debug&&this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1,hidden:!0})}try{SimpleAudio.lists.add(listId,trackObjs)}catch(ex){return this.error(ex.message)}Config.debug&&this.createDebugView(`/${this.name}`,`<</${this.name}>>`).modes({nonvoid:!1,hidden:!0})}}),Macro.add(\"masteraudio\",{handler(){if(0===this.args.length)return this.error(\"no actions specified\");const args=this.args.slice(0);let action,mute,muteOnHide,volume;for(;args.length>0;){const arg=args.shift();let raw;switch(arg){case\"load\":case\"stop\":case\"unload\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=arg;break;case\"mute\":case\"unmute\":mute=\"mute\"===arg;break;case\"muteonhide\":case\"nomuteonhide\":muteOnHide=\"muteonhide\"===arg;break;case\"volume\":if(0===args.length)return this.error(\"volume missing required level value\");if(raw=args.shift(),volume=Number.parseFloat(raw),Number.isNaN(volume)||!Number.isFinite(volume))return this.error(`cannot parse volume: ${raw}`);break;default:return this.error(`unknown action: ${arg}`)}}try{switch(null!=mute&&SimpleAudio.mute(mute),null!=muteOnHide&&SimpleAudio.muteOnHidden(muteOnHide),null!=volume&&SimpleAudio.volume(volume),action){case\"load\":SimpleAudio.load();break;case\"stop\":SimpleAudio.stop();break;case\"unload\":SimpleAudio.unload()}Config.debug&&this.debugView.modes({hidden:!0})}catch(ex){return this.error(`error executing action: ${ex.message}`)}}}),Macro.add(\"playlist\",{handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"list ID\"),this.args.length<2&&errors.push(\"actions\"),this.error(`no ${errors.join(\" or \")} specified`)}const id=String(this.args[0]).trim();if(!SimpleAudio.lists.has(id))return this.error(`playlist \"${id}\" does not exist`);const list=SimpleAudio.lists.get(id),args=this.args.slice(1);let action,fadeTo,loop,mute,shuffle,volume,fadeOver=5;for(;args.length>0;){const arg=args.shift();let raw;switch(arg){case\"load\":case\"pause\":case\"play\":case\"skip\":case\"stop\":case\"unload\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=arg;break;case\"fadein\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=\"fade\",fadeTo=1;break;case\"fadeout\":if(action)return this.error(errorOnePlaybackAction(arg,action));action=\"fade\",fadeTo=0;break;case\"fadeto\":if(action)return this.error(errorOnePlaybackAction(arg,action));if(0===args.length)return this.error(\"fadeto missing required level value\");if(action=\"fade\",raw=args.shift(),fadeTo=Number.parseFloat(raw),Number.isNaN(fadeTo)||!Number.isFinite(fadeTo))return this.error(`cannot parse fadeto: ${raw}`);break;case\"fadeoverto\":if(action)return this.error(errorOnePlaybackAction(arg,action));if(args.length<2){const errors=[];return args.length<1&&errors.push(\"seconds\"),args.length<2&&errors.push(\"level\"),this.error(`fadeoverto missing required ${errors.join(\" and \")} value${errors.length>1?\"s\":\"\"}`)}if(action=\"fade\",raw=args.shift(),fadeOver=Number.parseFloat(raw),Number.isNaN(fadeOver)||!Number.isFinite(fadeOver))return this.error(`cannot parse fadeoverto: ${raw}`);if(raw=args.shift(),fadeTo=Number.parseFloat(raw),Number.isNaN(fadeTo)||!Number.isFinite(fadeTo))return this.error(`cannot parse fadeoverto: ${raw}`);break;case\"volume\":if(0===args.length)return this.error(\"volume missing required level value\");if(raw=args.shift(),volume=Number.parseFloat(raw),Number.isNaN(volume)||!Number.isFinite(volume))return this.error(`cannot parse volume: ${raw}`);break;case\"mute\":case\"unmute\":mute=\"mute\"===arg;break;case\"loop\":case\"unloop\":loop=\"loop\"===arg;break;case\"shuffle\":case\"unshuffle\":shuffle=\"shuffle\"===arg;break;default:return this.error(`unknown action: ${arg}`)}}try{switch(null!=volume&&list.volume(volume),null!=mute&&list.mute(mute),null!=loop&&list.loop(loop),null!=shuffle&&list.shuffle(shuffle),action){case\"fade\":list.fade(fadeOver,fadeTo);break;case\"load\":list.load();break;case\"pause\":list.pause();break;case\"play\":list.playWhenAllowed();break;case\"skip\":list.skip();break;case\"stop\":list.stop();break;case\"unload\":list.unload()}Config.debug&&this.debugView.modes({hidden:!0})}catch(ex){return this.error(`error executing action: ${ex.message}`)}}}),Macro.add(\"removeaudiogroup\",{handler(){if(0===this.args.length)return this.error(\"no group ID specified\");const id=String(this.args[0]).trim();if(!SimpleAudio.groups.has(id))return this.error(`group \"${id}\" does not exist`);SimpleAudio.groups.delete(id),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"removeplaylist\",{handler(){if(0===this.args.length)return this.error(\"no list ID specified\");const id=String(this.args[0]).trim();if(!SimpleAudio.lists.has(id))return this.error(`playlist \"${id}\" does not exist`);SimpleAudio.lists.delete(id),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"waitforaudio\",{skipArgs:!0,handler(){SimpleAudio.loadWithScreen()}})}else Macro.add([\"audio\",\"cacheaudio\",\"createaudiogroup\",\"createplaylist\",\"masteraudio\",\"playlist\",\"removeaudiogroup\",\"removeplaylist\",\"waitforaudio\"],{skipArgs:!0,handler(){Config.debug&&this.debugView.modes({hidden:!0})}})})(),Macro.add([\"back\",\"return\"],{handler(){let passage,content,$link,momentIndex=-1;if(this.args.length>0)if(\"object\"==typeof this.args[0])if(this.args[0].isImage){content=document.createElement(\"img\");const $image=jQuery(content).attr(\"src\",this.args[0].source);Object.hasOwn(this.args[0],\"passage\")&&$image.attr(\"data-passage\",this.args[0].passage),Object.hasOwn(this.args[0],\"title\")&&$image.attr(\"title\",this.args[0].title),Object.hasOwn(this.args[0],\"align\")&&$image.attr(\"align\",this.args[0].align),Object.hasOwn(this.args[0],\"link\")&&(passage=this.args[0].link)}else content=document.createTextNode(this.args[0].text),passage=this.args[0].link;else{content=document.createDocumentFragment();const forbidden=jQuery(content).wikiWithOptions({cleanup:!1,profile:\"core\"},this.args[0]).getForbiddenInteractiveContentTagNames();if(forbidden.length>0)throw new Error(`text content contains restricted elements: <${forbidden.join(\">, <\")}>`);passage=this.args.length>1?this.args[1]:undefined}if(null==passage){for(let i=State.length-2;i>=0;--i)if(State.history[i].title!==State.passage){momentIndex=i,passage=State.history[i].title;break}if(null==passage&&\"return\"===this.name)for(let i=State.expired.length-1;i>=0;--i)if(State.expired[i]!==State.passage){passage=State.expired[i];break}}else{if(!Story.has(passage))return this.error(`passage \"${passage}\" does not exist`);if(\"back\"===this.name){for(let i=State.length-2;i>=0;--i)if(State.history[i].title===passage){momentIndex=i;break}if(-1===momentIndex)return this.error(`cannot find passage \"${passage}\" in the current story history`)}}if(null==passage)return this.error(\"cannot find passage\");\"back\"!==this.name||-1!==momentIndex?($link=jQuery(document.createElement(\"a\")).addClass(\"link-internal\").ariaClick({one:!0},\"return\"===this.name?()=>Engine.play(passage):()=>Engine.goTo(momentIndex)),content instanceof HTMLImageElement&&$link.addClass(\"link-image\")):$link=jQuery(document.createElement(\"span\")).addClass(\"link-disabled\"),$link.addClass(`macro-${this.name}`).append(content||document.createTextNode(L10n.get(`macro${this.name.toUpperFirst()}Text`))).appendTo(this.output)}}),Macro.add([\"button\",\"link\"],{isAsync:!0,tags:null,handler(){if(0===this.args.length)return this.error(`no ${\"button\"===this.name?\"button\":\"link\"} text specified`);const $link=jQuery(document.createElement(\"button\"===this.name?\"button\":\"a\"));let passage;if(\"object\"==typeof this.args[0])if(this.args[0].isImage){const $image=jQuery(document.createElement(\"img\")).attr(\"src\",this.args[0].source).appendTo($link);$link.addClass(\"link-image\"),Object.hasOwn(this.args[0],\"passage\")&&$image.attr(\"data-passage\",this.args[0].passage),Object.hasOwn(this.args[0],\"title\")&&$image.attr(\"title\",this.args[0].title),Object.hasOwn(this.args[0],\"align\")&&$image.attr(\"align\",this.args[0].align),passage=this.args[0].link}else $link.append(document.createTextNode(this.args[0].text)),passage=this.args[0].link;else{const $frag=jQuery(document.createDocumentFragment()).wikiWithOptions({cleanup:!1,profile:\"core\"},this.args[0]),forbidden=$frag.getForbiddenInteractiveContentTagNames();if(forbidden.length>0)throw new Error(`text content contains restricted elements: <${forbidden.join(\">, <\")}>`);$link.append($frag),passage=this.args.length>1?this.args[1]:undefined}null!=passage?($link.attr(\"data-passage\",passage),Story.has(passage)?($link.addClass(\"link-internal\"),Config.addVisitedLinkClass&&State.hasPlayed(passage)&&$link.addClass(\"link-visited\")):$link.addClass(\"link-broken\")):$link.addClass(\"link-internal\"),$link.addClass(`macro-${this.name}`).ariaClick({namespace:\".macros\",role:null!=passage?\"link\":\"button\",one:null!=passage},this.shadowHandler(\"\"!==this.payload[0].contents?()=>Wikifier.wikifyEval(this.payload[0].contents.trim()):null,null!=passage?()=>Engine.play(passage):null)).appendTo(this.output)}}),Macro.add(\"capture\",{skipArgs:!0,tags:null,tsVarRe:new RegExp(`(${Patterns.variable})`,\"g\"),handler(){if(0===this.args.raw.length)return this.error(\"no story/temporary variable list specified\");const valueCache={};try{const tsVarRe=this.self.tsVarRe;let match;for(;null!==(match=tsVarRe.exec(this.args.raw));){const varName=match[1],varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;Object.hasOwn(store,varKey)&&(valueCache[varKey]=store[varKey]),this.addShadow(varName)}new Wikifier(this.output,this.payload[0].contents)}finally{this.shadows.forEach((varName=>{const varKey=varName.slice(1),store=\"$\"===varName[0]?State.variables:State.temporary;Object.hasOwn(valueCache,varKey)?store[varKey]=valueCache[varKey]:delete store[varKey]}))}}}),Macro.add(\"checkbox\",{isAsync:!0,handler(){if(this.args.length<3){const errors=[];return this.args.length<1&&errors.push(\"variable name\"),this.args.length<2&&errors.push(\"unchecked value\"),this.args.length<3&&errors.push(\"checked value\"),this.error(`no ${errors.join(\" or \")} specified`)}if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);const varId=createSlug(varName),uncheckValue=this.args[1],checkValue=this.args[2],el=document.createElement(\"input\");switch(jQuery(el).attr({id:`${this.name}-${varId}`,name:`${this.name}-${varId}`,type:\"checkbox\",tabindex:0}).addClass(`macro-${this.name}`).on(\"change.macros\",this.shadowHandler((function(){State.setVar(varName,this.checked?checkValue:uncheckValue)}))).appendTo(this.output),this.args[3]){case\"autocheck\":State.getVar(varName)===checkValue?el.checked=!0:State.setVar(varName,uncheckValue);break;case\"checked\":el.checked=!0,State.setVar(varName,checkValue);break;default:State.setVar(varName,uncheckValue)}}}),Macro.add(\"copy\",{handler(){if(0===this.args.length)return this.error(\"no selector specified\");const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);jQuery(this.output).append($targets.html()),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add([\"cycle\",\"listbox\"],{isAsync:!0,skipArgs:[\"optionsfrom\"],tags:[\"option\",\"optionsfrom\"],handler(){if(0===this.args.length)return this.error(\"no variable name specified\");if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);const varId=createSlug(varName),len=this.payload.length;if(1===len)return this.error(\"no options specified\");const config={autoselect:!1,once:!1};for(let i=1;i<this.args.length;++i){const arg=this.args[i];switch(arg){case\"once\":config.once=!0;break;case\"autoselect\":config.autoselect=!0;break;default:return this.error(`unknown argument: ${arg}`)}}const options=[],tagCount={option:0,optionsfrom:0};let index=-1;for(let i=1;i<len;++i){const payload=this.payload[i];if(\"option\"===payload.name){if(++tagCount.option,0===payload.args.length)return this.error(`no arguments specified for <<${payload.name}>> (#${tagCount.option})`);const option={label:String(payload.args[0])};let isSelected=!1;switch(payload.args.length){case 1:option.value=payload.args[0];break;case 2:\"selected\"===payload.args[1]?(option.value=payload.args[0],isSelected=!0):option.value=payload.args[1];break;default:option.value=payload.args[1],\"selected\"===payload.args[2]&&(isSelected=!0)}if(options.push(option),isSelected){if(config.autoselect)return this.error(\"cannot specify both the autoselect and selected keywords\");if(-1!==index)return this.error(`multiple selected keywords specified for <<${payload.name}>> (#${index+1} & #${tagCount.option})`);index=options.length-1}}else{if(++tagCount.optionsfrom,0===payload.args.full.length)return this.error(`no expression specified for <<${payload.name}>> (#${tagCount.optionsfrom})`);let result;try{const exp=payload.args.full;result=Scripting.evalJavaScript(\"{\"===exp[0]?`(${exp})`:exp)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`)}if(\"object\"!=typeof result||null===result)return this.error(`expression must yield a supported collection or generic object (type: ${null===result?\"null\":typeof result})`);if(result instanceof Array||result instanceof Set)result.forEach((val=>options.push({label:String(val),value:val})));else if(result instanceof Map)result.forEach(((val,key)=>options.push({label:String(key),value:val})));else{const oType=getToStringTag(result);if(\"Object\"!==oType)return this.error(`expression must yield a supported collection or generic object (object type: ${oType})`);Object.keys(result).forEach((key=>options.push({label:key,value:result[key]})))}}}if(-1===index)if(config.autoselect){const curValue=State.getVar(varName),curValueIndex=options.findIndex((opt=>sameValueZero(opt.value,curValue)));index=-1===curValueIndex?0:curValueIndex}else index=0;if(\"cycle\"===this.name){const lastIndex=options.length-1;if(config.once&&index===lastIndex)jQuery(this.output).wikiWithOptions({cleanup:!1,profile:\"core\"},options[index].label);else{let cycleIndex=index;jQuery(document.createElement(\"a\")).wikiWithOptions({cleanup:!1,profile:\"core\"},options[index].label).attr(\"id\",`${this.name}-${varId}`).addClass(`macro-${this.name}`).ariaClick({namespace:\".macros\",role:\"button\"},this.shadowHandler((function(){const $this=$(this);cycleIndex=(cycleIndex+1)%options.length,State.setVar(varName,options[cycleIndex].value),$this.empty().wikiWithOptions({cleanup:!1,profile:\"core\"},options[cycleIndex].label),config.once&&cycleIndex===lastIndex&&$this.off().contents().unwrap()}))).appendTo(this.output)}}else{const $select=jQuery(document.createElement(\"select\"));options.forEach(((opt,i)=>{jQuery(document.createElement(\"option\")).val(i).text(opt.label).appendTo($select)})),$select.attr({id:`${this.name}-${varId}`,name:`${this.name}-${varId}`,tabindex:0}).addClass(`macro-${this.name}`).val(index).on(\"change.macros\",this.shadowHandler((function(){State.setVar(varName,options[Number(this.value)].value)}))).appendTo(this.output)}State.setVar(varName,options[index].value)}}),jQuery(document).on(\":redo\",(ev=>{const evTags=ev.detail&&ev.detail.tags||[],selector=0===evTags.length?\".redo-target\":evTags.map((tag=>`.redo-target[data-do-tags~=\"${tag}\"]`)).join(\", \");triggerEvent(\":redo-internal\",jQuery(selector),{bubbles:!1,detail:ev.detail})})),Macro.add(\"do\",{tags:null,handler(){let elTag=\"span\",tags=[];const options=this.args.slice();for(;options.length>0;){const option=options.shift();switch(option){case\"tag\":{if(0===options.length)return this.error(\"tag option missing required tag name(s)\");const raw=String(options.shift()).trim();if(\"\"===raw)throw new Error(\"tag option tag name(s) must be non-empty\");tags=String(raw).trim().splitOrEmpty(/\\s+/);break}case\"element\":if(0===options.length)return this.error(\"element option missing required element tag name\");if(elTag=String(options.shift()).trim(),\"\"===elTag)throw new Error(\"element option tag name must be non-empty\");break;default:return this.error(`unknown option: ${option}`)}}const contents=this.payload[0].contents;if(\"\"===contents.trim())return;Config.debug&&this.debugView.modes({block:\"span\"!==elTag});const $target=jQuery(document.createElement(elTag)).addClass(`macro-${this.name} redo-target`).attr(\"data-do-tags\",tags.join(\" \")).wiki(contents).on(\":redo-internal\",jQuery.throttle(Engine.DOM_DELAY,this.shadowHandler((()=>{const frag=document.createDocumentFragment();new Wikifier(frag,contents),$target.empty().append(frag)})))).appendTo(this.output)}}),Macro.add(\"redo\",{handler(){const failRE=/^(?:do|for)$/,passRE=/^(?:button|link(?:append|prepend|replace)?)$/,closest=this.contextFind((ctx=>failRE.test(ctx.name)||passRE.test(ctx.name)));if(closest&&failRE.test(closest.name))return this.error(`must not be used directly within macro <<${closest.name}>>`);const tags=this.args.length>0?String(this.args[0]).trim().splitOrEmpty(/\\s+/):[];triggerEvent(\":redo\",document,{detail:{tags:tags}})}}),Macro.add(\"done\",{skipArgs:!0,tags:null,handler(){const contents=this.payload[0].contents.trim();\"\"!==contents&&setTimeout(this.shadowHandler((()=>$.wiki(contents))),Engine.DOM_DELAY)}}),Macro.add(\"for\",{skipArgs:!0,tags:null,isRangeRe:new RegExp(`^(?:\\\\S${Patterns.anyChar}*?\\\\s+)?range\\\\s+\\\\S${Patterns.anyChar}*?$`),rangeRe:new RegExp(`^(?:(?:State\\\\.(variables|temporary)\\\\.(${Patterns.identifier})\\\\s*,\\\\s*)?State\\\\.(variables|temporary)\\\\.(${Patterns.identifier})\\\\s+)?range\\\\s+(\\\\S${Patterns.anyChar}*?)$`),threePartRe:/^([^;]*?)\\s*;\\s*([^;]*?)\\s*;\\s*([^;]*?)$/,forInRe:/^\\S+\\s+in\\s+\\S+/i,forOfRe:/^\\S+\\s+of\\s+\\S+/i,handler(){const argsStr=this.args.full.trim(),payload=this.payload[0].contents.replace(/\\n$/,\"\");if(0===argsStr.length)this.self.handleFor.call(this,payload,null,!0,null);else if(this.self.isRangeRe.test(argsStr)){const parts=argsStr.match(this.self.rangeRe);if(null===parts)return this.error(\"invalid range form syntax, format: [[index ,] value] range collection\");this.self.handleForRange.call(this,payload,{type:parts[1],name:parts[2]},{type:parts[3],name:parts[4]},parts[5])}else{let init,condition,post;if(-1===argsStr.indexOf(\";\")){if(this.self.forInRe.test(argsStr))return this.error(\"invalid syntax, for…in is not supported; see: for…range\");if(this.self.forOfRe.test(argsStr))return this.error(\"invalid syntax, for…of is not supported; see: for…range\");condition=argsStr}else{const parts=argsStr.match(this.self.threePartRe);if(null===parts)return this.error(\"invalid 3-part conditional form syntax, format: [init] ; [condition] ; [post]\");init=parts[1],condition=parts[2].trim(),post=parts[3],0===condition.length&&(condition=!0)}this.self.handleFor.call(this,payload,init,condition,post)}},handleFor(payload,init,condition,post){const evalJavaScript=Scripting.evalJavaScript;let first=!0,safety=Config.macros.maxLoopIterations;Config.debug&&this.debugView.modes({block:!0});try{if(TempState.break=null,init)try{evalJavaScript(init)}catch(ex){return this.error(`bad init expression: ${getErrorMessage(ex)}`)}for(;evalJavaScript(condition);){if(--safety<0)return this.error(`exceeded configured maximum loop iterations (${Config.macros.maxLoopIterations})`);if(new Wikifier(this.output,first?payload.replace(/^\\n/,\"\"):payload),first&&(first=!1),null!=TempState.break)if(1===TempState.break)TempState.break=null;else if(2===TempState.break){TempState.break=null;break}if(post)try{evalJavaScript(post)}catch(ex){return this.error(`bad post expression: ${getErrorMessage(ex)}`)}}}catch(ex){return this.error(`bad conditional expression: ${getErrorMessage(ex)}`)}finally{TempState.break=null}},handleForRange(payload,keyVar,valueVar,rangeExp){let rangeable,first=!0;try{rangeable=this.self.toRangeable(rangeExp)}catch(ex){return this.error(ex.message)}Config.debug&&this.debugView.modes({block:!0});try{for(TempState.break=null;;){const entry=rangeable.next();if(entry.done)break;if(keyVar.name&&(State[keyVar.type][keyVar.name]=entry.key),valueVar.name&&(State[valueVar.type][valueVar.name]=entry.value),new Wikifier(this.output,first?payload.replace(/^\\n/,\"\"):payload),first&&(first=!1),null!=TempState.break)if(1===TempState.break)TempState.break=null;else if(2===TempState.break){TempState.break=null;break}}}catch(ex){return this.error(getErrorMessage(ex))}finally{TempState.break=null}},toRangeable(rangeExp){let collection;try{collection=Scripting.evalJavaScript(\"{\"===rangeExp[0]?`(${rangeExp})`:rangeExp)}catch(ex){if(\"object\"!=typeof ex)throw new Error(`bad range expression: ${ex}`);throw ex.message=`bad range expression: ${ex.message}`,ex}switch(typeof collection){case\"number\":if(Number.isNaN(collection)||!Number.isFinite(collection))throw new Error(`unsupported range expression type: ${stringFrom(collection)}`);if(!Number.isInteger(collection))throw new Error(\"unsupported range expression type: floating-point number\");if(!Number.isSafeInteger(collection))throw new Error(\"unsupported range expression type: unsafe integer\");return collection<=0?{next:()=>({done:!0})}:{end:collection,pos:0,next(){if(this.pos<this.end){const key=this.pos++;return{key:key,value:key,done:!1}}return{done:!0}}};case\"string\":return{list:collection,end:collection.length,pos:0,next(){if(this.pos<this.end){const O=charAndPosAt(this.list,this.pos),key=this.pos;return this.pos=O.end+1,{key:key,value:O.char,done:!1}}return{done:!0}}};case\"object\":if(collection instanceof Array)return{list:collection,end:collection.length,pos:0,next(){if(this.pos<this.end){const key=this.pos++;return{key:key,value:this.list[key],done:!1}}return{done:!0}}};if(collection instanceof Set)return collection=Array.from(collection),{list:collection,end:collection.length,pos:0,next(){if(this.pos<this.end){const key=this.pos++;return{key:key,value:this.list[key],done:!1}}return{done:!0}}};if(collection instanceof Map){const keys=Array.from(collection.keys());return{keys:keys,list:collection,end:keys.length,pos:0,next(){if(this.pos<this.end){const key=this.keys[this.pos++];return{key:key,value:this.list.get(key),done:!1}}return{done:!0}}}}if(\"Object\"===getToStringTag(collection)){const keys=Object.keys(collection);return{keys:keys,list:collection,end:keys.length,pos:0,next(){if(this.pos<this.end){const key=this.keys[this.pos++];return{key:key,value:this.list[key],done:!1}}return{done:!0}}}}throw new Error(`unsupported range expression type: ${getToStringTag(collection)}`);default:throw new Error(\"unsupported range expression type: \"+typeof collection)}}}),Macro.add([\"break\",\"continue\"],{skipArgs:!0,handler(){if(!this.contextSome((ctx=>\"for\"===ctx.name)))return this.error(\"must only be used in conjunction with its parent macro <<for>>\");TempState.break=\"continue\"===this.name?1:2,Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"goto\",{handler(){if(0===this.args.length)return this.error(\"no passage specified\");let passage;if(passage=\"object\"==typeof this.args[0]?this.args[0].link:this.args[0],!Story.has(passage))return this.error(`passage \"${passage}\" does not exist`);setTimeout((()=>Engine.play(passage)),Engine.DOM_DELAY)}}),Macro.add(\"if\",{skipArgs:!0,tags:[\"elseif\",\"else\"],isElseifWsRE:/^\\s*if\\b/i,isAssignRE:/[^!%&*+\\-/<=>?^|]=[^=>]/,isLiteralRE:new RegExp([\"(?:\\\"\\\"|''|``)\",'(?:\"(?:\\\\\\\\.|[^\"\\\\\\\\])+\")',\"(?:'(?:\\\\\\\\.|[^'\\\\\\\\])+')\",\"(?:`(?:\\\\\\\\.|[^`\\\\\\\\])+`)\"].join(\"|\"),\"g\"),handler(){let i;try{const len=this.payload.length,isElseifWsRE=this.self.isElseifWsRE,isAssignRE=this.self.isAssignRE,isLiteralRE=this.self.isLiteralRE;for(i=0;i<len;++i)if(\"else\"===this.payload[i].name){if(this.payload[i].args.raw.length>0)return isElseifWsRE.test(this.payload[i].args.raw)?this.error('whitespace is not allowed between the \"else\" and \"if\" in <<elseif>> clause'+(i>0?` (#${i})`:\"\")):this.error(`<<else>> does not accept a conditional expression (perhaps you meant to use <<elseif>>), invalid: ${this.payload[i].args.raw}`);if(i+1!==len)return this.error(\"<<else>> must be the final clause\")}else{if(0===this.payload[i].args.full.length)return this.error(`no conditional expression specified for <<${this.payload[i].name}>> clause${i>0?` (#${i})`:\"\"}`);if((Config.debug||Config.enableOptionalDebugging)&&isAssignRE.test(this.payload[i].args.full.replace(isLiteralRE,\"\")))return this.error(`assignment operator found within <<${this.payload[i].name}>> clause${i>0?` (#${i})`:\"\"} (perhaps you meant to use an equality operator: ==, ===, eq, is), invalid: ${this.payload[i].args.raw}`)}const evalJavaScript=Scripting.evalJavaScript;let success=!1;for(i=0;i<len;++i){if(Config.debug&&this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1}),\"else\"===this.payload[i].name||evalJavaScript(this.payload[i].args.full)){success=!0,new Wikifier(this.output,this.payload[i].contents);break}Config.debug&&this.debugView.modes({hidden:!0,invalid:!0})}if(Config.debug){for(++i;i<len;++i)this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1,hidden:!0,invalid:!0});this.createDebugView(`/${this.name}`,`<</${this.name}>>`).modes({nonvoid:!1,hidden:!success,invalid:!success})}}catch(ex){return this.error(`bad conditional expression in <<${0===i?\"if\":\"elseif\"}>> clause${i>0?` (#${i})`:\"\"}: ${getErrorMessage(ex)}`,null,ex.stack)}}}),Macro.add(\"include\",{handler(){if(\"display\"===this.name&&console.warn(`[DEPRECATED] <<${this.name}>> macro is deprecated.`),0===this.args.length)return this.error(\"no passage specified\");let passage,$el;if(passage=\"object\"==typeof this.args[0]?this.args[0].link:this.args[0],!Story.has(passage))return this.error(`passage \"${passage}\" does not exist`);Config.debug&&this.debugView.modes({block:!0}),passage=Story.get(passage),$el=this.args[1]?jQuery(document.createElement(this.args[1])).addClass(`${passage.id} macro-${this.name}`).attr(\"data-passage\",passage.name).appendTo(this.output):jQuery(this.output),$el.wiki(passage.processText())}}),Macro.add([\"linkappend\",\"linkprepend\",\"linkreplace\"],{isAsync:!0,tags:null,t8nRe:/^(?:transition|t8n)$/,handler(){if(0===this.args.length)return this.error(\"no link text specified\");const $link=jQuery(document.createElement(\"a\")),$insert=jQuery(document.createElement(\"span\")),transition=this.args.length>1&&this.self.t8nRe.test(this.args[1]);$link.wikiWithOptions({cleanup:!1,profile:\"core\"},this.args[0]).addClass(`link-internal macro-${this.name}`).ariaClick({namespace:\".macros\",one:!0},this.shadowHandler((()=>{if(\"linkreplace\"===this.name?$link.remove():$link.wrap(`<span class=\"macro-${this.name}\"></span>`).replaceWith((()=>$link.html())),\"\"!==this.payload[0].contents){const frag=document.createDocumentFragment();new Wikifier(frag,this.payload[0].contents,{cleanup:!1}),$insert.append(frag)}transition&&setTimeout((()=>$insert.removeClass(`macro-${this.name}-in`)),Engine.DOM_DELAY)}))).appendTo(this.output),$insert.addClass(`macro-${this.name}-insert`),transition&&$insert.addClass(`macro-${this.name}-in`),\"linkprepend\"===this.name?$insert.insertBefore($link):$insert.insertAfter($link)}}),Macro.add(\"nobr\",{skipArgs:!0,tags:null,handler(){new Wikifier(this.output,this.payload[0].contents.replace(/^\\n+|\\n+$/g,\"\").replace(/\\n+/g,\" \"))}}),Macro.add([\"numberbox\",\"textbox\"],{isAsync:!0,handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"variable name\"),this.args.length<2&&errors.push(\"default value\"),this.error(`no ${errors.join(\" or \")} specified`)}if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);Config.debug&&this.debugView.modes({block:!0});const asNumber=\"numberbox\"===this.name,defaultValue=asNumber?Number(this.args[1]):this.args[1];if(asNumber&&Number.isNaN(defaultValue))return this.error(`default value \"${this.args[1]}\" is neither a number nor can it be parsed into a number`);const varId=createSlug(varName),el=document.createElement(\"input\");let passage,autofocus=!1;this.args.length>3?(passage=this.args[2],autofocus=\"autofocus\"===this.args[3]):this.args.length>2&&(\"autofocus\"===this.args[2]?autofocus=!0:passage=this.args[2]),\"object\"==typeof passage&&(passage=passage.link),jQuery(el).attr({id:`${this.name}-${varId}`,name:`${this.name}-${varId}`,type:asNumber?\"number\":\"text\",inputmode:asNumber?\"decimal\":\"text\",tabindex:0}).addClass(`macro-${this.name}`).on(\"change.macros\",this.shadowHandler((function(){State.setVar(varName,asNumber?Number(this.value):this.value)}))).on(\"keypress.macros\",this.shadowHandler((function(ev){13===ev.which&&(ev.preventDefault(),State.setVar(varName,asNumber?Number(this.value):this.value),null!=passage&&Engine.play(passage))}))).appendTo(this.output),asNumber&&(el.step=\"any\"),State.setVar(varName,defaultValue),el.value=defaultValue,autofocus&&(el.setAttribute(\"autofocus\",\"autofocus\"),Engine.isPlaying()?jQuery(document).one(\":passageend\",(()=>{setTimeout((()=>el.focus()),Engine.DOM_DELAY)})):setTimeout((()=>el.focus()),Engine.DOM_DELAY))}}),Macro.add([\"print\",\"=\",\"-\"],{skipArgs:!0,handler(){if(0===this.args.full.length)return this.error(\"no expression specified\");try{const result=stringFrom(Scripting.evalJavaScript(this.args.full));null!==result&&new Wikifier(this.output,\"-\"===this.name?encodeEntities(result):result)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`,null,ex.stack)}}}),Macro.add(\"radiobutton\",{isAsync:!0,handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"variable name\"),this.args.length<2&&errors.push(\"checked value\"),this.error(`no ${errors.join(\" or \")} specified`)}if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);const varId=createSlug(varName),checkValue=this.args[1],el=document.createElement(\"input\");switch(Object.hasOwn(TempState,this.name)||(TempState[this.name]={}),Object.hasOwn(TempState[this.name],varId)||(TempState[this.name][varId]=0),jQuery(el).attr({id:`${this.name}-${varId}-${TempState[this.name][varId]++}`,name:`${this.name}-${varId}`,type:\"radio\",tabindex:0}).addClass(`macro-${this.name}`).on(\"change.macros\",this.shadowHandler((function(){this.checked&&State.setVar(varName,checkValue)}))).appendTo(this.output),this.args[2]){case\"autocheck\":State.getVar(varName)===checkValue&&(el.checked=!0);break;case\"checked\":el.checked=!0,State.setVar(varName,checkValue)}}}),Macro.add(\"remove\",{handler(){if(0===this.args.length)return this.error(\"no selector specified\");const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);$targets.remove(),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"removeclass\",{handler(){if(0===this.args.length)return this.error(\"no selector specified\");const $targets=jQuery(this.args[0]);if(0===$targets.length)return this.error(`no elements matched the selector \"${this.args[0]}\"`);this.args.length>1?$targets.removeClass(this.args[1].trim()):$targets.removeClass(),Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"repeat\",{isAsync:!0,tags:null,timers:new Set,t8nRe:/^(?:transition|t8n)$/,handler(){if(0===this.args.length)return this.error(\"no time value specified\");let delay;try{delay=Math.max(Engine.DOM_DELAY,cssTimeToMS(this.args[0]))}catch(ex){return this.error(ex.message)}Config.debug&&this.debugView.modes({block:!0});const transition=this.args.length>1&&this.self.t8nRe.test(this.args[1]),$wrapper=jQuery(document.createElement(\"span\")).addClass(`macro-${this.name}`).appendTo(this.output);this.self.registerInterval(this.shadowHandler((()=>{const frag=document.createDocumentFragment();new Wikifier(frag,this.payload[0].contents,{cleanup:!1});let $output=$wrapper;transition&&($output=jQuery(document.createElement(\"span\")).addClass(\"macro-repeat-insert macro-repeat-in\").appendTo($output)),$output.append(frag),transition&&setTimeout((()=>$output.removeClass(\"macro-repeat-in\")),Engine.DOM_DELAY)})),delay)},registerInterval(callback,delay){if(\"function\"!=typeof callback)throw new TypeError(\"callback parameter must be a function\");const passage=State.passage,turn=State.turns,timers=this.timers;let timerId=null;timerId=setInterval((()=>{if(State.passage!==passage||State.turns!==turn)return clearInterval(timerId),void timers.delete(timerId);let timerIdCache;try{TempState.break=null,Object.hasOwn(TempState,\"repeatTimerId\")&&(timerIdCache=TempState.repeatTimerId),TempState.repeatTimerId=timerId,callback.call(this)}finally{void 0!==timerIdCache?TempState.repeatTimerId=timerIdCache:delete TempState.repeatTimerId,TempState.break=null}}),delay),timers.add(timerId),1===timers.size&&jQuery(document).one(\":passageinit\",(()=>{timers.forEach((timerId=>clearInterval(timerId))),timers.clear()}))}}),Macro.add(\"stop\",{skipArgs:!0,handler(){if(!Object.hasOwn(TempState,\"repeatTimerId\"))return this.error(\"must only be used in conjunction with its parent macro <<repeat>>\");const timers=Macro.get(\"repeat\").timers,timerId=TempState.repeatTimerId;clearInterval(timerId),timers.delete(timerId),TempState.break=2,Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"script\",{tags:null,handler(){let evalScript;switch(this.args.length>0?String(this.args[0]).toLowerCase():\"javascript\"){case\"javascript\":evalScript=Scripting.evalJavaScript;break;case\"twinescript\":evalScript=Scripting.evalTwineScript;break;default:return this.error(`unknown language \"${this.args[0]}\"`)}const output=document.createDocumentFragment();try{evalScript(this.payload[0].contents,output)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`)}Config.debug&&this.createDebugView(),output.hasChildNodes()&&this.output.appendChild(output)}}),Macro.add(\"set\",{skipArgs:!0,handler(){if(0===this.args.full.length)return this.error(\"no expression specified\");try{Scripting.evalJavaScript(this.args.full)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`,null,ex.stack)}Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"run\",\"set\"),Macro.add(\"silent\",{skipArgs:!0,tags:null,handler(){\"silently\"===this.name&&console.warn(`[DEPRECATED] <<${this.name}>> macro is deprecated.`);const frag=document.createDocumentFragment();if(new Wikifier(frag,this.payload[0].contents.trim()),Config.debug)this.debugView.modes({block:!0,hidden:!0}),this.output.appendChild(frag);else{const errList=Array.from(frag.querySelectorAll(\".error\")).map((errEl=>errEl.textContent));if(errList.length>0)return this.error(`error${1===errList.length?\"\":\"s\"} within contents (${errList.join(\"; \")})`)}}}),Macro.add(\"switch\",{skipArgs:[\"switch\"],tags:[\"case\",\"default\"],handler(){if(0===this.args.full.length)return this.error(\"no expression specified\");const len=this.payload.length;if(1===len)return this.error(\"no cases specified\");let i,result;for(i=1;i<len;++i)if(\"default\"===this.payload[i].name){if(this.payload[i].args.length>0)return this.error(`<<default>> does not accept values, invalid: ${this.payload[i].args.raw}`);if(i+1!==len)return this.error(\"<<default>> must be the final case\")}else if(0===this.payload[i].args.length)return this.error(`no value(s) specified for <<${this.payload[i].name}>> (#${i})`);try{result=Scripting.evalJavaScript(this.args.full)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`)}const debugView=this.debugView;let success=!1;for(Config.debug&&debugView.modes({nonvoid:!1,hidden:!0}),i=1;i<len;++i){if(Config.debug&&this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1}),\"default\"===this.payload[i].name||this.payload[i].args.some((val=>val===result))){success=!0,new Wikifier(this.output,this.payload[i].contents);break}Config.debug&&this.debugView.modes({hidden:!0,invalid:!0})}if(Config.debug){for(++i;i<len;++i)this.createDebugView(this.payload[i].name,this.payload[i].source).modes({nonvoid:!1,hidden:!0,invalid:!0});debugView.modes({nonvoid:!1,hidden:!0,invalid:!success}),this.createDebugView(`/${this.name}`,`<</${this.name}>>`).modes({nonvoid:!1,hidden:!0,invalid:!success})}}}),Macro.add(\"textarea\",{isAsync:!0,handler(){if(this.args.length<2){const errors=[];return this.args.length<1&&errors.push(\"variable name\"),this.args.length<2&&errors.push(\"default value\"),this.error(`no ${errors.join(\" or \")} specified`)}if(\"string\"!=typeof this.args[0])return this.error(\"variable name argument is not a string\");const varName=this.args[0].trim();if(\"$\"!==varName[0]&&\"_\"!==varName[0])return this.error(`variable name \"${this.args[0]}\" is missing its sigil ($ or _)`);Config.debug&&this.debugView.modes({block:!0});const varId=createSlug(varName),defaultValue=this.args[1],autofocus=\"autofocus\"===this.args[2],el=document.createElement(\"textarea\");jQuery(el).attr({id:`${this.name}-${varId}`,name:`${this.name}-${varId}`,rows:4,tabindex:0}).addClass(`macro-${this.name}`).on(\"change.macros\",this.shadowHandler((function(){State.setVar(varName,this.value)}))).appendTo(this.output),State.setVar(varName,defaultValue),el.textContent=defaultValue,autofocus&&(el.setAttribute(\"autofocus\",\"autofocus\"),Engine.isPlaying()?jQuery(document).one(\":passageend\",(()=>{setTimeout((()=>el.focus()),Engine.DOM_DELAY)})):setTimeout((()=>el.focus()),Engine.DOM_DELAY))}}),Macro.add(\"timed\",{isAsync:!0,tags:[\"next\"],timers:new Set,t8nRe:/^(?:transition|t8n)$/,handler(){if(0===this.args.length)return this.error(\"no time value specified in <<timed>>\");const items=[];try{items.push({name:this.name,source:this.source,delay:Math.max(Engine.DOM_DELAY,cssTimeToMS(this.args[0])),content:this.payload[0].contents})}catch(ex){return this.error(`${ex.message} in <<timed>>`)}if(this.payload.length>1){let i;try{let len;for(i=1,len=this.payload.length;i<len;++i)items.push({name:this.payload[i].name,source:this.payload[i].source,delay:0===this.payload[i].args.length?items[items.length-1].delay:Math.max(Engine.DOM_DELAY,cssTimeToMS(this.payload[i].args[0])),content:this.payload[i].contents})}catch(ex){return this.error(`${ex.message} in <<next>> (#${i})`)}}Config.debug&&this.debugView.modes({block:!0});const transition=this.args.length>1&&this.self.t8nRe.test(this.args[1]),$wrapper=jQuery(document.createElement(\"span\")).addClass(`macro-${this.name}`).appendTo(this.output);this.self.registerTimeout(this.shadowHandler((item=>{const frag=document.createDocumentFragment();new Wikifier(frag,item.content,{cleanup:!1});let $output=$wrapper;Config.debug&&\"next\"===item.name&&($output=jQuery(new DebugView($output[0],\"macro\",item.name,item.source).output)),transition&&($output=jQuery(document.createElement(\"span\")).addClass(\"macro-timed-insert macro-timed-in\").appendTo($output)),$output.append(frag),transition&&setTimeout((()=>$output.removeClass(\"macro-timed-in\")),Engine.DOM_DELAY)})),items)},registerTimeout(callback,items){if(\"function\"!=typeof callback)throw new TypeError(\"callback parameter must be a function\");const passage=State.passage,turn=State.turns,timers=this.timers;let timerId=null,nextItem=items.shift();const worker=function(){if(timers.delete(timerId),State.passage!==passage||State.turns!==turn)return;const curItem=nextItem;null!=(nextItem=items.shift())&&(timerId=setTimeout(worker,nextItem.delay),timers.add(timerId)),callback.call(this,curItem)};timerId=setTimeout(worker,nextItem.delay),timers.add(timerId),1===timers.size&&jQuery(document).one(\":passageinit\",(()=>{timers.forEach((timerId=>clearTimeout(timerId))),timers.clear()}))}}),Macro.add(\"type\",{isAsync:!0,tags:null,typeId:0,handler(){if(0===this.args.length)return this.error(\"no speed specified\");const speed=cssTimeToMS(this.args[0]);if(speed<0)return this.error(`speed time value must be non-negative (received: ${this.args[0]})`);let cursor,elClass=\"\",elId=\"\",elTag=\"div\",skipKey=Config.macros.typeSkipKey,start=400;const options=this.args.slice(1);for(;options.length>0;){const option=options.shift();switch(option){case\"class\":if(0===options.length)return this.error(\"class option missing required class name(s)\");if(elClass=options.shift(),\"\"===elClass)throw new Error('class option class name(s) must be non-empty (received: \"\")');break;case\"element\":if(0===options.length)return this.error(\"element option missing required element tag name\");if(elTag=options.shift(),\"\"===elTag)throw new Error('element option tag name must be non-empty (received: \"\")');break;case\"id\":if(0===options.length)return this.error(\"id option missing required ID\");if(elId=options.shift(),\"\"===elId)throw new Error('id option ID must be non-empty (received: \"\")');break;case\"keep\":cursor=\"keep\";break;case\"none\":cursor=\"none\";break;case\"skipkey\":if(0===options.length)return this.error(\"skipkey option missing required key value\");if(skipKey=options.shift(),\"\"===skipKey)throw new Error('skipkey option key value must be non-empty (received: \"\")');break;case\"start\":{if(0===options.length)return this.error(\"start option missing required time value\");const value=options.shift();if(start=cssTimeToMS(value),start<0)throw new Error(`start option time value must be non-negative (received: ${value})`);break}default:return this.error(`unknown option: ${option}`)}}const contents=this.payload[0].contents;if(\"\"===contents.trim())return;Config.debug&&this.debugView.modes({block:!0});const className=`macro-${this.name}`,namespace=`.${className}`,$target=jQuery(document.createElement(elTag)).addClass(`${className} ${className}-target`).appendTo(this.output);TempState.macroTypeQueue||(TempState.macroTypeQueue=[],$(document).off(namespace).one(`:passageinit${namespace}`,(()=>$(document).off(namespace))));const startTyping=0===TempState.macroTypeQueue.length,selfId=++this.self.typeId,allowCleanup=this.self.allowCleanup;TempState.macroTypeQueue.push({id:selfId,handler:this.shadowHandler((()=>{const $wrapper=jQuery(document.createElement(elTag)).addClass(className);elId&&$wrapper.attr(\"id\",elId),elClass&&$wrapper.addClass(elClass),new Wikifier($wrapper,contents,allowCleanup(elTag)?undefined:{cleanup:!1});const passage=State.passage,turn=State.turns;if(0===speed||!Config.macros.typeVisitedPassages&&State.passages.slice(0,-1).some((title=>title===passage))||$wrapper.find(\".error\").length>0)return $target.replaceWith($wrapper),TempState.macroTypeQueue.shift(),void(TempState.macroTypeQueue.length>0&&TempState.macroTypeQueue.first().handler());const typer=new NodeTyper({targetNode:$wrapper.get(0),classNames:\"none\"===cursor?null:`${className}-cursor`});$target.replaceWith($wrapper);const keydownAndNS=`keydown${namespace}`,typingStopAndNS=`:typingstop${namespace}`;$(document).off(keydownAndNS).on(keydownAndNS,(ev=>{scrubEventKey(ev.key)!==skipKey||ev.target!==document.body&&ev.target!==document.documentElement||(ev.preventDefault(),$(document).off(keydownAndNS),typer.finish())})).one(typingStopAndNS,(()=>{TempState.macroTypeQueue&&(0===TempState.macroTypeQueue.length?triggerEvent(\":typingcomplete\"):TempState.macroTypeQueue.first().handler())}));const typeNode=function(){const typeNodeMember=function(typeIntervalId){State.passage===passage&&State.turns===turn&&typer.type()||(typeIntervalId&&clearInterval(typeIntervalId),TempState.macroTypeQueue&&TempState.macroTypeQueue.length>0&&TempState.macroTypeQueue.first().id===selfId&&TempState.macroTypeQueue.shift(),triggerEvent(\":typingstop\",$wrapper),$wrapper.addClass(`${className}-done`),\"keep\"===cursor&&$wrapper.addClass(`${className}-cursor`))};triggerEvent(\":typingstart\",$wrapper),typeNodeMember();const typeNodeMemberId=setInterval((()=>typeNodeMember(typeNodeMemberId)),speed)};start?setTimeout(typeNode,start):typeNode()}))}),startTyping&&(Engine.isPlaying()?$(document).one(`:passageend${namespace}`,(()=>TempState.macroTypeQueue.first().handler())):TempState.macroTypeQueue.first().handler())},allowCleanup(tagName){switch(tagName.toUpperCase()){case\"ARTICLE\":case\"DIV\":case\"FOOTER\":case\"FORM\":case\"HEADER\":case\"MAIN\":case\"SECTION\":return!0}return!1}}),Macro.add(\"unset\",{skipArgs:!0,handler(){if(0===this.args.full.length)return this.error(\"no story/temporary variable list specified\");const searchRe=/[,;\\s]*((?:State\\.(?:variables|temporary)|setup)\\.)/g,replacer=(_,p1)=>`; delete ${p1}`,cleanupRe=/^; /;try{const unsetExp=this.args.full.replace(searchRe,replacer).replace(cleanupRe,\"\");Scripting.evalJavaScript(unsetExp)}catch(ex){return this.error(`bad evaluation: ${getErrorMessage(ex)}`)}Config.debug&&this.debugView.modes({hidden:!0})}}),Macro.add(\"widget\",{tags:null,handler(){if(0===this.args.length)return this.error(\"no widget name specified\");const widgetName=this.args[0],isNonVoid=this.args.length>1&&\"container\"===this.args[1];if(Macro.has(widgetName))return this.error(`cannot clobber existing ${Macro.get(widgetName).isWidget?\"widget\":\"macro\"} \"${widgetName}\"`);try{const widgetDef={isWidget:!0,handler:(widgetCode=this.payload[0].contents,function(){const shadowStore={};Object.hasOwn(State.temporary,\"args\")&&(shadowStore._args=State.temporary.args),State.temporary.args=Array.from(this.args),State.temporary.args.raw=this.args.raw,State.temporary.args.full=this.args.full,State.temporary.args.name=this.name,this.addShadow(\"_args\"),isNonVoid&&(Object.hasOwn(State.temporary,\"contents\")&&(shadowStore._contents=State.temporary.contents),State.temporary.contents=this.payload[0].contents,this.addShadow(\"_contents\")),Object.hasOwn(State.variables,\"args\")&&(shadowStore.$args=State.variables.args),State.variables.args=State.temporary.args,this.addShadow(\"$args\");try{const resFrag=document.createDocumentFragment(),errList=[];if(new Wikifier(resFrag,widgetCode),Array.from(resFrag.querySelectorAll(\".error\")).forEach((errEl=>{errList.push(errEl.textContent)})),0!==errList.length)return this.error(`error${errList.length>1?\"s\":\"\"} within widget code (${errList.join(\"; \")})`);this.output.appendChild(resFrag)}catch(ex){return this.error(`cannot execute widget: ${ex.message}`)}finally{Object.hasOwn(shadowStore,\"_args\")?State.temporary.args=shadowStore._args:delete State.temporary.args,isNonVoid&&(Object.hasOwn(shadowStore,\"_contents\")?State.temporary.contents=shadowStore._contents:delete State.temporary.contents),Object.hasOwn(shadowStore,\"$args\")?State.variables.args=shadowStore.$args:delete State.variables.args}})};isNonVoid&&(widgetDef.tags=[]),Macro.add(widgetName,widgetDef),Config.debug&&this.debugView.modes({hidden:!0})}catch(ex){return this.error(`cannot create widget macro \"${widgetName}\": ${ex.message}`)}var widgetCode}}),Macro.add(\"silently\",\"silent\"),Macro.add(\"actions\",{handler(){console.warn(`[DEPRECATED] <<${this.name}>> macro is deprecated.`);const $list=jQuery(document.createElement(\"ul\")).addClass(this.name).appendTo(this.output);for(let i=0;i<this.args.length;++i){let passage,text,$image,setFn;if(\"object\"==typeof this.args[i]?this.args[i].isImage?($image=jQuery(document.createElement(\"img\")).attr(\"src\",this.args[i].source),Object.hasOwn(this.args[i],\"passage\")&&$image.attr(\"data-passage\",this.args[i].passage),Object.hasOwn(this.args[i],\"title\")&&$image.attr(\"title\",this.args[i].title),Object.hasOwn(this.args[i],\"align\")&&$image.attr(\"align\",this.args[i].align),passage=this.args[i].link,setFn=this.args[i].setFn):(text=this.args[i].text,passage=this.args[i].link,setFn=this.args[i].setFn):text=passage=this.args[i],Object.hasOwn(State.variables,\"#actions\")&&Object.hasOwn(State.variables[\"#actions\"],passage)&&State.variables[\"#actions\"][passage])continue;const $link=jQuery(Wikifier.createInternalLink(jQuery(document.createElement(\"li\")).appendTo($list),passage,null,((passage,fn)=>()=>{Object.hasOwn(State.variables,\"#actions\")||(State.variables[\"#actions\"]={}),State.variables[\"#actions\"][passage]=!0,\"function\"==typeof fn&&fn()})(passage,setFn))).addClass(`macro-${this.name}`).append($image||document.createTextNode(text));$image&&$link.addClass(\"link-image\")}}}),Macro.add(\"choice\",{handler(){if(console.warn(`[DEPRECATED] <<${this.name}>> macro is deprecated.`),0===this.args.length)return this.error(\"no passage specified\");const choiceId=State.passage;let passage,text,$image,setFn,$link;if(1===this.args.length?\"object\"==typeof this.args[0]?this.args[0].isImage?($image=jQuery(document.createElement(\"img\")).attr(\"src\",this.args[0].source),Object.hasOwn(this.args[0],\"passage\")&&$image.attr(\"data-passage\",this.args[0].passage),Object.hasOwn(this.args[0],\"title\")&&$image.attr(\"title\",this.args[0].title),Object.hasOwn(this.args[0],\"align\")&&$image.attr(\"align\",this.args[0].align),passage=this.args[0].link,setFn=this.args[0].setFn):(text=this.args[0].text,passage=this.args[0].link,setFn=this.args[0].setFn):text=passage=this.args[0]:(passage=this.args[0],text=this.args[1]),Object.hasOwn(State.variables,\"#choice\")&&Object.hasOwn(State.variables[\"#choice\"],choiceId)&&State.variables[\"#choice\"][choiceId])return $link=jQuery(document.createElement(\"span\")).addClass(`link-disabled macro-${this.name}`).attr(\"tabindex\",-1).append($image||document.createTextNode(text)).appendTo(this.output),void($image&&$link.addClass(\"link-image\"));$link=jQuery(Wikifier.createInternalLink(this.output,passage,null,(()=>{Object.hasOwn(State.variables,\"#choice\")||(State.variables[\"#choice\"]={}),State.variables[\"#choice\"][choiceId]=!0,\"function\"==typeof setFn&&setFn()}))).addClass(`macro-${this.name}`).append($image||document.createTextNode(text)),$image&&$link.addClass(\"link-image\")}});var Dialog=(()=>{const DEFAULT_TOP=50;let $overlay=null,$dialog=null,$title=null,$body=null,lastActive=null,observer=null,onCloseFn=null,scrollbarWidth=0;function calcInset(top){const $window=jQuery(window),inset={left:\"\",right:\"\",top:\"\",bottom:\"\"};$dialog.css(inset);let horzSpace=$window.width()-$dialog.outerWidth(!0)-1,vertSpace=$window.height()-$dialog.outerHeight(!0)-1;if(horzSpace<=20+scrollbarWidth&&(vertSpace-=scrollbarWidth),vertSpace<=20+scrollbarWidth&&(horzSpace-=scrollbarWidth),inset.left=inset.right=horzSpace<=20?\"10px\":(horzSpace/2|0)+\"px\",vertSpace<=20)inset.top=inset.bottom=\"10px\";else{const vertPos=vertSpace/2|0;inset.top=vertPos>top?top+\"px\":inset.bottom=vertPos+\"px\"}return inset}function onResize(top){\"block\"===$dialog.css(\"display\")&&$dialog.css(calcInset(null!=top?top:DEFAULT_TOP))}function close(ev){if(triggerEvent(\":dialogclosing\",$body),jQuery(document).off(\".dialog-close\"),observer?(observer.disconnect(),observer=null):$body.off(\".dialog-resize\"),jQuery(window).off(\".dialog-resize\"),$dialog.removeClass(\"open\").css({left:\"\",right:\"\",top:\"\",bottom:\"\"}),jQuery(\"#ui-bar,#story\").find(\"[tabindex=-2]\").removeAttr(\"aria-hidden\").attr(\"tabindex\",0),jQuery(\"body>[tabindex=-3]\").removeAttr(\"aria-hidden\").removeAttr(\"tabindex\"),$overlay.removeClass(\"open\"),jQuery(document.documentElement).removeAttr(\"data-dialog\"),$title.empty(),$body.empty().removeClass(),lastActive&&(lastActive.focus(),lastActive=null),onCloseFn)try{onCloseFn(ev)}finally{onCloseFn=null}return triggerEvent(\":dialogclose\",$body),triggerEvent(\":dialogclosed\",$body),Dialog}function create(title,classNames){return $title.empty().append((null!=title?String(title):\"\")||\" \"),$body.empty().removeClass(),null!=classNames&&$body.addClass(classNames),Dialog}function getBody(){return $body.get(0)}function isOpen(classNames){return $dialog.hasClass(\"open\")&&(!classNames||classNames.splitOrEmpty(/\\s+/).every((cn=>$body.hasClass(cn))))}function wiki(...args){return $body.wiki(...args),Dialog}return Object.preventExtensions(Object.create(null,{append:{value:function(...args){return $body.append(...args),Dialog}},body:{value:getBody},close:{value:close},create:{value:create},empty:{value:function(){return $body.empty(),Dialog}},init:{value:function(){if(document.getElementById(\"ui-dialog\"))return;scrollbarWidth=(()=>{let calcWidth;try{const inner=document.createElement(\"p\");inner.style.width=\"100%\",inner.style.height=\"200px\";const outer=document.createElement(\"div\");outer.style.position=\"absolute\",outer.style.left=\"0\",outer.style.top=\"0\",outer.style.width=\"100px\",outer.style.height=\"100px\",outer.style.visibility=\"hidden\",outer.style.overflow=\"hidden\",outer.appendChild(inner),document.body.appendChild(outer);const w1=inner.offsetWidth;outer.style.overflow=\"auto\";let w2=inner.offsetWidth;w1===w2&&(w2=outer.clientWidth),document.body.removeChild(outer),calcWidth=w1-w2}catch(ex){}return calcWidth||17})();const $elems=jQuery(document.createDocumentFragment()).append(`<div id=\"ui-overlay\" class=\"ui-close\"></div><div id=\"ui-dialog\" tabindex=\"0\" role=\"dialog\" aria-labelledby=\"ui-dialog-title\" aria-modal=\"true\"><div id=\"ui-dialog-titlebar\"><h1 id=\"ui-dialog-title\"></h1><button id=\"ui-dialog-close\" class=\"ui-close\" tabindex=\"0\" aria-label=\"${L10n.get(\"textClose\")}\">ï€</button></div><div id=\"ui-dialog-body\"></div></div>`);$overlay=jQuery($elems.find(\"#ui-overlay\").get(0)),$dialog=jQuery($elems.find(\"#ui-dialog\").get(0)),$title=jQuery($elems.find(\"#ui-dialog-title\").get(0)),$body=jQuery($elems.find(\"#ui-dialog-body\").get(0)),$elems.insertBefore(\"body>script#script-sugarcube\")}},isOpen:{value:isOpen},open:{value:function(options,onClose){const{top:top}=Object.assign({top:DEFAULT_TOP},options);if(null!=onClose){const closeType=getTypeOf(onClose);if(\"function\"!==closeType)throw new TypeError(`Dialog.open onClose parameter must be a function (received: ${closeType})`);onCloseFn=onClose}else onCloseFn=null;triggerEvent(\":dialogopening\",$body),isOpen()||(lastActive=getActiveElement()),jQuery(document.documentElement).attr(\"data-dialog\",\"open\"),$overlay.addClass(\"open\"),jQuery(\"body>:not(script,#store-area,tw-storydata,#ui-bar,#ui-overlay,#ui-dialog)\").attr(\"tabindex\",-3).attr(\"aria-hidden\",!0),jQuery(\"#ui-bar,#story\").find(\"[tabindex]:not([tabindex^=-])\").attr(\"tabindex\",-2).attr(\"aria-hidden\",!0);const resizeHandler=jQuery.throttle(40,(()=>onResize(top)));return $body.imagesLoaded().always(resizeHandler),$dialog.css(calcInset(top)).addClass(\"open\").focus(),jQuery(window).off(\".dialog-resize\").on(\"resize.dialog-resize\",resizeHandler),Has.mutationObserver?(observer=new MutationObserver((mutations=>{for(let i=0;i<mutations.length;++i)if(\"childList\"===mutations[i].type){$body.imagesLoaded().always(resizeHandler),resizeHandler();break}})),observer.observe(getBody(),{childList:!0,subtree:!0})):$body.off(\".dialog-resize\").on(\"DOMNodeInserted.dialog-resize DOMNodeRemoved.dialog-resize\",(()=>{$body.imagesLoaded().always(resizeHandler),resizeHandler()})),jQuery(document).off(\".dialog-close\").one(\"click.dialog-close\",\".ui-close\",(ev=>{close(ev)})).one(\"keypress.dialog-close\",\".ui-close\",(function(ev){13!==ev.which&&32!==ev.which||triggerEvent(\"click\",this)})),triggerEvent(\":dialogopen\",$body),triggerEvent(\":dialogopened\",$body),Dialog}},resize:{value:function(options){return onResize(\"object\"==typeof options?options.top:undefined)}},wiki:{value:wiki},wikiPassage:{value:function(name){return wiki(Story.get(name).processText())}},setup:{value:function(title,classNames){return console.warn(\"[DEPRECATED] Dialog.setup() is deprecated.\"),create(title,classNames),getBody()}}}))})(),Engine=(()=>{const States=enumFrom({Init:\"init\",Idle:\"idle\",Playing:\"playing\",Rendering:\"rendering\"}),DOM_DELAY=40,_initDebugViews=[];let _state=States.Init,_lastPlay=null;function engineGo(offset){const succeeded=State.go(offset);return succeeded&&engineShow(),succeeded}function engineShow(){return enginePlay(State.passage,!0)}function enginePlay(title,noHistory){if(_state===States.Init)return!1;let passageReadyOutput,passageDoneOutput,passageTitle=title;if(_state=States.Playing,TempState={},State.clearTemporary(),\"function\"==typeof Config.navigation.override)try{const overrideTitle=Config.navigation.override(passageTitle);overrideTitle&&(passageTitle=overrideTitle)}catch(ex){}const passage=Story.get(passageTitle);if(jQuery.event.trigger({passage:passage,type:\":passageinit\",detail:{passage:passage}}),Object.keys(prehistory).forEach((task=>{\"function\"==typeof prehistory[task]&&prehistory[task].call(passage,task)})),noHistory||State.create(passage.name),document.body.className&&(document.body.className=\"\"),_lastPlay=now(),Object.keys(predisplay).forEach((task=>{\"function\"==typeof predisplay[task]&&predisplay[task].call(passage,task)})),Story.has(\"PassageReady\"))try{passageReadyOutput=Wikifier.wikifyEval(Story.get(\"PassageReady\").text)}catch(ex){console.error(ex),Alert.error(\"PassageReady\",ex.message)}_state=States.Rendering;const dataTags=passage.tags.length>0?passage.tags.join(\" \"):null,passageEl=document.createElement(\"div\");jQuery(passageEl).attr({id:passage.id,\"data-passage\":passage.name,\"data-tags\":dataTags}).addClass(`passage passage-in ${passage.className}`),jQuery(document.body).attr(\"data-tags\",dataTags).addClass(passage.className),jQuery(document.documentElement).attr(\"data-tags\",dataTags),jQuery.event.trigger({content:passageEl,passage:passage,type:\":passagestart\",detail:{content:passageEl,passage:passage}}),Object.keys(prerender).forEach((task=>{\"function\"==typeof prerender[task]&&prerender[task].call(passage,passageEl,task)})),Story.has(\"PassageHeader\")&&new Wikifier(passageEl,Story.get(\"PassageHeader\").processText()),passageEl.appendChild(passage.render()),Story.has(\"PassageFooter\")&&new Wikifier(passageEl,Story.get(\"PassageFooter\").processText()),jQuery.event.trigger({content:passageEl,passage:passage,type:\":passagerender\",detail:{content:passageEl,passage:passage}}),Object.keys(postrender).forEach((task=>{\"function\"==typeof postrender[task]&&postrender[task].call(passage,passageEl,task)}));const containerEl=document.getElementById(\"passages\");if(containerEl.hasChildNodes()&&(\"number\"==typeof Config.passages.transitionOut||\"string\"==typeof Config.passages.transitionOut&&\"\"!==Config.passages.transitionOut&&Has.transitionEndEvent?Array.from(containerEl.childNodes).forEach((outgoing=>{const $outgoing=jQuery(outgoing);if(outgoing.nodeType===Node.ELEMENT_NODE&&$outgoing.hasClass(\"passage\")){if($outgoing.hasClass(\"passage-out\"))return;$outgoing.attr({id:`out-${$outgoing.attr(\"id\")}`,\"aria-hidden\":\"true\",\"aria-live\":\"off\"}).addClass(\"passage-out\"),\"string\"==typeof Config.passages.transitionOut?$outgoing.on(Has.transitionEndEvent,(ev=>{ev.originalEvent.propertyName===Config.passages.transitionOut&&$outgoing.remove()})):setTimeout((()=>$outgoing.remove()),Math.max(DOM_DELAY,Config.passages.transitionOut))}else $outgoing.remove()})):jQuery(containerEl).empty()),jQuery(passageEl).appendTo(containerEl),setTimeout((()=>jQuery(passageEl).removeClass(\"passage-in\")),DOM_DELAY/2),window.scroll(0,0),_state=States.Playing,Story.has(\"PassageDone\"))try{passageDoneOutput=Wikifier.wikifyEval(Story.get(\"PassageDone\").text)}catch(ex){console.error(ex),Alert.error(\"PassageDone\",ex.message)}if(jQuery.event.trigger({content:passageEl,passage:passage,type:\":passagedisplay\",detail:{content:passageEl,passage:passage}}),Object.keys(postdisplay).forEach((task=>{\"function\"==typeof postdisplay[task]&&postdisplay[task].call(passage,task)})),UI.update(),Config.debug){let debugView;null!=passageReadyOutput&&(debugView=new DebugView(document.createDocumentFragment(),\"special\",\"PassageReady\",\"PassageReady\"),debugView.modes({hidden:!0}),debugView.append(passageReadyOutput),jQuery(passageEl).prepend(debugView.output)),null!=passageDoneOutput&&(debugView=new DebugView(document.createDocumentFragment(),\"special\",\"PassageDone\",\"PassageDone\"),debugView.modes({hidden:!0}),debugView.append(passageDoneOutput),jQuery(passageEl).append(debugView.output)),1===State.turns&&_initDebugViews.length>0&&jQuery(passageEl).prepend(_initDebugViews)}return jQuery(\"#story\").find(\"a,link,button,input,select,textarea\").not(\"[tabindex]\").attr(\"tabindex\",0),State.turns>1&&Save.browser.auto.isEnabled()&&Save.browser.auto.save(),jQuery.event.trigger({content:passageEl,passage:passage,type:\":passageend\",detail:{content:passageEl,passage:passage}}),_state=States.Idle,_lastPlay=now(),passageEl}return Object.preventExtensions(Object.create(null,{States:{value:States},DOM_DELAY:{get:()=>DOM_DELAY},init:{value:function(){if(_state!==States.Init)return;jQuery(\"#init-no-js,#init-lacking\").remove();const $main=jQuery('<div id=\"story\" role=\"main\"></div>'),markup=Story.has(\"StoryInterface\")&&Story.get(\"StoryInterface\").text.trim();if(markup){if(Config.ui.updateStoryElements=!1,UIBar.destroy(),jQuery(document.head).find(\"#style-core-display\").remove(),$main.append(markup),$main.find(\"#story\").length>0)throw new Error('element with ID \"story\" found within \"StoryInterface\" special passage');const $passages=$main.find(\"#passages\");if(0===$passages.length)throw new Error('no element with ID \"passages\" found within \"StoryInterface\" special passage');$passages.empty().not(\"[aria-live]\").attr(\"aria-live\",\"polite\").end();const $dataInitPassages=$main.find(\"[data-init-passage]\"),$dataPassages=$main.find(\"[data-passage]\");$dataInitPassages.each(((i,el)=>{if(\"passages\"===el.id)throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} id=\"passages\"> must not contain a \"data-init-passage\" content attribute`);const passage=el.getAttribute(\"data-init-passage\").trim();if(el.hasAttribute(\"data-passage\"))throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} data-init-passage=\"${passage}\"> must not contain a \"data-passage\" content attribute`);if(null!==el.firstElementChild)throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} data-init-passage=\"${passage}\"> contains child elements`);Story.has(passage)&&jQuery(document).one(\":uiupdate.engine\",(()=>{const frag=document.createDocumentFragment();new Wikifier(frag,Story.get(passage).processText().trim()),jQuery(el).empty().append(frag)}))})),$dataPassages.each(((i,el)=>{if(\"passages\"===el.id)throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} id=\"passages\"> must not contain a \"data-passage\" content attribute`);const passage=el.getAttribute(\"data-passage\").trim();if(null!==el.firstElementChild)throw new Error(`\"StoryInterface\" element <${el.nodeName.toLowerCase()} data-passage=\"${passage}\"> contains child elements`);Story.has(passage)&&jQuery(document).on(\":uiupdate.engine\",(()=>{const frag=document.createDocumentFragment();new Wikifier(frag,Story.get(passage).processText().trim()),jQuery(el).empty().append(frag)}))}))}else $main.append('<div id=\"passages\" aria-live=\"polite\"></div>');$main.insertBefore(\"body>script#script-sugarcube\")}},runUserScripts:{value:function(){_state===States.Init&&((()=>{const storyStyle=document.createElement(\"style\");new StyleWrapper(storyStyle).add(Story.getStyles().map((style=>style.text.trim())).join(\"\\n\")),jQuery(storyStyle).appendTo(document.head).attr({id:\"style-story\",type:\"text/css\"})})(),Story.getScripts().forEach((script=>{try{Scripting.evalJavaScript(script.text)}catch(ex){console.error(ex),Alert.error(script.name,getErrorMessage(ex))}})),Story.getWidgets().forEach((widget=>{try{Wikifier.wikifyEval(widget.processText())}catch(ex){console.error(ex),Alert.error(widget.name,getErrorMessage(ex))}})))}},runUserInit:{value:function(){if(_state===States.Init&&(Story.getInits().forEach((passage=>{try{const debugBuffer=Wikifier.wikifyEval(passage.text);if(Config.debug){const debugView=new DebugView(document.createDocumentFragment(),\"special\",`${passage.name} [init-tagged]`,`${passage.name} [init-tagged]`);debugView.modes({hidden:!0}),debugView.append(debugBuffer),_initDebugViews.push(debugView.output)}}catch(ex){console.error(ex),Alert.error(`${passage.name} [init-tagged]`,getErrorMessage(ex))}})),Story.has(\"StoryInit\")))try{const debugBuffer=Wikifier.wikifyEval(Story.get(\"StoryInit\").text);if(Config.debug){const debugView=new DebugView(document.createDocumentFragment(),\"special\",\"StoryInit\",\"StoryInit\");debugView.modes({hidden:!0}),debugView.append(debugBuffer),_initDebugViews.push(debugView.output)}}catch(ex){console.error(ex),Alert.error(\"StoryInit\",getErrorMessage(ex))}}},start:{value:function(){if(_state===States.Init){if(null==Config.passages.start)throw new Error(\"starting passage not selected\");if(!Story.has(Config.passages.start))throw new Error(`starting passage (\"${Config.passages.start}\") not found`);if(_state=States.Idle,document.documentElement.focus(),State.restore())engineShow();else{const autoloadType=typeof Config.saves._internal_autoload_;\"string\"===autoloadType?\"prompt\"===Config.saves._internal_autoload_&&(UI.buildAutoload(),Dialog.open()):new Promise(((resolve,reject)=>{if(Save.browser.size>0&&(\"boolean\"===autoloadType&&Config.saves._internal_autoload_||\"function\"===autoloadType&&Config.saves._internal_autoload_()))return resolve();reject()})).then((()=>{Save.browser.continue(),engineShow()})).catch((()=>{enginePlay(Config.passages.start)}))}}}},restart:{value:function(){LoadScreen.show(),window.scroll(0,0),State.reset(),triggerEvent(\":enginerestart\"),window.location.reload()}},state:{get:function(){return _state}},isIdle:{value:function(){return _state===States.Idle}},isPlaying:{value:function(){return _state!==States.Idle}},isRendering:{value:function(){return _state===States.Rendering}},lastPlay:{get:function(){return _lastPlay}},goTo:{value:function(index){const succeeded=State.goTo(index);return succeeded&&engineShow(),succeeded}},go:{value:engineGo},backward:{value:function(){return engineGo(-1)}},forward:{value:function(){return engineGo(1)}},show:{value:engineShow},play:{value:enginePlay},display:{value:function(title,link,option){console.warn(\"[DEPRECATED] Engine.display() is deprecated.\");let noHistory=!1;switch(option){case undefined:break;case\"replace\":case\"back\":noHistory=!0;break;default:throw new Error(`Engine.display option parameter called with obsolete value \"${option}\"; please notify the developer`)}enginePlay(title,noHistory)}},minDomActionDelay:{get:()=>DOM_DELAY}}))})();const idb=(()=>{if(null==window.indexedDB)return Object.freeze({lock:!0,init:()=>!1,get active(){return!1},set active(_){},get footerHTML(){return!1},set footerHTML(_){}});let lock=!0,active=!0,dbName=\"idb\",migrationNeeded=!1,open=!1,settings={};updateSettings();let db,saveDetails=[],openRequest=null;function openDB(name=dbName){return new Promise(((resolve,reject)=>{dbName=name,openRequest=indexedDB.open(idb.dbName),openRequest.onupgradeneeded=event=>{if(console.log(\"updating idb\",event.oldVersion),0===event.oldVersion)openRequest.result.createObjectStore(\"saves\",{keyPath:\"slot\"}),openRequest.result.createObjectStore(\"details\",{keyPath:\"slot\"}),migrationNeeded=!0},openRequest.onerror=()=>{console.log(\"error opening idb\",openRequest.error),reject(openRequest.error)},openRequest.onsuccess=()=>{db=openRequest.result,lock=!1,open=!0,getSaveDetails().then((d=>saveDetails=d)),console.log(\"idbOpen success\"),navigator.storage&&\"function\"==typeof navigator.storage.persist&&navigator.storage.persist(),db.onclose=ev=>{open=!1,active=!1,console.log(\"idb connection closed, this shouldn't happen\",ev),Errors?Errors.report(\"ERROR: idb connection closed unexpectedly\",ev):alert(\"ERROR: idb connection closed unexpectedly\")},db.onerror=ev=>{console.error(`Database error: ${ev.target.errorCode}`),active=!1},migrationNeeded&&(importFromLocalStorage(),migrationNeeded=!1),resolve(db)},openRequest.onblocked=()=>{console.log(\"something went wrong\",openRequest.error),reject(openRequest.error)}}))}function updateSettings(setting,value){settings=Serial.parse(localStorage.getItem(\"idb-settings\"))||{warnSave:!1,warnLoad:!1,warnDelete:!0,active:!window.FCHostPersistent,useDelta:!1},setting&&(settings[setting]=value),active=settings.active,localStorage.setItem(\"idb-settings\",Serial.stringify(settings))}updateSettings();const baddies=[];function funNuke(target,path=\"\",verbose=!0){if(!target)return console.log(\"no target specified\");for(const key in target){const value=target[key],newPath=`${path}['${key}']`;null==value||(\"function\"==typeof value||value.toJSON?(verbose&&V.idbTest&&console.log(`Warn: ${newPath} of type ${typeof value} shouldn't be in STORY variables!!!`),target[key]=Serial.stringify(value),baddies.push(newPath)):\"object\"==typeof value&&funNuke(value,newPath,verbose))}}function ekuNnuf(target=V,paths){function revive(target,path){if(\"string\"!=typeof path||\"\"===path)return console.log(\"Warn: invalid path\",clone(path));const accessors=path.slice(2,-2).split(\"']['\");let ref=target;for(let i=0,destination=accessors.length-1;i<=destination;i++)i===destination?ref[accessors[i]]=Serial.parse(ref[accessors[i]]):ref=ref[accessors[i]];return!0}let path=paths.shift();for(;path;){try{revive(target,path)}catch(ex){console.log(\"WARN: couldn't restore story var function\",path)}path=paths.shift()}}async function importFromLocalStorage(){function processSave(saveObj){const save=saveObj.state;save.delta&&(save.history=State.deltaDecode(save.delta)),delete save.delta,window.DoLSave&&DoLSave.decompressIfNeeded({state:save});const vars=save.history[save.index].variables;if(!vars.saveId){const saveId=Math.floor(9e4*Math.random())+1e4;save.history.forEach((s=>s.variables.saveId=saveId))}return[save,{date:saveObj.date,id:saveObj.id,title:saveObj.title,metadata:saveObj.metadata||{saveId:vars.saveId,saveName:vars.saveName}}]}const autoSaves=Save.browser.auto.entries();if(autoSaves.length>0){const saveData=processSave(Save.browser.auto.getFull(autoSaves[0].index));await setItem(0,saveData[0],{slot:0,data:saveData[1]})}const oldSaves=Save.browser.slot.entries();for(let i=0;i<oldSaves.length;i++){const saveData=processSave(Save.browser.slot.getFull(oldSaves[i].index));await setItem(i+1,saveData[0],{slot:i+1,data:saveData[1]})}return await getSaveDetails().then((d=>saveDetails=d)),console.log(\"idb migration successful\"),!0}function makePromise(transaction){return new Promise(((resolve,reject)=>{transaction.onsuccess=()=>(lock=!1,resolve(transaction.result)),transaction.oncomplete=()=>(lock=!1,resolve(transaction.result)),transaction.onerror=ev=>(lock=!1,active=!1,console.log(transaction.error,ev,\"error\"),reject(transaction.error)),transaction.onabort=()=>(lock=!1,console.log(\"aborted\",transaction.error),reject(transaction.error))}))}async function getItem(slot){open||await openDB();return makePromise(db.transaction(\"saves\",\"readonly\").objectStore(\"saves\").get(slot))}async function setItem(slot,saveObj,details={}){if(lock)return;if(null==saveObj||!saveObj.hasOwnProperty(\"history\"))return!1;lock=!0;const savesItem={slot:slot,data:saveObj},saveVars=saveObj.history[saveObj.index].variables,metadata={saveId:saveVars.saveId,saveName:saveVars.saveName};details=clone(details),details.slot??=slot,details.data??={},details.data.id??=Story.id,details.data.title??=Config.saves.descriptions(Save.Type.Slot),details.data.date??=Date.now(),details.data.metadata=metadata;try{open||await openDB();let counter=0;saveObj.history.forEach((s=>{baddies.splice(0),funNuke(s.variables,\"\",!counter++),baddies.length&&(s.baddies=clone(baddies))})),settings.useDelta&&(saveObj.delta=State.deltaEncode(saveObj.history),delete saveObj.history);const transactionRequest=db.transaction([\"saves\",\"details\"],\"readwrite\");return transactionRequest.objectStore(\"saves\").delete(slot),transactionRequest.objectStore(\"saves\").add(savesItem),transactionRequest.objectStore(\"details\").delete(slot),transactionRequest.objectStore(\"details\").add(details),makePromise(transactionRequest)}catch(ex){return window.Errors?Errors.report(`idb.setItem failure unknown. Couldn't complete the save in slot ${slot}`):alert(`idb.setItem failure unknown. Couldn't complete the save in slot ${slot}`),lock=!1,new Promise((resolve=>resolve(!1)))}}async function deleteItem(slot){if(lock)return;open||await openDB(),lock=!0;const transactionRequest=db.transaction([\"saves\",\"details\"],\"readwrite\");return transactionRequest.objectStore(\"saves\").delete(slot),transactionRequest.objectStore(\"details\").delete(slot),makePromise(transactionRequest).then(await getSaveDetails().then((d=>saveDetails=d)))}function loadState(slot){if(!lock)return getItem(slot).then((value=>{if(null==value)return!1;value.data.delta&&(value.data.history=State.deltaDecode(value.data.delta),delete value.data.delta),value.data.history.forEach((s=>{s.baddies&&(ekuNnuf(s.variables,s.baddies),delete s.baddies)})),Save.onLoad.handlers.forEach((fn=>fn({state:value.data}))),State.unmarshalForSave(value.data),Engine.show()}))}async function saveState(slot,title){if(lock)return;const saveObj=State.marshalForSave();if(!V.saveId){const saveId=Math.floor(9e4*Math.random())+1e4;V.saveId=saveId,State.history.forEach((s=>s.variables.saveId=saveId)),saveObj.history.forEach((s=>s.variables.saveId=saveId))}return Save.onSave.handlers.forEach((fn=>fn({state:saveObj,date:Date.now()},{type:slot<=0?\"autosave\":\"slot\"}))),null!=saveObj&&(await setItem(slot,saveObj,{data:{title:title}}),await getSaveDetails().then((d=>saveDetails=d)),!0)}async function getSaveDetails(){open||await openDB();return makePromise(db.transaction([\"details\"],\"readonly\").objectStore(\"details\").getAll())}async function clearAll(){if(lock)return;open||await openDB();const transactionRequest=db.transaction([\"saves\",\"details\"],\"readwrite\");return transactionRequest.objectStore(\"saves\").clear(),transactionRequest.objectStore(\"details\").clear(),saveDetails=[],makePromise(transactionRequest)}function savesAllowed(){return\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed()}let listLength,listPage;const listLengthMax=20,listPageMax=20;let extraSaveWarn,latestSave={slot:1,date:0},footerHTML=\"\";function generateSavesPage(page=listPage-1,length=listLength){const listContainer=document.createElement(\"div\");listContainer.id=\"saves-list\",listContainer.classList.add(\"idb-saves-list\"),listContainer.appendChild(function(){const frag=document.createDocumentFragment(),saveListHeader=document.createElement(\"div\");saveListHeader.className=\"savesListRow\",frag.appendChild(saveListHeader);const headerSaveGroup=document.createElement(\"div\");headerSaveGroup.className=\"saveGroup\",saveListHeader.appendChild(headerSaveGroup);const headerSaveId=document.createElement(\"div\");headerSaveId.className=\"saveId\",headerSaveId.innerText=\"#\",headerSaveGroup.appendChild(headerSaveId);const headerSaveButton=document.createElement(\"div\");headerSaveButton.className=\"saveButton\",headerSaveButton.innerText=L10n.get(\"savesHeaderSaveLoad\"),headerSaveGroup.appendChild(headerSaveButton);const headerSaveName=document.createElement(\"div\");headerSaveName.className=\"saveName\",headerSaveName.innerText=L10n.get(\"savesHeaderIDName\"),headerSaveGroup.appendChild(headerSaveName);const headerSaveDetails=document.createElement(\"div\");headerSaveDetails.className=\"saveDetails\",headerSaveDetails.innerText=L10n.get(\"savesHeaderDetails\"),headerSaveGroup.appendChild(headerSaveDetails);const headerDeleteButton=document.createElement(\"div\");return headerDeleteButton.className=\"deleteButton\",headerSaveGroup.appendChild(headerDeleteButton),frag}());const saveUnlock=savesAllowed();let autoSaveDate;if(latestSave={slot:1,date:0},saveDetails.forEach((d=>{0===d.slot?autoSaveDate=d.data.date:d.data.date>latestSave.date&&(latestSave.slot=d.slot,latestSave.date=d.data.date)})),!listLength){const slot=saveDetails.length?saveDetails.last().slot:0;for(listLength=10;slot>listLength*listPageMax&&listLength<listLengthMax;listLength++);length=listLength}if(!Number.isInteger(page)){const latestSlot=saveDetails.find((d=>d.slot===latestSave.slot));if(latestSlot){const autoSaveExists=0===saveDetails[0].slot,ignoreAutoSave=latestSlot.data.date>autoSaveDate||latestSlot.data.metadata.saveId===saveDetails[0].data.metadata.saveId;page=!autoSaveExists||ignoreAutoSave?Math.floor((latestSave.slot-1)/length):0}else page=0;listPage=page+1}const pageField=document.getElementById(\"pageNum\");null!=pageField&&(pageField.value=listPage);const lengthField=document.getElementById(\"pageLen\");null!=lengthField&&(lengthField.value=listLength);const defaultDetailsObj={date:\"\",title:\"\",metadata:{saveId:\"\",saveName:\"\"}},autoDetailsObj=saveDetails[0]&&0===saveDetails[0].slot?saveDetails[0].data:clone(defaultDetailsObj);autoSaveDate>latestSave.date&&(autoDetailsObj.latestSlot=!0),autoDetailsObj.slot=0,Save.browser.auto.isEnabled()&&listContainer.appendChild(generateSaveRow(autoDetailsObj));for(let slot=length*page+1;slot<length*(page+1)+1;slot++){let detailsObj=clone(defaultDetailsObj);const detailsIndex=saveDetails.findIndex((d=>d.slot===slot));-1!==detailsIndex&&(detailsObj=saveDetails[detailsIndex].data,Number(latestSave.slot)===slot&&(detailsObj.latestSlot=!0)),detailsObj.slot=slot,detailsObj.saveUnlock=saveUnlock,listContainer.appendChild(generateSaveRow(detailsObj))}return listContainer}function createActionItem(id,classNames,text,label,callback){const $btn=jQuery(document.createElement(\"button\")).attr(\"id\",`saves-${id}`).text(text);return classNames&&$btn.addClass(classNames),callback?$btn.ariaClick({label:label},callback):$btn.ariaDisabled(!0),jQuery(document.createElement(\"li\")).append($btn)}function generateFooterRow(){const $diskButtons=jQuery(document.createElement(\"ul\")).addClass(\"buttons slots\");if(Has.fileAPI){const diskLoadInput=function(id,callback){const input=document.createElement(\"input\");return jQuery(input).attr({id:id,type:\"file\",tabindex:-1,\"aria-hidden\":!0}).css({display:\"block\",visibility:\"hidden\",position:\"fixed\",left:\"-16128px\",top:\"-16128px\",width:\"1px\",height:\"1px\"}).on(\"change\",callback),input}(\"saves-disk-load-handler\",(ev=>{jQuery(document).one(\":dialogclosed\",(()=>{Save.disk.load(ev).then(Engine.show,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))})),Dialog.close()}));$diskButtons.append(createActionItem(\"disk-save\",null,`${L10n.get(\"textSave\")}…`,L10n.get(\"savesLabelDiskSave\"),\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Disk)?()=>{Save.disk.save(Story.name),Dialog.close()}:null)).append(createActionItem(\"disk-load\",null,`${L10n.get(\"textLoad\")}…`,L10n.get(\"savesLabelDiskLoad\"),(()=>diskLoadInput.click()))),jQuery(diskLoadInput).appendTo($diskButtons)}return $diskButtons.append(createActionItem(\"clipboard-save\",\"ui-close\",`${L10n.get(\"savesLabelToClipboard\")}…`,L10n.get(\"savesLabelToClipboard\"),\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Disk)?()=>Save.toClipboard():null)),$diskButtons.append(createActionItem(\"clear\",null,L10n.get(\"textClear\"),L10n.get(\"savesLabelBrowserClear\"),(()=>saveList(\"confirm clear\")))),$diskButtons}function createButton(id,classNames,kind,index,callback){let text;switch(id){case\"delete\":text=L10n.get(\"textDelete\");break;case\"load\":text=L10n.get(\"textLoad\");break;case\"save\":text=L10n.get(\"textSave\");break;default:throw new Error(`buildSaves unknown ID \"${id}\"`)}const $btn=jQuery(document.createElement(\"button\")).attr(\"id\",`saves-${id}-${index}`).addClass(id);return classNames&&$btn.addClass(classNames),callback?$btn.ariaClick({label:`${text} ${kind} ${index>0?index:\"Autosave\"}`},(()=>{try{callback(index)}catch(ex){openAlert(`${ex.message}.</p><p>${L10n.get(\"textAborting\")}.`)}})):$btn.ariaDisabled(!0),$btn}function generateSaveRow(details){const row=document.createElement(\"div\");details.latestSlot&&0!==details.slot&&(row.id=\"latestSaveRow\"),row.className=\"savesListRow\";const group=document.createElement(\"div\");group.className=\"saveGroup\";const saveId=document.createElement(\"div\");saveId.className=\"saveId\",saveId.innerText=0===details.slot?\"A\":details.slot,(details.slot>listPageMax*listLengthMax||details.slot<0)&&saveId.classList.add(\"red\");const saveLoad=document.createElement(\"div\");saveLoad.className=\"saveButton\";const $saveButton=createButton(\"save\",null,L10n.get(\"savesTextBrowserSlot\"),details.slot,details.saveUnlock?()=>saveList(\"confirm save\",details):null),$loadButton=createButton(\"load\",null,L10n.get(\"savesTextBrowserSlot\"),details.slot,details.date?()=>saveList(\"confirm load\",details):null);0!==details.slot&&$saveButton.appendTo(saveLoad),$loadButton.appendTo(saveLoad);const saveName=document.createElement(\"div\");saveName.className=\"saveName\",V.saveId===details.metadata.saveId&&saveName.classList.add(\"gold\"),saveName.innerText=details.metadata.saveName?details.metadata.saveName.slice(0,10):details.metadata.saveId;const saveDetails=document.createElement(\"div\");saveDetails.className=\"saveDetails\";const description=document.createElement(\"span\");description.innerText=details.title||\" \";const date=document.createElement(\"span\");date.className=\"datestamp\",details.date?(details.latestSlot?date.classList.add(\"green\"):details.date>Date.now()-18e5&&date.classList.add(\"gold\"),date.innerText=new Date(details.date).toLocaleString()):date.innerText=\" \",saveDetails.appendChild(description),saveDetails.appendChild(date);const $deleteButton=createButton(\"delete\",null,L10n.get(\"savesTextBrowserSlot\"),details.slot,details.date?()=>saveList(\"confirm delete\",details):null);return group.append(saveId,saveLoad,saveName,saveDetails),row.appendChild(group),$deleteButton.appendTo(row),row}const replaceChildren=!!document.body.replaceChildren;async function saveList(mode,details){open||await openDB(),active&&!settings.active&&updateSettings(\"active\",!0),mode||(await getSaveDetails().then((d=>saveDetails=d)),mode=\"show saves\"),await new Promise((r=>setTimeout((()=>r(!0)),0)));const savesDiv=document.getElementById(\"saveList\")||document.getElementsByClassName(\"saveList\")[0]||document.getElementsByClassName(\"saves\")[0],list=document.createDocumentFragment(),cancelButton=document.createElement(\"button\");function generateOldSaveDescription(details){const oldSaveDescription=document.createDocumentFragment();if(!details||!details.date)return oldSaveDescription;const oldSaveTitle=document.createElement(\"p\");oldSaveTitle.innerText=`${L10n.get(\"savesDescTitle\")} ${details.title}`;const oldSaveData=document.createElement(\"p\");return oldSaveData.innerText=`${details.metadata.saveName?L10n.get(\"savesDescName\")+details.metadata.saveName:L10n.get(\"savesDescId\")+details.metadata.saveId} ${L10n.get(\"savesDescDate\")} ${new Date(details.date).toLocaleString()}`,oldSaveDescription.append(oldSaveTitle,oldSaveData),oldSaveDescription}switch(cancelButton.className=\"saveMenuButton saveMenuConfirm\",cancelButton.innerText=L10n.get(\"textCancel\"),cancelButton.onclick=()=>saveList(\"show saves\"),mode){case\"show saves\":{if(!savesAllowed()){const notAllowedWarning=document.createElement(\"h3\");notAllowedWarning.className=\"red\",notAllowedWarning.innerText=V.replayScene?L10n.get(\"savesDisallowedReplay\"):L10n.get(\"savesDisallowed\"),list.appendChild(notAllowedWarning)}const exportReminder=document.createElement(\"p\");if(exportReminder.id=\"saves-export-reminder\",exportReminder.innerText=L10n.get(\"savesExportReminder\"),list.appendChild(exportReminder),extraSaveWarn){const lostSaves=document.createElement(\"p\");lostSaves.innerHTML='<i class=\"description\"><u>Where are my saves?</u></i> ';const lostSavesTooltip=document.createElement(\"mouse\");lostSavesTooltip.classList.add(\"tooltip\",\"linkBlue\"),lostSavesTooltip.innerText=\"(?)\",lostSavesTooltip.appendChild(document.createElement(\"span\")),lostSavesTooltip.lastChild.innerText=\"If you can't find your saves, it's possible you saved them using a different storage method. Try toggling the \\\"Use old legacy storage\\\" option below the saves list.\",lostSaves.appendChild(lostSavesTooltip),list.appendChild(lostSaves)}list.appendChild(generateSavesPage()),generateFooterRow().appendTo(list),footerHTML&&list.appendChild(function(){if(!footerHTML)return null;const container=document.createElement(\"ul\");return container.className=\"buttons\",container.innerHTML=footerHTML,container}()),list.appendChild(function(){const container=document.createElement(\"ul\");let li;container.className=\"buttons slots\",li=document.createElement(\"li\"),li.append(L10n.get(\"savesPagerPage\")),container.appendChild(li);const prevPage=document.createElement(\"button\");prevPage.append(\"<\"),listPage>1?(prevPage.classList.add(\"saveMenuButton\"),prevPage.onclick=()=>{--listPage,saveList(\"show saves\")}):prevPage.disabled=!0,li=document.createElement(\"li\"),li.appendChild(prevPage),container.appendChild(li);const pageNum=document.createElement(\"input\");Object.assign(pageNum,{id:\"pageNum\",type:\"number\",value:listPage,style:\"width: 3em\",min:1,max:listPageMax,onchange:()=>{listPage=Math.clamp(Math.round(pageNum.value),1,listPageMax),saveList(\"show saves\")}}),container.appendChild(pageNum);const nextPage=document.createElement(\"button\");nextPage.append(\">\"),listPage<listPageMax?(nextPage.classList.add(\"saveMenuButton\"),nextPage.onclick=()=>{++listPage,saveList(\"show saves\")}):nextPage.disabled=!0,nextPage.onclick=()=>{listPage<listPageMax&&listPage++,saveList(\"show saves\")},li=document.createElement(\"li\"),li.appendChild(nextPage),container.appendChild(li),li=document.createElement(\"li\"),li.append(L10n.get(\"savesPagerSavesPerPage\")),container.appendChild(li);const pageLen=document.createElement(\"input\");Object.assign(pageLen,{id:\"pageLen\",type:\"number\",value:listLength,style:\"width: 3em\",min:1,max:listLengthMax,onchange:()=>{listLength=Math.clamp(pageLen.value,1,listLengthMax),saveList(\"show saves\")}}),li=document.createElement(\"li\"),li.append(pageLen),container.appendChild(li);const jumpToLatest=document.createElement(\"button\");return jumpToLatest.className=\"saveMenuButton\",jumpToLatest.innerText=L10n.get(\"savesPagerJump\"),jumpToLatest.onclick=()=>{listPage=Math.floor((latestSave.slot-1)/listLength+1),saveList(\"show saves\"),setTimeout((()=>{const el=document.getElementById(\"latestSaveRow\");null!=el&&(el.classList.remove(\"jumpToSaveTransition\"),el.classList.add(\"jumpToSaveTransition\"))}),Engine.minDomActionDelay+100)},li=document.createElement(\"li\"),li.appendChild(jumpToLatest),container.appendChild(li),container}());const ul=document.createElement(\"ul\");let li;ul.className=\"buttons slots\",li=document.createElement(\"li\"),li.append(L10n.get(\"savesOptionsConfirmOn\")),ul.appendChild(li);const reqSaveLabel=document.createElement(\"label\");reqSaveLabel.innerText=`${L10n.get(\"savesOptionsOverwrite\")} `;const reqSave=document.createElement(\"input\");reqSave.type=\"checkbox\",reqSave.checked=settings.warnSave,reqSave.onchange=()=>updateSettings(\"warnSave\",reqSave.checked),reqSaveLabel.appendChild(reqSave),li=document.createElement(\"li\"),li.appendChild(reqSaveLabel),ul.appendChild(li);const reqLoadLabel=document.createElement(\"label\");reqLoadLabel.innerText=`${L10n.get(\"textLoad\")} `;const reqLoad=document.createElement(\"input\");reqLoad.type=\"checkbox\",reqLoad.checked=settings.warnLoad,reqLoad.onchange=()=>updateSettings(\"warnLoad\",reqLoad.checked),reqLoadLabel.appendChild(reqLoad),li=document.createElement(\"li\"),li.appendChild(reqLoadLabel),ul.append(\"|\",li);const reqDeleteLabel=document.createElement(\"label\");reqDeleteLabel.innerText=`${L10n.get(\"textDelete\")} `;const reqDelete=document.createElement(\"input\");reqDelete.type=\"checkbox\",reqDelete.checked=settings.warnDelete,reqDelete.onchange=()=>updateSettings(\"warnDelete\",reqDelete.checked),reqDeleteLabel.appendChild(reqDelete),li=document.createElement(\"li\"),li.appendChild(reqDeleteLabel),ul.append(\"|\",li),ul.append(document.createElement(\"li\"));const idbtoggle=document.createElement(\"button\");idbtoggle.id=\"saves-idb-toggle\",idbtoggle.className=\"saveMenuButton\",idbtoggle.innerText=L10n.get(\"savesOptionsUseLegacy\"),idbtoggle.onclick=()=>{updateSettings(\"active\",!1),window.DoLSave?$.wiki(\"<<replace #saveList>><<saveList>><</replace>>\"):UI.buildSaves()},li=document.createElement(\"li\"),li.appendChild(idbtoggle),ul.appendChild(li),list.appendChild(ul),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list));const pageField=document.getElementById(\"pageNum\");null!=pageField&&(pageField.value=listPage);const lengthField=document.getElementById(\"pageLen\");null!=lengthField&&(lengthField.value=listLength),Dialog.resize()}),Engine.minDomActionDelay);break}case\"confirm save\":{if(!details.date||!settings.warnSave&&details.metadata.saveId===V.saveId)return saveState(details.slot).then(window.closeOverlay());const confirmSaveWarning=document.createElement(\"div\");confirmSaveWarning.className=\"saveBorder\";const confirmSaveWarningTitle=document.createElement(\"h3\");if(confirmSaveWarningTitle.className=\"red\",confirmSaveWarningTitle.innerText=`${\"\"===details.date?L10n.get(\"savesWarningSaveOnSlot\"):L10n.get(\"savesWarningOverwriteSlot\")} ${details.slot}?`,details.date&&V.saveId!==details.metadata.saveId){const overwriteWarning=document.createElement(\"span\");overwriteWarning.className=\"red\",overwriteWarning.innerText=L10n.get(\"savesWarningOverwriteID\")}const saveButton=document.createElement(\"input\");Object.assign(saveButton,{type:\"button\",className:\"saveMenuButton saveMenuConfirm\",value:L10n.get(\"textSave\"),onclick:()=>saveState(details.slot).then((()=>window.closeOverlay()))}),confirmSaveWarning.append(confirmSaveWarningTitle,generateOldSaveDescription(details),saveButton,cancelButton),list.appendChild(confirmSaveWarning),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list))}),Engine.minDomActionDelay);break}case\"confirm delete\":{if(!settings.warnDelete)return deleteItem(details.slot).then((()=>saveList(\"show saves\")));const confirmDeleteWarning=document.createElement(\"div\");confirmDeleteWarning.className=\"saveBorder\";const confirmDeleteWarningTitle=document.createElement(\"h3\");confirmDeleteWarningTitle.className=\"red\",confirmDeleteWarningTitle.innerText=`${L10n.get(\"savesWarningDeleteInSlot\")+(0===details.slot?\"auto\":details.slot)}?`;const deleteButton=document.createElement(\"input\");Object.assign(deleteButton,{type:\"button\",className:\"saveMenuButton saveMenuConfirm\",value:L10n.get(\"textDelete\"),onclick:()=>deleteItem(details.slot).then((()=>saveList(\"show saves\")))}),confirmDeleteWarning.append(confirmDeleteWarningTitle,generateOldSaveDescription(details),deleteButton,cancelButton),list.appendChild(confirmDeleteWarning),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list))}),Engine.minDomActionDelay);break}case\"confirm load\":{if(!settings.warnLoad)return Dialog.close(),loadState(details.slot).then((()=>window.closeOverlay()));const confirmLoad=document.createElement(\"div\");confirmLoad.className=\"saveBorder\";const confirmLoadTitle=document.createElement(\"h3\");confirmLoadTitle.className=\"red\",confirmLoadTitle.innerText=`${L10n.get(\"savesWarningLoad\")+(0===details.slot?\"auto\":details.slot)}?`;const loadButton=document.createElement(\"input\");Object.assign(loadButton,{type:\"button\",className:\"saveMenuButton saveMenuConfirm\",value:L10n.get(\"textLoad\"),onclick:()=>{Dialog.close(),idb.loadState(details.slot).then((()=>window.closeOverlay()))}}),confirmLoad.append(confirmLoadTitle,generateOldSaveDescription(details),loadButton,cancelButton),list.appendChild(confirmLoad),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list))}),Engine.minDomActionDelay);break}case\"confirm clear\":{const confirmClear=document.createElement(\"div\");confirmClear.className=\"saveBorder\";const confirmClearTitle=document.createElement(\"h2\");confirmClearTitle.className=\"red\",confirmClearTitle.innerText=L10n.get(\"savesWarningDeleteAll\");const clearButton=document.createElement(\"input\");Object.assign(clearButton,{type:\"button\",className:\"saveMenuButton saveMenuConfirm\",value:L10n.get(\"textClear\"),onclick:()=>clearAll().then((()=>saveList(\"show saves\")))}),confirmClear.append(confirmClearTitle,clearButton,cancelButton),list.appendChild(confirmClear),setTimeout((()=>{replaceChildren?savesDiv.replaceChildren(list):(savesDiv.innerHTML=\"\",savesDiv.appendChild(list))}),Engine.minDomActionDelay);break}}}return void 0===window.closeOverlay&&(window.closeOverlay=Dialog.close),Object.freeze({get dbName(){return dbName},set dbName(val){dbName=val},get lock(){return lock},set lock(val){lock=Boolean(val)},get active(){return active},set active(val){active=val},get listLength(){return listLength},set listLength(val){listLength=val},get listPage(){return listPage},set listPage(val){listPage=val},getItem:getItem,setItem:setItem,deleteItem:deleteItem,clearAll:clearAll,getSaveDetails:getSaveDetails,getAllSaves:async function(){return open||await openDB(),makePromise(db.transaction([\"saves\"],\"readonly\").objectStore(\"saves\").getAll())},saveState:saveState,loadState:loadState,importFromLocalStorage:importFromLocalStorage,saveList:saveList,get footerHTML(){return footerHTML},set footerHTML(val){footerHTML=val},init:dbName=>openDB(dbName),close:function(){db.close(),open=!1},updateSettings:updateSettings,baddies:baddies,funNuke:funNuke,ekuNnuf:ekuNnuf})})();window.idb=idb;var Passage=(()=>{let tagsToSkip,decodePassageText;tagsToSkip=/^(?:debug|nobr|passage|widget|twine\\..*)$/i,decodePassageText=(()=>{const encodedRE=/\\r/g,hasEncodedRE=new RegExp(encodedRE.source);return function(str){if(null==str)return\"\";const val=String(str);return val&&hasEncodedRE.test(val)?val.replace(encodedRE,\"\"):val}})();return class{constructor(name,el){Object.defineProperties(this,{name:{value:decodeEntities(name)},element:{value:el||null},tags:{value:Object.freeze(el&&el.hasAttribute(\"tags\")?Array.from(new Set(el.getAttribute(\"tags\").trim().splitOrEmpty(/\\s+/))):[])}}),Object.defineProperties(this,{id:{value:`passage-${createSlug(this.name)}`},classes:{value:Object.freeze(0===this.tags.length?[]:(()=>this.tags.filter((tag=>!tagsToSkip.test(tag))).map((tag=>createSlug(tag))))())},domId:{get(){return this.id}},title:{get(){return this.name}}})}get className(){return this.classes.join(\" \")}get text(){if(null==this.element){const passage=encodeMarkup(this.name);return`<div class=\"error-view\"><span class=\"error\">${`${L10n.get(\"errorViewTitle\")}: ${L10n.get(\"errorNonexistentPassage\",{passage:passage})}`}</span></div>`}return decodePassageText(this.element.textContent)}processText(){if(null==this.element)return this.text;if(this.tags.includes(\"Twine.image\"))return`[img[${this.text}]]`;let processed=this.text;return Config.passages.onProcess&&(processed=Config.passages.onProcess.call(null,{title:this.name,tags:this.tags,text:processed})),(Config.passages.nobr||this.tags.includes(\"nobr\"))&&(processed=processed.replace(/^\\n+|\\n+$/g,\"\").replace(/\\n+/g,\" \")),processed}render(options){const frag=document.createDocumentFragment();return new Wikifier(frag,this.processText(),options),frag}description(){return`${L10n.get(\"textTurn\")} ${State.turns}`}}})(),Save=(()=>{const Type=enumFrom({Unknown:0,Auto:1,Slot:2,Disk:3,Base64:4,Autosave:1,Serialize:4}),MAX_INDEX=15,INDEX_DELIMITER=\":\",AUTO_SUBKEY=\"save.auto.\",AUTO_DATA_SUBKEY=`${AUTO_SUBKEY}data${INDEX_DELIMITER}`,AUTO_INFO_SUBKEY=`${AUTO_SUBKEY}info${INDEX_DELIMITER}`,SLOT_SUBKEY=\"save.slot.\",SLOT_DATA_SUBKEY=`${SLOT_SUBKEY}data${INDEX_DELIMITER}`,SLOT_INFO_SUBKEY=`${SLOT_SUBKEY}info${INDEX_DELIMITER}`,onLoadHandlers=new Set,onSaveHandlers=new Set;function createDetails(saveType,description,metadata){const metadataType=typeof metadata;if(\"object\"!==metadataType&&\"undefined\"!==metadataType)throw new TypeError(\"metadata parameter must be an object or null/undefined\");const cfgMetadata=Config.saves.metadata?Config.saves.metadata(saveType):undefined,cfgMetadataType=typeof cfgMetadata;if(\"object\"!==cfgMetadataType&&\"undefined\"!==cfgMetadataType)throw new TypeError(\"Config.saves.metadata function must return an object or null/undefined\");const details={type:saveType};let desc;null!=description&&(desc=String(description).trim()),desc||\"function\"!=typeof Config.saves.descriptions||(desc=Config.saves.descriptions(saveType),\"string\"==typeof desc&&(desc=desc.trim())),details.desc=desc||`${L10n.get(\"textTurn\")} ${State.turns}`;const fullMetadata=Object.assign({},cfgMetadata,metadata);return Object.keys(fullMetadata).length>0&&(details.metadata=fullMetadata),details}function findNewest(saveType){let keys;switch(saveType){case Type.Auto:keys=getKeys(isAutoInfoKey);break;case Type.Slot:keys=getKeys(isSlotInfoKey);break;default:keys=getKeys(isInfoKey)}switch(keys.length){case 0:return{index:-1};case 1:return{index:getIndexFromKey(keys[0]),type:getTypeFromKey(keys[0])}}return keys.map((key=>({value:{index:getIndexFromKey(key),type:getTypeFromKey(key)},date:storage.get(key).date}))).sort(((a,b)=>b.date-a.date)).first().value}function getIndexFromKey(key){const pos=key.lastIndexOf(INDEX_DELIMITER);if(-1===pos)throw new Error(`unable to get index from save key (received: ${key})`);return Number(key.slice(pos+1))}function getAutoInfoKeyFromIndex(index){return`${AUTO_INFO_SUBKEY}${index}`}function getAutoDataKeyFromIndex(index){return`${AUTO_DATA_SUBKEY}${index}`}function getSlotInfoKeyFromIndex(index){return`${SLOT_INFO_SUBKEY}${index}`}function getSlotDataKeyFromIndex(index){return`${SLOT_DATA_SUBKEY}${index}`}function getKeys(predicate){return storage.keys().filter(predicate)}function getTypeFromKey(key){return isAutoKey(key)?Type.Auto:Type.Slot}function isInfoKey(key){return key.startsWith(AUTO_INFO_SUBKEY)||key.startsWith(SLOT_INFO_SUBKEY)}function isAutoKey(key){return key.startsWith(AUTO_SUBKEY)}function isAutoInfoKey(key){return key.startsWith(AUTO_INFO_SUBKEY)}function isSlotKey(key){return key.startsWith(SLOT_SUBKEY)}function isSlotInfoKey(key){return key.startsWith(SLOT_INFO_SUBKEY)}function saveBlobToDiskAs(data,filename,extension){if(\"string\"!=typeof filename)throw new Error(\"filename parameter must be a string\");const baseName=createFilename(filename);if(\"\"===baseName)throw new Error(\"filename parameter must not consist solely of illegal characters\");const datestamp=function(date){if(!(date instanceof Date))throw new TypeError(\"createDatestamp date parameter must be a Date object\");let MM=date.getMonth()+1,DD=date.getDate(),hh=date.getHours(),mm=date.getMinutes(),ss=date.getSeconds();return MM<10&&(MM=`0${MM}`),DD<10&&(DD=`0${DD}`),hh<10&&(hh=`0${hh}`),mm<10&&(mm=`0${mm}`),ss<10&&(ss=`0${ss}`),`${date.getFullYear()}${MM}${DD}-${hh}${mm}${ss}`}(new Date);let saveName=`${baseName}-${datestamp}`;if(\"free-cities\"===Story.id&&\"save\"===extension)try{const vars=State.top.variables,arcologyName=vars.arcologies===undefined||0===vars.arcologies.length?\"New_Game_Setup\":vars.arcologies[0].name.replaceAll(\" \",\"_\").substring(0,20),week=String(vars.week||0).padStart(5,\"0\"),slaveCount=String(vars.slaves?.length||0).padStart(5,\"0\");saveName=`${baseName}-${arcologyName}-W${week}-S${slaveCount}-R${String(vars.releaseID||\"\").padStart(5,\"0\")}-${datestamp}`}catch(ex){console.error(ex),console.error(\"Could not find required data in V for the new naming scheme, falling back to the legacy naming scheme. See error above for details\")}const fileExt=createFilename(extension)||\"save\";saveAs(new Blob([data],{type:\"text/plain;charset=UTF-8\"}),`${saveName}.${fileExt}`)}function saveToBrowserStorage(saveData,compression=!0){const{data:data,dataKey:dataKey,info:info,infoKey:infoKey}=saveData;try{storage.set(dataKey,data,compression)&&(storage.set(infoKey,info)||storage.delete(dataKey))}catch(ex){throw storage.delete(dataKey),storage.delete(infoKey),ex}}function browserClear(){return autoClear(),slotClear(),!0}function browserIsEnabled(){return autoIsEnabled()||slotIsEnabled()}function autoClear(){return getKeys(isAutoKey).forEach((key=>storage.delete(key))),!0}function autoDelete(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.delete(getAutoInfoKeyFromIndex(index)),storage.delete(getAutoDataKeyFromIndex(index)),!0}function autoGet(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.get(getAutoInfoKeyFromIndex(index))}function autoHas(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.has(getAutoInfoKeyFromIndex(index))}function autoIsEnabled(){return\"cookie\"!==storage.name&&Config.saves.maxAutoSaves>0}function autoLoad(index){return new Promise((resolve=>{if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);if(Engine.state===Engine.States.Init)throw new Error(L10n.get(\"saveErrorLoadTooEarly\"));const info=storage.get(getAutoInfoKeyFromIndex(index)),data=storage.get(getAutoDataKeyFromIndex(index));if(!info||!data)throw new Error(L10n.get(\"saveErrorNonexistent\"));unmarshal(Object.assign(info,data)),resolve(!0)}))}function autoSave(desc,metadata){if(!autoIsEnabled()||\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed(Type.Auto))return!1;if(idb.active)return idb.saveState(0,desc),!0;const index=(findNewest(Type.Auto).index+1)%Config.saves.maxAutoSaves,infoKey=getAutoInfoKeyFromIndex(index),dataKey=getAutoDataKeyFromIndex(index),{info:info,data:data}=splitSave(marshal(createDetails(Type.Auto,desc,metadata)));saveToBrowserStorage({data:data,dataKey:dataKey,info:info,infoKey:infoKey},!1)}function slotClear(){return getKeys(isSlotKey).forEach((key=>storage.delete(key))),!0}function slotDelete(index){if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`slot save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.delete(getSlotInfoKeyFromIndex(index)),storage.delete(getSlotDataKeyFromIndex(index)),!0}function slotGet(index){if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`slot save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.get(getSlotInfoKeyFromIndex(index))}function slotHas(index){if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`slot save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);return storage.has(getSlotInfoKeyFromIndex(index))}function slotIsEnabled(){return\"cookie\"!==storage.name&&Config.saves.maxSlotSaves>0}function slotLoad(index){return new Promise((resolve=>{if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`slot save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);if(Engine.state===Engine.States.Init)throw new Error(L10n.get(\"saveErrorLoadTooEarly\"));const info=storage.get(getSlotInfoKeyFromIndex(index)),data=storage.get(getSlotDataKeyFromIndex(index));if(!info||!data)throw new Error(L10n.get(\"saveErrorNonexistent\"));unmarshal(Object.assign(info,data)),resolve(!0)}))}function slotSave(index,desc,metadata){if(!Number.isInteger(index))throw new TypeError(\"slot save index must be an integer\");if(index<0||index>=Config.saves.maxSlotSaves)throw new RangeError(`slot save index out of bounds (range: 0–${Config.saves.maxSlotSaves-1}; received: ${index})`);if(!slotIsEnabled()||\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed(Type.Slot))throw new Error(L10n.get(\"saveErrorDisallowed\"));const infoKey=getSlotInfoKeyFromIndex(index),dataKey=getSlotDataKeyFromIndex(index),{info:info,data:data}=splitSave(marshal(createDetails(Type.Slot,desc,metadata)));saveToBrowserStorage({data:data,dataKey:dataKey,info:info,infoKey:infoKey})}function slotSize(){return getKeys(isSlotInfoKey).length}function diskLoad(event){return new Promise(((resolve,reject)=>{const reader=new FileReader;jQuery(reader).on(\"loadend\",(()=>{try{if(Engine.state===Engine.States.Init)throw new Error(L10n.get(\"saveErrorLoadTooEarly\"));if(reader.error)throw new Error(`${L10n.get(\"saveErrorDiskLoadFail\")}: ${reader.error}`);let save;try{save=Serial.parse(LZString.decompressFromBase64(reader.result))}catch(ex){throw new Error(L10n.get(\"saveErrorDecodeFail\"))}unmarshal(save),resolve(save.metadata)}catch(ex){reject(ex)}})),reader.readAsText(event.target.files[0])}))}function diskSave(filename,metadata){if(null==filename)throw new Error(\"Save.disk.save filename parameter is required\");if(\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed(Type.Disk))throw new Error(L10n.get(\"saveErrorDisallowed\"));const details=createDetails(Type.Disk,filename,metadata);saveBlobToDiskAs(LZString.compressToBase64(Serial.stringify(marshal(details))),filename,\"save\")}function base64Load(base64){return new Promise((resolve=>{if(Engine.state===Engine.States.Init)throw new Error(L10n.get(\"saveErrorLoadTooEarly\"));let save;try{save=Serial.parse(LZString.decompressFromBase64(base64))}catch(ex){throw new Error(L10n.get(\"saveErrorDecodeFail\"))}unmarshal(save),resolve(save.metadata)}))}function base64Save(metadata){if(\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed(Type.Base64))throw new Error(L10n.get(\"saveErrorDisallowed\"));const details=createDetails(Type.Base64,null,metadata);return LZString.compressToBase64(Serial.stringify(marshal(details)))}function marshal(details){const save=Object.assign({},details,{date:Date.now(),id:Config.saves.id,state:State.marshalForSave()});return null!=Config.saves.version&&(save.version=Config.saves.version),onSaveHandlers.forEach((fn=>fn(save,function(save){switch(save.type){case Type.Auto:return{type:\"autosave\"};case Type.Slot:return{type:\"slot\"};case Type.Disk:return{type:\"disk\"};case Type.Base64:return{type:\"serialize\"}}throw new Error(`save.type must be an integer (received: ${typeof save.type})`)}(save)))),save.state.delta=State.deltaEncode(save.state.history),delete save.state.history,save}function splitSave(save){const{state:state,...info}=save;return{info:info,data:{state:state}}}function unmarshal(save){if(null==save||\"object\"!=typeof save||!Object.hasOwn(save,\"id\")||!Object.hasOwn(save,\"state\")||\"object\"!=typeof save.state||!Object.hasOwn(save.state,\"delta\"))throw new Error(L10n.get(\"saveErrorInvalidData\"));if(save.id!==Config.saves.id)throw new Error(L10n.get(\"saveErrorIdMismatch\"));if(save.state.history=State.deltaDecode(save.state.delta),delete save.state.delta,\"string\"==typeof save.type){switch(save.type){case\"auto\":case\"autosave\":save.type=Type.Auto;break;case\"slot\":save.type=Type.Slot;break;case\"disk\":save.type=Type.Disk;break;case\"base64\":case\"serialize\":save.type=Type.Base64}if(\"number\"!=typeof save.type)throw new Error(\"save.type is unknown\")}onLoadHandlers.forEach((fn=>fn(save))),State.unmarshalForSave(save.state)}return Object.preventExtensions(Object.create(null,{Type:{value:Type},MAX_INDEX:{get:()=>MAX_INDEX},init:{value:function(){return function(){const oldSaves=storage.get(\"saves\");if(null===oldSaves)return;if(autoClear(),slotClear(),oldSaves.autosave){const{info:info,data:data}=splitSave(oldSaves.autosave);info.desc=info.title,delete info.title,info.type=Type.Auto;const infoKey=getAutoInfoKeyFromIndex(0),dataKey=getAutoDataKeyFromIndex(0);storage.set(dataKey,data)&&(storage.set(infoKey,info)||storage.delete(dataKey))}oldSaves.slots.forEach(((save,index)=>{if(!save)return;const{info:info,data:data}=splitSave(save);info.desc=info.title,delete info.title,info.type=Type.Slot;const infoKey=getSlotInfoKeyFromIndex(index),dataKey=getSlotDataKeyFromIndex(index);storage.set(dataKey,data)&&(storage.set(infoKey,info)||storage.delete(dataKey))})),storage.delete(\"saves\")}(),function(){const index=storage.get(\"index\");if(storage.delete(\"index\"),null===index)return;if(null!==index.autosave){const autosave=storage.get(\"autosave\");storage.delete(\"autosave\");const{info:info,data:data}=splitSave(autosave);info.desc=info.title,delete info.title,info.type=Type.Auto;const infoKey=getAutoInfoKeyFromIndex(0),dataKey=getAutoDataKeyFromIndex(0);storage.set(dataKey,data)&&(storage.set(infoKey,info)||storage.delete(dataKey))}for(const[i,slot]of index.slots.entries()){if(null===slot)continue;const save=storage.get(`slot${i}`);storage.delete(`slot${i}`);const{info:info,data:data}=splitSave(save);info.desc=info.title,delete info.title,info.type=Type.Slot;const infoKey=getSlotInfoKeyFromIndex(i),dataKey=getSlotDataKeyFromIndex(i);storage.set(dataKey,data)&&(storage.set(infoKey,info)||storage.delete(dataKey))}}(),!0}},browser:{value:Object.preventExtensions(Object.create(null,{clear:{value:browserClear},continue:{value:function(){const newest=findNewest();return-1===newest.index?Promise.reject(new Error(L10n.get(\"saveErrorNonexistent\"))):newest.type===Type.Auto?autoLoad(newest.index):slotLoad(newest.index)}},isEnabled:{value:browserIsEnabled},size:{get:function(){return getKeys(isInfoKey).length}},auto:{value:Object.preventExtensions(Object.create(null,{clear:{value:autoClear},delete:{value:autoDelete},entries:{value:function(){return getKeys(isAutoInfoKey).map((key=>({index:getIndexFromKey(key),info:storage.get(key)}))).sort(((a,b)=>b.info.date-a.info.date))}},get:{value:autoGet},getFull:{value:function(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);const info=storage.get(getAutoInfoKeyFromIndex(index)),data=storage.get(getAutoDataKeyFromIndex(index));if(!info||!data)throw new Error(L10n.get(\"saveErrorNonexistent\"));return Object.assign(info,data)}},has:{value:autoHas},isEnabled:{value:autoIsEnabled},load:{value:autoLoad},save:{value:autoSave},size:{get:function(){return getKeys(isAutoInfoKey).length}}}))},slot:{value:Object.preventExtensions(Object.create(null,{clear:{value:slotClear},delete:{value:slotDelete},entries:{value:function(){return getKeys(isSlotInfoKey).map((key=>({index:getIndexFromKey(key),info:storage.get(key)}))).sort(((a,b)=>a.index-b.index))}},get:{value:slotGet},getFull:{value:function(index){if(!Number.isInteger(index))throw new TypeError(\"auto save index must be an integer\");if(index<0||index>MAX_INDEX)throw new RangeError(`auto save index out of bounds (range: 0–${MAX_INDEX}; received: ${index})`);const info=storage.get(getSlotInfoKeyFromIndex(index)),data=storage.get(getSlotDataKeyFromIndex(index));if(!info||!data)throw new Error(L10n.get(\"saveErrorNonexistent\"));return Object.assign(info,data)}},has:{value:slotHas},isEnabled:{value:slotIsEnabled},load:{value:slotLoad},save:{value:slotSave},size:{get:slotSize}}))}}))},disk:{value:Object.preventExtensions(Object.create(null,{export:{value:function(filename){if(null==filename)throw new Error(\"Save.browser.export filename parameter is required\");const auto=getKeys(isAutoInfoKey).map((infoKey=>{const index=getIndexFromKey(infoKey),info=storage.get(infoKey),data=storage.get(getAutoDataKeyFromIndex(index));if(!info||!data)throw new Error(\"during saves export auto save info or data nonexistent\");return{index:index,info:info,data:data}})),slot=getKeys(isSlotInfoKey).map((infoKey=>{const index=getIndexFromKey(infoKey),info=storage.get(infoKey),data=storage.get(getSlotDataKeyFromIndex(index));if(!info||!data)throw new Error(\"during saves export slot save info or data nonexistent\");return{index:index,info:info,data:data}}));saveBlobToDiskAs(LZString.compressToBase64(Serial.stringify({auto:auto,slot:slot})),filename,\"savesbundle\")}},import:{value:function(event){return new Promise(((resolve,reject)=>{const reader=new FileReader;jQuery(reader).on(\"loadend\",(()=>{try{if(reader.error)throw new Error(`${L10n.get(\"saveErrorDiskLoadFail\")}: ${reader.error}`);const badSave=O=>!Object.hasOwn(O,\"index\")||!Object.hasOwn(O,\"info\")||!Object.hasOwn(O,\"data\");let bundle;try{bundle=Serial.parse(LZString.decompressFromBase64(reader.result))}catch(ex){throw new Error(L10n.get(\"saveErrorDecodeFail\"))}if(null==bundle||\"object\"!=typeof bundle||!Object.hasOwn(bundle,\"auto\")||!(bundle.auto instanceof Array)||bundle.auto.some(badSave)||!Object.hasOwn(bundle,\"slot\")||!(bundle.slot instanceof Array)||bundle.slot.some(badSave))throw new Error(L10n.get(\"saveErrorInvalidData\"));autoClear(),slotClear(),bundle.auto.forEach((save=>saveToBrowserStorage({data:save.data,dataKey:getAutoDataKeyFromIndex(save.index),info:save.info,infoKey:getAutoInfoKeyFromIndex(save.index)},!1))),bundle.slot.forEach((save=>saveToBrowserStorage({data:save.data,dataKey:getSlotDataKeyFromIndex(save.index),info:save.info,infoKey:getSlotInfoKeyFromIndex(save.index)}))),resolve(!0)}catch(ex){reject(ex)}})),reader.readAsText(event.target.files[0])}))}},load:{value:diskLoad},save:{value:diskSave}}))},base64:{value:Object.preventExtensions(Object.create(null,{export:{value:function(){const auto=getKeys(isAutoInfoKey).map((infoKey=>{const index=getIndexFromKey(infoKey),info=storage.get(infoKey),data=storage.get(getAutoDataKeyFromIndex(index));if(!info||!data)throw new Error(\"during saves export auto save info or data nonexistent\");return{index:index,info:info,data:data}})),slot=getKeys(isSlotInfoKey).map((infoKey=>{const index=getIndexFromKey(infoKey),info=storage.get(infoKey),data=storage.get(getSlotDataKeyFromIndex(index));if(!info||!data)throw new Error(\"during saves export slot save info or data nonexistent\");return{index:index,info:info,data:data}}));return LZString.compressToBase64(Serial.stringify({auto:auto,slot:slot}))}},import:{value:function(base64){return new Promise((resolve=>{const badSave=O=>!Object.hasOwn(O,\"index\")||!Object.hasOwn(O,\"info\")||!Object.hasOwn(O,\"data\");let bundle;try{bundle=Serial.parse(LZString.decompressFromBase64(base64))}catch(ex){throw new Error(L10n.get(\"saveErrorDecodeFail\"))}if(null==bundle||\"object\"!=typeof bundle||!Object.hasOwn(bundle,\"auto\")||!(bundle.auto instanceof Array)||bundle.auto.some(badSave)||!Object.hasOwn(bundle,\"slot\")||!(bundle.slot instanceof Array)||bundle.slot.some(badSave))throw new Error(L10n.get(\"saveErrorInvalidData\"));autoClear(),slotClear(),bundle.auto.forEach((save=>saveToBrowserStorage({data:save.data,dataKey:getAutoDataKeyFromIndex(save.index),info:save.info,infoKey:getAutoInfoKeyFromIndex(save.index)},!1))),bundle.slot.forEach((save=>saveToBrowserStorage({data:save.data,dataKey:getSlotDataKeyFromIndex(save.index),info:save.info,infoKey:getSlotInfoKeyFromIndex(save.index)}))),resolve(!0)}))}},load:{value:base64Load},save:{value:base64Save}}))},toClipboard:{value:function(){if(\"function\"==typeof Config.saves.isAllowed&&!Config.saves.isAllowed())return void(Dialog.isOpen()?$(document).one(\":dialogclosed\",(()=>UI.alert(L10n.get(\"savesDisallowed\")))):UI.alert(L10n.get(\"savesDisallowed\")));const details=createDetails(Type.Disk);!function(text){navigator.clipboard?navigator.clipboard.writeText(text).then((()=>console.log(\"Async: Copying save data to clipboard was successful!\")),(err=>console.error(\"Async: Could not copy save data: \",err))):function(text){const textArea=document.createElement(\"textarea\");textArea.value=text,textArea.style.top=\"0\",textArea.style.left=\"0\",textArea.style.position=\"fixed\",document.body.appendChild(textArea),textArea.focus(),textArea.select();try{const msg=document.execCommand(\"copy\")?\"successful\":\"unsuccessful\";console.log(\"Fallback: Copying save data was\",msg)}catch(err){console.error(\"Fallback: Oops, unable to copy save data\",err)}document.body.removeChild(textArea)}(text)}(LZString.compressToBase64(Serial.stringify(marshal(details))))}},onLoad:{value:Object.preventExtensions(Object.create(null,{add:{value:function(handler){const valueType=getTypeOf(handler);if(\"function\"!==valueType)throw new TypeError(`Save.onLoad.add handler parameter must be a function (received: ${valueType})`);onLoadHandlers.add(handler)}},clear:{value:function(){onLoadHandlers.clear()}},delete:{value:function(handler){return onLoadHandlers.delete(handler)}},size:{get:function(){return onLoadHandlers.size}},handlers:{get:()=>onLoadHandlers}}))},onSave:{value:Object.preventExtensions(Object.create(null,{add:{value:function(handler){const valueType=getTypeOf(handler);if(\"function\"!==valueType)throw new TypeError(`Save.onSave.add handler parameter must be a function (received: ${valueType})`);onSaveHandlers.add(handler)}},clear:{value:function(){onSaveHandlers.clear()}},delete:{value:function(handler){return onSaveHandlers.delete(handler)}},size:{get:function(){return onSaveHandlers.size}},handlers:{get:()=>onSaveHandlers}}))},get:{value(){throw new Error(\"[REMOVED] Save.get() has been removed.\")}},clear:{value:()=>(console.warn(\"[DEPRECATED] Save.clear() is deprecated.\"),browserClear())},ok:{value:()=>(console.warn(\"[DEPRECATED] Save.ok() is deprecated.\"),browserIsEnabled())},autosave:{value:Object.preventExtensions(Object.create(null,{ok:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.ok() is deprecated.\"),autoIsEnabled())},has:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.has() is deprecated.\"),autoHas(0))},get:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.get() is deprecated.\"),autoGet(0))},load:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.load() is deprecated.\"),autoLoad(0))},save:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.autosave.save() is deprecated.\"),autoSave(...args))},delete:{value:()=>(console.warn(\"[DEPRECATED] Save.autosave.delete() is deprecated.\"),autoDelete(0))}}))},slots:{value:Object.preventExtensions(Object.create(null,{ok:{value:()=>(console.warn(\"[DEPRECATED] Save.slots.ok() is deprecated.\"),slotIsEnabled())},length:{get:()=>(console.warn(\"[DEPRECATED] Save.slots.length is deprecated.\"),Config.saves.maxSlotSaves)},isEmpty:{value:()=>(console.warn(\"[DEPRECATED] Save.slots.isEmpty() is deprecated.\"),0===slotSize())},count:{value:()=>(console.warn(\"[DEPRECATED] Save.slots.count() is deprecated.\"),slotSize())},has:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.has() is deprecated.\"),slotHas(...args))},get:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.get() is deprecated.\"),slotGet(...args))},load:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.load() is deprecated.\"),slotLoad(...args))},save:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.save() is deprecated.\"),slotSave(...args))},delete:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.slots.delete() is deprecated.\"),slotDelete(...args))}}))},export:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.export() is deprecated.\"),diskSave(...args))},import:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.import() is deprecated.\"),diskLoad(...args))},serialize:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.serialize() is deprecated.\"),base64Save(...args))},deserialize:{value:(...args)=>(console.warn(\"[DEPRECATED] Save.deserialize() is deprecated.\"),base64Load(...args))}}))})(),Setting=(()=>{const Types=enumFrom({Header:0,Toggle:1,List:2,Range:3,Value:4}),_definitions=[];function updateSettingsObject(value){window.SugarCube.settings=settings=value}function createResultObject(def){const result={name:def.name,value:settings[def.name],default:def.default};return Object.hasOwn(def,\"list\")&&(result.list=def.list),Object.hasOwn(def,\"min\")&&(result.min=def.min),Object.hasOwn(def,\"max\")&&(result.max=def.max),Object.hasOwn(def,\"step\")&&(result.step=def.step),result}function clear(){return updateSettingsObject(create()),storage.delete(\"settings\"),!0}function create(){return Object.create(null)}function load(){const defaultSettings=create(),loadedSettings=storage.get(\"settings\")||create();_definitions.filter((def=>def.type!==Types.Header)).forEach((def=>defaultSettings[def.name]=def.default)),updateSettingsObject(Object.assign(defaultSettings,loadedSettings))}function save(){const savedSettings=create();return Object.keys(settings).length>0&&_definitions.filter((def=>def.type!==Types.Header&&settings[def.name]!==def.default)).forEach((def=>savedSettings[def.name]=settings[def.name])),0===Object.keys(savedSettings).length?(storage.delete(\"settings\"),!0):storage.set(\"settings\",savedSettings)}function add(type,name,def){if(arguments.length<2){const errors=[];throw arguments.length<1&&errors.push(\"type\"),arguments.length<2&&errors.push(\"name\"),new Error(`missing parameters, no ${errors.join(\" or \")} specified`)}if(null==def)def={};else if(\"object\"!=typeof def)throw new TypeError(\"definition parameter must be an object\");if(has(name))throw new Error(`cannot clobber existing setting \"${name}\"`);const definition={type:type,name:name};if(type!==Types.Value&&(definition.label=\"string\"==typeof def.label?def.label.trim():\"\"),\"string\"==typeof def.desc){const desc=def.desc.trim();\"\"!==desc&&(definition.desc=desc)}switch(type){case Types.Header:break;case Types.List:if(!Object.hasOwn(def,\"list\"))throw new Error(\"no list specified\");if(!Array.isArray(def.list))throw new TypeError(\"list must be an array\");if(0===def.list.length)throw new Error(\"list must not be empty\");if(definition.list=Object.freeze(def.list),null==def.default)definition.default=def.list[0];else{const defaultIndex=def.list.indexOf(def.default);if(-1===defaultIndex)throw new Error(\"list does not contain default\");definition.default=def.list[defaultIndex]}break;case Types.Range:if(!Object.hasOwn(def,\"min\"))throw new Error(\"no min specified\");if(\"number\"!=typeof def.min||Number.isNaN(def.min)||!Number.isFinite(def.min))throw new TypeError(\"min must be a finite number\");if(!Object.hasOwn(def,\"max\"))throw new Error(\"no max specified\");if(\"number\"!=typeof def.max||Number.isNaN(def.max)||!Number.isFinite(def.max))throw new TypeError(\"max must be a finite number\");if(!Object.hasOwn(def,\"step\"))throw new Error(\"no step specified\");if(\"number\"!=typeof def.step||Number.isNaN(def.step)||!Number.isFinite(def.step)||def.step<=0)throw new TypeError(\"step must be a finite number greater than zero\");{const fracDigits=(()=>{const str=String(def.step),pos=str.lastIndexOf(\".\");return-1===pos?0:str.length-pos-1})();function stepValidate(value){if(fracDigits>0){const ma=Number(`${def.min}e${fracDigits}`),sa=Number(`${def.step}e${fracDigits}`),va=Number(`${value}e${fracDigits}`)-ma;return Number(`${va-va%sa+ma}e-${fracDigits}`)}const va=value-def.min;return va-va%def.step+def.min}if(stepValidate(def.max)!==def.max)throw new RangeError(`max (${def.max}) is not a multiple of the step (${def.step}) plus the min (${def.min})`)}if(definition.max=def.max,definition.min=def.min,definition.step=def.step,null==def.default)definition.default=def.max;else{if(\"number\"!=typeof def.default||Number.isNaN(def.default)||!Number.isFinite(def.default))throw new TypeError(\"default must be a finite number\");if(def.default<def.min)throw new RangeError(`default (${def.default}) is less than min (${def.min})`);if(def.default>def.max)throw new RangeError(`default (${def.default}) is greater than max (${def.max})`);definition.default=def.default}break;case Types.Toggle:definition.default=Boolean(def.default);break;case Types.Value:definition.default=def.default;break;default:throw new Error(`unknown Setting type: ${type}`)}\"function\"==typeof def.onInit&&(definition.onInit=Object.freeze(def.onInit)),\"function\"==typeof def.onChange&&(definition.onChange=Object.freeze(def.onChange)),_definitions.push(Object.freeze(definition))}function get(name){return _definitions.find((definition=>definition.name===name))}function has(name){return _definitions.some((definition=>definition.name===name))}return Object.preventExtensions(Object.create(null,{Types:{value:Types},init:{value:function(){load(),_definitions.forEach((def=>{if(Object.hasOwn(def,\"onInit\")){const data=createResultObject(def);def.onInit.call(data,data)}}))}},clear:{value:clear},create:{value:create},load:{value:load},reset:{value:function(name){if(0===arguments.length)clear(),load();else{if(null==name||!has(name))throw new Error(`nonexistent setting \"${name}\"`);const def=get(name);def.type!==Types.Header&&(settings[name]=def.default)}return save()}},save:{value:save},add:{value:add},addHeader:{value:function(name,desc){add(Types.Header,name,{desc:desc})}},addList:{value:function(...args){add(Types.List,...args)}},addRange:{value:function(...args){add(Types.Range,...args)}},addToggle:{value:function(...args){add(Types.Toggle,...args)}},addValue:{value:function(...args){add(Types.Value,...args)}},delete:{value:function(name){for(let i=0;i<_definitions.length;++i)if(_definitions[i].name===name){_definitions.splice(i,1);break}Object.hasOwn(settings,name)&&delete settings[name]}},forEach:{value:function(callback,thisArg){_definitions.forEach(callback,thisArg)}},get:{value:get},has:{value:has},isEmpty:{value:function(){return 0===_definitions.length}},getValue:{value:function(name){return settings[name]}},setValue:{value:function(name,value){if(!has(name))throw new Error(\"no such setting\");settings[name]=value,save();const def=get(name);if(Object.hasOwn(def,\"onChange\")){const data=createResultObject(def);def.onChange.call(data,data)}return!0}}}))})(),Story=(()=>{let _ifId=\"\",_id=\"\",_name=\"\";const _passages=createPassageStore(),_inits=[],_scripts=[],_styles=[],_widgets=[],codePassageNames=[\"PassageDone\",\"PassageFooter\",\"PassageHeader\",\"PassageReady\",\"StoryAuthor\",\"StoryBanner\",\"StoryCaption\",\"StoryDisplayTitle\",\"StoryInit\",\"StoryInterface\",\"StoryMenu\",\"StoryShare\",\"StorySubtitle\"],codeTagNames=[\"init\",\"widget\"];function createPassageStore(passages){const store=Object.create(null);return passages?Object.assign(store,passages):store}function generateName(rawName){if(null==rawName)throw new Error(\"story name must not be null or undefined\");const name=decodeEntities(String(rawName)).trim();if(\"\"===name)throw new Error(\"story name must not be empty or consist solely of whitespace\");return name}function getId(){return _id}function getName(){return _name}function filter(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"Story.filter() predicate parameter must be a function\");const results=[];for(let i=0,keys=Object.keys(_passages);i<keys.length;++i){const passage=_passages[keys[i]];predicate.call(void 0===thisArg?this:thisArg,passage)&&results.push(passage)}return results}return Object.preventExtensions(Object.create(null,{init:{value:function(){function assertNoCodeTags(passage,desc){if(passage.tags.includesAny(codeTagNames))throw new Error(`${desc} passage \"${passage.name}\" includes code tags; invalid: \"${passage.tags.filter((tag=>codeTagNames.includes(tag))).sort().join('\", \"')}\"`)}function assertValidCodeTagUsage(passage){const found=passage.tags.filter((tag=>codeTagNames.includes(tag))).sort();if(found.length>1)throw new Error(`passage \"${passage.name}\" includes multiple code tags; invalid: \"${found.join('\", \"')}\"`)}{const $storydata=jQuery(\"tw-storydata\"),startNode=$storydata.attr(\"startnode\")||\"\";Config.passages.start=null,Config.debug=/\\bdebug\\b/.test($storydata.attr(\"options\")),$storydata.children(\"style\").each((function(i){_styles.push(new Passage(`tw-user-style-${i}`,this))})),$storydata.children(\"script\").each((function(i){_scripts.push(new Passage(`tw-user-script-${i}`,this))})),$storydata.children('tw-passagedata:not([tags~=\"Twine.private\"],[tags~=\"annotation\"])').each((function(){const $this=jQuery(this),pid=$this.attr(\"pid\")||\"\",passage=new Passage($this.attr(\"name\"),this);pid===startNode&&\"\"!==startNode?(Config.passages.start=passage.name,assertNoCodeTags(passage,\"starting\"),_passages[passage.name]=passage):codePassageNames.includes(passage.name)?(assertNoCodeTags(passage,\"code\"),_passages[passage.name]=passage):passage.tags.includes(\"init\")?(assertValidCodeTagUsage(passage),_inits.push(passage)):passage.tags.includes(\"widget\")?(assertValidCodeTagUsage(passage),_widgets.push(passage)):_passages[passage.name]=passage})),_ifId=$storydata.attr(\"ifid\"),_name=generateName(\"{{STORY_NAME}}\")}_id=function(name){let id=createSlug(name);if(\"\"===id)if(\"\"!==_ifId)id=_ifId;else for(let i=0;i<name.length;++i){const{char:char,start:start,end:end}=charAndPosAt(name,i);id+=char.codePointAt(0).toString(16),i+=end-start}return id}(_name),Config.saves.id=_id,document.title=_name}},id:{get:getId},ifId:{get:function(){return _ifId}},name:{get:getName},add:{value:function(descriptor){if(\"Object\"!==getTypeOf(descriptor))throw new TypeError(\"Story.add() descriptor parameter must be a generic object\");if(Object.hasOwn(_passages,descriptor.name))return!1;const elem=document.createElement(\"div\");elem.setAttribute(\"name\",descriptor.name),elem.setAttribute(\"tags\",descriptor.tags),elem.textContent=descriptor.text;const passage=new Passage(descriptor.name,elem);if(codePassageNames.includes(passage.name))throw new Error(`Story.add() passage descriptor object \"${passage.name}\" must not be a code passage`);if(passage.tags.includesAny(codeTagNames))throw new Error(`Story.add() passage descriptor object \"${passage.name}\" must not include code tags`);return _passages[passage.name]=passage,!0}},addDirect:{value:function(passage){return _passages[passage.name]=passage,!0}},delete:{value:function(name){let type=typeof name;switch(type){case\"number\":case\"string\":{const key=String(name);if(!Object.hasOwn(_passages,key))return!1;if(key===Config.passages.start||codePassageNames.includes(key))throw new Error(`Story.delete() passage \"${key}\" must not be a code passage`);if(_passages[key].tags.includesAny(codeTagNames))throw new Error(`Story.delete() passage \"${key}\" must not include code tags`);return delete _passages[key],!0}case\"undefined\":break;case\"object\":type=null===name?\"null\":\"an object\";break;default:type=`a ${type}`}throw new TypeError(`Story.delete() name parameter cannot be ${type}`)}},filter:{value:filter},find:{value:function(predicate,thisArg){if(\"function\"!=typeof predicate)throw new TypeError(\"Story.find() predicate parameter must be a function\");for(let i=0,keys=Object.keys(_passages);i<keys.length;++i){const passage=_passages[keys[i]];if(predicate.call(void 0===thisArg?this:thisArg,passage))return passage}}},get:{value:function(name){let type=typeof name;switch(type){case\"number\":case\"string\":{const key=String(name);return Object.hasOwn(_passages,key)?_passages[key]:new Passage(key||\"(unknown)\")}case\"undefined\":break;case\"object\":type=null===name?\"null\":\"an object\";break;default:type=`a ${type}`}throw new TypeError(`Story.get() name parameter cannot be ${type}`)}},getInits:{value:function(){return Object.freeze(Array.from(_inits))}},getNormals:{value:function(){return Object.freeze(createPassageStore(_passages))}},getScripts:{value:function(){return Object.freeze(Array.from(_scripts))}},getStyles:{value:function(){return Object.freeze(Array.from(_styles))}},getWidgets:{value:function(){return Object.freeze(Array.from(_widgets))}},has:{value:function(name){let type=typeof name;switch(type){case\"number\":case\"string\":return Object.hasOwn(_passages,String(name));case\"undefined\":break;case\"object\":type=null===name?\"null\":\"an object\";break;default:type=`a ${type}`}throw new TypeError(`Story.has name parameter cannot be ${type}`)}},domId:{get:()=>(console.warn(\"[DEPRECATED] Story.domId is deprecated.\"),getId())},title:{get:()=>(console.warn(\"[DEPRECATED] Story.title is deprecated.\"),getName())},lookup:{value:function(key,value,sortKey=\"name\"){return console.warn(\"[DEPRECATED] Story.lookup() is deprecated.\"),filter((passage=>\"object\"==typeof passage[key]&&null!==passage[key]?passage[key]instanceof Array&&passage[key].some((m=>sameValueZero(m,value))):sameValueZero(passage[key],value))).sort(((a,b)=>a[sortKey]==b[sortKey]?0:a[sortKey]<b[sortKey]?-1:1))}},lookupWith:{value:function(predicate,sortKey=\"name\"){if(console.warn(\"[DEPRECATED] Story.lookupWith() is deprecated.\"),\"function\"!=typeof predicate)throw new TypeError(\"Story.lookupWith() predicate parameter must be a function\");return filter(predicate).sort(((a,b)=>a[sortKey]==b[sortKey]?0:a[sortKey]<b[sortKey]?-1:1))}}}))})(),UI=(()=>{function assembleLinkList(passage,listEl){let list=listEl;const debugState=Config.debug;Config.debug=!1;try{null==list&&(list=document.createElement(\"ul\"));const frag=document.createDocumentFragment();new Wikifier(frag,Story.get(passage).processText().trim(),{cleanup:!1});const errors=Array.from(frag.querySelectorAll(\".error\")).map((errEl=>errEl.textContent.replace(errorPrologRegExp,\"\")));if(errors.length>0)throw new Error(errors.join(\"; \"));for(;frag.hasChildNodes();){const node=frag.firstChild;if(node.nodeType===Node.ELEMENT_NODE&&\"A\"===node.nodeName.toUpperCase()){const li=document.createElement(\"li\");list.appendChild(li),li.appendChild(node)}else frag.removeChild(node)}}finally{Config.debug=debugState}return list}function buildRestart(){return Dialog.create(L10n.get(\"restartTitle\"),\"restart\").append(`<p>${L10n.get(\"restartMesgPrompt\")}</p><ul class=\"buttons\"><li><button id=\"restart-ok\">${L10n.get([\"restartTextOk\",\"textOk\"])}</button></li><li><button id=\"restart-cancel\" class=\"ui-close\">${L10n.get([\"restartTextCancel\",\"textCancel\"])}</button></li></ul>`),jQuery(Dialog.body()).find(\"#restart-ok\").ariaClick({one:!0},(()=>{jQuery(document).one(\":dialogclosed\",(()=>Engine.restart())),Dialog.close()})),!0}function buildSaves(){function createFileInput(id,callback){const input=document.createElement(\"input\");return jQuery(input).attr({id:id,type:\"file\",tabindex:-1,\"aria-hidden\":!0}).css({display:\"block\",visibility:\"hidden\",position:\"fixed\",left:\"-16128px\",top:\"-16128px\",width:\"1px\",height:\"1px\"}).on(\"change\",callback),input}function createActionItem(id,classNames,text,label,callback){const $btn=jQuery(document.createElement(\"button\")).attr(\"id\",`saves-${id}`).text(text);return classNames&&$btn.addClass(classNames),callback?$btn.ariaClick({label:label},callback):$btn.ariaDisabled(!0),jQuery(document.createElement(\"li\")).append($btn)}const browserEnabled=Save.browser.isEnabled();if(!browserEnabled&&!Has.fileAPI)return openAlert(L10n.get(\"warningNoSaves\")),!1;Dialog.create(L10n.get(\"savesTitle\"),\"saves\");const $dialogBody=jQuery(Dialog.body());if(browserEnabled){jQuery(document.createElement(\"h2\")).text(L10n.get(\"savesHeaderBrowser\")).appendTo($dialogBody),$dialogBody.append(function(){function createButton(id,classNames,kind,index,callback){let text;switch(id){case\"delete\":text=L10n.get(\"textDelete\");break;case\"load\":text=L10n.get(\"textLoad\");break;case\"save\":text=L10n.get(\"textSave\");break;default:throw new Error(`buildSaves unknown ID \"${id}\"`)}const $btn=jQuery(document.createElement(\"button\")).attr(\"id\",`saves-${id}-${index}`).addClass(id);return classNames&&$btn.addClass(classNames),callback?$btn.ariaClick({label:`${text} ${kind} ${index+1}`},(()=>{try{callback(index)}catch(ex){openAlert(`${ex.message}.</p><p>${L10n.get(\"textAborting\")}.`)}})):$btn.ariaDisabled(!0),$btn}const $tbody=jQuery(document.createElement(\"tbody\"));Save.browser.auto.entries().forEach((({index:index,info:info})=>{const $tdSlot=jQuery(document.createElement(\"td\")),$tdLoad=jQuery(document.createElement(\"td\")),$tdDesc=jQuery(document.createElement(\"td\")),$tdDele=jQuery(document.createElement(\"td\"));jQuery(document.createElement(\"div\")).text(info.desc).appendTo($tdDesc),jQuery(document.createElement(\"div\")).addClass(\"details\").addClass(\"datestamp\").text(`${L10n.get(\"savesTextBrowserAuto\")} ${index+1}  •  `).append(info.date?`${new Date(info.date).toLocaleString()}`:`<em>${L10n.get(\"savesTextNoDate\")}</em>`).appendTo($tdDesc),$tdLoad.append(createButton(\"load\",\"ui-close\",L10n.get(\"savesTextBrowserAuto\"),index,(index=>{jQuery(document).one(\":dialogclosed\",(()=>{Save.browser.auto.load(index).then(Engine.show,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))}))}))),$tdDele.append(createButton(\"delete\",null,L10n.get(\"savesTextBrowserAuto\"),index,(index=>{Save.browser.auto.delete(index),buildSaves()}))),jQuery(document.createElement(\"tr\")).append($tdSlot).append($tdLoad).append($tdDesc).append($tdDele).appendTo($tbody)}));const slotAllowed=\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Slot);return Save.browser.slot.entries().reduce(((slots,entry)=>(slots[entry.index]=entry,slots)),Array.from({length:Config.saves.maxSlotSaves},((_,i)=>({index:i})))).forEach((({index:index,info:info})=>{const $tdSlot=jQuery(document.createElement(\"td\")),$tdLoad=jQuery(document.createElement(\"td\")),$tdDesc=jQuery(document.createElement(\"td\")),$tdDele=jQuery(document.createElement(\"td\"));info?(jQuery(document.createElement(\"div\")).text(info.desc).appendTo($tdDesc),jQuery(document.createElement(\"div\")).addClass(\"details\").addClass(\"datestamp\").text(`${L10n.get(\"savesTextBrowserSlot\")} ${index+1}  •  `).append(info.date?`${new Date(info.date).toLocaleString()}`:`<em>${L10n.get(\"savesTextNoDate\")}</em>`).appendTo($tdDesc),$tdLoad.append(createButton(\"save\",null,L10n.get(\"savesTextBrowserSlot\"),index,index<Config.saves.maxSlotSaves&&slotAllowed?index=>{Save.browser.slot.save(index),buildSaves()}:null)),$tdLoad.append(createButton(\"load\",\"ui-close\",L10n.get(\"savesTextBrowserSlot\"),index,(index=>{jQuery(document).one(\":dialogclosed\",(()=>{Save.browser.slot.load(index).then(Engine.show,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))}))}))),$tdDele.append(createButton(\"delete\",null,L10n.get(\"savesTextBrowserSlot\"),index,(index=>{Save.browser.slot.delete(index),buildSaves()})))):($tdDesc.addClass(\"empty\"),jQuery(document.createElement(\"div\")).text(\" \").appendTo($tdDesc),jQuery(document.createElement(\"div\")).addClass(\"details\").addClass(\"datestamp\").text(`${L10n.get(\"savesTextBrowserSlot\")} ${index+1}`).appendTo($tdDesc),$tdLoad.append(createButton(\"save\",null,L10n.get(\"savesTextBrowserSlot\"),index,index<Config.saves.maxSlotSaves&&slotAllowed?index=>{Save.browser.slot.save(index),buildSaves()}:null)),$tdLoad.append(createButton(\"load\",\"ui-close\",L10n.get(\"savesTextBrowserSlot\"),index,null)),$tdDele.append(createButton(\"delete\",null,L10n.get(\"savesTextBrowserSlot\"),index))),jQuery(document.createElement(\"tr\")).append($tdSlot).append($tdLoad).append($tdDesc).append($tdDele).appendTo($tbody)})),jQuery(document.createElement(\"table\")).attr(\"id\",\"saves-list\").append($tbody)}());const $slotButtons=jQuery(document.createElement(\"ul\")).addClass(\"buttons slots\").appendTo($dialogBody);if(Has.fileAPI){const slotImportInput=createFileInput(\"saves-import-handler\",(ev=>{Save.disk.import(ev).then(buildSaves,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))}));$slotButtons.append(createActionItem(\"export\",null,`${L10n.get(\"textExport\")}…`,L10n.get(\"savesLabelBrowserExport\"),(()=>Save.disk.export(`saves-export-${Story.name}`)))).append(createActionItem(\"import\",null,`${L10n.get(\"textImport\")}…`,L10n.get(\"savesLabelBrowserImport\"),(()=>slotImportInput.click()))),jQuery(slotImportInput).appendTo($dialogBody)}idb.lock||$slotButtons.append(createActionItem(\"change-mode\",null,L10n.get(\"savesEnableIdb\"),L10n.get(\"savesEnableIdb\"),(()=>{Dialog.create(\"saves\",\"saves\").append($(document.createElement(\"h3\")).addClass(\"saves-loading\").text(\"Loading the save list, please wait...\")),idb.updateSettings(\"active\",!0),idb.saveList()}))),$slotButtons.append(createActionItem(\"clear\",null,L10n.get(\"textClear\"),L10n.get(\"savesLabelBrowserClear\"),Save.browser.size>0?()=>{Save.browser.clear(),buildSaves()}:null))}jQuery(document.createElement(\"h2\")).text(L10n.get(\"savesHeaderDisk\")).appendTo($dialogBody);const $diskButtons=jQuery(document.createElement(\"ul\")).addClass(\"buttons\").appendTo($dialogBody);if(Has.fileAPI){const diskLoadInput=createFileInput(\"saves-disk-load-handler\",(ev=>{jQuery(document).one(\":dialogclosed\",(()=>{Save.disk.load(ev).then(Engine.show,(ex=>openAlert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))})),Dialog.close()}));$diskButtons.append(createActionItem(\"disk-save\",null,`${L10n.get(\"textSave\")}…`,L10n.get(\"savesLabelDiskSave\"),\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Disk)?()=>Save.disk.save(Story.name):null)).append(createActionItem(\"disk-load\",null,`${L10n.get(\"textLoad\")}…`,L10n.get(\"savesLabelDiskLoad\"),(()=>diskLoadInput.click()))),jQuery(diskLoadInput).appendTo($dialogBody)}return $diskButtons.append(createActionItem(\"clipboard-save\",\"ui-close\",`${L10n.get(\"savesLabelToClipboard\")}…`,L10n.get(\"savesLabelToClipboard\"),\"function\"!=typeof Config.saves.isAllowed||Config.saves.isAllowed(Save.Type.Disk)?()=>Save.toClipboard():null)),!0}function buildSettings(){Dialog.create(L10n.get(\"settingsTitle\"),\"settings\");const $dialogBody=jQuery(Dialog.body());return Setting.forEach((control=>{switch(control.type){case Setting.Types.Header:{const name=control.name,id=createSlug(name),$header=jQuery(document.createElement(\"div\")),$heading=jQuery(document.createElement(\"h2\"));return $header.attr(\"id\",`header-body-${id}`).append($heading).appendTo($dialogBody),$heading.attr(\"id\",`header-heading-${id}`).wikiWithOptions({cleanup:!1},name),void(control.desc&&jQuery(document.createElement(\"p\")).attr(\"id\",`header-desc-${id}`).wikiWithOptions({cleanup:!1},control.desc).appendTo($header))}case Setting.Types.Value:return}const name=control.name,id=createSlug(name),$setting=jQuery(document.createElement(\"div\")),$label=jQuery(document.createElement(\"label\")),$controlBox=jQuery(document.createElement(\"div\"));let $control;switch(jQuery(document.createElement(\"div\")).append($label).append($controlBox).appendTo($setting),control.desc&&jQuery(document.createElement(\"p\")).attr(\"id\",`setting-desc-${id}`).wikiWithOptions({cleanup:!1},control.desc).appendTo($setting),$label.attr({id:`setting-label-${id}`,for:`setting-control-${id}`}).wikiWithOptions({cleanup:!1},control.label),null==Setting.getValue(name)&&Setting.setValue(name,control.default),control.type){case Setting.Types.List:$control=jQuery(document.createElement(\"select\"));for(let i=0,iend=control.list.length;i<iend;++i)jQuery(document.createElement(\"option\")).val(i).text(control.list[i]).appendTo($control);$control.val(control.list.indexOf(Setting.getValue(name))).attr(\"tabindex\",0).on(\"change\",(function(){Setting.setValue(name,control.list[Number(this.value)])}));break;case Setting.Types.Range:$control=jQuery(document.createElement(\"input\")),$control.attr({type:\"range\",min:control.min,max:control.max,step:control.step,value:Setting.getValue(name),tabindex:0}).on(\"change input\",(function(){Setting.setValue(name,Number(this.value))})).on(\"keypress\",(ev=>{13===ev.which&&(ev.preventDefault(),triggerEvent(\"change\",$control))}));break;case Setting.Types.Toggle:$control=jQuery(document.createElement(\"button\")),Setting.getValue(name)?$control.addClass(\"enabled\").text(L10n.get(\"textOn\")):$control.text(L10n.get(\"textOff\")),$control.ariaClick((function(){const status=Setting.getValue(name);status?jQuery(this).removeClass(\"enabled\").text(L10n.get(\"textOff\")):jQuery(this).addClass(\"enabled\").text(L10n.get(\"textOn\")),Setting.setValue(name,!status)}))}$control.attr(\"id\",`setting-control-${id}`).appendTo($controlBox),$setting.attr(\"id\",`setting-body-${id}`).appendTo($dialogBody)})),$dialogBody.append(`<ul class=\"buttons\"><li><button id=\"settings-ok\" class=\"ui-close\">${L10n.get([\"settingsTextOk\",\"textOk\"])}</button></li><li><button id=\"settings-reset\">${L10n.get(\"settingsTextReset\")}</button></li></ul>`).find(\"#settings-reset\").ariaClick({one:!0},(()=>{jQuery(document).one(\":dialogclosed\",(()=>{Setting.reset(),window.location.reload()})),Dialog.close()})),!0}function openAlert(message,...args){Dialog.create(L10n.get(\"alertTitle\"),\"alert\").append(`<p>${message}</p><ul class=\"buttons\"><li><button id=\"alert-ok\" class=\"ui-close\">${L10n.get([\"alertTextOk\",\"textOk\"])}</button></li></ul>`).open(...args)}function buildJumpto(){console.warn(\"[DEPRECATED] UI.buildJumpto() is deprecated.\");const list=document.createElement(\"ul\");Dialog.create(L10n.get(\"jumptoTitle\"),\"jumpto list\").append(list);const expired=State.expired.length;for(let i=State.size-1;i>=0;--i){if(i===State.activeIndex)continue;const passage=Story.get(State.history[i].title);passage&&passage.tags.includes(\"bookmark\")&&jQuery(document.createElement(\"li\")).append(jQuery(document.createElement(\"a\")).ariaClick({one:!0},function(index){return()=>jQuery(document).one(\":dialogclosed\",(()=>Engine.goTo(index)))}(i)).addClass(\"ui-close\").text(`${L10n.get(\"textTurn\")} ${expired+i+1}`)).appendTo(list)}list.hasChildNodes()||jQuery(list).append(`<li><a><em>${L10n.get(\"jumptoMesgUnavailable\")}</em></a></li>`)}function buildShare(){console.warn(\"[DEPRECATED] UI.buildShare() is deprecated.\");try{Dialog.create(L10n.get(\"shareTitle\"),\"share list\").append(assembleLinkList(\"StoryShare\"))}catch(ex){return console.error(ex),Alert.error(\"StoryShare\",ex.message),!1}return!0}return Object.preventExtensions(Object.create(null,{assembleLinkList:{value:assembleLinkList},buildRestart:{value:buildRestart},buildSaves:{value:buildSaves},buildSettings:{value:buildSettings},update:{value:function(){triggerEvent(\":uiupdate\")}},alert:{value:openAlert},restart:{value:function(...args){buildRestart(),Dialog.open(...args)}},saves:{value:function(...args){idb.active?(Dialog.create(\"saves\",\"saves\").append($(document.createElement(\"h3\")).addClass(\"saves-loading\").text(\"Loading the save list, please wait...\")),idb.saveList()):buildSaves(),Dialog.open(...args)}},settings:{value:function(...args){buildSettings(),Dialog.open(...args)}},buildAutoload:{value:function(){return console.warn(\"[DEPRECATED] UI.buildAutoload() is deprecated.\"),Dialog.create(L10n.get(\"autoloadTitle\"),\"autoload\").append(`<p>${L10n.get(\"autoloadMesgPrompt\")}</p><ul class=\"buttons\"><li><button id=\"autoload-ok\" class=\"ui-close\">${L10n.get([\"autoloadTextOk\",\"textOk\"])}</button></li><li><button id=\"autoload-cancel\" class=\"ui-close\">${L10n.get([\"autoloadTextCancel\",\"textCancel\"])}</button></li></ul>`),jQuery(document).one(\"click.autoload\",\".ui-close\",(ev=>{const isAutoloadOk=\"autoload-ok\"===ev.target.id;jQuery(document).one(\":dialogclosed\",(()=>{new Promise(((resolve,reject)=>{isAutoloadOk&&resolve(),reject()})).then((()=>Save.browser.continue())).catch((()=>{Engine.play(Config.passages.start)}))}))})),!0}},buildJumpto:{value:buildJumpto},buildShare:{value:buildShare},jumpto:{value:function(...args){buildJumpto(),Dialog.open(...args)}},share:{value:function(...args){buildShare(),Dialog.open(...args)}}}))})(),UIBar=(()=>{let _$uiBar=null;function stow(noAnimation){if(_$uiBar&&!_$uiBar.hasClass(\"stowed\")){let $story;noAnimation&&($story=jQuery(\"#story\"),$story.addClass(\"no-transition\"),_$uiBar.addClass(\"no-transition\")),_$uiBar.addClass(\"stowed\"),noAnimation&&setTimeout((()=>{$story.removeClass(\"no-transition\"),_$uiBar.removeClass(\"no-transition\")}),Engine.DOM_DELAY)}return UIBar}function update(){if(console.warn(\"[DEPRECATED] UIBar.update() is deprecated.\"),_$uiBar)return UI.update(),UIBar}return Object.preventExtensions(Object.create(null,{init:{value:function(){if(document.getElementById(\"ui-bar\"))return;const $elems=(()=>{const toggleLabel=L10n.get(\"uiBarLabelToggle\"),backwardLabel=L10n.get(\"uiBarLabelBackward\"),jumptoLabel=L10n.get(\"uiBarLabelJumpto\"),forwardLabel=L10n.get(\"uiBarLabelForward\");return jQuery(document.createDocumentFragment()).append(`<div id=\"ui-bar\" aria-live=\"polite\"><div id=\"ui-bar-tray\"><button id=\"ui-bar-toggle\" tabindex=\"0\" title=\"${toggleLabel}\" aria-label=\"${toggleLabel}\"></button><div id=\"ui-bar-history\"><button id=\"history-backward\" tabindex=\"0\" title=\"${backwardLabel}\" aria-label=\"${backwardLabel}\"></button><button id=\"history-jumpto\" tabindex=\"0\" title=\"${jumptoLabel}\" aria-label=\"${jumptoLabel}\"></button><button id=\"history-forward\" tabindex=\"0\" title=\"${forwardLabel}\" aria-label=\"${forwardLabel}\"></button></div></div><div id=\"ui-bar-body\"><header id=\"title\" role=\"banner\"><div id=\"story-banner\"></div><h1 id=\"story-title\"></h1><div id=\"story-subtitle\"></div><div id=\"story-title-separator\"></div><p id=\"story-author\"></p></header><div id=\"story-caption\"></div><nav id=\"menu\" role=\"navigation\"><ul id=\"menu-story\"></ul><ul id=\"menu-core\"><li id=\"menu-item-continue\"><a tabindex=\"0\">${L10n.get(\"continueTitle\")}</a></li><li id=\"menu-item-saves\"><a tabindex=\"0\">${L10n.get(\"savesTitle\")}</a></li><li id=\"menu-item-settings\"><a tabindex=\"0\">${L10n.get(\"settingsTitle\")}</a></li><li id=\"menu-item-restart\"><a tabindex=\"0\">${L10n.get(\"restartTitle\")}</a></li><li id=\"menu-item-share\"><a tabindex=\"0\">${L10n.get(\"shareTitle\")}</a></li></ul></nav></div></div>`)})();var $backward,$forward;_$uiBar=jQuery($elems.find(\"#ui-bar\").get(0)),$elems.insertBefore(\"body>script#script-sugarcube\"),jQuery(document).on(\":historyupdate.ui-bar\",($backward=jQuery(\"#history-backward\"),$forward=jQuery(\"#history-forward\"),()=>{$backward.ariaDisabled(State.length<2),$forward.ariaDisabled(State.length===State.size)}))}},destroy:{value:function(){_$uiBar&&(_$uiBar.hide(),jQuery(document).off(\".ui-bar\"),jQuery(document.head).find(\"#style-ui-bar\").remove(),_$uiBar.remove(),_$uiBar=null)}},hide:{value:function(){return _$uiBar&&_$uiBar.hide(),UIBar}},isHidden:{value:function(){return _$uiBar&&\"none\"===_$uiBar.css(\"display\")}},isStowed:{value:function(){return _$uiBar&&_$uiBar.hasClass(\"stowed\")}},show:{value:function(){return _$uiBar&&_$uiBar.show(),UIBar}},start:{value:function(){if(!_$uiBar)return;(\"boolean\"==typeof Config.ui.stowBarInitially?Config.ui.stowBarInitially:jQuery(window).width()<=Config.ui.stowBarInitially)&&stow(!0),jQuery(\"#ui-bar-toggle\").ariaClick({label:L10n.get(\"uiBarLabelToggle\")},(()=>_$uiBar.toggleClass(\"stowed\"))),Config.history.controls?(jQuery(\"#history-backward\").ariaDisabled(State.length<2).ariaClick({label:L10n.get(\"uiBarLabelBackward\")},(()=>Engine.backward())),Story.filter((passage=>passage.tags.includes(\"bookmark\"))).length>0?jQuery(\"#history-jumpto\").ariaClick({label:L10n.get(\"uiBarLabelJumpto\")},(()=>UI.jumpto())):jQuery(\"#history-jumpto\").remove(),jQuery(\"#history-forward\").ariaDisabled(State.length===State.size).ariaClick({label:L10n.get(\"uiBarLabelForward\")},(()=>Engine.forward()))):jQuery(\"#ui-bar-history\").remove();const addUiUpdateHandler=handler=>jQuery(document)[Config.ui.updateStoryElements?\"on\":\"one\"](\":uiupdate.ui-bar\",handler),addUpdaterOrRemove=(selector,passageName)=>{const $el=jQuery(selector);Story.has(passageName)?addUiUpdateHandler((()=>{$el.empty().append(Story.get(passageName).render())})):$el.remove()};{let storyTitleHandler;storyTitleHandler=Story.has(\"StoryDisplayTitle\")?()=>setDisplayTitle(Story.get(\"StoryDisplayTitle\").processText()):()=>setDisplayTitle(Story.name,!0),addUiUpdateHandler(storyTitleHandler)}if(addUpdaterOrRemove(\"#story-banner\",\"StoryBanner\"),addUpdaterOrRemove(\"#story-subtitle\",\"StorySubtitle\"),addUpdaterOrRemove(\"#story-author\",\"StoryAuthor\"),addUpdaterOrRemove(\"#story-caption\",\"StoryCaption\"),Story.has(\"StoryMenu\")){const $menuStory=jQuery(\"#menu-story\");jQuery(document).on(\":uiupdate.ui-bar\",(()=>{try{const frag=UI.assembleLinkList(\"StoryMenu\",document.createDocumentFragment());$menuStory.empty().append(frag)}catch(ex){console.error(ex),Alert.error(\"StoryMenu\",ex.message)}}))}else jQuery(\"#menu-story\").remove();Save.browser.size>0?(jQuery(\"#menu-item-continue a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),Save.browser.continue().then((()=>{jQuery(document).off(\".menu-item-continue\"),jQuery(\"#menu-item-continue\").remove(),Engine.show()}),(ex=>UI.alert(`${ex.message.toUpperFirst()}.</p><p>${L10n.get(\"textAborting\")}.`)))})).text(L10n.get(\"continueTitle\")),jQuery(document).on(\":passagestart.menu-item-continue\",(()=>{State.turns>1&&(jQuery(document).off(\".menu-item-continue\"),jQuery(\"#menu-item-continue\").remove())}))):jQuery(\"#menu-item-continue\").remove(),jQuery(\"#menu-item-saves a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),idb.active?(Dialog.create(\"saves\",\"saves\").append($(document.createElement(\"h3\")).addClass(\"saves-loading\").text(\"Loading the save list, please wait...\")),idb.saveList()):UI.buildSaves(),Dialog.open()})).text(L10n.get(\"savesTitle\")),Setting.isEmpty()?jQuery(\"#menu-item-settings\").remove():jQuery(\"#menu-item-settings a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),UI.buildSettings(),Dialog.open()})).text(L10n.get(\"settingsTitle\")),jQuery(\"#menu-item-restart a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),UI.buildRestart(),Dialog.open()})).text(L10n.get(\"restartTitle\")),Story.has(\"StoryShare\")?jQuery(\"#menu-item-share a\").ariaClick({role:\"button\"},(ev=>{ev.preventDefault(),UI.buildShare(),Dialog.open()})).text(L10n.get(\"shareTitle\")):jQuery(\"#menu-item-share\").remove()}},stow:{value:stow},unstow:{value:function(noAnimation){if(_$uiBar&&_$uiBar.hasClass(\"stowed\")){let $story;noAnimation&&($story=jQuery(\"#story\"),$story.addClass(\"no-transition\"),_$uiBar.addClass(\"no-transition\")),_$uiBar.removeClass(\"stowed\"),noAnimation&&setTimeout((()=>{$story.removeClass(\"no-transition\"),_$uiBar.removeClass(\"no-transition\")}),Engine.DOM_DELAY)}return UIBar}},setStoryElements:{value:update},update:{value:update}}))})(),DebugBar=(()=>{const STORAGE_KEY=\"debug.state\",WATCH_LIST_DELAY=200,VAR_LIST_DELAY=500,variableRE=new RegExp(`^${Patterns.variable}$`),numericKeyRE=/^\\d+$/,watchList=[];let varList=[],watchTimerId=null,listTimerId=null,stowed=!0,$debugBar=null,$watchBody=null,$varDataList=null,$turnSelect=null,$passageDataList=null;function debugBarStow(){disableWatchUpdates(),disableVarListUpdates(),$debugBar.css(\"right\",`-${$debugBar.outerWidth()}px`),stowed=!0,updateSession()}function debugBarUnstow(){debugBarWatchIsEnabled()&&enableWatchUpdates(),enableVarListUpdates(),$debugBar.css(\"right\",0),stowed=!1,updateSession()}function debugBarToggle(){stowed?debugBarUnstow():debugBarStow()}function debugBarWatchAdd(varName){variableRE.test(varName)&&(watchList.pushUnique(varName),watchList.sort(),updateWatchBody(),updateVarList(),updateSession())}function debugBarWatchAddAll(){Object.keys(State.variables).map((name=>watchList.pushUnique(`$${name}`))),Object.keys(State.temporary).map((name=>watchList.pushUnique(`_${name}`))),watchList.sort(),updateWatchBody(),updateVarList(),updateSession()}function debugBarWatchClear(){watchList.length=0,$watchBody.empty().append(`<div>— ${L10n.get(\"debugBarMesgNoWatches\")} —</div>`),updateWatchBody(),updateVarList(),updateSession()}function debugBarWatchDelete(varName){watchList.deleteFirst(varName),$watchBody.find(`tr[data-name=\"${varName}\"]`).remove(),updateWatchBody(),updateVarList(),updateSession()}function debugBarWatchDisable(){disableWatchUpdates(),disableWatch(),updateSession()}function debugBarWatchEnable(){enableWatchUpdates(),enableWatch(),updateSession()}function debugBarWatchIsEnabled(){return!$watchBody.attr(\"hidden\")}function debugBarWatchToggle(){$watchBody.attr(\"hidden\")?debugBarWatchEnable():debugBarWatchDisable()}function disableWatch(){$watchBody.attr({\"aria-hidden\":!0,hidden:\"hidden\"})}function disableWatchUpdates(){null!==watchTimerId&&(clearInterval(watchTimerId),watchTimerId=null)}function enableWatch(){$watchBody.removeAttr(\"aria-hidden hidden\")}function enableWatchUpdates(){null===watchTimerId&&(watchTimerId=setInterval((()=>updateWatchBody()),WATCH_LIST_DELAY))}function disableVarListUpdates(){null!==listTimerId&&(clearInterval(listTimerId),listTimerId=null)}function enableVarListUpdates(){null===listTimerId&&(listTimerId=setInterval((()=>updateVarList()),VAR_LIST_DELAY))}function clearSession(){session.delete(STORAGE_KEY)}function updateSession(){session.set(STORAGE_KEY,{stowed:stowed,watchList:watchList,watchEnabled:debugBarWatchIsEnabled(),viewsEnabled:DebugView.isEnabled()})}function updateWatchBody(){if(0===watchList.length)return;const $rowMap=new Map;let $tbody,$table=jQuery($watchBody.children(\"table\"));$table.length>0?($tbody=jQuery($table.children(\"tbody\")),$tbody.children(\"tr\").each(((_,el)=>$rowMap.set(el.getAttribute(\"data-name\"),jQuery(el))))):($table=jQuery(document.createElement(\"table\")),$tbody=jQuery(document.createElement(\"tbody\")),$table.append($tbody),$watchBody.empty().append($table));const delLabel=L10n.get(\"debugBarLabelWatchDelete\");let cursor=$rowMap.size>0?$tbody.children(\"tr\").get(0):null;watchList.forEach((varName=>{const varKey=varName.slice(1),value=toWatchString((\"$\"===varName[0]?State.variables:State.temporary)[varKey]);let $row=$rowMap.get(varName);if($row){const $code=$row.children().children(\"code\");value!==$code.text()&&$code.text(value)}else $row=function(varName,value){const $row=jQuery(document.createElement(\"tr\")),$delBtn=jQuery(document.createElement(\"button\")),$code=jQuery(document.createElement(\"code\"));return $row.attr(\"data-name\",varName),$delBtn.addClass(\"watch-delete\").ariaClick({one:!0,label:delLabel},(()=>debugBarWatchDelete(varName))),$code.text(value),jQuery(document.createElement(\"td\")).append($delBtn).appendTo($row),jQuery(document.createElement(\"td\")).text(varName).appendTo($row),jQuery(document.createElement(\"td\")).append($code).appendTo($row),$row}(varName,value),cursor?$row.insertAfter(cursor):$row.appendTo($tbody);cursor=$row.get(0)}))}function updateVarList(){const names=[].concat(Object.keys(State.variables).map((name=>`$${name}`)),Object.keys(State.temporary).map((name=>`_${name}`)));if(0===names.length)return varList.length=0,void $varDataList.empty();if(names.sort().deleteAll(watchList),names.length===varList.length&&names.every(((m,i)=>m===varList[i])))return;varList=names;const options=document.createDocumentFragment();varList.forEach((name=>{jQuery(document.createElement(\"option\")).val(name).appendTo(options)})),$varDataList.empty().append(options)}function updateTurnSelect(){const histLen=State.size,expLen=State.expired.length,options=document.createDocumentFragment();for(let i=0;i<histLen;++i)jQuery(document.createElement(\"option\")).val(i).text(`${expLen+i+1}. ${State.history[i].title}`).appendTo(options);$turnSelect.empty().ariaDisabled(histLen<2).append(options).val(State.activeIndex)}function updatePassageList(){const passages=Object.keys(Story.getNormals()).sort(),options=document.createDocumentFragment();passages.forEach((name=>{jQuery(document.createElement(\"option\")).val(name).appendTo(options)})),$passageDataList.empty().append(options)}function toWatchString(O){if(null===O)return\"null\";switch(typeof O){case\"bigint\":case\"boolean\":case\"number\":case\"symbol\":case\"undefined\":return String(O);case\"string\":return JSON.stringify(O);case\"function\":return\"Function\"}const objType=getToStringTag(O);if(\"Date\"===objType)return`Date {${O.toLocaleString()}}`;if(\"RegExp\"===objType)return`RegExp ${O.toString()}`;const result=[];if(O instanceof Array||O instanceof Set){const list=O instanceof Array?O:Array.from(O);for(let i=0,len=list.length;i<len;++i)result.push(Object.hasOwn(list,i)?toWatchString(list[i]):\"<empty>\");return Object.keys(list).filter((key=>!numericKeyRE.test(key))).forEach((key=>result.push(`${toWatchString(key)}: ${toWatchString(list[key])}`))),`${objType}(${list.length}) [${result.join(\", \")}]`}return O instanceof Map?(O.forEach(((val,key)=>result.push(`${toWatchString(key)} → ${toWatchString(val)}`))),`${objType}(${O.size}) {${result.join(\", \")}}`):(Object.keys(O).forEach((key=>result.push(`${toWatchString(key)}: ${toWatchString(O[key])}`))),`${objType} {${result.join(\", \")}}`)}return Object.preventExtensions(Object.create(null,{init:{value:function(){if(!Config.debug)return void jQuery(document.head).find('[id|=\"style-ui-debug\"]').remove();const barToggleLabel=L10n.get(\"debugBarLabelToggle\"),watchAddLabel=L10n.get(\"debugBarLabelWatchAdd\"),watchAllLabel=L10n.get(\"debugBarLabelWatchAll\"),watchClearLabel=L10n.get(\"debugBarLabelWatchClear\"),watchToggleLabel=L10n.get(\"debugBarLabelWatchToggle\"),viewsToggleLabel=L10n.get(\"debugBarLabelViewsToggle\"),passagePlayLabel=L10n.get(\"debugBarLabelPassagePlay\");jQuery(document.createDocumentFragment()).append(`<div id=\"debug-bar\"><div id=\"debug-bar-watch\"><div>— ${L10n.get(\"debugBarMesgNoWatches\")} —</div></div><div><label id=\"debug-bar-watch-label\" for=\"debug-bar-watch-input\">${L10n.get(\"debugBarTextWatch\")}</label><input id=\"debug-bar-watch-input\" name=\"debug-bar-watch-input\" type=\"text\" placeholder=\"${L10n.get(\"debugBarLabelWatchPlaceholder\")}\" list=\"debug-bar-var-list\" tabindex=\"0\"><datalist id=\"debug-bar-var-list\" aria-hidden=\"true\" hidden=\"hidden\"></datalist><button id=\"debug-bar-watch-add\" tabindex=\"0\" title=\"${watchAddLabel}\" aria-label=\"${watchAddLabel}\"></button><button id=\"debug-bar-watch-all\" tabindex=\"0\" title=\"${watchAllLabel}\" aria-label=\"${watchAllLabel}\"></button><button id=\"debug-bar-watch-clear\" tabindex=\"0\" title=\"${watchClearLabel}\" aria-label=\"${watchClearLabel}\"></button></div><div><label id=\"debug-bar-turn-label\" for=\"debug-bar-turn-select\">${L10n.get(\"textTurn\")}</label><select id=\"debug-bar-turn-select\" tabindex=\"0\"></select></div><div><label id=\"debug-bar-passage-label\" for=\"debug-bar-passage-input\">${L10n.get(\"debugBarTextPassage\")}</label><input id=\"debug-bar-passage-input\" name=\"debug-bar-passage-input\" type=\"text\" placeholder=\"${L10n.get(\"debugBarLabelPassagePlaceholder\")}\" list=\"debug-bar-passage-list\" tabindex=\"0\"><datalist id=\"debug-bar-passage-list\" aria-hidden=\"true\" hidden=\"hidden\"></datalist><button id=\"debug-bar-passage-play\" tabindex=\"0\" title=\"${passagePlayLabel}\" aria-label=\"${passagePlayLabel}\"></button></div><div><button id=\"debug-bar-views-toggle\" tabindex=\"0\" title=\"${viewsToggleLabel}\" aria-label=\"${viewsToggleLabel}\">${L10n.get(\"debugBarTextViews\")}</button><button id=\"debug-bar-watch-toggle\" tabindex=\"0\" title=\"${watchToggleLabel}\" aria-label=\"${watchToggleLabel}\">${L10n.get(\"debugBarTextWatch\")}</button></div><button id=\"debug-bar-toggle\" tabindex=\"0\" title=\"${barToggleLabel}\" aria-label=\"${barToggleLabel}\"></button></div><div id=\"debug-bar-hint\"></div>`).appendTo(\"body\"),$debugBar=jQuery(\"#debug-bar\"),$watchBody=jQuery($debugBar.find(\"#debug-bar-watch\").get(0)),$varDataList=jQuery($debugBar.find(\"#debug-bar-var-list\").get(0)),$turnSelect=jQuery($debugBar.find(\"#debug-bar-turn-select\").get(0)),$passageDataList=jQuery($debugBar.find(\"#debug-bar-passage-list\").get(0));const $watchInput=jQuery($debugBar.find(\"#debug-bar-watch-input\").get(0)),$watchAdd=jQuery($debugBar.find(\"#debug-bar-watch-add\").get(0)),$watchAll=jQuery($debugBar.find(\"#debug-bar-watch-all\").get(0)),$watchClear=jQuery($debugBar.find(\"#debug-bar-watch-clear\").get(0)),$passageInput=jQuery($debugBar.find(\"#debug-bar-passage-input\").get(0)),$passagePlay=jQuery($debugBar.find(\"#debug-bar-passage-play\").get(0)),$viewsToggle=jQuery($debugBar.find(\"#debug-bar-views-toggle\").get(0)),$watchToggle=jQuery($debugBar.find(\"#debug-bar-watch-toggle\").get(0)),$barToggle=jQuery($debugBar.find(\"#debug-bar-toggle\").get(0));$watchInput.on(\"sc:debug-watch-add\",(function(){debugBarWatchAdd(this.value.trim()),this.value=\"\"})).on(\"keypress\",(ev=>{13===ev.which&&(ev.preventDefault(),triggerEvent(\"sc:debug-watch-add\",$watchInput))})),$watchAdd.ariaClick((()=>triggerEvent(\"sc:debug-watch-add\",$watchInput))),$watchAll.ariaClick(debugBarWatchAddAll),$watchClear.ariaClick(debugBarWatchClear),$turnSelect.on(\"change\",(function(){Engine.goTo(Number(this.value))})),$passageInput.on(\"sc:debug-passage-play\",(function(){Engine.play(this.value.trim()),this.value=\"\"})).on(\"keypress\",(ev=>{13===ev.which&&(ev.preventDefault(),triggerEvent(\"sc:debug-passage-play\",$passageInput))})).on(\"focus\",updatePassageList),$passagePlay.ariaClick((()=>triggerEvent(\"sc:debug-passage-play\",$passageInput))),$viewsToggle.ariaClick((()=>{DebugView.toggle(),updateSession()})),$watchToggle.ariaClick(debugBarWatchToggle),$barToggle.ariaClick(debugBarToggle),jQuery(document).on(\":passageend.debug-bar\",(()=>{updateWatchBody(),updateVarList()})).on(\":historyupdate.debug-bar\",updateTurnSelect).on(\":enginerestart.debug-bar\",clearSession)}},isStowed:{value:function(){return stowed}},start:{value:function(){Config.debug&&(function(){if(!session.has(STORAGE_KEY))return!1;const debugState=session.get(STORAGE_KEY);watchList.push(...debugState.watchList),debugState.watchEnabled?(stowed?disableWatchUpdates():enableWatchUpdates(),enableWatch()):(disableWatchUpdates(),disableWatch());debugState.viewsEnabled?DebugView.enable():DebugView.disable();stowed=debugState.stowed,stowed?(disableVarListUpdates(),debugBarStow()):(enableVarListUpdates(),debugBarUnstow());return!0}()||(debugBarStow(),DebugView.enable(),enableWatchUpdates(),enableWatch()),updateVarList(),updateTurnSelect())}},stow:{value:debugBarStow},toggle:{value:debugBarToggle},unstow:{value:debugBarUnstow},watch:{value:Object.preventExtensions(Object.create(null,{add:{value:debugBarWatchAdd},all:{value:debugBarWatchAddAll},clear:{value:debugBarWatchClear},delete:{value:debugBarWatchDelete},disable:{value:debugBarWatchDisable},enable:{value:debugBarWatchEnable},isEnabled:{value:debugBarWatchIsEnabled},toggle:{value:debugBarWatchToggle}}))}}))})(),LoadScreen=(()=>{const _locks=new Set;let _autoId=0;function loadScreenHide(){jQuery(document.documentElement).removeAttr(\"data-init\")}function loadScreenShow(){jQuery(document.documentElement).attr(\"data-init\",\"loading\")}return Object.preventExtensions(Object.create(null,{init:{value:function(){jQuery(document).on(\"readystatechange.SugarCube\",(()=>{_locks.size>0||(\"complete\"===document.readyState?\"loading\"===jQuery(document.documentElement).attr(\"data-init\")&&(Config.loadDelay>0?setTimeout((()=>{0===_locks.size&&loadScreenHide()}),Math.max(Engine.DOM_DELAY,Config.loadDelay)):loadScreenHide()):loadScreenShow())}))}},clear:{value:function(){jQuery(document).off(\"readystatechange.SugarCube\"),_locks.clear(),loadScreenHide()}},hide:{value:loadScreenHide},show:{value:loadScreenShow},lock:{value:function(){return++_autoId,_locks.add(_autoId),loadScreenShow(),_autoId}},unlock:{value:function(id){if(null==id)throw new Error(\"LoadScreen.unlock called with a null or undefined ID\");_locks.has(id)&&_locks.delete(id),0===_locks.size&&triggerEvent(\"readystatechange\")}},size:{get:function(){return _locks.size}}}))})(),Util=Object.preventExtensions(Object.create(null,{charAndPosAt:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.charAndPosAt() is deprecated.\"),charAndPosAt(...args))},escape:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.escape() is deprecated.\"),encodeEntities(...args))},escapeMarkup:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.escapeMarkup() is deprecated.\"),encodeMarkup(...args))},fromCssProperty:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.fromCssProperty() is deprecated.\"),cssPropToDOMProp(...args))},fromCssTime:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.fromCssTime() is deprecated.\"),cssTimeToMS(...args))},getType:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.getType() is deprecated.\"),getTypeOf(...args))},hasMediaQuery:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.hasMediaQuery() is deprecated.\"),hasMediaQuery(...args))},newExceptionFrom:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.newExceptionFrom() is deprecated.\"),exceptionFrom(...args))},now:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.now() is deprecated.\"),now(...args))},parseUrl:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.parseUrl() is deprecated.\"),parseURL(...args))},sameValueZero:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.sameValueZero() is deprecated.\"),sameValueZero(...args))},sanitizeFilename:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.sanitizeFilename() is deprecated.\"),createFilename(...args))},scrubEventKey:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.scrubEventKey() is deprecated.\"),scrubEventKey(...args))},slugify:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.slugify() is deprecated.\"),createSlug(...args))},toCssTime:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.toCssTime() is deprecated.\"),msToCSSTime(...args))},toEnum:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.toEnum() is deprecated.\"),enumFrom(...args))},toStringTag:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.toStringTag() is deprecated.\"),getToStringTag(...args))},unescape:{value:(...args)=>(console.warn(\"[DEPRECATED] Util.unescape() is deprecated.\"),decodeEntities(...args))}})),version=(()=>{const semVerRE=/^[Vv]?(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?)?)?$/;return Object.preventExtensions(Object.create(null,{name:{value:\"SugarCube\"},major:{value:2},minor:{value:37},patch:{value:3},prerelease:{value:\"\"},build:{value:34},date:{value:new Date(\"2024-10-04T16:22:23.306Z\")},isOk:{value(semver){if(\"string\"!=typeof semver)throw new Error(`version.isOk semver parameter must be a string (received: ${typeof semver})`);const trimmed=semver.trim();if(\"\"===trimmed)throw new Error(\"version.isOk semver parameter must not be empty\");const match=semVerRE.exec(trimmed);if(!match)throw new Error(`version.isOk semver parameter is invalid (format: [v]MAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]; received: ${trimmed}`);const major=Number(match[1]),minor=Number(match[2])||0,patch=Number(match[3])||0;return major===this.major&&(minor<this.minor||minor===this.minor&&patch<=this.patch)}},long:{value(){return`${this.name} v${this.toString()} (${this.date.toUTCString()})`}},short:{value(){const prerelease=this.prerelease?`-${this.prerelease}`:\"\";return`${this.name} (v${this.major}.${this.minor}.${this.patch}${prerelease})`}},toString:{value(){const prerelease=this.prerelease?`-${this.prerelease}`:\"\";return`${this.major}.${this.minor}.${this.patch}${prerelease}+${this.build}`}},title:{value:\"SugarCube\"}}))})(),TempState={},session=null,settings=Setting.create(),setup={},storage=null,macros={},postdisplay={},postrender={},predisplay={},prehistory={},prerender={};Object.defineProperty(window,\"SugarCube\",{value:Object.seal(Object.assign(Object.create(null),{Browser:Browser,Config:Config,Dialog:Dialog,Engine:Engine,Fullscreen:Fullscreen,Has:Has,L10n:L10n,Macro:Macro,Passage:Passage,Save:Save,Scripting:Scripting,Setting:Setting,SimpleAudio:SimpleAudio,State:State,Story:Story,UI:UI,UIBar:UIBar,DebugBar:DebugBar,Util:Util,Visibility:Visibility,Wikifier:Wikifier,session:session,settings:settings,setup:setup,storage:storage,version:version}))}),jQuery((()=>{const lockId=LoadScreen.lock();LoadScreen.init(),document.normalize&&document.normalize(),new Promise((resolve=>{Story.init();try{SugarCube.storage=storage=SimpleStore.create(Story.id,!0),SugarCube.session=session=SimpleStore.create(Story.id,!1)}catch(ex){throw new Error(L10n.get(\"warningNoStorage\"))}Dialog.init(),UIBar.init(),Engine.init(),Outliner.init(),Engine.runUserScripts(),L10n.init(),session.has(\"rcWarn\")||\"cookie\"!==storage.name||(session.set(\"rcWarn\",1),window.alert(L10n.get(\"warningNoWebStorage\"))),Save.init(),Setting.init(),idb.init(Story.id),Macro.init(),DebugBar.init();const $window=jQuery(window),vpReadyId=setInterval((()=>{$window.width()&&LoadScreen.size<=1&&(clearInterval(vpReadyId),resolve())}),Engine.DOM_DELAY)})).then((()=>{Engine.runUserInit(),UIBar.start(),Engine.start(),DebugBar.start(),triggerEvent(\":storyready\"),setTimeout((()=>LoadScreen.unlock(lockId)),2*Engine.DOM_DELAY)})).catch((ex=>(console.error(ex),LoadScreen.clear(),Alert.fatal(null,ex.message,ex))))}))})(window,window.document,jQuery);}\n\t</script>\n</body>\n</html>\n"}); \ No newline at end of file diff --git a/devTools/types/FC/human.d.ts b/devTools/types/FC/human.d.ts index e2b74d81b1181b72149d9a0cf0ef66c68a6006ac..f7f71555d250129e6f8daadf2159133572885b2a 100644 --- a/devTools/types/FC/human.d.ts +++ b/devTools/types/FC/human.d.ts @@ -37,10 +37,11 @@ declare global { Pick<SlaveState, SlaveStateRequiredAttributes> { /** * [left arm, right arm, left leg, right leg]. - * When 0 keep the limb, when 1 remove the limb from the generated slave. - * [1, 1, 0, 0] would remove both arms, but keep the legs. + * When 0 remove the limb, when 1+ sets the limb to the given LimbType. + * [0, 0, 1, 1] would remove both arms, but keep the legs as normal. + * [6, 6, 0, 1] would make both arms cybernetic prostetics and remove the left leg. */ - removedLimbs?: number[]; + _limbs?: [0 | LimbType, 0 | LimbType, 0 | LimbType, 0 | LimbType]; } export interface GingeredSlave extends SlaveState { diff --git a/devTools/types/SugarCubeExtensions.d.ts b/devTools/types/SugarCubeExtensions.d.ts index a4971ee3f33967a24c476ea9663eef4290014657..ef0899024f22197499b4d00df957d8b6de39d3ef 100644 --- a/devTools/types/SugarCubeExtensions.d.ts +++ b/devTools/types/SugarCubeExtensions.d.ts @@ -12,11 +12,33 @@ declare module "twine-sugarcube" { interface StateAPI { expired: StoryMoment[]; clearTemporary(): void; + /** + * Restores the game state to the last state it was in. + * Usually the state that it was in when the latest passage was loaded + */ + restore(): void; } interface UIBarAPI { update(): void; } + + interface SerialAPI { + /** + * Converts a JavaScript Object Notation (JSON) string with custom revival methods into an object. + * @param text A valid JSON string created using Serial.stringify(). + * @param reviver A function that transforms the results. This function is called for each member of the object. + * If a member contains nested objects, the nested objects are transformed before the parent object is. + */ + parse(text: string, reviver?: (this: any, key: string, value: any) => any): any; + /** + * Converts a JavaScript value to a JavaScript Object Notation (JSON) string with custom revival methods. + * @param value A JavaScript value, usually an object or array, to be converted. + * @param replacer A function that transforms the results. + * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. + */ + stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; + } } export {}; diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js index ce876ab0957ee788d1c77327e3f7fea7517f31d2..5e9a6eaf817aabe17b66a4bc6cb94f40f93e9bc7 100644 --- a/js/003-data/gameVariableData.js +++ b/js/003-data/gameVariableData.js @@ -17,8 +17,10 @@ App.Data.defaultGameStateVariables = { releaseID: 0, // Slaves - /** @type {{[key: number]: number}} */ + /** @type {ReadonlyDeep<{[key: number]: number}>} */ slaveIndices: {}, + /** @type {Readonly<Array<Readonly<FC.SlaveState>>>} */ + slaves: [], /** * @readonly * Each slave and the player gets a genepool record when they are created @@ -37,8 +39,6 @@ App.Data.defaultGameStateVariables = { */ genePoolDefaults: undefined, // new App.Entity.GenePoolRecord(); App.Entity.GenePoolRecord doesn't exist yet... missingTable: {}, - /** @type {FC.SlaveState[]} */ - slaves: [], // PC /** @type {FC.PlayerState} */ @@ -104,6 +104,8 @@ App.Data.defaultGameStateVariables = { debugMode: 0, debugModeCustomFunction: 0, debugModeEventSelection: 0, + /** @type {FC.Bool} If true then the patching system will report any changes that happen */ + reportVerificationChanges: 0, difficultySwitch: 0, disableLisping: 0, displayAssignments: 1, @@ -272,10 +274,11 @@ App.Data.defaultGameStateVariables = { aiUserInterface: 0, /** * * 0: SD 1.X - * * 1: SDXL/Pony - could possibly separate these - * * 2: SD 3 - Unimplemented - * * 3: Flux.1 - Unimplemented - * * 4: Flow - Unimplemented + * * 1: SDXL + * * 2: Pony + * * 3: SD 3 - Unimplemented + * * 4: Flux.1 - Unimplemented + * * 5: Flow - Unimplemented */ aiBaseModel: 0, /** diff --git a/js/medicine/surgery/extreme/fuckdoll.js b/js/medicine/surgery/extreme/fuckdoll.js index 900913f6882f5768703f80760a19d77c8f0c90b0..65158ded13f0f8ba5f5127678887253d33ef34be 100644 --- a/js/medicine/surgery/extreme/fuckdoll.js +++ b/js/medicine/surgery/extreme/fuckdoll.js @@ -23,7 +23,7 @@ App.Medicine.Surgery.Reactions.Fuckdoll = class extends App.Medicine.Surgery.Sim reaction(slave, diff) { const reaction = super.reaction(slave, diff); const {He, he, His, his, him, sister, wife} = getPronouns(slave); - const relations = V.slaves.filter((s) => areRelated(s, slave) && (s.ID !== slave.relationshipTarget)); + const relations = getSlaves().filter((s) => areRelated(s, slave) && (s.ID !== slave.relationshipTarget)); let r = []; let relatedCount = 0; diff --git a/js/rulesAssistant/conditionEditorTree.js b/js/rulesAssistant/conditionEditorTree.js index 8e4607d5eb32b7770aaec8e8dfa38abcee48ba2a..6253c9d15bea0d0af768697c23f4e19449e73b53 100644 --- a/js/rulesAssistant/conditionEditorTree.js +++ b/js/rulesAssistant/conditionEditorTree.js @@ -1016,7 +1016,7 @@ App.RA.Activation.TreeEditor = (function() { } _validateRule(check) { - const slave = createReadonlyProxy(V.slaves[0]); + const slave = createReadonlyProxy(getSlaves()[0]); const context = new App.RA.Activation.Context(slave); (new Function("c", `return (${check})(c)`))(context); return true; diff --git a/src/002-config/fc-version.js b/src/002-config/fc-version.js index 89dc1b25277ee99064c97e8837fa0f6ceea7f855..e87e0c2765c47265da06cf150cbcfe6adcda2601 100644 --- a/src/002-config/fc-version.js +++ b/src/002-config/fc-version.js @@ -10,5 +10,5 @@ App.Version = { * The release numbers got messed up, this is corrected in `src/js/eventHandlers.js` and `/src/data/patches/patch.js`. * The two line above and this line should be safe to remove after release 2001. */ - release: 1262, + release: 1267, }; diff --git a/src/004-base/baseEvent.js b/src/004-base/baseEvent.js index 33f36c67b89a5574f5b354697d6c71276521aae5..f1dda12c4e2af4df95af0b44324c927f754cb20a 100644 --- a/src/004-base/baseEvent.js +++ b/src/004-base/baseEvent.js @@ -108,7 +108,7 @@ App.Events.BaseEvent = class BaseEvent { } for (; i < prereqs.length; ++i) { - const qualified = V.slaves.filter(s => !this.actors.includes(s.ID) && prereqs[i].every(p => p(s))); + const qualified = getSlaves().filter(s => !this.actors.includes(s.ID) && prereqs[i].every(p => p(s))); if (qualified.length === 0) { return false; // a required actor was not found } diff --git a/src/004-base/basePrompt.js b/src/004-base/basePrompt.js index 183ab181e9404b53f583d05b43db9510af2ff88c..e27f007827b6cc109888d23cef7c1d7bdc1bebb7 100644 --- a/src/004-base/basePrompt.js +++ b/src/004-base/basePrompt.js @@ -6,6 +6,9 @@ App.Art.GenAI.PromptPart = class PromptPart { constructor(slave) { this.slave = slave; this.censored = this.slave.visualAge < 18 && V.aiAgeFilter; + this.helper = App.Art.GenAI.PromptHelpers; + this.isFeminine = App.Art.GenAI.PromptHelpers.isFeminine(slave); + this.isMasculine = App.Art.GenAI.PromptHelpers.isMasculine(slave); } /** diff --git a/src/004-base/facility.js b/src/004-base/facility.js index 7813f01ccd67e06ff5c642a0892333d5847085b5..2f144f39f225b4cf37c90fb38243d0b8f89c2c81 100644 --- a/src/004-base/facility.js +++ b/src/004-base/facility.js @@ -99,7 +99,7 @@ App.Entity.Facilities.Job = class { */ assignmentLinkElement(ID, passage, callback, linkText) { linkText = linkText || this.desc.position; - return App.UI.DOM.assignmentLink(slaveStateById(ID), this.desc.assignment, passage, callback, linkText); + return App.UI.DOM.assignmentLink(getSlave(ID), this.desc.assignment, passage, callback, linkText); } /** @@ -107,7 +107,7 @@ App.Entity.Facilities.Job = class { * @returns {FC.SlaveState[]} */ employees() { - return [...this.employeesIDs()].map(id => slaveStateById(id)); + return [...this.employeesIDs()].map(id => getSlave(id)); } /** @@ -387,7 +387,16 @@ App.Entity.Facilities.Facility = class { * @returns {number} */ upgrade(name) { - return (typeof V[this.desc.baseName] === "object") ? V[this.desc.baseName].upgrade[name] : this.option("Upgrade" + name); + return (typeof V[this.desc.baseName] === "object") ? V[this.desc.baseName].upgrades[name] : this.option("Upgrade" + name); + } + + /** + * Sets an upgrade value. Only use this on a facility migrated to an object in V. + * @param {string} name + * @param {number} value + */ + setUpgrade(name, value) { + V[this.desc.baseName].upgrades[name] = value; } /** Can this facility be decorated? */ @@ -462,7 +471,7 @@ App.Entity.Facilities.Facility = class { */ assignmentLinkElements(ID, job, passage, callback) { /** @type {FC.SlaveState} */ - const slave = slaveStateById(ID); + const slave = getSlave(ID); const jobs = job === undefined ? this._jobs : {job: this._jobs[job]}; let res = []; @@ -560,7 +569,7 @@ App.Entity.Facilities.FacilitySingleJob = class extends App.Entity.Facilities.Jo */ assignmentLinkElement(ID, targetPassage, callback, linkText) { linkText = linkText || this.desc.position; - return App.UI.DOM.assignmentLink(slaveStateById(ID), this.desc.assignment, "", + return App.UI.DOM.assignmentLink(getSlave(ID), this.desc.assignment, "", (slave, assignment) => { if (callback) { callback(slave, assignment); diff --git a/src/004-base/specialSlavesProxy.js b/src/004-base/specialSlavesProxy.js index 66e3e91824dea7f78409d0df536133ff9f5050c5..13b9339ed2dbdf0a40c68788b08143bb35201fca 100644 --- a/src/004-base/specialSlavesProxy.js +++ b/src/004-base/specialSlavesProxy.js @@ -3,55 +3,52 @@ App.SpecialSlavesProxy = class SpecialSlavesProxy { } get Attendant() { - return slaveStateById(V.AttendantID); + return getSlave(V.AttendantID); } get Bodyguard() { - return slaveStateById(V.BodyguardID); + return getSlave(V.BodyguardID); } get Concubine() { - return slaveStateById(V.ConcubineID); + return getSlave(V.ConcubineID); } get DJ() { - return slaveStateById(V.djID); + return getSlave(V.djID); } get Farmer() { - return slaveStateById(V.FarmerID); + return getSlave(V.FarmerID); } get HeadGirl() { - return slaveStateById(V.HeadGirlID); + return getSlave(V.HeadGirlID); } get Lurcher() { - return slaveStateById(V.LurcherID); + return getSlave(V.LurcherID); } get Madam() { - return slaveStateById(V.MadamID); + return getSlave(V.MadamID); } get Matron() { - return slaveStateById(V.MatronID); + return getSlave(V.MatronID); } get Milkmaid() { - return slaveStateById(V.MilkmaidID); + return getSlave(V.MilkmaidID); } get Nurse() { - return slaveStateById(V.NurseID); + return getSlave(V.NurseID); } get Recruiter() { - return slaveStateById(V.RecruiterID); + return getSlave(V.RecruiterID); } get Schoolteacher() { - return slaveStateById(V.SchoolteacherID); + return getSlave(V.SchoolteacherID); } get Stewardess() { - return slaveStateById(V.StewardessID); + return getSlave(V.StewardessID); } get Stud() { - return slaveStateById(V.StudID); + return getSlave(V.StudID); } get Wardeness() { - return slaveStateById(V.WardenessID); - } - get activeSlave() { - return V.activeSlave; + return getSlave(V.WardenessID); } }; diff --git a/src/Mods/DinnerParty.js b/src/Mods/DinnerParty.js index 1a2860262131285f99df8630f7fcd7660bd64ad5..eb478467eef01376e92f7fbf6ef495c32bf3fdd2 100644 --- a/src/Mods/DinnerParty.js +++ b/src/Mods/DinnerParty.js @@ -141,7 +141,7 @@ App.Mods.DinnerParty.Execution = function() { App.Events.addNode(t, [], "p"); // Clean up and slaves reactions App.Events.addNode(t, ["When the last of your guests has stumbled drunkenly out your door, your slaves begin the daunting task of cleanup."], "div"); - for (const aliveSlave of V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion < 50)) { + for (const aliveSlave of getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion < 50)) { let relation; let feeling; const {his3, sister3, daughter3, He3} = getPronouns(aliveSlave).appendSuffix("3"); @@ -182,7 +182,7 @@ App.Mods.DinnerParty.Execution = function() { } } - for (const aliveSlave of V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion >= 85)) { + for (const aliveSlave of getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion >= 85)) { let relation; let feeling; const {his3, sister3, daughter3, He3} = getPronouns(aliveSlave).appendSuffix("3"); @@ -223,7 +223,7 @@ App.Mods.DinnerParty.Execution = function() { } } - let aliveSlave = V.slaves.find(s => s.ID === slave.relationshipTarget && s.fetish !== Fetish.MINDBROKEN); + let aliveSlave = getSlaves().find(s => s.ID === slave.relationshipTarget && s.fetish !== Fetish.MINDBROKEN); if (slave.relationship !== 0 && aliveSlave) { const {his3} = getPronouns(aliveSlave).appendSuffix("3"); App.Events.addNode(t, [`${aliveSlave.slaveName} is`, App.UI.DOM.makeElement("span", "distraught", ["mediumorchid"]), `that you ate ${his3} best source of comfort and companionship in a life of bondage.`], "div"); @@ -231,7 +231,7 @@ App.Mods.DinnerParty.Execution = function() { aliveSlave.devotion -= 20; } - aliveSlave = V.slaves.find(s => s.ID === slave.rivalryTarget && s.fetish !== Fetish.MINDBROKEN); + aliveSlave = getSlaves().find(s => s.ID === slave.rivalryTarget && s.fetish !== Fetish.MINDBROKEN); if (slave.rivalry !== 0 && aliveSlave) { const {his3, He3} = getPronouns(aliveSlave).appendSuffix("3"); App.Events.addNode(t, [`${aliveSlave.slaveName} is`, App.UI.DOM.makeElement("span", "pleased", ["hotpink"]), `that ${He3} won't have to see ${his3} rival any more.`], "div"); @@ -243,12 +243,12 @@ App.Mods.DinnerParty.Execution = function() { r.push(`The fat slaves are`, App.UI.DOM.makeElement("span", "worried", ["gold"]), "they are being fattened for consumption."); r.push(`But your worshipful chattel are`, App.UI.DOM.makeElement("span", "pleased", ["hotpink"]), "that you could find a use for them even in death and", App.UI.DOM.makeElement("span", "hope", ["mediumaquamarine"]), "a similar fate awaits them."); App.Events.addNode(t, r, "p"); - for (const aliveSlave of V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion < 50)) { + for (const aliveSlave of getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion < 50)) { aliveSlave.devotion -= 5; aliveSlave.trust -= (aliveSlave.diet === "fattening" || aliveSlave.weight > 10 ? 10 : 5); } - for (const aliveSlave of V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion >= 85)) { + for (const aliveSlave of getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion >= 85)) { aliveSlave.devotion += 5; aliveSlave.trust += 5; } @@ -277,7 +277,7 @@ App.Mods.DinnerParty.Execution = function() { V.MOD_enemy = {leader: 0, numSlave: 0, slaveTotalHP: 0, numDrone: 0, droneTotalHP: 0, numMerc: 0, mercTotalHP: 0, weekCreated: 0, enemyIndex: -1, hostility: 0}; V.MOD_enemy.leader = _slave; V.MOD_enemy.weekCreated = V.week; - V.MOD_enemy.numSlave = random(Math.trunc(V.slaves.length * 0.7), Math.trunc(V.slaves.length * 1.3)); + V.MOD_enemy.numSlave = random(Math.trunc(getSlaves().length * 0.7), Math.trunc(getSlaves().length * 1.3)); V.MOD_enemy.numDrone = random(25, 75); V.MOD_enemy.numMerc = random(10, 60); V.MOD_enemyList.push(V.MOD_enemy); @@ -292,7 +292,7 @@ App.Mods.DinnerParty.Execution = function() { App.Events.addNode(t, r, "p"); repX(forceNeg(dinnerRating * 100), "event"); - for (const aliveSlave of V.slaves) { + for (const aliveSlave of getSlaves()) { if (random(0, 1) > 0) { healthDamage(aliveSlave, 10); } @@ -348,7 +348,7 @@ App.Mods.DinnerParty.Execution = function() { App.Events.addNode(t, [], "p"); // Clean up and slaves reactions App.Events.addNode(t, ["When the last of your guests has stumbled drunkenly out your door, your slaves begin the daunting task of cleanup."], "div"); - for (const aliveSlave of V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion < 50)) { + for (const aliveSlave of getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion < 50)) { let relation; let feeling; const {his3, sister3, daughter3, He3} = getPronouns(aliveSlave).appendSuffix("3"); @@ -389,7 +389,7 @@ App.Mods.DinnerParty.Execution = function() { } } - for (const aliveSlave of V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion >= 85)) { + for (const aliveSlave of getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion >= 85)) { let relation; let feeling; const {his3, sister3, daughter3, He3} = getPronouns(aliveSlave).appendSuffix("3"); @@ -430,7 +430,7 @@ App.Mods.DinnerParty.Execution = function() { } } - let aliveSlave = V.slaves.find(s => s.ID === slave.relationshipTarget && s.fetish !== Fetish.MINDBROKEN); + let aliveSlave = getSlaves().find(s => s.ID === slave.relationshipTarget && s.fetish !== Fetish.MINDBROKEN); if (slave.relationship !== 0 && aliveSlave) { const {his3} = getPronouns(aliveSlave).appendSuffix("3"); App.Events.addNode(t, [`${aliveSlave.slaveName} is`, App.UI.DOM.makeElement("span", "distraught", ["mediumorchid"]), `that you ate ${his3} best source of comfort and companionship in a life of bondage.`], "div"); @@ -438,7 +438,7 @@ App.Mods.DinnerParty.Execution = function() { aliveSlave.devotion -= 20; } - aliveSlave = V.slaves.find(s => s.ID === slave.rivalryTarget && s.fetish !== Fetish.MINDBROKEN); + aliveSlave = getSlaves().find(s => s.ID === slave.rivalryTarget && s.fetish !== Fetish.MINDBROKEN); if (slave.rivalry !== 0 && aliveSlave) { const {his3, He3} = getPronouns(aliveSlave).appendSuffix("3"); App.Events.addNode(t, [`${aliveSlave.slaveName} is`, App.UI.DOM.makeElement("span", "pleased", ["hotpink"]), `that ${He3} won't have to see ${his3} rival any more.`], "div"); @@ -450,12 +450,12 @@ App.Mods.DinnerParty.Execution = function() { r.push(`The fat slaves are`, App.UI.DOM.makeElement("span", "worried", ["gold"]), "they are being fattened for consumption."); r.push(`But your worshipful chattel are`, App.UI.DOM.makeElement("span", "pleased", ["hotpink"]), "that you could find a use for them even in death and", App.UI.DOM.makeElement("span", "hope", ["mediumaquamarine"]), "a similar fate awaits them."); App.Events.addNode(t, r, "p"); - for (const aliveSlave of V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion < 50)) { + for (const aliveSlave of getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion < 50)) { aliveSlave.devotion -= 5; aliveSlave.trust -= (aliveSlave.diet === "fattening" || aliveSlave.weight > 10 ? 10 : 5); } - for (const aliveSlave of V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion >= 85)) { + for (const aliveSlave of getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.devotion >= 85)) { aliveSlave.devotion += 5; aliveSlave.trust += 5; } @@ -484,7 +484,7 @@ App.Mods.DinnerParty.Execution = function() { V.MOD_enemy = {leader: 0, numSlave: 0, slaveTotalHP: 0, numDrone: 0, droneTotalHP: 0, numMerc: 0, mercTotalHP: 0, weekCreated: 0, enemyIndex: -1, hostility: 0}; V.MOD_enemy.leader = _slave; V.MOD_enemy.weekCreated = V.week; - V.MOD_enemy.numSlave = random(Math.trunc(V.slaves.length * 0.7), Math.trunc(V.slaves.length * 1.3)); + V.MOD_enemy.numSlave = random(Math.trunc(getSlaves().length * 0.7), Math.trunc(getSlaves().length * 1.3)); V.MOD_enemy.numDrone = random(25, 75); V.MOD_enemy.numMerc = random(10, 60); V.MOD_enemyList.push(V.MOD_enemy); diff --git a/src/art/genAI/archivingAI.js b/src/art/genAI/archivingAI.js index c9d6bf018ef80fdb8e10a8713c12a5ff3a80240f..c5a258daeff0cb0e1dd06ac12950b208350b8cfa 100644 --- a/src/art/genAI/archivingAI.js +++ b/src/art/genAI/archivingAI.js @@ -1,4 +1,11 @@ App.Art.GenAI.Archiving = class Archiving { + /** + * Caches the sha1 signature of images in indexedDB, to compare when importing an archive. + * Should be empty unless when importing. + * @type {Map} + */ + static signatureCache = new Map(); + /** * Fetches all the stored images of a character and puts them in the given zip container * @@ -27,10 +34,14 @@ App.Art.GenAI.Archiving = class Archiving { await App.Art.GenAI.staticImageDB.getImage(aiImageId) .then(data => { let filename = `${s.ID}- ${s.slaveSurname} ${s.slaveName}/${aiImageId}${data.week ? "-week" + data.week : ""}.png`; - if (callbackBefore) { callbackBefore(filename); } + if (callbackBefore) { + callbackBefore(filename); + } zip.file(filename, data.data.substring('data:image/png;base64,'.length), {base64: true}); manifest.push({path: filename, week: data.week ? data.week : 'unknown'}); - if (callbackAfter) { callbackAfter(); } + if (callbackAfter) { + callbackAfter(); + } }) .catch(error => { console.log(error.message || error); @@ -55,12 +66,14 @@ App.Art.GenAI.Archiving = class Archiving { function beforeAdding(filename) { document.getElementById("dialog-ai-archiving").textContent = `Exporting ${filename}`; } + function afterAdding() { document.getElementById("dialog-ai-archiving-progress").value += 1; } + let imagesCount = V.PC.custom.aiImageIds.length; let manifest = {"PC": []}; - for (const s of V.slaves) { + for (const s of getSlaves()) { imagesCount += s.custom.aiImageIds.length; manifest[s.ID] = []; } @@ -72,7 +85,7 @@ App.Art.GenAI.Archiving = class Archiving { let zip = new JSZip(); manifest.PC = await Archiving.#exportImages(V.PC, zip, beforeAdding, afterAdding); - for (const s of V.slaves) { + for (const s of getSlaves()) { manifest[s.ID] = await Archiving.#exportImages(s, zip, beforeAdding, afterAdding); } @@ -105,7 +118,9 @@ App.Art.GenAI.Archiving = class Archiving { let zip = new JSZip(); let manifest = {}; - if (s.ID === -111111) { s.ID = "PC"; } + if (s.ID === -111111) { + s.ID = "PC"; + } manifest[s.ID] = await Archiving.#exportImages(s, zip); zip.file("manifest.json", JSON.stringify(manifest)); @@ -130,7 +145,7 @@ App.Art.GenAI.Archiving = class Archiving { link.download = filename; link.click(); link.remove(); - } catch (e) { + } catch (e) { console.log(e.message || e); } } @@ -173,7 +188,7 @@ App.Art.GenAI.Archiving = class Archiving { console.error(e); } } - }; + }; input.click(); } @@ -183,21 +198,28 @@ App.Art.GenAI.Archiving = class Archiving { * Calls importContainer with the expectation that all the characters in the chosen .zip * are present in the current arcology. */ - static async importArcology(){ + static async importArcology() { + function updateProgress() { + document.getElementById("dialog-ai-archiving-progress").value += 1; + } + Dialog.create("Importing an arcology"); + Dialog.append(`<p id="dialog-ai-archiving"></p>`); + Dialog.append(`<progress id="dialog-ai-archiving-progress" value="0" max="0" style="width: 100%"></progress>`); + const message = document.getElementById("dialog-ai-archiving"); + Dialog.open(); + message.textContent = `Opening the archive...`; await Archiving.importContainer(async (zip, manifest) => { - Dialog.setup("Importing an arcology"); - Dialog.append(`<p>${Object.keys(manifest).length} characters to import.</p>`); - Dialog.append(`<p id="dialog-ai-archiving"></p>`); - Dialog.append(`<progress id="dialog-ai-archiving-progress" value="0" max="${Object.keys(manifest).length}" style="width: 100%"></progress>`); - Dialog.open(); + document.getElementById("dialog-ai-archiving-progress").max = Object.values(manifest).reduce((a, c) => a + Object.keys(c).length, 0); + let i = 1; for (const [k, v] of Object.entries(manifest)) { let characterManifest = {}; characterManifest[k] = v; - let character = (k === "PC" ? V.PC : V.slaves[V.slaveIndices[k]]); - document.getElementById("dialog-ai-archiving").textContent = `Importing ${character.slaveSurname} ${character.slaveName}`; - await Archiving.#processCharacter(zip, character, characterManifest); - document.getElementById("dialog-ai-archiving-progress").value += 1; + let character = (k === "PC" ? V.PC : getSlave(Number(k))); + message.textContent = `Importing ${i}/${Object.keys(manifest).length}: ${character.slaveSurname} ${character.slaveName}`; + await Archiving.#processCharacter(zip, character, characterManifest, updateProgress); + i++; } + Archiving.signatureCache = new Map(); Dialog.close(); }); } @@ -213,9 +235,22 @@ App.Art.GenAI.Archiving = class Archiving { * Used to refresh the art container for the character. */ static async importCharacter(s, finalize) { + function updateProgress() { + document.getElementById("dialog-ai-archiving-progress").value += 1; + } + Dialog.create("Importing a character"); + Dialog.append(`<p id="dialog-ai-archiving"></p>`); + Dialog.append(`<progress id="dialog-ai-archiving-progress" value="0" max="0" style="width: 100%"></progress>`); + const message = document.getElementById("dialog-ai-archiving"); + const progress = document.getElementById("dialog-ai-archiving-progress"); + Dialog.open(); await Archiving.importContainer(async (zip, manifest) => { - await Archiving.#processCharacter(zip, s, manifest); + progress.max = Object.keys(manifest[s.ID]).length; + message.textContent = `Import ${progress.max} images for ${s.slaveSurname} ${s.slaveName}`; + await Archiving.#processCharacter(zip, s, manifest, updateProgress); finalize(); + Archiving.signatureCache = new Map(); + Dialog.close(); }); } @@ -225,36 +260,37 @@ App.Art.GenAI.Archiving = class Archiving { * according to the given manifest. * * @param {JSZip} zip - * @param {FC.SlaveState} s + * @param {FC.HumanState} s * @param {object} manifest See exportImages() + * @param {Function} callback Callback after each image * @returns {Promise<void>} */ - static async #processCharacter(zip, s, manifest) { + static async #processCharacter(zip, s, manifest, callback) { try { if (Object.keys(manifest)[0] === "PC") { manifest = {'-1': manifest.PC}; s = V.PC; } else if (!Object.keys(V.slaveIndices).includes(Object.keys(manifest)[0])) { throw new Error(`Character ID ${Object.keys(manifest)[0]} is not present in current game!`); - } else if (s.ID !== V.slaves[V.slaveIndices[Object.keys(manifest)[0]]].ID) { + } else if (s.ID !== getSlave(Number(Object.keys(manifest)[0])).ID) { throw new Error(`The loaded archive has not been made from the selected character!`); } + const aiImageIds = await App.Art.GenAI.staticImageDB.getIndexesList(); s.custom.aiImageIds = []; for (const img of manifest[s.ID]) { let f = zip.file(img.path); if (f) { let imageData = getImageData(await f.async("base64")); - let imagePreexisting = await compareExistingImages(s, imageData); - if (imagePreexisting === -1) { - const imageId = await App.Art.GenAI.staticImageDB.putImage({data: imageData, week: img.week}); - s.custom.aiImageIds.push(imageId); - } else { - s.custom.aiImageIds.push(imagePreexisting); + let imageId = await Archiving.compareSignatures(await Archiving.sha1(imageData), aiImageIds); + if (imageId === -1) { + imageId = await App.Art.GenAI.staticImageDB.putImage({data: imageData, week: img.week}); } + s.custom.aiImageIds.push(imageId); } else { console.log(`Path "${img.path}" is listed in the manifest but doesn't exist in the archive. The archive may be corrupted.`); } + callback(); } s.custom.aiDisplayImageIdx = s.custom.aiImageIds.length - 1; } catch (e) { @@ -262,4 +298,42 @@ App.Art.GenAI.Archiving = class Archiving { alert(e); } } + + /** + * Compare a sha1 signature against the signatures of a list of imageIDs in indexedDB. + * + * It builds a cache of sha1 signatures to speed up comparisons, which is meant to be + * cleared by the main import function after finishes its job. This means the calculations + * will need to be redone for each character or arcology import, but this is not a frequent + * enough operation to justify keeping it in-memory. + * + * @param {string} signature + * @param {number[]} imageIDs + * @returns {number} The ID of the existing image, or -1 if the image doesn't exist. + */ + static async compareSignatures(signature, imageIDs) { + for (let imageID of imageIDs) { + if (![...Archiving.signatureCache.values()].includes(imageID)) { + Archiving.signatureCache.set( + await Archiving.sha1((await App.Art.GenAI.staticImageDB.getImage(imageID)).data), + imageID); + } + if (Archiving.signatureCache.has(signature)) { + return Archiving.signatureCache.get(signature); + } + } + return -1; + } + + /** + * Returns the sha1 hash of a string. + * + * @param {string} s + * @returns {Promise<string>} + */ + static async sha1(s) { + const buffer = await crypto.subtle.digest('SHA-1', new TextEncoder().encode(s)); + const a = Array.from(new Uint8Array(buffer)); + return a.map(b => b.toString(16).padStart(2, '0')).join(''); + } }; diff --git a/src/art/genAI/buildPrompt.js b/src/art/genAI/buildPrompt.js index 3a4d63168abdb59f1a00283ae14d9ac02f28f4c3..9c4aa6b83f203113e6ccab482d4e55ba3be9db0a 100644 --- a/src/art/genAI/buildPrompt.js +++ b/src/art/genAI/buildPrompt.js @@ -9,16 +9,27 @@ globalThis.buildPrompt = (slave) => { } let prompts = []; switch (V.aiBaseModel) { - case 1: // SDXL/Pony + case 1: case 2: // SDXL/Pony prompts = [ new App.Art.GenAI.StylePromptPart(slave), new App.Art.GenAI.StructurePromptPart(slave), - new App.Art.GenAI.NationalityPromptPart(slave), new App.Art.GenAI.HairPromptPart(slave), new App.Art.GenAI.RacePromptPart(slave), + new App.Art.GenAI.NationalityPromptPart(slave), new App.Art.GenAI.DemographicsPromptPart(slave), - new App.Art.GenAI.FacePromptPart(slave), + new App.Art.GenAI.CrotchPromptPart(slave), + new App.Art.GenAI.AccessoryPromptPart(slave), + new App.Art.GenAI.PubicHairPromptPart(slave), + new App.Art.GenAI.WeightPromptPart(slave), + new App.Art.GenAI.SkinPromptPart(slave), + new App.Art.GenAI.MusclesPromptPart(slave), + new App.Art.GenAI.EarsPromptPart(slave), + new App.Art.GenAI.EyePromptPart(slave), + new App.Art.GenAI.EyebrowPromptPart(slave), + new App.Art.GenAI.ExpressionPromptPart(slave), + new App.Art.GenAI.ArousalPromptPart(slave), new App.Art.GenAI.ClothesPromptPart(slave), + new App.Art.GenAI.AndroidPromptPart(slave), new App.Art.GenAI.CustomPromptPart(slave), ]; break; @@ -37,9 +48,10 @@ globalThis.buildPrompt = (slave) => { new App.Art.GenAI.HeightPromptPart(slave), new App.Art.GenAI.MusclesPromptPart(slave), new App.Art.GenAI.ClothesPromptPart(slave), + new App.Art.GenAI.AccessoryPromptPart(slave), new App.Art.GenAI.CollarPromptPart(slave), new App.Art.GenAI.BreastsPromptPart(slave), - new App.Art.GenAI.CrotchPromptPart(slave), + new App.Art.GenAI.CrotchPromptPart(slave), new App.Art.GenAI.FakeTitsPromptPart(slave), new App.Art.GenAI.HugeFakeTitsPromptPart(slave), new App.Art.GenAI.WaistPromptPart(slave), diff --git a/src/art/genAI/helpers.js b/src/art/genAI/helpers.js index 287824330015f4ff69a057ccdeed3939f9f7a2cf..fad02eeda6da0eba3dd69cec3c4a787e1f1e64e9 100644 --- a/src/art/genAI/helpers.js +++ b/src/art/genAI/helpers.js @@ -1,126 +1,152 @@ App.Art.GenAI.PromptHelpers = (() => { + const SANITIZATION_REGEX = /^\s*(a?\s+)?(.*)\s*$/; -const SANITIZATION_REGEX = /^\s*(a?\s+)?(.*)\s*$/; + const BOTTOMLESS_OUTFITS = new Set([ + "harem gauze", + "bra", + "sports bra", + "striped bra", + "pasties", + ]); -const BOTTOMLESS_OUTFITS = new Set([ - "harem gauze", - "bra", - "sports bra", - "striped bra", - "pasties", -]); + const TOPLESS_OUTFITS = new Set([ + "striped underwear", + "thong", + "skimpy loincloth", + "boyshorts", + "panties", + "cutoffs", + "sport shorts", + "leather pants", + "jeans", + ]); -const TOPLESS_OUTFITS = new Set([ - "striped underwear", - "thong", - "skimpy loincloth", - "boyshorts", - "panties", - "cutoffs", - "sport shorts", - "leather pants", - "jeans", -]); + const NAKEDISH_OUTFITS = new Set([ + "no clothing", + "chains", + "body oil", + "uncomfortable straps", + "shibari ropes", + ]); -const NAKEDISH_OUTFITS = new Set([ - "no clothing", - "chains", - "body oil", - "uncomfortable straps", - "shibari ropes", -]); + const UNDERWEAR_ONLY_OUTFITS = new Set([ + "attractive lingerie", + "attractive lingerie for a pregnant woman", + "kitty lingerie", + "string bikini", + "scalemail bikini", + "striped panties", + ]); -const UNDERWEAR_ONLY_OUTFITS = new Set([ - "attractive lingerie", - "attractive lingerie for a pregnant woman", - "kitty lingerie", - "string bikini", - "scalemail bikini", - "striped panties", -]); + const TRANSPARENT_OUTFITS = new Set([ + "clubslut netting", + "harem gauze", + "slave gown", + ]); -const TRANSPARENT_OUTFITS = new Set([ - "clubslut netting", - "harem gauze", - "slave gown", -]); + const MIDRIFF_EXPOSING_OUTFITS = new Set([ + "cheerleader outfit", + "slave gown", + "tube top", + "bra", + "sports bra", + "striped bra", + "pasties", + "tube top and thong", + "sport shorts and a sports bra", + "panties and pasties", + "leather pants and a tube top", + "leather pants and pasties", + "slutty outfit", + "bimbo outfit", + ...TOPLESS_OUTFITS, + ...UNDERWEAR_ONLY_OUTFITS, + ...TRANSPARENT_OUTFITS, + ...NAKEDISH_OUTFITS, + ]); -const MIDRIFF_EXPOSING_OUTFITS = new Set([ - "cheerleader outfit", - "slave gown", - "tube top", - "bra", - "sports bra", - "striped bra", - "pasties", - "tube top and thong", - "sport shorts and a sports bra", - "panties and pasties", - "leather pants and a tube top", - "leather pants and pasties", - "slutty outfit", - "bimbo outfit", -]).union( - TOPLESS_OUTFITS -).union( - UNDERWEAR_ONLY_OUTFITS -).union( - TRANSPARENT_OUTFITS -).union( - NAKEDISH_OUTFITS -); + const NIPPLE_EXPOSING_OUTFITS = new Set([ + "attractive lingerie", + "attractive lingerie for a pregnant woman", + "string bikini", + ...TOPLESS_OUTFITS, + ...TRANSPARENT_OUTFITS, + ...NAKEDISH_OUTFITS, + ]); -const NIPPLE_EXPOSING_OUTFITS = new Set([ -]).union( - TOPLESS_OUTFITS -).union( - TRANSPARENT_OUTFITS -).union( - NAKEDISH_OUTFITS -); + const BREAST_EXPOSING_OUTFITS = new Set([ + "comfortable bodysuit", + "pasties", + "panties and pasties", + "leather pants and pasties", + "slutty outfit", + ...TOPLESS_OUTFITS, + ...TRANSPARENT_OUTFITS, + ...NAKEDISH_OUTFITS, + ]); -const BREAST_EXPOSING_OUTFITS = new Set([ - "comfortable bodysuit", - "pasties", - "panties and pasties", - "leather pants and pasties", - "slutty outfit", -]).union( - NIPPLE_EXPOSING_OUTFITS, -); + const CROTCH_EXPOSING_OUTFITS = new Set([ + ...BOTTOMLESS_OUTFITS, + ...TRANSPARENT_OUTFITS, + ...NAKEDISH_OUTFITS + ]); -const CROTCH_EXPOSING_OUTFITS = new Set([ -]).union( - BOTTOMLESS_OUTFITS -).union( - TRANSPARENT_OUTFITS -).union( - NAKEDISH_OUTFITS -); + const sanitizeDescriptor = (descriptor) => ( + /** + * Get's rid of leading "a" and any trailing or leading whitespace" and + * converts to lower-case. + **/ + descriptor.match(SANITIZATION_REGEX)[2].toLowerCase() + ); -const sanitizeDescriptor = (descriptor) => ( - /** - * Get's rid of leading "a" and any trailing or leading whitespace" and - * converts to lower-case. - **/ - descriptor.match(SANITIZATION_REGEX)[2].toLowerCase() -); + const validateAgainst = (description, targets) => targets.has(sanitizeDescriptor(description)); -const validateAgainst = (description, targets) => targets.has(sanitizeDescriptor(description)); + const xlBaseModel = () => V.aiBaseModel === (1||2); // this could be more general when other models are implemented -return { - sanitizeDescriptor, - exposesMidriff: (description) => validateAgainst( - description, MIDRIFF_EXPOSING_OUTFITS - ), - exposesNipples: (description) => validateAgainst( - description, NIPPLE_EXPOSING_OUTFITS - ), - exposesBreasts: (description) => validateAgainst( - description, BREAST_EXPOSING_OUTFITS - ), - exposesCrotch: (description) => validateAgainst( - description, CROTCH_EXPOSING_OUTFITS - ), -}; + const isFeminine = (slave) => { + if (V.aiGenderHint === 1) { // Hormone balance + const hormoneTransitionThreshold = 100; + if (slave.hormoneBalance >= hormoneTransitionThreshold) { + return true; // transwoman (or hormone-boosted natural woman) + } + return slave.genes === "XX" && (slave.hormoneBalance > -hormoneTransitionThreshold); // natural woman, and NOT transman + } else if (V.aiGenderHint === 2) { // Perceived gender + return perceivedGender(slave) > 1; + } else if (V.aiGenderHint === 3) { // Pronouns + return slave.pronoun === App.Data.Pronouns.Kind.female; + } else { + return false; + } + }; + + const isMasculine = (slave) => { + if (V.aiGenderHint === 1) { // Hormone balance + return !isFeminine(slave); + } else if (V.aiGenderHint === 2) { // Perceived gender + return perceivedGender(slave) < -1; + } else if (V.aiGenderHint === 3) { // Pronouns + return slave.pronoun === App.Data.Pronouns.Kind.male; + } else { + return false; + } + }; + + return { + sanitizeDescriptor, + exposesMidriff: (description) => validateAgainst( + description, MIDRIFF_EXPOSING_OUTFITS + ), + exposesNipples: (description) => validateAgainst( + description, NIPPLE_EXPOSING_OUTFITS + ), + exposesBreasts: (description) => validateAgainst( + description, BREAST_EXPOSING_OUTFITS + ), + exposesCrotch: (description) => validateAgainst( + description, CROTCH_EXPOSING_OUTFITS + ), + xlBaseModel, + isFeminine, + isMasculine, + }; })(); diff --git a/src/art/genAI/ponyPrompts/demographicsPromptPart.js b/src/art/genAI/ponyPrompts/demographicsPromptPart.js index b8c3d2108f64c6cf077a1e2974003c25e47a25c4..fabc1dc29884daf09d63bb23759db0c5f53a22e5 100644 --- a/src/art/genAI/ponyPrompts/demographicsPromptPart.js +++ b/src/art/genAI/ponyPrompts/demographicsPromptPart.js @@ -1,32 +1,4 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App.Art.GenAI.PromptPart { - get isFeminine() { - if (V.aiGenderHint === 1) { // Hormone balance - const hormoneTransitionThreshold = 100; - if (this.slave.hormoneBalance >= hormoneTransitionThreshold) { - return true; // transwoman (or hormone-boosted natural woman) - } - return this.slave.genes === "XX" && (this.slave.hormoneBalance > -hormoneTransitionThreshold); // natural woman, and NOT transman - } else if (V.aiGenderHint === 2) { // Perceived gender - return perceivedGender(this.slave) > 1; - } else if (V.aiGenderHint === 3) { // Pronouns - return this.slave.pronoun === App.Data.Pronouns.Kind.female; - } else { - return false; - } - } - - get isMasculine() { - if (V.aiGenderHint === 1) { // Hormone balance - return !this.isFeminine; - } else if (V.aiGenderHint === 2) { // Perceived gender - return perceivedGender(this.slave) < -1; - } else if (V.aiGenderHint === 3) { // Pronouns - return this.slave.pronoun === App.Data.Pronouns.Kind.male; - } else { - return false; - } - } - /** * @override */ @@ -44,24 +16,28 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. } if (this.isFeminine) { - if (slave?.visualAge >= 40) { - parts.push(height + 'mature'); + if ((slave?.visualAge < 18) && !V.aiAgeFilter) { + parts.push(height + 'young girl, loli'); } else if (slave?.visualAge <= 20) { parts.push(height + 'young woman'); - } else if ((slave?.visualAge < 18) && V.aiAgeFilter) { - parts.push(height + 'young girl'); + } else if (slave?.visualAge <= 40) { + parts.push(height + 'woman'); + } else if (slave?.visualAge >= 40) { + parts.push(height + 'mature'); } if (perceivedGender(this.slave) < -1) { parts.push('butch'); } } else if (this.isMasculine) { - if (slave?.visualAge >= 40) { - parts.push(height + 'older man'); + if ((slave?.visualAge < 18) && !V.aiAgeFilter) { + parts.push(height + 'young boy', 'shota'); } else if (slave?.visualAge <= 20) { parts.push(height + 'young man'); - } else if ((slave?.visualAge < 18) && V.aiAgeFilter) { - parts.push(height + 'young boy'); + } else if (slave?.visualAge <= 40) { + parts.push(height + 'man'); + } else if (slave?.visualAge >= 40) { + parts.push(height + 'older man'); } if (perceivedGender(this.slave) > 1) { @@ -69,116 +45,51 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. } } + if ((slave?.visualAge < 10) && !V.aiAgeFilter) { + parts.push(height + 'young child'); + } + if (slave?.visualAge >= 60) { parts.push('elderly'); } - if (slave?.visualAge <= 16 && V.aiAgeFilter) { + if (this.censored) { parts.push('teenager'); } - // weight - if (slave?.weight < -95) { - parts.push('skinny, emaciated'); - } else if (slave?.weight < -30) { - parts.push('skinny'); - } else if (slave?.weight < -10) { - parts.push('slim'); - } else if (slave?.weight > 10) { - parts.push('curvy'); - } else if (slave?.weight > 30) { - parts.push('fat'); - } else if (slave?.weight > 95) { - parts.push('fat, obese'); - } - - // skin colour - if (this.slave.geneticQuirks.albinism === 2) { - parts.push("albino"); - } - - switch (slave?.skin) { - case "pure white": - case "ivory": - case "white": - case "extremely fair": - parts.push("white skin"); - break; - case "extremely pale": - case "very pale": - case "pale": - case "light beige": - case "very fair": - parts.push("pale skin"); - break; - case "fair": - case "light": - case "beige": - parts.push("fair skin"); - break; - case "light olive": - case "sun tanned": - case "spray tanned": - case "tan": - parts.push("tan skin"); - break; - case "olive": - case "bronze": - case "dark beige": - parts.push("olive skin"); - break; - case "dark olive": - case "light brown": - case "brown": - parts.push("brown skin"); - break; - case "dark": - case "dark brown": - case "black": - case "ebony": - parts.push("dark skin"); - break; - case "pure black": - parts.push("black skin"); - break; - default: - parts.push(`${this.slave.skin} skin`); - } - - // muscles - if (slave?.muscles > 95) { - parts.push('huge muscles'); - } else if (slave?.muscles > 50) { - parts.push('muscles'); - } else if (slave?.muscles > 30) { - parts.push('toned'); + if ((slave?.visualAge < 10) && !V.aiAgeFilter) { + parts.push('kid'); + } else if ((slave?.visualAge < 6) && !V.aiAgeFilter) { + parts.push('child'); } // breasts let breastShape = ''; - switch (slave?.boobShape) { - case "perky": - case "torpedo-shaped": - breastShape = 'perky '; - break; - case "downward-facing": - case "saggy": - case "wide-set": - breastShape = 'saggy '; - break; + if (slave?.boobs > 300) { + switch (slave?.boobShape) { + case "perky": + case "torpedo-shaped": + breastShape = 'perky '; + break; + case "downward-facing": + case "saggy": + case "wide-set": + breastShape = 'saggy '; + break; + } } if (slave?.boobs < 300) { - breastShape += 'flat chest'; + breastShape += V.aiBaseModel === 2 ? 'flat chested' : 'flat chest'; // Pony uses a slightly different tag } else if (slave?.boobs < 400) { - breastShape += 'flat breasts'; + breastShape += 'tiny '; } else if (slave?.boobs < 500) { breastShape += 'small '; - } else if (slave?.boobs < 650 || (this.slave.visualAge < 6 && !V.aiAgeFilter)) { + } else if (slave?.boobs < 650 || (this.slave.visualAge < 6 && !this.censored)) { breastShape += 'medium '; - } else if (slave?.boobs < 800 || (this.slave.visualAge < 10 && !V.aiAgeFilter)) { + } else if (slave?.boobs < 800 || (this.slave.visualAge < 10 && !this.censored)) { breastShape += 'large '; - } else if (slave?.boobs < 1000 || (this.slave.visualAge < 18 && !V.aiAgeFilter)) { + } else if (slave?.boobs < 1000 || (!this.censored)) { breastShape += 'huge '; } else if (slave?.boobs < 1400) { breastShape += 'giant breasts, huge '; @@ -201,9 +112,9 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. const clothingBreastParts = []; if (clothingBreasts.includes(slave?.clothes)) { - if (slave?.boobsImplant === 0) { + if (slave?.boobsImplant === 0 && slave?.boobs > 300) { clothingBreastParts.push('breasts'); - } else { + } else if (slave?.boobsImplant !== 0) { clothingBreastParts.push('fake tits'); } } @@ -217,9 +128,9 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. clothingBreastParts.push('underboob'); } if (clothingBreastParts.length === 0) { - if (slave?.boobsImplant === 0) { + if (slave?.boobsImplant === 0 && slave?.boobs > 300) { clothingBreastParts.push('breasts'); - } else { + } else if (slave?.boobsImplant !== 0) { clothingBreastParts.push('fake tits'); } } @@ -228,7 +139,7 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. // display nipple if uncovered, or covered nipples if large // nipple piercings also handled here - if (clothingBreasts.includes(slave?.clothes)) { + if (this.helper.exposesNipples(this.slave.clothes)) { switch (slave?.nipples) { case "huge": parts.push('big nipples'); @@ -241,6 +152,9 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. case "partially inverted": parts.push('inverted nipples'); break; + default: + parts.push('nipples'); + break; } if ((slave?.piercing.areola.weight > 0 || slave?.piercing.nipple.weight > 0) && (slave?.visualAge < 18 && V.aiAgeFilter)) { @@ -250,7 +164,7 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. switch (slave?.nipples) { case "huge": case "puffy": - parts.push('covered nipples'); + parts.push(V.aiBaseModel === 2 ? 'nipple outline' : 'covered nipples'); // Using covered nipples on Pony is detrimental when clothed break; default: if (slave?.visualAge < 18 && V.aiAgeFilter) { @@ -268,7 +182,7 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. parts.push('wide hips'); } if (slave?.hips > 2) { - parts.push('huge ass'); // causes preference for behind view and conflicts with other parts of the prompt -- consider removing if troublesome + parts.push('wide hips, thick thighs'); } return parts.join(', '); @@ -281,23 +195,11 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. const slave = asSlave(this.slave); const parts = []; - if (slave?.visualAge < 18 && V.aiAgeFilter) { - parts.push('source_nsfw, nude'); - } - // handles masculine female phenotype if (this.isFeminine && perceivedGender(this.slave) < -1) { parts.push('woman'); } - if (slave?.weight < -30) { - parts.push('fat'); - } - - if (slave?.muscles < -30) { - parts.push('muscles'); - } - switch (slave?.boobShape) { case "perky": case "torpedo-shaped": @@ -318,7 +220,76 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. parts.push('wide hips'); } if (slave?.hips < -2) { - parts.push('huge ass'); + parts.push('huge hips'); + } + + return parts.join(', '); + } + + face() { + const slave = asSlave(this.slave); + const parts = []; + + // age, gender + if (this.isFeminine) { + if ((slave?.visualAge < 18) && !V.aiAgeFilter) { + switch (V.aiBaseModel) { + case 1: case 2: //SDXL and Pony + parts.push('young, loli'); + default: + parts.push('young girl'); + } + } else if (slave?.visualAge <= 20) { + parts.push('young woman'); + } else if (slave?.visualAge <= 40) { + parts.push('woman'); + } else if (slave?.visualAge >= 40) { + parts.push('mature'); + } + + if (perceivedGender(this.slave) < -1) { + parts.push('butch'); + } else if (perceivedGender(this.slave) > -1 && perceivedGender(this.slave) < 1) { + parts.push('androgynous'); + } + } else if (this.isMasculine) { + if ((slave?.visualAge < 18) && !V.aiAgeFilter) { + switch (V.aiBaseModel) { + case 1: case 2: //SDXL and Pony + parts.push('young, shota'); + default: + parts.push('young boy'); + } + } else if (slave?.visualAge <= 20) { + parts.push('young man'); + } else if (slave?.visualAge <= 40) { + parts.push('man'); + } else if (slave?.visualAge >= 40) { + parts.push('older man'); + } + + if (perceivedGender(this.slave) > 1) { + switch (V.aiBaseModel) { + case 1: case 2: + parts.push('girly, femboy'); + default: + parts.push('feminine'); + } + } else if (perceivedGender(this.slave) > -1 && perceivedGender(this.slave) < 1) { + parts.push('androgynous'); + } + } + + if ((slave?.visualAge < 10) && !V.aiAgeFilter) { + parts.push('child'); + } + + if (slave?.visualAge >= 60) { + parts.push('elderly'); + } + + if (slave?.visualAge <= 18 && V.aiAgeFilter) { + parts.push('teenager'); } return parts.join(', '); diff --git a/src/art/genAI/ponyPrompts/structurePromptPart.js b/src/art/genAI/ponyPrompts/structurePromptPart.js index f3b0feaf5da79509a1b305e41cefc97950ce4cea..8d217b52cdbe5fcc62946796ddc85849df97420a 100644 --- a/src/art/genAI/ponyPrompts/structurePromptPart.js +++ b/src/art/genAI/ponyPrompts/structurePromptPart.js @@ -8,7 +8,7 @@ App.Art.GenAI.StructurePromptPart = class StructurePromptPart extends App.Art.Ge const slave = asSlave(this.slave); const parts = []; - parts.push('realistic, portrait, solo'); // portrait structure prompt may become unnecessary once rest of body part prompts are in? + parts.push('portrait, solo'); // portrait structure prompt may become unnecessary once rest of body part prompts are in? if (isQuadrupedal(this.slave)) { return 'all fours'; // too hard to do anything else with this stance diff --git a/src/art/genAI/prompts/accessoryPromptPart.js b/src/art/genAI/prompts/accessoryPromptPart.js new file mode 100644 index 0000000000000000000000000000000000000000..073fdd5ffbada8992520a98c11f93c7216e99ffb --- /dev/null +++ b/src/art/genAI/prompts/accessoryPromptPart.js @@ -0,0 +1,38 @@ +App.Art.GenAI.AccessoryPromptPart = class AccessoryPromptPart extends App.Art.GenAI.PromptPart { + /** + * @returns {string} + */ + positive() { + let accessories = []; + + if (this.slave.armAccessory !== "none") { + accessories.push(this.slave.armAccessory); + } + + if (this.slave.legAccessory !== "none") { + accessories.push(this.slave.legAccessory); + } + + if (this.slave.bellyAccessory !== "none") { + accessories.push(this.slave.bellyAccessory); + } + + if (this.slave.buttplugAttachment !== "none") { + accessories.push(this.slave.buttplugAttachment); + } + + if (this.slave.shoes !== "none") { + accessories.push(this.slave.shoes); + } else { + accessories.push("barefoot"); + } + return accessories.join(', '); + } + + /** + * @returns {string} + * */ + negative() { + return undefined; + } +}; diff --git a/src/art/genAI/prompts/androidPromptPart.js b/src/art/genAI/prompts/androidPromptPart.js index 75785ae0aa4c5965cf0a5f6229f62be2a2879b26..e45a0cbd0b39b4b43a92e2e7afd148a828d2ea4f 100644 --- a/src/art/genAI/prompts/androidPromptPart.js +++ b/src/art/genAI/prompts/androidPromptPart.js @@ -7,13 +7,15 @@ App.Art.GenAI.AndroidPromptPart = class AndroidPromptPart extends App.Art.GenAI. if (asSlave(this.slave)?.fuckdoll > 0) { // limbs covered by fuckdoll suit - } else if (App.Art.GenAI.sdClient.hasLora("hololive_roboco-san-10")) { - if (hasBothProstheticArms(this.slave) && hasBothProstheticLegs(this.slave) && !this.censored) { - parts.push(`<lora:hololive_roboco-san-10:1>, android, mechanical arms, mechanical legs`); - } else if (hasBothProstheticArms(this.slave)) { - parts.push(`<lora:hololive_roboco-san-10:1>, android, mechanical arms`); - } else if (hasBothProstheticLegs(this.slave)) { - parts.push(`<lora:hololive_roboco-san-10:1>, android, mechanical legs`); + } else if (App.Art.GenAI.sdClient.hasLora("hololive_roboco-san-10") || V.aiBaseModel === 2) { + if (App.Art.GenAI.sdClient.hasLora("hololive_roboco-san-10") && (hasBothProstheticArms(this.slave) || hasBothProstheticLegs(this.slave))) { + parts.push(`<lora:hololive_roboco-san-10:1>, android`); + } + if (hasBothProstheticArms(this.slave)) { + parts.push(`mechanical arms`); + } + if (hasBothProstheticLegs(this.slave)) { + parts.push(`mechanical legs`); } } if (App.Art.GenAI.sdClient.hasLora('RobotDog0903') && isQuadrupedal(this.slave)) { @@ -30,7 +32,7 @@ App.Art.GenAI.AndroidPromptPart = class AndroidPromptPart extends App.Art.GenAI. if (asSlave(this.slave)?.fuckdoll > 0) { return; // limbs covered by fuckdoll suit } - if (App.Art.GenAI.sdClient.hasLora("hololive_roboco-san-10")) { + if (App.Art.GenAI.sdClient.hasLora("hololive_roboco-san-10") || V.aiBaseModel === 2) { if (hasBothProstheticArms(this.slave) && hasBothProstheticLegs(this.slave)) { return; // space for negative prompt if needed NG } else if (hasBothProstheticArms(this.slave)) { diff --git a/src/art/genAI/prompts/arousalPromptPart.js b/src/art/genAI/prompts/arousalPromptPart.js index 7c18a50b33c429a0c10fb1cd99f2bf7429ecbd27..2249647752757cd1e989afedeb2639a4f47df976 100644 --- a/src/art/genAI/prompts/arousalPromptPart.js +++ b/src/art/genAI/prompts/arousalPromptPart.js @@ -66,4 +66,32 @@ App.Art.GenAI.ArousalPromptPart = class ArousalPromptPart extends App.Art.GenAI. negative() { return undefined; } + + /** + * @override + */ + face() { + let prompt = {terms: [], weight: 1}; + + if (asSlave(this.slave)?.fuckdoll > 0) { + return undefined; + } + if (this.slave.energy > 60) { + prompt.terms.push("blush"); + } + if (this.slave.energy > 80) { + prompt.terms.push("sweat", "heavy breathing"); + } + if (this.slave.energy > 95) { + prompt.weight = 1.1; + } + + if (prompt.terms) { + if (prompt.weight !== 1) { + return `(${prompt.terms.join(", ")}:${prompt.weight})`; + } + return `${prompt.terms.join(", ")}`; + } + return undefined; + } }; diff --git a/src/art/genAI/prompts/beautyPromptPart.js b/src/art/genAI/prompts/beautyPromptPart.js index 29f1142229b9528fedc404d04a45b47760b0aa6b..b5f5b1818d64fcd0fafa7e8f55702c13f01a7880 100644 --- a/src/art/genAI/prompts/beautyPromptPart.js +++ b/src/art/genAI/prompts/beautyPromptPart.js @@ -8,15 +8,19 @@ App.Art.GenAI.BeautyPromptPart = class BeautyPromptPart extends App.Art.GenAI.Pr } if (this.slave.face < -95) { - return "ugly, low quality"; + return "ugly"; } else if (this.slave.face < -50) { - return "unattractive, low quality"; + return "unattractive"; } else if (this.slave.face < 10) { /* empty */ } else if (this.slave.face < 50) { - return "best quality"; + return "attractive"; } else if (this.slave.face < 95) { - return "masterpiece, best quality"; + if (geneToGender(this.slave.genes) === "XY") { + return "handsome"; + } else { + return "beautiful"; + } } else { - return "(masterpiece, best quality:1.1)"; + return "gorgeous"; } } @@ -24,10 +28,6 @@ App.Art.GenAI.BeautyPromptPart = class BeautyPromptPart extends App.Art.GenAI.Pr * @override */ negative() { - if (asSlave(this.slave)?.fuckdoll > 0) { - return undefined; // face not visible - } - - return "low quality"; + return undefined; } }; diff --git a/src/art/genAI/prompts/breastsPromptPart.js b/src/art/genAI/prompts/breastsPromptPart.js index f94c0785a9c9579f520cb99866ba31d4361f6e1d..8771dc97f8388bc56ff99a3fe75fdb59812d2e05 100644 --- a/src/art/genAI/prompts/breastsPromptPart.js +++ b/src/art/genAI/prompts/breastsPromptPart.js @@ -1,14 +1,15 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI.PromptPart { _breastPrompt() { - if (this.censored) { - return null; - } + if (this.censored) { + return null; + } let breastWord = "breasts"; let breastDescriptors = []; let {boobs, boobShape} = this.slave; + // @ts-ignore boobShape = boobShape.toLowerCase(); if (boobShape && boobShape !== "normal") { @@ -17,7 +18,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. if (boobs < 300) { breastDescriptors.push("flat"); - breastWord = "chest"; + breastWord = V.aiBaseModel === 2 ? "chested" : "chest"; } else if (boobs < 400) { breastDescriptors.push("very small"); } else if (boobs < 500) { @@ -30,6 +31,12 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. breastDescriptors.push("very large"); } else if (boobs < 1400) { breastDescriptors.push("huge"); + } else if (V.aiBaseModel === 2) { + if (boobs < 1600) { + breastDescriptors.push("gigantic"); + } else { + breastDescriptors.push("hyper"); + } } else { if (App.Art.GenAI.sdClient.hasLora("BEReaction")) { return `<lora:BEReaction:1>, bereaction, breast expansion, (gigantic breasts:1.2)`; @@ -67,7 +74,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. * middle eastern * amerindian * southern european - * semetic + * semitic * malay * indo-aryan * pacific islander @@ -92,7 +99,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. switch (race) { case "white": case "amerindian": - case "semetic": + case "semitic": case "latina": return "light pink"; case "asian": @@ -102,7 +109,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. case "southern european": case "indo-aryan": case "pacific islander": - case "mixed-race": + case "mixed race": return "light beige"; } } @@ -117,7 +124,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. switch (race) { case "white": case "amerindian": - case "semetic": + case "semitic": case "latina": return "pink"; case "asian": @@ -127,7 +134,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. case "southern european": case "indo-aryan": case "pacific islander": - case "mixed-race": + case "mixed race": return "light brown"; } } @@ -143,7 +150,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. switch (race) { case "white": case "amerindian": - case "semetic": + case "semitic": case "latina": return "dark pink"; case "asian": @@ -153,7 +160,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. case "southern european": case "indo-aryan": case "pacific islander": - case "mixed-race": + case "mixed race": return "brown"; } } @@ -168,7 +175,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. switch (race) { case "white": case "amerindian": - case "semetic": + case "semitic": case "latina": return "light brown"; case "asian": @@ -178,7 +185,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. case "southern european": case "indo-aryan": case "pacific islander": - case "mixed-race": + case "mixed race": return "dark brown"; } } @@ -191,7 +198,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. switch (race) { case "white": case "amerindian": - case "semetic": + case "semitic": case "latina": return "brown"; case "asian": @@ -201,7 +208,7 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. case "southern european": case "indo-aryan": case "pacific islander": - case "mixed-race": + case "mixed race": return "very dark brown"; } } @@ -220,12 +227,13 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. return null; } - const exposesNipples = App.Art.GenAI.PromptHelpers.exposesNipples(this.slave.clothes); + const exposesNipples = this.helper.exposesNipples(this.slave.clothes); if (!exposesNipples) { return null; } let {areolae, areolaeShape, nipples} = this.slave; + // @ts-ignore areolaeShape = areolaeShape.toLowerCase(); let areolaDescriptors = []; @@ -243,14 +251,13 @@ App.Art.GenAI.BreastsPromptPart = class BreastsPromptPart extends App.Art.GenAI. } const nippleAreolaColor = this._colorMatcher(); - areolaDescriptors.push(nippleAreolaColor); areolaDescriptors.push("areola"); let nippleDescriptors = [nippleAreolaColor, "nipples"]; if (nipples) { - nippleDescriptors.unshift(nipples.toLowerCase()); + nippleDescriptors.unshift(nipples); } return [ diff --git a/src/art/genAI/prompts/clothesPromptPart.js b/src/art/genAI/prompts/clothesPromptPart.js index 5ab0e251140edc161d48e6690853a462f5617b92..a54508820aaba9ed1f626ba4bd847393d6bf3b3c 100644 --- a/src/art/genAI/prompts/clothesPromptPart.js +++ b/src/art/genAI/prompts/clothesPromptPart.js @@ -2,7 +2,7 @@ const clothesPrompts = { "no clothing": { - "positive": "(completely nude:1.1)", + "positive": "nude", "negative": "clothes, jeans, underwear, pants, shorts, skirt, panties", }, "a Fuckdoll suit": { // NG good gen requires LoRA, but below will work without LoRA as well @@ -701,13 +701,6 @@ App.Art.GenAI.ClothesPromptPart = class ClothesPromptPart extends App.Art.GenAI. } return clothes; } - get isFeminine() { // re-used from genderPromptPart.js with same strike lines - const hormoneTransitionThreshold = 100; - if (this.slave.hormoneBalance >= hormoneTransitionThreshold) { - return true; // transwoman (or hormone-boosted natural woman) - } - return this.slave.genes === "XX" && (this.slave.hormoneBalance > -hormoneTransitionThreshold); // natural woman, and NOT transman - } /** * Remove positive keywords for genitalia from slaves that don't have the genitalia described by the keyword. @@ -776,7 +769,7 @@ App.Art.GenAI.ClothesPromptPart = class ClothesPromptPart extends App.Art.GenAI. } }); } - return negPrompt + return negPrompt; } /** diff --git a/src/art/genAI/prompts/crotchPromptPart.js b/src/art/genAI/prompts/crotchPromptPart.js index ec07f6fbc34f630331984332501fe9409a930e5e..1815566ea0ec75749ba33030a93f80ce6f726442 100644 --- a/src/art/genAI/prompts/crotchPromptPart.js +++ b/src/art/genAI/prompts/crotchPromptPart.js @@ -3,18 +3,29 @@ App.Art.GenAI.CrotchPromptPart = class CrotchPromptPart extends App.Art.GenAI.Pr * @override */ positive() { - const exposesCrotch = App.Art.GenAI.PromptHelpers.exposesCrotch(this.slave.clothes); + const exposesCrotch = this.helper.exposesCrotch(this.slave.clothes); if (!exposesCrotch || this.censored) { - return ""; + if (!this.censored && this.slave.dick) { + return "bulge" + } + return undefined; } + let promptParts = []; - const {vagina, clit, labia, dick, foreskin, scrotum, balls} = this.slave; + if (this.slave.chastityPenis || this.slave.chastityVagina) { + let type = this.slave.chastityPenis ? "cage" : "belt"; + if (App.Art.GenAI.sdClient.hasLora("chastitybelt")) { + return `chastity ${type}, <lora:chastitybelt:0.7>`; + } else { + return `chastity ${type}`; + } + } - let promptParts = []; + const {vagina, clit, labia, dick, foreskin, scrotum, balls} = this.slave; if (dick && vagina >= 0) { // Applying this hard to override dick and pussy prompts. - promptParts.push("(futanari)"); + promptParts.push("futanari, herm"); } if (dick) { @@ -113,7 +124,7 @@ App.Art.GenAI.CrotchPromptPart = class CrotchPromptPart extends App.Art.GenAI.Pr promptParts.push(vaginaDescription); } - return promptParts.join(","); + return promptParts.join(", "); } /** @@ -141,6 +152,6 @@ App.Art.GenAI.CrotchPromptPart = class CrotchPromptPart extends App.Art.GenAI.Pr } } - return promptParts.join(","); + return promptParts.join(", "); } }; diff --git a/src/art/genAI/prompts/earsPromptPart.js b/src/art/genAI/prompts/earsPromptPart.js index 86519f86a53a1f91e008d9801889671b33711cf6..aea8f1888d6a160285be48828c0021373d162248 100644 --- a/src/art/genAI/prompts/earsPromptPart.js +++ b/src/art/genAI/prompts/earsPromptPart.js @@ -18,4 +18,11 @@ App.Art.GenAI.EarsPromptPart = class EarsPromptPart extends App.Art.GenAI.Prompt negative() { return undefined; } + + /** + * @override + */ + face() { + return this.positive(); + } }; diff --git a/src/art/genAI/prompts/expressionPromptPart.js b/src/art/genAI/prompts/expressionPromptPart.js index 110ac4b3031302cfbb75e90872799a10249a90ee..c754e7aebe8358a53e97023d210c0b8a0f80ee4a 100644 --- a/src/art/genAI/prompts/expressionPromptPart.js +++ b/src/art/genAI/prompts/expressionPromptPart.js @@ -52,13 +52,20 @@ App.Art.GenAI.ExpressionPromptPart = class ExpressionPromptPart extends App.Art. } } + let expression; + if (devotionPart && trustPart) { - return `(${devotionPart}, ${trustPart})`; + expression = `${devotionPart}, ${trustPart}`; } else if (devotionPart) { - return `(${devotionPart})`; + expression = `${devotionPart}`; } else if (trustPart) { - return `(${trustPart})`; + expression = `${trustPart}`; + } + + if (this.helper.xlBaseModel()) { + return `${expression}`; } + return `(${expression})`; } } @@ -108,4 +115,11 @@ App.Art.GenAI.ExpressionPromptPart = class ExpressionPromptPart extends App.Art. } } } + + /** + * @override + */ + face() { + return this.positive(); + } }; diff --git a/src/art/genAI/prompts/eyePromptPart.js b/src/art/genAI/prompts/eyePromptPart.js index c448a77c9ccc6986a3e36cb1178a79d9b507bef6..eb0194aab9eeb45703597df2679b9a43040aa956 100644 --- a/src/art/genAI/prompts/eyePromptPart.js +++ b/src/art/genAI/prompts/eyePromptPart.js @@ -14,7 +14,19 @@ App.Art.GenAI.EyePromptPart = class EyePromptPart extends App.Art.GenAI.PromptPa if (!canSee(this.slave) && App.Art.GenAI.sdClient.hasLora("eye-allsclera")) { positive.push(`<lora:eye-allsclera:1>`); } else if (this.slave.eye.left.iris === this.slave.eye.right.iris) { - positive.push(`${this.slave.eye.left.iris} eyes`); + positive.push(`${this.slave.eye.left.iris} eyes, ${this.slave.eye.left.sclera} sclera`); + switch (this.slave.eye.left.sclera) { + case "catlike": case "demonic": case "devilish": case "serpent-like": + positive.push("slit pupils") + case "goat-like": + positive.push("horizontal pupils") //Probably won't do anything, even on Pony + case "heart-shaped": + positive.push("<3 eyes") + case "hypnotic": + positive.push("spiral eyes") + case "vacant": + positive.push("blank eyes") + } } else { positive.push(`heterochromia, ${this.slave.eye.left.iris} left eye, ${this.slave.eye.right.iris} right eye`); } @@ -25,6 +37,9 @@ App.Art.GenAI.EyePromptPart = class EyePromptPart extends App.Art.GenAI.PromptPa } else { positive.push(`closed eyes`); } + if (this.slave.eyewear === "corrective glasses" || this.slave.eyewear === "blurring glasses" || this.slave.eyewear === "glasses"){ + positive.push(`glasses`); + } return positive.join(`, `); } @@ -34,4 +49,11 @@ App.Art.GenAI.EyePromptPart = class EyePromptPart extends App.Art.GenAI.PromptPa negative() { return undefined; } + + /** + * @override + */ + face() { + return this.positive(); + } }; diff --git a/src/art/genAI/prompts/eyebrowPromptPart.js b/src/art/genAI/prompts/eyebrowPromptPart.js index 2a01a29e36448f3a0ad3e28630784368a95c03dd..f1abbb2d1382ee635ddff17cecbd316a3a05d2c7 100644 --- a/src/art/genAI/prompts/eyebrowPromptPart.js +++ b/src/art/genAI/prompts/eyebrowPromptPart.js @@ -3,6 +3,9 @@ App.Art.GenAI.EyebrowPromptPart = class EyebrowPromptPart extends App.Art.GenAI. * @override */ positive() { + if (this.helper.xlBaseModel()) { + return; + } const slave = asSlave(this.slave); if (slave?.fuckdoll > 0) { return; // covered by fuckdoll mask @@ -22,4 +25,11 @@ App.Art.GenAI.EyebrowPromptPart = class EyebrowPromptPart extends App.Art.GenAI. } return; } + + /** + * @override + */ + face() { + return this.positive(); + } }; diff --git a/src/art/genAI/prompts/genderPromptPart.js b/src/art/genAI/prompts/genderPromptPart.js index 5b35e56020ce9e192212af286766c65b84a648e4..c351df8f7f8c5ad686074d70339d6349115cc8fe 100644 --- a/src/art/genAI/prompts/genderPromptPart.js +++ b/src/art/genAI/prompts/genderPromptPart.js @@ -1,32 +1,4 @@ App.Art.GenAI.GenderPromptPart = class GenderPromptPart extends App.Art.GenAI.PromptPart { - get isFeminine() { - if (V.aiGenderHint === 1) { // Hormone balance - const hormoneTransitionThreshold = 100; - if (this.slave.hormoneBalance >= hormoneTransitionThreshold) { - return true; // transwoman (or hormone-boosted natural woman) - } - return this.slave.genes === "XX" && (this.slave.hormoneBalance > -hormoneTransitionThreshold); // natural woman, and NOT transman - } else if (V.aiGenderHint === 2) { // Perceived gender - return perceivedGender(this.slave) > 1; - } else if (V.aiGenderHint === 3) { // Pronouns - return this.slave.pronoun === App.Data.Pronouns.Kind.female; - } else { - return false; - } - } - - get isMasculine() { - if (V.aiGenderHint === 1) { // Hormone balance - return !this.isFeminine; - } else if (V.aiGenderHint === 2) { // Perceived gender - return perceivedGender(this.slave) < -1; - } else if (V.aiGenderHint === 3) { // Pronouns - return this.slave.pronoun === App.Data.Pronouns.Kind.male; - } else { - return false; - } - } - /** * @override */ @@ -70,7 +42,7 @@ App.Art.GenAI.GenderPromptPart = class GenderPromptPart extends App.Art.GenAI.Pr if (perceivedGender(this.slave) < -1) { // Feminine hormone but Masculine appearing return undefined; } else { // Feminine hormone, Feminine appearing - return `${facialHair}boy, man`; + return `${facialHair}man, boy`; } } else if (this.isMasculine) { if (perceivedGender(this.slave) > 1) { // Masculine hormone but Feminine appearing diff --git a/src/art/genAI/prompts/hairPromptPart.js b/src/art/genAI/prompts/hairPromptPart.js index 40c86989d5b061ac299a01f1cd0770e8b5f4f669..28596cbf3023fcb263cf2135286a77db39c63dca 100644 --- a/src/art/genAI/prompts/hairPromptPart.js +++ b/src/art/genAI/prompts/hairPromptPart.js @@ -14,9 +14,17 @@ App.Art.GenAI.HairPromptPart = class HairPromptPart extends App.Art.GenAI.Prompt const heightVhLength = this.slave.hLength / this.slave.height; let hairLength = ''; if (heightVhLength > 0.9) { - hairLength = `(very long:1.2)`; + if (V.aiBaseModel === 2) { + hairLength = `absurdly long`; + } else { + hairLength = `(very long:1.2)`; + } } else if (heightVhLength > 0.7) { - hairLength = `(very long:1.1)`; + if (V.aiBaseModel === 2) { + hairLength = `extremely long`; + } else { + hairLength = `(very long:1.1)`; + } } else if (heightVhLength >= 0.4) { hairLength = `very long`; } else if (heightVhLength >= 0.2) { @@ -28,9 +36,11 @@ App.Art.GenAI.HairPromptPart = class HairPromptPart extends App.Art.GenAI.Prompt } if (stylePostfix) { return `${hairLength} ${this.slave.hColor} hair ${styleStr}`; - } else { - return `${this.slave.hStyle} hair, ${hairLength} ${this.slave.hColor} hair`; } + if (this.helper.xlBaseModel()) { + return `${hairLength} ${this.slave.hStyle} hair, ${this.slave.hColor} hair`; + } + return `${this.slave.hStyle} hair, ${hairLength} ${this.slave.hColor} hair`; } /** @@ -42,4 +52,11 @@ App.Art.GenAI.HairPromptPart = class HairPromptPart extends App.Art.GenAI.Prompt } return; } + + /** + * @override + */ + face() { + return this.positive(); + } }; diff --git a/src/art/genAI/prompts/hipsPromptPart.js b/src/art/genAI/prompts/hipsPromptPart.js index 3605b9a484f0b32a662135bdb9111ef20aee024f..13e8db309adffe8fe23542c8a7b39dd90c917643 100644 --- a/src/art/genAI/prompts/hipsPromptPart.js +++ b/src/art/genAI/prompts/hipsPromptPart.js @@ -3,7 +3,7 @@ App.Art.GenAI.HipsPromptPart = class HipsPromptPart extends App.Art.GenAI.Prompt * @override */ positive() { - if (this.slave.visualAge < 18 && V.aiAgeFilter) { + if (this.censored) { return undefined; } if (this.slave.hips <= -2) { diff --git a/src/art/genAI/prompts/musclesPromptPart.js b/src/art/genAI/prompts/musclesPromptPart.js index bf3c75682bffb652ddc1b7fb2cde1a8b43fd3f39..a1f380bc763a0269a276a8e5493c477556ab944e 100644 --- a/src/art/genAI/prompts/musclesPromptPart.js +++ b/src/art/genAI/prompts/musclesPromptPart.js @@ -3,6 +3,15 @@ App.Art.GenAI.MusclesPromptPart = class MusclesPromptPart extends App.Art.GenAI. * @override */ positive() { + if (this.helper.xlBaseModel()) { + if (this.slave.muscles > 95) { + return 'huge muscles'; + } else if (this.slave.muscles > 50) { + return 'muscles'; + } else if (this.slave.muscles > 30) { + return 'toned'; + } + } if (this.slave.muscles > 95) { return `(very muscular:1.3), bodybuilder`; } else if (this.slave.muscles > 50) { diff --git a/src/art/genAI/prompts/nationalityPromptPart.js b/src/art/genAI/prompts/nationalityPromptPart.js index 068b74631cedb516846f97efb9ae8f74a25a6a36..10d5d0b2c77249e1b781f244843ad2284b235f00 100644 --- a/src/art/genAI/prompts/nationalityPromptPart.js +++ b/src/art/genAI/prompts/nationalityPromptPart.js @@ -51,4 +51,11 @@ App.Art.GenAI.NationalityPromptPart = class NationalityPromptPart extends App.Ar negative() { return undefined; } + + /** + * @override + */ + face() { + return this.positive(); + } }; diff --git a/src/art/genAI/prompts/piercingsPromptPart.js b/src/art/genAI/prompts/piercingsPromptPart.js index 9133a6212817cd0ccaa3d6583eb495bdf87277f3..2662d8bd2213fcd603afabfa203b2cb14616f1bf 100644 --- a/src/art/genAI/prompts/piercingsPromptPart.js +++ b/src/art/genAI/prompts/piercingsPromptPart.js @@ -5,10 +5,8 @@ App.Art.GenAI.PiercingsPromptPart = class PiercingsPromptPart extends App.Art.Ge positive() { const isFuckdoll = asSlave(this.slave)?.fuckdoll !== 0; - const helpers = App.Art.GenAI.PromptHelpers; - let piercingParts = []; - if (this.slave.piercing.areola.weight > 0 && !this.censored && helpers.exposesNipples(this.slave.clothes)) { + if (this.slave.piercing.areola.weight > 0 && !this.censored && this.helper.exposesNipples(this.slave.clothes)) { if (!isFuckdoll || this.slave.race === "catgirl") { // TODO: needs exposure check let desc = this.slave.piercing.areola.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.areola.desc) + ` `) : ``; piercingParts.push(`${desc}areola piercing`); @@ -30,13 +28,13 @@ App.Art.GenAI.PiercingsPromptPart = class PiercingsPromptPart extends App.Art.Ge let desc = this.slave.piercing.lips.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.lips.desc) + ` `) : ``; piercingParts.push(`${desc}lip piercing`); } - if (this.slave.piercing.navel.weight > 0 && !this.censored && helpers.exposesMidriff(this.slave.clothes)) { + if (this.slave.piercing.navel.weight > 0 && !this.censored && this.helper.exposesMidriff(this.slave.clothes)) { if (!isFuckdoll || this.slave.race === "catgirl") { // covered by fuckdoll suit or fur let desc = this.slave.piercing.navel.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.navel.desc) + ` `) : ``; piercingParts.push(`${desc}navel piercing`); } } - if (this.slave.piercing.nipple.weight > 0 && !this.censored && helpers.exposesNipples(this.slave.clothes)) { + if (this.slave.piercing.nipple.weight > 0 && !this.censored && this.helper.exposesNipples(this.slave.clothes)) { if (!isFuckdoll) { // TODO: needs exposure check let desc = this.slave.piercing.nipple.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.nipple.desc) + ` `) : ``; piercingParts.push(`${desc}nipple piercing`); @@ -52,7 +50,7 @@ App.Art.GenAI.PiercingsPromptPart = class PiercingsPromptPart extends App.Art.Ge let desc = this.slave.piercing.tongue.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.tongue.desc) + ` `) : ``; piercingParts.push(`${desc}tongue piercing`); } - if (this.slave.piercing.vagina.weight > 0 && this.slave.dick <= 0 && !this.censored && helpers.exposesCrotch(this.slave.clothes)) { + if (this.slave.piercing.vagina.weight > 0 && this.slave.dick <= 0 && !this.censored && this.helper.exposesCrotch(this.slave.clothes)) { let desc = this.slave.piercing.vagina.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.vagina.desc) + ` `) : ``; piercingParts.push(`${desc}labia piercing`); } diff --git a/src/art/genAI/prompts/pubicHairPromptPart.js b/src/art/genAI/prompts/pubicHairPromptPart.js index 06edc31fcdf8a81f0d80975620207397a4c8309a..3c4ee92323f963fe72d67309d42582aa646fe350 100644 --- a/src/art/genAI/prompts/pubicHairPromptPart.js +++ b/src/art/genAI/prompts/pubicHairPromptPart.js @@ -3,14 +3,15 @@ App.Art.GenAI.PubicHairPromptPart = class PubicHairPromptPart extends App.Art.Ge * @override */ positive() { - if (this.censored) { + const exposesCrotch = this.helper.exposesCrotch(this.slave.clothes); + if (!exposesCrotch || this.censored) { return undefined; } if (this.slave.pubicHStyle === "waxed" || this.slave.pubicHStyle === "bald" || this.slave.pubicHStyle === "hairless" || this.slave.physicalAge < Math.min(this.slave.pubertyAgeXX, this.slave.pubertyAgeXY)) { return; } - if (App.Data.clothes.get(this.slave.clothes).exposure < 3 || (asSlave(this.slave)?.fuckdoll > 0)) { + if ((asSlave(this.slave)?.fuckdoll > 0)) { return; // pubic region should be covered by clothes } const style = (this.slave.pubicHStyle === "bushy in the front and neat in the rear" ? "bushy" : this.slave.pubicHStyle); // less complicated prompt works better for the long style diff --git a/src/art/genAI/prompts/racePromptPart.js b/src/art/genAI/prompts/racePromptPart.js index 09858a6a34220cf016acb5f7f7b5614694321430..b1f4ff01b03de58373df29726324ec913effac78 100644 --- a/src/art/genAI/prompts/racePromptPart.js +++ b/src/art/genAI/prompts/racePromptPart.js @@ -22,4 +22,11 @@ App.Art.GenAI.RacePromptPart = class RacePromptPart extends App.Art.GenAI.Prompt } return; } + + /** + * @override + */ + face() { + return undefined; + } }; diff --git a/src/art/genAI/prompts/skinPromptPart.js b/src/art/genAI/prompts/skinPromptPart.js index 040260ce7db67a1138ac4321ecd0fa96d095d4be..d90e96e376099cde02a2aac56d65ebc9a3b602ab 100644 --- a/src/art/genAI/prompts/skinPromptPart.js +++ b/src/art/genAI/prompts/skinPromptPart.js @@ -15,35 +15,49 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt case "pure white": case "ivory": case "white": + case "extremely fair": return "white skin"; case "extremely pale": case "very pale": case "pale": - return "pale skin"; - case "extremely fair": + case "light beige": case "very fair": + return "pale skin"; case "fair": case "light": - case "light olive": + case "beige": return "fair skin"; + case "light olive": case "sun tanned": case "spray tanned": case "tan": + return "tan skin"; case "olive": case "bronze": - case "dark olive": - case "dark": - case "light beige": - case "beige": case "dark beige": + if (this.helper.xlBaseModel()) { + return "olive skin"; + } + return "tan skin"; + case "dark olive": case "light brown": case "brown": + if (this.helper.xlBaseModel()) { + return "brown skin"; + } return "tan skin"; + case "dark": case "dark brown": case "black": case "ebony": + if (App.Art.GenAI.sdClient.hasLora("melanin3")) { + return `<lora:melanin3:0.8>, melanin, dark skin`; + } return "dark skin"; case "pure black": + if (App.Art.GenAI.sdClient.hasLora("melanin3")) { + return `<lora:melanin3:1.0>, melanin, black skin`; + } return "black skin"; default: return `${this.slave.skin} skin`; @@ -54,6 +68,12 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt * @override */ negative() { + if (this.helper.xlBaseModel()) { + if (this.positive() === "tan skin") { + return "tan lines"; + } + return; + } switch (this.slave.skin) { case "pure white": case "ivory": @@ -87,5 +107,13 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt return "light skin"; } } + + + /** + * @override + */ + face() { + return this.positive(); + } }; diff --git a/src/art/genAI/prompts/stylePromptPart.js b/src/art/genAI/prompts/stylePromptPart.js index e38ef0eee76735925d4e954f3e75ec41e19631f7..9cb0adfcd19f6a77fa6714d78477b230fb8fe583 100644 --- a/src/art/genAI/prompts/stylePromptPart.js +++ b/src/art/genAI/prompts/stylePromptPart.js @@ -3,25 +3,29 @@ App.Art.GenAI.StylePromptPart = class StylePromptPart extends App.Art.GenAI.Prom * @override */ positive() { + let positive = ""; + // Check if filter is on and needed, then pick model-appropriate framing tags. + if (this.censored) { + if (V.aiBaseModel === 2) { + positive += "front view, half-length portrait, "; + } else { + positive += "straight-on, cowboy shot, "; + } + positive += "face focus, "; + } else { + if (V.aiBaseModel === 2) { + positive += "full-length portrait, "; + } else { + positive += "full body, portrait, "; + } + } switch (V.aiStyle) { - case 0: // custom - if (this.censored) { - return "front-up portrait, (tight medium shot:1.3), " + V.aiCustomStylePos; // custom may break the control - } else { - return V.aiCustomStylePos; - } - case 1: // photorealistic - if (this.censored) { - return "<lora:LowRA:0.5> front-up portrait, (tight medium shot:1.2), (focus on face:1.1), photorealistic, dark theme, black background"; - } else { - return "<lora:LowRA:0.5> full body portrait, photorealistic, dark theme, black background"; - } - case 2: // anime/hentai - if (this.censored) { - return "front-up portrait, (tight medium shot:1.1), (focus on face:1.1), 2d, anime, hentai, dark theme, black background"; - } else { - return "full body portrait, 2d, anime, hentai, dark theme, black background"; - } + case 0: // Custom Style + return positive + V.aiCustomStylePos; + case 1: // Photorealistic + return positive + "photorealistic, dark theme, black background"; + case 2: // Anime/Hentai + return positive + "2d, anime, hentai"; } } @@ -29,25 +33,29 @@ App.Art.GenAI.StylePromptPart = class StylePromptPart extends App.Art.GenAI.Prom * @override */ negative() { + let negative = ""; + if (this.censored) { + negative += "NSFW, nude, "; + if (V.aiBaseModel === 2) { + negative += "full-length portrait, "; + } else { + negative += "full body, "; + } + } else { + negative += "close-up, "; + if (V.aiBaseModel === 2) { + negative += "half-length portrait, "; + } else { + negative += "cowboy shot, "; + } + } switch (V.aiStyle) { - case 0: // custom - if (this.censored) { - return "NSFW, full shot, medium full shot, full body portrait, waist, hips, bottom, navel, legs, " + V.aiCustomStyleNeg; - } else { - return V.aiCustomStyleNeg; - } - case 1: // photorealistic - if (this.censored) { - return "NSFW, greyscale, monochrome, cg, render, unreal engine, full shot, medium full shot, full body portrait, waist, hips, navel, bottom, legs, (head out of frame:1.1), (eye out of frame:1.2)"; - } else { - return "greyscale, monochrome, cg, render, unreal engine, closeup, medium shot"; - } - case 2: // anime/hentai - if (this.censored) { - return "NSFW, greyscale, monochrome, photography, 3d render, text, speech bubble, (head out of frame), full shot, medium full shot, full body portrait, waist, hips, navel, bottom, legs, head out of frame, eye out of frame"; - } else { - return "greyscale, monochrome, photography, 3d render, text, speech bubble, closeup, medium shot"; - } + case 0: // Custom Style + return negative + V.aiCustomStyleNeg; + case 1: // Photorealistic + return negative + "greyscale, monochrome, cg, render"; + case 2: // Anime/Hentai + return negative + "greyscale, monochrome, photography, 3d render, speech bubble"; } } }; diff --git a/src/art/genAI/prompts/tattoosPromptPart.js b/src/art/genAI/prompts/tattoosPromptPart.js index 6b5cb1ada8e5ccf795ac70246f74dd1b60870139..391ca4701ff977a481fc6eb9fa89e225f4526f12 100644 --- a/src/art/genAI/prompts/tattoosPromptPart.js +++ b/src/art/genAI/prompts/tattoosPromptPart.js @@ -7,7 +7,6 @@ App.Art.GenAI.TattoosPromptPart = class TattoosPromptPart extends App.Art.GenAI. return undefined; // fuckdoll suit covers all possible tattoo locations, catgirl covered with fur } - const helpers = App.Art.GenAI.PromptHelpers; const {clothes} = this.slave; let tattooParts = []; @@ -18,10 +17,10 @@ App.Art.GenAI.TattoosPromptPart = class TattoosPromptPart extends App.Art.GenAI. if (this.slave.legsTat && !this.censored) { tattooParts.push(`${this.slave.legsTat} leg tattoo`); } - if (this.slave.bellyTat && helpers.exposesMidriff(clothes)) { + if (this.slave.bellyTat && this.helper.exposesMidriff(clothes)) { tattooParts.push(`${this.slave.bellyTat} belly tattoo`); } - if (this.slave.boobsTat && helpers.exposesNipples(clothes)) { // TODO: needs exposure check + if (this.slave.boobsTat && this.helper.exposesBreasts(clothes)) { tattooParts.push(`${this.slave.boobsTat} ${this.censored ? "chest" : "breast"} tattoo`); } diff --git a/src/art/genAI/prompts/weightPromptPart.js b/src/art/genAI/prompts/weightPromptPart.js index a771a27b263f6e5065bb0cf32105e805d6aebe6e..0b812280d8c17bc2c272fcb8687bb2ff2132e511 100644 --- a/src/art/genAI/prompts/weightPromptPart.js +++ b/src/art/genAI/prompts/weightPromptPart.js @@ -3,6 +3,25 @@ App.Art.GenAI.WeightPromptPart = class WeightPromptPart extends App.Art.GenAI.Pr * @override */ positive() { + if (this.helper.xlBaseModel()) { + if (this.slave.weight < -95) { + return 'skinny, emaciated'; + } else if (this.slave.weight < -30) { + return 'skinny'; + } else if (this.slave.weight < -10) { + return `slim`; + } else if (this.slave.weight < 10) { + return null; + } else if (this.slave.weight < 30) { + return `curvy`; + } else if (this.slave.weight < 60) { + return 'fat'; + } else if (this.slave.weight < 95) { + return 'obese'; + } else { + return 'fat, obese'; + } + } if (this.slave.weight < -95) { return `emaciated, very thin, skinny`; } else if (this.slave.weight < -30) { @@ -24,6 +43,11 @@ App.Art.GenAI.WeightPromptPart = class WeightPromptPart extends App.Art.GenAI.Pr * @override */ negative() { + if (this.helper.xlBaseModel()) { + if (this.slave.weight < -30) { + return 'fat'; + } + } if (this.slave.weight < -30) { return `plump, chubby`; } else if (this.slave.weight < 50) { @@ -32,4 +56,11 @@ App.Art.GenAI.WeightPromptPart = class WeightPromptPart extends App.Art.GenAI.Pr return `thin, skinny`; } } + + /** + * @override + */ + face() { + return this.positive(); + } }; diff --git a/src/art/genAI/reactiveImageDB.js b/src/art/genAI/reactiveImageDB.js index 9036e3609f34d3d376db5a61511c5a2912b5075d..78763851bb003a98f6d30e297857608fbc572035 100644 --- a/src/art/genAI/reactiveImageDB.js +++ b/src/art/genAI/reactiveImageDB.js @@ -52,7 +52,7 @@ const SIGNIFICANTLY_DIFFERENT_THRESHOLD = 50; -App.Art.GenAI.reactiveImageDB = (function () { +App.Art.GenAI.reactiveImageDB = (function() { const sleep = (/** @type {number} */ n = 100) => new Promise(r => setTimeout(r, n)); /** @type {import("../../../devTools/types/idb/entry").IDBPDatabase} */ @@ -92,10 +92,10 @@ App.Art.GenAI.reactiveImageDB = (function () { upgrade: (database, oldVersion, newVersion, tx, ev) => { // v1 DB spec if (oldVersion < 1) { - const eventStore = database.createObjectStore(EVENT_STORE.path, { autoIncrement: true, keyPath: 'id' }); - eventStore.createIndex('id', 'id', { unique: true }); - eventStore.createIndex("bySlaveIdsActions", ['slaveIds', 'action'], { multiEntry: false }); // to check if a given actor is in _any_ scene. Does not matter who the other is. - eventStore.createIndex('bySlaveId', 'slaveIds', { multiEntry: true }); + const eventStore = database.createObjectStore(EVENT_STORE.path, {autoIncrement: true, keyPath: 'id'}); + eventStore.createIndex('id', 'id', {unique: true}); + eventStore.createIndex("bySlaveIdsActions", ['slaveIds', 'action'], {multiEntry: false}); // to check if a given actor is in _any_ scene. Does not matter who the other is. + eventStore.createIndex('bySlaveId', 'slaveIds', {multiEntry: true}); eventStore.createIndex('byImageId', 'imageId'); // for easy deletion } }, @@ -314,7 +314,7 @@ App.Art.GenAI.reactiveImageDB = (function () { prevRecord.matches.push(currentRecord.entry); } return prevRecord; - }, { matches: [], averageDifference: Number.MAX_SAFE_INTEGER }); + }, {matches: [], averageDifference: Number.MAX_SAFE_INTEGER}); // to regenerate, we need an exact match. if (options.forceRegenerate && fuzzyResults.averageDifference > 0) { return { @@ -369,7 +369,7 @@ App.Art.GenAI.reactiveImageDB = (function () { /** @type {App.Art.GenAI.EventStore.Entry[]} */ const eventEntries = await db.getAllFromIndex(EVENT_STORE.path, EVENT_STORE.indicies.bySlaveIdsActions, IDBKeyRange.only([event.slaveIds, event.action])); - const { matches, averageDifference } = findClosestEvents(slaves, eventEntries, effectiveOptions); + const {matches, averageDifference} = findClosestEvents(slaves, eventEntries, effectiveOptions); const shouldUseCache = (averageDifference <= SIGNIFICANTLY_DIFFERENT_THRESHOLD) && !effectiveOptions.forceRegenerate; const isExactMatch = averageDifference === 0; const chosenEvent = matches[Math.floor(Math.random() * matches.length)]; @@ -517,7 +517,7 @@ App.Art.GenAI.reactiveImageDB = (function () { * Regenerates images for all slaves */ async function regenAllImages() { - V.slaves.forEach((s) => getImage([s], { forceRegenerate: true })); + getSlaves().forEach((s) => getImage([s], {forceRegenerate: true})); } @@ -547,7 +547,7 @@ App.Art.GenAI.reactiveImageDB = (function () { /** * Flow control */ - /** Initalizes database */ + /** Initializes database */ init, /** Resolves promise when DB has been initalized */ waitForInit, diff --git a/src/art/genAI/stableDiffusion.js b/src/art/genAI/stableDiffusion.js index af0fb46dc743bd034be5f24bf7165560bfb752c4..042328da1cc5c27afe02c51f2f66b0b9ec09fcae 100644 --- a/src/art/genAI/stableDiffusion.js +++ b/src/art/genAI/stableDiffusion.js @@ -259,7 +259,7 @@ App.Art.GenAI.StableDiffusionClientQueue = class { body: top.body, }; if (V.aiUserInterface === 0) { - fetchWithTimeout(`${V.aiApiUrl}/sdapi/v1/txt2img`, (V.aiTimeoutPerStep * 1000 + 200) * V.aiSamplingSteps, options) + fetchWithTimeout(`${V.aiApiUrl}/sdapi/v1/txt2img`, (V.aiTimeoutPerStep * 1000 + 200) * (V.aiFaceDetailer ? V.aiSamplingSteps * 2 : V.aiSamplingSteps), options) .then((value) => { return value.json(); }).then(obj => { @@ -455,7 +455,8 @@ App.Art.GenAI.StableDiffusionClient = class { true, // ad_enable true, // skip_img2img { - "ad_model": "face_yolov8s.pt" + "ad_model": "face_yolov8s.pt", + "ad_prompt": prompt.face() } ] }; @@ -824,6 +825,9 @@ App.Art.GenAI.StableDiffusionClient = class { if (V.aiDisabledLoRAs.includes(loraName)) { return false; // this LoRA is disabled } + if (V.aiBaseModel === (1 || 2)) { + return false; // TODO: remove when XL loras have been implemented - @Engineerix + } return (this.#loraCachedList.includes(loraName)); } @@ -972,8 +976,8 @@ App.Art.GenAI.StaticCaching = class { const imageData = getImageData(base64Image); const imagePreexisting = await compareExistingImages(slave, imageData); if (!isEventImage) { - let vSlave = globalThis.getSlave(slave.ID); - // if `slave` is owned but the variable has become detached from V.slaves, save the image changes to V.slaves instead + let vSlave = getSlave(slave.ID); + // if `slave` is owned but the variable has become detached from the main slave pool, save the image changes to the main slave pool instead // but don't do it for temporary images because they might be intentionally using a copy of a slave for temporary changes if (vSlave && slave !== vSlave) { slave = vSlave; @@ -1110,8 +1114,8 @@ App.Art.GenAI.ReactiveCaching = class { } const imageData = getImageData(base64Image); const imagePreexisting = await compareExistingImages(slave, imageData); - const vSlave = globalThis.getSlave(slave.ID); - // if `slave` is owned but the variable has become detached from V.slaves, save the image changes to V.slaves instead + const vSlave = getSlave(slave.ID); + // if `slave` is owned but the variable has become detached from the main slave pool, save the image changes to the main slave pool instead if (vSlave && slave !== vSlave) { slave = vSlave; } @@ -1140,7 +1144,7 @@ App.Art.GenAI.reactiveCache = new App.Art.GenAI.ReactiveCaching(); /** * Search slave's existing images for a match with the new image. - * @param {FC.SlaveState} slave - The slave we're updating + * @param {FC.HumanState} slave - The slave we're updating * @param {string} newImageData - new image * @returns {Promise<number>} index of the image in aiImageIds or -1 */ diff --git a/src/art/genAI/staticImageDB.js b/src/art/genAI/staticImageDB.js index 98960dbfff70e01b692eb0e9607904cb3a28ed09..9a72bf4669432dd82908d243d79ba12153d2d01c 100644 --- a/src/art/genAI/staticImageDB.js +++ b/src/art/genAI/staticImageDB.js @@ -155,13 +155,39 @@ App.Art.GenAI.staticImageDB = (function() { return `${count} images ${sizeEstimate ? ` (${sizeEstimate})` : ''}`; } + /** + * Returns alls the indexes in the indexedDB. + * @returns {Promise<unknown>} + */ + async function getIndexesList() { + await waitForInit(); + return new Promise((resolve, reject) => { + const transaction = db.transaction(['images'], 'readonly'); + const objectStore = transaction.objectStore('images'); + const request = objectStore.getAllKeys(); + + request.onsuccess = function() { + if (request.result === undefined) { + reject(new Error(`Error while retrieving index list.`)); + } else { + resolve(request.result); + } + }; + + request.onerror = function() { + reject(new Error(`Error fetching index list`)); + }; + }); + } + return { createDB, putImage, getImage, removeImage, clear, - sizeInfo + sizeInfo, + getIndexesList }; })(); diff --git a/src/art/genAI/uiOptions.js b/src/art/genAI/uiOptions.js index 9e19a615894a61d175c968f10e093c5b41a66bb7..6dd0874a5564890fb7a0772a9cea3bac6dcd0a30 100644 --- a/src/art/genAI/uiOptions.js +++ b/src/art/genAI/uiOptions.js @@ -96,6 +96,11 @@ App.Art.GenAI.UI.Options.loraList = () => { urls: ["https://civitai.com/api/download/models/6433?type=Model&format=SafeTensor&size=full&fp=fp16"], usage: "Fixes some eyes Problems", }, + { + name: "melanin3", + urls: ["https://civitai.com/models/133279?modelVersionId=263127"], + usage: "Apply a darker skintone for dark skins", + }, ]; /** @@ -272,7 +277,8 @@ App.Art.GenAI.UI.Options.promptingOptions = (options) => { options.addOption("AI Base Model", "aiBaseModel").addValueList([ ["SD 1.X", 0], - ["SDXL/Pony", 1], + ["SDXL", 1], + ["Pony", 2], ]); options.addOption("AI style prompting", "aiStyle") @@ -310,7 +316,7 @@ App.Art.GenAI.UI.Options.promptingOptions = (options) => { }); } - if (V.aiPrebuiltWorkflow === 0 || V.aiUserInterface === 0) { + if (V.aiUserInterface === 0 || V.aiPrebuiltWorkflow !== 2) { options.addOption("LoRA models are", "aiLoraPack") .addValue("Enabled", true).on().addValue("Disabled", false).off().addComment(loraSpan); } @@ -397,13 +403,13 @@ App.Art.GenAI.UI.Options.artOptions = (options) => { .addButton("Regenerate images for all slaves", () => { // queue all slaves for regeneration in the background if (V.aiCachingStrategy === 'static') { - V.slaves.forEach(s => App.Art.GenAI.staticCache.updateSlave(s) + getSlaves().forEach(s => App.Art.GenAI.staticCache.updateSlave(s) .catch(error => { console.log(error.message || error); })); } else { // reactive - V.slaves.forEach(s => App.Art.GenAI.reactiveCache.updateSlave(s) + getSlaves().forEach(s => App.Art.GenAI.reactiveCache.updateSlave(s) .catch(error => { console.log(error.message || error); })); diff --git a/src/art/genAI/uiSlaveInteract.js b/src/art/genAI/uiSlaveInteract.js index 6d90c5f3c0106fb4eb77b2ddd8735c559188e8aa..711730616f2c964eace05d937a6d721208697ddb 100644 --- a/src/art/genAI/uiSlaveInteract.js +++ b/src/art/genAI/uiSlaveInteract.js @@ -202,6 +202,8 @@ App.Art.GenAI.UI.SlaveInteract.custom = (slave, refresh) => { el.appendChild(document.createElement('kbd')).textContent = prompt.positive(); el.appendChild(document.createElement('h5')).textContent = `Negative prompt`; el.appendChild(document.createElement('kbd')).textContent = prompt.negative(); + el.appendChild(document.createElement('h5')).textContent = `Face prompt`; + el.appendChild(document.createElement('kbd')).textContent = prompt.face(); return el; } @@ -347,7 +349,6 @@ App.Art.GenAI.UI.SlaveInteract.custom = (slave, refresh) => { function refresh() { App.UI.reload(); } - if (slave.custom.aiDisplayImageIdx === -1) { return; } await App.Art.GenAI.Archiving.importCharacter(slave, refresh); }) ]), diff --git a/src/cheats/cheatEditActor.js b/src/cheats/cheatEditActor.js index 07c856e6883d94c2a590e87bad5d7c35b60446bb..02d9a1b4a77f6c072e9ba05dc58cad709e6f61dc 100644 --- a/src/cheats/cheatEditActor.js +++ b/src/cheats/cheatEditActor.js @@ -24,7 +24,7 @@ App.UI.Cheat.cheatEditActor = function(actor) { const realInfant = V.cribsIndices[actor.ID] !== undefined ? infant : undefined; /** null if the actor isn't a ChildState object, otherwise a ChildState object */ - const child = undefined; // TODO: replace undefined once ChildState is actually implemented + const child = null; // TODO: replace null once ChildState is actually implemented /** a ChildState object if baseActor has an ID that exists in ???, otherwise undefined */ const realChild = undefined; // TODO: replace undefined once ChildState is actually implemented @@ -39,10 +39,13 @@ App.UI.Cheat.cheatEditActor = function(actor) { const realSlave = V.slaveIndices[actor.ID] !== undefined ? slave : undefined; /** null if the actor isn't a [this is a placeholder] object, otherwise a [this is a placeholder] object */ - const citizen = undefined; // placeholder for when/if persistant citizens are added + const citizen = null; // placeholder for when/if persistant citizens are added /** a [this is a placeholder] object if baseActor has an ID that exists in ???, otherwise undefined */ const realCitizen = undefined; // placeholder for when/if persistant citizens are added + console.log(`type; player: ${player !== null}, infant: ${infant !== null}, child: ${child !== null}, tankSlave: ${tankSlave !== null}, slave: ${slave !== null}, citizen: ${citizen !== null}`); + console.log(`real; player: ${realPlayer !== undefined}, infant: ${realInfant !== undefined}, child: ${realChild !== undefined}, tankSlave: ${realTankSlave !== undefined}, slave: ${realSlave !== undefined}, citizen: ${realCitizen !== undefined}`); + App.UI.DOM.appendNewElement("h1", el, `Cheat edit ${actor.slaveName}`); if (player) { @@ -2154,7 +2157,7 @@ App.UI.Cheat.cheatEditActor = function(actor) { V.PC = player; } else if (realSlave) { normalizeRelationship(); - V.slaves[V.slaveIndices[actor.ID]] = slave; + overwriteSlave(actor.ID, slave); } else if (realTankSlave) { normalizeRelationship(); V.incubator.tanks[V.incubator.tankIndices[actor.ID]] = tankSlave; diff --git a/src/cheats/cheatEditSlave.js b/src/cheats/cheatEditSlave.js index c84be7dc39b182cbbdb614a52d6df310a1c2e299..da4ef0ac881ffb16b00765d0223cf3f3f718128f 100644 --- a/src/cheats/cheatEditSlave.js +++ b/src/cheats/cheatEditSlave.js @@ -60,9 +60,9 @@ App.UI.SlaveInteract.cheatEditSlave = function(slave) { App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link( "Apply cheat edits", () => { - App.Verify.slaveState("V.tempActor", asSlave(V.tempActor), "V.slaves"); + App.Verify.slaveState("V.tempActor", asSlave(V.tempActor), "main slave pool"); normalizeRelationship(); - V.slaves[V.slaveIndices[slave.ID]] = asSlave(V.tempActor); + overwriteSlave(slave.ID, asSlave(V.tempActor)); ibc.recalculate_coeff_id(slave.ID); delete V.tempActor; }, diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js index b8a67104a709b1dc9e7bfd263b6187a890272144..b176d51e8221c5428c3df51ad9ae6d84c0bde29d 100644 --- a/src/data/backwardsCompatibility/backwardsCompatibility.js +++ b/src/data/backwardsCompatibility/backwardsCompatibility.js @@ -1445,12 +1445,12 @@ App.Update.globalVariables = function(node) { V.rival = V.rival || {}; V.rival.FS = V.rival.FS || {}; - if (V.slaves.find(s => s.origin.includes("You were acquainted with $him before you were an arcology owner") && s.newGamePlus === 0)) { + if (getSlaves().find(s => s.origin.includes("You were acquainted with $him before you were an arcology owner") && s.newGamePlus === 0)) { V.rival.hostageState = 2; V.hostage = 0; delete V.hostageWife; } - if (V.hostageAnnounced && !V.slaves.find(s => s.origin.includes("You were acquainted with $him before you were an arcology owner") && s.newGamePlus === 0)) { + if (V.hostageAnnounced && !getSlaves().find(s => s.origin.includes("You were acquainted with $him before you were an arcology owner") && s.newGamePlus === 0)) { V.rival.hostageState = 1; } V.rival.hostageState = V.rival.hostageState || 0; @@ -1484,7 +1484,7 @@ App.Update.globalVariables = function(node) { V.rival.state = 5; } if (V.releaseID < 1180) { - const rivalEnslaved = V.slaves.filter(s => s.newGamePlus === 0 && s.origin.includes("$He was once an arcology owner like yourself.")).length > 0; + const rivalEnslaved = getSlaves().filter(s => s.newGamePlus === 0 && s.origin.includes("$He was once an arcology owner like yourself.")).length > 0; if (V.rival.state === 1 && rivalEnslaved) { V.rival.state = 5; } else if (V.rival.state === 1 && !rivalEnslaved && V.arcologies.find(a => a.direction !== 0 && a.rival !== 1)) { @@ -2929,6 +2929,7 @@ App.Update.globalVariables = function(node) { * @param {Node} node */ App.Update.slaveIndices = function(node) { + if (!Array.isArray(V.slaves)) { return; } // future proofing; if we move to an object and this was somehow called it could be bad for (let bci = 0; bci < V.slaves.length; bci++) { if (typeof V.slaves[bci] !== "object") { V.slaves.deleteAt(bci); @@ -2967,7 +2968,7 @@ App.Update.slaveRecords = function(node) { App.Update.SlaveDatatypeCleanup(slave); }; - V.slaves.forEach((slave) => updateRecord(slave)); + getSlaves().forEach((slave) => updateRecord(slave)); for (const slave of detachedSlaves) { if (typeof slave !== "undefined" && slave !== 0) { updateRecord(slave); @@ -3025,7 +3026,7 @@ App.Update.slaveRecords = function(node) { } // fix anything that has to do with fetuses - V.slaves.concat([V.PC]).forEach(human => { + getSlaves().concat([V.PC]).forEach(human => { human.womb.forEach(fetus => { // variables releated to App.Events.PregnancyNotice fetus.noticeData = fetus.noticeData || {}; @@ -3043,7 +3044,7 @@ App.Update.slaveRecords = function(node) { }); // update clitoridal drugs - V.slaves.concat([V.PC]).forEach(s => { + getSlaves().concat([V.PC]).forEach(s => { if (s.drugs.includes("penis") && s.dick === 0 && s.vagina >= 0) { s.drugs = s.drugs.replace("penis", "clitoris"); } @@ -3091,7 +3092,6 @@ App.Update.logIssue = (primaryMessage, secondaryMessage=undefined, node=undefine * @param {Node} [node=undefined] * @returns {FC.HumanState} this should be assigned to the original variable, with the exception of hero slave templates * @example V.PC = App.Update.human(V.PC, "PC"); - * @example V.slaves[V.slaveIndices[slave.ID]] = App.Update.human(V.slaves[V.slaveIndices[slave.ID]], "normal"); */ App.Update.human = (actor, slaveType, node=undefined) => { let slaveLoc = (actor.ID === -1) ? "V.PC" : "Slave"; @@ -3111,7 +3111,7 @@ App.Update.human = (actor, slaveType, node=undefined) => { slaveLoc = "V.incubator.tanks"; } - console.log(`Starting property migration on HumanState with ID: ${actor.ID}`); + // console.log(`Starting property migration on HumanState with ID: ${actor.ID}`); // ----------------------------------- delete any unneeded properties here ----------------------------------- @@ -3158,7 +3158,7 @@ App.Update.human = (actor, slaveType, node=undefined) => { // ----------------------------------- automated beyond this point ----------------------------------- if (slaveType !== "hero") { - console.log(`Adding any missing properties to HumanState with ID: ${actor.ID}`); + // console.log(`Adding any missing properties to HumanState with ID: ${actor.ID}`); const base = (actor.ID === -1) ? new App.Entity.PlayerState() : new App.Entity.SlaveState(); _.merge(base, actor); // (deep) write values that are in actor to base overwritting as needed actor = base; // set actor to base, now actor has any keys that it was missing from base @@ -3166,7 +3166,7 @@ App.Update.human = (actor, slaveType, node=undefined) => { const baseKeys = Object.keys((actor.ID === -1) ? new App.Entity.PlayerState() : new App.Entity.SlaveState()); - console.log(`Checking HumanState with ID '${actor.ID}' for unexpected keys`); + // console.log(`Checking HumanState with ID '${actor.ID}' for unexpected keys`); Object.keys(actor).forEach((key) => { if (!baseKeys.includes(key)) { if (key === "pornFameBonus") { return; } // TODO:@franklygeorge `pornFameBonus` is supposed to be proxied so that it doesn't end up on `SlaveState`, but it is. So figure out why and fix it @@ -3223,7 +3223,7 @@ App.Update.humanRecords = (node) => { heroSlaves.forEach((slave) => App.Update.human(slave, "hero", node)); // normal slaves - V.slaves.forEach((slave) => V.slaves[V.slaveIndices[slave.ID]] = App.Update.human(slave, "normal", node)); + getSlaves().forEach((slave) => overwriteSlave(slave.ID, App.Update.human(slave, "normal", node))); // detached slaves V.hostage = (V.hostage) ? App.Update.human(V.hostage, "detached", node) : V.hostage; @@ -3277,8 +3277,8 @@ App.Update.genePoolRecords = function(node) { deduplication(slave); let dontDeleteMe = 0; - if (typeof V.slaveIndices[slave.ID] !== "undefined") { - /* are we still in the V.slaves array? */ + if (typeof getSlave(slave.ID) !== "undefined") { + /* are we still in the main slave pool? */ dontDeleteMe = 1; } if (V.traitor !== 0) { @@ -3299,8 +3299,9 @@ App.Update.genePoolRecords = function(node) { } if (dontDeleteMe === 0) { /* avoid going through this loop if possible */ - for (let bci2 = 0; bci2 < V.slaves.length; bci2++) { - if (isImpregnatedBy(V.slaves[bci2], slave, true)) { + const slaves = getSlaves(); + for (let bci2 = 0; bci2 < slaves.length; bci2++) { + if (isImpregnatedBy(slaves[bci2], slave, true)) { /* have we impregnated a slave on the slaves array? */ dontDeleteMe = 1; break; @@ -3393,7 +3394,7 @@ App.Update.genePoolRecords = function(node) { */ App.Update.RAassistantData = function(node) { const ruleIDs = V.defaultRules.map(rule => rule.ID); - const slaveIDs = V.slaves.map(slave => slave.ID); + const slaveIDs = getSlaves().map(slave => slave.ID); V.defaultRules = V.defaultRules.map(rule => App.Update.RARuleDatatypeCleanup(rule)); for (const ruleID of Object.keys(V.rulesToApplyOnce)) { @@ -3450,13 +3451,13 @@ App.Update.arcology = function(node) { * @deprecated Future BC should be handled in `/src/data/patches/patch.js` and `/src/data/verification/zVerify.js`. */ App.Update.oldVersions = function(node) { - V.slaves.filter(s => s.career === 0).forEach(s => s.career = "a slave"); - V.slaves.filter(s => s.origin === 0).forEach(s => s.origin = ""); + getSlaves().filter(s => s.career === 0).forEach(s => s.career = "a slave"); + getSlaves().filter(s => s.origin === 0).forEach(s => s.origin = ""); if (V.releaseID === 1021 || V.releaseID === 1020 || V.releaseID === 1019 || V.releaseID === 2022) { V.releaseID = 1022; } if (V.releaseID === 1043) { - V.slaves.forEach(s => { + getSlaves().forEach(s => { if (s.skill && s.skill.whore) { s.skill.whoring = s.skill.whore / 2; } @@ -4148,7 +4149,7 @@ App.Update.oldVersions = function(node) { } } if (V.releaseID < 1207) { - V.slaves.forEach(s => { + getSlaves().forEach(s => { if (s.geneMods.NCS === 1 || (s.geneticQuirks.neoteny >= 2 && s.geneticQuirks.progeria !== 2)) { s.ovaryAge = Math.max(s.ovaryAge, Math.min(s.physicalAge * 0.5, s.physicalAge - 2, 45)); } else { diff --git a/src/data/backwardsCompatibility/datatypeCleanup.js b/src/data/backwardsCompatibility/datatypeCleanup.js index ae186d1ac4d419bb8d5ad250881a7d851fc47854..fafad5265fd05fb4c46ba55b0970addcaa059f9d 100644 --- a/src/data/backwardsCompatibility/datatypeCleanup.js +++ b/src/data/backwardsCompatibility/datatypeCleanup.js @@ -2028,7 +2028,7 @@ App.Update.FacilityDatatypeCleanup = (function() { * @returns {number} ID of the first matched slave or 0 if no match was found */ function findSlaveId(predicate) { - const s = V.slaves.find(predicate); + const s = getSlaves().find(predicate); return s ? s.ID : 0; } @@ -2446,7 +2446,7 @@ App.Update.RARuleDatatypeCleanup = function() { if (count === 0) { count++; cond.activation = [false]; - console.log("no match", JSON.parse(JSON.stringify(cond))); + console.log("no match", Serial.parse(Serial.stringify(cond))); } cond.activation.push(count, "and"); } @@ -2455,7 +2455,7 @@ App.Update.RARuleDatatypeCleanup = function() { cond.activation = [false, 1, "and"]; } } catch (e) { - console.log("condition broke", e.message, JSON.parse(JSON.stringify(cond))); + console.log("condition broke", e.message, Serial.parse(Serial.stringify(cond))); cond.activation = [false, 1, "and"]; } finally { delete cond.function; @@ -2487,7 +2487,7 @@ App.Update.RARuleDatatypeCleanup = function() { } } } catch (e) { - console.log("assignments broke", e.message, JSON.parse(JSON.stringify(cond))); + console.log("assignments broke", e.message, Serial.parse(Serial.stringify(cond))); } finally { // @ts-ignore delete cond.assignment; diff --git a/src/data/dataUtils.js b/src/data/dataUtils.js index ebe05fbaacf783c493b9d87e247a5b5eda59014b..c9c5bcb8f7f73040ff3f39518cdd18d0442ac062 100644 --- a/src/data/dataUtils.js +++ b/src/data/dataUtils.js @@ -25,7 +25,30 @@ App.Utils.setNonexistentProperties = function(obj, props) { * @param {...object} defaultObjs one or more objects to add the properties from. */ App.Utils.assignMissingDefaults = (obj, ...defaultObjs) => { - _.defaultsDeep(obj, ...defaultObjs); + if (obj === undefined || obj == null) { + throw new Error(`assignMissingDefaults() expects param in position 1 to be an object`); + } + /** @type {object[]} */ + const defaults = [...defaultObjs]; + for (const index in defaults) { + if (defaults[index] === undefined || defaults[index] == null) { + throw new Error(`assignMissingDefaults() expects param in position ${Number(index) +2} to be an object`); + } + } + for (const defaultObj of defaults) { + for (const key of Object.keys(defaultObj)) { + if (obj[key] === undefined) { + obj[key] = clone(defaultObj[key]); + } else if ( + obj[key] != null && typeof obj[key] === "object" && + defaultObj[key] != null && typeof defaultObj[key] === "object" && + !Array.isArray(defaultObj[key]) + ) { + App.Utils.assignMissingDefaults(obj[key], defaultObj[key]); + } + } + } + return obj; // we return the obj so that is some idiot (like me) tries to assign the result of this call to something it will work as they expect }; /** @@ -59,17 +82,32 @@ App.Utils.setExistentProperties = function(obj, props) { * @param {...object} defaultObjs one or more objects to use the properties and values from */ App.Utils.overwriteWithDefaults = (obj, ...defaultObjs) => { + if (obj === undefined || obj == null) { + throw new Error(`overwriteWithDefaults() expects and object`); + } /** @type {object[]} */ const defaults = [...defaultObjs]; - defaults.forEach((defaultObj) => { - Object.keys(defaultObj).forEach((key) => { - if (typeof obj[key] === "object" && typeof defaultObj[key] === "object" && !Array.isArray(defaultObj[key])) { - obj[key] = App.Utils.overwriteWithDefaults(obj[key] ?? {}, defaultObj[key]); + for (const index in defaults) { + if (defaults[index] === undefined || defaults[index] == null) { + throw new Error(`overwriteWithDefaults() expects param in position ${Number(index) +2} to be an object`); + } + } + for (const defaultObj of defaults) { + if (defaultObj === undefined || obj == null) { continue; } + for (const key of Object.keys(defaultObj)) { + if (obj[key] != null && typeof obj[key] === "object" && + defaultObj[key] != null && typeof defaultObj[key] === "object" && + !Array.isArray(defaultObj[key]) + ) { + App.Utils.overwriteWithDefaults(obj[key] ?? {}, defaultObj[key]); + } else if (Array.isArray(obj[key]) && Array.isArray(defaultObj[key])) { + obj[key] = Array.from(clone(defaultObj[key])); } else { obj[key] = defaultObj[key]; } - }); - }); + } + } + return obj; // we return the obj so that is some idiot (like me) tries to assign the result of this call to something it will work as they expect }; /** diff --git a/src/data/newGamePlus.js b/src/data/newGamePlus.js index 2758d89cf81dda1657604eacdb765e3dda9478e8..29cd3ffe1ec2a39faea3f30c1137f77887a6fd35 100644 --- a/src/data/newGamePlus.js +++ b/src/data/newGamePlus.js @@ -59,7 +59,7 @@ App.Data.NewGamePlus = (function() { * @returns {Readonly<{[key: string]: Partial<FC.GenePoolRecord>}>} */ const ngUpdateGenePool = function(genePool = {}) { - const transferredSlaveIds = (V.slaves || []) + const transferredSlaveIds = (getSlaves() || []) .filter(s => s.ID >= NGPOffset) .map(s => s.ID - NGPOffset); /** @type {{[key: string]: Partial<FC.GenePoolRecord>}} */ @@ -84,7 +84,7 @@ App.Data.NewGamePlus = (function() { const newTable = {}; let needed = []; - (V.slaves || []) + (getSlaves() || []) .forEach(s => ([s.pregSource + NGPOffset, s.mother + NGPOffset, s.father + NGPOffset] .filter(i => (i in missingTable)) .forEach(i => { @@ -92,7 +92,7 @@ App.Data.NewGamePlus = (function() { needed.push(i); } }))); - (V.slaves || []).forEach(s => (s.womb + (getSlaves() || []).forEach(s => (s.womb .forEach(f => ([f.fatherID, f.genetics.father, f.genetics.mother] .filter(i => (i in missingTable)) .forEach(i => { @@ -131,7 +131,7 @@ App.Data.NewGamePlus = (function() { }; let oldMissingParentID = Math.min(-10000, ...Object.keys(V.missingTable)) - 1; - V.slaves.filter(s => (s.assignment !== Job.IMPORTED)).forEach(s => { + getSlaves().filter(s => (s.assignment !== Job.IMPORTED)).forEach(s => { V.missingTable[oldMissingParentID] = { slaveName: s.slaveName, slaveSurname: s.slaveSurname, @@ -151,7 +151,7 @@ App.Data.NewGamePlus = (function() { so.father = oldMissingParentID; } }); - [].concat(V.slaves).concat([V.PC]).forEach(so => { + [].concat(getSlaves()).concat([V.PC]).forEach(so => { if (so.mother === s.ID) { so.mother = oldMissingParentID; } @@ -165,9 +165,9 @@ App.Data.NewGamePlus = (function() { oldMissingParentID--; }); - V.slaves.deleteWith((s) => s.assignment !== Job.IMPORTED); + getSlaves().deleteWith((s) => s.assignment !== Job.IMPORTED); - for (let slave of V.slaves) { + for (let slave of getSlaves()) { slave.ID += NGPOffset; slave.assignment = Job.REST; if (V.freshPC === 1) { // check whether to reset weekAcquired same way we check whether to change father of fetus @@ -204,7 +204,7 @@ App.Data.NewGamePlus = (function() { slave.pregControl = "none"; } V.slaveIndices = slaves2indices(); - for (let slave of V.slaves) { + for (let slave of getSlaves()) { slave.pregSource = slaveOrZero(slave.pregSource); slave.cloneID = slaveOrZero(slave.cloneID); slave.relationshipTarget = slaveOrZero(slave.relationshipTarget); @@ -213,7 +213,7 @@ App.Data.NewGamePlus = (function() { V.genePool = ngUpdateGenePool(V.genePool); V.missingTable = ngUpdateMissingTable(V.missingTable); let validRelationship = (s) => (s.relationshipTarget !== 0 && getSlave(s.relationshipTarget).relationshipTarget === s.ID); - for (let slave of V.slaves) { + for (let slave of getSlaves()) { if ((slave.relationship < 0 && V.freshPC === 1) || (slave.relationship > 0 && !validRelationship(slave))) { slave.relationship = 0; slave.relationshipTarget = 0; diff --git a/src/data/patches/patch.js b/src/data/patches/patch.js index 513c248991ff19ea8c185b8004730f36be77df26..8c995fc9e4dd32f13ce0d061486f064fb471aec4 100644 --- a/src/data/patches/patch.js +++ b/src/data/patches/patch.js @@ -1,4 +1,4 @@ -// cSpell:words TLDR +// cSpell:words divs /** * Need to know how to apply a patch? Go to the line with `====== How to apply a patch ======`. @@ -76,6 +76,7 @@ */ // TODO:@franklygeorge add a way to force apply a list of patch versions and types in order +// TODO:@franklygeorge move the "Open All Reports" code from App.EndWeek.slaveAssignmentReport to App.UI.DOM and then utilize it in the patch system /** * registers a patch to the database @@ -104,13 +105,13 @@ App.Patch.log = (message, type="info") => { const iTemplate = `<span>${locator}: ${message}</span>`; const div = App.UI.DOM.makeElement("div"); if (type === "info") { - console.log(message); + // console.log(message); div.innerHTML = iTemplate; } else if (type === "error") { - console.error(message); + // console.error(message); div.innerHTML += eTemplate; } else if (type === "warn") { - console.warn(message); + // console.warn(message); div.innerHTML += wTemplate; } App.Patch.Utils.current.div.append(div); @@ -123,190 +124,295 @@ App.Patch.log = (message, type="info") => { * @returns {DocumentFragment} a document fragment with the results of the patching */ App.Patch.applyAll = () => { - // TODO:@franklygeorge on error, provide a human parsable patch log with valid markdown formatting for directly pasteing into a gitlab issue - // TODO:@franklygeorge include a save in the above in text form (do we need to change active passage?) - // TODO:@franklygeorge put each patches info in a collapsed div with a number for how many times `App.Patch.log` was called. `Log (call times)` - // TODO:@franklygeorge remove said collapsed div if it has no content - const f = document.createDocumentFragment(); - let header = App.UI.DOM.appendNewElement("div", f); - - const patchVersions = Object.keys(App.Patch.Patches).sort(); - - // check that the last patch (largest releaseID) is equal to App.Version.release - if (Number(patchVersions.at(-1)) > App.Version.release) { - throw new Error(`Patch exists for release ${patchVersions.at(-1)}, but App.Version.release is at ${App.Version.release}! Did you forget to increment release in '/src/002-config/fc-version.js'?`); - } else if (!(App.Version.release in App.Patch.Patches)) { + // create a loading screen + App.Patch.Utils.loadingScreen.start(); + + // create our document fragment and our main divs + const frag = document.createDocumentFragment(); + const head = App.UI.DOM.appendNewElement("div", frag); + head.id = "patch-header"; + const cDiv = App.UI.DOM.appendNewElement("div", frag); + cDiv.id = "patch-content"; + + // get all available patches in reverse order so that when we call .pop we will get the smallest patch version + let patchVersions = Object.keys(App.Patch.Patches).sort((a, b)=> +b - +a); + + // check that the first patch in patchVersions (largest releaseID) is equal to App.Version.release + if (Number(patchVersions[0]) > App.Version.release) { + throw new Error(`Patch exists for release ${patchVersions[0]}, but App.Version.release is at ${App.Version.release}! Did you forget to increment release in '/src/002-config/fc-version.js'?`); + } else if (Number(patchVersions[0]) < App.Version.release) { throw new Error(`No patch exists for releaseID ${App.Version.release}! Did you make a patch? Instructions are in '/src/data/patches/patch.js'.`); } - /** - * @typedef {object} App.Patch.applyAllWombsObj - * @property {string} identifier - * @property {FC.HumanState} actor - * @property {HTMLDivElement} div - */ - - let i; - /** @type {number} */ - let patchID; - /** @type {App.Patch.applyAllWombsObj[]} */ - let wombs = []; - - try { - for (const ID in patchVersions) { - patchID = Number(patchVersions[ID]); - App.Patch.Utils.current.patch = patchID; - - App.UI.DOM.appendNewElement("h3", f, `Applying Patch ${patchID}`); - console.log(`Applying Patch ${patchID}`); - - App.Patch.Utils.current.div = App.UI.DOM.appendNewElement("div", f); - - // pre patch - App.Patch.Utils.gameVariables("pre", App.Patch.Utils.current.div, patchID); // This should always be the first patch - - // PlayerState - App.Patch.Utils.playerState("V.PC", V.PC, "V.PC", App.Patch.Utils.current.div, patchID); - wombs.push({identifier: `V.PC`, actor: V.PC, div: App.Patch.Utils.current.div}); - - // SlaveState - for (i in V.slaves ?? []) { - App.Patch.Utils.slaveState( - `V.slaves[${i}]`, V.slaves[i], "V.slaves", App.Patch.Utils.current.div, patchID - ); - wombs.push({identifier: `V.slaves[${i}]`, actor: V.slaves[i], div: App.Patch.Utils.current.div}); - } + // remove all unneeded patch versions from the array + patchVersions = patchVersions.filter((patchID) => { return Number(patchID) > V.releaseID; }); + // get the amount of the patches we are going to apply for later use + const patchCount = patchVersions.length; - if (V.hostage) { - App.Patch.Utils.slaveState( - `V.hostage`, V.hostage, "V.hostage", App.Patch.Utils.current.div, patchID - ); - wombs.push({identifier: `V.hostage`, actor: V.hostage, div: App.Patch.Utils.current.div}); - } + // We use setTimeout here to give the App.Patch.applyAll() function time to return frag and SugarCube the time to change passages + // The execution flow skips this setTimeout call temporarily + setTimeout((() => { + // get the elements we created earlier + let f = document.getElementById("patch-content"); + let header = document.getElementById("patch-header"); + // this element was created by the App.Patch.Utils.loadingScreen.start() call + let message = document.getElementById("patch-message"); - if (V.boomerangSlave) { - App.Patch.Utils.slaveState( - `V.boomerangSlave`, V.boomerangSlave, "V.boomerangSlave", - App.Patch.Utils.current.div, patchID - ); - wombs.push({identifier: `V.boomerangSlave`, actor: V.boomerangSlave, div: App.Patch.Utils.current.div}); - } + let verificationStart; - if (V.shelterSlave) { - App.Patch.Utils.slaveState( - `V.shelterSlave`, V.shelterSlave, "V.shelterSlave", - App.Patch.Utils.current.div, patchID - ); - wombs.push({identifier: `V.shelterSlave`, actor: V.shelterSlave, div: App.Patch.Utils.current.div}); + /** This is called by App.Verify.everything() when it is done */ + const finalize = () => { + if (getProp(V, "reportVerificationChanges", 0) === 0) { + App.Patch.Utils.current.div.append(App.UI.DOM.makeElement('div', "Change detection was skipped because it is disabled")); } - if (V.traitor) { - App.Patch.Utils.slaveState( - `V.traitor`, V.traitor, "V.traitor", App.Patch.Utils.current.div, patchID - ); - wombs.push({identifier: `V.traitor`, actor: V.traitor, div: App.Patch.Utils.current.div}); - } + // report the time taken and the amount of content added to current div + const verificationTime = (new Date().getTime() - verificationStart).toLocaleString(); + const divLength = App.Patch.Utils.current.div.childNodes.length; - // TankSlaveState - for (i in V.incubator.tanks ?? []) { - App.Patch.Utils.tankSlaveState( - `V.incubator.tanks[${i}]`, V.incubator.tanks[i], App.Patch.Utils.current.div, patchID - ); - wombs.push({ - identifier: `V.incubator.tanks[${i}]`, - actor: V.incubator.tanks[i], - div: App.Patch.Utils.current.div - }); - } + f.append(App.UI.DOM.accordion( + `Cleanup and Verification (${divLength}) (${verificationTime}ms)`, + App.Patch.Utils.current.div, + (divLength === 0 || getProp(V, "useAccordion", 1) > 0) + )); - // InfantState - for (i in V.cribs ?? []) { - App.Patch.Utils.infantState( - `V.cribs[${i}]`, V.cribs[i], "V.cribs", App.Patch.Utils.current.div, patchID - ); - wombs.push({identifier: `V.cribs[${i}]`, actor: V.cribs[i], div: App.Patch.Utils.current.div}); // shouldn't be needed, but InfantStates are HumanStates so might as well make sure it is right + // handle App.Verify.Utils.verificationError + if (App.Verify.Utils.verificationError) { + header.innerHTML += `<span class="error">Verification failed!</span>`; + console.error("Verification failed!"); + State.restore(); // restore the state to before patching + } else { + if (patchCount !== 0) { + header.innerHTML += `<span class="green">${patchCount} patches applied! You are on release ${V.releaseID}</span>`; + } else { + header.innerHTML += `<span class="green">No patches needed to be applied! You are on release ${V.releaseID}</span>`; + } + App.UI.DOM.appendNewElement("h3", f, "Done!"); + console.log("Done!"); } - // ChildState - // TODO:@franklygeorge this is waiting on FC.ChildState to be implemented - const children = []; - for (i in children) { - App.Patch.Utils.childState( - // @ts-ignore - `children[${i}]`, children[i], "children", App.Patch.Utils.current.div, patchID - ); - wombs.push({identifier: `children[${i}]`, actor: children[i], div: App.Patch.Utils.current.div}); - } + header.innerHTML += `<br><span>See below for details</span><hr>`; + + // update the sidebar to remove any potential errors that were cause by being on an outdated save + App.Utils.scheduleSidebarRefresh(); - // Wombs - wombs.forEach((womb) => { - App.Patch.Utils.patchWomb(womb.identifier, womb.actor, womb.div, patchID); - }); + // remove the loading screen so the user can see the results + App.Patch.Utils.loadingScreen.end(); - // CustomOrderSlave - if (V.customSlave) { - App.Patch.Utils.customSlaveOrder( - "V.customSlave", V.customSlave, App.Patch.Utils.current.div, patchID - ); + App.Patch.Utils.current.div = undefined; + // this is where the execution actually stops for the patching system + }; + + /** + * This function is called later in the code. + * It does verification and final cleanup after the patching is done + * @returns {undefined} + */ + const verifyAndCleanup = () => { + // make a new div + App.Patch.Utils.current.div = App.UI.DOM.makeElement("div"); + + // Cleanup + console.log(`Cleanup`); + + V.NaNArray = findNaN(); // reset NaNArray + App.UI.SlaveSummary.settingsChanged(); // let slave summary know that settings may have changed + + // verification + console.log(`Verification`); + + App.Verify.Utils.verificationError = false; + try { + verificationStart = new Date().getTime(); + // does the actual verification + App.Verify.everything(App.Patch.Utils.current.div, finalize); + } catch (e) { + header.innerHTML += `<span class="error">Verification failed!</span>`; + console.error("Verification failed!"); + App.Patch.Utils.current.div.append(App.UI.DOM.formatException(e)); + State.restore(); // restore the state to before patching + header.innerHTML += `<br><span>See below for details</span><hr>`; + // close the loading screen so that the user can see the error + App.Patch.Utils.loadingScreen.end(); + return; } - if (V.huskSlave) { - App.Patch.Utils.customSlaveOrder( - "V.huskSlave", V.huskSlave, App.Patch.Utils.current.div, patchID - ); + }; + + const patchingStart = new Date().getTime(); + let i; + + /** + * This function is called later in the code. + * It applies a single patch. + * If there are more patches to apply it calls itself, if not then it calls verifyAndCleanup(). + * @returns {undefined} + */ + const applyPatch = () => { + const patchID = Number(patchVersions.pop()); + + /** @type {{identifier: string, actor: FC.HumanState, div: HTMLDivElement}[]} */ + const wombs = []; + + const patchStart = new Date().getTime(); + + // patch + try { + // make a new div + App.Patch.Utils.current.div = App.UI.DOM.makeElement("div"); + + // Pre patch; This should always be the first patch + App.Patch.Utils.gameVariables("pre", App.Patch.Utils.current.div, patchID); + + // PlayerState + App.Patch.Utils.playerState("V.PC", V.PC, "V.PC", App.Patch.Utils.current.div, patchID); + wombs.push({identifier: `V.PC`, actor: V.PC, div: App.Patch.Utils.current.div}); + + // SlaveState + const slaves = getSlaves(); + for (i in slaves ?? []) { + App.Patch.Utils.slaveState( + `getSlaves()[${i}]`, slaves[i], "main slave pool", App.Patch.Utils.current.div, patchID + ); + wombs.push({identifier: `getSlaves()[${i}]`, actor: slaves[i], div: App.Patch.Utils.current.div}); + } + + if (V.hostage) { + App.Patch.Utils.slaveState( + `V.hostage`, V.hostage, "V.hostage", App.Patch.Utils.current.div, patchID + ); + wombs.push({identifier: `V.hostage`, actor: V.hostage, div: App.Patch.Utils.current.div}); + } + + if (V.boomerangSlave) { + App.Patch.Utils.slaveState( + `V.boomerangSlave`, V.boomerangSlave, "V.boomerangSlave", + App.Patch.Utils.current.div, patchID + ); + wombs.push({identifier: `V.boomerangSlave`, actor: V.boomerangSlave, div: App.Patch.Utils.current.div}); + } + + if (V.shelterSlave) { + App.Patch.Utils.slaveState( + `V.shelterSlave`, V.shelterSlave, "V.shelterSlave", + App.Patch.Utils.current.div, patchID + ); + wombs.push({identifier: `V.shelterSlave`, actor: V.shelterSlave, div: App.Patch.Utils.current.div}); + } + + if (V.traitor) { + App.Patch.Utils.slaveState( + `V.traitor`, V.traitor, "V.traitor", App.Patch.Utils.current.div, patchID + ); + wombs.push({identifier: `V.traitor`, actor: V.traitor, div: App.Patch.Utils.current.div}); + } + + // TankSlaveState + for (i in V.incubator.tanks ?? []) { + App.Patch.Utils.tankSlaveState( + `V.incubator.tanks[${i}]`, V.incubator.tanks[i], App.Patch.Utils.current.div, patchID + ); + wombs.push({ + identifier: `V.incubator.tanks[${i}]`, + actor: V.incubator.tanks[i], + div: App.Patch.Utils.current.div + }); + } + + // InfantState + for (i in V.cribs ?? []) { + App.Patch.Utils.infantState( + `V.cribs[${i}]`, V.cribs[i], "V.cribs", App.Patch.Utils.current.div, patchID + ); + wombs.push({identifier: `V.cribs[${i}]`, actor: V.cribs[i], div: App.Patch.Utils.current.div}); // shouldn't be needed, but InfantStates are HumanStates so might as well make sure it is right + } + + // ChildState + // TODO:@franklygeorge this is waiting on FC.ChildState to be implemented + const children = []; + for (i in children) { + App.Patch.Utils.childState( + // @ts-ignore + `children[${i}]`, children[i], "children", App.Patch.Utils.current.div, patchID + ); + wombs.push({identifier: `children[${i}]`, actor: children[i], div: App.Patch.Utils.current.div}); + } + + // Wombs/Fetuses; This should always be below all the HumanState patches + wombs.forEach((womb) => { + App.Patch.Utils.patchWomb(womb.identifier, womb.actor, womb.div, patchID); + }); + + // CustomOrderSlave + if (V.customSlave) { + App.Patch.Utils.customSlaveOrder( + "V.customSlave", V.customSlave, App.Patch.Utils.current.div, patchID + ); + } + if (V.huskSlave) { + App.Patch.Utils.customSlaveOrder( + "V.huskSlave", V.huskSlave, App.Patch.Utils.current.div, patchID + ); + } + + // Post patch; This should always be the last patch + App.Patch.Utils.gameVariables("post", App.Patch.Utils.current.div, patchID); + } catch (e) { + header.innerHTML += `<span class="error">Patching Failed when applying patch ${App.Patch.Utils.current.patch}["${App.Patch.Utils.current.type}"] to ${App.Patch.Utils.current.identifier}!</span>`; + App.Patch.Utils.current.div.append(App.UI.DOM.formatException(e)); + State.restore(); // restore the state to before patching + header.innerHTML += `<br><span>See below for details</span><hr>`; + // close the loading screen so that the user can see the error + App.Patch.Utils.loadingScreen.end(); + return; } - // post patch - App.Patch.Utils.gameVariables("post", App.Patch.Utils.current.div, patchID); // This should always be the last patch - } - } catch (e) { - header.innerHTML += `<span class="error">Patching Failed when applying patch ${App.Patch.Utils.current.patch}["${App.Patch.Utils.current.type}"] to ${App.Patch.Utils.current.identifier}!</span>`; - App.Patch.Utils.current.div.append(App.UI.DOM.formatException(e)); - // @ts-ignore - State.restore(); // restore the state to before patching - header.innerHTML += `<br><span>See below for details</span><hr>`; - // report the results - return f; - } + // report the time taken and the amount of content added to current div + const patchTime = (new Date().getTime() - patchStart).toLocaleString(); + const divLength = App.Patch.Utils.current.div.childNodes.length; - App.Patch.Utils.current.div = App.UI.DOM.appendNewElement("div", f); - - // verification - App.UI.DOM.appendNewElement("h3", App.Patch.Utils.current.div, `Verification`); - console.log(`Verification`); - App.Verify.Utils.verificationError = false; - try { - App.Verify.everything(App.Patch.Utils.current.div); - } catch (e) { - header.innerHTML += `<span class="error">Verification failed!</span>`; - console.error("Verification failed!"); - App.Patch.Utils.current.div.append(App.UI.DOM.formatException(e)); - // @ts-ignore - State.restore(); // restore the state to before patching - header.innerHTML += `<br><span>See below for details</span><hr>`; - // report the results - return f; - } + f.append(App.UI.DOM.accordion( + `Patch ${patchID} (${divLength}) (${patchTime}ms)`, + App.Patch.Utils.current.div, + (divLength === 0 || getProp(V, "useAccordion", 1) > 0) + )); - // Cleanup - App.UI.DOM.appendNewElement("h3", App.Patch.Utils.current.div, `Cleanup`); - console.log(`Cleanup`); - V.NaNArray = findNaN(); // reset NaNArray - App.UI.SlaveSummary.settingsChanged(); // let slave summary know that settings may have changed - - // handle App.Verify.Utils.verificationError - if (App.Verify.Utils.verificationError) { - header.innerHTML += `<span class="error">Verification failed!</span>`; - console.error("Verification failed!"); - // @ts-ignore - State.restore(); // restore the state to before patching - } else { - header.innerHTML += `<span class="green">Patches applied! You are on release ${V.releaseID}</span>`; - App.UI.DOM.appendNewElement("h3", f, "Patches Applied!"); - console.log("Patches Applied!"); - } + // continue + if (patchVersions.length !== 0) { + // let the user know what we are doing, by changing the loading screen message + message.innerHTML = `Applying Patch ${patchVersions.last()}...`; + // give the DOM time to update and then call applyPatch() again + setTimeout(applyPatch, 0); + } else { + const patchingTime = (new Date().getTime() - patchingStart).toLocaleString(); + f.append(App.UI.DOM.accordion( + `Patching results (${patchCount} patches) (${patchingTime}ms)`, + App.UI.DOM.makeElement('div', `Patching completed successfully, applying ${patchCount} patches in ${patchingTime}ms`), + true, + )); + // let the user know what we are doing, by changing the loading screen message + message.innerHTML = `Cleaning up and verifying...`; + // give the DOM time to update and then call verifyAndCleanup() + setTimeout(verifyAndCleanup, 0); + } + }; - header.innerHTML += `<br><span>See below for details</span><hr>`; + // start the patching + if (patchVersions.length !== 0) { + // let the user know what we are doing, by changing the loading screen message + message.innerHTML = `Applying Patch ${patchVersions.last()}...`; + // give the DOM time to update and then call applyPatch() + setTimeout(applyPatch, 0); + } else { + // we didn't have any patches to apply but we still run verification + App.UI.DOM.appendNewElement('div', f, `No patches needed to be applied`); + // let the user know what we are doing, by changing the loading screen message + message.innerHTML = `Cleaning up and verifying...`; + // give the DOM time to update and then call verifyAndCleanup() + setTimeout(verifyAndCleanup, 0); + } + }), 0); - // report the results - return f; + // return the empty document + // the first setTimeout above will execute soon after the passage change happens + return frag; }; diff --git a/src/data/patches/patchUtils.js b/src/data/patches/patchUtils.js index 5b81a8e9cac06a65ff7cdf2c3356d7aff5ced5d6..22e90b6b5a521d366d07939416b052f4d71e315c 100644 --- a/src/data/patches/patchUtils.js +++ b/src/data/patches/patchUtils.js @@ -41,7 +41,7 @@ App.Patch.Utils.patch = (patchType, patchUpTo, identifier, div=undefined, obj, e console.log(`\\/ \\/ \\/ Patching of '${patchType}' started for '${identifier}' \\/ \\/ \\/`); } const patchVersions = Object.keys(App.Patch.Patches).sort().filter((version) => { - return Number(version) <= patchUpTo; + return (Number(version) <= patchUpTo && Number(version) > obj.releaseID); }); /** @type {number} */ @@ -349,7 +349,7 @@ App.Patch.Utils.current = { */ /** - * @typedef {"V.slaves"|"V.PC"|"V.hostage"|"V.boomerangSlave"|"V.traitor"|"V.shelterSlave"|"V.incubator.tanks"|"V.genePool"|"V.cribs"|"none"} App.Patch.Utils.HumanStateLocation + * @typedef {"main slave pool"|"V.PC"|"V.hostage"|"V.boomerangSlave"|"V.traitor"|"V.shelterSlave"|"V.incubator.tanks"|"V.genePool"|"V.cribs"|"none"} App.Patch.Utils.HumanStateLocation */ /** @@ -375,3 +375,43 @@ App.Patch.Utils.current = { * @property {(div: HTMLDivElement, child: FC.ChildState) => FC.ChildState} [childState] * @property {(div: HTMLDivElement, order: FC.CustomSlaveOrder, location: "V.customSlave"|"V.huskSlave") => FC.CustomSlaveOrder} [customSlaveOrder] */ + +// put on a loading screen +// this was copied from endWeekAnim.js and modified +App.Patch.Utils.loadingScreen = (function() { + let loadLockID = -1; + let infoDiv = null; + + function makeInfoDiv() { + infoDiv = $(` + <div class="endweek-titleblock"> + <div class="endweek-maintitle">Applying patches...</div> + <div class="endweek-subtitle" id="patch-message"></div> + </div> + `); + } + + function start() { + if (loadLockID === -1) { + makeInfoDiv(); + $("#init-screen").append(infoDiv); + loadLockID = LoadScreen.lock(); + } + } + + function end() { + if (loadLockID !== -1) { + setTimeout(() => { + LoadScreen.unlock(loadLockID); + infoDiv.remove(); + infoDiv = null; + loadLockID = -1; + }, 0); + } + } + + return { + start, + end + }; +})(); diff --git a/src/data/patches/releases/1261_fixBrokenEyesAndPartners.js b/src/data/patches/releases/1261_fixBrokenEyesAndPartners.js index 9daad3875cb9b4817826645024c35df9295b7926..96ff6f736a7c5b82092b47aebec972ba1d334538 100644 --- a/src/data/patches/releases/1261_fixBrokenEyesAndPartners.js +++ b/src/data/patches/releases/1261_fixBrokenEyesAndPartners.js @@ -10,7 +10,7 @@ App.Patch.register({ if (Array.isArray(actor.partners)) { actor.partners = new Set(getProp(actor, "partners")); } else { - App.Patch.log(`partners was '${JSON.stringify(actor.partners)}' of type '${typeof actor.partners}', setting partners to an empty set`); + App.Patch.log(`partners was '${Serial.stringify(actor.partners)}' of type '${typeof actor.partners}', setting partners to an empty set`); actor.partners = new Set([]); } } @@ -47,7 +47,7 @@ App.Patch.register({ App.Utils.assignMissingDefaults(actor.eye.right, defaultEye.right); } actor.eye.origColor = actor.eye.origColor ?? origColor; - if (JSON.stringify(origEye) !== JSON.stringify(actor.eye)) { + if (Serial.stringify(origEye) !== Serial.stringify(actor.eye)) { App.Patch.log('Fixed corrupted eye object'); } deleteProps(actor, "eyeColor"); diff --git a/src/data/patches/releases/1263_renameIncubatorUpgrades.js b/src/data/patches/releases/1263_renameIncubatorUpgrades.js new file mode 100644 index 0000000000000000000000000000000000000000..e9e034e86683dcd73cb7786b244ddb24278221c6 --- /dev/null +++ b/src/data/patches/releases/1263_renameIncubatorUpgrades.js @@ -0,0 +1,8 @@ +App.Patch.register({ + releaseID: 1263, + descriptionOfChanges: "V.incubator.upgrade must be moved to V.incubator.upgrades before work on further facility conversions can advance.", + pre: (div) => { + V.incubator.upgrades = clone(V.incubator.upgrade); + deleteProps(V.incubator, "upgrade"); + } +}); diff --git a/src/data/patches/releases/1264_fixBrokenSerialization.js b/src/data/patches/releases/1264_fixBrokenSerialization.js new file mode 100644 index 0000000000000000000000000000000000000000..5bc0a8d28c23e50384141b48380ce2e737a28ecd --- /dev/null +++ b/src/data/patches/releases/1264_fixBrokenSerialization.js @@ -0,0 +1,24 @@ +App.Patch.register({ + releaseID: 1264, + descriptionOfChanges: `Some old saves incorrectly serialized 'undefined' as '[ "(revive:eval)", "undefined" ]'`, + slaveState: (div, actor, location) => { + if (typeof actor.clothingBaseColor !== 'string' && actor.clothingBaseColor !== undefined) { + actor.clothingBaseColor = undefined; + App.Patch.log("Fixed corrupted 'clothingBaseColor'"); + } + if (typeof actor.glassesColor !== 'string' && actor.glassesColor !== undefined) { + actor.glassesColor = undefined; + App.Patch.log("Fixed corrupted 'glassesColor'"); + } + if (typeof actor.shoeColor !== 'string' && actor.shoeColor !== undefined) { + actor.shoeColor = undefined; + App.Patch.log("Fixed corrupted 'shoeColor'"); + } + if (typeof actor.kindness !== 'string' && actor.kindness !== undefined) { + actor.kindness = undefined; + App.Patch.log("Fixed corrupted 'kindness'"); + } + + return actor; + }, +}); diff --git a/src/data/patches/releases/1265_fixSlavesBeingDetecedAsTankSlaves.js b/src/data/patches/releases/1265_fixSlavesBeingDetecedAsTankSlaves.js new file mode 100644 index 0000000000000000000000000000000000000000..abc167930b91cc7011aa03972b8773b5dbfa5d38 --- /dev/null +++ b/src/data/patches/releases/1265_fixSlavesBeingDetecedAsTankSlaves.js @@ -0,0 +1,10 @@ +App.Patch.register({ + releaseID: 1265, + descriptionOfChanges: "Remove incubatorSettings from all HumanStates except for TankSlaveStates", + humanState: (div, actor, location) => { + if (location !== "V.incubator.tanks" && "incubatorSettings" in actor) { + deleteProps(actor, "incubatorSettings"); + } + return actor; + } +}); diff --git a/src/data/patches/releases/1266_fixPartnersAgain.js b/src/data/patches/releases/1266_fixPartnersAgain.js new file mode 100644 index 0000000000000000000000000000000000000000..359c87240222d6dff41decde3b6284a8237990f8 --- /dev/null +++ b/src/data/patches/releases/1266_fixPartnersAgain.js @@ -0,0 +1,10 @@ +App.Patch.register({ + releaseID: 1266, + descriptionOfChanges: `Recent changes to SC meant that imported/exported slaves were not serialized correctly. This 'fixes' (data is lost) those slaves.`, + humanState: (div, actor, location) => { + if (!(actor.partners instanceof Set)) { + actor.partners = new Set([]); + } + return actor; + } +}); diff --git a/src/data/patches/releases/1267_fixEyeColorsInFetuses.js b/src/data/patches/releases/1267_fixEyeColorsInFetuses.js new file mode 100644 index 0000000000000000000000000000000000000000..2be2431286a93e3cccf8614f817feb3938d6d9b0 --- /dev/null +++ b/src/data/patches/releases/1267_fixEyeColorsInFetuses.js @@ -0,0 +1,12 @@ +App.Patch.register({ + releaseID: 1267, + descriptionOfChanges: "Adds eye color to fetuses if it is missing due to bugs in getGenePoolRecord()", + fetus: (div, fetus, mother) => { + if (fetus.genetics.eyeColor === undefined) { + const motherColor = getGenePoolRecord(mother).eye.origColor; + fetus.genetics.eyeColor = motherColor; + App.Patch.log(`Setting undefined eye color to '${motherColor}'`); + } + return fetus; + } +}); diff --git a/src/data/verification/verifyFetus.js b/src/data/verification/verifyFetus.js index a2ce680f42551db9fed2ab9bf990854b4252a4bf..24377e0f589ef10209e54379324d3668769aa70a 100644 --- a/src/data/verification/verifyFetus.js +++ b/src/data/verification/verifyFetus.js @@ -7,10 +7,11 @@ App.Verify.fetuses = (div) => { let i; let f; - for (i in V.slaves) { - if (V.slaves[i].womb && Array.isArray(V.slaves[i].womb)) { - for (f in V.slaves[i].womb) { - App.Verify.fetus(`V.slaves[${i}].womb[${f}]`, V.slaves[i].womb[f], V.slaves[i], div); + const slaves = getSlaves(); + for (i in slaves) { + if (slaves[i].womb && Array.isArray(slaves[i].womb)) { + for (f in slaves[i].womb) { + App.Verify.fetus(`getSlaves()[${i}].womb[${f}]`, slaves[i].womb[f], slaves[i], div); } } } diff --git a/src/data/verification/verifyGameVariables.js b/src/data/verification/verifyGameVariables.js index 551298f816b5dc5c8ee10da043d063115758903d..59a02d133d09d6db6de422f51ebdb7c646af35a1 100644 --- a/src/data/verification/verifyGameVariables.js +++ b/src/data/verification/verifyGameVariables.js @@ -23,7 +23,7 @@ App.Verify.gameVariables = (div) => { * @type {App.Verify.Utils.FunctionGameVariables} */ App.Verify.I.genePool = () => { - const AllHumanIDs = getAllHumans().map((s) => s.ID); + const AllHumanIDs = getHumanStates().map((s) => s.ID); // remove all unneeded records from the genePool for (const [key, record] of Object.entries(_.cloneDeep(V.genePool))) { if (key === "-1" || AllHumanIDs.includes(Number(key))) { continue; } @@ -70,7 +70,7 @@ App.Verify.I.genePool = () => { }); // add any missing records to the genePool - getAllHumans().forEach((human) => { + getHumanStates().forEach((human) => { if (!isInGenePool(human)) { addToGenePool(human); } diff --git a/src/data/verification/verifyHumanState.js b/src/data/verification/verifyHumanState.js index cb210f2caed16b9db238d3e93cf090fb15c38aa5..69cf4d6582121f1ed8bd826b38fc56bdc6baceb8 100644 --- a/src/data/verification/verifyHumanState.js +++ b/src/data/verification/verifyHumanState.js @@ -76,7 +76,7 @@ App.Verify.I.humanHealth = (actor, location) => { * @see updateHealth * To get around this issue we are only running updateHealth(actor) if the values were actually changed by this function */ - if (JSON.stringify(oldHealth) !== JSON.stringify(actor.health)) { + if (Serial.stringify(oldHealth) !== Serial.stringify(actor.health)) { updateHealth(actor); } return actor; diff --git a/src/data/verification/verifySlaveState.js b/src/data/verification/verifySlaveState.js index 240d1b8f2a995d88494a72d7b5223833a060dffb..4ac8c2e8a9c68ac4b6bc48f6178797c460ddb5fa 100644 --- a/src/data/verification/verifySlaveState.js +++ b/src/data/verification/verifySlaveState.js @@ -7,8 +7,9 @@ */ App.Verify.slaveStates = (div) => { let i; - for (i in V.slaves) { - App.Verify.slaveState(`V.slaves[${i}]`, V.slaves[i], "V.slaves", div); + const slaves = getSlaves(); + for (i in slaves) { + App.Verify.slaveState(`getSlaves()[${i}]`, slaves[i], "main slave pool", div); } if (V.hostage) { App.Verify.slaveState("V.hostage", V.hostage, "V.hostage", div); diff --git a/src/data/verification/verifyUtils.js b/src/data/verification/verifyUtils.js index 5f3d138b1b7f3bb28c4cc1dd0912ab4533fd5fa9..90d21cf568b51e5b761c248d3a940cff4233d2c4 100644 --- a/src/data/verification/verifyUtils.js +++ b/src/data/verification/verifyUtils.js @@ -4,7 +4,7 @@ * @returns {number} ID of the first matched slave or 0 if no match was found */ App.Verify.Utils.findSlaveId = (predicate) => { - const s = V.slaves.find(predicate); + const s = getSlaves().find(predicate); return s ? s.ID : 0; }; @@ -29,7 +29,7 @@ App.Verify.Utils.findSlaveId = (predicate) => { App.Verify.Utils.changeSummary = (obj1, obj2, setKey, instructionID, identifier) => { const temp = `When executing 'App.Verify.instructions.${setKey}.${instructionID}': '{path}' {change}`; - if (JSON.stringify(obj1) === JSON.stringify(obj2)) { return undefined; } // Quick and dirty comparision, don't do work when it isn't needed + if (Serial.stringify(obj1) === Serial.stringify(obj2)) { return undefined; } // Quick and dirty comparision, don't do work when it isn't needed // something has changed, deep comparision needed /** @@ -42,7 +42,7 @@ App.Verify.Utils.changeSummary = (obj1, obj2, setKey, instructionID, identifier) /** @type {App.Verify.Utils.ChangeRecord[]} */ let changes = []; - if (JSON.stringify(obj1) === JSON.stringify(obj2)) { return changes; } // don't do work when it isn't needed + if (Serial.stringify(obj1) === Serial.stringify(obj2)) { return changes; } // don't do work when it isn't needed let keys1 = Object.keys(obj1); let keys2 = Object.keys(obj2); @@ -178,7 +178,6 @@ App.Verify.Utils.verify = (setKey, identifier, obj, extra, div) => { } if (isV) { // rollback the game state - // @ts-ignore restore does exist on our custom SugarCube State.restore(); // and return nothing return; @@ -187,38 +186,41 @@ App.Verify.Utils.verify = (setKey, identifier, obj, extra, div) => { return original; } } - // log any changes - const changes = App.Verify.Utils.changeSummary(original, obj, setKey, instructionID, identifier); - if (changes) { - changes.forEach((record) => { - if (record.path === "V.IDNumber") { - return; - } - let level = "error"; - if ( - record.description.includes(`'App.Verify.instructions.gameVariables.genePool'`) || - record.type === "key" - ) { - // The genePool verification is one of the (maybe the only) times that properties should actually be deleted/created - level = "orange"; - } - if (["key", "type"].includes(record.type)) { - if (div) { - $(div).append(`<div><span class="${level}">${record.description}</span></div>`); - } else if (level === "error") { - console.error(record.description); - } else { - console.warn(record.description); + + // report changes if V.logVerificationChanges is set to 1 + if (getProp(V, "reportVerificationChanges", 0) === 1) { + const changes = App.Verify.Utils.changeSummary(original, obj, setKey, instructionID, identifier); + if (changes) { + changes.forEach((record) => { + if (record.path === "V.IDNumber") { + return; + } + let level = "error"; + if ( + record.description.includes(`'App.Verify.instructions.gameVariables.genePool'`) || + record.type === "key" + ) { + // The genePool verification is one of the (maybe the only) times that properties should actually be deleted/created + level = "orange"; } - } else { - if (div) { - $(div).append(`<div><span>${record.description}</span></div>`); + if (["key", "type"].includes(record.type)) { + if (div) { + $(div).append(`<div><span class="${level}">${record.description}</span></div>`); + } else if (level === "error") { + console.error(record.description); + } else { + console.warn(record.description); + } } else { - console.warn(record.description); - console.warn("original val:", record.origVal, "new val:", record.newVal); + if (div) { + $(div).append(`<div><span>${record.description}</span></div>`); + } else { + console.warn(record.description); + console.warn("original val:", record.origVal, "new val:", record.newVal); + } } - } - }); + }); + } } } if (DEBUG) { diff --git a/src/data/verification/zVerify.js b/src/data/verification/zVerify.js index ac5e256927baad54ca9b8966d17c359c27e70db0..fbb53f4296d5ca14969fc143e1144ed67202cd33 100644 --- a/src/data/verification/zVerify.js +++ b/src/data/verification/zVerify.js @@ -243,14 +243,66 @@ App.Verify.instructions = { * Runs verification for everything. * This is resource intensive. If you only need to verify a single data structure, use its verification function(s) instead. * @param {HTMLDivElement} [div] if provided then info may be appended to this div + * @param {Function} [callback] Called when verification finishes if provided */ -App.Verify.everything = (div) => { - App.Verify.slaveStates(div); - App.Verify.tankSlaveStates(div); - App.Verify.childStates(div); - App.Verify.infantStates(div); - App.Verify.fetuses(div); - App.Verify.playerState(V.PC, "V.PC", div); - App.Verify.customSlaveOrders(div); - App.Verify.gameVariables(div); // game variables should always be verified last +App.Verify.everything = (div, callback) => { + // a list of verifications to run + const funcs = [ + {func: App.Verify.slaveStates, params: [div], message: "Verifying SlaveStates..."}, + {func: App.Verify.tankSlaveStates, params: [div], message: "Verifying TankSlaveStates..."}, + {func: App.Verify.childStates, params: [div], message: "Verifying ChildStates..."}, + {func: App.Verify.infantStates, params: [div], message: "Verifying InfantStates..."}, + {func: App.Verify.fetuses, params: [div], message: `Verifying ${V.seePreg === 1 ? 'Fetuses' : 'FStates'}...`}, + {func: App.Verify.playerState, params: [V.PC, "V.PC", div], message: "Verifying PlayerState..."}, + {func: App.Verify.customSlaveOrders, params: [div], message: "Verifying CustomSlaveOrders..."}, + {func: App.Verify.gameVariables, params: [div], message: "Verifying GameVariables (V)..."}, // game variables should always be verified last + ].reverse(); + + // attempt to get the element, use a dummy if it doesn't exist + const message = document.getElementById("patch-message") ?? App.UI.DOM.makeElement("div"); + + const verify = () => { + // get the verification to run + const func = funcs.pop(); + // run the verification + try { + func.func.apply(null, func.params); + } catch (e) { + if (div) { + // attempt to get the element, use a dummy if it doesn't exist + const header = document.getElementById("patch-header") ?? App.UI.DOM.makeElement("div"); + header.innerHTML += `<span class="error">Verification failed!</span>`; + console.error("Verification failed!"); + if (App.Patch.Utils.current.div) { + App.Patch.Utils.current.div.append(App.UI.DOM.formatException(e)); + } else { + div.append(App.UI.DOM.formatException(e)); + } + header.innerHTML += `<br><span>See below for details</span><hr>`; + } else { + console.error(e); + console.error("Verification failed!"); + } + State.restore(); // restore the state to before patching + // close the loading screen (if it is open) so that the user can see the error + App.Patch.Utils.loadingScreen.end(); + return; + } + + // check if there are more to run + if (funcs.length !== 0) { + // set the message the player sees + message.innerHTML = funcs.last().message; + // wait for the DOM to update then call verify + setTimeout(verify, 0); + } else if (callback) { + callback(); + } + }; + if (funcs.length !== 0) { + // set the message the player sees + message.innerHTML = funcs.last().message; + // wait for the DOM to update then call verify + setTimeout(verify, 0); + } }; diff --git a/src/debugging/debugJS.js b/src/debugging/debugJS.js index aba847a385a179199499466caf9c9eed87aec37f..61fda059a51c05afca2a7818d440baef2051735f 100644 --- a/src/debugging/debugJS.js +++ b/src/debugging/debugJS.js @@ -107,12 +107,18 @@ App.Debug.dumpGameState = function() { } const handler = (save) => { - downloadToFile(JSON.stringify(save, null, 2), save.id + ".json", "text/plain"); + let name = save.id + ".json"; + try { + name = App.Utils.getSaveFilename(undefined, "json"); + } catch (ex) { + console.error(ex); + } + downloadToFile(Serial.stringify(save, null, 2), name, "text/plain"); }; Save.onSave.add(handler); try { - SugarCube.Save.base64.save(); + Save.base64.save(); } finally { Save.onSave.delete(handler); } @@ -120,6 +126,6 @@ App.Debug.dumpGameState = function() { App.Debug.slaveSummaryText = function(idx) { let span = document.createElement("span"); - span.appendChild(App.UI.SlaveSummary.render(V.slaves[idx])); + span.appendChild(App.UI.SlaveSummary.render(getSlaves()[idx])); return span.outerHTML; }; diff --git a/src/descriptions/arcologyDescription.js b/src/descriptions/arcologyDescription.js index 8c78e751bd5f696cc9b5bf372c9926113aa5b904..529fe2853987a8a51419ab6de77f21f97700a183 100644 --- a/src/descriptions/arcologyDescription.js +++ b/src/descriptions/arcologyDescription.js @@ -962,7 +962,7 @@ App.Desc.playerArcology = function(lastElement) { return buffer.join(" "); } - const citizenCount = `${num(V.ACitizens)} citizens and ${num(V.ASlaves + V.slaves.length)} slaves live in ${A.name}.`; + const citizenCount = `${num(V.ACitizens)} citizens and ${num(V.ASlaves + getSlaves().length)} slaves live in ${A.name}.`; function fsLaws() { let buffer = []; diff --git a/src/descriptions/familySummaries.js b/src/descriptions/familySummaries.js index b75e03cf9338cc5076b5a32f72876f91a0f331b6..6b523495ee6544b152d8d48ab2217dc8f800a418 100644 --- a/src/descriptions/familySummaries.js +++ b/src/descriptions/familySummaries.js @@ -126,7 +126,7 @@ App.Desc.family = (function() { r.push(`${He} was `, familySpan(`born from `, knownSlave(slave.mother, allowLinks), `'s`), ` fertile womb.`); } - let children = V.slaves.filter((s) => slave.ID === s.father && slave.ID === s.mother); + let children = getSlaves().filter((s) => slave.ID === s.father && slave.ID === s.mother); const isSoleParent = children.length > 0; if (children.length > 2) { r.push(He, familySpan(`is the sole parent of `, slaveListToText(children, allowLinks), `.`)); @@ -136,7 +136,7 @@ App.Desc.family = (function() { r.push(He, familySpan(`is the sole parent of a single slave of yours: `, slaveListToText(children, allowLinks), `.`)); } - children = V.slaves.filter((s) => slave.ID === s.father && slave.ID !== s.mother); + children = getSlaves().filter((s) => slave.ID === s.father && slave.ID !== s.mother); if (children.length > 2) { r.push(He, familySpan(`fathered `, slaveListToText(children, allowLinks), `${isSoleParent ? " with other mothers" : ""}.`)); } else if (children.length > 1) { @@ -145,7 +145,7 @@ App.Desc.family = (function() { r.push(He, familySpan(`fathered a single slave of yours${isSoleParent ? " with another mother" : ""}: `, slaveListToText(children, allowLinks), `.`)); } - children = V.slaves.filter((s) => slave.ID === s.mother && slave.ID !== s.father); + children = getSlaves().filter((s) => slave.ID === s.mother && slave.ID !== s.father); if (children.length > 2) { r.push(He, familySpan(`gave birth to `, slaveListToText(children, allowLinks), `${isSoleParent ? " with other fathers" : ""}.`)); } else if (children.length > 1) { @@ -313,7 +313,7 @@ App.Desc.family = (function() { } /* grandchild - determines how many grandchildren the current slave has */ - children = V.slaves.filter((s) => isGrandparentP(s, slave)); + children = getSlaves().filter((s) => isGrandparentP(s, slave)); if (children.length > 0) { r.push(`${He} has`); if (children.length > 2) { @@ -327,7 +327,7 @@ App.Desc.family = (function() { /* PC aunt and uncle - determines how many aunts and uncles you have */ if (isAunt(V.PC, slave)) { - const {m: uncles, f: aunts} = splitBySex(V.slaves.filter((s) => s.ID !== slave.ID && isAunt(V.PC, s))); + const {m: uncles, f: aunts} = splitBySex(getSlaves().filter((s) => s.ID !== slave.ID && isAunt(V.PC, s))); r.push(`${He} is`); if (slave.genes === "XX") { @@ -346,7 +346,7 @@ App.Desc.family = (function() { } /* aunt and uncle - determines how many aunts and uncles a slave has*/ - const {m: uncles, f: aunts} = splitBySex(V.slaves.filter((s) => isAunt(slave, s))); + const {m: uncles, f: aunts} = splitBySex(getSlaves().filter((s) => isAunt(slave, s))); if (aunts.length > 0) { r.push(`${He} has`); @@ -372,7 +372,7 @@ App.Desc.family = (function() { /* PC niece and nephew - determines how many nieces and nephews you have*/ if (isAunt(slave, V.PC)) { const {m: nephews, f: nieces} = - splitBySex(V.slaves.filter((s) => s.ID !== slave.ID && isAunt(s, V.PC))); + splitBySex(getSlaves().filter((s) => s.ID !== slave.ID && isAunt(s, V.PC))); r.push(`${He} is`); if (slave.genes === "XX") { @@ -391,7 +391,7 @@ App.Desc.family = (function() { } /* niece and nephew - determines how many nieces and nephews a slave has*/ - const {m: nephews, f: nieces} = splitBySex(V.slaves.filter((s) => isAunt(s, slave))); + const {m: nephews, f: nieces} = splitBySex(getSlaves().filter((s) => isAunt(s, slave))); if (nieces.length > 0) { r.push(`${He} has`); @@ -422,7 +422,7 @@ App.Desc.family = (function() { let halfBrothers = []; let cousins = []; - for (const s of V.slaves) { + for (const s of getSlaves()) { let sisterCheck = areSisters(s, slave); if (sisterCheck === 1) { twins.push(s); @@ -552,7 +552,7 @@ App.Desc.family = (function() { if (V.showDistantRelatives) { /* PC cousin - determines how many cousins you have*/ if (areCousins(slave, V.PC)) { - const PCcousins = V.slaves.filter((s) => s.ID !== slave.ID && areCousins(V.PC, s)); + const PCcousins = getSlaves().filter((s) => s.ID !== slave.ID && areCousins(V.PC, s)); r.push(`${He} is`); if (PCcousins.length > 0) { r.push(familySpan(`your cousin along with `, slaveListToText(PCcousins, allowLinks), `.`)); @@ -620,7 +620,7 @@ App.Desc.family = (function() { parents.push(V.missingTable[V.PC.father]); } } - parents = parents.concat(V.slaves.filter((s) => isParentP(V.PC, s))); + parents = parents.concat(getSlaves().filter((s) => isParentP(V.PC, s))); if (parents.length > 1) { r.push(`<br>Your parents are `, familySpan(knownSlave(parents[0].ID, allowLinks), ` and `, knownSlave(parents[1].ID, allowLinks), `.`)); @@ -636,7 +636,7 @@ App.Desc.family = (function() { /* Player aunts and uncles */ if (V.showDistantRelatives) { - const {m: uncles, f: aunts} = splitBySex(V.slaves.filter((s) => isAunt(V.PC, s))); + const {m: uncles, f: aunts} = splitBySex(getSlaves().filter((s) => isAunt(V.PC, s))); if (aunts.length > 0) { r.push(`<br>You have`); @@ -667,7 +667,7 @@ App.Desc.family = (function() { let halfBrothers = []; let cousins = []; - for (const s of V.slaves) { + for (const s of getSlaves()) { let sisterCheck = areSisters(s, V.PC); if (sisterCheck === 1) { twins.push(s); @@ -729,7 +729,7 @@ App.Desc.family = (function() { /* Player nieces and nephews */ if (V.showDistantRelatives) { - const {m: nephews, f: nieces} = splitBySex(V.slaves.filter((s) => isAunt(s, V.PC))); + const {m: nephews, f: nieces} = splitBySex(getSlaves().filter((s) => isAunt(s, V.PC))); if (nieces.length > 0) { r.push(`<br>You have`); @@ -754,27 +754,27 @@ App.Desc.family = (function() { } /* Player is sole parent */ - let children = V.slaves.filter((s) => s.father === V.PC.ID && s.mother === V.PC.ID); + let children = getSlaves().filter((s) => s.father === V.PC.ID && s.mother === V.PC.ID); if (children.length > 0) { r.push(`<br>You are the sole parent of ${num(children.length)} of your slaves, `, familySpan(slaveListToText(children, allowLinks), `.`)); } const isSoleParent = children.length > 0; /* Player is Father, lists children you fathered */ - children = V.slaves.filter((s) => s.father === V.PC.ID && s.mother !== V.PC.ID); + children = getSlaves().filter((s) => s.father === V.PC.ID && s.mother !== V.PC.ID); if (children.length > 0) { r.push(`<br>You fathered ${num(children.length)} of your slaves${isSoleParent ? " with other mothers" : ''}, `, familySpan(slaveListToText(children, allowLinks), `.`)); } /* Player is Mother, lists birthed children */ - children = V.slaves.filter((s) => s.mother === V.PC.ID && s.father !== V.PC.ID); + children = getSlaves().filter((s) => s.mother === V.PC.ID && s.father !== V.PC.ID); if (children.length > 0) { r.push(`<br>You gave birth to ${num(children.length)} of your slaves${isSoleParent ? " who had other fathers" : ''}, `, familySpan(slaveListToText(children, allowLinks), `.`)); } /* Player is grandparent */ if (V.showDistantRelatives) { - children = V.slaves.filter((s) => isGrandparentP(s, V.PC)); + children = getSlaves().filter((s) => isGrandparentP(s, V.PC)); if (children.length > 0) { r.push(`<br>You have ${num(children.length)} grandchildren as your slaves, `, familySpan(slaveListToText(children, allowLinks), `.`)); } diff --git a/src/descriptions/officeDescription.js b/src/descriptions/officeDescription.js index cab86ea0efe694e7b70c5e40f41e75738ce9be2c..1a11a807303621355c34704acab41f1dd9d2e449 100644 --- a/src/descriptions/officeDescription.js +++ b/src/descriptions/officeDescription.js @@ -60,7 +60,7 @@ App.Desc.officeDescription = function(lastElement) { r.push(`A corner of your desk`); } r.push(`is piled with sample merchandise from the campaign promoting your club.`); - const clubSlaves = V.slaves.filter(s => s.assignment === Job.CLUB); + const clubSlaves = getSlaves().filter(s => s.assignment === Job.CLUB); if (clubSlaves.length > 0) { const modeledSlave = clubSlaves.random(); const {He, his} = getPronouns(modeledSlave); @@ -198,7 +198,7 @@ App.Desc.officeDescription = function(lastElement) { } r.push(`is piled with sample merchandise from the campaign promoting ${V.brothelName}.`); } - const brothelSlaves = V.slaves.filter(s => s.assignment === Job.BROTHEL); + const brothelSlaves = getSlaves().filter(s => s.assignment === Job.BROTHEL); if (brothelSlaves.length > 0) { const modeledSlave = brothelSlaves.random(); const {he, his} = getPronouns(modeledSlave); @@ -294,13 +294,14 @@ App.Desc.officeDescription = function(lastElement) { const r = []; r.push("Next to your desk is a sturdy black leather couch. All the walls on this floor are glass, so you can see your"); - if (V.slaves.length > 50) { + const slavesLength = getSlaves().length; + if (slavesLength > 50) { r.push(`innumerable`); - } else if (V.slaves.length > 20) { + } else if (slavesLength > 20) { r.push(`many`); - } else if (V.slaves.length > 10) { + } else if (slavesLength > 10) { r.push(`numerous`); - } else if (V.slaves.length > 5) { + } else if (slavesLength > 5) { r.push(`handful of`); } else { r.push(`few`); diff --git a/src/endWeek/economics/reputation.js b/src/endWeek/economics/reputation.js index 7aa9041acbf85e44d19cebc79ecc9815485b31ba..eab84baaf942dfe416d0e75ec7a4a63eaad25d04 100644 --- a/src/endWeek/economics/reputation.js +++ b/src/endWeek/economics/reputation.js @@ -14,10 +14,10 @@ App.EndWeek.reputation = function() { if (V.arcologies[0].FSChattelReligionistCreed === 1) { r.push(`${V.arcologies[0].name} keeps the creed of the ${V.nicaea.name}. The faithful`); if (V.nicaea.achievement === "slaves") { - if (V.slaves.length > 50) { + if (getSlaves().length > 50) { r.push(`<span class="green">strongly approve</span> of the large`); FutureSocieties.Change("Chattel Religionist", 5); - } else if (V.slaves.length > 20) { + } else if (getSlaves().length > 20) { r.push(`<span class="green">approve</span> of the good`); FutureSocieties.Change("Chattel Religionist", 2); } else { @@ -720,7 +720,7 @@ App.EndWeek.reputation = function() { r.push(`Society <span class="green">approves</span> of how you are providing for the defense of the state, as should all citizens of the new Rome.`); FutureSocieties.Change("Roman Revivalist", V.mercenaries); } - if (V.slaves.length > 20 && V.cash > 50000) { + if (getSlaves().length > 20 && V.cash > 50000) { r.push(`Society <span class="green">strongly approves</span> of your wealth and prosperity, fit goals for the`); if (V.PC.customTitle) { r.push(`${V.PC.customTitle}`); @@ -766,7 +766,7 @@ App.EndWeek.reputation = function() { r.push(`Society <span class="green">approves</span> of your strong militarism and elite mercenaries, as your tradition of Imperial conquest glorifies military success above all else.`); FutureSocieties.Change("Neo-Imperialist", V.mercenaries); } - if (V.slaves.length > 20 && V.cash > 50000) { + if (getSlaves().length > 20 && V.cash > 50000) { r.push(`Society <span class="green">strongly approves</span> of your great wealth and prosperity, as is only fitting for an`); if (V.PC.customTitle) { r.push(`${V.PC.customTitle}.`); @@ -792,7 +792,7 @@ App.EndWeek.reputation = function() { FutureSocieties.Change("Neo-Imperialist", 2); } } else if (FutureSocieties.isActive('FSEgyptianRevivalist')) { - const racialVarieties = new Set(V.slaves.map((s) => s.race)); + const racialVarieties = new Set(getSlaves().map((s) => s.race)); if (racialVarieties.size > 4) { r.push(`Society <span class="green">strongly approves</span> of how you own a cornucopia of different races, which advances the ancient Egyptian ideal of cosmopolitan sex slavery.`); FutureSocieties.Change("Egyptian Revivalist", 5); @@ -803,7 +803,7 @@ App.EndWeek.reputation = function() { } } else if (FutureSocieties.isActive('FSEdoRevivalist')) { const threshold = Math.trunc(V.rep / 2000); - if (V.slaves.filter(s => [Job.CLUB, Job.DJ, Job.PUBLIC].includes(s.assignment) || (s.assignment === Job.RECRUITER && V.recruiterTarget === "other arcologies" && V.arcologies[0].influenceTarget !== -1)).length <= threshold) { + if (getSlaves().filter(s => [Job.CLUB, Job.DJ, Job.PUBLIC].includes(s.assignment) || (s.assignment === Job.RECRUITER && V.recruiterTarget === "other arcologies" && V.arcologies[0].influenceTarget !== -1)).length <= threshold) { r.push(`Society <span class="red">disapproves</span> of your failure to provide for cultural development by offering public servants or club slaves in a number that befits your reputation.`); FutureSocieties.Change("Edo Revivalist", -2); } else { @@ -876,22 +876,23 @@ App.EndWeek.reputation = function() { } // 200 is probably a bit ridiculous side, but might as well give a fun little reward for it - if (V.slaves.length >= 200) { + const slavesLength = getSlaves().length; + if (slavesLength >= 200) { r.push(`Society is in <span class="green">awe</span> with the sheer size of your stable of slaves.`); FutureSocieties.Change("Antebellum Revivalist", 25); - } else if (V.slaves.length >= 100) { + } else if (slavesLength >= 100) { r.push(`Society is <span class="green">impressed</span> with the number of slaves you own.`); FutureSocieties.Change("Antebellum Revivalist", 10); - } else if (V.slaves.length >= 50) { + } else if (slavesLength >= 50) { r.push(`Society holds <span class="green">great respect</span> for the number of slaves you own.`); FutureSocieties.Change("Antebellum Revivalist", 5); - } else if (V.slaves.length >= 25) { + } else if (slavesLength >= 25) { r.push(`Society <span class="green">approves</span> of the number of slaves you own.`); FutureSocieties.Change("Antebellum Revivalist", 3); - } else if (V.slaves.length >= 10) { + } else if (slavesLength >= 10) { r.push(`Society <span class="green">slightly approves</span> of the number of slaves you own.`); FutureSocieties.Change("Antebellum Revivalist", 1); - } else if (V.slaves.length >= 5) { + } else if (slavesLength >= 5) { r.push(`Society neither approves or disapproves of the size of your stable of slaves, but would respectively approve or disapprove if it grew or shrank.`); } else { r.push(`Society finds it <span class="green">strange</span> for someone of your stature to own so few slaves.`); diff --git a/src/endWeek/endWeek.js b/src/endWeek/endWeek.js index 51977908dbd2eb8455f976f3c414e1c9a7c71a1e..02ce128478c22a0345beda910eeef4efde031aee 100644 --- a/src/endWeek/endWeek.js +++ b/src/endWeek/endWeek.js @@ -9,7 +9,7 @@ globalThis.endWeek = (function() { // globals setup resetSlaveMarkets(); - for (const s of V.slaves) { + for (const s of getSlaves()) { slavePrep(s); } setUseWeights(); @@ -309,7 +309,7 @@ globalThis.endWeek = (function() { } function advance() { - if (V.slaves.length < 1) { + if (getSlaves().length < 1) { V.gameover = "no slaves"; Engine.play("Gameover"); } else if (V.arcologies[0].ownership < V.arcologies[0].minority) { diff --git a/src/endWeek/endWeekAnim.js b/src/endWeek/endWeekAnim.js index e331ef0ed53780009c6cef187fd4675fe6cd5d7d..1829252902c537f8e3b627acc77b49c7ff34d81d 100644 --- a/src/endWeek/endWeekAnim.js +++ b/src/endWeek/endWeekAnim.js @@ -6,7 +6,7 @@ App.UI.EndWeekAnim = (function() { infoDiv = $(` <div class="endweek-titleblock"> <div class="endweek-maintitle">Processing week ${V.week}...</div> - <div class="endweek-subtitle">${V.arcologies[0].name} | ${V.slaves.length} slaves</div> + <div class="endweek-subtitle">${V.arcologies[0].name} | ${getSlaves().length} slaves</div> </div> `); } diff --git a/src/endWeek/events/expire.js b/src/endWeek/events/expire.js index 193856b04974b9b516a33e73bc6763b285dcb3a3..e227008808f866408a9063321827f3cd6b733127 100644 --- a/src/endWeek/events/expire.js +++ b/src/endWeek/events/expire.js @@ -5,7 +5,7 @@ App.Events.SEExpiration = class SEExpiration extends App.Events.BaseEvent { /** Custom casting: all expiring slaves are cast automatically. If no slaves are cast, casting fails and the event does not run. */ castActors() { - this.actors = V.slaves.filter(s => s.indenture === 0).map(s => s.ID); + this.actors = getSlaves().filter(s => s.indenture === 0).map(s => s.ID); return this.actors.length > 0; } @@ -60,7 +60,7 @@ App.Events.SEExpiration = class SEExpiration extends App.Events.BaseEvent { V.lowerClass++; let seed = 0; - for (const seeXp of V.slaves.filter(s => s.devotion <= 20)) { + for (const seeXp of getSlaves().filter(s => s.devotion <= 20)) { seed = 1; seeXp.devotion--; } diff --git a/src/endWeek/events/retire.js b/src/endWeek/events/retire.js index c1bab25e017a6335c3d1067b0d03223ec6855671..c28677675bb312314221be051bafc602d22749f6 100644 --- a/src/endWeek/events/retire.js +++ b/src/endWeek/events/retire.js @@ -5,7 +5,7 @@ App.Events.SERetire = class SERetire extends App.Events.BaseEvent { /** Custom casting: all slaves ready for retirement are cast automatically. if no slaves are cast, casting fails and the event does not run. */ castActors() { - this.actors = V.slaves.filter(s => retirementReady(s)).map(s => s.ID); + this.actors = getSlaves().filter(s => retirementReady(s)).map(s => s.ID); return this.actors.length > 0; } @@ -68,7 +68,7 @@ App.Events.retire = function(originalSlave, artRenderer) { if (V.policies.retirement.fate === "citizen") { r.push(`in a way that will fill the rest of your property with envy and <span class="mediumaquamarine">trust.</span>`); - for (const s of V.slaves) { + for (const s of getSlaves()) { s.trust += 3; } if (lover) { @@ -326,7 +326,7 @@ App.Events.retire = function(originalSlave, artRenderer) { } } else if (V.policies.retirement.fate === "bioreactor") { r.push(`in a way that will inevitably fill the rest of your property with <span class="gold">fear.</span>`); - for (const s of V.slaves) { + for (const s of getSlaves()) { s.trust -= 3; } @@ -375,7 +375,7 @@ App.Events.retire = function(originalSlave, artRenderer) { V.menialBioreactors += 1; } else if (V.policies.retirement.fate === "arcade") { r.push(`in a way that will inevitably fill the rest of your property with <span class="gold">fear.</span>`); - for (const s of V.slaves) { + for (const s of getSlaves()) { s.trust -= 3; } diff --git a/src/endWeek/healthFunctions.js b/src/endWeek/healthFunctions.js index c8dd4cfbe10fc463c57cd9ec95b84afa70729df4..9b642482f03ee57a933d36f188983d72cb25efed 100644 --- a/src/endWeek/healthFunctions.js +++ b/src/endWeek/healthFunctions.js @@ -298,7 +298,7 @@ globalThis.nurseEffectiveness = function(slave) { const clinicScreening = V.clinicRegularCheckups || 0; if (S.Nurse) { const nurseSkill = App.Data.Careers.Leader.nurse.includes(S.Nurse.career) ? 200 : S.Nurse.skill.nurse; - let nurseEffectiveness = Math.trunc((nurseSkill * clinicUpgrade / Math.max((App.Entity.facilities.clinic.employeesIDs().size * 10 + (V.slaves.length * 2) * clinicScreening), 1)) * 20); + let nurseEffectiveness = Math.trunc((nurseSkill * clinicUpgrade / Math.max((App.Entity.facilities.clinic.employeesIDs().size * 10 + (getSlaves().length * 2) * clinicScreening), 1)) * 20); if (H.illness > 1 && slave.assignment === Job.CLINIC) { if (nurseEffectiveness < 20) { return nurseEffectiveness; diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js index 2aa0ee7e961ec8e36aacbcc15d71b450a4736af9..3b596471e3e03778b0b20f6cc45f0dd5fc3dbb17 100644 --- a/src/endWeek/nextWeek/nextWeek.js +++ b/src/endWeek/nextWeek/nextWeek.js @@ -8,7 +8,7 @@ App.EndWeek.nextWeek = function() { if (rival && V.rival.prosperity !== 0) { V.rival.prosperity = rival.prosperity; } else if (!rival) { - if (V.slaves.filter(s => s.newGamePlus === 0 && s.origin.includes("$He was once an arcology owner like yourself.")).length > 0) { + if (getSlaves().filter(s => s.newGamePlus === 0 && s.origin.includes("$He was once an arcology owner like yourself.")).length > 0) { V.rival.state = 5; } else if (V.plot > 0 && V.rival.prosperity > 0) { if (V.arcologies.length > 1) { @@ -175,7 +175,7 @@ App.EndWeek.nextWeek = function() { V.pornStars[genre.fameVar].p1count = 0; } } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { ageSlaveWeeks(slave); if (slave.indenture > 0) { slave.indenture -= 1; @@ -454,7 +454,7 @@ App.EndWeek.nextWeek = function() { while (isTemporaryImage()) { await sleep(); } - V.slaves.forEach(s => { + getSlaves().forEach(s => { if ((V.week - s.weekAcquired) % V.aiAutoGenFrequency === 0 && !s.custom.aiAutoRegenExclude){ App.Art.GenAI.staticCache.updateSlave(s, null, false) .catch(error => { diff --git a/src/endWeek/player/prHealth.js b/src/endWeek/player/prHealth.js index 909628ed8e9d10ab45788f91e6dd902124f8c08f..efd12cd48eb771d38d0cea343c8254688ecebf35 100644 --- a/src/endWeek/player/prHealth.js +++ b/src/endWeek/player/prHealth.js @@ -203,9 +203,9 @@ App.EndWeek.Player.health = function(PC = V.PC) { * then personal attention targets, * and lastly, anything in the penthouse. */ - const sexPartners = V.slaves.filter(s => App.Utils.sexAllowed(PC, s) && isSlaveAvailable(s)); - const fucktoys = V.slaves.filter(s => [Job.FUCKTOY, Job.MASTERSUITE, Job.CONCUBINE].includes(s.assignment)); - const wives = V.slaves.filter(s => s.relationship === -3); + const sexPartners = getSlaves().filter(s => App.Utils.sexAllowed(PC, s) && isSlaveAvailable(s)); + const fucktoys = getSlaves().filter(s => [Job.FUCKTOY, Job.MASTERSUITE, Job.CONCUBINE].includes(s.assignment)); + const wives = getSlaves().filter(s => s.relationship === -3); if (PCH.illness === 0 && wives.length > 0) { for (const other of wives.filter(s => s.health.illness > 1)) { if (catchesIllness(20)) { diff --git a/src/endWeek/player/prLongTermPhysicalEffects.js b/src/endWeek/player/prLongTermPhysicalEffects.js index f842e9754c3a19fa687036df1d291a9991f61902..c0b9bc691bef13f000ed4e682eddb44001a28a64 100644 --- a/src/endWeek/player/prLongTermPhysicalEffects.js +++ b/src/endWeek/player/prLongTermPhysicalEffects.js @@ -8,7 +8,7 @@ App.EndWeek.Player.longTermPhysicalEffects = function(PC = V.PC) { const boobSize = App.Medicine.fleshSize(PC, 'boobs'); const buttSize = App.Medicine.fleshSize(PC, 'butt'); const faceValue = PC.face - PC.faceImplant; - const averageDicking = V.slaves.filter(s => canAchieveErection(s) && isSlaveAvailable(s) && ((V.policies.sexualOpenness === 1 && s.devotion > 20 && App.Utils.sexAllowed(V.PC, s)) || s.toyHole === ToyHole.DICK)); + const averageDicking = getSlaves().filter(s => canAchieveErection(s) && isSlaveAvailable(s) && ((V.policies.sexualOpenness === 1 && s.devotion > 20 && App.Utils.sexAllowed(V.PC, s)) || s.toyHole === ToyHole.DICK)); const isNull = PC.dick === 0 && PC.vagina === -1; teeth(); @@ -305,7 +305,7 @@ App.EndWeek.Player.longTermPhysicalEffects = function(PC = V.PC) { } function sexualSatisfaction() { - const sexPartners = V.slaves.filter(s => App.Utils.sexAllowed(V.PC, s) && isSlaveAvailable(s) && s.assignment !== Job.FUCKTOY).shuffle(); + const sexPartners = getSlaves().filter(s => App.Utils.sexAllowed(V.PC, s) && isSlaveAvailable(s) && s.assignment !== Job.FUCKTOY).shuffle(); const wives = sexPartners.filter(s => s.relationship === -3); if (V.debugMode) { r.push(`Need: ${PC.need}.`); @@ -402,7 +402,7 @@ App.EndWeek.Player.longTermPhysicalEffects = function(PC = V.PC) { } PC.lusty = 0; // Needs more holes to fuck, or more dedicated fucktoys. - const fuckpitSlaves = V.slaves.filter(s => s.assignment === Job.MASTERSUITE || s.assignment === Job.CONCUBINE || (s.assignment === Job.FUCKTOY && (canWalk(s) || (canMove(s) && s.rules.mobility === "permissive"))) && s.rules.release.master !== 0); + const fuckpitSlaves = getSlaves().filter(s => s.assignment === Job.MASTERSUITE || s.assignment === Job.CONCUBINE || (s.assignment === Job.FUCKTOY && (canWalk(s) || (canMove(s) && s.rules.mobility === "permissive"))) && s.rules.release.master !== 0); if (V.masterSuiteUpgradeLuxury === 2 && fuckpitSlaves.length > 1 && !isPlayerFrigid()) { let fuckpitSex = Math.ceil(V.PC.energy / 2); r.push(`Whenever you feel the urge for sexual release building and have the time to slip away, you head back to ${V.masterSuiteName} to slide into the fuckpit orgy to sate your lust.`); diff --git a/src/endWeek/player/prPregnancy.js b/src/endWeek/player/prPregnancy.js index a02026bf19916b5e5f7079b7a4c703017ddae116..f8e0b6e511f74052949a2c27d7302a1f5a3b2055 100644 --- a/src/endWeek/player/prPregnancy.js +++ b/src/endWeek/player/prPregnancy.js @@ -515,9 +515,9 @@ App.EndWeek.Player.pregnancy = function(PC = V.PC) { let eligibleSlaves; if (V.policies.sexualOpenness === 1) { - eligibleSlaves = V.slaves.filter(s => canImpreg(V.PC, s) && App.Utils.sexAllowed(V.PC, s) && isSlaveAvailable(s) && canAchieveErection(s) && s.devotion > 20 && raceIsAcceptable); + eligibleSlaves = getSlaves().filter(s => canImpreg(V.PC, s) && App.Utils.sexAllowed(V.PC, s) && isSlaveAvailable(s) && canAchieveErection(s) && s.devotion > 20 && raceIsAcceptable); } else { - eligibleSlaves = V.slaves.filter(s => canImpreg(V.PC, s) && isSlaveAvailable(s) && s.toyHole === ToyHole.DICK); + eligibleSlaves = getSlaves().filter(s => canImpreg(V.PC, s) && isSlaveAvailable(s) && s.toyHole === ToyHole.DICK); } const dadHash = eligibleSlaves.reduce((acc, cur, i) => Object.assign(acc, {[i]: score(cur)}), {}); const chosenDadIndex = hashChoice(dadHash); @@ -527,7 +527,7 @@ App.EndWeek.Player.pregnancy = function(PC = V.PC) { } if (canGetPregnant(PC) && !onBedRest(PC, true) && !isPCCareerInCategory("servant")) { // Sperm mod leavings around the penthouse. Gives servants more of a point too. - let slobs = V.slaves.filter(s => isSlaveAvailable(s) && s.geneMods.aggressiveSperm === 1 && (s.fetish === Fetish.MINDBROKEN || s.energy > 95 || (s.devotion < -20 && s.trust > 20) || (s.intelligence + s.intelligenceImplant < -10))); + let slobs = getSlaves().filter(s => isSlaveAvailable(s) && s.geneMods.aggressiveSperm === 1 && (s.fetish === Fetish.MINDBROKEN || s.energy > 95 || (s.devotion < -20 && s.trust > 20) || (s.intelligence + s.intelligenceImplant < -10))); if (slobs.length > (totalServantCapacity() / 5)) { tryKnockMeUp(PC, -50, 2, slobs.random()); } diff --git a/src/endWeek/reports/incubatorReport.js b/src/endWeek/reports/incubatorReport.js index 5b5caafdb814501d64e3dc29cd465f7730157bc9..0105260cb584210ef2fd3a51a413ac72210f2016 100644 --- a/src/endWeek/reports/incubatorReport.js +++ b/src/endWeek/reports/incubatorReport.js @@ -3,8 +3,9 @@ */ App.EndWeek.incubatorReport = function() { const frag = document.createDocumentFragment(); + let incubator = App.Entity.facilities.incubator; - if (V.incubator.capacity === 0) { + if (incubator.capacity === 0) { return { before: frag, slaves: [], @@ -13,6 +14,8 @@ App.EndWeek.incubatorReport = function() { } V.incubator.readySlaves = 0; + const speedUpgrade = incubator.upgrade('speed'); + for (const tank of V.incubator.tanks) { const entry = App.UI.DOM.appendNewElement('p', frag); let r = []; @@ -26,13 +29,13 @@ App.EndWeek.incubatorReport = function() { } } if (tank.incubatorSettings.growTime > 0) { - tank.incubatorSettings.growTime -= V.incubator.upgrade.speed; + tank.incubatorSettings.growTime -= speedUpgrade; r.push(`<span class="pink">${tank.slaveName}'s</span> growth is currently being accelerated. ${He}`); - if (Math.ceil(tank.incubatorSettings.growTime/V.incubator.upgrade.speed) <= 0) { + if (Math.ceil(tank.incubatorSettings.growTime/speedUpgrade) <= 0) { r.push(`is <span class="lime">ready for release.</span> ${He} will be ejected from ${his} tank upon your approach.`); V.incubator.readySlaves = 1; } else { - r.push(`will be ready for release in about ${Math.ceil(tank.incubatorSettings.growTime/V.incubator.upgrade.speed)} weeks.`); + r.push(`will be ready for release in about ${Math.ceil(tank.incubatorSettings.growTime/speedUpgrade)} weeks.`); } } else { r.push(`<span class="pink">${tank.slaveName}</span> is <span class="lime">ready for release.</span> ${He} will be ejected from ${his} tank upon your approach.`); @@ -41,46 +44,46 @@ App.EndWeek.incubatorReport = function() { App.Events.addNode(entry, r, "div"); r = []; - if (V.incubator.upgrade.weight === 1) { + if (incubator.upgrade('weight') === 1) { if (tank.incubatorSettings.weight === 1) { if (tank.weight < 200) { - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.weight += 70; - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.weight += 40; - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.weight += 20; - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.weight += 10; - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.weight += 5; } } r.push(`The weight monitoring systems are overloading ${his} intake causing <span class="red">rapid weight gain.</span>`); } else if (tank.incubatorSettings.weight === 2) { if (tank.weight > 10) { - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.weight -= 30; - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.weight -= 10; - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.weight -= 5; - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.weight -= 2; - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.weight -= 1; } r.push(`The weight monitoring systems detect ${he} is overweight and <span class="green">decrease ${his} caloric intake.</span>`); } else if (tank.weight < -10) { - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.weight += 30; - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.weight += 10; - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.weight += 5; - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.weight += 2; - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.weight += 1; } r.push(`The weight monitoring systems detect ${he} is underweight and <span class="green">increase ${his} caloric intake.</span>`); @@ -102,46 +105,46 @@ App.EndWeek.incubatorReport = function() { App.Events.addNode(entry, r, "div"); r = []; - if (V.incubator.upgrade.muscles === 1) { + if (incubator.upgrade('muscles') === 1) { if (tank.incubatorSettings.muscles === 2) { if (tank.muscles < 100) { - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.muscles += 70; - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.muscles += 40; - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.muscles += 20; - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.muscles += 10; - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.muscles += 5; } } r.push(`The strength monitoring systems are overloading ${him} with steroids causing <span class="green">rapid muscle development.</span>`); } else if (tank.incubatorSettings.muscles === 1) { if (tank.muscles > 10) { - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.muscles -= 30; - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.muscles -= 10; - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.muscles -= 5; - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.muscles -= 2; - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.muscles--; } r.push(`The strength monitoring systems detect ${he} is overly muscular and <span class="green">decrease ${his} steroid dosage.</span>`); } else if (tank.muscles < -10) { - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.muscles += 30; - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.muscles += 10; - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.muscles += 5; - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.muscles += 2; - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.muscles++; } r.push(`The strength monitoring systems detect ${he} is weak and <span class="green">increase ${his} steroid dosage.</span>`); @@ -163,7 +166,7 @@ App.EndWeek.incubatorReport = function() { App.Events.addNode(entry, r, "div"); r = []; - if (V.incubator.upgrade.growthStims === 1 && tank.incubatorSettings.growthStims !== 0) { + if (incubator.upgrade('growthStims') === 1 && tank.incubatorSettings.growthStims !== 0) { let heightLimit = Math.clamp((Height.forAge(tank.natural.height, tank) * 1.25), 0, 274); let heightLimitAge = Height.forAge(tank.natural.height, tank); if (tank.geneticQuirks.dwarfism === 2 && tank.geneticQuirks.gigantism !== 2) { @@ -193,28 +196,28 @@ App.EndWeek.incubatorReport = function() { } else { if (tank.incubatorSettings.weight >= 1 && tank.incubatorSettings.muscles <= 1 && tank.incubatorSettings.reproduction <= 1) { r.push(`The monitoring system floods ${his} body with growth stimulants. ${His} caloric intake and expenditure rates are ideal for maximum response, causing <span class="green">explosive growth.</span>`); - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.height += random(3, 6); - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.height += random(2, 5); - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.height += random(1, 4); - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.height += random(1, 3); - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.height += random(1, 2); } } else { r.push(`The monitoring system floods ${his} body with growth stimulants, causing <span class="green">a sharp increase in growth rate.</span>`); - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.height += random(2, 5); - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.height += random(1, 4); - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.height += random(1, 3); - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.height += random(1, 2); - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.height += random(0, 1); } } @@ -226,29 +229,29 @@ App.EndWeek.incubatorReport = function() { } else if (tank.height > heightLimitAge) { r.push(`The monitoring systems detect ${he} is near the expected height, so it carefully regulates stimulant injections to <span class="yellow">maintain ${his} current stature.</span>`); if (random(1, 10) === 10) { - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.height += random(1, 4); - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.height += random(1, 3); - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.height += random(1, 2); - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.height += random(0, 1); - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.height += random(0, 1); } } } else { r.push(`The monitoring systems detect ${his} body is capable of developing more rapidly and <span class="green">increase ${his} growth stimulant dosage.</span>`); - if (V.incubator.upgrade.speed === 52) { + if (speedUpgrade === 52) { tank.height += random(1, 4); - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { tank.height += random(1, 3); - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { tank.height += random(1, 2); - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { tank.height += random(0, 1); - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { tank.height += random(0, 1); } } @@ -260,7 +263,7 @@ App.EndWeek.incubatorReport = function() { App.Events.addNode(entry, r, "div"); r = []; - if (V.incubator.upgrade.reproduction === 1) { + if (incubator.upgrade('reproduction') === 1) { const rearQuirk = tank.geneticQuirks.rearLipedema === 2 ? 2 : 1; const rearLimit = 20; // current maximum ass size, used to avoid reporting failed growth if (tank.incubatorSettings.reproduction === 2) { @@ -276,7 +279,7 @@ App.EndWeek.incubatorReport = function() { if (tank.geneMods.NCS === 1) { /* NCS blocks hormonal growth of all secondary sexual characteristics */ r.push(`${His} <span class="orange">NCS blocks all growth</span> despite the excess estrogen-laced growth hormones flooding ${his} body.`); - } else if (V.incubator.upgrade.speed === 52) { + } else if (speedUpgrade === 52) { if (tank.boobs < 8000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 2000; @@ -289,7 +292,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt += 4; } - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { if (tank.boobs < 8000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 500; @@ -302,7 +305,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt += 3; } - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { if (tank.boobs < 8000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 200; @@ -315,7 +318,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear grow fatter.</span>`); tank.butt += 2; } - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { if (tank.boobs < 8000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 100; @@ -328,7 +331,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt++; } - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { if (tank.boobs < 8000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 100; @@ -350,7 +353,7 @@ App.EndWeek.incubatorReport = function() { if (tank.geneMods.NCS === 1) { /* NCS blocks hormonal growth of all secondary sexual characteristics */ r.push(`${His} <span class="orange">NCS blocks all growth</span> despite the excess testosterone-laced growth hormones flooding ${his} body.`); - } else if (V.incubator.upgrade.speed === 52) { + } else if (speedUpgrade === 52) { if (tank.balls < 40) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls += 16; @@ -359,7 +362,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick += 4; } - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { if (tank.balls < 40 && random(1, 100) > 10) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls += 9; @@ -368,7 +371,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick += 3; } - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { if (tank.balls < 40 && random(1, 100) > 20) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls += 4; @@ -377,7 +380,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick += 2; } - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { if (tank.balls < 40 && random(1, 100) > 30) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls += 2; @@ -386,7 +389,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick++; } - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { if (tank.balls < 40 && random(1, 100) > 30) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls++; @@ -408,7 +411,7 @@ App.EndWeek.incubatorReport = function() { if (tank.geneMods.NCS === 1) { /* NCS blocks hormonal growth of all secondary sexual characteristics */ r.push(`${His} <span class="orange">NCS blocks all growth</span> despite the excess estrogen-laced growth hormones flooding ${his} body.`); - } else if (V.incubator.upgrade.speed === 52) { + } else if (speedUpgrade === 52) { if (tank.boobs < 4000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 1000; @@ -421,7 +424,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt += 3; } - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { if (tank.boobs < 4000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 500; @@ -434,7 +437,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt++; } - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { if (tank.boobs < 4000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 200; @@ -447,7 +450,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt++; } - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { if (tank.boobs < 4000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 100; @@ -460,7 +463,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt++; } - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { if (tank.boobs < 4000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 100; @@ -482,7 +485,7 @@ App.EndWeek.incubatorReport = function() { if (tank.geneMods.NCS === 1) { /* NCS blocks hormonal growth of all secondary sexual characteristics */ r.push(`${His} <span class="orange">NCS blocks all growth</span> despite the excess testosterone-laced growth hormones flooding ${his} body.`); - } else if (V.incubator.upgrade.speed === 52) { + } else if (speedUpgrade === 52) { if (tank.balls < 10) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls += 3; @@ -491,7 +494,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick += 2; } - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { if (tank.balls < 10 && random(1, 100) > 10) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls += 2; @@ -500,7 +503,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick++; } - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { if (tank.balls < 10 && random(1, 100) > 20) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls++; @@ -509,7 +512,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick++; } - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { if (tank.balls < 10 && random(1, 100) > 30) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls++; @@ -518,7 +521,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick++; } - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { if (tank.balls < 10 && random(1, 100) > 30) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls++; @@ -540,7 +543,7 @@ App.EndWeek.incubatorReport = function() { if (tank.geneMods.NCS === 1) { /* NCS blocks hormonal growth of all secondary sexual characteristics */ r.push(`${His} <span class="orange">NCS blocks all growth</span> despite the excess estrogen-laced growth hormones flooding ${his} body.`); - } else if (V.incubator.upgrade.speed === 52) { + } else if (speedUpgrade === 52) { if (tank.boobs < 2000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 700; @@ -553,7 +556,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt += 2; } - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { if (tank.boobs < 2000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 200; @@ -566,7 +569,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt++; } - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { if (tank.boobs < 2000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly balloon ${his} breasts.</span>`); tank.boobs += 50; @@ -579,7 +582,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt++; } - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { if (tank.boobs < 2000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly grow ${his} breasts.</span>`); tank.boobs += 20; @@ -592,7 +595,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess estrogen-laced growth hormones <span class="green">cause ${his} rear to grow fatter.</span>`); tank.butt++; } - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { if (tank.boobs < 2000) { r.push(`The excess estrogen-laced growth hormones <span class="green">rapidly grow ${his} breasts.</span>`); tank.boobs += 10; @@ -614,7 +617,7 @@ App.EndWeek.incubatorReport = function() { if (tank.geneMods.NCS === 1) { /* NCS blocks hormonal growth of all secondary sexual characteristics */ r.push(`${His} <span class="orange">NCS blocks all growth</span> despite the excess testosterone-laced growth hormones flooding ${his} body.`); - } else if (V.incubator.upgrade.speed === 52) { + } else if (speedUpgrade === 52) { if (tank.balls < 6) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to grow for extra cum production.</span>`); tank.balls += 2; @@ -623,7 +626,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick++; } - } else if (V.incubator.upgrade.speed === 18) { + } else if (speedUpgrade === 18) { if (tank.balls < 6 && random(1, 100) > 50) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to grow for extra cum production.</span>`); tank.balls++; @@ -632,7 +635,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick++; } - } else if (V.incubator.upgrade.speed === 9) { + } else if (speedUpgrade === 9) { if (tank.balls < 6 && random(1, 100) > 60) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to balloon for extra cum production.</span>`); tank.balls++; @@ -641,7 +644,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick += 2; } - } else if (V.incubator.upgrade.speed === 6) { + } else if (speedUpgrade === 6) { if (tank.balls < 6 && random(1, 100) > 70) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to grow for extra cum production.</span>`); tank.balls++; @@ -650,7 +653,7 @@ App.EndWeek.incubatorReport = function() { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} penis to swell.</span>`); tank.dick++; } - } else if (V.incubator.upgrade.speed === 5) { + } else if (speedUpgrade === 5) { if (tank.balls < 6 && random(1, 100) > 80) { r.push(`The excess testosterone-laced growth hormones <span class="green">cause ${his} balls to grow for extra cum production.</span>`); tank.balls++; @@ -793,18 +796,18 @@ App.EndWeek.incubatorReport = function() { } else { r.push(`The incubator is working on adapting ${his} abdomen and reproductive organs for future pregnancies.`); - let weekAdapt = tank.incubatorSettings.pregAdaptationInWeek * V.incubator.upgrade.speed; + let weekAdapt = tank.incubatorSettings.pregAdaptationInWeek * speedUpgrade; if (isNaN(weekAdapt)) { /* NaN check AFTER multiply operation, against it result is critical here. Need to be absolutely sure about this operation, not about just tank property itself. This give me two very unpleasant hours to catch this */ tank.incubatorSettings.pregAdaptationInWeek = (15000 / 2000 - tank.pregAdaptation) / tank.incubatorSettings.growTime; } - weekAdapt = tank.incubatorSettings.pregAdaptationInWeek * V.incubator.upgrade.speed; + weekAdapt = tank.incubatorSettings.pregAdaptationInWeek * speedUpgrade; /* Now it should be fine */ weekAdapt *= 1 + (tank.incubatorSettings.reproduction / 5); weekAdapt *= 1 + (tank.hormoneBalance / 1500); tank.pregAdaptation += weekAdapt; /* here goes side effect from intense and extreme settings: */ - if (random(1, 100) <= (tank.incubatorSettings.pregAdaptationPower - 1) * (V.incubator.upgrade.speed / 2 + 1)) { + if (random(1, 100) <= (tank.incubatorSettings.pregAdaptationPower - 1) * (speedUpgrade / 2 + 1)) { switch (random(1, 9)) { /* side effect selection*/ case 1: if (tank.preg > -2) { diff --git a/src/endWeek/reports/penthouseReport.js b/src/endWeek/reports/penthouseReport.js index ac3732e14735f7012265277bb3317dc355d34074..f41cf1adc65bd2b5f4495e79da9f53716e0ee7eb 100644 --- a/src/endWeek/reports/penthouseReport.js +++ b/src/endWeek/reports/penthouseReport.js @@ -4,7 +4,7 @@ App.EndWeek.penthouseReport = function() { const beforeFrag = document.createElement("p"); - const penthouseSlaves = V.slaves.filter(s => assignmentVisible(s) || !App.EndWeek.saVars.slaveCheckedIn.includes(s.ID)); + const penthouseSlaves = getSlaves().filter(s => assignmentVisible(s) || !App.EndWeek.saVars.slaveCheckedIn.includes(s.ID)); const HGSuiteSlaves = App.Utils.jobForAssignment(Job.HEADGIRLSUITE).employees(); const hgSlave = HGSuiteSlaves.length > 0 ? App.SlaveAssignment.reportSlave(HGSuiteSlaves[0]) : null; const HGTrainSlavesIDs = slavesToTrain(); diff --git a/src/endWeek/reports/rulesAssistantReport.js b/src/endWeek/reports/rulesAssistantReport.js index 0bfd98b6bbdb4e472730b49e52d48c469ef6ed33..093f6c352f7f4028e354a167d86af0fb0d1b34b9 100644 --- a/src/endWeek/reports/rulesAssistantReport.js +++ b/src/endWeek/reports/rulesAssistantReport.js @@ -4,7 +4,7 @@ App.EndWeek.rulesAssistantReport = function() { const frag = $(document.createDocumentFragment()); const lines = []; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.useRulesAssistant === 1) { try { lines.push(DefaultRules(slave)); diff --git a/src/endWeek/saBeYourHeadGirl.js b/src/endWeek/saBeYourHeadGirl.js index 66a43046fbce594ab89dd901f1de5db6332de270..81083950201f72a6a3fbef53989b807c819bcafe 100644 --- a/src/endWeek/saBeYourHeadGirl.js +++ b/src/endWeek/saBeYourHeadGirl.js @@ -239,7 +239,7 @@ App.SlaveAssignment.beYourHeadGirl = function saBeYourHeadGirl(slave) { if (slave.dick > 0 && V.universalRulesImpregnation === "HG" && canPenetrate(slave)) { r.push(`${He} finds ${his} duty to impregnate slaves at will sexually satisfying.`); slave.need = 0; - } else if (V.slaves.length > 5) { + } else if (getSlaves().length > 5) { r.push(`Seldom a day goes by without ${him} finding an outlet among your slaves for ${his} sexual desires.`); slave.need = 0; } diff --git a/src/endWeek/saDevotion.js b/src/endWeek/saDevotion.js index eb3a1096e8cad114d3d4c79d184906ca4dcaa176..6c6aa9181e3c64bd1beaab8cf5ff0e5ba352b7e3 100644 --- a/src/endWeek/saDevotion.js +++ b/src/endWeek/saDevotion.js @@ -729,7 +729,7 @@ App.SlaveAssignment.devotion = function saDevotion(slave) { * */ function collectiveSpirit(slave) { - if (V.slaves.length > 3) { + if (getSlaves().length > 3) { let collectiveTrustEffect = 0; let collectiveDevotionEffect = 0; if (V.enduringDevotion > 50) { diff --git a/src/endWeek/saGuardYou.js b/src/endWeek/saGuardYou.js index 72bee0a0bbe39c15d9adf225f1ae112af3cdf1d2..c37b52888ab08b9b6ba3a70b21611ad419fe090c 100644 --- a/src/endWeek/saGuardYou.js +++ b/src/endWeek/saGuardYou.js @@ -292,7 +292,7 @@ App.SlaveAssignment.guardYou = function saGuardYou(slave) { r.push(`<span class="yellow">${He} is ${toSentence(requirements.filter(s => s[0]).map(s => s[1]))} to train any successors.</span>`); } } else { - const successorCandidates = V.slaves.filter(s => (assignmentVisible(s) || [Job.CONCUBINE, Job.WARDEN, Job.HEADGIRL, Job.QUARTER, Job.MASTERSUITE].includes(s.assignment)) && bodyguardSuccessorEligible(s)); + const successorCandidates = getSlaves().filter(s => (assignmentVisible(s) || [Job.CONCUBINE, Job.WARDEN, Job.HEADGIRL, Job.QUARTER, Job.MASTERSUITE].includes(s.assignment)) && bodyguardSuccessorEligible(s)); const combatSkilled = successorCandidates.filter(s => s.skill.combat > 60); r.push(`${He}'s confident in ${his} martial skills, but smart enough to know that${slave.geneMods.immortality > 0 ? `, while technically immortal, ${he} isn't invincible` : ` ${he} isn't immortal`}, and devoted enough to worry about who will protect you should ${he} die.`); diff --git a/src/endWeek/saPleaseYou.js b/src/endWeek/saPleaseYou.js index f645816137dfa423a4b6e6d6a79cc22eab44cb8b..2a2c1a81a14e74b830a9503360249b04d6a75bd3 100644 --- a/src/endWeek/saPleaseYou.js +++ b/src/endWeek/saPleaseYou.js @@ -4430,7 +4430,7 @@ App.SlaveAssignment.pleaseYou = function saPleaseYou(slave) { function familyBonus(slave) { let multiplier = 0; const isFucktoy = (s) => [Job.CONCUBINE, Job.MASTERSUITE, Job.FUCKTOY].includes(s.assignment); - const fucktoys = V.slaves.filter(s => isFucktoy(s)); + const fucktoys = getSlaves().filter(s => isFucktoy(s)); if (areRelated(V.PC, slave)) { r.push(`Keeping your own ${relativeTerm(V.PC, slave)} as a personal ${canFuck ? `fucktoy` : `bedwarmer`} leaves quite a public impression.`); diff --git a/src/endWeek/saPregnancy.js b/src/endWeek/saPregnancy.js index 10589109b5dca5a2ba2721219f26f167947818f0..8f868f1e8f67dc6d86580e90fede48a84e5b800a 100644 --- a/src/endWeek/saPregnancy.js +++ b/src/endWeek/saPregnancy.js @@ -901,7 +901,7 @@ App.SlaveAssignment.pregnancy = function saPregnancy(slave) { */ function impregnation(slave) { const conceptionSeed = random(1, 100); - let Stud = slaveStateById(V.StudID); // May be null! + let Stud = getSlave(V.StudID); // May be undefined! const studIgnoresRules = (Stud && V.universalRulesImpregnation === "Stud" && Stud.career === "a breeding bull" && Stud.fetish === Fetish.MINDBROKEN && canMove(Stud)); const pussy = (slave.mpreg === 1 ? "asspussy" : "pussy"); let satisfiedPregFetish = 0; @@ -1746,7 +1746,7 @@ App.SlaveAssignment.pregnancy = function saPregnancy(slave) { } } } else if (V.universalRulesImpregnation === "Slaves" && slave.preg === 0 && slave.inseminationExclude !== 1 && ((![Job.CONCUBINE, Job.MASTERSUITE, Job.FUCKTOY].includes(slave.assignment) && slave.relationship !== -3 ) || V.universalHGImpregnateMasterSuiteToggle === 1)) { - const potentialSlaveFathers = V.slaves.filter(s => s.ID !== slave.ID && canBreed(slave, s) && ![Job.AGENT, Job.AGENTPARTNER].includes(s.assignment)); + const potentialSlaveFathers = getSlaves().filter(s => s.ID !== slave.ID && canBreed(slave, s) && ![Job.AGENT, Job.AGENTPARTNER].includes(s.assignment)); if (potentialSlaveFathers.length === 0) { r.push(`${slave.slaveName} is ripe for breeding, but you have no other slaves to harvest sperm from to use on ${him}.`); } else { @@ -1956,7 +1956,7 @@ App.SlaveAssignment.pregnancy = function saPregnancy(slave) { if (pcCanKnockUpSlave(slave)) { pcDoKnockUpSlave(slave); } else { // look for a random father among master suite slaves - const msSlaves = V.slaves.filter((s) => s.assignment === Job.MASTERSUITE).shuffle(); + const msSlaves = getSlaves().filter((s) => s.assignment === Job.MASTERSUITE).shuffle(); for (const msSlave of msSlaves) { if (canImpreg(slave, msSlave) && App.Utils.sexAllowed(slave, msSlave)) { /* catch for self-impregnation */ @@ -2057,7 +2057,7 @@ App.SlaveAssignment.pregnancy = function saPregnancy(slave) { } else if (random(1, 100) > 95 && slave.eggType === "human" && slave.trust > 20 && slave.relationship.isBetween(-2, 4) && (slave.devotion <= 20 || slave.energy > 95)) { // 5% chance of impregnation by random citizen in defiant and nymphomaniac slaves. pregSource = -2; } else { - const potentialFathers = V.slaves.filter(s => canImpreg(slave, s)).shuffle(); + const potentialFathers = getSlaves().filter(s => canImpreg(slave, s)).shuffle(); const motherDisobeys = disobedience(slave) > random(0, 100); for (const father of potentialFathers) { if (father.ID === slave.ID) { /* self-impregnation check */ @@ -2092,7 +2092,7 @@ App.SlaveAssignment.pregnancy = function saPregnancy(slave) { } /* closes random chance and non-zero sex acts check */ if (canGetPregnant(slave) && canWalk(slave) && isSlaveAvailable(slave) && (V.personalAttention.task !== PersonalAttention.MAID || onBedRest(V.PC))) { // Sperm mod leavings around the penthouse. Gives servants more of a point too. - let slobs = V.slaves.filter(s => canFemImpreg(slave, s) && isSlaveAvailable(s) && s.geneMods.aggressiveSperm === 1 && (s.fetish === Fetish.MINDBROKEN || s.energy > 95 || (s.devotion < -20 && s.trust > 20) || (s.intelligence + s.intelligenceImplant < -10))); + let slobs = getSlaves().filter(s => canFemImpreg(slave, s) && isSlaveAvailable(s) && s.geneMods.aggressiveSperm === 1 && (s.fetish === Fetish.MINDBROKEN || s.energy > 95 || (s.devotion < -20 && s.trust > 20) || (s.intelligence + s.intelligenceImplant < -10))); if (slobs.length > (totalServantCapacity() / 5)) { tryKnockMeUp(slave, -50, 2, slobs.random()); } diff --git a/src/endWeek/saRecruitGirls.js b/src/endWeek/saRecruitGirls.js index 6e1a9f1e621c42251f598d507ee1539908218e63..743dd0c643bbf53d00c7bd8bf9ed995d1b6f8764 100644 --- a/src/endWeek/saRecruitGirls.js +++ b/src/endWeek/saRecruitGirls.js @@ -15,6 +15,7 @@ App.SlaveAssignment.recruitGirls = function recruitGirls(slave) { const targetArcologyInfo = targetArcology ? new App.Utils.Arcology(targetArcology) : null; const totalInt = slave.intelligence + slave.intelligenceImplant; + const slavesLength = getSlaves().length; const { he, him, his, himself, girl, woman, women, He, His, @@ -26,7 +27,7 @@ App.SlaveAssignment.recruitGirls = function recruitGirls(slave) { tooTired(); } else if (V.recruiterTarget === "other arcologies") { influenceNeighbor(slave); - } else if (V.slaves.length < idleTarget) { + } else if (slavesLength < idleTarget) { recruiting(slave); } else { idlePublicity(slave); @@ -91,7 +92,7 @@ App.SlaveAssignment.recruitGirls = function recruitGirls(slave) { delete V.oldRecruiterTarget; } } - } else if (V.slaves.length < idleTarget) { + } else if (slavesLength < idleTarget) { r.push(`better prepare to manipulate ${V.recruiterTarget} into enslavement.`); } else { r.push(`prepare methods to better support your cultural directions.`); @@ -890,7 +891,7 @@ App.SlaveAssignment.recruitGirls = function recruitGirls(slave) { const modScore = SlaveStatsChecker.modScore(slave); r.push(`tries to maintain ${his} network of prospects without promising anyone a space in ${arcology.name}, since you already control`); - if (V.slaves.length > idleTarget) { + if (slavesLength > idleTarget) { r.push(`more sex slaves than`); } else { r.push(`as many sex slaves as`); @@ -1678,7 +1679,7 @@ App.SlaveAssignment.recruitGirls = function recruitGirls(slave) { FSmatch++; seed += 5; arcology.FSAntebellumRevivalist += 0.02 * V.FSSingleSlaveRep; - } else if (V.slaves.length < 10) { + } else if (slavesLength < 10) { pushFS(`${He} wants to show-off your Penthouse to try and garner interest, but can't hide just how empty it is on camera.`); } else if (V.servantsQuarters === 0) { pushFS(`${He} doesn't feel right selling the idea of Southern hospitality without a stable of servants to cater to any would-be visitors.`); diff --git a/src/endWeek/saRelationships.js b/src/endWeek/saRelationships.js index 8297ded19eac2691cc8bf14044eda1055e2e0f2d..eb8067b0059f1b05efa9f8a12a9773d8d3325539 100644 --- a/src/endWeek/saRelationships.js +++ b/src/endWeek/saRelationships.js @@ -140,13 +140,13 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { slave.relationship = -2; } } else if (slave.career === "a Futanari Sister" && slave.rules.relationship === "permissive") { - const potentialFriend = V.slaves.find((s) => s.career === "a Futanari Sister" && s.rules.relationship === "permissive" && canStartFriendship(slave, s)); + const potentialFriend = getSlaves().find((s) => s.career === "a Futanari Sister" && s.rules.relationship === "permissive" && canStartFriendship(slave, s)); if (potentialFriend !== undefined) { r.push(`${slave.slaveName} greets ${potentialFriend.slaveName} with joy. It's not clear whether they ever knew each other during their lives as Futanari Sisters, but it seems that they believe themselves to be in a relationship by simple virtue of having been Sisters. In any case, ${slave.slaveName} and ${potentialFriend.slaveName} <span class="relationship">become inseparable lovers</span> instantly, as though there's no possibility they would do anything else. They're even surprised when other slaves ask them about it; it's as though they're unaware that other possibilities even exist.`); startFriendship(slave, potentialFriend, 4); } } else if (slave.origin === "You were acquainted with $him before you were an arcology owner; your rival tried to use $him to manipulate you, but you rescued $him." && V.rival.duration > 20 && !["Intellectual Dependency", "Paternalism", "Racial Supremacism", "Slave Professionalism"].includes(V.rival.FS.name) && slave.newGamePlus === 0) { - const potentialFriend = V.slaves.find((s) => (s.prestigeDesc === "You bankrupted and enslaved $him in revenge for $his part in the attack on your arcology by the Daughters of Liberty." && s.fuckdoll === 0 && s.fetish !== Fetish.MINDBROKEN && s.newGamePlus === 0)); + const potentialFriend = getSlaves().find((s) => (s.prestigeDesc === "You bankrupted and enslaved $him in revenge for $his part in the attack on your arcology by the Daughters of Liberty." && s.fuckdoll === 0 && s.fetish !== Fetish.MINDBROKEN && s.newGamePlus === 0)); if (potentialFriend !== undefined) { r.push(`${slave.slaveName} greets ${potentialFriend.slaveName} with joy, happy to see a familiar face again. Without any regard to you, <span class="relationship">they continue their prior relationship.</span>`); if (potentialFriend.relationship > 0) { // remove me with multi-friend system @@ -168,7 +168,7 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { const manipulationSkill = (slave.devotion + slave.trust + ((slave.intelligence + slave.intelligenceImplant) / 10)); // intended for defiant slaves to ingrain themselves with facility heads if (randomSeed > 75) { let resentment = 0; - for (const potentialFriend of V.slaves) { + for (const potentialFriend of getSlaves()) { if (canStartFriendship(slave, potentialFriend) && potentialFriend.assignment !== Job.CONFINEMENT) { const {him2, He2} = getPronouns(potentialFriend).appendSuffix("2"); if (potentialFriend.ID === V.MadamID && slave.assignment === Job.BROTHEL) { @@ -297,11 +297,11 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { } } } - } else if (mutualChildren(slave, potentialFriend, V.slaves) > 0) { + } else if (mutualChildren(slave, potentialFriend, getSlaves()) > 0) { if (App.Utils.sexAllowed(slave, potentialFriend)) { if (potentialFriend.rules.relationship === "permissive") { r.push(`${slave.slaveName} and ${potentialFriend.slaveName} have`); - if (mutualChildren(slave, potentialFriend, V.slaves) === 1) { + if (mutualChildren(slave, potentialFriend, getSlaves()) === 1) { r.push(`a child`); } else { r.push(`children`); @@ -631,7 +631,7 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { r.push(`They build on their family relationship and become <span class="relationship">best friends.</span>`); slave.relationship++; friend.relationship = slave.relationship; - } else if (mutualChildren(slave, friend, V.slaves) > 0 && (random(1, 100) < (50 + (10 * mutualChildren(slave, friend, V.slaves))))) { + } else if (mutualChildren(slave, friend, getSlaves()) > 0 && (random(1, 100) < (50 + (10 * mutualChildren(slave, friend, getSlaves()))))) { r.push(`Hoping to benefit their mutual children, they draw closer together, becoming <span class="relationship">best friends.</span>`); slave.relationship++; friend.relationship = slave.relationship; @@ -683,7 +683,7 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { friend.relationshipTarget = 0; slave.relationshipTarget = 0; } else if (App.Utils.sexAllowed(slave, friend) && slave.rules.relationship !== "just friends" && friend.rules.relationship !== "just friends") { - if (mutualChildren(slave, friend, V.slaves) > 0 && random(1, 100) < (50 + (10 * mutualChildren(slave, friend, V.slaves)) + seed)) { + if (mutualChildren(slave, friend, getSlaves()) > 0 && random(1, 100) < (50 + (10 * mutualChildren(slave, friend, getSlaves())) + seed)) { r.push(`Having already had kids together, their relationship turns sexual once again, turning them into <span class="relationship">friends with benefits.</span>`); slave.relationship++; friend.relationship = slave.relationship; @@ -747,7 +747,7 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { r.push(`${He} gets deep, perverse satisfaction by constant commission of the sin of incest, which is extreme enough to appease even ${his} appetite for transgression. ${His} incestuous relationship becomes <span class="relationship">romantically emotional</span> as well as physical and familial.`); slave.relationship++; friend.relationship = slave.relationship; - } else if (mutualChildren(slave, friend, V.slaves) > 0 && random(1, 100) < (50 + (10 * mutualChildren(slave, friend, V.slaves)) + seed)) { + } else if (mutualChildren(slave, friend, getSlaves()) > 0 && random(1, 100) < (50 + (10 * mutualChildren(slave, friend, getSlaves())) + seed)) { r.push(`Between their children and common sexual flings, they begin seeing each other as a traditional couple. Their relationship becomes <span class="relationship">strongly emotional</span> as well as physical.`); if (slave.pregSource === friend.ID && friend.pregSource === slave.ID && slave.pregKnown === 1 && friend.pregKnown === 1) { r.push(`Not very surprising, since they both have the other's child growing in their womb.`); @@ -1252,7 +1252,7 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { const overwhelmed = 5; if (slave.trust <= 95) { - let relatives = V.slaves.filter((s) => areRelated(slave, s)); + let relatives = getSlaves().filter((s) => areRelated(slave, s)); if (slave.trust < -20) { /** @type {Array<FC.SlaveState>} */ const worriedAboutChildren = []; diff --git a/src/endWeek/saRivalries.js b/src/endWeek/saRivalries.js index f1d74be68b520d4a91454f515016e4f0ac1ea686..81bf8140793b7012188898ce3e2ef3e6c666d9a2 100644 --- a/src/endWeek/saRivalries.js +++ b/src/endWeek/saRivalries.js @@ -43,7 +43,7 @@ App.SlaveAssignment.rivalries = function saRivalries(slave) { function generateRivalry(slave) { let foundRival = 0; - for (const potentialRival of V.slaves) { + for (const potentialRival of getSlaves()) { if (canStartRivalry(potentialRival) && potentialRival.ID !== slave.ID && potentialRival.ID !== slave.relationshipTarget) { if (potentialRival.origBodyOwnerID === slave.ID && potentialRival.devotion > 0 && slave.devotion < -30) { r.push(`${slave.slaveName} loathes that ${SlaveFullName(potentialRival)} is using <span class="em">${his}</span> body to benefit you and makes it abundantly clear every chance ${he} gets. <span class="rivalry inc">They start to dislike each other.</span>`); diff --git a/src/endWeek/saRules.js b/src/endWeek/saRules.js index 3aa9c1a768da46eebdde12978436cfa9b3f0dbb7..838298b29247bd66a6f1fad167b2efb17541722e 100644 --- a/src/endWeek/saRules.js +++ b/src/endWeek/saRules.js @@ -1653,7 +1653,7 @@ App.SlaveAssignment.rules = function(slave) { r.push(App.SlaveAssignment.rewardAndPunishment(slave)); break; case Job.QUARTER: - slave.need -= V.slaves.length * 5; + slave.need -= getSlaves().length * 5; if (slave.devotion < -50) { r.push(`is so unhappy that ${he} has little interest in getting off.`); slave.need = 0; diff --git a/src/endWeek/saRulesFunctions.js b/src/endWeek/saRulesFunctions.js index b5037478ab5763edfcf14fdaf4c7a768f828cf79..82bb6396d0b568bcb0bf08d2f8f5487dc0e8db24 100644 --- a/src/endWeek/saRulesFunctions.js +++ b/src/endWeek/saRulesFunctions.js @@ -1653,7 +1653,7 @@ App.EndWeek.Rules.consentRules = function(slave) { case Job.QUARTER: case Job.HOUSE: return Object.assign(obj, { - peers: V.slaves, // ALL THE SLAVES! + peers: getSlaves(), // ALL THE SLAVES! (Not all the slaves, so hopefully thats okay -FranklyGeorge) emptyPlace: "your penthouse" // always, even for servants' quarter slaves }); case Job.MILKMAID: diff --git a/src/endWeek/saServeThePublic.js b/src/endWeek/saServeThePublic.js index 31ff534440300fb300aa3b71394b3bcac72dfd88..cc4bbf7a343160141bddca7ad8f5ba1de7db55f0 100644 --- a/src/endWeek/saServeThePublic.js +++ b/src/endWeek/saServeThePublic.js @@ -590,7 +590,7 @@ App.SlaveAssignment.serveThePublic = function saServeThePublic(slave) { } if (totalRelatives(slave) > 0) { - let children = V.slaves.filter((s) => areRelated(slave, s) && (s.assignment === slave.assignment)); + let children = getSlaves().filter((s) => areRelated(slave, s) && (s.assignment === slave.assignment)); if (children.length > 1) { r += ` Since ${his} relatives, ${toSentence(children.map(s => s.slaveName))}, are public sluts too, ${he} earns extra attention.`; } else if (children.length > 0) { diff --git a/src/endWeek/saWhore.js b/src/endWeek/saWhore.js index cade9765463d9d49ac01a63bb74b70949259c322..ec0499760cec4c01e882906f02479ac80d52989e 100644 --- a/src/endWeek/saWhore.js +++ b/src/endWeek/saWhore.js @@ -683,7 +683,7 @@ App.SlaveAssignment.whore = function(slave) { } if (totalRelatives(slave) > 0) { - let children = V.slaves.filter((s) => areRelated(slave, s) && (s.assignment === slave.assignment)); + let children = getSlaves().filter((s) => areRelated(slave, s) && (s.assignment === slave.assignment)); if (children.length > 1) { r += ` Since ${his} relatives, ${toSentence(children.map(s => s.slaveName))}, are selling themselves too, ${he} earns extra ¤ by working with them.`; } else if (children.length > 0) { diff --git a/src/endWeek/slaveAssignmentReport.js b/src/endWeek/slaveAssignmentReport.js index be6d7f9a4f7be95aa1ebb4024203bd1423586c59..fcfb044cc56ae4901f04a6b2a806f788dfa31e87 100644 --- a/src/endWeek/slaveAssignmentReport.js +++ b/src/endWeek/slaveAssignmentReport.js @@ -30,7 +30,7 @@ App.EndWeek.slaveAssignmentReport = function() { const res = document.createDocumentFragment(); /* perform reassignments before generating reports */ - for (const slave of V.slaves) { + for (const slave of getSlaves()) { for (const sk in skillsToTest) { if (_.isNil(slave.skill[sk])) { _printSlaveError(`Reset bad ${skillsToTest[sk]} skill`, slave); @@ -50,7 +50,7 @@ App.EndWeek.slaveAssignmentReport = function() { App.EndWeek.computeSexualServicesModel(res); let slavesWithWorkingDicks = 0; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if ((V.seeDicks > 0) && canPenetrate(slave) && App.Utils.hasNonassignmentSex(slave)) { App.EndWeek.saVars.averageDick += slave.dick; slavesWithWorkingDicks++; @@ -183,7 +183,7 @@ App.EndWeek.slaveAssignmentReport = function() { } } } - } // for (const slave of V.slaves) + } // for (const slave of slaves) // Optimized sperm slaves cumming up the spa pool. if (facilities.spa.established) { @@ -199,7 +199,7 @@ App.EndWeek.slaveAssignmentReport = function() { if (V.HeadGirlID !== 0) { App.EndWeek.saVars.HGEnergy++; - const slave = slaveStateById(V.HeadGirlID); + const slave = S.HeadGirl; if (V.personalAttention.task === PersonalAttention.SUPPORT_HG && !onBedRest(V.PC, true)) { App.EndWeek.saVars.HGEnergy++; if (slave.trust > 95) { @@ -232,7 +232,7 @@ App.EndWeek.slaveAssignmentReport = function() { App.EndWeek.saVars.StudCum += 1; } let studCumLimit = App.EndWeek.saVars.StudCum; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (studCumLimit === 0 || stud.need <= 0) { break; } @@ -268,7 +268,7 @@ App.EndWeek.slaveAssignmentReport = function() { if (V.seeImages && V.seeReportImages) { // agents and partners are not drawn; penthouse partners and the head girl's slave will be drawn via a different mechanism (since they are larger and right-aligned) const undrawnJobs = [Job.AGENT, Job.AGENTPARTNER, Job.HEADGIRLSUITE]; - const drawnSlaveIDs = V.slaves.filter(s => !assignmentVisible(s) && !undrawnJobs.includes(s.assignment)).map(s => s.ID); + const drawnSlaveIDs = getSlaves().filter(s => !assignmentVisible(s) && !undrawnJobs.includes(s.assignment)).map(s => s.ID); // this batch renderer object will be accessible to all the facility reports App.EndWeek.saVars.slaveArt = new App.Art.SlaveArtBatch(drawnSlaveIDs, 0); res.append(App.EndWeek.saVars.slaveArt.writePreamble()); diff --git a/src/events/PESS/pessHeadgirlDickgirl.js b/src/events/PESS/pessHeadgirlDickgirl.js index ececef0edf267893253f629cf9b2f0d54ccd08d6..0f57eff1f7b6a696a49c36e9e462251d0944670e 100644 --- a/src/events/PESS/pessHeadgirlDickgirl.js +++ b/src/events/PESS/pessHeadgirlDickgirl.js @@ -75,7 +75,7 @@ App.Events.pessHeadgirlDickgirl = class pessHeadgirlDickgirl extends App.Events. } r.push(`cheek. In the coming week, no shirker is safe from ${his} wrath. <span class="devotion inc">Every single slave in your penthouse has become better broken to your will.</span>`); seX(S.HeadGirl, "oral", V.PC, "penetrative"); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (assignmentVisible(slave)) { slave.devotion += 2; } diff --git a/src/events/PESS/pessLovingHeadgirl.js b/src/events/PESS/pessLovingHeadgirl.js index 5bec0d6339419fff53ebb0ddb64b437d341fb043..a580c3a48bc915e4494783dff5da3b8f3f47e785 100644 --- a/src/events/PESS/pessLovingHeadgirl.js +++ b/src/events/PESS/pessLovingHeadgirl.js @@ -3,7 +3,7 @@ App.Events.pessLovingHeadgirl = class pessLovingHeadgirl extends App.Events.Base return [ () => !!S.HeadGirl, () => S.HeadGirl.devotion > 95, - () => V.slaves.length > 4 + () => getSlaves().length > 4 ]; } @@ -15,7 +15,7 @@ App.Events.pessLovingHeadgirl = class pessLovingHeadgirl extends App.Events.Base const {title: Master} = getEnunciation(S.HeadGirl); const art = App.UI.DOM.appendNewElement("span", node); App.Events.drawEventArt(art, S.HeadGirl); - const subSlave = V.slaves.find((s) => s.ID !== V.HeadGirlID && s.devotion <= 20); + const subSlave = getSlaves().find((s) => s.ID !== V.HeadGirlID && s.devotion <= 20); App.Events.addParagraph(node, [ `You and`, @@ -153,7 +153,7 @@ App.Events.pessLovingHeadgirl = class pessLovingHeadgirl extends App.Events.Base if (subSlave.anus === 0) { subSlave.anus = 1; } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.devotion += 4; slave.trust -= 4; } diff --git a/src/events/PESS/pessMadamStrategy.js b/src/events/PESS/pessMadamStrategy.js index ad7c7a54144ff644624462a94c0d6e8b255416b0..1b64be91cb403f606117c64c65ad25b7195b933d 100644 --- a/src/events/PESS/pessMadamStrategy.js +++ b/src/events/PESS/pessMadamStrategy.js @@ -29,7 +29,7 @@ App.Events.pessMadamStrategy = class pessMadamStrategy extends App.Events.BaseEv function review() { S.Madam.devotion += 4; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.assignment === Job.BROTHEL) { if (slave.skill.oral < 100) { slave.skill.oral += 5; @@ -47,7 +47,7 @@ App.Events.pessMadamStrategy = class pessMadamStrategy extends App.Events.BaseEv function surgery() { S.Madam.devotion += 4; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.assignment === Job.BROTHEL) { if (slave.boobs < 400) { slave.boobs += 200; diff --git a/src/events/PESS/pessWorriedHeadgirl.js b/src/events/PESS/pessWorriedHeadgirl.js index 514e43e5a3edd223eba32610256bd015f94cf020..aa46839f3d0404e746af016f73776d2cc4293c16 100644 --- a/src/events/PESS/pessWorriedHeadgirl.js +++ b/src/events/PESS/pessWorriedHeadgirl.js @@ -91,7 +91,7 @@ App.Events.pessWorriedHeadgirl = class pessWorriedHeadgirl extends App.Events.Ba r.push(`up`); } r.push(`to look at you, <span class="devotion inc">${his} ${App.Desc.eyesColor(S.HeadGirl)} glittering at the compliment.</span> "Thank you, ${Master}," ${he} murmurs. There's another flash on the horizon, followed by a series of smaller flashes and a low, slowly growing glow as secondaries go off and start a fire. ${S.HeadGirl.slaveName} seems affected, a certain amount of moisture gathering in ${his} eyes, but ${he} turns away to return to ${his} duties when it becomes clear that you intend to keep watching for a while, and aren't going to have sex with ${him} right this minute. ${He} does ${his} best to communicate the new reality to those of your slaves who are obedient enough to understand the truth: though they are slaves, <span class="trust inc">there is safety to be found in slavery.</span>`); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.devotion > 20) { slave.trust += 1; } diff --git a/src/events/PESS/pessWorshipfulImpregnatrix.js b/src/events/PESS/pessWorshipfulImpregnatrix.js index da1e3aba500f3e96df0e5209b0fa18b59ded068e..bfa1903169a3fd497a970d828a007ea528454e02 100644 --- a/src/events/PESS/pessWorshipfulImpregnatrix.js +++ b/src/events/PESS/pessWorshipfulImpregnatrix.js @@ -155,7 +155,7 @@ App.Events.pessWorshipfulImpregnatrix = class pessWorshipfulImpregnatrix extends seX(S.HeadGirl, "anal", V.PC, "penetrative"); } S.HeadGirl.devotion += 5; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (assignmentVisible(slave)) { slave.devotion += 2; } @@ -191,7 +191,7 @@ App.Events.pessWorshipfulImpregnatrix = class pessWorshipfulImpregnatrix extends } r.push(`producing a shiver of pleasure as your fingers massage ${his} scalp. As you cuddle with your Head Girl, you praise ${his} hard work, and tell ${him} that the next generation of sex slaves in the Free Cities will owe a lot to ${him}. They'll learn from ${his} leadership, of course, but they'll also have ${his} genes. ${He} stiffens a little, and there's a slight moisture against your skin as tears begin to run down ${his} cheeks. ${He} cranes ${his} neck up and <span class="devotion inc">kisses you rapturously.</span> ${He} seems to have absorbed a bit of your vision for the future, and over the next couple of days ${he} takes special care to make sure the slaves in your penthouse <span class="trust inc">know their place in the new world you're building.</span>`); S.HeadGirl.devotion += 5; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (assignmentVisible(slave)) { slave.trust += 2; } diff --git a/src/events/PETS/petsAggressiveWardeness.js b/src/events/PETS/petsAggressiveWardeness.js index fd7b68960cac3a282011730b9ab07a6febd6b3a2..33686079b3b2a5a0c4f4820b1f02e8fe9caa2493 100644 --- a/src/events/PETS/petsAggressiveWardeness.js +++ b/src/events/PETS/petsAggressiveWardeness.js @@ -49,7 +49,7 @@ App.Events.petsAggressiveWardeness = class petsAggressiveWardeness extends App.E App.Events.addResponses(node, choices); function encourage() { - V.slaves.forEach(function(s) { + getSlaves().forEach(function(s) { if (s.assignment === Job.CELLBLOCK) { s.devotion += 10; healthDamage(s, 10); @@ -59,7 +59,7 @@ App.Events.petsAggressiveWardeness = class petsAggressiveWardeness extends App.E } function quiet() { - V.slaves.forEach(function(s) { + getSlaves().forEach(function(s) { if (s.assignment === Job.CELLBLOCK) { improveCondition(s, 10); } diff --git a/src/events/PETS/petsNurseMolestation.js b/src/events/PETS/petsNurseMolestation.js index ccf017c45701f6db5866a02c95ca2786cec7b253..62150b8aa648ee36fd2cdae95996d1e761b9f10d 100644 --- a/src/events/PETS/petsNurseMolestation.js +++ b/src/events/PETS/petsNurseMolestation.js @@ -72,7 +72,7 @@ App.Events.petsNurseMolestation = class petsNurseMolestation extends App.Events. seX(S.Nurse, "anal", V.PC, "penetrative"); } actX(S.Nurse, "oral", 20); - V.slaves.forEach(function(s) { + getSlaves().forEach(function(s) { if (s.assignment === Job.CLINIC) { s.trust += 2; } diff --git a/src/events/RE/REBusyBrothel.js b/src/events/RE/REBusyBrothel.js index 326a1891aa016193dd7e7f36052655cd95d463c0..0f4a50b48f99af2b59f31c39083d13e8e2eae07b 100644 --- a/src/events/RE/REBusyBrothel.js +++ b/src/events/RE/REBusyBrothel.js @@ -19,7 +19,7 @@ App.Events.REBusyBrothel = class REBusyBrothel extends App.Events.BaseEvent { function rest() { cashX(-1000, "event"); - for (const slave of V.slaves.filter(s => s.assignment === Job.BROTHEL)) { + for (const slave of getSlaves().filter(s => s.assignment === Job.BROTHEL)) { slave.devotion += 4; slave.health.tired = 0; } @@ -27,7 +27,7 @@ App.Events.REBusyBrothel = class REBusyBrothel extends App.Events.BaseEvent { } function lessons() { cashX(-2000, "event"); - for (const slave of V.slaves.filter(s => s.assignment === Job.BROTHEL)) { + for (const slave of getSlaves().filter(s => s.assignment === Job.BROTHEL)) { slave.lastWeeksCashIncome += 250; slave.lifetimeCashIncome += 250; if (slave.skill.whoring < 100) { @@ -41,7 +41,7 @@ App.Events.REBusyBrothel = class REBusyBrothel extends App.Events.BaseEvent { function promote() { repX(1000, "event"); cashX(-2000, "event"); - for (const slave of V.slaves.filter(s => s.assignment === Job.BROTHEL)) { + for (const slave of getSlaves().filter(s => s.assignment === Job.BROTHEL)) { healthDamage(slave, 10); if (canDoVaginal(slave)) { seX(slave, "vaginal", "public", "penetrative", 5); diff --git a/src/events/RE/REBusyDairy.js b/src/events/RE/REBusyDairy.js index 2f3b27b3a950f4a7c09e46f8f17570dbf7cb8041..de95918106940ea07282053e12e8833df35b708e 100644 --- a/src/events/RE/REBusyDairy.js +++ b/src/events/RE/REBusyDairy.js @@ -23,7 +23,7 @@ App.Events.REBusyDairy = class REBusyDairy extends App.Events.BaseEvent { App.Events.addResponses(node, choices); function share() { - const dairySlaves = V.slaves.filter(s => s.assignment === Job.DAIRY); + const dairySlaves = getSlaves().filter(s => s.assignment === Job.DAIRY); cashX(-1000, "event"); for (const slave of dairySlaves) { slave.devotion += 4; diff --git a/src/events/RE/reArcologyInspection.js b/src/events/RE/reArcologyInspection.js index 8e45cdea4e5d09aa34e5f04393b22776a12372e3..0a4c3847baddcf6ed619e8f7a971cce1a20974e1 100644 --- a/src/events/RE/reArcologyInspection.js +++ b/src/events/RE/reArcologyInspection.js @@ -27,7 +27,7 @@ App.Events.REArcologyInspection = class REArcologyInspection extends App.Events. const {He, him, himself, his, he} = agent ? getPronouns(agent) : getPronouns({pronoun: App.Data.Pronouns.Kind.plural}); const Master = agent ? getEnunciation(agent).title : (V.PC.title ? "Sir" : "Madam"); const BG = S.Bodyguard; - const agentLover = agent ? V.slaves.find(s => (s.ID === agent.relationshipTarget && s.assignment === Job.AGENTPARTNER)) : undefined; + const agentLover = agent ? getSlaves().find(s => (s.ID === agent.relationshipTarget && s.assignment === Job.AGENTPARTNER)) : undefined; App.Events.drawEventArt(node, [BG, agent, agentLover].filter(x => !!x)); diff --git a/src/events/RE/reBoomerang.js b/src/events/RE/reBoomerang.js index 52d9d01eb17ba431e8aa785491bb99bd18f56f4f..e1d8f447aeb9ffb74c6dfefc67490d5ace33fdac 100644 --- a/src/events/RE/reBoomerang.js +++ b/src/events/RE/reBoomerang.js @@ -872,7 +872,7 @@ App.Events.REBoomerang = class REBoomerang extends App.Events.BaseEvent { if (V.boomerangStats.PCfather > 0) { V.PC.father = slave.ID; } - for (const s of V.slaves) { + for (const s of getSlaves()) { if (V.boomerangStats.boomerangMother.includes(s.ID)) { s.mother = slave.ID; } diff --git a/src/events/RE/reBrothelFunction.js b/src/events/RE/reBrothelFunction.js index d4b2e70484abaaf36b6f563652e95ec6520edca1..0938bb755f267bda8bf7dc09c5be11ea2786b55f 100644 --- a/src/events/RE/reBrothelFunction.js +++ b/src/events/RE/reBrothelFunction.js @@ -35,7 +35,7 @@ App.Events.REBrothelFunction = class REBrothelFunction extends App.Events.BaseEv const frag = new DocumentFragment(); let r = []; r.push(`Though you close down ${brothelNameCaps} for a day, it's far from a day off for your hard-working brothel slaves. In the absence of the convenient center for the sale of sexual services that a brothel represents, you disperse them onto the streets to sell their bodies the old fashioned way. At the end of the day you receive a brief message of gratitude from your fellow arcology owner while your whores <span class="devotion inc">appreciate the opportunity to stretch their legs on the street</span> for a change of pace.`); - for (const slave of V.slaves.filter(s => s.assignment === Job.BROTHEL)) { + for (const slave of getSlaves().filter(s => s.assignment === Job.BROTHEL)) { slave.devotion += 4; } cashX(largeCash, "event"); @@ -47,7 +47,7 @@ App.Events.REBrothelFunction = class REBrothelFunction extends App.Events.BaseEv const frag = new DocumentFragment(); let r = []; r.push(`Though a citizen he may be, this serial seducer may have more notches on his proverbial bedpost than even your oldest slaves. Though you are not present to view his mastery of the sexual craft first-hand, the dreamy fucked-out looks of exhaustion and gratified satisfaction painting every single one of your slaves' faces at the end of the day speak volumes. Indeed, all of your brothel slaves with any room for improvement in their whoring skills <span class="skill inc">learn from his skillful coupling,</span> while even those with nothing to learn from him <span class="devotion inc">gain confidence</span> from the intensity of their sexual congress.`); - for (const slave of V.slaves.filter(s => s.assignment === Job.BROTHEL)) { + for (const slave of getSlaves().filter(s => s.assignment === Job.BROTHEL)) { if (slave.skill.whoring < 100) { slave.skill.whoring += 10; } else { @@ -71,7 +71,7 @@ App.Events.REBrothelFunction = class REBrothelFunction extends App.Events.BaseEv const frag = new DocumentFragment(); let r = []; r.push(`Though he was but a boy yesterday, none can say that this newly made man entered his manhood with anything less than a sterling display of enthusiasm and virility, though he is somewhat lacking in general technique. Nevertheless, any man able to fuck his way through an entire brothel of sex slaves and back again is clearly capable of bearing the mantle of citizenry in ${V.arcologies[0].name}. The story of a boy entering manhood in such a spectacular manner spreads rapidly and reflects well in the court of <span class="reputation inc">public opinion,</span> with many citizens recalling their own passage past the age of majority. However, a lifetime of indulgence and spoiling have rendered this new citizen unable to understand the concept of being refused — not that your slaves could refuse him, in any case. His rough treatment has left your poor slave whores <span class="health dec">battered</span> by his brutally selfish lovemaking.`); - for (const slave of V.slaves.filter(s => s.assignment === Job.BROTHEL)) { + for (const slave of getSlaves().filter(s => s.assignment === Job.BROTHEL)) { healthDamage(slave, 5); if (canDoVaginal(slave) && canDoAnal(slave)) { actX(slave, "vaginal"); diff --git a/src/events/RE/reBusyMasterSuite.js b/src/events/RE/reBusyMasterSuite.js index cde28721bf0d117dc4102d5854774d0fdee95edf..b124fea48970951e32272728bd8b1fecf39571df 100644 --- a/src/events/RE/reBusyMasterSuite.js +++ b/src/events/RE/reBusyMasterSuite.js @@ -23,7 +23,7 @@ App.Events.REBusyMasterSuite = class REBusyMasterSuite extends App.Events.BaseEv } execute(node) { - const msSlaves = V.slaves.filter((s) => s.fuckdoll === 0 && s.assignment === Job.MASTERSUITE) + const msSlaves = getSlaves().filter((s) => s.fuckdoll === 0 && s.assignment === Job.MASTERSUITE) .map((s) => { /** @type {Array<FC.SlaveActs|"none">} */ let options = []; diff --git a/src/events/RE/reBusyServantsQuarters.js b/src/events/RE/reBusyServantsQuarters.js index a8be6118ef3c1b9304efdc206fe97685069f82de..c9efe7b90eb6921c6e41b6e04d180a301a54d97e 100644 --- a/src/events/RE/reBusyServantsQuarters.js +++ b/src/events/RE/reBusyServantsQuarters.js @@ -16,7 +16,7 @@ App.Events.REBusyServantsQuarters = class REBusyServantsQuarters extends App.Eve ]); function share() { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.assignment !== Job.QUARTER) { slave.devotion += 4; if (canPenetrate(slave)) { diff --git a/src/events/RE/reRelativeRecruiter.js b/src/events/RE/reRelativeRecruiter.js index ecc82e907b1eccd3ebdea7ed0e1587ad47e3f965..2101790d96ab9c5fa80473f3f9af82b2541ff135 100644 --- a/src/events/RE/reRelativeRecruiter.js +++ b/src/events/RE/reRelativeRecruiter.js @@ -41,7 +41,7 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba /** find all eligible target relatives for a slave; one will be selected randomly (or by cheating) * @param {FC.SlaveState} slave who's doing the recruiting (should be first actor) - * @param {FC.GenePoolRecord} [gp] genepool entry for this slave, if known + * @param {ReadonlyDeep<FC.GenePoolRecord>} [gp] genepool entry for this slave, if known * @returns {string[]} */ _getTargetRelativeChoices(slave, gp) { @@ -608,7 +608,7 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba newSlave.origin = relativeOrigin(); applyBackground(newSlave); if (that.params.relative === "mother") { - newSlave.counter.birthsTotal += V.slaves.reduce((acc, cur) => acc + (sameDad(eventSlave, cur) ? 1 : 0), 0); + newSlave.counter.birthsTotal += getSlaves().reduce((acc, cur) => acc + (sameDad(eventSlave, cur) ? 1 : 0), 0); } applyCommon(newSlave); return newSlave; @@ -621,7 +621,7 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba * @param {number} [parentIDs.father] */ function setUnknownParents(slave, parentIDs = {}) { - const gp = isInGenePool(slave) ? getGenePoolRecord(slave, false, true) : undefined; + const gp = isInGenePool(slave) ? getGenePoolRecordWriteMode(slave) : undefined; if (parentIDs.mother) { slave.mother = parentIDs.mother; @@ -645,7 +645,7 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba switch (that.params.relative) { case "mother": { setUnknownParents(eventSlave, {mother: newSlave.ID} ); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (sameDad(eventSlave, slave)) { setUnknownParents(slave, {mother: newSlave.ID} ); } @@ -654,7 +654,7 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba } case "father": { setUnknownParents(eventSlave, {father: newSlave.ID} ); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (sameMom(eventSlave, slave)) { setUnknownParents(slave, {father: newSlave.ID} ); } @@ -672,7 +672,7 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba } else if (eventSlave.father === 0) { setMissingParents(eventSlave); setUnknownParents(newSlave, {father: eventSlave.father}); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (sameMom(eventSlave, slave)) { setUnknownParents(slave, {father: eventSlave.father}); } @@ -680,7 +680,7 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba } else if (eventSlave.mother === 0) { setMissingParents(eventSlave); setUnknownParents(newSlave, {mother: eventSlave.mother}); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (sameDad(eventSlave, slave)) { setUnknownParents(slave, {mother: eventSlave.mother}); } diff --git a/src/events/RE/reReputedDaughter.js b/src/events/RE/reReputedDaughter.js index 84439dfc8dfb3ae677aa6e232478fb0e30893bd6..5b5aad2cd293cff370ee5f4dea15948077c2ed06 100644 --- a/src/events/RE/reReputedDaughter.js +++ b/src/events/RE/reReputedDaughter.js @@ -27,7 +27,9 @@ App.Events.REReputedDaughter = class REReputedDaughter extends App.Events.BaseEv const {His, He, he, his, him, himself} = getPronouns(slave); const {HeF, heF, hisF, himF, womanF, fatherF} = getNonlocalPronouns(PC.title === 0 && FutureSocieties.isActive("FSGenderRadicalist") ? 0 : 100).appendSuffix('F'); const newAge = Math.max(V.minimumSlaveAge, V.fertilityAge - (V.precociousPuberty ? V.pubertyHormones ? 3 : 1 : 0)); - const rDaughter = GenerateNewSlave("XX", {minAge: newAge, maxAge: newAge, race: "nonslave", disableDisability: 1}); + const rDaughter = GenerateNewSlave("XX", { + minAge: newAge, maxAge: newAge, race: "nonslave", disableDisability: 1 + }); const {HisD, HeD, heD, hisD, himD, girlD, daughterD} = getPronouns(rDaughter).appendSuffix('D'); const kid = rDaughter.actualAge > 12 ? rDaughter.actualAge < 18 ? "teenager" : "young "+ girlD : "kid"; const child = rDaughter.actualAge > 12 ? girlD : "child"; @@ -126,7 +128,7 @@ App.Events.REReputedDaughter = class REReputedDaughter extends App.Events.BaseEv const compensation = 1000 + (Math.min(Math.round(V.cash / 5000), 4) * 500); // from 1,000 to 3,000 const value = 30000 + Math.clamp((Math.round(((slaveCost(rDaughter) - 35000) * .9) / 500) * 500), 0, 30000); // from 30,000 to 60,000 - const canBuy = !V.slaves.some(s => s.origin.includes("disinherited $him and sold $him into slavery") && V.week - s.weekAcquired < 6) && V.seeDicks !== 100; // we don't want a legion of reputed daughters + const canBuy = !getSlaves().some(s => s.origin.includes("disinherited $him and sold $him into slavery") && V.week - s.weekAcquired < 6) && V.seeDicks !== 100; // we don't want a legion of reputed daughters const choices = []; choices.push(V.cash > compensation ? new App.Events.Result(`Offer ${himF} ${cashFormat(compensation)} as financial compensation.`, money) @@ -694,7 +696,7 @@ App.Events.REReputedDaughter = class REReputedDaughter extends App.Events.BaseEv } } r.push(`When they learn what has happened, your other slaves are <span class="devotion inc">glad that you'd protect them</span> from false accusations, although the more rebellious ones feel <span class="defiant inc">they can take advantage of your benevolence.</span>`); - V.slaves.forEach(s => { + getSlaves().forEach(s => { if (s.devotion < -20 && s.trust > 50) { s.devotion--; s.trust += 5; @@ -705,7 +707,7 @@ App.Events.REReputedDaughter = class REReputedDaughter extends App.Events.BaseEv return r; } else if (action === "given" || action === "punished") { r.push(`After learning of what happened to ${slave.slaveName}, <span class="trust dec">your other slaves are afraid</span> that any accusation against them, no matter how fabricated, could have unpredictable consequences. Those not devoted to you begin to have <span class="devotion dec">serious doubts</span> about their futures.`); - V.slaves.forEach(s => { + getSlaves().forEach(s => { s.trust -= 5; if (s.devotion <= 50) { s.devotion -= 5; @@ -755,7 +757,7 @@ App.Events.REReputedDaughter = class REReputedDaughter extends App.Events.BaseEv if (mindbroken) { r.push(`This opinion of you is further tarnished by the fact that ${slave.slaveName} ${exitus ? "was" : "is"} mindbroken and incapable of doing anything wrong on purpose.`); } - V.slaves.forEach(s => { + getSlaves().forEach(s => { s.trust -= (8 + (exitus ? 2 : 0) + (mindbroken ? 1 : 0)); s.devotion -= ((exitus ? 1 : 0) + (mindbroken ? 2 : 0)); if (s.devotion <=51) { diff --git a/src/events/REFS/refsAztecArtifact.js b/src/events/REFS/refsAztecArtifact.js index b5f37989661d99f437df7ac08bfaf16f26901af2..d200227ccae7c192e56017c9a37eec7ed74a941a 100644 --- a/src/events/REFS/refsAztecArtifact.js +++ b/src/events/REFS/refsAztecArtifact.js @@ -62,7 +62,7 @@ App.Events.refsAztecArtifact = class refsAztecArtifact extends App.Events.BaseEv frag.append(`Choose a slave to sacrifice. This slave will die.`); - V.slaves + getSlaves() .filter(s => (s.breedingMark === 0 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || !FutureSocieties.isActive('FSRestart'))) .forEach(slave => { App.Events.addNode(frag, [ diff --git a/src/events/RESS/escapee.js b/src/events/RESS/escapee.js index 343fc2640a99c19ff2abdf318ff2229cd403df6c..e15bc3ab47718197602f3026bdc2553405eeb254 100644 --- a/src/events/RESS/escapee.js +++ b/src/events/RESS/escapee.js @@ -83,7 +83,7 @@ App.Events.RESSEscapee = class RESSEscapee extends App.Events.BaseEvent { t.push(newRumor.weakness()); eventSlave.devotion -= 10; eventSlave.trust += 2; - V.slaves.forEach(function(s) { if (s.devotion <= 20) { s.trust += 8; } }); + getSlaves().forEach(function(s) { if (s.devotion <= 20) { s.trust += 8; } }); return t; } @@ -95,7 +95,7 @@ App.Events.RESSEscapee = class RESSEscapee extends App.Events.BaseEvent { eventSlave.devotion += 4; assignJob(eventSlave, "stay confined"); - V.slaves.forEach(function(s) { if (s.devotion <= 20) { s.trust += 4; } }); + getSlaves().forEach(function(s) { if (s.devotion <= 20) { s.trust += 4; } }); return t; } @@ -107,7 +107,7 @@ App.Events.RESSEscapee = class RESSEscapee extends App.Events.BaseEvent { eventSlave.trust -= 5; healthDamage(eventSlave, 40); - V.slaves.forEach(function(s) { if (s.devotion <= 20) { s.trust -= 5; } }); + getSlaves().forEach(function(s) { if (s.devotion <= 20) { s.trust -= 5; } }); return t; } @@ -121,7 +121,7 @@ App.Events.RESSEscapee = class RESSEscapee extends App.Events.BaseEvent { eventSlave.trust -= 5; eventSlave.heels = 1; surgeryDamage(eventSlave, 10); - V.slaves.forEach(function(s) { if (s.devotion <= 20) { s.trust -= 5; } }); + getSlaves().forEach(function(s) { if (s.devotion <= 20) { s.trust -= 5; } }); return t; } @@ -136,7 +136,7 @@ App.Events.RESSEscapee = class RESSEscapee extends App.Events.BaseEvent { eventSlave.diet = "healthy"; removeLimbs(eventSlave, "all"); surgeryDamage(eventSlave, 40); - V.slaves.forEach(function(s) { if (s.devotion <= 20) { s.trust -= 10; } }); + getSlaves().forEach(function(s) { if (s.devotion <= 20) { s.trust -= 10; } }); return t; } @@ -150,7 +150,7 @@ App.Events.RESSEscapee = class RESSEscapee extends App.Events.BaseEvent { eventSlave.trust -= 50; eyeSurgery(eventSlave, "both", "blind"); surgeryDamage(eventSlave, 20); - V.slaves.forEach(function(s) { if (s.devotion <= 20) { s.trust -= 10; } }); + getSlaves().forEach(function(s) { if (s.devotion <= 20) { s.trust -= 10; } }); return t; } @@ -164,7 +164,7 @@ App.Events.RESSEscapee = class RESSEscapee extends App.Events.BaseEvent { eventSlave.trust -= 25; eventSlave.voice = 0; surgeryDamage(eventSlave, 10); - V.slaves.forEach(function(s) { if (s.devotion <= 20) { s.trust -= 5; } }); + getSlaves().forEach(function(s) { if (s.devotion <= 20) { s.trust -= 5; } }); return t; } diff --git a/src/events/RESS/kitchenMolestation.js b/src/events/RESS/kitchenMolestation.js index 62ad9f54e73ba32aa20d7366cf621f764b2f673a..d665c4e0338030ca0d56a86f1bff14aa3d2b4bba 100644 --- a/src/events/RESS/kitchenMolestation.js +++ b/src/events/RESS/kitchenMolestation.js @@ -33,7 +33,7 @@ App.Events.RESSKitchenMolestation = class RESSKitchenMolestation extends App.Eve } = getNonlocalPronouns(V.seeDicks).appendSuffix('U'); const belly = bellyAdjective(eventSlave); const targetJobs = ["be a servant", "be a subordinate slave", "get milked", "learn in the schoolroom", "please you", "rest in the spa", "rest", "serve in the club", "serve the public", "take classes", "whore", "work a glory hole", "work as a servant", "work in the brothel"]; - const targetSlaves = V.slaves.filter(s => targetJobs.includes(s.assignment) && s.ID !== eventSlave.ID); + const targetSlaves = getSlaves().filter(s => targetJobs.includes(s.assignment) && s.ID !== eventSlave.ID); const PC = V.PC; App.Events.drawEventArt(node, eventSlave, "no clothing"); diff --git a/src/events/RESS/mutinyAttempt.js b/src/events/RESS/mutinyAttempt.js index 431a3c3dcfa714587a8bdd40f45a5a941557c496..8b187d592a0b5f40271e4204e755a0050eaa2e1b 100644 --- a/src/events/RESS/mutinyAttempt.js +++ b/src/events/RESS/mutinyAttempt.js @@ -307,14 +307,14 @@ App.Events.RESSMutinyAttempt = class RESSMutinyAttempt extends App.Events.BaseEv function lock() { eventSlave.trust += 10; eventSlave.chastityPenis = 1; - V.slaves.forEach(function(s) { if (s.devotion < -50) { s.trust += 5; } }); + getSlaves().forEach(function(s) { if (s.devotion < -50) { s.trust += 5; } }); return `You simply clamp a chastity cage onto ${his} limp dick; ${he}'ll be taking a little break from fucking girls for the time being. When ${he} comes to and finds ${himself} locked in chastity, ${he} immediately begins fiddling with it in an attempt to remove it. ${He} feels this punishment is laughable and only <span class="defiant inc">grows more defiant.</span> Word spreads through your chattel that the only downside of trying to rape ${getWrittenTitle(eventSlave)} is getting locked in chastity, <span class="defiant inc">spreading defiance</span> through your rebellious slaves.`; } function flog() { eventSlave.trust -= 15; healthDamage(eventSlave, 15); - V.slaves.forEach(function(s) { if (s.devotion < -50) { s.trust -= 5; } }); + getSlaves().forEach(function(s) { if (s.devotion < -50) { s.trust -= 5; } }); return `You bind ${his} naked body to the wall in preparation for a good beating. Going against one's master is bad, but going against you is even worse. You thoroughly strike ${him}, showering extra attention to ${his} crotch, while making sure ${he} will be in pain for days to come. Such a beating leaves ${him} <span class="health dec">in agonizing pain</span> and makes a clear example to ${him} and all your other rebellious slaves that <span class="trust dec">you are not to be trifled with.</span>`; } @@ -322,7 +322,7 @@ App.Events.RESSMutinyAttempt = class RESSMutinyAttempt extends App.Events.BaseEv eventSlave.trust += 5; eventSlave.devotion -= 15; eventSlave.voice = 0; - V.slaves.forEach(function(s) { if (s.devotion < -50) { s.trust += 10; } }); + getSlaves().forEach(function(s) { if (s.devotion < -50) { s.trust += 10; } }); cashX(forceNeg(V.surgeryCost), "slaveSurgery", eventSlave); return `As you pull ${his} limp body to the remote surgery, you notice ${he} understands what ${he} has done and begs you to reconsider your decision; but your mind is set. ${He} tried to rape you, ${he} must be silenced. Restrained as ${he} is, the most ${he} can do is cry and beg. When ${he} awakens from surgery, ${he} realizes all you did was stop ${him} from talking; <span class="defiant inc">what stops ${him} from making another go at you?</span> Your other rebellious slaves see this as a minor loss for a potentially huge gain and, if anything, <span class="defiant inc">become more defiant.</span>`; } @@ -332,7 +332,7 @@ App.Events.RESSMutinyAttempt = class RESSMutinyAttempt extends App.Events.BaseEv eventSlave.devotion -= 10; eventSlave.balls = 0; eventSlave.scrotum = 0; - V.slaves.forEach(function(s) { if (s.devotion < -50) { s.trust -= 10; } }); + getSlaves().forEach(function(s) { if (s.devotion < -50) { s.trust -= 10; } }); cashX(forceNeg(V.surgeryCost), "slaveSurgery", eventSlave); surgeryDamage(eventSlave, 10); return `As you pull ${his} limp body to the remote surgery, you notice ${he} understands what ${he} has done and begs you to reconsider your decision; but your mind is set. ${He} had the balls to try and rape you, and now ${he} won't. Restrained as ${he} is, the most ${he} can do is cry and beg. Once ${he} comes to after the surgery, ${he} faces ${his} new life; <span class="devotion dec">${he}'ll never get hard again</span> and ${he}'s <span class="trust dec">the only one to blame</span> for ${his} <span class="health dec">suffering.</span> Every other rebellious slave is <span class="trust dec">mortified by the example.</span>`; @@ -348,7 +348,7 @@ App.Events.RESSMutinyAttempt = class RESSMutinyAttempt extends App.Events.BaseEv eventSlave.dickAccessory = "none"; eventSlave.vagina = 1; eventSlave.chastityPenis = 0; - V.slaves.forEach(function(s) { if (s.devotion < -50) { s.trust -= 15; } }); + getSlaves().forEach(function(s) { if (s.devotion < -50) { s.trust -= 15; } }); cashX(forceNeg(V.surgeryCost*2), "slaveSurgery", eventSlave); surgeryDamage(eventSlave, 20); @@ -367,7 +367,7 @@ App.Events.RESSMutinyAttempt = class RESSMutinyAttempt extends App.Events.BaseEv eventSlave.scrotum = 0; eventSlave.dickAccessory = "none"; eventSlave.chastityPenis = 0; - V.slaves.forEach(function(s) { if (s.devotion < -50) { s.trust -= 15; } }); + getSlaves().forEach(function(s) { if (s.devotion < -50) { s.trust -= 15; } }); cashX(forceNeg(V.surgeryCost*2), "slaveSurgery", eventSlave); surgeryDamage(eventSlave, 20); return `You ask ${him} if ${he} enjoyed the last time ${he} used ${his} dick and if it was worth crossing you, because it will not happen again. Restrained as ${he} is, the most ${he} can do is cry and beg. Once ${he} comes to after the surgery, ${he} faces ${his} new body; <span class="devotion dec">${he}'s now a surgical null</span> and ${he}'s <span class="trust dec">the only one to blame</span> for ${his} <span class="health dec">suffering.</span> Every other rebellious slave is <span class="trust dec">horrified by the example.</span>`; @@ -387,7 +387,7 @@ App.Events.RESSMutinyAttempt = class RESSMutinyAttempt extends App.Events.BaseEv eventSlave.vaginalAccessory = "none"; eventSlave.vaginalAttachment = "none"; eventSlave.chastityVagina = 0; - V.slaves.forEach(function(s) { if (s.devotion < -50) { s.trust -= 15; } }); + getSlaves().forEach(function(s) { if (s.devotion < -50) { s.trust -= 15; } }); cashX(forceNeg(V.surgeryCost*4), "slaveSurgery", eventSlave); surgeryDamage(eventSlave, 20); diff --git a/src/events/RESS/obedientAddict.js b/src/events/RESS/obedientAddict.js index 6917eef9a57af4038521985e2817a5c0fdbd741e..822615c96459e07a6f40c69b2742546204389df2 100644 --- a/src/events/RESS/obedientAddict.js +++ b/src/events/RESS/obedientAddict.js @@ -83,7 +83,7 @@ App.Events.RESSObedientAddict = class RESSObedientAddict extends App.Events.Base } t.push(`For the hour or so it takes ${him} to pass out, slaves using the kitchen have to step over ${his} prostrate, orgasming body, lying in a pool of ${his} own drool, tears, sweat, and fluids. The next time you see ${him} in the kitchen, ${he} takes ${his} medicine like a <span class="gold">good ${girl}.</span> All your aphrodisiac addicts recognize the symptoms and the punishment, and <span class="gold">avoid even thinking</span> about resisting the system.`); - V.slaves.forEach(function(s) { if (s.aphrodisiacs > 0 || s.inflationType === "aphrodisiac") { s.trust -= 5; } }); + getSlaves().forEach(function(s) { if (s.aphrodisiacs > 0 || s.inflationType === "aphrodisiac") { s.trust -= 5; } }); return t; } diff --git a/src/events/RESS/review/confidentTanning.js b/src/events/RESS/review/confidentTanning.js index 2faeb2161212a72a3014527f001b0d4f56e72f27..9df415c99473c4772f1656365d07bdbaa838b352 100644 --- a/src/events/RESS/review/confidentTanning.js +++ b/src/events/RESS/review/confidentTanning.js @@ -315,7 +315,7 @@ App.Events.RESSConfidentTanning = class RESSConfidentTanning extends App.Events. } r.push(`that a slave can receive credit for finding a good thing.`); eventSlave.trust++; - V.slaves.forEach((s) => { + getSlaves().forEach((s) => { if (s.devotion > 20) { s.trust++; } }); r.toParagraph(); diff --git a/src/events/RESS/review/hugeTits.js b/src/events/RESS/review/hugeTits.js index af027551133a0f21152da524f165ac07b3f9a026..b2751e8656ed46939592ac63970f2e0413b88c4d 100644 --- a/src/events/RESS/review/hugeTits.js +++ b/src/events/RESS/review/hugeTits.js @@ -4,7 +4,7 @@ App.Events.RESSHugeTits = class RESSHugeTits extends App.Events.BaseEvent { () => V.boobAccessibility !== 1, () => V.ballsAccessibility !== 1, () => V.pregAccessibility !== 1, - () => V.slaves.length > 2, + () => getSlaves().length > 2, ]; // always valid if sufficient actors can be cast successfully } diff --git a/src/events/RESS/review/millenary.js b/src/events/RESS/review/millenary.js index fd7f18297274c9fb89f8c7e9a3e72061b48b29ab..83894d9b3f5e8f07648da697e156c76624109a10 100644 --- a/src/events/RESS/review/millenary.js +++ b/src/events/RESS/review/millenary.js @@ -37,7 +37,7 @@ App.Events.RESSMillenary = class RESSMillenary extends App.Events.BaseEvent { App.Events.addParagraph(node, [`As the Free Cities grow and evolve, slave culture does too. It seems this is a new tradition among obedient sex slaves. ${He} obviously expects you to do the honors, and it seems the rest of your slaves are looking forward to it.`]); let choices = [new App.Events.Result(`Give ${him} ${his} thousandth fuck`, fuck)]; - if (V.slaves.length > 2) { + if (getSlaves().length > 2) { choices.push(new App.Events.Result(`Include everyone in ${his} millenary`, everyone)); } if (canDoAnal(slave) && slave.counter.anal !== 0) { @@ -154,8 +154,8 @@ App.Events.RESSMillenary = class RESSMillenary extends App.Events.BaseEvent { } r.push(`gently pumping ${his} butt the whole time. When ${he}'s done, ${he} thanks you exhaustedly and begs you to do this for ${his} next millenary. <span class="devotion inc">${His} love for you has greatly increased.</span>`); slave.devotion += 10; - seX(slave, "oral", "slaves", "penetrative", (V.slaves.length * 2)); - V.slaves.forEach(function(s) { if (s.ID !== slave.ID) { s.counter.oral++; } }); + seX(slave, "oral", "slaves", "penetrative", (getSlaves().length * 2)); + getSlaves().forEach(function(s) { if (s.ID !== slave.ID) { s.counter.oral++; } }); if (canDoVaginal(slave)) { r.push(VCheck.Vaginal(slave, 1)); } else { @@ -249,8 +249,8 @@ App.Events.RESSMillenary = class RESSMillenary extends App.Events.BaseEvent { slave.devotion += 4; slave.trust += 4; seX(slave, "oral", V.PC, "penetrative"); - seX(slave, "anal", "slaves", "penetrative", V.slaves.length+1); - V.slaves.forEach(function(s) { if (s.ID !== slave.ID) { s.counter.penetrative++; } }); + seX(slave, "anal", "slaves", "penetrative", getSlaves().length + 1); + getSlaves().forEach(function(s) { if (s.ID !== slave.ID) { s.counter.penetrative++; } }); return r; } diff --git a/src/events/RESS/review/tendonFall.js b/src/events/RESS/review/tendonFall.js index 9646daee96564227fecc0eb7ffd34efd27783c54..fd0f74e924fd9423bed63c4146d0b5937a9e6683 100644 --- a/src/events/RESS/review/tendonFall.js +++ b/src/events/RESS/review/tendonFall.js @@ -1,7 +1,7 @@ App.Events.RESSTendonFall = class RESSTendonFall extends App.Events.BaseEvent { eventPrerequisites() { return [ - () => V.slaves.length > 2, + () => getSlaves().length > 2, ]; } diff --git a/src/events/RESS/review/torpedoSqueeze.js b/src/events/RESS/review/torpedoSqueeze.js index 762a38de419add6a94913c4638c1362eb253ca8e..0417eaf1b38e06b980432e22193b251fd427c7d9 100644 --- a/src/events/RESS/review/torpedoSqueeze.js +++ b/src/events/RESS/review/torpedoSqueeze.js @@ -29,7 +29,7 @@ App.Events.RESSTorpedoSqueeze = class RESSTorpedoSqueeze extends App.Events.Base const r = new SpacedTextAccumulator(node); r.push(`The penthouse bathroom has a long counter and mirror arrangement with many sinks, so a number of slaves can get ready at once. During those moments of the day when`); - if (V.slaves.length > 10) { + if (getSlaves().length > 10) { r.push(`many`); } else { r.push(`more than one`); diff --git a/src/events/assistant/assistantSP.js b/src/events/assistant/assistantSP.js index df38c28055bd841e5e83d7530ab4bbb73db755f9..d3f243cd8c0b1651c78973133d182df1719c8a08 100644 --- a/src/events/assistant/assistantSP.js +++ b/src/events/assistant/assistantSP.js @@ -21,7 +21,7 @@ App.Events.assistantSP = class assistantSP extends App.Events.BaseEvent { let r = []; V.assistant.options = 1; - const slave = V.slaves.find(s => (s.vagina > 0 || s.anus > 0) && s.rules.release.masturbation === 1) || V.slaves.random(); + const slave = getSlaves().find(s => (s.vagina > 0 || s.anus > 0) && s.rules.release.masturbation === 1) || getSlaves().random(); const {him} = getPronouns(slave); App.Events.drawEventArt(node, "assistant"); @@ -30,7 +30,7 @@ App.Events.assistantSP = class assistantSP extends App.Events.BaseEvent { App.Events.addParagraph(node, r); r = []; r.push(`${HeA} continues more seriously,`); - if (V.slaves.some(s => s.piercing.genitals.smart)) { + if (getSlaves().some(s => s.piercing.genitals.smart)) { r.push(`"You may have noticed that the smart implants you've got your slaves wearing are working a little bit better than when I was a boring old secretary type. I'm not a true artificial intelligence, but I can adapt with experience, and I've had a lot of lovely experience lately! Also, a lot of the computing power I use to be sexy helps me adapt smart piercings to individual slaves' sexualities."`); } else { r.push(`"I'm sure you've seen those expensive smart piercings the body mod studio can implant. I think they would work a little bit better now than when I was a boring old secretary type. I'm not a true artificial intelligence, but I can adapt with experience, and I've had a lot of lovely experience lately! Also, a lot of the computing power I use to be sexy would help me adapt smart piercings to individual slaves' sexualities."`); diff --git a/src/events/debugEvent.js b/src/events/debugEvent.js index 7524721ba7a31c0f2ad4370629377baf6f1d7b95..564b26418dbf27f5d38974d3e9fba0d950bcf360 100644 --- a/src/events/debugEvent.js +++ b/src/events/debugEvent.js @@ -58,7 +58,7 @@ App.Events.debugEvent = function(eventName, hostPassage) { } )); } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { let slaveDiv = App.UI.DOM.makeElement("div", App.UI.DOM.makeElement("span", SlaveFullName(slave), "slave-name")); let slaveFails = false; for (const p of actorRequirements[i]) { diff --git a/src/events/intro/acquisition.js b/src/events/intro/acquisition.js index ff8a46727ddaa65fa59c3ce44b0122eb21fbb989..422d51c57d4752758a37363dc40ea43348211b26 100644 --- a/src/events/intro/acquisition.js +++ b/src/events/intro/acquisition.js @@ -6,11 +6,11 @@ App.Intro.acquisition = function() { const r = []; if (_.isArray(V.careerBonusNeeded)) { - V.slaves.filter(s => V.careerBonusNeeded.includes(s.ID)).forEach(App.StartingGirls.applyCareerBonus); + getSlaves().filter(s => V.careerBonusNeeded.includes(s.ID)).forEach(App.StartingGirls.applyCareerBonus); delete V.careerBonusNeeded; delete V.applyCareerBonus; } - V.slaves.filter(s => s.origin === "$auto").forEach(x => App.StartingGirls.playerOrigin(x).apply()); + getSlaves().filter(s => s.origin === "$auto").forEach(x => App.StartingGirls.playerOrigin(x).apply()); if (V.freshPC === 1 || V.saveImported === 0) { PCSetup(); @@ -54,7 +54,7 @@ App.Intro.acquisition = function() { } newSlave(slave); } - const {He, his, girl} = getPronouns(V.slaves.random()); + const {He, his, girl} = getPronouns(getSlaves().random()); switch (V.targetArcology.fs) { case "FSSupremacist": r.push(`They kept a personal stable of fearful ${V.arcologies[0].FSSupremacistRace} sex slaves, but their sexual training is incomplete. Several of them are still here.`); @@ -185,17 +185,21 @@ App.Intro.acquisition = function() { } let addFamilyMember = false; let secondMember = baseSlave(); + let slaveDatabaseID = 0; let secondMemberDatabaseID = 0; // We initialize this here so that we use it to set incestuous relationships. + let isSecondMember = false; for (let j = 0; j < heroSlaves.length; j++) { let slave; if (addFamilyMember) { slave = secondMember; + isSecondMember = true; addFamilyMember = false; } else if (valueOwed - valueGiven <= 5000) { break; } else { + isSecondMember = false; const heroSlaveTemplate = heroSlaves[j]; - const slaveDatabaseID = heroSlaveTemplate.ID; + slaveDatabaseID = heroSlaveTemplate.ID; heroSlaves.splice(j, 1); j--; slave = App.Utils.getHeroSlave(heroSlaveTemplate); @@ -248,12 +252,18 @@ App.Intro.acquisition = function() { slave.oldDevotion = slave.devotion; slave.oldTrust = slave.trust; slave.health.tired = 0; + if (isSecondMember) { + V.heroSlavesPurchased.push(secondMemberDatabaseID); + } else { + V.heroSlavesPurchased.push(slaveDatabaseID); + } + newSlave(slave); // Set incestuous relationship. Checking "addFamilyMember" makes sure we only do this after both family members have been added. let incestTarget = undefined; if (V.seeIncest === 1 && !addFamilyMember && secondMemberDatabaseID in incestFamilies) { - incestTarget = V.slaves.find(s => areSisters(s, slave) > 0); + incestTarget = getSlaves().find(s => areSisters(s, slave) > 0); slave.relationship = 3; slave.relationshipTarget = incestTarget.ID; incestTarget.relationship = 3; @@ -326,7 +336,7 @@ App.Intro.acquisition = function() { V.averageTrust = 0; V.averageDevotion = 0; let slavesContributing = 0; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { updateHealth(slave); slave.oldDevotion = slave.devotion; slave.oldTrust = slave.trust; @@ -411,7 +421,7 @@ App.Intro.acquisition = function() { V.PC.counter.birthMaster = 8; } } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.mother === -1) { V.PC.counter.birthsTotal++; if (slave.father === -1) { @@ -423,7 +433,7 @@ App.Intro.acquisition = function() { } } } else if (isPCCareerInCategory("escort")) { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.mother === -1) { V.PC.counter.birthsTotal++; if (slave.father === -1) { @@ -437,7 +447,7 @@ App.Intro.acquisition = function() { } } } else { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.mother === -1) { V.PC.counter.birthsTotal++; if (slave.father === -1) { @@ -555,17 +565,17 @@ App.Intro.acquisition = function() { } } checkMissingParents(V.PC); - V.slaves.forEach(checkMissingParents); + getSlaves().forEach(checkMissingParents); } function PCChildrenCount() { let PCPregnancies = []; let SPregnancies = []; let birthData = ""; - V.slaves.forEach(function(s) { + getSlaves().forEach(function(s) { PCPregnancies = []; SPregnancies = []; - V.slaves.filter(s0 => s0.newGamePlus === 0).forEach(function(s1) { + getSlaves().filter(s0 => s0.newGamePlus === 0).forEach(function(s1) { if (s1.father === s.ID && s1.mother === -1) { birthData = s1.actualAge + " " + s1.birthWeek + " " + s1.father; if (!PCPregnancies.includes(birthData)) { @@ -592,17 +602,17 @@ App.Intro.acquisition = function() { function inbreedingCalc() { const coeffSlaves = []; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.newGamePlus === 0) { slave.inbreedingCoeff = -1; - getGenePoolRecord(slave, false, true).inbreedingCoeff = -1; + getGenePoolRecordWriteMode(slave).inbreedingCoeff = -1; coeffSlaves.push(slave); } } const ibcoeffs = ibc.coeff_slaves(coeffSlaves); for (const slave of coeffSlaves) { slave.inbreedingCoeff = ibcoeffs[slave.ID]; - getGenePoolRecord(slave, false, true).inbreedingCoeff = ibcoeffs[slave.ID]; + getGenePoolRecordWriteMode(slave).inbreedingCoeff = ibcoeffs[slave.ID]; } } diff --git a/src/events/intro/customizeSlaveTrade.js b/src/events/intro/customizeSlaveTrade.js index aceb9beccb7d4ac8b2512a68efb1463431d3e48a..3d0483c98881cd5b26df555c2f0ccc055f4732bd 100644 --- a/src/events/intro/customizeSlaveTrade.js +++ b/src/events/intro/customizeSlaveTrade.js @@ -394,7 +394,7 @@ App.Intro.CustomSlaveTrade = function() { */ function settingsExport(container) { let textArea = document.createElement("textarea"); - textArea.value = JSON.stringify(V.nationalities); + textArea.value = Serial.stringify(V.nationalities); $(container).empty().append(textArea); } @@ -407,7 +407,7 @@ App.Intro.CustomSlaveTrade = function() { button.append("Load"); button.onclick = () => { try { - V.nationalities = JSON.parse(textArea.value); + V.nationalities = Serial.parse(textArea.value); } catch (SyntaxError) { Dialog.create("Invalid Input"); Dialog.append("The input is not a valid nationalities object."); diff --git a/src/events/intro/introSummary.js b/src/events/intro/introSummary.js index a1720a0ce8b9fa990da35d23a3b3339fae877fc7..043994d7ee420763390aba4b8f45fa9ea4e84742 100644 --- a/src/events/intro/introSummary.js +++ b/src/events/intro/introSummary.js @@ -26,7 +26,7 @@ App.Intro.getNondefaultOptionsAsObject = function(exportFrom = V, defaults = App }; App.Intro.getNondefaultOptionsAsJSON = function() { - return JSON.stringify(App.Intro.getNondefaultOptionsAsObject(), null, 2); + return Serial.stringify(App.Intro.getNondefaultOptionsAsObject(), null, 2); }; App.Intro.summary = function() { @@ -68,7 +68,7 @@ App.Intro.summary = function() { V.PC.origSkin = V.PC.skin; V.PC.origHColor = V.PC.hColor; V.PC.eyebrowHColor = V.PC.hColor; - V.PC.pubicHColor = V.PC.hColor; + V.PC.underArmHColor = V.PC.hColor; } // Ensure SecExp variables are in sync. Important to do here so NGP is handled as well. if ((V.secExpEnabled && Object.values(V.SecExp).length <= 1) || (!V.secExpEnabled && Object.values(V.SecExp).length > 1)) { @@ -436,7 +436,7 @@ App.Intro.summary = function() { App.UI.DOM.link( "Import game options", () => { - const optionsFromJSON = JSON.parse(textareaElement.value); + const optionsFromJSON = Serial.parse(textareaElement.value); const tooltipsEnabled = V.tooltipsEnabled; App.Intro.assignOnlyMatchingKeys(V, optionsFromJSON, App.Data.defaultGameOptions); if (tooltipsEnabled !== V.tooltipsEnabled) { diff --git a/src/events/intro/newGamePlusPassage.js b/src/events/intro/newGamePlusPassage.js index f2b27c4f23d9903b776116f85fa32c0a1e262123..3b2c31e620f4d6952d8d14265d107a2887b726b8 100644 --- a/src/events/intro/newGamePlusPassage.js +++ b/src/events/intro/newGamePlusPassage.js @@ -80,7 +80,7 @@ App.Intro.newGamePlus = function() { App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( "DEBUG: Add all slaves to import list", () => { - V.slaves.forEach(s => assignJob(s, Job.IMPORTED)); + getSlaves().forEach(s => assignJob(s, Job.IMPORTED)); App.UI.reload(); } )); diff --git a/src/events/intro/takeoverTarget.js b/src/events/intro/takeoverTarget.js index a69a399b99809bc1ed4d92233e6d635da4d01db3..0f9d18c0655a240d5fefc5541029ba20219067be 100644 --- a/src/events/intro/takeoverTarget.js +++ b/src/events/intro/takeoverTarget.js @@ -1,7 +1,7 @@ // cSpell:ignore maskirovka App.Intro.takeoverTarget = function() { - const slavesImported = V.slaves.filter(s => s.newGamePlus === 1); + const slavesImported = getSlaves().filter(s => s.newGamePlus === 1); if (slavesImported.length > 0) { V.retirementAge = Math.max(V.retirementAge, _.max(slavesImported.map(s => s.actualAge)) + 2); const highestActualAge = _.max(slavesImported.map(s => s.actualAge)); diff --git a/src/events/nonRandom/daughters/pUndergroundRailroad.js b/src/events/nonRandom/daughters/pUndergroundRailroad.js index b1fc03872f825196ef6274b136462d074170f4d4..9f1d894e0333d352b12a027adb700709929739b1 100644 --- a/src/events/nonRandom/daughters/pUndergroundRailroad.js +++ b/src/events/nonRandom/daughters/pUndergroundRailroad.js @@ -249,7 +249,7 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events. (s) => s.trust < 75, ]; let rankedSlaves = []; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { let value = 0; for (const quality of qualities) { if (quality(slave)) { @@ -305,7 +305,7 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events. if (V.PC.father === V.traitor.ID) { V.traitorStats.PCfather = V.traitor.ID; } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.ID !== V.traitor.ID) { if (slave.mother === V.traitor.ID) { V.traitorStats.traitorMother.push(slave.ID); @@ -341,7 +341,7 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events. V.traitor.sisters = 0; V.traitor.daughters = 0; if (V.traitor.bodySwap > 0) { - const myBody = V.slaves.find(s => s.origBodyOwnerID === traitor.ID); + const myBody = getSlaves().find(s => s.origBodyOwnerID === traitor.ID); if (myBody) { V.traitorStats.traitorBody = myBody.ID; } @@ -369,7 +369,7 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events. let r = []; unlock(); r.push(`${traitor.slaveName} nods ${his} head in acceptance. There is too much at stake to take such a risk. All attempts to use your monitoring systems to find the citizens who contacted ${him} fail; it seems their ability to corrupt your systems is considerable. ${He} keeps ${his} lips shut tight in an effort to prevent rumors from spreading, but <span class="devotion dec">whispers of freedom</span> still manage to run through your chattel.`); - V.slaves.filter(desiresFreedom).forEach(s => s.devotion -= 5); + getSlaves().filter(desiresFreedom).forEach(s => s.devotion -= 5); App.Events.addParagraph(frag, r); return frag; } @@ -378,7 +378,7 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events. const frag = new DocumentFragment(); let r = []; unlock(); - r.push(`You decide to release ${him} into the streets and keep an eye on ${him}. ${He} is quickly scooped up by several citizens, some of which you recognize from the earlier video, and taken away. There is a plot in motion against you, and it extends worringly deep into your domain.`); + r.push(`You decide to release ${him} into the streets and keep an eye on ${him}. ${He} is quickly scooped up by several citizens, some of which you recognize from the earlier video, and taken away. There is a plot in motion against you, and it extends worryingly deep into your domain.`); sendTraitor(); App.Events.addParagraph(frag, r); return frag; @@ -389,7 +389,7 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events. let r = []; unlock(); r.push(`You see no reason to humor them. All attempts to use your monitoring systems to find the citizens who visited ${traitor.slaveName} fail; it seems their ability to corrupt your systems is considerable. While ${he} doesn't talk, <span class="devotion dec">whispers of freedom</span> still manage to run through your chattel.`); - V.slaves.filter(desiresFreedom).forEach(s => s.devotion -= 5); + getSlaves().filter(desiresFreedom).forEach(s => s.devotion -= 5); App.Events.addParagraph(frag, r); return frag; } @@ -420,7 +420,7 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events. r.push(`${traitor.slaveName} almost <span class="devotion dec">faints with relief</span> when it becomes apparent you aren't going to punish ${him} for speaking of freedom.`); } r.push(`All attempts to use your monitoring systems to find the citizens who contacted ${him} fail; it seems their ability to corrupt your systems is considerable. <span class="devotion dec">Whispers of freedom</span> run like wildfire amongst your slaves.`); - V.slaves.filter(desiresFreedom).forEach(s => s.devotion -= 10); + getSlaves().filter(desiresFreedom).forEach(s => s.devotion -= 10); traitor.devotion -= 15; newRumor.weakness(); App.Events.addParagraph(frag, r); @@ -471,7 +471,7 @@ App.Events.PUndergroundRailroad = class PUndergroundRailroad extends App.Events. } r.push(`The populace understands the necessity of the punishment, though they are <span class="reputation dec">disturbed</span> that such a thing could happen in your penthouse of all places. The surviving slaves are <span class="trust dec">terrified</span> at the display, but at least you can be sure they will remember the price of failing you.`); repX(-500, "event", traitor); - V.slaves.forEach(function(s) { + getSlaves().forEach(function(s) { s.trust -= 10 + random(10); }); removeSlave(traitor); diff --git a/src/events/nonRandom/mercs/pMercenaryRomeo.js b/src/events/nonRandom/mercs/pMercenaryRomeo.js index 9652f0dd255b6e84c15446126ea6be0949208690..5324905be4b202cbf4ad5f6f4710f208430616b1 100644 --- a/src/events/nonRandom/mercs/pMercenaryRomeo.js +++ b/src/events/nonRandom/mercs/pMercenaryRomeo.js @@ -12,9 +12,9 @@ App.Events.PMercenaryRomeo = class PMercenaryRomeo extends App.Events.BaseEvent this.actors = []; const juliet = // first try - find an available sex worker - V.slaves.filter(s => s.fetish !== Fetish.MINDBROKEN && s.fuckdoll === 0 && ["serve in the club", "serve the public", "whore", "work in the brothel"].includes(s.assignment)).random() || + getSlaves().filter(s => s.fetish !== Fetish.MINDBROKEN && s.fuckdoll === 0 && ["serve in the club", "serve the public", "whore", "work in the brothel"].includes(s.assignment)).random() || // second try - find a slave who had public exposure and is hopefully not important to the PC personally - V.slaves.filter(s => (s.counter.publicUse > 0) && (s.newGamePlus === 0) && (s.relationship > -3) && !["be your Concubine", "serve in the master suite"].includes(s.assignment)).random(); + getSlaves().filter(s => (s.counter.publicUse > 0) && (s.newGamePlus === 0) && (s.relationship > -3) && !["be your Concubine", "serve in the master suite"].includes(s.assignment)).random(); if (juliet) { this.actors.push(juliet.ID); return true; diff --git a/src/events/nonRandom/pBadBreasts.js b/src/events/nonRandom/pBadBreasts.js index f3c7db1924a1cc544d2379088a8d5c57e6d05204..e03d08abc14c081a0800508c812014d482d66947 100644 --- a/src/events/nonRandom/pBadBreasts.js +++ b/src/events/nonRandom/pBadBreasts.js @@ -23,9 +23,9 @@ App.Events.pBadBreasts = class pBadBreasts extends App.Events.BaseEvent { const [slave] = this.actors.map(a => getSlave(a)); const {He, him} = getPronouns(slave); - cashX(500 * V.slaves.length, "event"); + cashX(500 * getSlaves().length, "event"); V.badB = 1; - V.slaves.forEach(function(s) { + getSlaves().forEach(function(s) { if (["breast injections", "hyper breast injections", "intensive breast injections"].includes(s.drugs)) { healthDamage(s, Math.floor(Math.random() * 2 + 1)); } @@ -49,7 +49,7 @@ App.Events.pBadBreasts = class pBadBreasts extends App.Events.BaseEvent { return node; function keepPreg() { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.drugs.includes("breast injections")) { const isIntense = slave.drugs.includes("intensive"); const isHyper = slave.drugs.includes("hyper"); @@ -127,12 +127,12 @@ App.Events.pBadBreasts = class pBadBreasts extends App.Events.BaseEvent { } function wantMoney() { - cashX(2000 * V.slaves.length, "event"); + cashX(2000 * getSlaves().length, "event"); return `You muster all the contractual remedies available to you and join the crowd of slaveowners laying into the hapless manufacturer. Of course, with so many attackers, there is as much infighting between them as conflict with the helpless enemy, since everyone knows the business will go bankrupt before everyone gets paid. Nevertheless you <span class="cash inc">approximately double</span> the money you make out of the situation, plenty to deal with the pregnancies.`; } function repair() { - for (const s of V.slaves) { + for (const s of getSlaves()) { if (canGetPregnant(s)) { if (s.drugs === "breast injections") { if (s.geneMods.NCS > 0) { diff --git a/src/events/nonRandom/pBadCuratives.js b/src/events/nonRandom/pBadCuratives.js index aadb504a9d18c75dda9960bf99c71785ecbd1fe7..69c98536afc5a1f949a1e999c78c3ddca4fb51a8 100644 --- a/src/events/nonRandom/pBadCuratives.js +++ b/src/events/nonRandom/pBadCuratives.js @@ -21,7 +21,7 @@ App.Events.pBadCuratives = class pBadCuratives extends App.Events.BaseEvent { const [slave] = this.actors.map(a => getSlave(a)); const {He, him} = getPronouns(slave); - cashX(500 * V.slaves.length, "event"); + cashX(500 * getSlaves().length, "event"); V.badC = 1; let r = []; r.push(`Early one morning, you hear convulsive dry heaving coming from one of the bathrooms. On investigation, it seems that ${slave.slaveName} woke up feeling terribly nauseous. ${He}'s in no danger, but you've hardly checked ${him} over before more slaves stagger in. Every one of your slaves on curatives has been struck by the mysterious malady and has <span class="health dec">sickened.</span>`); @@ -42,7 +42,7 @@ App.Events.pBadCuratives = class pBadCuratives extends App.Events.BaseEvent { return node; function freeGrowth() { - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.curatives > 1) { if (s.geneMods.NCS > 0) { s.boobs += Math.floor(Math.random() * 10 + 1) * 50; @@ -68,7 +68,7 @@ App.Events.pBadCuratives = class pBadCuratives extends App.Events.BaseEvent { } function wantMoney() { - cashX(500 * V.slaves.length, "event"); + cashX(500 * getSlaves().length, "event"); return `You muster all the contractual remedies available to you and join the crowd of slaveowners laying into the hapless manufacturer. Of course, with so many attackers, there is as much infighting between them as conflict with the helpless enemy, since everyone knows the business will go bankrupt before everyone gets paid. Nevertheless you <span class="cash inc">approximately double</span> the money you make out of the situation.`; } diff --git a/src/events/nonRandom/pLoanshark.js b/src/events/nonRandom/pLoanshark.js index 0af998a46bef67cac6b7eaaffaabca2b0f699487..e1b0128efaf21e2d3b130a7d86c526770f505d62 100644 --- a/src/events/nonRandom/pLoanshark.js +++ b/src/events/nonRandom/pLoanshark.js @@ -17,7 +17,7 @@ App.Events.pLoanshark = class pLoanshark extends App.Events.BaseEvent { V.cash > loan.full ? new App.Events.Result(`Pay the man`, pay) : new App.Events.Result(null, null, `You do not have enough cash to pay the loan back`), - V.slaves.some(slave => slaveCost(slave) > loan.full) + getSlaves().some(slave => slaveCost(slave) > loan.full) ? new App.Events.Result(`Offer one of your slaves instead`, slave) : new App.Events.Result(null, null, `You do not have any slaves valuable enough to cover the loan`), new App.Events.Result(`Refuse`, refuse) @@ -47,7 +47,7 @@ App.Events.pLoanshark = class pLoanshark extends App.Events.BaseEvent { frag.append(`Choose a slave to send with the group:`); - V.slaves + getSlaves() .filter(slave => slaveCost(slave) > loan.full) .sort((a, b) => slaveCost(a) - slaveCost(b)) .forEach(slave => { @@ -74,7 +74,7 @@ App.Events.pLoanshark = class pLoanshark extends App.Events.BaseEvent { function refuse() { const text = []; - if (V.cash > loan.full || V.slaves.some(slave => slaveCost(slave) > loan.full)) { + if (V.cash > loan.full || getSlaves().some(slave => slaveCost(slave) > loan.full)) { text.push(`You simply give the man a cold smile and cross your arms, a clear signal of defiance and refusal. The envoy gives a subtle signal to one of his compatriots, and the large soldier takes a step forward, restraints in hand. "As you know," the representative begins, "Anyone with significant enough debt is subject to enslavement, and the contract you signed with my employer states that you are now a slave. You're coming with us."`); } else { text.push(`Unfortunately, you're in a little over your head – you have neither the cash needed, nor any slaves valuable enough to cover the cost. Upon hearing this, the envoy nods, his face expressionless. "As you know," he starts, "Anyone with significant enough debt is subject to enslavement, and the contract you signed with my employer states that you are now a slave. You're coming with us."`); diff --git a/src/events/nonRandom/pregnancyNotice.js b/src/events/nonRandom/pregnancyNotice.js index b0edbfa4230b0b3bb90a590a260f4c74006edc52..8ec311ad2fc850f2deb362527015fdcd12115093 100644 --- a/src/events/nonRandom/pregnancyNotice.js +++ b/src/events/nonRandom/pregnancyNotice.js @@ -443,7 +443,6 @@ App.Events.PregnancyNotice.Event = (node, mother) => { const twins = getFetusTwins(fetus); /** @type {FC.SlaveState} */ - // @ts-expect-error As long as generateChild's code is not changed incubator = true will return a SlaveState object const fakeChild = generateChild(mother, fetus, true); // Age fake child up to the ideal age while (fakeChild.actualAge < V.idealAge) { diff --git a/src/events/nonRandom/rival/pRivalInitiation.js b/src/events/nonRandom/rival/pRivalInitiation.js index d83e355010ed6531d2a892f32b4b5913fe2cb474..36ed99c8aba56d5fc006815911f943ce004a6eb4 100644 --- a/src/events/nonRandom/rival/pRivalInitiation.js +++ b/src/events/nonRandom/rival/pRivalInitiation.js @@ -68,15 +68,15 @@ App.Events.PRivalInitiation = class PRivalInitiation extends App.Events.BaseEven let r = []; const { his2, him2, - } = getPronouns(V.slaves[1]).appendSuffix("2"); - r.push(`${V.slaves[0].slaveName} leads ${him} out into the arcology's largest atrium, forces ${him} to`); + } = getPronouns(getSlaves()[1]).appendSuffix("2"); + r.push(`${getSlaves()[0].slaveName} leads ${him} out into the arcology's largest atrium, forces ${him} to`); if (hasBothLegs(slave)) { r.push(`${his} knees,`); } else { r.push(`the ground,`); } - r.push(`and, in full view of the whole arcology, orally rapes someone who was until this week a slaveowner ${himself}. Behind them, ${V.slaves[1].slaveName} is standing ready for ${his2} turn, and all your other slaves stand behind ${him2}. Public opinion is divided; the precedent is universally agreed to be bad, but the punishment is generally thought to be terrible and deserved. Your slaves, however, are almost insufferably <span class="hotpink">pleased with you</span> for forcing ${slave.slaveName}, whom they still view as a slaveowner, to pleasure them.`); - V.slaves.forEach(s => { + r.push(`and, in full view of the whole arcology, orally rapes someone who was until this week a slaveowner ${himself}. Behind them, ${getSlaves()[1].slaveName} is standing ready for ${his2} turn, and all your other slaves stand behind ${him2}. Public opinion is divided; the precedent is universally agreed to be bad, but the punishment is generally thought to be terrible and deserved. Your slaves, however, are almost insufferably <span class="hotpink">pleased with you</span> for forcing ${slave.slaveName}, whom they still view as a slaveowner, to pleasure them.`); + getSlaves().forEach(s => { seX(slave, "oral", s); s.devotion += 10; }); diff --git a/src/events/scheduled/burst/burst.js b/src/events/scheduled/burst/burst.js index 4fd5ee214cb95336bbfb05084feee0416bd410e7..4a96589d66552feddf841a0c5a5431d55c752907 100644 --- a/src/events/scheduled/burst/burst.js +++ b/src/events/scheduled/burst/burst.js @@ -5,7 +5,7 @@ App.Events.SEBurst = class SEBurst extends App.Events.BaseEvent { /** Custom casting: all bursting slaves are cast automatically. If no slaves are cast, casting fails and the event does not run. */ castActors() { - this.actors = V.slaves.filter(s => burstCheck(s)).map(s => s.ID); + this.actors = getSlaves().filter(s => burstCheck(s)).map(s => s.ID); return this.actors.length > 0; } @@ -157,7 +157,7 @@ globalThis.horrifiedSlaves = function(slave) { el.append(`Word of the late slave and ${his} gruesome fate spread fast, `); App.UI.DOM.appendNewElement("span", el, "terrifying", "gold"); el.append(` your untrusting slaves.`); - for (const bystander of V.slaves) { + for (const bystander of getSlaves()) { if (bystander.trust <= 50) { if (slave.inflation > 0) { bystander.trust -= (Math.pow(slave.inflation, 3) * 5); diff --git a/src/events/schools/resFailure.js b/src/events/schools/resFailure.js index 4ec6e819073fc02eeaa4c86121441c869efb2c41..d91e76478b6843abca8cfb403fdd70f8a462ec6f 100644 --- a/src/events/schools/resFailure.js +++ b/src/events/schools/resFailure.js @@ -269,7 +269,7 @@ App.Events.RESFailure = class RESFailure extends App.Events.BaseEvent { let r = []; const isMatron = (s) => (s.origin === "$He was the leader of your arcology's Futanari Sisters until you engineered $his community's failure and enslavement.") && (s.newGamePlus !== 1); // player can choose "Rape her" before or after the other choices...if she's not been enslaved yet, alter her template instead - const matron = V.slaves.find(isMatron) || slaveArray.find(isMatron); + const matron = getSlaves().find(isMatron) || slaveArray.find(isMatron); matron.devotion += 10; seX(matron, "anal", V.PC, "penetrative"); seX(matron, "vaginal", V.PC, "penetrative"); diff --git a/src/facilities/dairy/dairyReportUtilities.js b/src/facilities/dairy/dairyReportUtilities.js index 0ec04674de12890ce4bd72c52d560eaa629d4eba..45c4409ed42ddf5cd17ac0e8f06b37f6673a0719 100644 --- a/src/facilities/dairy/dairyReportUtilities.js +++ b/src/facilities/dairy/dairyReportUtilities.js @@ -3,7 +3,7 @@ App.Facilities.Dairy.inflation = function() { milk: 0, cum: 0 }; - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.inflationMethod === 1 || s.inflationMethod === 2) { if (s.inflationType === "milk") { inflatedSlaves.milk++; diff --git a/src/facilities/dairy/freeRangeDairyAssignmentScene.js b/src/facilities/dairy/freeRangeDairyAssignmentScene.js index b9c1d7f3da08898b7514957a64fc1f56aa693682..e364205314e14ee1234dfb34a81c279955727feb 100644 --- a/src/facilities/dairy/freeRangeDairyAssignmentScene.js +++ b/src/facilities/dairy/freeRangeDairyAssignmentScene.js @@ -33,7 +33,7 @@ App.Facilities.Dairy.freeRangeAssignmentScene = function(slave) { r.push(`to ${his} designated stall, ${he} passes the other cows currently at their milking machines. Not being hurried, ${he} occasionally watches a cow in detail.`); App.Events.addParagraph(node, r); r = []; - if (slave.fetish === "boobs" && V.slaves.filter(s => s.assignment === Job.DAIRY && s.lactation > 0).length > 0) { + if (slave.fetish === "boobs" && getSlaves().filter(s => s.assignment === Job.DAIRY && s.lactation > 0).length > 0) { aroused = true; r.push(`${He} cannot help but to feel aroused at the view of all those udders being thoroughly milked.`); if (slave.sexualFlaw === "breast growth") { @@ -55,7 +55,7 @@ App.Facilities.Dairy.freeRangeAssignmentScene = function(slave) { App.Events.addParagraph(node, r); r = []; - const cow = V.slaves.find(s => s.assignment === Job.DAIRY && s.ID !== slave.ID && s.balls >= 10 && s.dick > 0); + const cow = getSlaves().find(s => s.assignment === Job.DAIRY && s.ID !== slave.ID && s.balls >= 10 && s.dick > 0); if (cow) { const { He2, His2, diff --git a/src/facilities/dressingRoom/dressingRoom.js b/src/facilities/dressingRoom/dressingRoom.js index adb9562de53f362b67da0605db9ce9fdab801960..a75b874acf195739ee7385eb7a3fcbb8cae450f1 100644 --- a/src/facilities/dressingRoom/dressingRoom.js +++ b/src/facilities/dressingRoom/dressingRoom.js @@ -8,7 +8,7 @@ App.UI.DressingRoom.render = function() { // If modelId isn't set or the model no longer exists, set it from existing slaves if (!App.UI.DressingRoom.modelId || !getSlave(App.UI.DressingRoom.modelId)) { // If favorites exist, choose from them, otherwise choose from all slaves - const defaultModelChoices = V.favorites?.length ? V.favorites.map(slaveId => getSlave(slaveId)) : V.slaves; + const defaultModelChoices = V.favorites?.length ? V.favorites.map(slaveId => getSlave(slaveId)) : getSlaves(); const defaultModel = defaultModelChoices.sort((a, b) => Beauty(b) - Beauty(a))[0]; App.UI.DressingRoom.modelId = defaultModel?.ID; } @@ -33,7 +33,7 @@ App.UI.DressingRoom.render = function() { } App.UI.DOM.appendNewElement('p', el, `${SlaveFullName(model)} is the model.`); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { const div = App.UI.DOM.appendNewElement("div", el, App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave))); div.append(" ", App.UI.DOM.link( "Select", @@ -418,7 +418,7 @@ App.UI.DressingRoom.render = function() { cont.appendChild(element); } // @ts-ignore - element.value = JSON.stringify(V.customClothesPrompts, null, 2); + element.value = Serial.stringify(V.customClothesPrompts, null, 2); } ), App.UI.DOM.link( @@ -438,7 +438,7 @@ App.UI.DressingRoom.render = function() { submitBtn.onclick = () => { try { // @ts-ignore - V.customClothesPrompts = JSON.parse(element.value); + V.customClothesPrompts = Serial.parse(element.value); options.refresh(); } catch (e) { alert(`Couldn't import prompts:\n${e.message}`); diff --git a/src/facilities/facilityRetrievalWorkaround.js b/src/facilities/facilityRetrievalWorkaround.js index b6113482705a71d5e1450522bc8608f60f1f9f8a..22f9d43a9830998380e0b196fbd6d1dc8a1454e8 100644 --- a/src/facilities/facilityRetrievalWorkaround.js +++ b/src/facilities/facilityRetrievalWorkaround.js @@ -36,13 +36,15 @@ App.UI.facilityRetrievalWorkaround = function(facility) { App.UI.DOM.appendNewElement("span", node, `You can't sustain ${him} and thus must sell ${him} for ${cashFormat(price)}.`, "note"); } } + V.readySlave = App.Entity.TankSlaveState.fromTank(/** @type {FC.TankSlaveState} */ (V.readySlave)); } else { App.UI.DOM.appendNewElement("div", node, App.Desc.longSlave(V.readySlave)); App.UI.DOM.appendNewElement("div", node, App.UI.newChildIntro(V.readySlave)); } } else if (V.newSlavePool) { App.UI.DOM.appendNewElement("p", node, `The following slaves were discharged from ${facilityName}:`); - for (const slave of V.newSlavePool) { + for (const TankSlave of V.newSlavePool) { + const slave = isIncubator ? App.Entity.TankSlaveState.fromTank(/** @type {FC.TankSlaveState} */ (TankSlave)) : TankSlave; App.UI.DOM.appendNewElement("div", node, `Name: ${SlaveFullName(slave)}`); App.UI.DOM.appendNewElement("div", node, parent(slave, "mother")); App.UI.DOM.appendNewElement("div", node, parent(slave, "father")); diff --git a/src/facilities/farmyard/food/food.js b/src/facilities/farmyard/food/food.js index 970846d5e3f300893ff1e5d1b8ac3a75bb66c5d8..40cdbee4388ea78df899d1010b8a466cdeab8d39 100644 --- a/src/facilities/farmyard/food/food.js +++ b/src/facilities/farmyard/food/food.js @@ -151,7 +151,7 @@ App.Facilities.Farmyard.foodConsumption = function(target = 'both') { function slaveConsumption() { let total = 0; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { let amount = 8; if (slave.diet === "restricted") { diff --git a/src/facilities/farmyard/food/foodMarket.js b/src/facilities/farmyard/food/foodMarket.js index 1c433b893280a4717843066ba0d3e8756abb3830..f8709e2080bd23cd1beb9d875b680d3db73e4275 100644 --- a/src/facilities/farmyard/food/foodMarket.js +++ b/src/facilities/farmyard/food/foodMarket.js @@ -107,9 +107,9 @@ App.UI.foodMarket.foodStorageDescription = () => { if (V.mods.food.enabled && V.eventResults.foodCrisis) { if (foodAvailable > consumption) { - text.push(`This is enough to provide for ${numberWithPluralOne(V.slaves.length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} for about ${years(Math.trunc(foodAvailable / consumption))}.`); + text.push(`This is enough to provide for ${numberWithPluralOne(getSlaves().length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} for about ${years(Math.trunc(foodAvailable / consumption))}.`); } else if (foodAvailable < consumption) { - text.push(`You will need an additional ${massFormat(consumption - foodAvailable)} to provide for ${numberWithPluralOne(V.slaves.length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} during the upcoming week.`); + text.push(`You will need an additional ${massFormat(consumption - foodAvailable)} to provide for ${numberWithPluralOne(getSlaves().length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} during the upcoming week.`); } } diff --git a/src/facilities/incubator/incubatorInteract.js b/src/facilities/incubator/incubatorInteract.js index 4cd9dab5e5c3219b4458cea99ac668dab856f767..db1c1fbcd2c49b173895d774f7a9215c441be374 100644 --- a/src/facilities/incubator/incubatorInteract.js +++ b/src/facilities/incubator/incubatorInteract.js @@ -3,6 +3,7 @@ App.UI.incubator = function() { V.nextLink = "Main"; V.returnTo = "Incubator"; App.UI.StoryCaption.encyclopedia = "The Incubation Facility"; + let incubator = App.Entity.facilities.incubator; V.readySlave = 0; const tankMultiplier = [1, 5, 10, 20, 100, 500]; @@ -187,7 +188,7 @@ App.UI.incubator = function() { ["Number of Children", "data-preg-count"], ]); - if (V.slaves.length > 0) { + if (getSlaves().length > 0) { /** * @param {Map<string, string>} sortingOptions */ @@ -224,7 +225,7 @@ App.UI.incubator = function() { } const qlIncubator = document.createElement("div"); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.preg > 0 && slave.pregKnown === 1 && slave.eggType === "human") { const r = []; const reserveDisallowed = (slave.assignment === Job.DAIRY && V.dairyPregSetting > 0) || slave.assignment === Job.AGENT || slave.assignment === Job.AGENTPARTNER; @@ -489,7 +490,7 @@ App.UI.incubator = function() { App.UI.DOM.link( "Clear all reserved children", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (WombReserveCount(slave, "incubator") !== 0) { WombCleanGenericReserve(slave, 'incubator', 9999); } @@ -844,7 +845,7 @@ App.UI.incubator = function() { V.incubator.readySlaves = 1; appendRow(p, `${He} is ready to be released from ${his} tank.`); } else { - const weekDisplay = Math.ceil(V.incubator.tanks[i].incubatorSettings.growTime / V.incubator.upgrade.speed); + const weekDisplay = Math.ceil(V.incubator.tanks[i].incubatorSettings.growTime / incubator.upgrade('speed')); appendRow(p, `${His} growth is currently being accelerated. ${He} will be ready for release in about ${weekDisplay} ${(weekDisplay > 1) ? `weeks` : `week`}.`); } @@ -862,7 +863,7 @@ App.UI.incubator = function() { } - if (V.incubator.upgrade.weight === 1) { + if (incubator.upgrade('weight') === 1) { if (V.incubator.tanks[i].incubatorSettings.weight === 1) { appendRow(p, `${His} weight is not being properly managed, saving costs but likely causing excessive weight gain.`); } else if (V.incubator.tanks[i].incubatorSettings.weight === 2) { @@ -871,7 +872,7 @@ App.UI.incubator = function() { appendRow(p, `Weight management systems are offline; ${he} will likely be malnourished.`); } } - if (V.incubator.upgrade.muscles === 1) { + if (incubator.upgrade('muscles') === 1) { if (V.incubator.tanks[i].incubatorSettings.muscles === 2) { appendRow(p, `${His} strength levels are purposefully set higher than recommended; ${he} is likely to have excessive musculature.`); } else if (V.incubator.tanks[i].incubatorSettings.muscles === 1) { @@ -880,7 +881,7 @@ App.UI.incubator = function() { appendRow(p, `Strength management systems are offline; ${he} will likely be released extremely weak.`); } } - if (V.incubator.upgrade.growthStims === 1) { + if (incubator.upgrade('growthStims') === 1) { if (V.incubator.tanks[i].incubatorSettings.growthStims === 2) { appendRow(p, `${He} is being injected with higher than recommended doses of stimulants; ${he} is likely to be much taller than expected.`); } else if (V.incubator.tanks[i].incubatorSettings.growthStims === 1) { @@ -889,7 +890,7 @@ App.UI.incubator = function() { appendRow(p, `Growth stimulant injection systems are offline; ${he} will develop normally.`); } } - if (V.incubator.upgrade.reproduction === 1) { + if (incubator.upgrade('reproduction') === 1) { if (V.incubator.tanks[i].incubatorSettings.reproduction === 2) { appendRow(p, `${His} hormone levels are purposefully set higher than recommended; ${his} reproductive systems are likely to be over-active.`); } else if (V.incubator.tanks[i].incubatorSettings.reproduction === 1) { @@ -951,7 +952,7 @@ App.UI.incubator = function() { row.append(App.UI.DOM.generateLinksStrip(links)); p.append(row); } - if ((V.incubator.upgrade.organs === 1) && (V.incubator.tanks[i].tankBaby !== 3)) { + if ((incubator.upgrade('organs') === 1) && (V.incubator.tanks[i].tankBaby !== 3)) { r = []; r.push(`You can extract a sample and prepare a new organ for ${him} to be implanted once ${he} exits ${his} tank.`); const tankOrgans = { @@ -1122,51 +1123,51 @@ App.UI.incubator = function() { /* Growth acceleration */ let section = document.createElement("p"); - if (V.incubator.upgrade.speed === 52) { + if (incubator.upgrade('speed') === 52) { section.append(`It has been upgraded with perfected growth accelerants; children grow at the rate of 1 week to 1 year.`); - } else if (V.incubator.upgrade.speed === 18) { + } else if (incubator.upgrade('speed') === 18) { const cost = Math.trunc(500000 * V.upgradeMultiplierArcology); section.append(`It has been upgraded with advanced experimental growth accelerants; children grow at the rate of 3 weeks to 1 year.`); section.append( makePurchase(`Fund speculative research into maximizing growth rate`, cost, "capEx", { handler: () => { - V.incubator.upgrade.speed = 52; + incubator.setUpgrade('speed', 52); refresh(); }, notes: [`will increase upkeep costs`] }) ); - } else if (V.incubator.upgrade.speed === 9) { + } else if (incubator.upgrade('speed') === 9) { const cost = Math.trunc(75000 * V.upgradeMultiplierArcology); section.append(`It has been upgraded with advanced growth accelerants; children grow at the rate of 6 weeks to 1 year.`); section.append( makePurchase(`Fund research into increasing growth rate even further`, cost, "capEx", { handler: () => { - V.incubator.upgrade.speed = 18; + incubator.setUpgrade('speed', 18); refresh(); }, notes: [`will increase upkeep costs`] }) ); - } else if (V.incubator.upgrade.speed === 6) { + } else if (incubator.upgrade('speed') === 6) { const cost = Math.trunc(30000 * V.upgradeMultiplierArcology); section.append(`It has been upgraded with growth accelerants; children grow at the rate of 9 weeks to 1 year.`); section.append( makePurchase(`Further upgrade the incubators with specialized stem cells to speed growth`, cost, "capEx", { handler: () => { - V.incubator.upgrade.speed = 9; + incubator.setUpgrade('speed', 9); refresh(); }, notes: [`will increase upkeep costs`] }) ); - } else if (V.incubator.upgrade.speed === 5) { + } else if (incubator.upgrade('speed') === 5) { const cost = Math.trunc(30000 * V.upgradeMultiplierArcology); section.append(`The incubation tanks are basic; children grow at the rate of 12 weeks to 1 year.`); section.append( makePurchase(`Upgrade the incubators with growth accelerating drugs`, cost, "capEx", { handler: () => { - V.incubator.upgrade.speed = 6; + incubator.setUpgrade('speed', 6); refresh(); }, notes: [`will increase upkeep costs`] @@ -1178,7 +1179,7 @@ App.UI.incubator = function() { /* Weight monitoring */ section = document.createElement("p"); - if (V.incubator.upgrade.weight === 1) { + if (incubator.upgrade('weight') === 1) { section.append(`Advanced caloric monitoring systems have been installed in the tanks to monitor and maintain a developing child's weight.`); } else { const cost = Math.trunc(20000 * V.upgradeMultiplierArcology); @@ -1186,7 +1187,7 @@ App.UI.incubator = function() { section.append( makePurchase(`Upgrade the growth tanks with weight monitoring systems`, cost, "capEx", { handler: () => { - V.incubator.upgrade.weight = 1; + incubator.setUpgrade('weight', 1); refresh(); }, notes: [`will increase upkeep costs`] @@ -1198,7 +1199,7 @@ App.UI.incubator = function() { /* Muscles */ section = document.createElement("p"); - if (V.incubator.upgrade.muscles === 1) { + if (incubator.upgrade('muscles') === 1) { section.append(`Advanced monitoring and steroid injection systems have been installed in the tanks to monitor and maintain a developing child's musculature.`); } else { const cost = Math.trunc(20000 * V.upgradeMultiplierArcology); @@ -1206,7 +1207,7 @@ App.UI.incubator = function() { section.append( makePurchase(`Upgrade the growth tanks with muscle monitoring systems`, cost, "capEx", { handler: () => { - V.incubator.upgrade.muscles = 1; + incubator.setUpgrade('muscles', 1); refresh(); }, notes: [`will increase upkeep costs`] @@ -1218,7 +1219,7 @@ App.UI.incubator = function() { /* Height */ section = document.createElement("p"); - if (V.incubator.upgrade.growthStims === 1) { + if (incubator.upgrade('growthStims') === 1) { section.append(`Advanced monitoring and stimulant injection systems have been installed in the tanks to monitor and maintain a developing child's height.`); } else if (V.growthStim === 1) { const cost = Math.trunc(20000 * V.upgradeMultiplierArcology); @@ -1226,7 +1227,7 @@ App.UI.incubator = function() { section.append( makePurchase(`Upgrade the growth tanks with stimulants injection systems`, cost, "capEx", { handler: () => { - V.incubator.upgrade.growthStims = 1; + incubator.setUpgrade('growthStims', 1); refresh(); }, notes: [`will increase upkeep costs`] @@ -1240,7 +1241,7 @@ App.UI.incubator = function() { /* Reproductive system */ section = document.createElement("p"); - if (V.incubator.upgrade.reproduction === 1) { + if (incubator.upgrade('reproduction') === 1) { section.append(`Advanced monitoring and hormone injection systems have been installed in the tanks to influence a developing child's reproductive organs.`); } else { const cost = Math.trunc(50000 * V.upgradeMultiplierArcology); @@ -1248,7 +1249,7 @@ App.UI.incubator = function() { section.append( makePurchase(`Upgrade the growth tanks with hormone monitoring systems`, cost, "capEx", { handler: () => { - V.incubator.upgrade.reproduction = 1; + incubator.setUpgrade('reproduction', 1); refresh(); }, notes: [`will increase upkeep costs`] @@ -1263,30 +1264,30 @@ App.UI.incubator = function() { /* Main prerequisite - stable repopulation FS OR documentation purchased from black market. And age gate. */ let div = document.createElement("div"); section = document.createElement("div"); - if (V.incubator.upgrade.pregAdaptation === 1) { + if (incubator.upgrade('pregAdaptation') === 1) { section.append(`The incubators have been upgraded with special set of manipulators, probes, nozzles and syringes coupled together with specific programs to take advantage of the accelerated growth to heighten viable reproductive capacity. These include injections of specialized serums and mechanical manipulation of the reproductive system and associated tissues, organs, muscles and bones.`); } else { section.append(`The highly controlled environment inside incubation tube coupled with the greatly accelerated growth process is the perfect opportunity to push the boundaries of a body's ability to sustain pregnancy. This will include injections of specialized serums and mechanical manipulation of their reproductive system through a special set of manipulators, probes, nozzles and syringes supervised by a powerful monitoring program. Costly to maintain.`); div.append(section); section = document.createElement("div"); - if (V.incubator.upgrade.reproduction < 1) { + if (incubator.upgrade('reproduction') < 1) { /* Now with reports - what is lacking for construction */ section.append(`${incubatorNameCaps} lacks advanced monitoring and hormone injection systems. Construction not possible.`); - } else if (V.incubator.upgrade.organs < 1) { + } else if (incubator.upgrade('organs') < 1) { section.append(`${incubatorNameCaps} lacks the ability to extract tissue samples. Construction not possible.`); } else if (V.dispensaryUpgrade < 1) { section.append(`${incubatorNameCaps} lacks a connection to an advanced pharmaceutical fabricator. Cutting-edge targeted serums production needed as integral part. Construction not possible.`); } else if (V.bellyImplants < 1) { section.append(`${incubatorNameCaps} lacks a connection with an implant manufacturing to construct fillable abdominal implants to simulate expansion. Construction not possible.`); - } else if (V.incubator.upgrade.growthStims < 1) { + } else if (incubator.upgrade('growthStims') < 1) { section.append(`${incubatorNameCaps} lacks advanced monitoring and stimulant injection systems. Construction not possible.`); } else { const cost = Math.trunc(2000000 * V.upgradeMultiplierArcology); section.append( makePurchase(`Manufacture and install this subsystem`, cost, "capEx", { handler: () => { - V.incubator.upgrade.pregAdaptation = 1; + incubator.setUpgrade('pregAdaptation', 1); refresh(); }, notes: [`will increase upkeep costs`] @@ -1301,7 +1302,7 @@ App.UI.incubator = function() { /* Tissue sampling */ section = document.createElement("p"); - if (V.incubator.upgrade.organs === 1) { + if (incubator.upgrade('organs') === 1) { section.append(`Surgical tools have been added to the tank to be able to extract tissue samples from the occupant.`); } else if (V.organFarmUpgrade >= 1) { const cost = Math.trunc(10000 * V.upgradeMultiplierArcology); @@ -1309,7 +1310,7 @@ App.UI.incubator = function() { section.append( makePurchase(`Upgrade the growth tanks with surgical extraction tools`, cost, "capEx", { handler: () => { - V.incubator.upgrade.organs = 1; + incubator.setUpgrade('organs', 1); refresh(); }, notes: [`will increase upkeep costs`] @@ -1403,7 +1404,7 @@ App.UI.incubator = function() { /* Weight */ - if (V.incubator.upgrade.weight === 1) { + if (incubator.upgrade('weight') === 1) { section = document.createElement("p"); linkArray = []; @@ -1431,7 +1432,7 @@ App.UI.incubator = function() { /* Muscles */ - if (V.incubator.upgrade.muscles === 1) { + if (incubator.upgrade('muscles') === 1) { section = document.createElement("p"); linkArray = []; @@ -1459,7 +1460,7 @@ App.UI.incubator = function() { /* Height */ - if (V.incubator.upgrade.growthStims === 1) { + if (incubator.upgrade('growthStims') === 1) { section = document.createElement("p"); linkArray = []; @@ -1487,7 +1488,7 @@ App.UI.incubator = function() { /* Reproductive system */ - if (V.incubator.upgrade.reproduction === 1) { + if (incubator.upgrade('reproduction') === 1) { section = document.createElement("p"); linkArray = []; @@ -1515,7 +1516,7 @@ App.UI.incubator = function() { /* Preg adaptation */ - if (V.incubator.upgrade.reproduction === 1 && V.incubator.upgrade.pregAdaptation === 1) { + if (incubator.upgrade('reproduction') === 1 && incubator.upgrade('pregAdaptation') === 1) { section = document.createElement("div"); linkArray = []; diff --git a/src/facilities/incubator/incubatorUtils.js b/src/facilities/incubator/incubatorUtils.js index 58922a7210561b67168905141a140debb82c8e41..af4ff9d4ec0fcec87832de90dbaf41836ec68ab6 100644 --- a/src/facilities/incubator/incubatorUtils.js +++ b/src/facilities/incubator/incubatorUtils.js @@ -33,7 +33,7 @@ App.Facilities.Incubator.init = function(state) { name: "the Incubator", organs: [], readySlaves: 0, - upgrade: { + upgrades: { speed: 5, weight: 0, muscles: 0, diff --git a/src/facilities/incubator/inspectTankSettings.js b/src/facilities/incubator/inspectTankSettings.js index 8bfef4f2f53c4e5f210138e17acb54c9ee10ca37..0caca5a437a813909620894df3d854bce8d08b05 100644 --- a/src/facilities/incubator/inspectTankSettings.js +++ b/src/facilities/incubator/inspectTankSettings.js @@ -1,4 +1,5 @@ App.UI.inspectTankSettings = function(isFetus, isPCMother = false) { + let incubator = App.Entity.facilities.incubator; let tankSetting; let child; let fetus; @@ -111,7 +112,7 @@ App.UI.inspectTankSettings = function(isFetus, isPCMother = false) { /* Weight */ section = App.UI.DOM.makeElement("p"); - if (V.incubator.upgrade.weight === 1) { + if (incubator.upgrade('weight') === 1) { linkArray = []; if (tankSetting.weight === 1) { @@ -141,7 +142,7 @@ App.UI.inspectTankSettings = function(isFetus, isPCMother = false) { /* Muscles */ section = App.UI.DOM.makeElement("p"); - if (V.incubator.upgrade.muscles === 1) { + if (incubator.upgrade('muscles') === 1) { linkArray = []; if (tankSetting.muscles === 2) { @@ -171,7 +172,7 @@ App.UI.inspectTankSettings = function(isFetus, isPCMother = false) { /* Height */ section = App.UI.DOM.makeElement("p"); - if (V.incubator.upgrade.growthStims === 1) { + if (incubator.upgrade('growthStims') === 1) { linkArray = []; if (tankSetting.growthStims === 2) { @@ -200,7 +201,7 @@ App.UI.inspectTankSettings = function(isFetus, isPCMother = false) { /* Reproduction */ section = App.UI.DOM.makeElement("p"); - if (V.incubator.upgrade.reproduction === 1) { + if (incubator.upgrade('reproduction') === 1) { linkArray = []; if (tankSetting.reproduction === 2) { @@ -228,7 +229,7 @@ App.UI.inspectTankSettings = function(isFetus, isPCMother = false) { /* Pregnancy Adaptation */ - if (V.incubator.upgrade.reproduction === 1 && V.incubator.upgrade.pregAdaptation === 1) { + if (incubator.upgrade('reproduction') === 1 && incubator.upgrade('pregAdaptation') === 1) { section = App.UI.DOM.makeElement("div"); linkArray = []; @@ -251,7 +252,7 @@ App.UI.inspectTankSettings = function(isFetus, isPCMother = false) { } section = App.UI.DOM.makeElement("div"); - if (V.incubator.upgrade.reproduction === 1 && V.incubator.upgrade.pregAdaptation === 1 && tankSetting.pregAdaptation === 1) { + if (incubator.upgrade('reproduction') === 1 && incubator.upgrade('pregAdaptation') === 1 && tankSetting.pregAdaptation === 1) { linkArray = []; if (tankSetting.pregAdaptationPower === 0) { @@ -283,7 +284,7 @@ App.UI.inspectTankSettings = function(isFetus, isPCMother = false) { } } - if (V.incubator.upgrade.reproduction === 1 && V.incubator.upgrade.pregAdaptation === 1 && !isFetus) { + if (incubator.upgrade('reproduction') === 1 && incubator.upgrade('pregAdaptation') === 1 && !isFetus) { section.append(App.UI.DOM.makeElement("div", `Due to the high complexity and steep risks of the procedure, these settings cannot be changed on tanks in use.`)); } node.append(section); diff --git a/src/facilities/nursery/nursery.js b/src/facilities/nursery/nursery.js index fe548bf0a95096d137d742804a03d61b896378a1..eea471a1a6d91de007f49a18b82c74e6d0651c89 100644 --- a/src/facilities/nursery/nursery.js +++ b/src/facilities/nursery/nursery.js @@ -337,7 +337,7 @@ App.Facilities.Nursery.nursery = class Nursery extends App.Facilities.Facility { ["Number of Children", "data-preg-count"], ]); - if (V.slaves.length > 0) { + if (getSlaves().length > 0) { /** * @param {Map<string, string>} sortingOptions */ @@ -374,7 +374,7 @@ App.Facilities.Nursery.nursery = class Nursery extends App.Facilities.Facility { } const qlNursery = document.createElement("div"); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.preg > 0 && slave.pregKnown === 1 && slave.eggType === "human") { const r = []; const reserveDisallowed = (slave.assignment === Job.DAIRY && V.dairyPregSetting > 0) || slave.assignment === Job.AGENT || slave.assignment === Job.AGENTPARTNER; @@ -742,7 +742,7 @@ App.Facilities.Nursery.nursery = class Nursery extends App.Facilities.Facility { App.UI.DOM.link( "Clear all reserved children", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (WombReserveCount(slave, "incubator") !== 0) { WombCleanGenericReserve(slave, 'incubator', 9999); } diff --git a/src/facilities/nursery/nurseryDatatypeCleanup.js b/src/facilities/nursery/nurseryDatatypeCleanup.js index 70808cba1d7344c34aa36808cbc5df6046a597c5..5975cced18beb25513048603bf9fa6e57fc969ce 100644 --- a/src/facilities/nursery/nurseryDatatypeCleanup.js +++ b/src/facilities/nursery/nurseryDatatypeCleanup.js @@ -529,7 +529,7 @@ App.Facilities.Nursery.InfantDatatypeCleanup = function(child) { // old versions of FC assign overlapping IDs to infants and other slaves, which needs to be fixed // resolve conflicting IDs between infants and older children/tank babies/adults by reassigning the infant's ID if (V.cribs.find((s) => s.ID === child.ID && (s.birthWeek !== child.birthWeek || s.actualAge !== child.actualAge)) !== undefined || - V.slaves.find((s) => s.ID === child.ID) !== undefined || (V.incubator.tanks.find((s) => s.ID === child.ID) !== undefined)) { + getSlaves().find((s) => s.ID === child.ID) !== undefined || (V.incubator.tanks.find((s) => s.ID === child.ID) !== undefined)) { child.ID = generateSlaveID(); } diff --git a/src/facilities/nursery/utils/nurseryUtils.js b/src/facilities/nursery/utils/nurseryUtils.js index c4718bc65afdfc445c52984fccbb5f07f640bd7e..02b0bc1d5dd6b7d836393c1d6cb0bdadee6d4ebd 100644 --- a/src/facilities/nursery/utils/nurseryUtils.js +++ b/src/facilities/nursery/utils/nurseryUtils.js @@ -429,7 +429,6 @@ App.Facilities.Nursery.removeChild = function removeChild(index) { */ App.Facilities.Nursery.nurserySort = function nurserySort() { const PC = V.PC; - const SL = V.slaves.length; const arcology = V.arcologies[0]; const freeCribs = (V.nurseryCribs - V.cribs.length); @@ -448,7 +447,7 @@ App.Facilities.Nursery.nurserySort = function nurserySort() { r += `<div id="ql-nursery">`; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { const {His, his} = getPronouns(slave); if (slave.preg > 0 && !slave.broodmother && slave.pregKnown && slave.eggType === "human") { @@ -633,7 +632,7 @@ App.Facilities.Nursery.nurserySort = function nurserySort() { if (reservedChildrenNursery || nurseryHasReservedChildren) { r += `<br>`; - r += App.UI.passageLink("Clear all reserved children", "Nursery", `${V.slaves.forEach((slave) => WombCleanGenericReserve(slave, "nursery", 9999))}, ${WombCleanGenericReserve(PC, "nursery", 9999)}`); + r += App.UI.passageLink("Clear all reserved children", "Nursery", `${getSlaves().forEach((slave) => WombCleanGenericReserve(slave, "nursery", 9999))}, ${WombCleanGenericReserve(PC, "nursery", 9999)}`); } function byName() { diff --git a/src/facilities/penthouse/penthouseFramework.js b/src/facilities/penthouse/penthouseFramework.js index 91bfe5848cb41973aa013bf123ae9954a4deb026..ceb90bacfda81b35b2fcb8a8c1ff0f92c37635b6 100644 --- a/src/facilities/penthouse/penthouseFramework.js +++ b/src/facilities/penthouse/penthouseFramework.js @@ -139,7 +139,7 @@ App.Entity.Facilities.PenthouseJobs = { assignmentLinkElement(ID, passage, callback, linkText) { linkText = linkText || this.desc.position; - return App.UI.DOM.assignmentLink(slaveStateById(ID), this.desc.assignment, "Subordinate Targeting", + return App.UI.DOM.assignmentLink(getSlave(ID), this.desc.assignment, "Subordinate Targeting", (slave, assignment) => { if (callback) { callback(slave, assignment); diff --git a/src/facilities/pit/pitWorkaround.js b/src/facilities/pit/pitWorkaround.js index 411bc93a7f07a10305f490ede139773d1f2e1932..96dbf7c74d4be371dd8bd1043cdd88c614fea3bf 100644 --- a/src/facilities/pit/pitWorkaround.js +++ b/src/facilities/pit/pitWorkaround.js @@ -39,7 +39,7 @@ App.Facilities.Pit.workaround = function() { App.UI.DOM.appendNewElement("div", grid, "Slave"); App.UI.DOM.appendNewElement("div", grid, "Deadliness"); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { const div = document.createElement("div"); if (V.pit.slavesFighting.includes(slave.ID)) { div.append("Assign"); diff --git a/src/facilities/servantsQuarters/servantsQuarters.js b/src/facilities/servantsQuarters/servantsQuarters.js index f9a714bab380977e9e56945352d9239127a2bf3d..611912f47f9d2effd0df776fce0cbc27add94ae5 100644 --- a/src/facilities/servantsQuarters/servantsQuarters.js +++ b/src/facilities/servantsQuarters/servantsQuarters.js @@ -149,20 +149,21 @@ App.Facilities.ServantsQuarters.servantsQuarters = class ServantsQuarters extend /** @returns {HTMLDivElement} */ get staffing() { const div = document.createElement("div"); + const slavesLength = getSlaves().length; div.append(`Your household servants are `); const capacity = totalServantCapacity(); - if (capacity > V.slaves.length * 1.5) { + if (capacity > slavesLength * 1.5) { div.append(`frankly more numerous than you really need at this point, and some have to be occupied with unproductive "busy work." You should consider reassigning some to other tasks.`); - } else if (capacity >= V.slaves.length * 0.95) { + } else if (capacity >= slavesLength * 0.95) { div.append(`capable of adequately cleaning your facilities and seeing to your slaves, without having too much idle time. You have neither too many nor too few.`); - } else if (capacity >= V.slaves.length * 0.5) { + } else if (capacity >= slavesLength * 0.5) { div.append(`constantly busy, and could probably use a little more help.`); } else { div.append(`severely understaffed. Assigning additional slaves would yield financial benefits.`); } - div.append(` They can currently help reduce the maintenance of up to ${num(capacity)} slaves, and you have ${num(V.slaves.length)}.`); + div.append(` They can currently help reduce the maintenance of up to ${num(capacity)} slaves, and you have ${num(slavesLength)}.`); return div; } diff --git a/src/facilities/studio/studio.js b/src/facilities/studio/studio.js index bda2b42639c700c0afd8526c8590510280a1dd4b..b2465d16f38cf63692ac8a7f60e31558c04f32e6 100644 --- a/src/facilities/studio/studio.js +++ b/src/facilities/studio/studio.js @@ -72,7 +72,7 @@ App.UI.mediaStudio = function() { type: genre.type.name, }); } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.porn.feed) { summary.actors++; if (slave.porn.spending > 0) { @@ -96,7 +96,7 @@ App.UI.mediaStudio = function() { } } } - r.push(`${num(summary.actors)} of your ${num(V.slaves.length)} slaves are currently featured in porn. You are spending a total of ${cashFormatColor(summary.totalCost)} promoting ${num(summary.promoted)} of them.`); + r.push(`${num(summary.actors)} of your ${num(getSlaves().length)} slaves are currently featured in porn. You are spending a total of ${cashFormatColor(summary.totalCost)} promoting ${num(summary.promoted)} of them.`); r.toParagraph(); App.UI.DOM.appendNewElement("h2", t, `Genre Coverage`); @@ -239,16 +239,15 @@ App.UI.mediaStudio = function() { } // just dump them all into one giant list for now. TODO: sorting and filtering might come later? - const slaves = V.slaves; let batchRenderer = null; if ((V.seeImages === 1) && (V.seeSummaryImages === 1)) { - batchRenderer = new App.Art.SlaveArtBatch(slaves.map(s => s.ID), 1); + batchRenderer = new App.Art.SlaveArtBatch(getSlaves().map(s => s.ID), 1); t.appendChild(batchRenderer.writePreamble()); } else { batchRenderer = null; } - for (const slave of slaves) { + for (const slave of getSlaves()) { const slaveDiv = document.createElement("div"); slaveDiv.id = `slave-${slave.ID}`; slaveDiv.classList.add("slaveSummary"); diff --git a/src/facilities/surgery/multiImplant.js b/src/facilities/surgery/multiImplant.js index e35f5de192a757ae2ba399d06c64babcd81d1a94..5490a5758ca7e16378ccca4220c49c2b9544532e 100644 --- a/src/facilities/surgery/multiImplant.js +++ b/src/facilities/surgery/multiImplant.js @@ -6,7 +6,7 @@ App.UI.multipleOrganImplant = function() { App.UI.DOM.appendNewElement("h1", node, "Implant Prosthetics"); /* prosthetics */ - for (const slave of V.slaves) { + for (const slave of getSlaves()) { /* count for estimating health impact */ const prostheticCount = V.adjustProsthetics.filter(p => p.slaveID === slave.ID && p.workLeft <= 0).length; @@ -327,7 +327,7 @@ App.UI.multipleOrganImplant = function() { const f = new DocumentFragment(); let F = App.Medicine.OrganFarm; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { let sortedOrgans = F.getSortedOrgans(slave); if (sortedOrgans.length === 0) { continue; diff --git a/src/facilities/toyShop/toyShop.js b/src/facilities/toyShop/toyShop.js index 795e094a1b405e8e549ce037b5a5199fba928c56..d6055b4135c1dd36a0c44b6564448311f3923c7e 100644 --- a/src/facilities/toyShop/toyShop.js +++ b/src/facilities/toyShop/toyShop.js @@ -162,7 +162,7 @@ App.UI.toyShop = function() { function deleteVA() { V.customItem.vaginalAccessory.delete(vaginalAcc.name); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.vaginalAccessory === vaginalAcc.name) { slave.vaginalAccessory = "none"; } @@ -261,7 +261,7 @@ App.UI.toyShop = function() { function deletePlug() { V.customItem.buttplug.delete(buttPlug.name); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.buttplug === buttPlug.name) { slave.buttplug = "none"; } diff --git a/src/facilities/wardrobe/wardrobeShopping.js b/src/facilities/wardrobe/wardrobeShopping.js index 42df5b82f079e4ed2e7157d22cd9e3aa16f7e3eb..e17d919066eb062875cd957bd6f5d980ae1c7e96 100644 --- a/src/facilities/wardrobe/wardrobeShopping.js +++ b/src/facilities/wardrobe/wardrobeShopping.js @@ -71,8 +71,8 @@ App.UI.WardrobeShopping = function() { let model; if (V?.favorites.length > 0) { modelChoices = V.favorites.map(slaveId => getSlave(slaveId)); - } else if (V.slaves?.length > 0) { - modelChoices = V.slaves; + } else if (getSlaves()?.length > 0) { + modelChoices = getSlaves(); } if (modelChoices.length > 1) { diff --git a/src/futureSocieties/aztec/slaveSacrificeLife.js b/src/futureSocieties/aztec/slaveSacrificeLife.js index a3e9b5234cd875fe4f31d03f2aa8e3322141590f..ca266472d914cd8cd07708e0bce74e0b5b440614 100644 --- a/src/futureSocieties/aztec/slaveSacrificeLife.js +++ b/src/futureSocieties/aztec/slaveSacrificeLife.js @@ -46,9 +46,9 @@ App.UI.SlaveInteract.aztecSlaveSacrificeLife = function(sacrifice) { } else { r.push(`The crowd cheers to the bloody spectacle.`); } - if (V.slaves.length > 0) { + if (getSlaves().length > 0) { r.push(`On the other hand, your remaining ${asPlural("slave is", "slaves are")} suitably <span class="trust dec">terrified.</span>`); - for (const slave of V.slaves.filter((s) => !isVegetable(s))) { + for (const slave of getSlaves().filter((s) => !isVegetable(s))) { slave.trust -= 5 + random(5); } } diff --git a/src/futureSocieties/fsPassage.js b/src/futureSocieties/fsPassage.js index b27b4eca53dfceee925c8190b6f77eda42421ac9..24e409eb9f105d557c3078c5c34a8684c1e6a1c4 100644 --- a/src/futureSocieties/fsPassage.js +++ b/src/futureSocieties/fsPassage.js @@ -187,7 +187,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Give all your slaves devotional names", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.slaveName = App.Data.misc.chattelReligionistSlaveNames.random(); } refresh(); @@ -201,7 +201,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Give all your lactating slaves cow names", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.lactation) { slave.slaveName = App.Data.misc.cowSlaveNames.random(); } @@ -217,7 +217,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Give all your idiotic slaves stripper names", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.intelligence < -15) { slave.slaveName = App.Data.misc.bimboSlaveNames.random(); } @@ -233,7 +233,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Rename all your slaves according to Roman custom", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.slaveName = App.Data.misc.romanSlaveNames.random(); slave.slaveSurname = App.Data.misc.romanSlaveSurnames.random(); } @@ -246,7 +246,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Rename all your slaves according to ancient Aztec custom", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.slaveName = App.Data.misc.aztecSlaveNames.random(); slave.slaveSurname = 0; } @@ -259,7 +259,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Rename all your slaves according to ancient Egyptian custom", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.slaveName = App.Data.misc.ancientEgyptianSlaveNames.random(); slave.slaveSurname = 0; } @@ -272,7 +272,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Rename all your slaves according to feudal Japanese custom", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.slaveName = App.Data.misc.edoSlaveNames.random(); slave.slaveSurname = App.Data.misc.edoSlaveSurnames.random(); } @@ -285,7 +285,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Rename all your slaves according to old Southern custom", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.slaveName = App.Data.misc.antebellumSlaveNames.random(); slave.slaveSurname = App.Data.misc.antebellumSlaveSurnames.random(); } @@ -299,7 +299,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Rename all your slaves according to Degradationist custom", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { DegradingName(slave); } refresh(); @@ -313,7 +313,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Rename your obedient slaves according to Paternalist custom", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.devotion > 20 || (slave.devotion >= -20 && slave.trust < -20)) { if (!["Miss", "Ms.", "Mrs."].some(title => slave.slaveName.includes(title))) { if (slave.relationship > 4) { @@ -337,7 +337,7 @@ App.UI.fsPassage = function() { App.UI.DOM.link( "Give all your slaves simple bimbo names", () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.slaveName = App.Data.misc.bimboSlaveNames.random(); slave.slaveSurname = 0; } @@ -365,7 +365,7 @@ App.UI.fsPassage = function() { */ function evaluation(proposedFS) { const effectCounts = new Map(); - for (const slave of App.SlaveAssignment.reportSlaves(V.slaves)) { + for (const slave of App.SlaveAssignment.reportSlaves(getSlaves())) { const slaveEffects = App.SlaveAssignment.saSocialEffects(slave).newForFS(proposedFS); for (const effect of slaveEffects) { const curVal = effectCounts.get(effect.shortDesc); @@ -386,7 +386,7 @@ App.UI.fsPassage = function() { App.UI.DOM.appendNewElement("div", grid, key); avg += count; } - avg /= V.slaves.length; + avg /= getSlaves().length; const grid2 = document.createElement("div"); grid2.classList.add("grid-2columns-auto"); diff --git a/src/gui/favorite.js b/src/gui/favorite.js index 0b5b8d6a7847d8cca6669cdfe02489d235b2f563..49481d03839907a5954fd0d36366e8617522147f 100644 --- a/src/gui/favorite.js +++ b/src/gui/favorite.js @@ -10,7 +10,7 @@ App.UI.favoriteToggle = function(slave, handler) { function favLink() { const linkID = `fav-link-${slave.ID}`; if (V.favorites.includes(slave.ID)) { - const link = App.UI.DOM.link("\u0041", () => { + const link = App.UI.DOM.link("★", () => { V.favorites.deleteAll(slave.ID); $(`#${linkID}`).replaceWith(favLink()); @@ -18,11 +18,11 @@ App.UI.favoriteToggle = function(slave, handler) { handler(); } }); - link.classList.add("icons-star", "favorite"); + link.classList.add("unicode-icons", "favorite"); link.id = linkID; return link; } else { - const link = App.UI.DOM.link("\u0042", () => { + const link = App.UI.DOM.link("☆", () => { V.favorites.push(slave.ID); $(`#${linkID}`).replaceWith(favLink()); @@ -30,7 +30,7 @@ App.UI.favoriteToggle = function(slave, handler) { handler(); } }); - link.classList.add("icons-star", "not-favorite"); + link.classList.add("unicode-icons", "not-favorite"); link.id = linkID; return link; } diff --git a/src/gui/options/options.js b/src/gui/options/options.js index 62142773afdfe313de22cf4d97fb5d5eef0da5d6..8e8d310e0bb1e61a3e873c0364fee0ad8e06e876 100644 --- a/src/gui/options/options.js +++ b/src/gui/options/options.js @@ -517,6 +517,10 @@ App.UI.optionsPassage = function() { .addValue("Manual", 1).on().addValue("Automatic", 0).off(); } + options.addOption("Reporting changes caused by verification is", "reportVerificationChanges") + .addValue("Enabled", 1).on().addValue("Disabled", 0).off() + .addComment("This will report most changes caused by the verification system. While helpful it does make verification (and patching by extension) slower"); + option = options.addCustomOption("Genetics array"); if (V.cheatMode === 1) { option.addButton("Edit Genetics", () => { }, "Edit Genetics"); diff --git a/src/gui/options/summaryOptions.js b/src/gui/options/summaryOptions.js index 50816d19f7f15ee1795dfbf6574b4974ca583b82..6fbae0e805dd95779e46e985336c8349d36cc49c 100644 --- a/src/gui/options/summaryOptions.js +++ b/src/gui/options/summaryOptions.js @@ -31,7 +31,7 @@ App.UI.summaryOptions = function() { App.UI.DOM.appendNewElement("h2", el, "Individual panels"); App.UI.DOM.appendNewElement("div", el, "Sample summary:"); - el.append(App.UI.SlaveList.render([V.slaves.random().ID], [], App.UI.SlaveList.SlaveInteract.stdInteract)); + el.append(App.UI.SlaveList.render([getSlaves().random().ID], [], App.UI.SlaveList.SlaveInteract.stdInteract)); options = (new App.UI.OptionsGroup()).enableDoubleColumn(); diff --git a/src/gui/storyCaption.js b/src/gui/storyCaption.js index b97ed4f0df2906e22b1624f31af28bb924fe41d6..c1ebec8b77782ec9a111a960b6b13754559ca4ba 100644 --- a/src/gui/storyCaption.js +++ b/src/gui/storyCaption.js @@ -278,7 +278,7 @@ App.UI.StoryCaption.render = function() { } App.UI.DOM.appendNewElement("span", div, "Total Sex Slaves", css); - div.append(` | ${V.slaves.length}`); + div.append(` | ${getSlaves().length}`); if (V.sideBarOptions.roomPop > 0 && V.sideBarOptions.Style === 'compact') { div.classList.add("has-tooltip"); const popupDiv = document.createElement("div"); @@ -298,7 +298,7 @@ App.UI.StoryCaption.render = function() { function slavesGrid(container) { App.UI.DOM.appendNewElement("span", container, "Total Sex Slaves", ["pink"]); App.UI.DOM.appendNewElement("div", container, "|"); - App.UI.DOM.appendNewElement("div", container, `${V.slaves.length}`); + App.UI.DOM.appendNewElement("div", container, `${getSlaves().length}`); } /** diff --git a/src/interaction/artificialInsemination.js b/src/interaction/artificialInsemination.js index a272b9a26f6f7060cdeb27f20d2376a748bfe500..02c903e985083a4b11fad3349edbd873a763562a 100644 --- a/src/interaction/artificialInsemination.js +++ b/src/interaction/artificialInsemination.js @@ -11,7 +11,7 @@ App.UI.SlaveInteract.artificialInsemination = function() { r = []; let any = false; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.balls > 0 && slave.pubertyXY === 1 && canBreed(getSlave(V.AS), slave)) { const {his} = getPronouns(slave); @@ -37,7 +37,7 @@ App.UI.SlaveInteract.artificialInsemination = function() { App.UI.DOM.appendNewElement("p", f, "You have no slaves with potent sperm.", "note"); } - if (V.incubator.tanks.length > 0 && V.incubator.upgrade.reproduction === 1) { + if (V.incubator.tanks.length > 0 && App.Entity.facilities.incubator.upgrade('reproduction') === 1) { r = []; any = false; for (const tank of V.incubator.tanks) { diff --git a/src/interaction/main/mainLinks.js b/src/interaction/main/mainLinks.js index 5b35aee873a43182a992623ffcc101d76cf9e6bc..9b8b3d82607ff14da9866a6bed2d7d7acabdb274 100644 --- a/src/interaction/main/mainLinks.js +++ b/src/interaction/main/mainLinks.js @@ -133,7 +133,7 @@ App.UI.View.mainLinks = function() { App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Head Girl", "Head Girl Select"), "major-link"), " ", App.UI.DOM.makeElement("span", App.UI.Hotkeys.hotkeys("Head Girl Select"), "hotkey")); div.id = "manageHG"; - } else if (V.slaves.length > 1) { + } else if (getSlaves().length > 1) { div.append(`You have not selected a Head Girl`); if (V.arcologies[0].FSEgyptianRevivalistLaw === 1) { div.append(` and Consort`); @@ -180,7 +180,7 @@ App.UI.View.mainLinks = function() { return (typeof organ === 'object' && getSlave(organ.ID) !== undefined); }); /* cycle through slaves, for each slave cycle through completed organs and track how many are of the interrogated slave (and if organs have a slaves to be implanted on) */ - for (const slave of V.slaves) { + for (const slave of getSlaves()) { const slaveOrgans = V.completedOrgans.reduce((acc, organ) => organ.ID === slave.ID ? acc + 1 : acc, 0); /* if the interrogated slave has one or more organs ready: */ if (slaveOrgans > 0) { diff --git a/src/interaction/main/walkPastList.js b/src/interaction/main/walkPastList.js index de78109e5a573fda69447578a225a7ae03c3a9a5..e8ff9dd5f908182e9a8609833c41f74639da3086 100644 --- a/src/interaction/main/walkPastList.js +++ b/src/interaction/main/walkPastList.js @@ -30,7 +30,7 @@ App.UI.walkPastAll = function() { * @returns {DocumentFragment} */ function walkPastCategory(fixedTarget) { - return App.UI.DOM.combineNodes(...V.slaves.map( + return App.UI.DOM.combineNodes(...getSlaves().map( (s) => App.UI.DOM.makeElement("p", walkPast(s, fixedTarget)) )); } diff --git a/src/interaction/policies/changeLanguage.js b/src/interaction/policies/changeLanguage.js index 1c70d6ed7d646f57945d836378ddd735f0617b62..74ab085bb769e4ee74fe049c1481b6f9917b9c41 100644 --- a/src/interaction/policies/changeLanguage.js +++ b/src/interaction/policies/changeLanguage.js @@ -52,7 +52,7 @@ App.Arcology.changeLanguage = function() { function setLanguage(targetLanguage) { V.language = targetLanguage; V.arcologies[0].prosperity = Math.trunc(0.9 * V.arcologies[0].prosperity); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.fetish !== Fetish.MINDBROKEN) { nationalityToAccent(slave); if (slave.accent >= 3) { diff --git a/src/interaction/policies/coursingAssociation.js b/src/interaction/policies/coursingAssociation.js index aaa780153aa066133ed061d2c8fe0e7a506c0ac9..174da7d8605d134445aaecb6bc75c4a9f5ffdf13 100644 --- a/src/interaction/policies/coursingAssociation.js +++ b/src/interaction/policies/coursingAssociation.js @@ -7,7 +7,7 @@ App.UI.coursingAssociation = function() { r.push(`The chasing slaves are known as lurchers, the term once used for the sighthounds. They require speed most of all, but must also be able to tackle their quarry; lurchers with the ability and willingness to make a spectacle of molesting the hares can improve their owners' reputations.`); if (V.LurcherID !== 0) { - r.push(`${SlaveFullName(slaveStateById(V.LurcherID))} is assigned to compete as your lurcher.`); + r.push(`${SlaveFullName(getSlave(V.LurcherID))} is assigned to compete as your lurcher.`); } else { r.push(`You have not selected a lurcher, meaning that you will not participate in coursing events.`); } diff --git a/src/interaction/saleFunctions.js b/src/interaction/saleFunctions.js index 6fe020d2f77c4fce58d16b7bfb8c1dbe312f9e6c..68c900458f187c450a1d46047909940538cc287d 100644 --- a/src/interaction/saleFunctions.js +++ b/src/interaction/saleFunctions.js @@ -2,7 +2,7 @@ App.Interact.Sale.separationReactions = function(slave) { const {sister, daughter, father, mother} = getPronouns(slave); const resultNode = document.createDocumentFragment(); - for (const s of V.slaves) { + for (const s of getSlaves()) { const {his2} = getPronouns(s).appendSuffix("2"); if (slave.mother === s.ID) { App.Events.addNode(resultNode, [`${s.slaveName} is <span class="devotion dec">grieved</span> that you are selling ${his2} ${daughter}.`], "div"); @@ -45,7 +45,7 @@ App.Interact.Sale.separationReactions = function(slave) { } else if (slave.relationship === -3) { App.Events.addParagraph(resultNode, [`Selling one of your slave wives is <span class="reputation dec">socially unacceptable.</span> In addition, your other devoted slaves are <span class="trust dec">worried</span> that you may not respect their status.`]); repX(-200, "slaveTransfer"); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion > 50) { s.trust -= 5; } diff --git a/src/interaction/selectPartner.js b/src/interaction/selectPartner.js index 8090292e0c642217da6026262209c35dd33ad106..5734d914902d0a65248be5e71202bd79e4d44831 100644 --- a/src/interaction/selectPartner.js +++ b/src/interaction/selectPartner.js @@ -41,7 +41,7 @@ App.Interact.choosePartner = function(renderer, target, refresh) { App.UI.DOM.appendNewElement("div", node, renderer.intro); const slave = renderer.slave; - const eligibles = V.slaves.filter((s) => (s.ID !== slave.ID) && renderer.eligible(s)); + const eligibles = getSlaves().filter((s) => (s.ID !== slave.ID) && renderer.eligible(s)); for (const eligible of eligibles) { const div = App.UI.DOM.appendNewElement("div", node); div.append(App.UI.DOM.link( diff --git a/src/interaction/sellSlave.js b/src/interaction/sellSlave.js index dfcac8902bc953f78f14805cb07ade497bbafbae..b1a8335744f5dc38080f9c6066de2b7a223b20e2 100644 --- a/src/interaction/sellSlave.js +++ b/src/interaction/sellSlave.js @@ -859,7 +859,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is quickly escorted out by ${his} new master. ${He} is rarely seen in public anymore, but ${his} records show ${he} is settling well into being ${his} new owner's breeder.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.breedingMark !== 1 && V.propOutcome === 1) { s.devotion -= 5; slaveImpact = 1; @@ -958,7 +958,7 @@ App.Interact.sellSlave = function(slave) { if (V.PC.father === V.AS) { V.boomerangStats.PCfather = V.AS; } - for (const s of V.slaves) { // TODO: review for hyper fertility compatibility + for (const s of getSlaves()) { // TODO: review for hyper fertility compatibility if (s.ID !== V.AS) { if (s.mother === V.AS) { V.boomerangStats.boomerangMother.push(s.ID); @@ -1000,7 +1000,7 @@ App.Interact.sellSlave = function(slave) { V.boomerangStats.boomerangRivalry = slave.rivalryTarget; } if (slave.bodySwap > 0) { - const myBody = V.slaves.find(s => s.origBodyOwnerID === V.AS); + const myBody = getSlaves().find(s => s.origBodyOwnerID === V.AS); if (myBody) { V.boomerangStats.boomerangBody = myBody.ID; } @@ -1036,7 +1036,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} settles into ${his} new life in a humbler part of ${V.arcologies[0].name}, and can occasionally be seen accompanying ${his} master in public.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.trust >= -20) { if (s.physicalAge > 30) { s.trust += 1; @@ -1059,7 +1059,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} settles in to ${his} new role easily enough; ${he}'s one of the most pampered slaves in the arcology. All ${he}'s expected to do is light housework and self-maintenance, along with gentle unprotected vaginal sex with ${his} new master.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "pregnancy") { if (s.fetishKnown === 1) { s.trust += 1; @@ -1082,7 +1082,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is seen in a research report nine months later; ${he} has undergone some interesting changes. As expected by someone interested in ${his} odd womb, ${he} is quite pregnant, but what really stands out is the massive size of ${his} testicles and ${his} huge round implants. A quick glance at the article reveals that they aren't implants; in fact, ${his} breasts and testicles are rounded with children.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.mpreg === 1) { s.trust -= 5; slaveImpact = 1; @@ -1121,7 +1121,7 @@ App.Interact.sellSlave = function(slave) { r.push(`${his} torso teetering`); } r.push(`pathetically atop its quivering mass. The headline reads "New drug allows for upwards of seven hundred children carried at once". Live on stream, ${his} body loses stability and ruptures, flooding the room with fluid and children.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.vagina === 0) { if (isFertile(s)) { s.trust -= 20; @@ -1145,7 +1145,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is seen nearly a year later, happy and healthy, along with ${his} owner and newborn son. They are quite a good looking family.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.intelligence + s.intelligenceImplant < -15) { if (isFertile(s)) { s.devotion -= 2; @@ -1174,7 +1174,7 @@ App.Interact.sellSlave = function(slave) { } else { r.push(`moans lewdly as ${his} children kick away in ${his} womb.`); } - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.vagina === 0) { if (isFertile(s)) { if (s.fetish === "pregnancy") { @@ -1200,7 +1200,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is seen in a shipment of slaves leaving the arcology a month later, with just the slightest hint of a gravid belly and a worn-down expression on ${his} face.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.vagina === 0) { if (s.ovaries === 1) { s.trust -= 2; @@ -1223,7 +1223,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is soon seen on live TV, restrained and still grotesquely pregnant. ${He} screams into ${his} restraints as the host approaches with a comically large syringe of abortifacients and drives it deep into ${his} womb. Within minutes, a flood of liquid and fetuses are pouring from ${his} gaping cunt, all the while he times how long it takes ${his} overburdened womb to drain of all its contents.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.bellyPreg >= 300000) { s.trust -= 15; slaveImpact = 1; @@ -1245,7 +1245,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s new mistress is an exhibitionist as well as a nipple fetishist, and before long, she's seen in the club, riding ${slave.slaveName}'s chest with her wet pussy. The slave is expected to keep ${his} nipples erect for her at all times.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "boobs") { if (s.fetishKnown === 1) { s.trust += 1; @@ -1268,7 +1268,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s new master is an exhibitionist as well as a nipple fetishist, and before long, he's seen in the club, plowing ${slave.slaveName}'s engorged breasts. Since nipple cunts aren't naturally lubricated, some owners find stimulating milk production a suitable replacement; judging from the pooling fluids and sympathetic gushes from ${his} ignored tit, he is one of them.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "boobs") { if (s.fetishKnown === 1) { if (s.nipples === "fuckable") { @@ -1299,7 +1299,7 @@ App.Interact.sellSlave = function(slave) { r.push(`moving`); } r.push(`a little oddly. ${His} naked dick has the flaccidity of sexual satiation, and ${he} has a tired but dreamy expression on ${his} face.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "buttslut") { if (s.fetishKnown === 1) { s.trust += 1; @@ -1322,7 +1322,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`The next time ${slave.slaveName} is seen in public, ${he}'s obediently accompanying ${his} new master. After doing some business on the promenade, he pulls ${him} into an alcove and lets ${him} masturbate as he uses ${his} throat.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "cumslut") { if (s.fetishKnown === 1) { s.trust += 1; @@ -1345,7 +1345,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is not seen again in public for a long time, but the crack of leather on flesh and the resultant hoarse female howling that issues from ${his} new mistress's apartment is well-known.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "masochist") { if (s.fetishKnown === 1) { s.trust += 1; @@ -1368,7 +1368,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} rarely leaves ${his} new mistress's apartments, but the slave rumor mill bears stories about ${him} to your penthouse anyway. ${His} mistress uses ${him} as a rapist on demand, and ${his} dumbly obedient brutality is renowned.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "sadist") { if (s.fetishKnown === 1) { s.trust += 1; @@ -1391,7 +1391,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} wins ${himself} a leadership position with ${his} new master, who repays ${his} hard work by allowing ${him} to use his slaves at will.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "dom") { if (s.fetishKnown === 1) { s.trust += 1; @@ -1414,7 +1414,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`The back of ${slave.slaveName}'s head becomes a well-known sight in business circles, since ${his} mistress rarely lets it out from between her legs.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === Fetish.SUBMISSIVE) { if (s.fetishKnown === 1) { s.trust += 1; @@ -1437,7 +1437,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`In short order, ${slave.slaveName} is heard out on the promenade, sobbing and screaming as ${his} new owner breaks in ${his} virgin butt in public.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.anus === 0) { s.trust -= 2; slaveImpact = 1; @@ -1458,7 +1458,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is soon well-known among the slaves of the arcology, as many of them are sold after passing under ${his} hands in training. ${He} performs effectively, imparting good sex slave ethics in a generation of sluts.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.intelligence + s.intelligenceImplant > 15) { s.trust += 1; slaveImpact = 1; @@ -1479,7 +1479,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} becomes a common sight around the arcology, training slaves for ${his} new master. They're usually seen hanging close by ${him} as ${he} manages them with an air at once protective and frankly sexual.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.actualAge > 35) { s.trust += 1; slaveImpact = 1; @@ -1500,7 +1500,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} becomes quite a fixture at social events hosted by ${his} new master; he enjoys showing off how healthy, happy and productive his cow is.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.lactation > 0) { s.trust += 1; slaveImpact = 1; @@ -1521,7 +1521,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} heads off to form part of whatever great design ${his} new master is pursuing; all you know is that it apparently requires lots of lithe, sharp toothed slave ${girl}s.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion <= 20) { s.trust += 1; slaveImpact = 1; @@ -1542,7 +1542,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is quickly embraced by ${his} new owner and spirited away like all the other ${girl}s that catch his fancy.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion <= 20) { s.trust += 1; slaveImpact = 1; @@ -1563,7 +1563,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s buyer takes charge of ${him}, and cannot resist immediately running a hand between ${his} buttocks to sink a couple of groping fingers into ${his} soft asspussy.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "buttslut") { s.trust += 1; slaveImpact = 1; @@ -1610,7 +1610,7 @@ App.Interact.sellSlave = function(slave) { if (random(1, 3) === 1 && V.seePreg !== 0) { // Monster movie r.push(`${slave.slaveName} soon makes ${his} debut on the big screen in a thrilling horror movie. At its end, the male lead finds his partner, played by ${him} in this scene, glued to a wall with a massively distended middle filled to capacity with the monster's spawn. The camera slowly zooms in on ${him} as ${he} gives birth to a future sequel.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.sexualFlaw === "breeder") { s.devotion -= 2; slaveImpact = 1; @@ -1622,7 +1622,7 @@ App.Interact.sellSlave = function(slave) { } else { // Sex Double r.push(`${slave.slaveName} soon makes ${his} debut on the big screen in a debaucherous gangbang in place of the popular lead. ${He} is a spitting image of the actress, even when coated in layers of semen.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.sexualFlaw === "attention whore") { s.devotion -= 2; slaveImpact = 1; @@ -1644,7 +1644,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is an occasional sight around the arcology; ${he}'s never seen outside the company of ${his} new slave superior. This is one of ${his} new master's more favored slaves. ${He} has a huge cock, and ${slave.slaveName} is usually seen crouching down, hugging one of ${his} superior's legs and keeping ${his} mouth obediently near that dick.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetishKnown === 1) { if (s.fetish === "cumslut") { s.trust += 1; @@ -1667,7 +1667,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} becomes a frequent sight around the arcology, accompanying ${his} new master. ${He}'s clearly happy, and is frequently seen to offer ${his} butt to him with a smile.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.dick > 0) { if (s.devotion > 20) { s.trust += 1; @@ -1690,7 +1690,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s buyer arrives promptly; he seems pleased with his new slave's bountiful bottom, so far off the ground.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "buttslut") { if (s.fetishKnown === 1) { s.trust += 1; @@ -1713,7 +1713,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s buyer arrives and seems pleased with ${his} lovely feminine appearance; he verifies ${his} lactation and ${his} ability to achieve erection despite ${his} lack of visible balls.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.dick > 0) { if (s.boobs > 400) { s.trust += 1; @@ -1735,7 +1735,7 @@ App.Interact.sellSlave = function(slave) { get completeSale() { const r = []; r.push(`When ${slave.slaveName}'s buyer appears, the big ${girl} is almost bashful. He tries to resist the impulse, but quickly breaks down and sweeps ${him} into a tight hug. ${He} accepts the embrace meekly. Your other slaves find this <span class="trust inc">very romantic.</span>`); - for (const s of V.slaves) { + for (const s of getSlaves()) { s.trust += 1; } return r; @@ -1750,7 +1750,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s lithe, muscular form is rarely seen after ${his} buyer takes charge of ${him}, since ${he} seems to spend most of ${his} time at home making babies.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetish === "pregnancy") { if (s.fetishKnown === 1) { s.trust += 4; @@ -1773,7 +1773,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is an occasional sight around the arcology; ${he}'s never seen outside the company of ${his} new slave superior. This is one of ${his} new master's more favored slaves. ${He} has a huge cock, and ${slave.slaveName} is usually seen crouching down, hugging one of ${his} superior's legs and keeping ${his} mouth obediently near that dick.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.fetishKnown === 1) { if (s.fetish === "cumslut") { s.trust += 1; @@ -1796,7 +1796,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s nervous buyer comes to collect ${him}, stammering and sweating and doing his best to pretend he does this all the time.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.counter.vaginal + s.counter.anal < 20) { s.trust += 1; slaveImpact = 1; @@ -1816,7 +1816,7 @@ App.Interact.sellSlave = function(slave) { get completeSale() { const r = []; r.push(`${slave.slaveName} is never seen again. ${His} buyer prefers to keep whatever happened to ${him} private. However, rumors of steaks, rump roasts, sweetbreads, and blood pudding eaten at three in the morning filter out from time to time. Naturally, these murmurs never fail to <span class="trust dec">terrify</span> your other slaves.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { s.trust -= 2; } return r; @@ -1831,7 +1831,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is rarely seen after ${his} buyer takes charge of ${him}, since he prefers to keep his prize safe and sound at home.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.porn.prestige === 1) { if (s.devotion > 20) { s.trust += 1; @@ -1854,7 +1854,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} becomes a frequent sight in ${slave.porn.fameType} smut and attracts huge crowds with each public appearance.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.porn.prestige.isBetween(0, 3)) { if (s.devotion > 20) { s.trust += 2; @@ -1877,7 +1877,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is not pleased by ${his} change in circumstances, since ${he} is soon subjected to training rigor that ${he} did not experience while your property.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.intelligenceImplant < 15) { s.trust -= 2; slaveImpact = 1; @@ -1898,7 +1898,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`A few weeks later, ${slave.slaveName} is seen in a shipment of slaves heading out of the arcology. ${He} has new fake tits, a bigger butt, lip implants, and even some facial bone structure alterations, but ${his} balloon breasts are the most shocking change.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.boobsImplant === 0) { s.trust -= 2; slaveImpact = 1; @@ -1919,7 +1919,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`A few weeks later, ${slave.slaveName} is seen in a shipment of slaves heading out of the arcology. ${He} is almost unrecognizable, having been quickly returned to as natural an appearance as skillful removal of ${his} implants could manage.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.boobsImplant > 800) { s.trust += 1; slaveImpact = 1; @@ -1940,7 +1940,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is occasionally visible around the arcology, looking rather tired and gaunt under the stresses of a severe crash diet coupled with a punishing cardio regime.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.weight > 10) { s.trust -= 2; slaveImpact = 1; @@ -1961,7 +1961,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is only rarely seen around the arcology, since ${his} new owners force ${him} to spend most of ${his} time sleeping, eating and looking after ${himself}. But ${his} belly, painfully distended with food, makes ${his} situation obvious.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.weight > 10) { s.trust -= 2; slaveImpact = 1; @@ -1982,7 +1982,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is last seen somewhat later, packed into a shipment of cows heading out of the arcology. ${He} looks rather ill from the drugs ${he}'s been filled with, and ${his} now-distended breasts are marred by unsightly stretch marks.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.lactation === 0) { s.trust -= 2; slaveImpact = 1; @@ -2003,7 +2003,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is frequently seen in public over the next few weeks, since ${he}'s being trained to improve ${his} feminine deportment. ${He} grows visibly more feminine as time passes, as the hormonal effects of having ${his} balls cut off become apparent.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.balls > 0) { s.trust -= 2; slaveImpact = 1; @@ -2024,7 +2024,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is next seen after some weeks of surgery. ${He}'s barely recognizable, and now possesses a serviceable vagina which ${he} clearly is unsure of. ${His} original status is scarcely discernible.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.dick > 0) { s.trust -= 2; slaveImpact = 1; @@ -2045,7 +2045,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is subjected to a stock assay and then packed off to take ${his} place as a prize heifer.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.lactation === 0) { if (s.devotion <= 20) { s.trust -= 2; @@ -2068,7 +2068,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s journey to ${his} new home is respectful, even celebratory, as far as you can see. ${He} is gravely informed by the purchasing agent that many slaves await ${his} learned instruction.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.intelligence + s.intelligenceImplant < -50) { s.devotion -= 2; slaveImpact = 1; @@ -2089,7 +2089,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is transported after losing a military engagement. Though ${his} will remains strong, ${he}'s <span class="trust dec">filled with fear</span> when ${he} sees the rivers of blood that flow through the city.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.skill.combat > 30) { s.trust -= 2; slaveImpact = 1; @@ -2110,7 +2110,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is shipped to a new arcology, and culturally, across the centuries. ${His} skill at arms is well enough known that ${his} impending role as a gladiatrix is easily deduced.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.skill.combat > 30) { s.trust -= 2; slaveImpact = 1; @@ -2131,7 +2131,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is taken away by an expensive, flashy shuttle shortly after you finalize the trade. ${He} is swept into a life of luxury; the next time you see ${him}, ${he}'s dressed in a manner more befitting of a consort than a simple slave.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.intelligence + s.intelligenceImplant > 50) { s.devotion -= 2; slaveImpact = 1; @@ -2152,7 +2152,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is terrified of ${his} impending religious life; perhaps ${he}'s heard the new text that reads 'no woman come of age is holy unless she performs the act as many times per day as she has years less than forty.'`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.counter.anal < 200) { s.trust -= 2; slaveImpact = 1; @@ -2173,7 +2173,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`Stories about the arcology ${slave.slaveName} is headed to have circulated among slaves. Most intelligent slaves see a life of workouts as relatively harmless.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.weight > 10) { if (s.intelligence + s.intelligenceImplant < -15) { s.trust -= 2; @@ -2196,7 +2196,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is taken away to join a quivering mass of plump, pampered ladies that crowd the bedroom of ${his} new owner.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.behavioralFlaw === "gluttonous") { s.devotion -= 2; slaveImpact = 1; @@ -2217,7 +2217,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s new owner is quite fond of his work and typically sends out photos of his progress. This is no exception; you are treated to a series of images featuring ${slave.slaveName} being force-fed until ${his} stomach bulges. Day after day, you watch ${him} handle more and more food until ${his} belly is big enough to fill ${his} lap even when empty.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.weight < 10) { s.trust -= 2; slaveImpact = 1; @@ -2238,7 +2238,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`A purchasing agent arrives for ${slave.slaveName}; he uses a lull in the proceedings to use a permanent marker to begin mapping out surgical sites across ${his} body. There are a lot of them.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion <= 20) { s.trust -= 2; slaveImpact = 1; @@ -2260,7 +2260,7 @@ App.Interact.sellSlave = function(slave) { let slaveImpact; r.push(`A shipping container arrives for ${slave.slaveName}; as ${he}'s loaded into it, it sedates ${him} and begins to pump hormones, curatives and growth enhancers into no less than seven places scattered over ${his} body.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion <= 20) { s.trust -= 2; slaveImpact = 1; @@ -2281,7 +2281,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is taken away to join the tribe of squealing, slim forms that populate the arcology of ${his} new owner.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.intelligence + s.intelligenceImplant > 50) { s.devotion -= 2; slaveImpact = 1; @@ -2302,7 +2302,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is shipped to ${his} new owner's arcology to have ${his} implants extracted and the resultant damage addressed.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion <= 50) { if (s.boobsImplant > 1000) { s.devotion -= 2; @@ -2325,7 +2325,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`Stories about the place ${he}'s going have reached ${V.arcologies[0].name}, and ${slave.slaveName} suspects the fate ${he}'s been condemned to when ${he}'s loaded into a shipping container expressly designed to keep the inmate awake and uncomfortable.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion > 20) { s.trust -= 2; slaveImpact = 1; @@ -2346,7 +2346,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is shipped off to be improved into a happy, educated slave at the best pace ${his} new owner can manage.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion < -20) { if (s.intelligence + s.intelligenceImplant < -15) { s.devotion -= 2; @@ -2369,7 +2369,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is taken away to join the legion of airheaded, big-titted sex slaves that throng the arcology owned by ${his} purchaser.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.intelligence + s.intelligenceImplant > 50) { s.devotion -= 2; slaveImpact = 1; @@ -2390,7 +2390,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is shipped off, but ${his} buyer is so unwilling to waste any time that the shipment container includes hormonal injectors to get ${him} started on an intensive feminization regime as quickly as possible.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.dick > 0) { if (s.devotion <= 20) { s.trust -= 2; @@ -2413,7 +2413,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} leaves your control forthwith, to be freed and installed in a favored life in an arcology that gives ${slave.race} people every possible advantage.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion < 10) { s.devotion -= 2; slaveImpact = 1; @@ -2434,7 +2434,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is shipped off to help produce a race of ${slave.race} idiots to perform eternal servitude. ${He} is not perceptive enough to fear ${his} upcoming life as a downtrodden breeder.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.intelligence + s.intelligenceImplant > 15) { s.trust -= 2; slaveImpact = 1; @@ -2455,7 +2455,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is soon seen on shift outside a seedy establishment in the lower arcology, mechanically offering ${his} holes to passersby and flinching whenever ${his} superiors come out to check on ${him}.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.assignment === Job.WHORE || s.assignment === Job.BROTHEL) { s.trust -= 2; slaveImpact = 1; @@ -2483,7 +2483,7 @@ App.Interact.sellSlave = function(slave) { } else { r.push(`tits.`); } - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion <= 50) { s.trust -= 2; slaveImpact = 1; @@ -2504,7 +2504,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`The upper half of ${slave.slaveName}'s body is never seen again. ${His} butt, on the other hand, is periodically visible in a lower-level arcade, ${his} orifices gradually showing the wear and ${his} price gradually decreasing, until finally ${he} is seen no more.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.devotion < 10) { s.trust -= 2; slaveImpact = 1; @@ -2525,7 +2525,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`The breeder already has stud stock, and ${slave.slaveName} is rapidly impregnated. ${He}'s kept in a stockyard on the lower service levels of the arcology, one of a dense crowd of beaten-down women with gravid bellies.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.ovaries === 1) { s.trust -= 2; slaveImpact = 1; @@ -2546,7 +2546,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} disappears for a time as ${his} training is perfected, but ${he} reappears in the refined brothel, wearing classy clothes and flirting gracefully with patrons of ${his} body.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if ((s.assignment === Job.WHORE) || (s.assignment === Job.BROTHEL)) { s.trust += 1; slaveImpact = 1; @@ -2567,7 +2567,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is a common sight around the arcology, since free range cows are allowed to range between milkings. ${He} seems reasonably content.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if ((s.assignment === Job.MILKED) || (s.assignment === Job.DAIRY)) { s.trust += 1; slaveImpact = 1; @@ -2588,7 +2588,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName} is a common sight around the arcology, since free range cows are allowed to range between milkings. ${He} seems reasonably content.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.milkFlavor !== "none") { s.trust += 1; slaveImpact = 1; @@ -2608,7 +2608,7 @@ App.Interact.sellSlave = function(slave) { get completeSale() { const r = []; r.push(`Though ${slave.slaveName}'s fate as a source of organs for transplantation is not announced, rumors of what happens to those who <span class="trust dec">fail to be valuable to you</span> pass among your slaves.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { s.trust -= 2; } return r; @@ -2622,7 +2622,7 @@ App.Interact.sellSlave = function(slave) { get completeSale() { const r = []; r.push(`Though ${slave.slaveName}'s fate as a living fucktoy is not obvious, since most of ${his} body will forever after be encased in thick latex, rumors of what happens to those who <span class="trust dec">fail to be valuable to you</span> pass among your slaves.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { s.trust -= 2; } return r; @@ -2637,7 +2637,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`Sometime later, a snuff film starring ${slave.slaveName} as a heroine captured, raped, and fatally bred by tentacles is released. It receives rave reviews for the scene involving ${slave.slaveName}, depicting ${his} aphrodisiac-filled body being penetrated in all ${his} holes by tentacles. Their thrusting into ${him} increases until large bulges of cum pass through the ones filling ${his} stretched cunt, visibly bloating ${his} belly. ${He} then collapses to the ground, ${his} swollen belly rapidly growing with the tentacle spawn gestating within ${him}. As they bulge against the straining walls of ${his} implant-filled middle; ${he} lets out a final moan as ${his} belly ruptures, releasing ${his} "spawn" to hunt down the other heroines.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (canSee(s)) { if (s.intelligence + s.intelligenceImplant < -15) { s.devotion -= 4; @@ -2673,7 +2673,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`As ${slave.slaveName} now spends all ${his} time backstage, ${he}'s rarely seen again. Occasionally, however, a roadie will bring ${him} outside as he hauls the equipment, and ${he} jacks him off.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.hears < 0) { s.trust += 1; slaveImpact = 1; @@ -2694,7 +2694,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`${slave.slaveName}'s new etiquette trainer sends you courtesy updates on ${his} progress, as ${he} learns proper poise and enunciation, the correct locations of silverware, and how to avoid making vulgar comments while performing lascivious acts.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.sexualFlaw === "crude") { s.trust -= 1; slaveImpact = 1; @@ -2715,7 +2715,7 @@ App.Interact.sellSlave = function(slave) { const r = []; let slaveImpact; r.push(`The mercenary sniper greets ${slave.slaveName} before the two of them head off for a battlefield halfway around the world. "Let's hope you've got a good eye for political assassinations," he says humorlessly.`); - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.skill.combat <= 15) { s.trust -= 3; slaveImpact = 1; @@ -2740,7 +2740,7 @@ App.Interact.sellSlave = function(slave) { "lusty futanari": s => boolToNum(s.balls > 0 && s.scrotum > 0 && s.dick > 0 && s.vagina > -1 && s.devotion > 0) * Math.clamp((s.energy + s.devotion) / 150, 0, 1.2), "cum addicts": s => (boolToNum(s.fetish === "cumslut") * s.fetishStrength / 120) + 0.5 * boolToNum(s.sexualFlaw === "cum addict"), "flesh balloons": s => Math.clamp((s.belly-10000) / 10000, 0, 1.2) * Math.clamp(s.butt / 9, 0, 1.2), - "big-breasted cows": s => boolToNum(s.lactation > 1) * Math.clamp((s.boobs - 1200) / 1000, 0, 1.4), + "big-breasted cows": s => boolToNum(s.lactation >= 1) * Math.clamp((s.boobs - 1200) / 1000, 0, 1.4), "fertile virgins": s => boolToNum(s.vagina >= 0 && s.vagina <= 1) * ((s.vagina === 0 ? 0.6 : 0) + (isFertile(s) ? 0.6 : 0) + (s.anus === 0 ? 0.15 : 0) - 0.2), "baby obsessed breeders": s => (boolToNum(s.fetish === "pregnancy") * s.fetishStrength / 120) + 0.5 * boolToNum(s.sexualFlaw === "breeder"), "lusty preggos": s => boolToNum(s.devotion > 0) * boolToNum(s.preg > s.pregData.normalBirth / 4) * Math.clamp((s.energy + s.devotion) / 150, 0, 1.2), diff --git a/src/interaction/siCustom.js b/src/interaction/siCustom.js index 1d8ebe98feb9a12899d6376897855b978a98f7a1..e71995b55170cb0985bc072a149d92279e212a0d 100644 --- a/src/interaction/siCustom.js +++ b/src/interaction/siCustom.js @@ -548,14 +548,11 @@ App.UI.SlaveInteract.custom = function(slave, refresh) { } function updateName(slave, {oldName: oldName, oldSurname: oldSurname}) { - // @ts-ignore you shouldn't access V.genePool directly because it isn't supposed to change; this is an exception; For normal use use getGenePoolRecord() - let genepoolRec = isInGenePool(slave) ? getGenePoolRecord(slave, false, true) : undefined; + let genepoolRec = isInGenePool(slave) ? getGenePoolRecordWriteMode(slave) : undefined; if (genepoolRec) { genepoolRec.slaveName = slave.slaveName; genepoolRec.slaveSurname = slave.slaveSurname; App.UI.SlaveInteract.rename(slave, {oldName: oldName, oldSurname: oldSurname}); - } else { - console.error(`slave with ID ${slave.ID} is missing its gene pool record`); } refresh(); } diff --git a/src/interaction/siFamily.js b/src/interaction/siFamily.js index 555727de9e5d688cf80827e02503a9a976251eb9..c4622adc52c8856c6cf9d4d9b059d8313a3b4b07 100644 --- a/src/interaction/siFamily.js +++ b/src/interaction/siFamily.js @@ -5,7 +5,7 @@ App.UI.SlaveInteract.family = function(slave) { const p = document.createElement("p"); p.id = "family"; - p.append(renderFamilyTree(V.slaves, slave.ID)); + p.append(renderFamilyTree(getSlaves(), slave.ID)); return p; }; diff --git a/src/interaction/siNavigation.js b/src/interaction/siNavigation.js index f0368d774e6a18e3c08d24b18533c22bc5f07243..b22ce706203b40fd7d1e7ed27de935bdf2dbdbdf 100644 --- a/src/interaction/siNavigation.js +++ b/src/interaction/siNavigation.js @@ -17,7 +17,7 @@ App.UI.SlaveInteract.navigation = function(slave) { */ App.UI.DOM.appendNewElement("div", f, App.UI.DOM.passageLink("Cheat Edit Slave", "Cheat Edit Actor", () => { - App.Verify.slaveState(`getSlave(${V.AS})`, getSlave(V.AS), "V.slaves"); + App.Verify.slaveState(`getSlave(${V.AS})`, getSlave(V.AS), "main slave pool"); V.tempActor = clone(getSlave(V.AS)); }), "cheat-menu" diff --git a/src/interaction/siRecords.js b/src/interaction/siRecords.js index 6b19c336f9426c3dc8c85100119873ae42af3a3e..bb3034658e3cf9b37668948a5379abfd4a04ff70 100644 --- a/src/interaction/siRecords.js +++ b/src/interaction/siRecords.js @@ -251,7 +251,7 @@ App.UI.SlaveInteract.records = function (slave, refresh) { r.push(App.UI.DOM.makeElement("span", `The slave market is bearish; the price of slaves is low.`, ["yellow"])); } - if (V.slaves.length < 2) { + if (getSlaves().length < 2) { r.push("You cannot sell your last slave"); } else if (slave.origin === "You bought $him from a body dump, completely broken." && (V.week - slave.weekAcquired <= 8)) { r.push(`A discarded slave must be kept for at least two months to ensure health before being sold.`); diff --git a/src/interaction/siUtilities.js b/src/interaction/siUtilities.js index d344f78c0c99c4fb853b6ced2bff26477f3603de..da656f4a41931f166483223584421d8db1b6ccb8 100644 --- a/src/interaction/siUtilities.js +++ b/src/interaction/siUtilities.js @@ -4,7 +4,7 @@ */ App.UI.SlaveInteract.placeInLine = function(slave) { const useSlave = assignmentVisible(slave) ? ((s) => assignmentVisible(s)) : ((s) => slave.assignment === s.assignment); - const slaveList = V.slaves.filter(useSlave); + const slaveList = getSlaves().filter(useSlave); SlaveSort.slaves(slaveList); const curSlaveIndex = slaveList.findIndex((s) => s.ID === slave.ID); diff --git a/src/interaction/siWork.js b/src/interaction/siWork.js index 8e9aee6800852f3cb7ee01fce6002b6256ed115f..05f2d8c280bfc08abf312b7521af2aa478727f49 100644 --- a/src/interaction/siWork.js +++ b/src/interaction/siWork.js @@ -614,7 +614,7 @@ App.UI.SlaveInteract.work = function(slave, refresh) { } sexOptions.push({text: `Abuse ${him}`, scene: () => App.Interact.fAbuse(slave)}); if (V.seeIncest === 1 && totalRelatives(slave) > 0) { - const availableRelatives = V.slaves.filter(s => areRelated(s, slave) && isSlaveAvailable(s)); + const availableRelatives = getSlaves().filter(s => areRelated(s, slave) && isSlaveAvailable(s)); if (availableRelatives.length > 1) { sexOptions.push({ text: `Fuck ${him} with one of ${his} close relatives`, diff --git a/src/interaction/universalRules.js b/src/interaction/universalRules.js index d4adb34ba6c0414c9bf9eee14ff16126441f7601..6bcf9fbb0e7688527f82c2193778282992bad255 100644 --- a/src/interaction/universalRules.js +++ b/src/interaction/universalRules.js @@ -83,7 +83,7 @@ App.UI.universalRules = function() { .addValue("Yes", 0).on() .addValue(`No going forward`, 1).off() .customButton(`No and strip all current surnames`, () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slave.slaveSurname = 0; } V.surnamesForbidden = 1; @@ -199,7 +199,7 @@ App.UI.universalRules = function() { if (!V.StudID) { r.push(`Fertile slaves will be systematically impregnated by a Stud, once you designate a subordinate slave to act as such.`); } else { - const stud = slaveStateById(V.StudID); + const stud = getSlave(V.StudID); const {he} = getPronouns(stud ? stud : {pronoun: App.Data.Pronouns.Kind.plural}); r.push(`Fertile slaves will be systematically impregnated by your Stud, if ${he} is able to do so.`); } diff --git a/src/interaction/useSlave/useSlaveOptions.js b/src/interaction/useSlave/useSlaveOptions.js index a637a1adb4852eddf99cd3442d63eeb511695689..bb5f693b073beb118d7cb4960583e2cd3eede815 100644 --- a/src/interaction/useSlave/useSlaveOptions.js +++ b/src/interaction/useSlave/useSlaveOptions.js @@ -832,7 +832,7 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta link: `Bring in another slave`, desc: generalText.bringInSlave(clone), tooltip: `Have another slave join the two of you.`, - prereq: () => V.slaves.length > 1 && + prereq: () => getSlaves().length > 1 && slaveState.sexAct === null, effect: () => { return; // temporarily disabled diff --git a/src/js/assignJS.js b/src/js/assignJS.js index 2d5881ac3e98a83cb366b8717389549dab23dee3..767287b679da553d63a0d0eff706b243ea336980 100644 --- a/src/js/assignJS.js +++ b/src/js/assignJS.js @@ -42,7 +42,7 @@ globalThis.assignJob = function(slave, job) { const specialIDProp = `${propName}ID`; const prevAssigneeID = V[specialIDProp]; if (prevAssigneeID !== slave.ID) { - removeJob(slaveStateById(prevAssigneeID), job, true); + removeJob(getSlave(prevAssigneeID), job, true); } V[specialIDProp] = slave.ID; } @@ -638,7 +638,7 @@ globalThis.removeJob = function(slave, assignment, saveRecord = false) { case "be your head girl": { slave.assignment = Job.REST; - const HGSlave = V.slaves.find(s => s.assignment === Job.HEADGIRLSUITE); + const HGSlave = getSlaves().find(s => s.assignment === Job.HEADGIRLSUITE); if (HGSlave) { removeJob(HGSlave, Job.HEADGIRLSUITE); if (V.HGSuiteEquality === 1 && HGSlave.devotion > 50) { @@ -667,7 +667,7 @@ globalThis.removeJob = function(slave, assignment, saveRecord = false) { slave.assignment = Job.REST; if (slave.relationshipTarget > 0) { /* following code assumes there can be at most one companion */ - const lover = V.slaves.find(s => haveRelationshipP(s, slave) && s.assignment === Job.AGENTPARTNER); + const lover = getSlaves().find(s => haveRelationshipP(s, slave) && s.assignment === Job.AGENTPARTNER); if (lover) { removeJob(lover, Job.AGENTPARTNER, saveRecord); } @@ -754,7 +754,7 @@ globalThis.makeJobIdMap = function() { res[jn] = new Set(); } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { res[slave.assignment].add(slave.ID); } @@ -804,7 +804,7 @@ App.UI.jobLinks = function() { */ function assignmentsFragment(ID, passage, callback) { let penthouseJobs = App.Entity.facilities.penthouse.assignmentLinkElements(ID, undefined, passage, callback); - const slave = slaveStateById(ID); + const slave = getSlave(ID); const sp = getPronouns(slave); if (slave.fuckdoll === 0) { @@ -836,7 +836,7 @@ App.UI.jobLinks = function() { function transfersFragment(ID, callback) { /** @type {HTMLElement[]} */ const transfers = []; - const slave = slaveStateById(ID); + const slave = getSlave(ID); for (const f of facilitiesOrder) { if (!f.established || f.jobs.length === 0) { diff --git a/src/js/birth/birth.js b/src/js/birth/birth.js index 842e263b05d290f9caa7f40dcc0ecfdb1ccb07f4..53f735a3a0e51053c4d61193eb3d2393c7d167b7 100644 --- a/src/js/birth/birth.js +++ b/src/js/birth/birth.js @@ -7,7 +7,7 @@ App.Events.SEBirth = class SEBirth extends App.Events.BaseEvent { /** Custom casting: all slaves in labor are cast automatically. If no slaves are cast, casting fails and the event does not run. */ castActors() { - this.actors = V.slaves.filter(s => isInLabor(s)).map(s => s.ID); + this.actors = getSlaves().filter(s => isInLabor(s)).map(s => s.ID); return this.actors.length > 0; } diff --git a/src/js/consistencyCheck.js b/src/js/consistencyCheck.js index cdd1e986184471fe30b217d8a0e32119d0494f98..ece35cf408677a7b10dd07ed3da9f7f3ef93c968 100644 --- a/src/js/consistencyCheck.js +++ b/src/js/consistencyCheck.js @@ -1,25 +1,25 @@ /** - * checks V.slaves for consistency + * checks the main slave pool for consistency * @param {JQuery.PassageRenderingEvent} event */ App.Debug.slavesConsistency = function(event) { - if (V.slaves !== undefined) { // no V.slaves at game start - if (V.slaves.includes(null)) { + if (getSlaves() !== undefined) { // the main slave pool doesn't exist at game start + if (getSlaves().includes(null)) { const p = document.createElement("p"); p.append(App.UI.DOM.makeElement("span", "ERROR: Main slaves array contains a null entry! Please report this. ", "error"), // we can't reload the passage as we could be on a passage that changes the game state. - App.UI.DOM.link("Fix for next passage.", () => { V.slaves.deleteAll(null); })); + App.UI.DOM.link("Fix for next passage.", () => { getSlaves().deleteAll(null); })); event.content.append(p); } else { // This part would break with a null entry. - _(V.slaves).countBy(s => s.ID) + _(getSlaves()).countBy(s => s.ID) .pickBy(count => count > 1) .keys() .map(id => Number(id)) .value() .forEach(id => { event.content.append(App.UI.DOM.makeElement("p", `Duplicate slave ID ${id} at indices ${ - _(V.slaves) + _(getSlaves()) .map((s, idx) => ({ ID: s.ID, idx: idx, name: s.slaveName, assignment: s.assignment })) diff --git a/src/js/displayVariables.js b/src/js/displayVariables.js index d169a25ea8cdd66af7fd1ef27ad934bc0ee5d1d3..c065dc7786a425c4e0ee6e8e281e8eed051507ce 100644 --- a/src/js/displayVariables.js +++ b/src/js/displayVariables.js @@ -1,3 +1,59 @@ /*! <<checkvars>> macro for SugarCube 2.x */ /* converted from macro to normal function for easy usage in pure JS, no logic changes */ -App.checkVars = function(){function toString(value,indent){var baseType=typeof value;switch(baseType){case"number":return isNaN(value)?"NaN":isFinite(value)?String(value):"Infinity";case"string":return JSON.stringify(value);case"function":return"(function)";default:if("object"!==baseType||null==value)return String(value);var objType=Object.prototype.toString.call(value);if("[object Date]"===objType)return'(object: Date, value: "'+value.toISOString()+'")';if("[object RegExp]"===objType)return"(object: RegExp, value: "+value.toString()+")";var opener,closer,result=[],indentText=" ";return indent||(indent=""),("[object Set]"===objType||value instanceof Set)&&(value=Array.from(value)),Array.isArray(value)?(opener="[\n",closer="\n"+indent+"]",value.forEach(function(p,i){result.push(indent+indentText+i+" ⇒ "+toString(value[i],indent+indentText))}),Object.keys(value).forEach(function(p){/^\d+$/.test(p)||result.push(indent+indentText+toString(p)+" ⇒ "+toString(value[p],indent+indentText))})):"[object Map]"===objType||value instanceof Map?(opener="{\n",closer="\n"+indent+"}",Array.from(value).map(function(kv){result.push(indent+indentText+toString(kv[0],indent+indentText)+" ⇒ "+toString(kv[1],indent+indentText))})):(opener="{\n",closer="\n"+indent+"}",Object.keys(value).forEach(function(p){result.push(indent+indentText+toString(p)+" ⇒ "+toString(value[p],indent+indentText))})),opener+result.join(",\n")+closer}}var dialog,sv=State.variables,names=Object.keys(sv);if(dialog=UI.setup("Story $variables","checkvars"),0===names.length)return dialog.innerHTML="<h1>Story $variables (<code>State.variables</code>):</h1><p><em>No $variables currently set…</em></p>",void UI.open();dialog.innerHTML="<h1>Story $variables (<code>State.variables</code>):</h1><table><thead><tr><th>Name</th><th>Value</th></tr></thead><tbody></tbody></table>"+(/applewebkit|chrome/.test(Browser.userAgent)?"":'<div class="scroll-pad"> </div>');var tbody=dialog.querySelector("tbody");names.sort(function(a,b){return Util.isNumeric(a)&&Util.isNumeric(b)?Number(a)-Number(b):a.localeCompare(b)});for(var i=0;i<names.length;i++){var tr=document.createElement("tr"),tdName=document.createElement("td"),tdValue=document.createElement("td");tdName.textContent="$"+names[i],tdValue.textContent = toString(sv[names[i]]),tr.appendChild(tdName),tr.appendChild(tdValue),tbody.appendChild(tr)}UI.open()}; \ No newline at end of file +/* modified for SC 2.37 */ +App.checkVars = function() { + function toString(value, indent) { + var baseType = typeof value; + switch (baseType) { + case"number": + return isNaN(value) ? "NaN" : isFinite(value) ? String(value) : "Infinity"; + case"string": + return Serial.stringify(value); + case"function": + return "(function)"; + default: + if ("object" !== baseType || null == value) { + return String(value); + } + var objType = Object.prototype.toString.call(value); + if ("[object Date]" === objType) { + return '(object: Date, value: "' + value.toISOString() + '")'; + } + if ("[object RegExp]" === objType) { + return "(object: RegExp, value: " + value.toString() + ")"; + } + var opener, closer, result = [], indentText = " "; + return indent || (indent = ""), ("[object Set]" === objType || value instanceof Set) && (value = Array.from(value)), Array.isArray(value) ? (opener = "[\n", closer = "\n" + indent + "]", value.forEach(function(p, i) { + result.push(indent + indentText + i + " ⇒ " + toString(value[i], indent + indentText)); + }), Object.keys(value).forEach(function(p) { + /^\d+$/.test(p) || result.push(indent + indentText + toString(p) + " ⇒ " + toString(value[p], indent + indentText)); + })) : "[object Map]" === objType || value instanceof Map ? (opener = "{\n", closer = "\n" + indent + "}", Array.from(value).map(function(kv) { + result.push(indent + indentText + toString(kv[0], indent + indentText) + " ⇒ " + toString(kv[1], indent + indentText)); + })) : (opener = "{\n", closer = "\n" + indent + "}", Object.keys(value).forEach(function(p) { + result.push(indent + indentText + toString(p) + " ⇒ " + toString(value[p], indent + indentText)); + })), opener + result.join(",\n") + closer; + } + } + + function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); + } + + + var dialog, sv = State.variables, names = Object.keys(sv); + if (dialog = Dialog.create("Story $variables", "checkvars"), 0 === names.length) { + dialog.append("<h1>Story $variables (<code>State.variables</code>):</h1><p><em>No $variables currently set…</em></p>"); + } else { + dialog.append("<h1>Story $variables (<code>State.variables</code>):</h1><table><thead><tr><th>Name</th><th>Value</th></tr></thead><tbody></tbody></table>" + (/applewebkit|chrome/.test(Browser.userAgent) ? "" : '<div class="scroll-pad"> </div>')); + var tbody = dialog.body().querySelector("tbody"); + names.sort(function(a, b) { + return isNumeric(a) && isNumeric(b) ? Number(a) - Number(b) : a.localeCompare(b); + }); + for (var i = 0; i < names.length; i++) { + var tr = document.createElement("tr"), tdName = document.createElement("td"), + tdValue = document.createElement("td"); + tdName.textContent = "$" + names[i], tdValue.textContent = toString(sv[names[i]]), tr.appendChild(tdName), tr.appendChild(tdValue), tbody.appendChild(tr); + } + } + Dialog.open(); +}; diff --git a/src/js/economyJS.js b/src/js/economyJS.js index 236f5bf5cdd1f02613e5054efe1c0160d82afaa6..8a4d94f39423cec3032e9280773fb63ca697fcb5 100644 --- a/src/js/economyJS.js +++ b/src/js/economyJS.js @@ -429,13 +429,13 @@ globalThis.calculateCosts = (function() { // slave expenses function predictTotalSlaveCosts() { let loopCosts = 0; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { loopCosts += getSlaveCost(slave); } const reducibleUpkeep = Math.trunc(loopCosts * 0.2); const servantCapacity = totalServantCapacity(); - if (V.slaves.length > servantCapacity) { - loopCosts -= Math.trunc(reducibleUpkeep / V.slaves.length * servantCapacity); + if (getSlaves().length > servantCapacity) { + loopCosts -= Math.trunc(reducibleUpkeep / getSlaves().length * servantCapacity); } else { loopCosts -= reducibleUpkeep; } @@ -448,7 +448,7 @@ globalThis.calculateCosts = (function() { let loopCosts = 0; // Find the total slave upkeep, calculate and subtract per assignment - for (const slave of V.slaves) { + for (const slave of getSlaves()) { slaveCost = getSlaveCost(slave); loopCosts += slaveCost; // Switch to subtract and track upkeep per assignment @@ -587,7 +587,7 @@ globalThis.calculateCosts = (function() { // Calculate the servant reduction and credit them for it const reducibleUpkeep = Math.trunc(loopCosts * 0.2); - const actualNumberServed = Math.min(V.slaves.length, totalServantCapacity()); + const actualNumberServed = Math.min(getSlaves().length, totalServantCapacity()); const savedPerSlot = reducibleUpkeep / actualNumberServed; App.Utils.jobForAssignment(Job.QUARTER).employees().forEach(s => { slaveCostMinor = Math.trunc(savedPerSlot * houseServantEffectiveness(s)); @@ -633,22 +633,29 @@ globalThis.calculateCosts = (function() { } function getIncubatorCosts() { - const facIncMultiplier = V.facilityCost * V.incubator.capacity; - return (facIncMultiplier * 10) + - 0.2 * V.incubator.upgrade.weight * facIncMultiplier + - 0.2 * V.incubator.upgrade.muscles * facIncMultiplier + - 0.2 * V.incubator.upgrade.reproduction * facIncMultiplier + - 0.2 * V.incubator.upgrade.growthStims * facIncMultiplier + - 0.2 * V.incubator.upgrade.organs * facIncMultiplier + - 0.5 * V.incubator.upgrade.reproduction * facIncMultiplier + - 0.5 * V.incubator.upgrade.speed * facIncMultiplier; + const facInc = App.Entity.facilities.incubator; + return V.facilityCost * facInc.capacity * (10 + + 0.2 * facInc.upgrade('weight') + + 0.2 * facInc.upgrade('muscles') + + 0.2 * facInc.upgrade('reproduction') + + 0.2 * facInc.upgrade('growthStims') + + 0.2 * facInc.upgrade('organs') + + 0.5 * facInc.upgrade('reproduction') + + 0.5 * facInc.upgrade('speed') + ); } function getIncubatorSlavesCosts() { + let incubator = App.Entity.facilities.incubator; + const incubatorCostBase = + incubator.upgrade('weight') + + incubator.upgrade('muscles') + + incubator.upgrade('reproduction') + + incubator.upgrade('growthStims') + + incubator.upgrade('organs'); let sum = 0; for (const tank of V.incubator.tanks) { - sum += ((V.incubator.upgrade.weight + V.incubator.upgrade.muscles + V.incubator.upgrade.reproduction + - V.incubator.upgrade.growthStims + V.incubator.upgrade.organs + tank.incubatorSettings.pregAdaptationPower) * 500); + sum += ((incubatorCostBase + tank.incubatorSettings.pregAdaptationPower) * 500); } return sum; } @@ -2633,8 +2640,7 @@ globalThis.cashX = function(cost, what, who) { // Spend the money V.cash += cost; - if (!who || isPlayer(who)) { return; } // nothing to do or we don't want to do record keeping on the player - + // detailed record keeping performed for slaves only const whoSlave = asSlave(who); // INCOME diff --git a/src/js/eventHandlers.js b/src/js/eventHandlers.js index f5834988d59426d7d1593828719b653f76809f7a..4ecc7fafc64c821e9bab4b418baab6fa780e02f0 100644 --- a/src/js/eventHandlers.js +++ b/src/js/eventHandlers.js @@ -24,6 +24,15 @@ App.EventHandlers = function() { * @param {TwineSugarCube.SaveObject} save */ function onSave(save) { + try { + // make sure all genePool records are sparse before saving + // this saves storage space; in some cases by a crazy amount + for (const record of Object.values(V.genePool)) { + makeSparseGeneRecord(/** @type {FC.GenePoolRecord} */ (record)); + } + } catch (ex) { + console.error(ex); + } if (App.Utils.isEndWeek() && V.endweekSaveWarning && Dialog.isOpen()) { $(document).one(':dialogclosed', () => { Dialog.create("Saving during End Week"); diff --git a/src/js/extendedFamilyModeJS.js b/src/js/extendedFamilyModeJS.js index 4708755c71f092320ebff2a18c64389761f0c914..54c21bf727c1d079a1eda3dac52a3ccb8726bbbd 100644 --- a/src/js/extendedFamilyModeJS.js +++ b/src/js/extendedFamilyModeJS.js @@ -32,7 +32,7 @@ globalThis.getRelative = function(ID) { return slave; } // ex-slave - const genePool = getGenePoolRecord(ID); + const genePool = getGenePoolRecordWriteMode(ID); if (genePool) { return genePool; } @@ -334,7 +334,7 @@ globalThis.randomRelatedSlave = function(slave, filterFunction) { if (typeof filterFunction !== 'function') { filterFunction = () => true; } - const arr = V.slaves.filter((s) => areRelated(slave, s) && filterFunction(s)); + const arr = getSlaves().filter((s) => areRelated(slave, s) && filterFunction(s)); return arr.random(); }; @@ -483,21 +483,21 @@ globalThis.relativeTerm = function(slave1, slave2) { /** completely reset all the family counters in the game state (for both PC and slaves) */ globalThis.resetFamilyCounters = function() { - for (let slave of V.slaves) { + for (let slave of getSlaves()) { slave.daughters = 0; slave.sisters = 0; } V.PC.daughters = 0; V.PC.sisters = 0; - for (let slave of V.slaves) { + for (let slave of getSlaves()) { if (slave.mother === -1 || slave.father === -1) { V.PC.daughters++; } if (areSisters(slave, V.PC)) { V.PC.sisters++; } - for (let otherSlave of V.slaves) { + for (let otherSlave of getSlaves()) { if (isParentP(otherSlave, slave)) { slave.daughters++; } @@ -512,7 +512,7 @@ globalThis.resetFamilyCounters = function() { * @param {Relative} slave */ globalThis.setMissingParents = function(slave) { - const gp = isInGenePool(slave.ID) ? getGenePoolRecord(slave.ID, false, true) : undefined; + const gp = isInGenePool(slave.ID) ? getGenePoolRecordWriteMode(slave.ID) : undefined; if (!specificMom(slave)) { slave.mother = V.missingParentID; if (gp) { diff --git a/src/js/findSlave.js b/src/js/findSlave.js index 9902580009bdb7c21687c4b4e1f162723cdb503f..662369b9c7ecdfe03e6607055ee45fbd16296427 100644 --- a/src/js/findSlave.js +++ b/src/js/findSlave.js @@ -114,7 +114,7 @@ App.UI.findSlave = function() { * @returns {number[]} */ function _slaveIDs(predicate) { - return V.slaves.reduce((acc, slave) => { + return getSlaves().reduce((acc, slave) => { if (predicate(createReadonlyProxy(slave))) { acc.push(slave.ID); } diff --git a/src/js/fsConformance.js b/src/js/fsConformance.js index 8dc11dd48cdf70c0c5b4b95538c172be0bc3c12d..68b80102a09aaa3dcc231da7f785bd80cc8ef67c 100644 --- a/src/js/fsConformance.js +++ b/src/js/fsConformance.js @@ -61,7 +61,7 @@ App.FSConformance = function() { /** @type {{slave: FC.ReportSlave, effects: FC.SlaveSocialEffect[]}[]} */ const slaveSocialEffects = []; - for (const rpSlave of App.SlaveAssignment.reportSlaves(V.slaves)) { + for (const rpSlave of App.SlaveAssignment.reportSlaves(getSlaves())) { slaveSocialEffects.push({slave: rpSlave, effects: App.SlaveAssignment.saSocialEffects(rpSlave).effects()}); } diff --git a/src/js/ibcJS.js b/src/js/ibcJS.js index 6525c7ad20a36f04b368faefa9d2f554b61f6cc7..d05410228259edeed5fc7fe625dc16563a35f4f7 100644 --- a/src/js/ibcJS.js +++ b/src/js/ibcJS.js @@ -27,12 +27,12 @@ globalThis.ibc = (() => { */ findSlaveState(id) { let record; - record = slaveStateById(id); + record = getSlave(id); if (!record) { if (Array.isArray(V.genePool)) { record = V.genePool.find((s) => { return s.ID === id; }); } else { - record = getGenePoolRecord(id, true); + record = getGenePoolRecordWriteMode(id); } } record = record || ((id in V.missingTable) ? V.missingTable[id] : null) || null; @@ -45,7 +45,7 @@ globalThis.ibc = (() => { */ getSlavesAndSuch() { /** @type {FC.GenePoolRecord[]} */ - let allSlaveRecords = getAllSlaves() + let allSlaveRecords = getSlaveStates() // @ts-ignore you shouldn't access V.genePool directly because it isn't supposed to change; this is an exception; For normal use use getGenePoolRecord() .concat(Object.values(V.genePool)) .concat(Object.values(V.missingTable)); @@ -57,12 +57,12 @@ globalThis.ibc = (() => { }, /** - * get all FC.FetusGenetics that exist in V.slaves + * get all FC.FetusGenetics that exist in the main slave pool * @returns {FC.FetusGenetics[]} */ getFetuses() { /** @type {FC.FetusGenetics[]} */ - return V.slaves.filter(s => s.preg > 0).map(s => s.womb.map(i => i.genetics)).reduce((res, cur) => res.concat(cur), []); + return getSlaves().filter(s => s.preg > 0).map(s => s.womb.map(i => i.genetics)).reduce((res, cur) => res.concat(cur), []); } }; diff --git a/src/js/main.js b/src/js/main.js index 0d9a4a71577903074a223c7b36fb615b6805cc2d..75507558d8f4e4c45a73e6846e1815509b64b9cc 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -134,7 +134,7 @@ App.MainView.full = function() { if (V.releaseID >= 1000 || ["0.9", "0.8", "0.7", "0.6"].includes(V.ver)) { if (V.releaseID < App.Version.release) { newError().append(App.UI.DOM.makeElement("span", "INCOMPATIBILITY WARNING:", "major-warning"), - ` Your saved game was created using version: ${V.ver}, release: ${V.releaseID}. You must run `, + ` Your saved game was created using version: ${V.ver}, release: ${V.releaseID}${("commitHash" in V && V.commitHash !== "") ? `, commit ${V.commitHash}` : ""}. You must run `, App.UI.DOM.passageLink("Backwards Compatibility", "Backwards Compatibility")); } } else { @@ -198,7 +198,7 @@ App.MainView.full = function() { } else { V.currentRule = null; } - SlaveSort.slaves(V.slaves); + SlaveSort.slaves(getSlaves()); App.UI.SlaveList.ScrollPosition.restore(); } @@ -234,7 +234,7 @@ App.MainView.full = function() { } links.push(App.UI.DOM.link(`Re-apply Rules Assistant now`, () => { - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (assignmentVisible(slave) && slave.useRulesAssistant === 1) { DefaultRules(slave); } @@ -254,7 +254,7 @@ App.MainView.full = function() { */ function useFucktoys() { const fragment = document.createDocumentFragment(); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.assignment !== Job.FUCKTOY) { continue; } @@ -270,7 +270,7 @@ App.MainView.full = function() { const outerDiv = document.createElement("div"); outerDiv.id = "walkpast"; - const slave = V.slaves.filter(s => ![Job.BODYGUARD, Job.FUCKTOY].includes(s.assignment) && (!getPersonalAttention(s.ID, "torture") || onBedRest(V.PC, true))).random(); + const slave = getSlaves().filter(s => ![Job.BODYGUARD, Job.FUCKTOY].includes(s.assignment) && (!getPersonalAttention(s.ID, "torture") || onBedRest(V.PC, true))).random(); if (slave) { App.UI.DOM.appendNewElement("span", outerDiv, globalThis.walkPast(slave), "scene-intro"); } diff --git a/src/js/pregJS.js b/src/js/pregJS.js index 288da21c4d447347c7b9e4b9b12e9ee7832ca4d5..2b5a5ff77cb2e7b60101ec98f6135d32c9d61e96 100644 --- a/src/js/pregJS.js +++ b/src/js/pregJS.js @@ -540,7 +540,7 @@ globalThis.findFather = function(fatherID) { if (father === undefined) { // fast methods didn't find them so do a search through all HumanState objects - father = getAllHumans().find((s) => s.ID === fatherID); + father = getHumanStates().find((s) => s.ID === fatherID); } return father; diff --git a/src/js/releaseRules.js b/src/js/releaseRules.js index bd3deb69e67bb36f9d87757dd08d20854f58dbba..e08dffc2319b87c29976bc14fa10e946e57377aa 100644 --- a/src/js/releaseRules.js +++ b/src/js/releaseRules.js @@ -72,7 +72,7 @@ App.Utils.hasFamilySex = function hasFamilySex(slave) { if (slave.sisters + slave.daughters === 0) { return false; } - return V.slaves.some(s => areRelated(slave, s) && this.sexAllowed(slave, s)); + return getSlaves().some(s => areRelated(slave, s) && this.sexAllowed(slave, s)); }; /** @@ -336,7 +336,7 @@ App.Utils.testAllReleaseText = function testAllReleaseText() { rule.master = Number(bits[4]); slave.rules.release = rule; - r += JSON.stringify(rule) + "\n"; + r += Serial.stringify(rule) + "\n"; r += App.Utils.releaseSummaryShort(slave) + "\n"; r += App.Utils.releaseSummaryLong(slave) + "\n"; r += App.Desc.releaseDesc(slave) + "\n"; diff --git a/src/js/removeSlave.js b/src/js/removeSlave.js index 0deb18d630655c8d9ad732da7cba5bdad5866da1..13804b8f1ae8fe6f975ac40141a5216140a4fc8f 100644 --- a/src/js/removeSlave.js +++ b/src/js/removeSlave.js @@ -5,7 +5,7 @@ globalThis.removeSlave = function(slave) { const AS_ID = slave.ID; - let LENGTH = V.slaves.length; + let LENGTH = getSlaves().length; const INDEX = V.slaveIndices[AS_ID]; let missing = false; @@ -63,7 +63,7 @@ globalThis.removeSlave = function(slave) { } }); } - V.slaves.forEach(s => { + getSlaves().forEach(s => { WombChangeID(s, AS_ID, V.missingParentID); if (s.pregSource === V.missingParentID) { missing = true; @@ -241,7 +241,7 @@ globalThis.removeSlave = function(slave) { // remove slaves from V.rulesToApplyOnce if needed removeFromRulesToApplyOnce(slave); - V.slaves.deleteAt(INDEX); + getSlaves().deleteAt(INDEX); V.slaveIndices = slaves2indices(); LENGTH--; V.JobIDMap = makeJobIdMap(); /* need to call this once more to update count of resting slaves*/ diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js index c351cc2a608e0393d94714c8ef0589e08bae821f..996bfa1ed136336ebf9a3e49332d318029d11dba 100644 --- a/src/js/rulesAssistantOptions.js +++ b/src/js/rulesAssistantOptions.js @@ -418,7 +418,7 @@ App.RA.options = (function() { } else { selected = this.children.filter(listItem => this.dataEqual(listItem.data, dataValue)); } - if (selected.length > 1) { throw Error(`Multiple shortcuts matched ${JSON.stringify(dataValue)}`); } + if (selected.length > 1) { throw Error(`Multiple shortcuts matched ${Serial.stringify(dataValue)}`); } if (selected.length === 1) { const listItem = selected[0]; listItem.select(false); @@ -1214,7 +1214,7 @@ App.RA.options = (function() { loadNewRule() { const text = this.textarea.value; try { - const rule = JSON.parse(text); + const rule = Serial.parse(text); if (Array.isArray(rule)) { rule.forEach(r => { r.ID = generateNewID(); @@ -1351,7 +1351,7 @@ App.RA.options = (function() { render() { const elem = document.querySelector("#application-log") || document.createElement("div"); elem.id = "application-log"; - elem.innerHTML = V.slaves.map(slave => DefaultRules(slave)).join(""); + elem.innerHTML = getSlaves().map(slave => DefaultRules(slave)).join(""); if (V.experimental.raSortOutput === 1) { // sort RA output mod // Get the text content from the element const text = elem.innerHTML; @@ -1385,12 +1385,12 @@ App.RA.options = (function() { class ExportField extends Element { render(...args) { - let element = document.getElementById("exportfield"); + let element = /** @type {HTMLTextAreaElement} */ (document.getElementById("exportfield")); if (element === null) { element = document.createElement("textarea"); element.id = "exportfield"; } - element.value = JSON.stringify(args, null, 2); + element.value = Serial.stringify(args, null, 2); return element; } } @@ -1435,7 +1435,7 @@ App.RA.options = (function() { class SlaveSelection extends ButtonList { constructor() { super("Include specific slaves"); - V.slaves.forEach(slave => this.appendChild(new ButtonItem( + getSlaves().forEach(slave => this.appendChild(new ButtonItem( [slave.slaveName, slave.slaveSurname].join(" "), slave.ID, current_rule.condition.selectedSlaves.includes(slave.ID)))); @@ -1449,7 +1449,7 @@ App.RA.options = (function() { class SlaveExclusion extends ButtonList { constructor() { super("Exclude specific slaves"); - V.slaves.forEach(slave => this.appendChild(new ButtonItem( + getSlaves().forEach(slave => this.appendChild(new ButtonItem( [slave.slaveName, slave.slaveSurname].join(" "), slave.ID, current_rule.condition.excludedSlaves.includes(slave.ID)))); @@ -4548,7 +4548,7 @@ App.RA.options = (function() { } else { selected = this.children.filter(listItem => this.dataEqual(listItem.data, dataValue)); } - if (selected.length > 1) { throw Error(`Multiple shortcuts matched ${JSON.stringify(dataValue)}`); } + if (selected.length > 1) { throw Error(`Multiple shortcuts matched ${Serial.stringify(dataValue)}`); } if (selected.length === 1) { const listItem = selected[0]; listItem.select(false); diff --git a/src/js/rulesAssistantSummary.js b/src/js/rulesAssistantSummary.js index aaac0045430c8984b10e03317cee6ef205b24442..c1720ceaec5bb497edb24167d711886d7a970924 100644 --- a/src/js/rulesAssistantSummary.js +++ b/src/js/rulesAssistantSummary.js @@ -104,10 +104,10 @@ App.RA.summary = function() { } else if (v.hasOwnProperty('min') && v.hasOwnProperty('max')) { return `${v.min} to ${v.max}`; } else { - return JSON.stringify(v); + return Serial.stringify(v); } } else if (Array.isArray(v)) { - return JSON.stringify(v); + return Serial.stringify(v); } return `${v}`; } diff --git a/src/js/slaveCostJS.js b/src/js/slaveCostJS.js index 88a9d98fbbb00282d7e5d6d213d00e21f04438b0..19ea26b1c83db45068b8204ce47a78bf186c9330 100644 --- a/src/js/slaveCostJS.js +++ b/src/js/slaveCostJS.js @@ -1955,7 +1955,7 @@ globalThis.FResultArray = (function() { * @param {FC.SlaveState} slave */ function calcWorksWithRelatives(slave) { - for (const potentialRel of V.slaves) { + for (const potentialRel of getSlaves()) { if (sameAssignmentP(slave, potentialRel)) { if (isParentP(slave, potentialRel)) { adjustFResult(`Works with their parent(s)`, 1); @@ -1983,7 +1983,7 @@ globalThis.FResultArray = (function() { * @param {FC.SlaveState} slave */ function calcWorksWithRelationship(slave) { - const fre = V.slaves.find(s => haveRelationshipP(slave, s) && sameAssignmentP(slave, s)); + const fre = getSlaves().find(s => haveRelationshipP(slave, s) && sameAssignmentP(slave, s)); if (fre) { adjustFResult(`Works with lover`, 1); } diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js index 90c5b939cd957f722ee619f4e5784dc562cb2430..9f4c0930b5aae15727e2759de829d63bdeaa5319 100644 --- a/src/js/slaveListing.js +++ b/src/js/slaveListing.js @@ -79,7 +79,7 @@ App.UI.SlaveList.render = function(IDs, rejectedSlaves, interactionLink, postNot } for (const rs of rejectedSlaves) { - const slave = slaveStateById(rs.id); + const slave = getSlave(rs.id); const rejects = rs.rejects; const slaveName = SlaveFullName(slave); let slaveDiv = document.createElement("div"); @@ -119,7 +119,7 @@ App.UI.SlaveList.render = function(IDs, rejectedSlaves, interactionLink, postNot hr.style.margin = "0"; res.appendChild(hr); } - const slave = slaveStateById(id); + const slave = getSlave(id); if (batchRenderer && (!V.seeCustomImagesOnly || (V.seeCustomImagesOnly && slave.custom.image))) { let imgDiv = document.createElement("div"); @@ -566,7 +566,7 @@ App.UI.SlaveList.listJFacilitySlaves = function(jobName, facility, facilityPassa if (facility.hasFreeSpace) { const assignableSlaveIDs = job.desc.partTime - ? V.slaves.map(slave => slave.ID) // all slaves can work here + ? getSlaves().map(slave => slave.ID) // all slaves can work here : [...App.Entity.facilities.penthouse.employeesIDs()]; // only slaves from the penthouse can be transferred here tabBar.addTab(tabCaptions.assign, "assign", assignableTabContent(assignableSlaveIDs)); } else { @@ -596,7 +596,7 @@ App.UI.SlaveList.listJFacilitySlaves = function(jobName, facility, facilityPassa if (showTransfersTab) { if (facility.hasFreeSpace) { // slaves from other facilities can be transferred here - const transferableIDs = V.slaves.reduce((acc, slave) => { + const transferableIDs = getSlaves().reduce((acc, slave) => { if (!assignmentVisible(slave) && !facility.isHosted(slave)) { acc.push(slave.ID); } @@ -621,7 +621,7 @@ App.UI.SlaveList.listJFacilitySlaves = function(jobName, facility, facilityPassa let rejectedSlaves = []; let passedSlaves = []; slaveIDs.forEach((id) => { - const rejects = facility.canHostSlave(slaveStateById(id), jobName); + const rejects = facility.canHostSlave(getSlave(id), jobName); if (rejects.length > 0) { rejectedSlaves.push({id: id, rejects: rejects}); } else { @@ -669,7 +669,7 @@ App.UI.SlaveList.listNGPSlaves = function() { let imported = []; let nonImported = []; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { // @ts-ignore: handle the legacy assignment string if (slave.assignment === "be imported") { slave.assignment = Job.IMPORTED; @@ -766,7 +766,7 @@ App.UI.SlaveList.penthousePage = function() { slaveWrapper.append(link, " ", App.UI.DOM.makeElement("span", App.UI.Hotkeys.hotkeys("Head Girl Select"), "hotkey")); slaveWrapper.append(App.UI.SlaveList.render([HG.ID], [], interactRenderer)); } else { - if (V.slaves.length > 1) { + if (getSlaves().length > 1) { slaveWrapper.append("You have ", App.UI.DOM.makeElement("span", "not", "warning"), " selected a Head Girl"); if (A.FSEgyptianRevivalistLaw === 1) { slaveWrapper.append(" and Consort"); @@ -954,7 +954,7 @@ App.UI.SlaveList.penthousePage = function() { } function arcologyTab() { - const allSlaveIDs = V.slaves.map((slave) => slave.ID); + const allSlaveIDs = getSlaves().map((slave) => slave.ID); SlaveSort.IDs(allSlaveIDs); return makeTabDesc("arcology", `Arcology${V.useSlaveSummaryTabs > 0 ? ` (${allSlaveIDs.length})` : ""}`, App.UI.SlaveList.render(allSlaveIDs, [], interactRenderer)); @@ -1113,15 +1113,14 @@ App.UI.SlaveList.slaveSelectionList = function() { * @returns {DocumentFragment} */ function _listSlaves(assignmentStr) { - const slaves = V.slaves; /** @type {Array<number>} */ let unfilteredIDs; switch (assignmentStr) { case 'all': - unfilteredIDs = slaves.map(s => s.ID); + unfilteredIDs = getSlaves().map(s => s.ID); break; case 'experienced': - unfilteredIDs = slaves.reduce((acc, s) => { + unfilteredIDs = getSlaves().reduce((acc, s) => { if (options.expCheck(s)) { acc.push(s.ID); } @@ -1137,7 +1136,7 @@ App.UI.SlaveList.slaveSelectionList = function() { let rejects = []; unfilteredIDs.forEach(id => { - const fr = options.filter(slaveStateById(id)); + const fr = options.filter(getSlave(id)); if (fr === true || (Array.isArray(fr) && fr.length === 0)) { passingIDs.push(id); } else { diff --git a/src/js/slaveSummaryHelpers.js b/src/js/slaveSummaryHelpers.js index 5c2b79dff9c3235dd94b09c8e086fdfc976d3e3c..9f6482abfe9754005f68de42628688a0d42c61cb 100644 --- a/src/js/slaveSummaryHelpers.js +++ b/src/js/slaveSummaryHelpers.js @@ -247,7 +247,7 @@ App.UI.SlaveSummaryImpl = function() { } } if (slave.mother > 0) { - const ssj = V.slaves.find(s => s.ID === slave.mother); + const ssj = getSlaves().find(s => s.ID === slave.mother); if (ssj) { helpers.referenceSlaveWithPreview(block, ssj, SlaveFullName(ssj)); addText(block, "'s "); @@ -263,7 +263,7 @@ App.UI.SlaveSummaryImpl = function() { makeSpan(block, bits.makeBit(getPronouns(slave).daughter), cssClassName); } if (slave.father > 0 && slave.father !== slave.mother) { - const ssj = V.slaves.find(s => s.ID === slave.father); + const ssj = getSlaves().find(s => s.ID === slave.father); if (ssj) { helpers.referenceSlaveWithPreview(block, ssj, SlaveFullName(ssj)); addText(block, "'s "); @@ -279,7 +279,7 @@ App.UI.SlaveSummaryImpl = function() { makeSpan(block, bits.makeBit(getPronouns(slave).daughter), cssClassName); } if (slave.daughters === 1) { - const ssj = V.slaves.find(s => s.mother === slave.ID || s.father === slave.ID); + const ssj = getSlaves().find(s => s.mother === slave.ID || s.father === slave.ID); if (ssj) { helpers.referenceSlaveWithPreview(block, ssj, SlaveFullName(ssj)); addText(block, "'s "); @@ -300,7 +300,7 @@ App.UI.SlaveSummaryImpl = function() { } } if (slave.sisters === 1) { - const ssj = V.slaves.find(s => areSisters(s, slave) > 0); + const ssj = getSlaves().find(s => areSisters(s, slave) > 0); if (ssj) { helpers.referenceSlaveWithPreview(block, ssj, SlaveFullName(ssj)); addText(block, "'s "); @@ -321,7 +321,7 @@ App.UI.SlaveSummaryImpl = function() { } } if (slave.relationship > 0 && handled !== 1) { - const ssj = V.slaves.find(s => s.ID === slave.relationshipTarget); + const ssj = getSlaves().find(s => s.ID === slave.relationshipTarget); if (ssj) { helpers.referenceSlaveWithPreview(block, ssj, SlaveFullName(ssj)); addText(block, "'s "); @@ -1499,7 +1499,7 @@ App.UI.SlaveSummaryImpl = function() { function shortRival(slave, c) { if (slave.rivalry !== 0) { const block = makeBlock(c, "lightsalmon"); - const ssj = V.slaves.find(s => s.ID === slave.rivalryTarget); + const ssj = getSlaves().find(s => s.ID === slave.rivalryTarget); if (ssj) { if (slave.rivalry <= 1) { block.textContent = 'Disl '; @@ -1543,7 +1543,7 @@ App.UI.SlaveSummaryImpl = function() { function longRival(slave, c) { if (slave.rivalry !== 0) { const block = makeBlock(c); - const ssj = V.slaves.find(s => s.ID === slave.rivalryTarget); + const ssj = getSlaves().find(s => s.ID === slave.rivalryTarget); if (ssj) { if (slave.rivalry <= 1) { makeSpan(block, "Dislikes", "lightsalmon"); diff --git a/src/js/states/001-GenePoolRecord.js b/src/js/states/001-GenePoolRecord.js index 464d4fe16a5fe8558a46f5bde2bc5ccaf126add0..b1e1494d7bae07537c059f8d12ccdca66edcbdf5 100644 --- a/src/js/states/001-GenePoolRecord.js +++ b/src/js/states/001-GenePoolRecord.js @@ -3,6 +3,7 @@ * This houses App.Entity.GenePoolRecord and the functions that you should use to manipulate the gene pool. * The gene pool is read only and should not be accessed directly. Use the functions below to access it. * @see getGenePoolRecord use this to get a record from the gene pool. + * @see getGenePoolRecordWriteMode use this to edit a record in the gene pool. * @see isInGenePool use this to check if a record is in the gene pool already; gene pool records must have unique slave IDs * @see addToGenePool use this to add a HumanState object to the gene pool; this will throw an error if a record already exist for the HumanState * @see deleteGenePoolRecord use this to remove the record from the gene pool; by default this will keep records that are still needed @@ -10,76 +11,24 @@ * @see App.Entity.GenePoolRecord the class that defines what a GenePoolRecord is. Handle with care */ - /** * Returns a read only record from the gene pool, will return undefined if there is no valid record. + * Use `getGenePoolRecordWriteMode()` if you need to edit records. + * @see getGenePoolRecordWriteMode + * @param {FC.HumanState|number} key The HumanState object or ID to get the record for. + * @returns {ReadonlyDeep<FC.GenePoolRecord>} + */ +globalThis.getGenePoolRecord = (key) => { + return _getGenePoolRecord(key, false, false); +}; + +/** + * Returns a read/write record from the gene pool, will return undefined if there is no valid record. * @param {FC.HumanState|number} key The HumanState object or ID to get the record for. - * @param {boolean} [missingOkay=false] if true then we won't warn if the record is missing, use sparingly. - * @param {boolean} [write=false] if true allow writing to the record, is this sparingly and with caution. * @returns {FC.GenePoolRecord} */ -globalThis.getGenePoolRecord = (key, missingOkay=false, write=false) => { - /** @type {string} */ - let ID; - if (typeof key === "number") { - ID = String(key); - } else if (typeof key === "object" && "ID" in key) { - ID = String(key.ID); - } else { - throw new Error(`key must be an FC.HumanState object or valid HumanState.ID! Got: ${JSON.stringify(key)}`); - } - if (ID === "0") { - console.warn(new Error("getGenePoolRecord: actors with an ID equal to 0 cannot exist in the gene pool")); - return undefined; - } - if (ID in V.genePool) { - const handler = { - /** - * @param {Partial<FC.GenePoolRecord> & {_canWrite: boolean}} target - * @param {string} key - * @param {*} value - * @returns {boolean} - */ - set(target, key, value) { - if (write === true) { - target[key] = value; - return true; - } - console.error(`Attempt to set '${String(key)}' in read only gene pool record with ID '${ID}' to '${value}' was blocked`); - return false; - }, - /** - * @param {Partial<FC.GenePoolRecord>} target - * @param {keyof FC.GenePoolRecord} key - * @returns {*} - */ - get(target, key) { - const handle = (obj) => { - if (typeof obj === 'object' && obj !== null) { - return new Proxy(obj, handler); - } else { - return obj; - } - }; - if (key in target) { - return handle(target[key]); - } else if (key in V.genePoolDefaults) { - return handle(V.genePoolDefaults[key]); - } else { - const newRecord = new App.Entity.GenePoolRecord(); - if (key in newRecord) { - return handle(newRecord[key]); - } - } - } - }; - return /** @type {FC.GenePoolRecord} */ (new Proxy(V.genePool[ID], handler)); - } else { - if (!missingOkay) { - console.warn(`Gene pool record missing for ID '${ID}'`); - } - return undefined; - } +globalThis.getGenePoolRecordWriteMode = (key) => { + return _getGenePoolRecord(key, false, true); }; /** @@ -95,7 +44,7 @@ globalThis.isInGenePool = (key) => { } else if (typeof key === "object" && "ID" in key) { ID = String(key.ID); } else { - throw new Error(`key must be an FC.HumanState object or valid HumanState.ID! Got: ${JSON.stringify(key)}`); + throw new Error(`key must be an FC.HumanState object or valid HumanState.ID! Got: ${Serial.stringify(key)}`); } if (ID in V.genePool) { return true; @@ -104,40 +53,12 @@ globalThis.isInGenePool = (key) => { }; /** - * Adds a clone of the given human to the genePool as a valid FC.GenePoolRecord. - * Throws an error if they are already in the pool. - * If unsure, use `isInGenePool()` first to check. - * @see isInGenePool - * @param {FC.HumanState} actor + * Makes the given GenePoolRecord sparse saving storage space. + * If record is undefined then we do nothing. + * @param {FC.GenePoolRecord} record */ -globalThis.addToGenePool = (actor) => { - const record = _.cloneDeep(actor); - const player = asPlayer(record); - const slave = asSlave(record); - if (player) { - App.Verify.playerState( - player, - `<Player with ID '${record.ID}' passed to addToGenePool()>`, - undefined, - "V.genePool", - ); - } else if (slave) { - App.Verify.slaveState( - `<Slave with ID '${record.ID}' passed to addToGenePool()>`, - slave, - "V.genePool" - ); - } else { - console.error(`addToGenePool: actor with ID '${record.ID}' is not a valid SlaveState or PlayerState object`); - // TODO:@franklygeorge double check that all the keys from new App.Entity.GenePoolRecord() exist on actor - // TODO:@franklygeorge if not then throw an error; once you write that code change the console.error above to console.warn - } - - if (record.ID === 0) { - console.error(new Error("addToGenePool: actors with an ID equal to 0 cannot be added to the gene pool")); - return; - } - +globalThis.makeSparseGeneRecord = (record) => { + if (record === undefined) { return; } /** * DANGER * strip keys from obj that aren't in template, recursively @@ -170,7 +91,7 @@ globalThis.addToGenePool = (actor) => { continue; } if (key in template) { - if (JSON.stringify(obj[key]) === JSON.stringify(template[key])) { + if (Serial.stringify(obj[key]) === Serial.stringify(template[key])) { delete obj[key]; } else if (obj[key] && typeof obj[key] === "object" && !Array.isArray(obj[key])) { if (template[key] && typeof template[key] === "object" && !Array.isArray(template[key])) { @@ -183,6 +104,47 @@ globalThis.addToGenePool = (actor) => { } }; + // strip the record down to a valid GenePoolRecord + stripKeys(record, new App.Entity.GenePoolRecord()); + // remove all default keys from GenePoolRecord + removeDefaults(record, V.genePoolDefaults); +}; + +/** + * Adds a clone of the given human to the genePool as a valid FC.GenePoolRecord. + * Throws an error if they are already in the pool. + * If unsure, use `isInGenePool()` first to check. + * @see isInGenePool + * @param {FC.HumanState} actor + */ +globalThis.addToGenePool = (actor) => { + const record = _.cloneDeep(actor); + const player = asPlayer(record); + const slave = asSlave(record); + if (player) { + App.Verify.playerState( + player, + `<Player with ID '${record.ID}' passed to addToGenePool()>`, + undefined, + "V.genePool", + ); + } else if (slave) { + App.Verify.slaveState( + `<Slave with ID '${record.ID}' passed to addToGenePool()>`, + slave, + "V.genePool" + ); + } else { + console.error(`addToGenePool: actor with ID '${record.ID}' is not a valid SlaveState or PlayerState object`); + // TODO:@franklygeorge double check that all the keys from new App.Entity.GenePoolRecord() exist on actor + // TODO:@franklygeorge if not then throw an error; once you write that code change the console.error above to console.warn + } + + if (record.ID === 0) { + console.error(new Error("addToGenePool: actors with an ID equal to 0 cannot be added to the gene pool")); + return; + } + if (record.ID in V.genePool) { throw new Error(`There is already a genePool record for ID '${record.ID}'`); } @@ -190,10 +152,7 @@ globalThis.addToGenePool = (actor) => { // cull the contents of womb from the record record.womb = []; - // strip the record down to a valid GenePoolRecord - stripKeys(record, new App.Entity.GenePoolRecord()); - // remove all default keys from GenePoolRecord - removeDefaults(record, V.genePoolDefaults); + makeSparseGeneRecord(record); // @ts-expect-error V.genePool is set to read only. This is the one of the few lines that should be writing to it V.genePool[String(record.ID)] = record; @@ -238,7 +197,7 @@ globalThis.deleteGenePoolRecord = (actor, force=false) => { } if (!keep) { /* avoid going through this loop if possible */ - keep = getAllSlaves().some(slave => { + keep = getSlaveStates().some(slave => { /* have we impregnated a slave that is not ourselves? */ return (slave.ID !== actor.ID && isImpregnatedBy(slave, actor)); }); @@ -250,6 +209,41 @@ globalThis.deleteGenePoolRecord = (actor, force=false) => { } }; +/** + * Use `getGenePoolRecord()` or `getGenePoolRecordWriteMode()` instead of calling this directly + * @see getGenePoolRecord + * @see getGenePoolRecordWriteMode + * @param {FC.HumanState|number} key The HumanState object or ID to get the record for. + * @param {boolean} [missingOkay=false] if true then we won't warn if the record is missing, use sparingly. + * @param {boolean} [write=false] if true allow writing to the record. + * @returns {FC.GenePoolRecord} + */ +globalThis._getGenePoolRecord = (key, missingOkay=false, write=false) => { + /** @type {string} */ + let ID; + if (typeof key === "number") { + ID = String(key); + } else if (typeof key === "object" && "ID" in key) { + ID = String(key.ID); + } else { + throw new Error(`key must be an FC.HumanState object or valid HumanState.ID! Got: ${Serial.stringify(key)}`); + } + if (ID in V.genePool) { + // this implementation means that write=true will convert the record from a sparse object into a full one. + // this should be okay since validation will reconvert it to sparse later, but it is not ideal + // the reason for doing this is that proxies are an absolute pain if you need to fill in values with defaults recursively. + // this also means that if someone tries to write to this with write=false there will be no error or warning to indindcate that something is wrong + const record = write ? V.genePool[ID] : clone(V.genePool[ID]); + App.Utils.assignMissingDefaults(record, V.genePoolDefaults, new App.Entity.GenePoolRecord()); + return /** @type {FC.GenePoolRecord} */ (record); + } else { + if (!missingOkay) { + console.warn(`Gene pool record missing for ID '${ID}'`); + } + return undefined; + } +}; + /** * This defines properties that are shared between the gene pool and all HumanState objects. * The values here should be the default for SlaveState objects. diff --git a/src/js/states/002-HumanState.js b/src/js/states/002-HumanState.js index 374e5cf0d6c45df62c898418f41dcafd018f2b0d..e87dca5a6545bf40aaa67a99682fb10e4d2d192f 100644 --- a/src/js/states/002-HumanState.js +++ b/src/js/states/002-HumanState.js @@ -6,10 +6,10 @@ * Doesn't return partial HumanState objects from V.missingTable; * @returns {FC.HumanState[]} */ -globalThis.getAllHumans = () => { +globalThis.getHumanStates = () => { // TODO:@franklygeorge once ChildState is implemented add it to this let allHumanRecords = [] - .concat(getAllSlaves()) + .concat(getSlaveStates()) .concat([V.PC]); diff --git a/src/js/states/003-SlaveState.js b/src/js/states/003-SlaveState.js index 7d93d3f9530a9aa3454e3b54b6d1d121dbced7a6..bc7e9382eb024df9c191a6bf88a3a605403d80c3 100644 --- a/src/js/states/003-SlaveState.js +++ b/src/js/states/003-SlaveState.js @@ -6,10 +6,10 @@ * Doesn't return partial SlaveState objects from V.missingTable; * @returns {FC.SlaveState[]} */ -globalThis.getAllSlaves = () => { +globalThis.getSlaveStates = () => { // TODO:@franklygeorge once ChildState is implemented add it to this let allSlaveRecords = [] - .concat(V.slaves) + .concat(getSlaves()) .concat(V.cribs) .concat(V.incubator.tanks); diff --git a/src/js/storyJS.js b/src/js/storyJS.js index 8704a7826660e75ed66994ea155a300cebed6ff2..cbb8e0bca4641c409d2d82c4b551cf12059d29b8 100644 --- a/src/js/storyJS.js +++ b/src/js/storyJS.js @@ -459,7 +459,7 @@ globalThis.bodyguardSuccessorEligible = function(slave) { * @returns {string} */ globalThis.toJson = function(obj) { - let jsontext = JSON.stringify(obj); + let jsontext = Serial.stringify(obj); jsontext = jsontext.replace(/^{/, ""); jsontext = jsontext.replace(/}$/, ""); return jsontext; diff --git a/src/js/utilsArcology.js b/src/js/utilsArcology.js index afb864c8dbd2bb169fca80c27f7be669d53a37a7..d54dccf4f3e2865594f64bb84de3cba75603abf4 100644 --- a/src/js/utilsArcology.js +++ b/src/js/utilsArcology.js @@ -152,14 +152,14 @@ globalThis.penetrativeSocialUse = function(slave = null) { } if (total >= 40) { // Once dicks are trendy, availability starts to increase interest - let haveDick = V.slaves.filter(s => s.dick > 0).length; + let haveDick = getSlaves().filter(s => s.dick > 0).length; if (haveDick) { - let withDick = (haveDick / V.slaves.length); // percentage of slaves with dicks + let withDick = (haveDick / getSlaves().length); // percentage of slaves with dicks total += withDick > .2 ? 15 * withDick : 0; - let toyHole = V.slaves.filter(s => s.toyHole === "dick").length; + let toyHole = getSlaves().filter(s => s.toyHole === "dick").length; total += 10 * (toyHole / haveDick); let penetrativeAverage = 0; - V.slaves.filter(s => s.dick > 0).forEach(s1 => { + getSlaves().filter(s => s.dick > 0).forEach(s1 => { penetrativeAverage += s1.skill.penetrative; }); total += (penetrativeAverage / haveDick) * .1; diff --git a/src/js/utilsDOM.js b/src/js/utilsDOM.js index 63e33b3d7d351747da37548e9ca86b9287544cd1..98a7c3de853cc9719cef87a16666f317f9f1e412 100644 --- a/src/js/utilsDOM.js +++ b/src/js/utilsDOM.js @@ -527,9 +527,11 @@ App.UI.DOM.formatException = function formatException(ex, recursion = false) { const header = document.createElement("p"); header.classList.add("error"); + App.UI.DOM.appendNewElement("div", header, `Please provide a text copy (or screenshot) of this error message starting with \`\`\` and ending with 'End of error message' below, a save file, and any other relevant information.`); + fragment.append(App.UI.DOM.makeElement("br")); App.UI.DOM.appendNewElement("div", header, `\`\`\``); + fragment.append(App.UI.DOM.makeElement("br")); App.UI.DOM.appendNewElement("div", header, `Apologies! An error has occurred. Please report this.`, ["bold"]); - App.UI.DOM.appendNewElement("div", header, `Please provide a screenshot of the error message, a save file and any other relevant information.`); fragment.append(header); const eventLabel = () => { @@ -564,7 +566,29 @@ App.UI.DOM.formatException = function formatException(ex, recursion = false) { App.UI.DOM.appendNewElement("div", error, ex.toString(), ["bold"]); } - fragment.append(error, `\`\`\``); + fragment.append(error); + + fragment.append(App.UI.DOM.makeElement("br")); + + fragment.append(`\`\`\``); + + fragment.append(App.UI.DOM.makeElement("br")); + + fragment.append(App.UI.DOM.makeElement("div", `End of error message`)); + + fragment.append(App.UI.DOM.makeElement("br")); + + const reportDiv = App.UI.DOM.makeElement("div", `Please report this error `); + + const reportLink = App.UI.DOM.makeElement("a", "here"); + + reportLink.classList.add("link-external"); + reportLink.href = "https://gitgud.io/pregmodfan/fc-pregmod/issues/"; + reportLink.target = "_blank"; + + reportDiv.append(reportLink); + + fragment.append(reportDiv); fragment.append(App.UI.DOM.makeElement("br")); diff --git a/src/js/utilsMisc.js b/src/js/utilsMisc.js index 2e0f5c1662cec3b658ba0b0fcd4894886c20a869..74946aff6a277f3a54b166d8b5e2918db3127fe0 100644 --- a/src/js/utilsMisc.js +++ b/src/js/utilsMisc.js @@ -392,7 +392,7 @@ App.Utils.totalNetWorth = function() { total += V.cash; - for (const slave of V.slaves) { + for (const slave of getSlaves()) { total += slaveCost(slave); } @@ -689,7 +689,7 @@ App.Utils.getSaveFilename = (baseName='free-cities', extension='save', s = null) const arcologyName = V.arcologies === undefined || V.arcologies.length === 0 ? "New_Game_Setup" : V.arcologies[0].name.replaceAll(' ', '_').substring(0, 20); const week = String(V.week).padStart(5, '0'); const slave = !s - ? String(V.slaves.length).padStart(5, '0') + ? String(getSlaves().length).padStart(5, '0') : `${s.ID > 0 ? 'ID' + String(s.ID).padStart(5, '0'): 'PC'}-${((s.slaveSurname ? s.slaveSurname : '' ) + s.slaveName).replaceAll(' ', '').substring(0, 30)}`; const release = String(V.releaseID).padStart(5, '0'); const date = App.Utils.getDatestamp(); diff --git a/src/js/utilsPC.js b/src/js/utilsPC.js index c1be65a74922a9ead2a3a920e72449252d246c7c..2188711a3c88ca24569c203581f0f0e7a88a7716 100644 --- a/src/js/utilsPC.js +++ b/src/js/utilsPC.js @@ -550,19 +550,19 @@ globalThis.PCTitle = function() { } } - if (V.slaves.length > 50) { + if (getSlaves().length > 50) { if (V.PC.title === 1) { titles.push("Master of Slaves"); } else { titles.push("Mistress of Slaves"); } - } else if (V.slaves.length > 40) { + } else if (getSlaves().length > 40) { titles.push("Holder of Slaves"); - } else if (V.slaves.length > 30) { + } else if (getSlaves().length > 30) { titles.push("Keeper of Slaves"); - } else if (V.slaves.length > 20) { + } else if (getSlaves().length > 20) { titles.push("Manager of Slaves"); - } else if (V.slaves.length > 10) { + } else if (getSlaves().length > 10) { titles.push("owner of slaves"); } const corpValue = App.Corporate.calculateValue(); @@ -1123,7 +1123,11 @@ globalThis.isPlayerReceptive = function(penetrator = null) { return true; // penetrative campaign } else if (V.PC.drugs.includes("fertility") || V.PC.diet.includes("fertility") || V.PC.refreshment.includes("fertility")) { return true; // PC wants to be pregnant, even if not fertile - } else if (V.slaves.filter(s => s.toyHole === "dick").length * 4 > V.slaves.filter(s => s.dick > 0).length || V.slaves.filter(s => s.toyHole === "dick").length * 10 > V.slaves.length || V.slaves.filter(s => s.toyHole === "dick").length >= 8) { + } else if ( + getSlaves().filter(s => s.toyHole === "dick").length * 4 > getSlaves().filter(s => s.dick > 0).length || + getSlaves().filter(s => s.toyHole === "dick").length * 10 > getSlaves().length || + getSlaves().filter(s => s.toyHole === "dick").length >= 8 + ) { return true; // at least 8 slaves, or 25% of the slaves with penises, or 10% of all the slaves, have dick as toyHole } else if (V.PC.counter.anal * 2 > V.week) { return true; // player is used to anal penetration @@ -1186,21 +1190,20 @@ globalThis.isPlayerFrigid = function() { if ((rumorType === "weakness" || rumorType === "all") && result.weakness > 0) { result.weakness = 1 + Math.round((result.weakness - 1) * 0.5); // weakness is not as devastating as other bad rumors. if (result.penetrative + result.birth > 20) { - result.weakness = Math.round(result.weakness * 0.66); // other rumors downplay the impact of weakness ones. + result.weakness = Math.round(result.weakness * 0.66); // other rumors downplay the impact of weakness ones. } } return rumorType === "all" ? result.penetrative + result.birth + result.weakness : result[rumorType]; -} - - /** Records possible harmful rumors about the player. */ - globalThis.newRumor = (function() { +}; - return{ +/** Records possible harmful rumors about the player. */ +globalThis.newRumor = (function() { + return { penetrative: penetrated, birth: miscegenated, weakness: weak, // other: other, - } + }; /** Records rumors about the player being penetrated by a slave, if applicable, and returns a warning text in that case. * @param {FC.SlaveState} slave - penetrator @@ -1234,7 +1237,7 @@ globalThis.isPlayerFrigid = function() { * @param {number} strength - multiplier, defaults to 1 */ function miscegenated(strength = 10) { - if (V.arcologies[0].FSChattelReligionistLaw === 1) { // society accepts the acts of the prophet + if (V.arcologies[0].FSChattelReligionistLaw === 1) { // society accepts the acts of the prophet return; } let weight = FutureSocieties.isActive("FSRepopulationFocus") && V.arcologies[0].FSRepopulationFocus > 99 ? .1 : 2; @@ -1261,16 +1264,15 @@ globalThis.isPlayerFrigid = function() { } })(); - /** Softens harmful rumors about the player. */ - globalThis.softenRumors = (function() { - - return{ +/** Softens harmful rumors about the player. */ +globalThis.softenRumors = (function() { + return { penetrative: penetrated, birth: miscegenated, weakness: weak, // other: other, all: all, - } + }; /** Softens rumors about the player being penetrated by slaves. * @param {number} strength - multiplier, defaults to 1 @@ -1351,4 +1353,4 @@ globalThis.getPCPreferredHole = function() { } else { return "anus"; } -} +}; diff --git a/src/js/utilsSlave.js b/src/js/utilsSlave.js index 3534b170e861f19bada454baca5d0ce294946a1a..d568e58f5d386b9d228bfc35de2e871fc0fe34d6 100644 --- a/src/js/utilsSlave.js +++ b/src/js/utilsSlave.js @@ -1488,7 +1488,7 @@ globalThis.newSlave = function(slave) { if (areSisters(V.PC, slave) > 0) { V.PC.sisters += 1; } - for (const other of V.slaves) { + for (const other of getSlaves()) { if (other.mother === slave.ID || other.father === slave.ID) { slave.daughters++; } @@ -1567,7 +1567,8 @@ globalThis.newSlave = function(slave) { generatePronouns(slave); SetBellySize(slave); - V.slaveIndices[slave.ID] = V.slaves.push(slave) - 1; + // @ts-expect-error slave indices are read only + V.slaveIndices[slave.ID] = getSlaves().push(slave) - 1; if (isInGenePool(slave)) { console.warn(`A gene pool record already exists for a slave with the ID '${slave.ID}', leaving old record intact`); @@ -2524,9 +2525,8 @@ globalThis.PaternalistName = function(slave) { * @param {FC.SlaveState} child */ globalThis.parentNames = function(parent, child) { - const slaves = V.slaves; - let currentSlaveNames = slaves.map(s => s.slaveName); + let currentSlaveNames = getSlaves().map(s => s.slaveName); let continentNationality; const useMaleName = (child.genes === "XY" && V.allowMaleSlaveNames === true); @@ -3795,7 +3795,7 @@ globalThis.generateSlaveID = function() { // get the ID props for all objects that have slave IDs // note that V.missingTable has IDs too but those aren't included here because they're always negative by design const allSlaveIDs = [ - ...getAllSlaves().map((s) => s.ID), + ...getSlaveStates().map((s) => s.ID), ...Object.values(V.genePool).map((s) => s.ID) ]; @@ -3813,21 +3813,41 @@ globalThis.generateSlaveID = function() { }; /** + * Returns a slave for the given ID from the main slave pool. + * If the ID doesn't exist in the main slave pool then undefined is returned. * @param {number} ID - * @returns {FC.SlaveState} + * @returns {FC.SlaveState} will return undefined if the ID is invalid */ -globalThis.slaveStateById = function(ID) { +globalThis.getSlave = function(ID) { const index = V.slaveIndices[ID]; - return index === undefined ? null : V.slaves[index]; + return index === undefined ? undefined : V.slaves[index]; }; /** + * Overwrite the given ID in the main slave pool with the given slave object. + * Will throw an error if slave is not an object or if the given ID is not in the main slave pool * @param {number} ID - * @returns {FC.SlaveState} will return undefined if the ID is invalid + * @param {FC.SlaveState} slave */ -globalThis.getSlave = function(ID) { +globalThis.overwriteSlave = function(ID, slave) { + if (!slave || !(typeof slave === "object") || slave === null || Array.isArray(slave)) { + throw new Error(`Passed object is not a SlaveState object. Object: ${Serial.stringify(slave)}`); + } const index = V.slaveIndices[ID]; - return index === undefined ? undefined : V.slaves[index]; + if (index !== undefined) { + // @ts-expect-error V.slaves is read only + V.slaves[index] = slave; + } else { + throw new Error(`No slave exists with ID '${ID}' in the main slave pool`); + } +}; + +/** + * returns an array of all slaves from the main slave pool + * @returns {FC.SlaveState[]} + */ +globalThis.getSlaves = () => { + return /** @type {FC.SlaveState[]} */ (V.slaves); }; /** @@ -3849,7 +3869,7 @@ globalThis.getTankSlave = function(ID) { }; /** - * NOTE: this only checks V.PC and V.slaves, search through `getAllHumans()` if you need to truly check all humans + * NOTE: this only checks V.PC and the main slave pool, search through `getAllHumanStates()` if you need to truly check all humans * @param {number} ID * @returns {FC.HumanState} will return undefined if the ID is invalid */ @@ -3939,7 +3959,7 @@ globalThis.randomRapeRivalryTarget = function(slave, predicate) { predicate = (() => true); } - const arr = V.slaves.filter((s) => { return canBeARapeRival(s) && canRape(slave, s); }).shuffle(); + const arr = getSlaves().filter((s) => { return canBeARapeRival(s) && canRape(slave, s); }).shuffle(); return arr.find(predicate); }; @@ -3961,7 +3981,7 @@ globalThis.restoreTraitor = function() { if (V.traitorStats.PCfather > 0) { V.PC.father = V.traitor.ID; } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (V.traitorStats.traitorMother.includes(slave.ID)) { slave.mother = V.traitor.ID; } @@ -3998,7 +4018,7 @@ globalThis.restoreTraitor = function() { pca.origBodyOwnerID = V.traitor.ID; } } - for (const slave of V.slaves) { + for (const slave of getSlaves()) { WombChangeID(slave, V.traitor.missingParentTag, V.traitor.ID); } newSlave(V.traitor); /* skip New Slave Intro */ diff --git a/src/js/utilsSlaves.js b/src/js/utilsSlaves.js index 2a7d32f07ba42368eb255383312102d3d507bdc4..e16652bb384472f6c3bfb43e6fb3eb9ff23404a4 100644 --- a/src/js/utilsSlaves.js +++ b/src/js/utilsSlaves.js @@ -5,20 +5,20 @@ globalThis.cumSlaves = function() { - return V.slaves.filter(s => (s.assignment === Job.MILKED || s.assignment === Job.DAIRY) && s.balls > 0 && s.ballType === "human"); + return getSlaves().filter(s => (s.assignment === Job.MILKED || s.assignment === Job.DAIRY) && s.balls > 0 && s.ballType === "human"); }; globalThis.haremLength = function() { - return V.slaves.filter(s => [Job.FUCKTOY, Job.MASTERSUITE, Job.CONCUBINE].includes(s.assignment)).length; + return getSlaves().filter(s => [Job.FUCKTOY, Job.MASTERSUITE, Job.CONCUBINE].includes(s.assignment)).length; }; globalThis.fuckSlavesLength = function() { - return V.slaves.filter(s => [Job.FUCKTOY, Job.MASTERSUITE, Job.CONCUBINE].includes(s.assignment) && s.rules.release.master !== 0).length; + return getSlaves().filter(s => [Job.FUCKTOY, Job.MASTERSUITE, Job.CONCUBINE].includes(s.assignment) && s.rules.release.master !== 0).length; }; globalThis.servantsLength = function() { - return V.slaves.filter(s => [Job.HOUSE, Job.QUARTER].includes(s.assignment)).length; + return getSlaves().filter(s => [Job.HOUSE, Job.QUARTER].includes(s.assignment)).length; }; globalThis.getRieEligibleSlaves = function() { - return V.slaves.filter(s => s.fuckdoll === 0 && + return getSlaves().filter(s => s.fuckdoll === 0 && (assignmentVisible(s) || [Job.MASTERSUITE, Job.CONCUBINE, Job.QUARTER].includes(s.assignment)) && !V.eventControl.RIESkip.includes(s.ID) ); @@ -97,16 +97,16 @@ globalThis.SlaveSort = function() { /** @param {FC.SlaveState[]} [slaves] */ function sortSlaves(slaves) { - slaves = slaves || V.slaves; + slaves = slaves || getSlaves(); slaves.sort(_comparator()); - if (slaves === V.slaves) { + if (slaves === getSlaves()) { V.slaveIndices = slaves2indices(); } } /** @param {number[]} [slaveIDs] */ function sortIDs(slaveIDs) { - const slaves = V.slaves; + const slaves = getSlaves(); const slaveIndices = V.slaveIndices; const cmp = _comparator(); slaveIDs = slaveIDs || slaves.map(s => s.ID); @@ -115,7 +115,7 @@ globalThis.SlaveSort = function() { /** @param {number[]} [slaveIndices] */ function sortIndices(slaveIndices) { - const slaves = V.slaves; + const slaves = getSlaves(); const cmp = _comparator(); slaveIndices = slaveIndices || [...slaves.keys()]; slaveIndices.sort((ia, ib) => cmp(slaves[ia], slaves[ib])); @@ -167,7 +167,7 @@ globalThis.slaveSortMinor = function(slaves) { * @param {FC.SlaveState[]} [slaveArray] * @returns {FC.SlaveState[]} sorted from best to worst */ -globalThis.getBestSlaves = function({part, count = 3, largest = true, filter = (() => true)}, slaveArray = V.slaves) { +globalThis.getBestSlaves = function({part, count = 3, largest = true, filter = (() => true)}, slaveArray = getSlaves()) { const partCB = _.isFunction(part) ? part : (slave) => slave[part]; const sortMethod = largest ? (left, right) => right.value - left.value : (left, right) => left.value - right.value; @@ -190,7 +190,7 @@ globalThis.getBestSlavesIDs = function(info) { * @param {FC.SlaveState[]} [slaves] * @returns {{[key: string]: number}} */ -globalThis.slaves2indices = function(slaves = V.slaves) { +globalThis.slaves2indices = function(slaves = getSlaves()) { return slaves.reduce((acc, slave, i) => { acc[slave.ID] = i; return acc; @@ -247,7 +247,7 @@ globalThis.penthouseCensus = function() { return true; // takes her own room } - const penthouseSlaves = V.slaves.filter(s => assignmentVisible(s)); + const penthouseSlaves = getSlaves().filter(s => assignmentVisible(s)); V.roomsPopulation = penthouseSlaves.filter(occupiesRoom).length; V.dormitoryPopulation = penthouseSlaves.filter(s => s.rules.living !== "luxurious").length; }; diff --git a/src/js/wombJS.js b/src/js/wombJS.js index 5d4d09387c17d44dad2a20e3fd25dfeba6b116f7..2c1ac93c3bc16663f26d6e70c32fc5fb4f978c9f 100644 --- a/src/js/wombJS.js +++ b/src/js/wombJS.js @@ -797,7 +797,7 @@ globalThis.FetusGlobalReserveCount = function(reserveType) { return 0; } - V.slaves.forEach(function(slave) { + getSlaves().forEach(function(slave) { slave.womb.forEach(function(ft) { if (ft.reserve === reserveType) { cnt++; diff --git a/src/js/wombT+T.js b/src/js/wombT+T.js index 86885bc4fdec151feb5aced9f89e0dcd92cd21ab..504acaf07ec74b01aacdfddad2184aa169dba4d7 100644 --- a/src/js/wombT+T.js +++ b/src/js/wombT+T.js @@ -230,7 +230,7 @@ globalThis.transplantingTool = ( let option = options.addOption(`Select a host`, "receptrix"); App.UI.DOM.appendNewElement("h4", transplantDiv, "Slave details"); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if ((mother.ID !== slave.ID && slave.ovaries > 0 || slave.mpreg > 0) && isSlaveAvailable(slave) && slave.preg >= 0 && slave.preg < slave.pregData.normalBirth / 10 && slave.pregWeek >= 0 && slave.pubertyXX === 1 && slave.pregType < 12 && diff --git a/src/neighbor/neighborInteract.js b/src/neighbor/neighborInteract.js index 3d57af47c0ce43d8028319bbc31fa65ccbc107b5..96ee2c3be3ce3c4e6cae5c66f35b98afc5d11b0b 100644 --- a/src/neighbor/neighborInteract.js +++ b/src/neighbor/neighborInteract.js @@ -313,7 +313,7 @@ App.Neighbor.Interact = function() { } else { let linkText = `Recall and reenslave ${him}`; const residentList = [agent.ID]; - const agentPartner = V.slaves.find((s) => s.assignment === Job.AGENTPARTNER && s.relationshipTarget === agent.ID); + const agentPartner = getSlaves().find((s) => s.assignment === Job.AGENTPARTNER && s.relationshipTarget === agent.ID); if (agentPartner) { linkText = `Recall them and reenslave your agent`; residentList.push(agentPartner.ID); diff --git a/src/npc/children/childSummary.js b/src/npc/children/childSummary.js index 66cbd7e5c02a2a85a703348784c273d08afffa57..d6116eb858a232ee7b7c3a322cc773fd0b2f343d 100644 --- a/src/npc/children/childSummary.js +++ b/src/npc/children/childSummary.js @@ -3812,12 +3812,12 @@ App.Facilities.Nursery.ChildSummary = function(child) { const {daughter, sister, wife} = getPronouns(child); let handled = 0; if (child.mother > 0) { - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return s.ID === child.mother; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s ${daughter}`; - if (child.relationshipTarget === V.slaves[_ssj].ID) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s ${daughter}`; + if (child.relationshipTarget === getSlaves()[_ssj].ID) { const friendShipShort = relationshipTermShort(child); r += ` & ${friendShipShort}`; handled = 1; @@ -3835,12 +3835,12 @@ App.Facilities.Nursery.ChildSummary = function(child) { r += `${V.missingTable[child.mother].fullName}'s ${daughter} `; } if (child.father > 0 && child.father !== child.mother) { - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return s.ID === child.father; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s ${daughter}`; - if (child.relationshipTarget === V.slaves[_ssj].ID && handled !== 1) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s ${daughter}`; + if (child.relationshipTarget === getSlaves()[_ssj].ID && handled !== 1) { const friendShipShort = relationshipTermShort(child); r += ` & ${friendShipShort}`; handled = 1; @@ -3858,24 +3858,24 @@ App.Facilities.Nursery.ChildSummary = function(child) { r += `${V.missingTable[child.father].fullName}'s ${daughter}`; } if (child.daughters === 1) { - let _ssj = V.slaves.findIndex(function(s) { + let _ssj = getSlaves().findIndex(function(s) { return s.mother === child.ID; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s mother`; - if (child.relationshipTarget === V.slaves[_ssj].ID) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s mother`; + if (child.relationshipTarget === getSlaves()[_ssj].ID) { const friendShipShort = relationshipTermShort(child); r += ` & ${friendShipShort}`; handled = 1; } } r += " "; - _ssj = V.slaves.findIndex(function(s) { + _ssj = getSlaves().findIndex(function(s) { return s.father === child.ID; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s father`; - if (child.relationshipTarget === V.slaves[_ssj].ID && handled !== 1) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s father`; + if (child.relationshipTarget === getSlaves()[_ssj].ID && handled !== 1) { const friendShipShort = relationshipTermShort(child); r += ` & ${friendShipShort}`; handled = 1; @@ -3886,12 +3886,12 @@ App.Facilities.Nursery.ChildSummary = function(child) { r += `multiple daughters `; } if (child.sisters === 1) { - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return areSisters(s, child) > 0; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s ${sister}`; - if (child.relationshipTarget === V.slaves[_ssj].ID) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s ${sister}`; + if (child.relationshipTarget === getSlaves()[_ssj].ID) { const friendShipShort = relationshipTermShort(child); r += `& ${friendShipShort}`; handled = 1; @@ -3902,11 +3902,11 @@ App.Facilities.Nursery.ChildSummary = function(child) { r += `multiple sisters `; } if (child.relationship > 0 && handled !== 1) { - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return s.ID === child.relationshipTarget; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; + r += `${SlaveFullName(getSlaves()[_ssj])}'s`; const friendShipShort = relationshipTermShort(child); r += ` ${friendShipShort}`; } @@ -3934,17 +3934,17 @@ App.Facilities.Nursery.ChildSummary = function(child) { function shortRival(child) { if (child.rivalry !== 0) { r += ` `; - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return s.ID === child.rivalryTarget; }); if (_ssj !== -1) { r += `<span class="lightsalmon">`; if (child.rivalry <= 1) { - r += `Disl ${SlaveFullName(V.slaves[_ssj])}`; + r += `Disl ${SlaveFullName(getSlaves()[_ssj])}`; } else if (child.rivalry <= 2) { - r += `${SlaveFullName(V.slaves[_ssj])}'s rival`; + r += `${SlaveFullName(getSlaves()[_ssj])}'s rival`; } else { - r += `Hates ${SlaveFullName(V.slaves[_ssj])}`; + r += `Hates ${SlaveFullName(getSlaves()[_ssj])}`; } r += `</span> `; } @@ -3957,12 +3957,12 @@ App.Facilities.Nursery.ChildSummary = function(child) { function longExtendedFamily(child) { let handled = 0; if (child.mother > 0) { - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return s.ID === child.mother; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">daughter`; - if (child.relationshipTarget === V.slaves[_ssj].ID) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s <span class="lightgreen">daughter`; + if (child.relationshipTarget === getSlaves()[_ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; @@ -3981,12 +3981,12 @@ App.Facilities.Nursery.ChildSummary = function(child) { r += `${V.missingTable[child.mother].fullName}'s <span class="lightgreen">daughter.</span> `; } if (child.father > 0 && child.father !== child.mother) { - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return s.ID === child.father; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">daughter`; - if (child.relationshipTarget === V.slaves[_ssj].ID) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s <span class="lightgreen">daughter`; + if (child.relationshipTarget === getSlaves()[_ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; @@ -4005,24 +4005,24 @@ App.Facilities.Nursery.ChildSummary = function(child) { r += `${V.missingTable[child.father].fullName}'s <span class="lightgreen">daughter.</span> `; } if (child.daughters === 1) { - let _ssj = V.slaves.findIndex(function(s) { + let _ssj = getSlaves().findIndex(function(s) { return s.mother === child.ID; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">mother`; - if (child.relationshipTarget === V.slaves[_ssj].ID) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s <span class="lightgreen">mother`; + if (child.relationshipTarget === getSlaves()[_ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; } r += `.</span> `; } - _ssj = V.slaves.findIndex(function(s) { + _ssj = getSlaves().findIndex(function(s) { return s.father === child.ID; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">father`; - if (child.relationshipTarget === V.slaves[_ssj].ID) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s <span class="lightgreen">father`; + if (child.relationshipTarget === getSlaves()[_ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; @@ -4039,12 +4039,12 @@ App.Facilities.Nursery.ChildSummary = function(child) { } } if (child.sisters === 1) { - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return areSisters(s, child) > 0; }); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">sister`; - if (child.relationshipTarget === V.slaves[_ssj].ID) { + r += `${SlaveFullName(getSlaves()[_ssj])}'s <span class="lightgreen">sister`; + if (child.relationshipTarget === getSlaves()[_ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; @@ -4061,12 +4061,12 @@ App.Facilities.Nursery.ChildSummary = function(child) { } } if (child.relationship > 0 && handled !== 1) { - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return s.ID === child.relationshipTarget; }); if (_ssj !== -1) { const friendship = relationshipTerm(child); - r += `${SlaveFullName(V.slaves[_ssj])}'s `; + r += `${SlaveFullName(getSlaves()[_ssj])}'s `; r += `<span class="lightgreen">${friendship}.</span> `; } } else if (child.relationship === -3 && child.mother !== -1 && child.father !== -1) { @@ -4093,16 +4093,16 @@ App.Facilities.Nursery.ChildSummary = function(child) { function longRival(child) { if (child.rivalry !== 0) { r += ` `; - const _ssj = V.slaves.findIndex(function(s) { + const _ssj = getSlaves().findIndex(function(s) { return s.ID === child.rivalryTarget; }); if (_ssj !== -1) { if (child.rivalry <= 1) { - r += `<span class="lightsalmon">Dislikes</span> ${SlaveFullName(V.slaves[_ssj])}. `; + r += `<span class="lightsalmon">Dislikes</span> ${SlaveFullName(getSlaves()[_ssj])}. `; } else if (child.rivalry <= 2) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightsalmon">rival.</span> `; + r += `${SlaveFullName(getSlaves()[_ssj])}'s <span class="lightsalmon">rival.</span> `; } else { - r += `<span class="lightsalmon">Hates</span> ${SlaveFullName(V.slaves[_ssj])}. `; + r += `<span class="lightsalmon">Hates</span> ${SlaveFullName(getSlaves()[_ssj])}. `; } } r += " "; diff --git a/src/npc/children/longChildDescription.js b/src/npc/children/longChildDescription.js index f0b7f89278862f3aed316e17bc432ff158a59321..70c7a14279a9ffba1389140f22152ce1e1d06406 100644 --- a/src/npc/children/longChildDescription.js +++ b/src/npc/children/longChildDescription.js @@ -7,7 +7,6 @@ App.Facilities.Nursery.LongChildDescription = function(child, {market = 0, event // MARK: Declarations const arcology = V.arcologies[0]; const PC = V.PC; - const slaves = V.slaves; const desc = child.actualAge < 13 ? `child` : `teen`; // TODO: const father = child.father === -1 ? PC : getSlave(child.father); const mother = child.mother === -1 ? PC : getSlave(child.mother); diff --git a/src/npc/databases/cheatmodeDatabase.js b/src/npc/databases/cheatmodeDatabase.js index 09db66a30337d22487cbf325d670bf646ee7145c..d89edb30af11bc02b8baa456dec5c1f8dd2714e0 100644 --- a/src/npc/databases/cheatmodeDatabase.js +++ b/src/npc/databases/cheatmodeDatabase.js @@ -12,6 +12,7 @@ App.Intro.cheatModeSlaves = function() { const templates = App.Utils.buildHeroArray().pluckMany(jsRandom(3, 6)); for (const template of templates) { const HS = App.Utils.getHeroSlave(template); + V.heroSlavesPurchased.push(template.ID); newSlave(HS); slaveNames.push(HS.slaveName); } diff --git a/src/npc/databases/slavesDatabase_000-Instructions.md b/src/npc/databases/slavesDatabase_000-Instructions.md index acc74a9207f47797190cacc9abfff41285b29162..dfee07c6757acf17b34f86b6a3d444a1e6c5712a 100644 --- a/src/npc/databases/slavesDatabase_000-Instructions.md +++ b/src/npc/databases/slavesDatabase_000-Instructions.md @@ -58,15 +58,26 @@ To make a female Hero Slave infertile, give her an "ovaries" value of 1, and a " To make a male Hero Slave infertile without castrating him, set "ballType" to "sterile". -## Removing Limbs From Hero Slaves +## Removing Hero Slave limbs or making them prostetics -Hero Slaves with missing limbs need to go in one of the extreme databases +Hero Slaves with missing limbs need to go in one of the extreme databases. +Hero Slaves with prostetics can usually go into any of the databases. -To remove limbs from a Hero Slave you use the `removedLimbs` property. -This property is an array with a 1 or 0 in 4 different positions. The positions are `[left arm, right arm, left leg, right leg]`. A 1 will remove that limb, while a 0 will keep it. For example `[1, 1, 1, 1]` would remove all limbs from the given slave and `[1, 1, 0, 0]` would only remove the arms. +To modify a Hero Slave's limbs you use the `_limbs` property. +This property is an array of 4 numbers. The positions are `[left arm, right arm, left leg, right leg]`. A 0 will remove that limb, while a 1 will keep it natural. Anything above 1 will set that limb to the prostetic corresponding to the given number. For example `[0, 0, 0, 0]` would remove all limbs from the given slave, `[0, 0, 1, 1]` would only remove the arms, and `[6, 6, 0, 1]` would make both arms cybernetic prostetics, remove the left leg, and keep the right leg natural. See existing extreme slaves for examples. +Here are the different limb types available: + +* 0: removed +* 1: normal +* 2: simple prosthetic +* 3: advanced - Sex +* 4: advanced - Beauty +* 5: advanced - Combat +* 6: cybernetic + ## Families Two slaves can be siblings (parent/child relationships can't easily be made to work with the Special Market, because the relationship is stored only on the child). To be siblings, two slaves must share at least one parent (a negative dummy ID, not the ID of a slave in the game--make sure it doesn't conflict with parent ID's already in the databases); it's helpful to match sure they match by setting their birth surname, race, and nationality explicitly, and setting twins' birth weeks explicitly. diff --git a/src/npc/databases/slavesDatabase_XX_Extreme.js b/src/npc/databases/slavesDatabase_XX_Extreme.js index 3dd6d67383c45958c08a6171250820f7f14ad634..d50bb1fb69ce67e42b09c5a81f09b504addd5cf7 100644 --- a/src/npc/databases/slavesDatabase_XX_Extreme.js +++ b/src/npc/databases/slavesDatabase_XX_Extreme.js @@ -40,7 +40,7 @@ App.Data.HeroSlaves.XXExtreme = [ fetishKnown: 1, voice: 0, nipples: "puffy", - removedLimbs: [1, 1, 1, 1] + _limbs: [0, 0, 0, 0] }, { /* put some of $his custom description in $his origin (box stuff), tagged as amp, lowered obedience, increased weight but lowered health, changed skin color from white to pale */ @@ -81,7 +81,7 @@ App.Data.HeroSlaves.XXExtreme = [ attrXY: 40, fetishKnown: 1, custom: {desc: "$His amputation sites have titanium rings that go through to the bone. $He has been chemically blinded."}, - removedLimbs: [1, 1, 1, 1], + _limbs: [0, 0, 0, 0], eye: { left: { vision: 0 @@ -122,7 +122,7 @@ App.Data.HeroSlaves.XXExtreme = [ behavioralFlaw: "odd", custom: {desc: "$He is a work of art: stoic, mysterious, doll-like — and always smiling."}, voice: 0, - removedLimbs: [1, 1, 1, 1], + _limbs: [0, 0, 0, 0], }, { /* Added career to match origin. -DerangedLoner */ @@ -201,7 +201,7 @@ App.Data.HeroSlaves.XXExtreme = [ nipple: {weight: 2}, lips: {weight: 2}, tongue: {weight: 2}, vagina: {weight: 2}, anus: {weight: 2}, ear: {weight: 2}, nose: {weight: 2}, eyebrow: {weight: 2}, navel: {weight: 2}, genitals: {weight: 2, smart: true} }, clitSetting: "boobs", - removedLimbs: [1, 1, 1, 1], + _limbs: [0, 0, 0, 0], career: "homeless" }, { @@ -257,7 +257,7 @@ App.Data.HeroSlaves.XXExtreme = [ energy: 100, attrXY: 40, fetishKnown: 1, - removedLimbs: [1, 1, 1, 1], + _limbs: [0, 0, 0, 0], career: "a political activist" }, { @@ -333,7 +333,7 @@ App.Data.HeroSlaves.XXExtreme = [ fetishKnown: 1, behavioralFlaw: "bitchy", custom: {desc: "$He fits perfectly into a pillowcase."}, - removedLimbs: [1, 1, 1, 1], + _limbs: [0, 0, 0, 0], }, { /* mindbroken*/ diff --git a/src/npc/databases/slavesDatabase_XY_Extreme.js b/src/npc/databases/slavesDatabase_XY_Extreme.js index f0da94e2c1763648e124cae83483e0712b5436dc..220e29c85c45a696bc27589b7e1d1ba2fb7e9031 100644 --- a/src/npc/databases/slavesDatabase_XY_Extreme.js +++ b/src/npc/databases/slavesDatabase_XY_Extreme.js @@ -107,6 +107,6 @@ App.Data.HeroSlaves.XYExtreme = [ fetish: "submissive", fetishKnown: 1, behavioralQuirk: "advocate", - removedLimbs: [1, 1, 1, 1], + _limbs: [0, 0, 0, 0], }, ]; diff --git a/src/npc/descriptions/accent.js b/src/npc/descriptions/accent.js index 123b20126a038bcc739032cbb3def8fad6b312e9..f962e0061f1b77d991f5900bc6eb30e93d523ec1 100644 --- a/src/npc/descriptions/accent.js +++ b/src/npc/descriptions/accent.js @@ -8,7 +8,7 @@ App.Desc.accent = function(slave) { him, He } = getPronouns(slave); let accent; - if (slave.accent !== 0) { + if (slave.voice > 0 && slave.accent !== 0) { if (slave.accent === 1) { accent = either("a beautiful", "a distinctive", "an intriguing", "a light", "a lovely", "a mild", "a pleasant", "a rich", "a slight", "a smooth"); r.push(`${He} speaks ${V.language} in ${accent}`); diff --git a/src/npc/descriptions/descriptionWidgets.js b/src/npc/descriptions/descriptionWidgets.js index 9ff56a5facb9f0c38cb85fb27e3b8c8f596a8c36..d330576e16744b7a764fea5eefa10cb0301eef11 100644 --- a/src/npc/descriptions/descriptionWidgets.js +++ b/src/npc/descriptions/descriptionWidgets.js @@ -1393,7 +1393,7 @@ App.Desc.sexualHistory = function(slave) { } if (slave.counter.slavesKnockedUp > 0 || slave.counter.slavesFathered > 0 || slave.counter.PCKnockedUp > 0) { - let PCChildrenFatheredCount = V.slaves.filter(s => s.father === slave.ID && s.mother === -1).length; // The slave is also the father of the children transferred from the PC's womb to other slave's one. + let PCChildrenFatheredCount = getSlaves().filter(s => s.father === slave.ID && s.mother === -1).length; // The slave is also the father of the children transferred from the PC's womb to other slave's one. r += `<span class="relationship">`; if (slave.counter.slavesKnockedUp > 0) { r += `${He}'s knocked up ${numberWithPluralOne(slave.counter.slavesKnockedUp, "other slave girl")} `; diff --git a/src/npc/generate/generateGenetics.js b/src/npc/generate/generateGenetics.js index e4af097d88ddbd9223637041fe82abfc285baf6e..3d58a778ca24463a529c6d5b89a76c24e8c58fa8 100644 --- a/src/npc/generate/generateGenetics.js +++ b/src/npc/generate/generateGenetics.js @@ -2,11 +2,11 @@ // Generates a child's genetics based off mother and father and returns it as an object to be attached to an ovum globalThis.generateGenetics = (function() { - /** @type {FC.GenePoolRecord} */ + /** @type {ReadonlyDeep<FC.GenePoolRecord>} */ let mother; /** @type {FC.Zeroable<FC.GenePoolRecord>} */ let activeMother; - /** @type {FC.Zeroable<FC.GenePoolRecord>} */ + /** @type {FC.Zeroable<ReadonlyDeep<FC.GenePoolRecord>>} */ let father; /** @type {FC.Zeroable<FC.GenePoolRecord>} */ let activeFather; @@ -122,8 +122,8 @@ globalThis.generateGenetics = (function() { } /** set expected adult height for the fetus - * @param {FC.Zeroable<FC.GenePoolRecord>} father - * @param {FC.GenePoolRecord} mother + * @param {FC.Zeroable<ReadonlyDeep<FC.GenePoolRecord>>} father + * @param {ReadonlyDeep<FC.GenePoolRecord>} mother * @param {string} gender * @param {FC.Race} race * @param {string} nationality @@ -153,8 +153,8 @@ globalThis.generateGenetics = (function() { } /** set breast size potential for the fetus - * @param {FC.GenePoolRecord} mother - * @param {FC.Zeroable<FC.GenePoolRecord>} father + * @param {ReadonlyDeep<FC.GenePoolRecord>} mother + * @param {FC.Zeroable<ReadonlyDeep<FC.GenePoolRecord>>} father * @returns {number} */ function setBoobPotential(mother, father) { @@ -338,8 +338,8 @@ globalThis.generateGenetics = (function() { } /** - * @param {FC.Zeroable<FC.GenePoolRecord>} father - * @param {FC.GenePoolRecord} mother + * @param {FC.Zeroable<ReadonlyDeep<FC.GenePoolRecord>>} father + * @param {ReadonlyDeep<FC.GenePoolRecord>} mother * @param {FC.Race} race */ function setSkin(father, mother, race) { @@ -429,6 +429,10 @@ globalThis.generateGenetics = (function() { */ function validGeneticEyeColor(eyeColor) { switch (eyeColor) { + case undefined: + console.error(new Error(`validGeneticEyeColor was given 'undefined' instead of a string! Setting the eye color to 'brown'`)); + eyeColor = "brown"; + break; case "blind blue": eyeColor = "deep blue"; break; @@ -443,8 +447,8 @@ globalThis.generateGenetics = (function() { // eyeColor function setEyeColor(father, mother) { let eyeColor; - /** @type {FC.Zeroable<string>} */ - let fatherEye = 0; + /** @type {string} */ + let fatherEye; // during BC WombInit, the mother has been updated but the father might not have been yet. // if the father is defined but doesn't have eyes, see if maybe he has an old eye color diff --git a/src/npc/generate/heroCreator.js b/src/npc/generate/heroCreator.js index fb06e20777f5d696bcf61838ea7cc3c35492cc8d..53d36fbb2c2e0d1ff96f59db8abc2b9aed211c7b 100644 --- a/src/npc/generate/heroCreator.js +++ b/src/npc/generate/heroCreator.js @@ -1,7 +1,7 @@ // cSpell:ignore Dextreme, Dincest, lolify, lolifying, lolification /** creates an array from App.Data.HeroSlaves that will be similar to the old $heroSlaves. - * @returns {Array} + * @returns {FC.HeroSlaveTemplate[]} */ App.Utils.buildHeroArray = function() { let chunks = []; @@ -90,31 +90,32 @@ App.Utils.getHeroFamilies = function() { }; /** - * @param {FC.HeroSlaveTemplate} template + * @param {FC.HeroSlaveTemplate} heroTemplate * @param {number} [newAge=undefined] * @returns {FC.SlaveState} * The optional newAge parameter is used for maintaining age gaps between siblings during arcology acquisition, and to make sure * one sibling isn't lolified if the other isn't. It has no effect outside of pedo mode, but in pedo m [The rest of this is missing for some reason] */ -App.Utils.getHeroSlave = function(template, newAge = undefined) { +App.Utils.getHeroSlave = function(heroTemplate, newAge = undefined) { + const template = clone(heroTemplate); /** * @param {FC.SlaveState & FC.HeroSlaveTemplate} slave */ function repairLimbs(slave) { - if (slave.hasOwnProperty("removedLimbs")) { - if (slave.removedLimbs[0] === 1) { - removeLimbs(slave, "left arm"); + if (slave.hasOwnProperty("_limbs")) { + if (slave._limbs[0] >= 0) { + configureLimbs(slave, "left arm", slave._limbs[0]); } - if (slave.removedLimbs[1] === 1) { - removeLimbs(slave, "right arm"); + if (slave._limbs[1] >= 0) { + configureLimbs(slave, "right arm", slave._limbs[1]); } - if (slave.removedLimbs[2] === 1) { - removeLimbs(slave, "left leg"); + if (slave._limbs[2] >= 0) { + configureLimbs(slave, "left leg", slave._limbs[2]); } - if (slave.removedLimbs[3] === 1) { - removeLimbs(slave, "right leg"); + if (slave._limbs[3] >= 0) { + configureLimbs(slave, "right leg", slave._limbs[3]); } - delete slave.removedLimbs; + delete slave._limbs; } } @@ -203,7 +204,7 @@ App.Utils.getHeroSlave = function(template, newAge = undefined) { */ let slave; if (heroSlave.mother === -9999 && heroSlave.father === -9998) { // The twins — Camille & Kennerly - slave = V.slaves.find(s => areSisters(s, heroSlave) > 0); + slave = getSlaves().find(s => areSisters(s, heroSlave) > 0); if (slave) { heroSlave.actualAge = slave.actualAge; heroSlave.physicalAge = heroSlave.actualAge; @@ -223,7 +224,7 @@ App.Utils.getHeroSlave = function(template, newAge = undefined) { } } if (heroSlave.mother === -9997 && heroSlave.father === -9996) { // The rebel siblings — Elisa & Martin - slave = V.slaves.find(s => areSisters(s, heroSlave) > 0); + slave = getSlaves().find(s => areSisters(s, heroSlave) > 0); if (slave) { const adjustedAge = adjustNewSiblingAge(heroSlave, slave, "Elisa", "Martin", 1, 1); newAge = adjustedAge; @@ -238,7 +239,7 @@ App.Utils.getHeroSlave = function(template, newAge = undefined) { } } if (heroSlave.mother === -9995 && heroSlave.father === -9994) { // The fruit siblings — Green & Purple Grape - slave = V.slaves.find(s => areSisters(s, heroSlave) > 0); + slave = getSlaves().find(s => areSisters(s, heroSlave) > 0); if (slave) { const adjustedAge = adjustNewSiblingAge(heroSlave, slave, "Green Grape", "Purple Grape", 5, 3); newAge = adjustedAge; @@ -253,7 +254,7 @@ App.Utils.getHeroSlave = function(template, newAge = undefined) { } } if (heroSlave.mother === -9993 && heroSlave.father === -9992) { // The professional siblings — Bai & Qiang - slave = V.slaves.find(s => areSisters(s, heroSlave) > 0); + slave = getSlaves().find(s => areSisters(s, heroSlave) > 0); if (slave) { const adjustedAge = adjustNewSiblingAge(heroSlave, slave, "Qiang", "Bai", 2, 2); newAge = adjustedAge; diff --git a/src/npc/importSlave.js b/src/npc/importSlave.js index 507504b57bbc39b43b6af46a3982f4b20ccf2972..7754d3e6291c7a13d2525ad51b314300f9af97b9 100644 --- a/src/npc/importSlave.js +++ b/src/npc/importSlave.js @@ -44,7 +44,7 @@ App.UI.SlaveInteract.importSlaveFromCharacterCard = () => { const pngAb = await pngFile.arrayBuffer(); const allTextContent = App.UI.SlaveInteract.SlaveBot.Png.Parse(pngAb); - const slaveBotObj = JSON.parse(allTextContent); + const slaveBotObj = Serial.parse(allTextContent); /** * Parser returns the stuff we care about under "data". * @type {FC.SlaveBot.CharacterBook} @@ -95,7 +95,7 @@ App.UI.SlaveInteract.importSlaveFromString = (slaveSrc, div) => { if (slaveSrc[0] !== "{") { slaveSrc = "{" + slaveSrc; } if (slaveSrc.slice(-1) !== "}") { slaveSrc += "}"; } // generate slave - let slave = JSON.parse(slaveSrc); + let slave = Serial.parse(slaveSrc); slave.ID = generateSlaveID(); App.Verify.slaveState("<imported>", slave, "none", div); if (slave?.assignment) { @@ -112,7 +112,7 @@ App.UI.SlaveInteract.exportSlave = function(slave) { const exportSlave = _.cloneDeep(slave); App.Verify.slaveState("<exported>", exportSlave, "none"); exportSlave.ID = 0; - return JSON.stringify(exportSlave, null, 2); + return Serial.stringify(exportSlave, null, 2); }; /** diff --git a/src/npc/infants/infantSummary.js b/src/npc/infants/infantSummary.js index 90bf6f628d4285ea45443eb51cdb10307bad7a97..ea4747450f651711b667b87e605d254155037f96 100644 --- a/src/npc/infants/infantSummary.js +++ b/src/npc/infants/infantSummary.js @@ -1563,12 +1563,12 @@ App.Facilities.Nursery.InfantSummary = function(child) { let r = ``; if (child.mother > 0) { - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return s.ID === child.mother; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s ${daughter}`; - if (child.relationshipTarget === V.slaves[ssj].ID) { + r += `${SlaveFullName(getSlaves()[ssj])}'s ${daughter}`; + if (child.relationshipTarget === getSlaves()[ssj].ID) { const friendShipShort = relationshipTermShort(child); r += ` & ${friendShipShort}`; handled = 1; @@ -1587,12 +1587,12 @@ App.Facilities.Nursery.InfantSummary = function(child) { } if (child.father > 0 && child.father !== child.mother) { - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return s.ID === child.father; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s ${daughter}`; - if (child.relationshipTarget === V.slaves[ssj].ID && handled !== 1) { + r += `${SlaveFullName(getSlaves()[ssj])}'s ${daughter}`; + if (child.relationshipTarget === getSlaves()[ssj].ID && handled !== 1) { const friendShipShort = relationshipTermShort(child); r += ` & ${friendShipShort}`; handled = 1; @@ -1611,24 +1611,24 @@ App.Facilities.Nursery.InfantSummary = function(child) { } if (child.daughters === 1) { - let ssj = V.slaves.findIndex(function(s) { + let ssj = getSlaves().findIndex(function(s) { return s.mother === child.ID; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s mother`; - if (child.relationshipTarget === V.slaves[ssj].ID) { + r += `${SlaveFullName(getSlaves()[ssj])}'s mother`; + if (child.relationshipTarget === getSlaves()[ssj].ID) { const friendShipShort = relationshipTermShort(child); r += ` & ${friendShipShort}`; handled = 1; } } r += " "; - ssj = V.slaves.findIndex(function(s) { + ssj = getSlaves().findIndex(function(s) { return s.father === child.ID; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s father`; - if (child.relationshipTarget === V.slaves[ssj].ID && handled !== 1) { + r += `${SlaveFullName(getSlaves()[ssj])}'s father`; + if (child.relationshipTarget === getSlaves()[ssj].ID && handled !== 1) { const friendShipShort = relationshipTermShort(child); r += ` & ${friendShipShort}`; handled = 1; @@ -1640,12 +1640,12 @@ App.Facilities.Nursery.InfantSummary = function(child) { } if (child.sisters === 1) { - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return areSisters(s, child) > 0; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s ${sister}`; - if (child.relationshipTarget === V.slaves[ssj].ID) { + r += `${SlaveFullName(getSlaves()[ssj])}'s ${sister}`; + if (child.relationshipTarget === getSlaves()[ssj].ID) { const friendShipShort = relationshipTermShort(child); r += `& ${friendShipShort}`; handled = 1; @@ -1657,11 +1657,11 @@ App.Facilities.Nursery.InfantSummary = function(child) { } if (child.relationship > 0 && handled !== 1) { - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return s.ID === child.relationshipTarget; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s`; + r += `${SlaveFullName(getSlaves()[ssj])}'s`; const friendShipShort = relationshipTermShort(child); r += ` ${friendShipShort}`; } @@ -1683,12 +1683,12 @@ App.Facilities.Nursery.InfantSummary = function(child) { let r = ``; if (child.mother > 0) { - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return s.ID === child.mother; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s <span class="lightgreen">${daughter}`; - if (child.relationshipTarget === V.slaves[ssj].ID) { + r += `${SlaveFullName(getSlaves()[ssj])}'s <span class="lightgreen">${daughter}`; + if (child.relationshipTarget === getSlaves()[ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; @@ -1709,12 +1709,12 @@ App.Facilities.Nursery.InfantSummary = function(child) { } if (child.father > 0 && child.father !== child.mother) { - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return s.ID === child.father; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s <span class="lightgreen">${daughter}`; - if (child.relationshipTarget === V.slaves[ssj].ID) { + r += `${SlaveFullName(getSlaves()[ssj])}'s <span class="lightgreen">${daughter}`; + if (child.relationshipTarget === getSlaves()[ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; @@ -1734,24 +1734,24 @@ App.Facilities.Nursery.InfantSummary = function(child) { } if (child.daughters === 1) { - let ssj = V.slaves.findIndex(function(s) { + let ssj = getSlaves().findIndex(function(s) { return s.mother === child.ID; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s <span class="lightgreen">mother`; - if (child.relationshipTarget === V.slaves[ssj].ID) { + r += `${SlaveFullName(getSlaves()[ssj])}'s <span class="lightgreen">mother`; + if (child.relationshipTarget === getSlaves()[ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; } r += `.</span> `; } - ssj = V.slaves.findIndex(function(s) { + ssj = getSlaves().findIndex(function(s) { return s.father === child.ID; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s <span class="lightgreen">father`; - if (child.relationshipTarget === V.slaves[ssj].ID) { + r += `${SlaveFullName(getSlaves()[ssj])}'s <span class="lightgreen">father`; + if (child.relationshipTarget === getSlaves()[ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; @@ -1769,12 +1769,12 @@ App.Facilities.Nursery.InfantSummary = function(child) { } if (child.sisters === 1) { - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return areSisters(s, child) > 0; }); if (ssj !== -1) { - r += `${SlaveFullName(V.slaves[ssj])}'s <span class="lightgreen">${sister}`; - if (child.relationshipTarget === V.slaves[ssj].ID) { + r += `${SlaveFullName(getSlaves()[ssj])}'s <span class="lightgreen">${sister}`; + if (child.relationshipTarget === getSlaves()[ssj].ID) { const friendShipShort = relationshipTerm(child); r += ` and ${friendShipShort}`; handled = 1; @@ -1792,12 +1792,12 @@ App.Facilities.Nursery.InfantSummary = function(child) { } if (child.relationship > 0 && handled !== 1) { - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return s.ID === child.relationshipTarget; }); if (ssj !== -1) { const friendship = relationshipTerm(child); - r += `${SlaveFullName(V.slaves[ssj])}'s `; + r += `${SlaveFullName(getSlaves()[ssj])}'s `; r += `<span class="lightgreen">${friendship}.</span> `; } } else if (child.relationship === -3 && child.mother !== -1 && child.father !== -1) { @@ -1816,17 +1816,17 @@ App.Facilities.Nursery.InfantSummary = function(child) { if (child.rivalry !== 0) { r += ` `; - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return s.ID === child.rivalryTarget; }); if (ssj !== -1) { r += `<span class="lightsalmon">`; if (child.rivalry <= 1) { - r += `Disl ${SlaveFullName(V.slaves[ssj])}`; + r += `Disl ${SlaveFullName(getSlaves()[ssj])}`; } else if (child.rivalry <= 2) { - r += `${SlaveFullName(V.slaves[ssj])}'s rival`; + r += `${SlaveFullName(getSlaves()[ssj])}'s rival`; } else { - r += `Hates ${SlaveFullName(V.slaves[ssj])}`; + r += `Hates ${SlaveFullName(getSlaves()[ssj])}`; } r += `</span> `; } @@ -1840,17 +1840,17 @@ App.Facilities.Nursery.InfantSummary = function(child) { if (child.rivalry !== 0) { r += ` `; - const ssj = V.slaves.findIndex(function(s) { + const ssj = getSlaves().findIndex(function(s) { return s.ID === child.rivalryTarget; }); if (ssj !== -1) { if (child.rivalry <= 1) { - r += `<span class="lightsalmon">Dislikes</span> ${SlaveFullName(V.slaves[ssj])}. `; + r += `<span class="lightsalmon">Dislikes</span> ${SlaveFullName(getSlaves()[ssj])}. `; } else if (child.rivalry <= 2) { - r += `${SlaveFullName(V.slaves[ssj])}'s <span class="lightsalmon">rival.</span> `; + r += `${SlaveFullName(getSlaves()[ssj])}'s <span class="lightsalmon">rival.</span> `; } else { - r += `<span class="lightsalmon">Hates</span> ${SlaveFullName(V.slaves[ssj])}. `; + r += `<span class="lightsalmon">Hates</span> ${SlaveFullName(getSlaves()[ssj])}. `; } } r += " "; diff --git a/src/npc/interaction/fSuckDick.js b/src/npc/interaction/fSuckDick.js index 55737558913acb96b3edf167219b1ad3b8551939..e9c48e77f21817ea74c8a68ced4dbde76894f92a 100644 --- a/src/npc/interaction/fSuckDick.js +++ b/src/npc/interaction/fSuckDick.js @@ -654,7 +654,7 @@ App.Interact.fSuckDick = function(slave) { function cleanup() { const text = []; - if (V.slaves.length > 1) { + if (getSlaves().length > 1) { text.push(`You order one of your other slaves to clean up the mess on the floor.`); } else if (canMove(slave)) { text.push(`You order ${slave.slaveName} to clean up the mess on the floor, which ${he} does.`); diff --git a/src/npc/interaction/killSlave.js b/src/npc/interaction/killSlave.js index 9d1fc74ffe3e513a3d12d91094c2d9646fcae6fd..ed2f6d2a448698bbee2a6d491de1a1d3f161ac86 100644 --- a/src/npc/interaction/killSlave.js +++ b/src/npc/interaction/killSlave.js @@ -308,7 +308,7 @@ App.UI.SlaveInteract.killSlave = function(slave) { let relationshipTarget = null; let rival = null; - for (const target of V.slaves) { + for (const target of getSlaves()) { if (target.devotion > 50 && isWife) { target.trust -= 25; } @@ -567,7 +567,7 @@ App.UI.SlaveInteract.killSlave = function(slave) { function getWifeEffects() { const subDiv = document.createElement("div"); - V.slaves + getSlaves() .filter(slave => slave.devotion > 50) .forEach(slave => slave.devotion -= 15); diff --git a/src/npc/interaction/slaveOnSlaveFeeding/slaveOnSlaveFeeding.js b/src/npc/interaction/slaveOnSlaveFeeding/slaveOnSlaveFeeding.js index 2efe2a856a1092a999f48546fb2f0dccb075f55a..90b4771aef030cb02874b4c3e99942cb1e83b94c 100644 --- a/src/npc/interaction/slaveOnSlaveFeeding/slaveOnSlaveFeeding.js +++ b/src/npc/interaction/slaveOnSlaveFeeding/slaveOnSlaveFeeding.js @@ -40,7 +40,7 @@ App.UI.SlaveInteract.slaveOnSlaveFeedingSelection = function(slave) { header.append(App.UI.DOM.makeElement("th", name)); } - for (const tapSlave of V.slaves) { + for (const tapSlave of getSlaves()) { let output; if (inflationType === "milk") { output = (tapSlave.lactation > 0) ? milkLoad(tapSlave) : 0; diff --git a/src/npc/slaveBot/generateSlaveBot.js b/src/npc/slaveBot/generateSlaveBot.js index 9c8af462b0a5c6f423975e4406ef3279f29d8a6e..ab60f0e75a2e3a2724ac68c221df0a6860908b38 100644 --- a/src/npc/slaveBot/generateSlaveBot.js +++ b/src/npc/slaveBot/generateSlaveBot.js @@ -23,7 +23,7 @@ App.UI.SlaveInteract.SlaveBot.createSlaveBot = (slave) => { /** - * + * * @param {File} pngFile File from <input type="file" /> */ App.UI.SlaveInteract.SlaveBot.importSlavePNG = async (pngFile) => { @@ -34,7 +34,7 @@ App.UI.SlaveInteract.SlaveBot.importSlavePNG = async (pngFile) => { /** * @type {FC.SlaveBot.CharacterBook} */ - const slaveBotData = JSON.parse(allTextContent); + const slaveBotData = Serial.parse(allTextContent); if (!slaveBotData.extensions.freecitiesJSON) { alert("No Free Cities data found from this character card. Maybe it is corrupted?"); @@ -297,7 +297,7 @@ App.UI.SlaveInteract.SlaveBot.downloadFile = (file) => { * @returns {File} */ App.UI.SlaveInteract.SlaveBot.exportJsonFile = (characterCard) => { - const file = new File([JSON.stringify(characterCard, undefined, '\t')], `${characterCard.data.name || 'character'}.card.json`, { type: 'application/json;charset=utf-8' }); + const file = new File([Serial.stringify(characterCard, undefined, '\t')], `${characterCard.data.name || 'character'}.card.json`, {type: 'application/json;charset=utf-8'}); return file; }; @@ -312,7 +312,7 @@ App.UI.SlaveInteract.SlaveBot.exportFile = async (slaveState) => { if (V.aiCachingStrategy === 'static') { const displayedIdx = slaveState.custom.aiDisplayImageIdx; const imageDbId = slaveState.custom.aiImageIds[displayedIdx]; - const { data } = await App.Art.GenAI.staticImageDB.getImage(imageDbId); + const {data} = await App.Art.GenAI.staticImageDB.getImage(imageDbId); imageUrl = data; } else { @@ -335,23 +335,23 @@ App.UI.SlaveInteract.SlaveBot.exportFile = async (slaveState) => { - const json = JSON.stringify(characterCardObj, undefined, '\t'); + const json = Serial.stringify(characterCardObj, undefined, '\t'); const png = App.UI.SlaveInteract.Png.Generate(imageArrayBuffer, json); - const file = new File([png], `${characterCardObj.data.name || 'character'}.card.png`, { type: 'image/png' }); + const file = new File([png], `${characterCardObj.data.name || 'character'}.card.png`, {type: 'image/png'}); return file; } catch (e) { - const { fallbackImage, createCharacterDataFromSlave } = App.UI.SlaveInteract.SlaveBot; + const {fallbackImage, createCharacterDataFromSlave} = App.UI.SlaveInteract.SlaveBot; const imageRes = await fetch(fallbackImage); const imageArrayBuffer = await imageRes.arrayBuffer(); const characterCardObj = createCharacterDataFromSlave(slaveState); - const json = JSON.stringify(characterCardObj, undefined, '\t'); + const json = Serial.stringify(characterCardObj, undefined, '\t'); const png = App.UI.SlaveInteract.SlaveBot.Png.Generate(imageArrayBuffer, json); - const file = new File([png], `${characterCardObj.data.name || 'character'}.card.png`, { type: 'image/png' }); + const file = new File([png], `${characterCardObj.data.name || 'character'}.card.png`, {type: 'image/png'}); return file; } }; @@ -428,7 +428,7 @@ App.UI.SlaveInteract.SlaveBot.createCharacterDataFromSlave = (slave) => { */ App.UI.SlaveInteract.SlaveBot.Generate.description = (slave) => { let r = []; - const { he, his } = getPronouns(slave); + const {he, his} = getPronouns(slave); let descParts = []; // NAME @@ -869,7 +869,7 @@ App.UI.SlaveInteract.SlaveBot.Generate.standardPrompt = () => { */ App.UI.SlaveInteract.SlaveBot.Generate.firstMessage = (slave) => { let r = []; - const { He, His, he, his } = getPronouns(slave); + const {He, His, he, his} = getPronouns(slave); // Set up basic scenario r.push("I am sitting in my office as {{char}} arrives for inspection.\r\n"); @@ -1319,7 +1319,7 @@ App.UI.SlaveInteract.SlaveBot.Generate.lorebookHeadGirl = (startId) => { keys: ["Head Girl", "headgirl", S.HeadGirl.slaveName], // either/or title, first name secondary_keys: [], // not used comment: "HeadGirl", - content: App.UI.SlaveInteract.SlaveBot.Generate.description(S.HeadGirl) + "/nThe head girl manages the health, training, and wellbeing of all slaves in your penthouse, and ensures your businesses are running smoothly.",// slave description minus relationships + content: App.UI.SlaveInteract.SlaveBot.Generate.description(S.HeadGirl) + "/nThe head girl manages the health, training, and wellbeing of all slaves in your penthouse, and ensures your businesses are running smoothly.", // slave description minus relationships constant: false, // selectively applied selective: false, insertion_order: 100, diff --git a/src/npc/slaveBot/slaveBotGreetings.js b/src/npc/slaveBot/slaveBotGreetings.js index fd8a9e5f786980ae782deb92f4ff8d68f718fe25..04315e1dea5c1706598a17f06d0f593bc6a13ffe 100644 --- a/src/npc/slaveBot/slaveBotGreetings.js +++ b/src/npc/slaveBot/slaveBotGreetings.js @@ -1583,7 +1583,7 @@ App.UI.SlaveInteract.SlaveBotGreetings = [ // SRC torpedoSqueeze let r = []; r.push(`The penthouse bathroom has a long counter and mirror arrangement with many sinks, so a number of slaves can get ready at once. During those moments of the day when`); - if (V.slaves.length > 10) { + if (getSlaves().length > 10) { r.push(`many`); } else { r.push(`more than one`); diff --git a/src/npc/startingGirls/editFamily.js b/src/npc/startingGirls/editFamily.js index 8568f8c131075887055dbed0e61136899dac6352..32b90d13d782ce762c0dfdc75c6075cef0f8a30d 100644 --- a/src/npc/startingGirls/editFamily.js +++ b/src/npc/startingGirls/editFamily.js @@ -122,7 +122,7 @@ App.Intro.editFamily = function(slave, cheat) { ) ); - for (const potentialRel of V.slaves) { + for (const potentialRel of getSlaves()) { const relTerm = relativeTerm(slave, potentialRel); const link = document.createElement("span"); link.append(App.UI.DOM.link( @@ -192,7 +192,7 @@ App.Intro.editFamily = function(slave, cheat) { ) ); - for (const potentialRival of V.slaves) { + for (const potentialRival of getSlaves()) { linkArray.push(App.UI.DOM.link( potentialRival.slaveName, () => { @@ -241,7 +241,7 @@ App.Intro.editFamily = function(slave, cheat) { ); } - for (const potentialRel of V.slaves) { + for (const potentialRel of getSlaves()) { if (canBecomeMotherOf(slave, potentialRel) && potentialRel.newGamePlus === 0) { linkArray.push( App.UI.DOM.link( @@ -294,7 +294,7 @@ App.Intro.editFamily = function(slave, cheat) { ); } - for (const potentialRel of V.slaves) { + for (const potentialRel of getSlaves()) { if (canBecomeFatherOf(slave, potentialRel) && potentialRel.newGamePlus === 0) { linkArray.push( App.UI.DOM.link( @@ -349,7 +349,7 @@ App.Intro.editFamily = function(slave, cheat) { ); } - for (const potentialRel of V.slaves) { + for (const potentialRel of getSlaves()) { if ((!mother || canBecomeMotherOf(potentialRel, mother)) && potentialRel.newGamePlus === 0) { linkArray.push( App.UI.DOM.link( @@ -418,7 +418,7 @@ App.Intro.editFamily = function(slave, cheat) { ); } - for (const potentialRel of V.slaves) { + for (const potentialRel of getSlaves()) { if ((!father || canBecomeFatherOf(potentialRel, father)) && potentialRel.newGamePlus === 0) { linkArray.push( App.UI.DOM.link( @@ -461,7 +461,7 @@ App.Intro.editFamily = function(slave, cheat) { App.UI.DOM.link( "Reset", () => { - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.mother === slave.ID && s.newGamePlus === 0) { s.mother = 0; } @@ -486,7 +486,7 @@ App.Intro.editFamily = function(slave, cheat) { ); } - for (const potentialRel of V.slaves) { + for (const potentialRel of getSlaves()) { if (canBecomeMotherOf(potentialRel, slave) && potentialRel.newGamePlus === 0) { linkArray.push( App.UI.DOM.link( @@ -536,7 +536,7 @@ App.Intro.editFamily = function(slave, cheat) { App.UI.DOM.link( "Reset", () => { - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.father === slave.ID && s.newGamePlus === 0) { s.father = 0; } @@ -561,7 +561,7 @@ App.Intro.editFamily = function(slave, cheat) { ); } - for (const potentialRel of V.slaves) { + for (const potentialRel of getSlaves()) { if (canBecomeFatherOf(potentialRel, slave) && potentialRel.newGamePlus === 0) { linkArray.push( App.UI.DOM.link( @@ -599,7 +599,7 @@ App.Intro.editFamily = function(slave, cheat) { App.UI.DOM.link( "Reset ALL PC Relatives", () => { - for (const s of V.slaves) { + for (const s of getSlaves()) { if (s.newGamePlus === 0) { if (s.mother === V.PC.ID || s.mother === V.PC.mother) { s.mother = 0; diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js index 49e1935f9b67e79129bc0dbe25eaeed64f6d4f3e..0b33b65ef084ee5cb68cacb8cbf1fa19d0e80b28 100644 --- a/src/npc/startingGirls/startingGirls.js +++ b/src/npc/startingGirls/startingGirls.js @@ -308,7 +308,7 @@ App.StartingGirls.listOfSlavesWithParent = function(parent, id) { if (V.PC[parent] === id) { slaveNames.push("You"); } - const slavesWithParent = V.slaves.filter((s) => s[parent] === id); + const slavesWithParent = getSlaves().filter((s) => s[parent] === id); slaveNames = slaveNames.concat(slavesWithParent.map((s) => s.slaveName)); return slaveNames.join(" | "); }; @@ -319,7 +319,7 @@ App.StartingGirls.listOfSlavesWithParent = function(parent, id) { */ App.StartingGirls.uncommittedFamilyTree = function(slave) { /** @type {FC.HumanState[]} */ - let tSlaves = V.slaves.filter(s => s.ID !== slave.ID); // exclude the unedited copy of this slave, if it exists + let tSlaves = getSlaves().filter(s => s.ID !== slave.ID); // exclude the unedited copy of this slave, if it exists return renderFamilyTree(tSlaves.concat([slave]), slave.ID); }; @@ -2014,7 +2014,7 @@ App.StartingGirls.mental = function(slave, cheat = false) { .addValueList([["Uneducated", 0], ["Educated", 15], ["Well educated", 30]]); option = options.addOption("Devotion", "devotion", slave); - App.StartingGirls.addSet(option, App.Data.StartingGirls.devotion, true); + App.StartingGirls.addSet(option, App.Data.StartingGirls.devotion, cheat); if (slave.devotion > 20 && !cheat) { r = []; r.push("Starting slaves incur"); @@ -2036,7 +2036,7 @@ App.StartingGirls.mental = function(slave, cheat = false) { } option = options.addOption("Trust", "trust", slave); - App.StartingGirls.addSet(option, App.Data.StartingGirls.trust, true); + App.StartingGirls.addSet(option, App.Data.StartingGirls.trust, cheat); const rollRandomFetish = () => either("boobs", "buttslut", "cumslut", "dom", "humiliation", "masochist", "pregnancy", "sadist", "submissive", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none"); diff --git a/src/npc/startingGirls/startingGirlsPassage.js b/src/npc/startingGirls/startingGirlsPassage.js index 53061c92c655ebf2169057d988aba5bac19f3125..8adc6b750e72b2b35032ae7148efa0c335027746 100644 --- a/src/npc/startingGirls/startingGirlsPassage.js +++ b/src/npc/startingGirls/startingGirlsPassage.js @@ -6,7 +6,7 @@ App.StartingGirls.passage = function() { const el = new DocumentFragment(); let r = []; let linkArray = []; - if (V.slaves.length === 0) { + if (getSlaves().length === 0) { r.push(`You're no stranger to the Free Cities, which means you're no stranger to slavery. If you wish, you can bring slaves from your past life with you to your arcology. You can spend your cash reserves on slaves here, or bring it with you to start the game. Slaves created here will be much cheaper than if they were purchased on the market.`); if (V.PC.dick !== 0 && V.PC.vagina !== -1 && (V.seeDicks !== 0 || V.makeDicks === 1)) { r.push(`Since you have both a penis and a vagina yourself, you've obviously had access to a source of advanced surgery and organ farming. <span class="skill player">Slaves get a smaller cost increase here for having both penises and vaginas, and for having both testicles and ovaries.</span>`); @@ -23,13 +23,13 @@ App.StartingGirls.passage = function() { r.push(`these slaves, <span class="skill player">they cost half of what they normally would have here.</span>`); } } else { - const pronoun = V.slaves.length > 1 ? "they" : getPronouns(V.slaves[0]).he; + const pronoun = getSlaves().length > 1 ? "they" : getPronouns(getSlaves()[0]).he; r.push(`The following slave records have been finalized; ${pronoun} will arrive with you when you take over your new arcology.`); } r.push(App.UI.DOM.makeElement("div", "Current cash reserves can be found on the far left sidebar.")); App.Events.addNode(el, r, "p"); - if (V.slaves.length > 0) { - for (const slave of V.slaves) { + if (getSlaves().length > 0) { + for (const slave of getSlaves()) { const cost = slave.slaveCost; App.Events.addNode(el, [ App.UI.DOM.slaveDescriptionDialog(slave), @@ -344,7 +344,7 @@ App.StartingGirls.passage = function() { ) ); - const newSlaves = V.slaves.filter(s => s.newGamePlus === 0); + const newSlaves = getSlaves().filter(s => s.newGamePlus === 0); if (newSlaves.length > 0) { linkArray.push( App.UI.DOM.link( diff --git a/src/npc/surgery/bodySwap/bodySwap.js b/src/npc/surgery/bodySwap/bodySwap.js index 99af7253e2dc64f60f40cd5866daa8b104df290f..3cfeb506efe31b1a372be31ee7e46ea0e0d6ef3e 100644 --- a/src/npc/surgery/bodySwap/bodySwap.js +++ b/src/npc/surgery/bodySwap/bodySwap.js @@ -259,7 +259,7 @@ globalThis.bodySwapSelection = function(soul) { App.UI.DOM.appendNewElement("div", el, `The surgeon awaits the pair of slaves to be strapped into the surgery. So far only ${soul.slaveName} is prepped:`, "scene-intro"); App.UI.DOM.appendNewElement("div", el, `Select ${(V.seeExtreme) ? `an eligible slave (any slave who is not a fuckdoll)` : `a slave`} who will be trading bodies with ${him}. This operation will cost ${cashFormat(cost)}.`); - for (const body of V.slaves) { + for (const body of getSlaves()) { if (body.ID === soul.ID) { // Do not allow slave to be swapped with themselves continue; } @@ -333,7 +333,7 @@ globalThis.huskSwapSelection = function(body) { `, "scene-intro"); App.UI.DOM.appendNewElement("div", el, `Select the slave whose mind will be transferred into the waiting husk. Amputated slaves must not be wearing prosthetics. This operation will cost ${cashFormat(cost)}.`); - for (const soul of V.slaves) { + for (const soul of getSlaves()) { if (isSlaveAvailable(soul)) { if (soul.fuckdoll === 0) { if (!hasAnyProstheticLimbs(soul)) { diff --git a/src/npc/surgery/bodySwap/huskSlaveSwap.js b/src/npc/surgery/bodySwap/huskSlaveSwap.js index 65399965cbdfb9e1188b37a8b861626720376ad1..59d85bce3297c4a70f0089c1fb04da499f30686e 100644 --- a/src/npc/surgery/bodySwap/huskSlaveSwap.js +++ b/src/npc/surgery/bodySwap/huskSlaveSwap.js @@ -9,7 +9,7 @@ App.UI.SlaveInteract.huskSlaveSwap = function() { App.UI.DOM.appendNewElement("p", node, `You strap ${target.slaveName}, and the body to which ${he} will be transferred, into the remote surgery and stand back as it goes to work.`); bodySwap(target, asSlave(V.activeSlave), false); - const gps = isInGenePool(V.activeSlave) ? getGenePoolRecord(V.activeSlave, false, true) : undefined; + const gps = isInGenePool(V.activeSlave) ? getGenePoolRecordWriteMode(V.activeSlave) : undefined; // special exception to swap genePool since the temporary body lacks an entry. Otherwise we could just call bodySwap using the genePool entries gps.race = target.race; gps.origRace = target.origRace; @@ -33,7 +33,7 @@ App.UI.SlaveInteract.huskSlaveSwap = function() { let r = []; r.push(`${target.slaveName}'s old body was bought by the Flesh Heap for ${cashFormat(payout)}.`); if (target.bodySwap > 0) { - const origBodyOwner = V.slaves.find(s => s.origBodyOwnerID === target.ID); + const origBodyOwner = getSlaves().find(s => s.origBodyOwnerID === target.ID); if (origBodyOwner) { origBodyOwner.origBodyOwnerID = 0; const { diff --git a/src/npc/surgery/bodySwap/slaveSlaveSwap.js b/src/npc/surgery/bodySwap/slaveSlaveSwap.js index 22d6a135bd4ba5c4577908d687232e80ee7b09bb..306d20a7c1081ed03c73fb1a01ab92abfac761b2 100644 --- a/src/npc/surgery/bodySwap/slaveSlaveSwap.js +++ b/src/npc/surgery/bodySwap/slaveSlaveSwap.js @@ -7,11 +7,11 @@ App.UI.SlaveInteract.slaveSlaveSwap = function() { const ss2 = getSlave(V.swappingSlave); const ss2Clone = clone(ss2); - const gps1 = /** @type {FC.SlaveState} */ (getGenePoolRecord(ss1)); + const gps1 = /** @type {FC.SlaveState} */ (getGenePoolRecordWriteMode(ss1)); App.Utils.assignMissingDefaults(gps1, clone(ss1)); const gps1Clone = clone(gps1); - const gps2 = /** @type {FC.SlaveState} */ (getGenePoolRecord(ss2)); + const gps2 = /** @type {FC.SlaveState} */ (getGenePoolRecordWriteMode(ss2)); App.Utils.assignMissingDefaults(gps2, clone(ss2)); const gps2Clone = clone(gps2); @@ -72,7 +72,7 @@ App.UI.SlaveInteract.slaveSlaveSwap = function() { // if my new body originally belonged to someone else, update the original owner's reference to point to me // note that the original owner may also be me; we'll take care of that later (after generating the reaction) // but we never want to find a self-reference, since those are always temporary - const originalOwner = V.slaves.find(s => s.origBodyOwnerID === opposingClone.ID && s.origBodyOwnerID !== s.ID); + const originalOwner = getSlaves().find(s => s.origBodyOwnerID === opposingClone.ID && s.origBodyOwnerID !== s.ID); if (originalOwner) { originalOwner.origBodyOwnerID = target.ID; } diff --git a/src/npc/surgery/cloningWorkaround.js b/src/npc/surgery/cloningWorkaround.js index 907c283cd094aafcd79e351d3b6d3e317ce85d37..9a3f22b49246a0e98539be6239a530d1d6c04d55 100644 --- a/src/npc/surgery/cloningWorkaround.js +++ b/src/npc/surgery/cloningWorkaround.js @@ -30,7 +30,7 @@ App.UI.cloningWorkaround = function() { App.UI.reload(); } )); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { const div = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave))); if (donatrix === slave.ID) { div.classList.add("note"); @@ -47,7 +47,7 @@ App.UI.cloningWorkaround = function() { App.UI.DOM.appendNewElement("h2", node, `Surrogate`); App.UI.DOM.appendNewElement("div", node, `Chosen surrogate: ${receive}`); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (canBeReceptrix(slave)) { const div = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave))); if (receptrix === slave.ID) { diff --git a/src/npc/surgery/surrogacyWorkaround.js b/src/npc/surgery/surrogacyWorkaround.js index 5fe8635f4c7409bdb5e0f94e2332bdc83c63fc67..a3aa41053f16fc2eb702a16c7111a7ea8314dbe5 100644 --- a/src/npc/surgery/surrogacyWorkaround.js +++ b/src/npc/surgery/surrogacyWorkaround.js @@ -50,7 +50,7 @@ App.UI.surrogacyWorkaround = function() { App.UI.DOM.appendNewElement("h2", node, `Semen donatrix: ${impreg}`); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (slave.balls > 0 && slave.pubertyXY === 1 && isSlaveAvailable(slave) && canBreed(getHuman(donatrix), slave)) { const div = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave))); div.append(" ", App.UI.DOM.link( @@ -67,7 +67,7 @@ App.UI.surrogacyWorkaround = function() { App.UI.DOM.appendNewElement("div", node, "You have no slaves with potent sperm."); } - if (V.incubator.tanks.length > 0 && V.incubator.upgrade.reproduction === 1) { + if (V.incubator.tanks.length > 0 && App.Entity.facilities.incubator.upgrade('reproduction') === 1) { for (const tank of V.incubator.tanks) { if (tank.balls > 0 && tank.dick > 0 && tank.incubatorSettings.reproduction === 2 && canBreed(getSlave(donatrix), tank)) { if (eligibilityI === 0) { @@ -109,7 +109,7 @@ App.UI.surrogacyWorkaround = function() { App.UI.DOM.appendNewElement("h2", node, `Chosen surrogate: ${receive}`); - for (const slave of V.slaves) { + for (const slave of getSlaves()) { if (canBeReceptrix(slave)) { const div = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave))); div.append(" ", App.UI.DOM.link( diff --git a/src/personalAssistant/assistantAppearance.js b/src/personalAssistant/assistantAppearance.js index b7fa3065b70269a86457a60bdce6eee9ef1c7429..65d2bd27f3c88a6151b5043c7c755b9174c1aae3 100644 --- a/src/personalAssistant/assistantAppearance.js +++ b/src/personalAssistant/assistantAppearance.js @@ -34,7 +34,7 @@ globalThis.PersonalAssistantAppearance = function() { const { hisU, himU, himselfU, girlU } = getNonlocalPronouns(V.seeDicks).appendSuffix('U'); - const masturbationAllowed = V.slaves.some((s) => s.rules.release.masturbation === 1) ? 1 : 0; + const masturbationAllowed = getSlaves().some((s) => s.rules.release.masturbation === 1) ? 1 : 0; const paSeed = random(1, 8); const r = []; switch (V.assistant.appearance) { diff --git a/src/player/electiveSurgery.js b/src/player/electiveSurgery.js index c5c3da8d7aba32284d1457c13f88dd1a5b4d5964..731891d40dbfef53e05866b4f189467c2229a84f 100644 --- a/src/player/electiveSurgery.js +++ b/src/player/electiveSurgery.js @@ -3087,7 +3087,7 @@ App.UI.electiveSurgery = function() { ], "div"); } else { App.Events.addNode(el, [ - `"Some people really like anal play and end up over doing it, but we can easily tighten up back up for span class="cash">${cashFormat(applyDiscount(4000))},</span> yep yep! And even better, we can touch up an unsightly oversized anus for a mere <span class="cash">${cashFormat(applyDiscount(700))}!</span> Just no surprises up there, please."` + `"Some people really like anal play and end up over doing it, but we can easily tighten up back up for <span class="cash">${cashFormat(applyDiscount(4000))},</span> yep yep! And even better, we can touch up an unsightly oversized anus for a mere <span class="cash">${cashFormat(applyDiscount(700))}!</span> Just no surprises up there, please."` ], "div"); } if (V.PC.anus <= 1) { diff --git a/src/player/managePersonalAffairs.js b/src/player/managePersonalAffairs.js index 7abb1feb747ceb83b13877899a360f56b7b3bf36..46c2e1369ea2bdf3bea2a88c381216ea11679cc2 100644 --- a/src/player/managePersonalAffairs.js +++ b/src/player/managePersonalAffairs.js @@ -348,7 +348,7 @@ App.UI.managePersonalAffairs = function() { function family() { App.UI.DOM.appendNewElement("h3", familyDiv, `Family`); - familyDiv.append(App.UI.DOM.linkReplace(`Pull up the file on your family tree`, renderFamilyTree(V.slaves, -1))); + familyDiv.append(App.UI.DOM.linkReplace(`Pull up the file on your family tree`, renderFamilyTree(getSlaves(), -1))); if (totalPlayerRelatives(PC) > 0 || (V.showMissingSlaves && (PC.mother in V.missingTable || PC.father in V.missingTable))) { familyDiv.append(App.Desc.family(PC, true)); diff --git a/src/pregmod/blackMarket.js b/src/pregmod/blackMarket.js index bc362df4b50c90c1daeedfda62a02852adfee1a5..b142ec3b530709875143c5f74bf45bf5fba089dc 100644 --- a/src/pregmod/blackMarket.js +++ b/src/pregmod/blackMarket.js @@ -563,7 +563,7 @@ App.UI.blackMarket = function() { V.merchantIllegalWares.deleteAll("BlackmarketPregAdaptation"); } } else if (V.incubator.capacity > 0) { - if (V.incubator.upgrade.pregAdaptation === 0 && V.minimumSlaveAge > 6) { + if (App.Entity.facilities.incubator.upgrade('pregAdaptation') === 0 && V.minimumSlaveAge > 6) { r.push(`You have no interest in such a distasteful offer.`); V.merchantIllegalWares.deleteAll("BlackmarketPregAdaptation"); } else { diff --git a/src/pregmod/editGenetics.js b/src/pregmod/editGenetics.js index 9c56ebbd6029f67ce14adc382c28f1d5eea64bec..2751d1f08568322f449cfbcecaf8a6a64dd563cc 100644 --- a/src/pregmod/editGenetics.js +++ b/src/pregmod/editGenetics.js @@ -646,7 +646,7 @@ App.UI.editGenetics = function() { /* The PC */ return birthFullName(V.PC) + ' (PC)'; } else { - let parent = getGenePoolRecord(id); + const parent = getGenePoolRecordWriteMode(id); return parent ? birthFullName(parent) : App.Events.makeNode([ @@ -715,8 +715,7 @@ App.UI.editGenetics = function() { el.on('click', function() { jQuery('button.selectedslave').removeClass('selectedslave'); el.addClass('selectedslave'); - // @ts-ignore you shouldn't access V.genePool directly because it isn't supposed to change; this is an exception; For normal use use getGenePoolRecord() - let slave = getGenePoolRecord(id); + let slave = getGenePoolRecordWriteMode(id); geneDetails.html(geneDetailsFunction(slave)); let numberEditorOpen = function() { diff --git a/submodules/sugarcube-2 b/submodules/sugarcube-2 index f37f2e6ae4597347dc0b80c9741c77399348bc28..db7d147ee3f38cf127013cf9719e07cdbe709782 160000 --- a/submodules/sugarcube-2 +++ b/submodules/sugarcube-2 @@ -1 +1 @@ -Subproject commit f37f2e6ae4597347dc0b80c9741c77399348bc28 +Subproject commit db7d147ee3f38cf127013cf9719e07cdbe709782