123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060 |
- <!DOCTYPE html>
- <!--[if lte IE 8]><html class="lt-ie9"><![endif]-->
- <!--[if gt IE 8]><!--><html><!--<![endif]-->
- <head>
- <meta charset="utf-8">
- <title>Sugarcane</title>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <!--
- Made in Twee 1.4.3
- Built on 07 Dec 2014 at 19:46:43, -0500
- Sugarcane is based on:
- TiddlyWiki 1.2.39 by Jeremy Ruston, (jeremy [at] osmosoft [dot] com)
- Published under a BSD open source license
- Copyright (c) Osmosoft Limited 2005
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this
- list of conditions and the following disclaimer in the documentation and/or other
- materials provided with the distribution.
- Neither the name of the Osmosoft Limited nor the names of its contributors may be
- used to endorse or promote products derived from this software without specific
- prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGE.
- -->
- <script title="engine">
- (function(){
- /*
- **
- ** Basic utility functions
- **
- */
- function clone(a) {
- var constructor, b, proto;
- // Primitive types and functions are flat-out passed by value.
- if (!a || typeof a != "object") {
- return a;
- }
- constructor = a.constructor;
- if (constructor == Date || constructor == RegExp) {
- b = new constructor(a);
- }
- else if (constructor == Array) {
- b = [];
- }
- else if (a.nodeType && typeof a.cloneNode == "function") {
- b = a.cloneNode(true);
- }
- else {
- proto = (typeof Object.getPrototypeOf == "function" ? Object.getPrototypeOf(a) : a.__proto__);
- b = proto ? Object.create(proto) : {};
- }
- // This should work on both arrays and objects equally -
- // even copying expando properties foolishly added to arrays.
- for (var property in a) {
- if (Object.prototype.hasOwnProperty.call(a,property) && !isCyclic(a[property])) {
- if (typeof a[property] == "object") {
- try {
- b[property] = clone(a[property]);
- continue;
- }
- catch(e) {}
- }
- b[property] = a[property];
- }
- }
- return b;
- }
- function isCyclic(obj) {
- var properties = [];
- return (function recurse(obj) {
- var key, i, ownProps = [];
- if (obj && typeof obj == "object") {
- if (properties.indexOf(obj) > -1) {
- return true;
- }
- properties.push(obj);
- for (key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj,key) && recurse(obj[key])) {
- return true;
- }
- }
- }
- return false;
- }(obj));
- }
- function insertElement(a, d, f, c, e) {
- var b = document.createElement(d);
- if (f) {
- b.id = f
- }
- if (c) {
- b.className = c
- }
- if (e) {
- insertText(b, e)
- }
- if (a) {
- a.appendChild(b)
- }
- return b
- }
- function addClickHandler(el, fn) {
- if (el.addEventListener) {
- el.addEventListener('click', fn);
- } else if (el.attachEvent) {
- el.attachEvent('onclick', fn);
- }
- }
- function insertText(a, b) {
- return a.appendChild(document.createTextNode(b))
- }
- function removeChildren(a) {
- while (a.hasChildNodes()) {
- a.removeChild(a.firstChild)
- }
- }
- function findPassageParent(el) {
- while(el && el != document.body && !~el.className.indexOf("passage")) {
- el = el.parentNode;
- }
- return el == document.body ? null : el;
- }
- function setPageElement(c, b, a) {
- var place;
- if (place = (typeof c == "string" ? document.getElementById(c) : c)) {
- removeChildren(place);
- if (tale.has(b)) {
- new Wikifier(place, tale.get(b).processText())
- } else {
- new Wikifier(place, a)
- }
- }
- }
- var scrollWindowInterval;
- function scrollWindowTo(e, margin) {
- var d = window.scrollY ? window.scrollY : document.documentElement.scrollTop,
- m = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight,
- g = k(e),
- j = (d > g) ? -1 : 1,
- b = 0,
- c = Math.abs(d - g);
- scrollWindowInterval && window.clearInterval(scrollWindowInterval);
- if (c) {
- scrollWindowInterval = window.setInterval(h, 25);
- }
-
- function h() {
- b += 0.1;
- window.scrollTo(0, d + j * (c * Math.easeInOut(b)));
- if (b >= 1) {
- window.clearInterval(scrollWindowInterval)
- }
- }
- function k(o) {
- var p = a(o),
- h = o.offsetHeight,
- n = d + m;
- p = Math.min(Math.max(p + (margin || 0) * ( p < d ? -1 : 1), 0), n);
- if (p < d) {
- return p
- } else {
- if (p+h > n) {
- if (h < m) {
- return (p - (m - h) + 20)
- } else {
- return p
- }
- } else {
- return p
- }
- }
- }
- function a(l) {
- var m = 0;
- while (l.offsetParent) {
- m += l.offsetTop;
- l = l.offsetParent
- }
- return m
- }
- }
- // Returns an object containing the properties in neu which differ from old.
- function delta(old,neu) {
- var vars, ret = {};
- if (old && neu) {
- for (vars in neu) {
- if (neu[vars] !== old[vars]) {
- ret[vars] = neu[vars];
- }
- }
- }
- return ret;
- }
- // Convert various exotic objects into JSON-serialisable plain objects.
- function decompile(val) {
- var i, ret;
- if ((typeof val != "object" && typeof val != "function") || !val) {
- return val;
- }
- // Passage objects: store only their name
- else if (val instanceof Passage) {
- return { "[[Passage]]" : val.id };
- }
- else if (Array.isArray(val)) {
- ret = [];
- }
- else {
- ret = {};
- }
- // Deep-copy own properties
- for (i in val) {
- if (Object.prototype.hasOwnProperty.call(val,i) && !isCyclic(val[i])) {
- ret[i] = decompile(val[i]);
- }
- }
- // Functions: store the decompiled function body as a property
- // arbitrarily called "[[Call]]".
- if (typeof val == "function" || val instanceof RegExp) {
- try {
- // Check if it can be recompiled (i.e. isn't a bound or native)
- internalEval(val+"");
- ret["[[Call]]"] = val+"";
- } catch(e) {
- // Silently fail
- ret["[[Call]]"] = "function(){}"
- }
- }
- return ret;
- }
- // Reverses the effects of decompile()
- // Takes recently JSON.parse()d objects and makes them exotic again.
- function recompile(val) {
- var i, ret = val;
- if (val && typeof val == "object") {
- // Passages
- if (typeof val["[[Passage]]"] == "number") {
- return tale.get(val["[[Passage]]"]);
- }
- // Functions/RegExps
- if (typeof val["[[Call]]"] == "string") {
- try {
- ret = internalEval(val["[[Call]]"]);
- }
- catch(e){}
- }
- // Recursively recompile all properties
- // or, if a function/regexp, deep-copy them to the new function.
- for (i in val) {
- if (Object.prototype.hasOwnProperty.call(val,i)) {
- ret[i] = recompile(val[i]);
- }
- }
- }
- return ret;
- }
- function addStyle(b) {
- if (document.createStyleSheet) {
- document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd", " <style>" + b + "</style>")
- } else {
- var a = document.createElement("style");
- a.appendChild(document.createTextNode(b));
- document.getElementsByTagName("head")[0].appendChild(a)
- }
- }
- function alterCSS(text) {
- var temp = '', imgPassages = tale.lookup("tags", "Twine.image");
- // Remove comments
- text = text.replace(/\/\*(?:[^\*]|\*(?!\/))*\*\//g,'');
- // Replace :link
- text = text.replace(/:link/g,"[class*=Link]");
- // Replace :visited
- text = text.replace(/:visited/g,".visitedLink");
- // Hoist @import
- text = text.replace(/@import\s+(?:url\s*\(\s*['"]?|['"])[^"'\s]+(?:['"]?\s*\)|['"])\s*([\w\s\(\)\d\:,\-]*);/g, function(e) {
- temp += e; return '';
- });
- text = temp + text;
-
- // Add images
- return text.replace(new RegExp(Wikifier.imageFormatter.lookahead, "gim"), function(m,p1,p2,p3,src) {
- for (var i = 0; i < imgPassages.length; i++) {
- if (imgPassages[i].title == src) {
- src = imgPassages[i].text;
- break;
- }
- }
- return "url(" + src + ")"
- });
- }
- function setTransitionCSS(styleText) {
- styleText = alterCSS(styleText);
- var style = document.getElementById("transitionCSS");
- style.styleSheet ? (style.styleSheet.cssText = styleText) : (style.innerHTML = styleText);
- }
- function throwError(a, b, tooltip) {
- if (a) {
- var elem = insertElement(a, "span", null, "marked", b);
- tooltip && elem.setAttribute("title", tooltip);
- } else {
- alert("Regrettably, this " + tale.identity() + "'s code just ran into a problem:\n" + b + ".\n"+softErrorMessage);
- }
- }
- Math.easeInOut = function (a) {
- return (1 - ((Math.cos(a * Math.PI) + 1) / 2))
- };
- String.prototype.readMacroParams = function (keepquotes) {
- var exec, re = /(?:\s*)(?:(?:"([^"]*)")|(?:'([^']*)')|(?:\[\[((?:[^\]]|\](?!\]))*)\]\])|([^"'\s]\S*))/mg,
- params = [];
- do {
- var val;
- exec = re.exec(this);
- if (exec) {
- if (exec[1]) {
- val = exec[1];
- keepquotes && (val = '"' + val + '"');
- } else if (exec[2]) {
- val = exec[2];
- keepquotes && (val = "'" + val + "'");
- } else if (exec[3]) {
- val = exec[3];
- keepquotes && (val = '"' + val.replace('"','\\"') + '"');
- } else if (exec[4]) {
- val = exec[4];
- }
- val && params.push(val);
- }
- } while (exec);
- return params
- };
- String.prototype.readBracketedList = function () {
- var c, b = "\\[\\[([^\\]]+)\\]\\]",
- a = "[^\\s$]+",
- e = "(?:" + b + ")|(" + a + ")",
- d = new RegExp(e, "mg"),
- f = [];
- do {
- c = d.exec(this);
- if (c) {
- if (c[1]) {
- f.push(c[1])
- } else {
- if (c[2]) {
- f.push(c[2])
- }
- }
- }
- } while (c);
- return (f)
- };
- function rot13(s) {
- return s.replace(/[a-zA-Z]/g, function(c) {
- return String.fromCharCode((c<="Z" ? 90 : 122) >= (c=c.charCodeAt()+13) ? c : c-26);
- });
- }
- /*
- **
- ** Polyfills
- **
- */
- Object.create || (function() {
- var F = function(){};
- Object.create = function (o) {
- if (typeof o != 'object') throw TypeError();
- F.prototype = o;
- return new F();
- };
- })();
- String.prototype.trim || (String.prototype.trim = function () {
- return this.replace(/^\s\s*/, "").replace(/\s\s*$/, "")
- });
- Array.isArray || (Array.isArray = function(arg) {
- return Object.prototype.toString.call(arg) === '[object Array]';
- });
- Array.prototype.indexOf || (Array.prototype.indexOf = function (b, d) {
- d = (d == null) ? 0 : d;
- var a = this.length;
- for (var c = d; c < a; c++) {
- if (this[c] == b) {
- return c
- }
- }
- return -1
- });
- Array.prototype.forEach || (Array.prototype.forEach=function(fun){if(this==null){throw TypeError()}var t=Object(this);var len=+t.length;if(typeof fun!="function"){throw TypeError()}var thisArg=arguments.length>=2?arguments[1]:void 0;for(var i=0;i<len;i++){if(i in t){fun.call(thisArg,t[i],i,t)}}});
- /* btoa/atob polyfill by github.com/davidchambers */
- (function(){function t(t){this.message=t}var e=window,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t();o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t();for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
- /* Polyfill for fade transition */
- var hasTransition = 'transition' in document.documentElement.style || '-webkit-transition' in document.documentElement.style;
- function fade(f, c) {
- var h;
- var e = f.cloneNode(true);
- var g = (c.fade == "in") ? 1 : -1;
- f.parentNode.replaceChild(e, f);
- if (c.fade == "in") {
- h = 0;
- e.style.visibility = "visible"
- } else {
- h = 1
- }
- b(e, h);
- var a = window.setInterval(d, 25);
- function d() {
- h += 0.05 * g;
- b(e, Math.easeInOut(h));
- if (((g == 1) && (h >= 1)) || ((g == -1) && (h <= 0))) {
- f.style.visibility = (c.fade == "in") ? "visible" : "hidden";
- if (e.parentNode) {
- e.parentNode.replaceChild(f, e);
- }
- window.clearInterval(a);
- if (c.onComplete) {
- c.onComplete.call(f)
- }
- }
- }
- function b(k, j) {
- var l = Math.floor(j * 100);
- k.style.zoom = 1;
- k.style.filter = "alpha(opacity=" + l + ")";
- k.style.opacity = j
- }
- }
- /*
- **
- ** History object
- **
- */
- function History() {
- this.history = [{
- passage: null,
- variables: {}
- }]
- // Unique identifier for this game session
- this.id = new Date().getTime()+'';
- // URL of the bookmark link
- this.hash = '';
- }
- History.prototype.encodeHistory = function(b, noVars) {
- var ret = ".", vars, type, hist = this.history[b],
- d = this.history[b+1] ? delta(this.history[b+1].variables, hist.variables) : hist.variables;
-
- function vtob(val) {
- try {
- return window.btoa(unescape(encodeURIComponent(JSON.stringify(decompile(val)))));
- } catch(e) {
- return "0";
- }
- }
-
- if (!hist.passage || hist.passage.id == null) {
- return ""
- }
- ret += hist.passage.id.toString(36);
- if (noVars) {
- return ret;
- }
- for (vars in d) {
- type = typeof d[vars];
- if (type != "undefined") {
- ret += "$" + vtob(vars) + "," + vtob(d[vars]);
- }
- }
- for (vars in hist.linkVars) {
- type = typeof hist.linkVars[vars];
- if (type != "function" && type != "undefined") {
- ret += "[" + vtob(vars) + "," + vtob(hist.linkVars[vars]);
- }
- }
- return ret
- };
- History.decodeHistory = function(str, prev) {
- var name, splits, variable, c, d,
- ret = { variables: clone(prev.variables) || {} },
- match = /([a-z0-9]+)((?:\$[A-Za-z0-9\+\/=]+,[A-Za-z0-9\+\/=]+)*)((?:\[[A-Za-z0-9\+\/=]+,[A-Za-z0-9\+\/=]+)*)/g.exec(str);
-
- function btov(str) {
- try {
- return recompile(JSON.parse(decodeURIComponent(escape(window.atob(str)))));
- } catch(e) {
- return 0;
- }
- }
- if (match) {
- name = parseInt(match[1], 36);
- if (!tale.has(name)) {
- return false
- }
- if (match[2]) {
- ret.variables || (ret.variables = {});
- splits = match[2].split('$');
- for (c = 0; c < splits.length; c++) {
- variable = splits[c].split(",");
- d = btov(variable[0]);
- if (d) {
- ret.variables[d]=btov(variable[1]);
- }
- }
- }
- if (match[3]) {
- ret.linkVars || (ret.linkVars = {});
- splits = match[3].split('[');
- for (c = 0; c < splits.length; c++) {
- variable = splits[c].split(",");
- d = btov(variable[0]);
- if (d) {
- ret.linkVars[d]=btov(variable[1]);
- }
- }
- }
- ret.passage = tale.get(name);
- return ret;
- }
- };
- History.prototype.save = function() {
- var hist, b, a = "";
- for (b = this.history.length - 1; b >= 0; b--) {
- hist = this.history[b];
- if (!hist) {
- break;
- }
- a += this.encodeHistory(b);
- }
- return "#" + a
- };
- History.prototype.restore = function () {
- var a, b, c, vars;
- try {
- if (!window.location.hash || (window.location.hash == "#")) {
- if (testplay) {
- if (tale.has("StoryInit")) {
- new Wikifier(insertElement(null, "span"), tale.get("StoryInit").text);
- }
- this.display(testplay, null, 'quietly');
- return true
- }
- return false
- }
- if (window.location.hash.substr(0, 2) == '#!') {
- c = window.location.hash.substr(2).split('_').join(' ');
- this.display(c, null, 'quietly');
- return true
- }
- a = window.location.hash.replace("#", "").split(".");
- for (b = 0; b < a.length; b++) {
- vars = History.decodeHistory(a[b], vars || {});
- if (vars) {
- if (b == a.length - 1) {
- vars.variables = clone(this.history[0].variables);
- for (c in this.history[0].linkVars) {
- vars.variables[c] = clone(this.history[0].linkVars[c]);
- }
- this.history.unshift(vars);
- this.display(vars.passage.title, null, "back");
- }
- else {
- this.history.unshift(vars);
- }
- }
- }
- return true
- } catch (d) {
- return false
- }
- };
- History.prototype.saveVariables = function(c, el, callback) {
- if (typeof callback == "function") {
- callback.call(el);
- }
- this.history.unshift({
- passage: c,
- variables: clone(this.history[0].variables)
- });
- };
- var restart = History.prototype.restart = function () {
- if (typeof window.history.replaceState == "function") {
- (typeof this.pushState == "function") && this.pushState(true, window.location.href.replace(/#.*$/,''));
- window.location.reload()
- }
- else {
- window.location.hash = "";
- }
- };
- /*
- **
- ** Macros
- **
- */
- var version = {
- major: 4,
- minor: 3,
- revision: 0,
- date: new Date("2014"),
- extensions: {}
- };
- var testplay, tale, state, prerender = {}, postrender = {}, macros = window.macros = {};
- version.extensions.displayMacro = {
- major: 2,
- minor: 0,
- revision: 0
- };
- macros.display = {
- // Used by parameter() and parameterValue()
- parameters: [],
- handler: function (place, macroName, params, parser) {
- var t, j, output, oldDisplayParams, name = parser.fullArgs();
-
- if (macroName != "display") {
- output = macroName;
- // Shorthand displays can have parameters
- params = parser.fullMatch().replace(/^\S*|>>$/g,'').readMacroParams(true);
- // The above line recreates params, with the quotes.
- try {
- for(j=0; j < params.length; j++) {
- params[j] = internalEval(Wikifier.parse(params[j]));
- }
- } catch (e) {
- throwError(place, parser.fullMatch() + " bad argument: " + params[j], parser.fullMatch());
- return
- }
- }
- else {
- try {
- output = internalEval(name);
- }
- catch(e) {
- }
- if (output == null) {
- // Last-ditch attempt
- if (tale.has(name)) {
- output = name;
- }
- }
- }
- if (!output) {
- throwError(place, '<<' + macroName + '>>: "' +name + "\" did not evaluate to a passage name", parser.fullMatch());
- } else if (!tale.has(output+"")) {
- throwError(place, '<<' + macroName + ">>: The \"" + output + "\" passage does not exist", parser.fullMatch());
- } else {
- oldDisplayParams = this.parameters;
- this.parameters = params;
- t = tale.get(output+"");
- if (t.tags.indexOf("script") > -1) {
- scriptEval(t);
- }
- else {
- new Wikifier(place, t.processText());
- }
- this.parameters = oldDisplayParams;
- }
- }
- };
- version.extensions.actionsMacro = {
- major: 1,
- minor: 2,
- revision: 0
- };
- macros.actions = {
- handler: function (a, f, g) {
- var v = state.history[0].variables, e = insertElement(a, "ul");
- if (!v["actions clicked"]) {
- v["actions clicked"] = {}
- }
- for (var b = 0; b < g.length; b++) {
- if (v["actions clicked"][g[b]]) {
- continue
- }
- var d = insertElement(e, "li");
- var c = Wikifier.createInternalLink(d, g[b], (function(link) {
- return function() { state.history[0].variables["actions clicked"][link] = true; }
- }(g[b])));
- insertText(c, g[b]);
- }
- }
- };
- version.extensions.printMacro = {
- major: 1,
- minor: 1,
- revision: 1
- };
- macros.print = {
- handler: function (place, macroName, params, parser) {
- var args = parser.fullArgs(macroName != "print"), output;
- try {
- // See comment within macros.display
- output = internalEval(args);
- if (output != null && (typeof output != "number" || !isNaN(output))) {
- new Wikifier(place, ''+output);
- }
- } catch (e) {
- throwError(place, "<<print>> bad expression: " + params.join(' '), parser.fullMatch());
- }
- }
- };
- version.extensions.setMacro = {
- major: 1,
- minor: 1,
- revision: 0
- };
- macros.set = {
- handler: function (a, b, c, parser) {
- macros.set.run(a, parser.fullArgs(), parser, c.join(' '))
- },
- run: function (a,expression, parser, original) {
- try {
- return internalEval(expression);
- } catch (e) {
- throwError(a, "bad expression: " + (original || expression), parser ? parser.fullMatch() : expression)
- }
- }
- };
- version.extensions.ifMacros = {
- major: 2,
- minor: 0,
- revision: 0
- };
- macros["if"] = {
- handler: function (place, macroName, params, parser) {
- var conditions = [],
- clauses = [],
- rawConds = [],
- srcOffset = parser.source.indexOf(">>", parser.matchStart) + 2,
- src = parser.source.slice(srcOffset),
- endPos = -1,
- rawCond = params.join(' '),
- currentCond = parser.fullArgs(),
- currentClause = "",
- t = 0,
- nesting = 0,
- i = 0;
-
- for (; i < src.length; i++) {
- if ((src.substr(i, 6) == "<<else") && !nesting) {
- rawConds.push(rawCond);
- conditions.push(currentCond.trim());
- clauses.push(currentClause);
- currentClause="";
- t = src.indexOf(">>",i+6);
- if(src.substr(i+6,4)==" if " || src.substr(i+6,3)=="if ") {
- rawCond = src.slice(i+9,t);
- currentCond = Wikifier.parse(rawCond);
- }
- else {
- rawCond = "";
- currentCond = "true";
- }
- i = t+2;
- }
- if (src.substr(i, 5) == "<<if ") {
- nesting++;
- }
- if (src.substr(i, 9) == "<<endif>>") {
- nesting--;
- if (nesting < 0) {
- endPos = srcOffset + i + 9;
- rawConds.push(rawCond);
- conditions.push(currentCond.trim());
- clauses.push(currentClause);
- break;
- }
- }
- currentClause += src.charAt(i);
- }
- if (endPos != -1) {
- parser.nextMatch = endPos;
- try {
- for(i=0;i<clauses.length;i++) {
- if (internalEval(conditions[i])) {
- new Wikifier(place, clauses[i]);
- break;
- }
- }
- } catch (e) {
- throwError(place, "<<" + (i ? "else " : "") + "if>> bad condition: " + rawConds[i], !i ? parser.fullMatch()
- : "<<else if " + rawConds[i] + ">>");
- }
- } else {
- throwError(place, "I can't find a matching <<endif>>", parser.fullMatch());
- }
- }
- };
- macros["else"] = macros.elseif = macros.endif = {
- handler: function () {}
- };
- version.extensions.rememberMacro = {
- major: 2,
- minor: 0,
- revision: 0
- };
- macros.remember = {
- handler: function (place, macroName, params, parser) {
- var variable, value, re, match,
- statement = params.join(" ");
- macros.set.run(place, parser.fullArgs(), null, params.join(' '));
- if (!window.localStorage) {
- throwError(place, "<<remember>> can't be used "
- + (window.location.protocol == "file:" ? " by local HTML files " : "") + " in this browser.",parser.fullMatch());
- return;
- }
- re = new RegExp(Wikifier.textPrimitives.variable, "g");
- while (match = re.exec(statement)) {
- variable = match[1];
- value = state.history[0].variables[variable];
- try {
- value = JSON.stringify(value);
- } catch (e) {
- throwError(place, "can't <<remember>> the variable $" + variable + " (" + (typeof value) + ")", parser.fullMatch());
- return;
- }
- window.localStorage[this.prefix + variable] = value;
- }
- },
- init: function () {
- var i, variable, value;
- this.prefix = "Twine." + tale.defaultTitle + ".";
- for (i in window.localStorage) {
- if (i.indexOf(this.prefix) == 0) {
- variable = i.substr(this.prefix.length);
- value = window.localStorage[i];
- try {
- value = JSON.parse(value);
- state.history[0].variables[variable]=value;
- } catch (e) {
- }
- }
- }
- },
- expire: null,
- prefix: null
- };
- version.extensions.forgetMacro = {
- major: 1,
- minor: 0,
- revision: 0
- };
- macros.forget = {
- handler: function (place, macroName, params) {
- var re, match, variable,
- statement = params.join(" ");
- re = new RegExp(Wikifier.textPrimitives.variable, "g");
- while (match = re.exec(statement)) {
- variable = match[1] + ""
- delete state.history[0].variables[variable];
- delete window.localStorage[macros.remember.prefix + variable];
- }
- }
- };
-
- version.extensions.SilentlyMacro = {
- major: 1,
- minor: 1,
- revision: 0
- };
- macros.nobr = macros.silently = {
- handler: function (place, macroName, f, parser) {
- var i, h = insertElement(null, 'div'),
- k = parser.source.indexOf('>>', parser.matchStart) + 2,
- a = parser.source.slice(k),
- d = -1,
- c = '',
- l = 0;
- for (i = 0; i < a.length; i++) {
- if (a.substr(i, macroName.length+7) == '<<end' + macroName + '>>') {
- if (l == 0) {
- d = k + i + macroName.length+7;
- break;
- } else {
- l--;
- }
- } else if (a.substr(i, macroName.length+4) == '<<' + macroName + '>>') {
- l++;
- }
- if (macroName == "nobr" && a.charAt(i) == '\n') {
- c += "\u200c"; // Zero-width space
- }
- else {
- c += a.charAt(i);
- }
- }
- if (d != -1) {
- new Wikifier(macroName == "nobr" ? place : h, c);
- parser.nextMatch = d;
- } else {
- throwError(place, "can't find matching <<end" + macroName+">>", parser.fullMatch());
- }
- }
- };
- macros.endsilently = {
- handler: function () {}
- };
- version.extensions.choiceMacro = {
- major: 2,
- minor: 0,
- revision: 0
- };
- macros.choice = {
- callback: function() {
- var i, other, passage = findPassageParent(this);
-
- if (passage) {
- other = passage.querySelectorAll(".choice");
- for (i = 0; i < other.length; i++) {
- other[i].outerHTML = "<span class=disabled>" + other[i].innerHTML + "</span>";
- }
- state.history[0].variables["choice clicked"][passage.id.replace(/\|[^\]]*$/,'')] = true;
- }
- },
- handler: function (A, C, D, parser) {
- var link, id, match,
- text = D[1] || D[0].split("|")[0],
- passage = findPassageParent(A);
- // Get ID of the "choice clicked" entry
- if (!passage) {
- throwError(A, "<<"+C+">> can't be used here.",parser.fullMatch());
- return;
- }
- id = (passage && passage.id.replace(/\|[^\]]*$/,''));
- if (id && (state.history[0].variables["choice clicked"] ||
- (state.history[0].variables["choice clicked"] = {}))[id]) {
- insertElement(A, "span", null, "disabled", text);
- }
- else {
- match = new RegExp(Wikifier.linkFormatter.lookahead).exec(parser.fullMatch());
-
- if (match) {
- link = Wikifier.linkFormatter.makeLink(A,match,this.callback);
- }
- else {
- link = Wikifier.linkFormatter.makeLink(A,[0,text,D[0]],this.callback);
- }
- link.className += " " + C;
- }
- }
- };
- version.extensions.backMacro = {
- major: 2,
- minor: 0,
- revision: 0
- };
- macros.back = {
- labeltext: '« back',
- handler: function (a, b, e, parser) {
- var labelParam, c, el,
- labeltouse = this.labeltext,
- steps = 1,
- stepsParam = e.indexOf("steps"),
- stepsParam2 = "";
- // Steps parameter
- if(stepsParam > 0) {
- stepsParam2 = e[stepsParam - 1];
- if(stepsParam2[0] == '$') {
- try {
- stepsParam2 = internalEval(Wikifier.parse(stepsParam2));
- }
- catch(r) {
- throwError(a, parser.fullMatch() + " bad expression: " + r.message, parser.fullMatch())
- return;
- }
- }
- // Previously, trying to go back more steps than were present in the
- // history would silently revert to just 1 step.
- // Instead, let's just go back to the start.
- steps = +stepsParam2;
- if(steps >= state.history.length - 1) {
- steps = state.history.length - 2;
- }
- e.splice(stepsParam - 1, 2);
- }
- // Label parameter
- labelParam = e.indexOf("label");
- if(labelParam > -1) {
- if(!e[labelParam + 1]) {
- throwError(a, parser.fullMatch() + ": " + e[labelParam] + ' keyword needs an additional label parameter', parser.fullMatch());
- return;
- }
- labeltouse = e[labelParam + 1];
- e.splice(labelParam, 2);
- }
- // What's left is the passage name parameter
- if(stepsParam <= 0) {
- if(e[0]) {
- if(e[0].charAt(0) == '$') {
- try {
- e = internalEval(Wikifier.parse(e[0]));
- }
- catch(r) {
- throwError(a, parser.fullMatch() + " bad expression: " + r.message, parser.fullMatch())
- return;
- }
- }
- else {
- e = e[0];
- }
- if(!tale.has(e)) {
- throwError(a, "The \"" + e + "\" passage does not exist",parser.fullMatch());
- return;
- }
- for(c = 0; c < state.history.length; c++) {
- if(state.history[c].passage.title == e) {
- steps = c;
- break;
- }
- }
- }
- }
- el = document.createElement("a");
- el.className = b;
- addClickHandler(el, (function(b) { return function () {
- return macros.back.onclick(b == "back", steps, el)
- }}(b)));
- el.innerHTML = labeltouse;
- a.appendChild(el);
- }
- };
- version.extensions.returnMacro = {
- major: 2,
- minor: 0,
- revision: 0
- };
- macros["return"] = {
- labeltext: '« return',
- handler: function(a,b,e) {
- macros.back.handler.call(this,a,b,e);
- }
- };
- version.extensions.textInputMacro = {
- major: 2,
- minor: 0,
- revision: 0
- };
- macros.checkbox = macros.radio = macros.textinput = {
- handler: function (A, C, D, parser) {
- var match,
- class_ = C.replace('input','Input'),
- q = A.querySelectorAll('input'),
- id = class_ + "|" + ((q && q.length) || 0);
- input = insertElement(null, 'input', id, class_);
-
- input.name=D[0];
- input.type=C.replace('input','');
- // IE 8 support - delay insertion until now
- A.appendChild(input);
-
- if (C == "textinput" && D[1]) {
- match = new RegExp(Wikifier.linkFormatter.lookahead).exec(parser.fullMatch());
-
- if (match) {
- Wikifier.linkFormatter.makeLink(A,match, macros.button.callback, 'button');
- }
- else {
- Wikifier.linkFormatter.makeLink(A,[0,(D[2] || D[1]),D[1]], macros.button.callback, 'button');
- }
- }
- else if ((C == "radio" || C == "checkbox") && D[1]) {
- input.value = D[1];
- insertElement(A, 'label','', '', D[1]).setAttribute('for',id);
- if (D[2]) {
- insertElement(A,'br');
- D.splice(1,1);
- macros[C].handler(A,C,D)
- }
- }
- }
- };
- version.extensions.buttonMacro = {
- major: 1,
- minor: 0,
- revision: 0
- };
- macros.button = {
- callback: function() {
- var el = findPassageParent(this);
- if (el) {
- var inputs = el.querySelectorAll("input");
- for (i = 0; i < inputs.length; i++) {
- if (inputs[i].type!="checkbox" && (inputs[i].type!="radio" || inputs[i].checked)) {
- macros.set.run(null, Wikifier.parse(inputs[i].name+' = "'+inputs[i].value.replace(/"/g,'\\"')+'"'));
- }
- else if (inputs[i].type=="checkbox" && inputs[i].checked) {
- macros.set.run(null, Wikifier.parse(
- inputs[i].name+' = [].concat('+inputs[i].name+' || []);'));
- macros.set.run(null, Wikifier.parse(
- inputs[i].name+'.push("'+inputs[i].value.replace(/"/g,'\\"')+'")'));
- }
- }
- }
- },
- handler: function (A, C, D, parser) {
- var link,
- match = new RegExp(Wikifier.linkFormatter.lookahead).exec(parser.fullMatch());
-
- if (match) {
- Wikifier.linkFormatter.makeLink(A, match, this.callback, 'button');
- }
- else {
- Wikifier.linkFormatter.makeLink(A,[0,D[1] || D[0], D[0]], this.callback, 'button');
- }
- }
- };
- /*
- **
- ** Passage object
- **
- */
- function Passage(c, b, a, ofunc) {
- var t;
- if (!this || this.constructor != Passage) {
- throw new ReferenceError("passage() must be in lowercase");
- }
- this.title = c;
- ofunc = typeof ofunc == 'function' && ofunc;
- if (b) {
- this.id = a;
- // Load tags
- this.tags = b.getAttribute("tags");
- if (typeof this.tags == "string") {
- if (ofunc) {
- this.tags = ofunc(this.tags);
- }
- this.tags = this.tags.readBracketedList();
- } else this.tags = [];
- // Load text
- t = b.firstChild ? b.firstChild.nodeValue : "";
- if (ofunc && !this.isImage()) {
- this.text = ofunc(Passage.unescapeLineBreaks(t));
- } else {
- this.text = Passage.unescapeLineBreaks(t);
- }
- // Preload linked images
- if (!this.isImage()) {
- this.preloadImages();
- }
- // Check for the .char selector, or the [data-char] selector
- // False positives aren't a big issue.
- if (/\.char\b|\[data\-char\b/.exec(this.text) && Wikifier.charSpanFormatter) {
- Wikifier.formatters.push(Wikifier.charSpanFormatter);
- delete Wikifier.charSpanFormatter;
- }
- } else {
- this.text = '@@This passage does not exist: ' + c + '@@';
- this.tags = [];
- }
- }
- Passage.prototype.isImage = function() {
- return !!~(this.tags.indexOf("Twine.image"));
- };
- Passage.prototype.preloadImages = function() {
- // Don't preload URLs containing '$' - suspect that they are variables.
- var u = "\\s*['\"]?([^\"'$]+\\.(jpe?g|a?png|gif|bmp|webp|svg))['\"]?\\s*",
- k = function(c, e) {
- var i,d;
- do {
- d = c.exec(this.text);
- if(d) {
- i = new Image();
- i.src = d[e];
- }
- } while (d);
- return k;
- };
- k.call(this, new RegExp(Wikifier.imageFormatter.lookahead.replace("[^\\[\\]\\|]+",u), "mg"), 4)
- .call(this, new RegExp("url\\s*\\(" + u + "\\)", "mig"), 1)
- .call(this, new RegExp("src\\s*=" + u, "mig"), 1);
- };
- Passage.unescapeLineBreaks = function (a) {
- if (a && typeof a == "string") {
- return a.replace(/\\n/mg, "\n").replace(/\\t/mg, "\t").replace(/\\s/mg, "\\").replace(/\\/mg, "\\").replace(/\r/mg, "")
- } else {
- return ""
- }
- };
- Passage.prototype.setTags = function(b) {
- var t = this.tags != null && this.tags.length ? this.tags.join(' ') : "";
- if (t) {
- b.setAttribute('data-tags', this.tags.join(' '));
- }
- document.body.setAttribute("data-tags", t);
- };
- Passage.prototype.processText = function() {
- var ret = this.text;
- if (~this.tags.indexOf("nobr")) {
- ret = ret.replace(/\n/g,"\u200c");
- }
- if (this.isImage()) {
- ret = "[img[" + ret + "]]"
- }
- return ret;
- };
- /*
- **
- ** Tale object
- **
- */
- function Tale() {
- var a,b,c,lines,i,kv,nsc,isImage,
- settings = this.storysettings = {
- lookup: function(a, dfault) {
- // The two runtime settings (undo and bookmark) default to true.
- if (!(a in this)) return dfault;
- return (this[a]+"") != "off";
- }
- },
- HTMLtitle = document.querySelector('title');
- tiddlerTitle = '';
- this.defaultTitle = (HTMLtitle && (HTMLtitle.textContent || HTMLtitle.innerText)) || "Untitled Story";
- this.passages = {};
- //Look for and load the StorySettings
- if (document.normalize) document.normalize();
- a = document.getElementById("storeArea").children;
- for (b = 0; b < a.length; b++) {
- c = a[b];
- if (c.getAttribute && c.getAttribute("tiddler") == 'StorySettings') {
- lines = new Passage('StorySettings', c, 0, null, null).text.split('\n');
- for (i in lines) {
- if (typeof lines[i] == "string" && lines[i].indexOf(':') > -1) {
- kv = lines[i].toLowerCase().split(':');
- kv[0] = kv[0].replace(/^\s+|\s+$/g, '');
- kv[1] = kv[1].replace(/^\s+|\s+$/g, '');
- if (kv[0] != "lookup") {
- settings[kv[0]] = kv[1];
- }
- }
- }
- }
- }
- //Load in the passages
- if (settings.obfuscate == 'rot13') {
- for (b = 0; b < a.length; b++) {
- c = a[b];
- if (c.getAttribute && (tiddlerTitle = c.getAttribute("tiddler"))) {
- isImage = (c.getAttribute("tags")+"").indexOf("Twine.image")>-1;
- if (tiddlerTitle != 'StorySettings' && !isImage)
- tiddlerTitle = rot13(tiddlerTitle);
- this.passages[tiddlerTitle] = new Passage(tiddlerTitle, c, b+1, !isImage && rot13);
- }
- }
- } else {
- for (b = 0; b < a.length; b++) {
- c = a[b];
- if (c.getAttribute && (tiddlerTitle = c.getAttribute("tiddler"))) {
- this.passages[tiddlerTitle] = new Passage(tiddlerTitle, c, b, null, null)
- }
- }
- }
- }
- Tale.prototype.has = function (a) {
- if (typeof a == "string") {
- return (this.passages[a] != null)
- } else {
- for (var i in this.passages) {
- if (this.passages[i].id == a) {
- return true
- }
- }
- return false
- }
- };
- Tale.prototype.get = function (a) {
- if (typeof a == "string") {
- return this.passages[a] || new Passage(a)
- } else {
- for (var i in this.passages) {
- if (this.passages[i].id == a) {
- return this.passages[i]
- }
- }
- }
- };
- Tale.prototype.lookup = function (h, g, a) {
- var d = [];
- for (var c in this.passages) {
- var f = this.passages[c];
- for (var b = 0; b < f[h].length; b++) {
- if (f[h][b] == g) {
- d.push(f)
- }
- }
- }
- if (!a) {
- a = "title"
- }
- d.sort(function (k, j) {
- if (k[a] == j[a]) {
- return (0)
- } else {
- return (k[a] < j[a]) ? -1 : +1
- }
- });
- return d
- };
- Tale.prototype.canUndo = function() {
- return this.storysettings.lookup('undo',true);
- };
- Tale.prototype.identity = function () {
- var meta = document.querySelector("meta[name='identity']"),
- identity = meta ? meta.getAttribute("content") : "story";
-
- return (Tale.prototype.identity = function() {
- return identity;
- })();
- };
- Tale.prototype.forEachStylesheet = function(tags, callback) {
- var passage, i;
- tags = tags || [];
-
- if (typeof callback != "function")
- return;
- for (passage in this.passages) {
- passage = tale.passages[passage];
- if (passage && ~passage.tags.indexOf("stylesheet")) {
- for (i = 0; i < tags.length; i++) {
- if (~passage.tags.indexOf(tags[i])) {
- callback(passage);
- break;
- }
- }
- }
- }
- };
- Tale.prototype.setPageElements = function() {
- var storyTitle;
-
- setPageElement("storyTitle", "StoryTitle", this.defaultTitle);
- storyTitle = document.getElementById("storyTitle");
- document.title = this.title = (storyTitle && (storyTitle.textContent || storyTitle.innerText)) || this.defaultTitle;
-
- setPageElement("storySubtitle", "StorySubtitle", "");
- if (tale.has("StoryAuthor")) {
- setPageElement("titleSeparator", null, "\n");
- setPageElement("storyAuthor", "StoryAuthor", "");
- }
- if (tale.has("StoryMenu")) {
- document.getElementById("storyMenu").setAttribute("style","");
- setPageElement("storyMenu", "StoryMenu", "");
- }
- };
- /*
- **
- ** Wikifier object
- **
- */
- function Wikifier(place, source) {
- this.source = source;
- this.output = place;
- this.nextMatch = 0;
- this.assembleFormatterMatches(Wikifier.formatters);
- this.subWikify(this.output);
- }
- Wikifier.textPrimitives = {
- upperLetter: "[A-Z\u00c0-\u00de\u0150\u0170]",
- lowerLetter: "[a-z\u00df-\u00ff_0-9\\-\u0151\u0171]",
- anyLetter: "[A-Za-z\u00c0-\u00de\u00df-\u00ff_0-9\\-\u0150\u0170\u0151\u0171]"
- }
- Wikifier.textPrimitives.variable = "\\$((?:"+Wikifier.textPrimitives.anyLetter.replace("\\-", "")+"*"+
- Wikifier.textPrimitives.anyLetter.replace("0-9\\-", "")+"+"+
- Wikifier.textPrimitives.anyLetter.replace("\\-", "")+"*)+)";
- Wikifier.textPrimitives.unquoted = "(?=(?:[^\"'\\\\]*(?:\\\\.|'(?:[^'\\\\]*\\\\.)*[^'\\\\]*'|\"(?:[^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^'\"]*$)";
- Wikifier.prototype.assembleFormatterMatches = function (formatters) {
- this.formatters = [];
- var pattern = [];
- for (var n = 0; n < formatters.length; n++) {
- pattern.push("(" + formatters[n].match + ")");
- this.formatters.push(formatters[n]);
- };
- this.formatterRegExp = new RegExp(pattern.join("|"), "mg");
- };
- Wikifier.prototype.subWikify = function (output, terminator) {
- // Temporarily replace the output pointer
- var terminatorMatch, formatterMatch, oldOutput = this.output;
- this.output = output;
- // Prepare the terminator RegExp
- var terminatorRegExp = terminator ? new RegExp("(" + terminator + ")", "mg") : null;
- do {
- // Prepare the RegExp match positions
- this.formatterRegExp.lastIndex = this.nextMatch;
- if (terminatorRegExp) terminatorRegExp.lastIndex = this.nextMatch;
- // Get the first matches
- formatterMatch = this.formatterRegExp.exec(this.source);
- terminatorMatch = terminatorRegExp ? terminatorRegExp.exec(this.source) : null;
- // Check for a terminator match
- if (terminatorMatch && (!formatterMatch || terminatorMatch.index <= formatterMatch.index)) {
- // Output any text before the match
- if (terminatorMatch.index > this.nextMatch) this.outputText(this.output, this.nextMatch, terminatorMatch.index);
- // Set the match parameters
- this.matchStart = terminatorMatch.index;
- this.matchLength = terminatorMatch[1].length;
- this.matchText = terminatorMatch[1];
- this.nextMatch = terminatorMatch.index + terminatorMatch[1].length;
- // Restore the output pointer and exit
- this.output = oldOutput;
- return;
- }
- // Check for a formatter match
- else if (formatterMatch) {
- // Output any text before the match
- if (formatterMatch.index > this.nextMatch) this.outputText(this.output, this.nextMatch, formatterMatch.index);
- // Set the match parameters
- this.matchStart = formatterMatch.index;
- this.matchLength = formatterMatch[0].length;
- this.matchText = formatterMatch[0];
- this.nextMatch = this.formatterRegExp.lastIndex;
- // Figure out which formatter matched
- var matchingFormatter = -1;
- for (var t = 1; t < formatterMatch.length; t++) {
- if (formatterMatch[t]) {
- matchingFormatter = t - 1;
- break;
- }
- }
- // Call the formatter
- if (matchingFormatter != -1) { this.formatters[matchingFormatter].handler(this); }
- }
- }
- while (terminatorMatch || formatterMatch);
- // Output any text after the last match
- if (this.nextMatch < this.source.length) {
- this.outputText(this.output, this.nextMatch, this.source.length);
- this.nextMatch = this.source.length;
- }
- // Restore the output pointer
- this.output = oldOutput;
- };
- Wikifier.prototype.outputText = function (place, startPos, endPos) {
- if (place) {
- insertText(place, this.source.substring(startPos, endPos));
- }
- };
- Wikifier.prototype.fullMatch = function() {
- return this.source.slice(this.matchStart, this.source.indexOf('>>', this.matchStart)+2);
- };
- Wikifier.prototype.fullArgs = function (includeName) {
- var source = this.source.replace(/\u200c/g," "),
- endPos = this.nextMatch-2,
- startPos = source.indexOf(includeName ? '<<' : ' ', this.matchStart);
- if (!~startPos || !~endPos || endPos <= startPos) {
- return "";
- }
- return Wikifier.parse(source.slice(startPos + (includeName ? 2 : 1), endPos).trim());
- };
- Wikifier.parse = function (input) {
- var m, re, b = input, found = [],
- g = Wikifier.textPrimitives.unquoted;
-
- function alter(from,to) {
- b = b.replace(new RegExp(from+g,"gim"),to);
- return alter;
- }
- // Extract all the variables, and set them to 0 if undefined.
- re = new RegExp(Wikifier.textPrimitives.variable+g,"gi");
- while (m = re.exec(input)) {
- if (!~found.indexOf(m[0])) {
- // This deliberately contains a 'null or undefined' check
- b = m[0]+" == null && ("+m[0]+" = 0);"+b;
- found.push(m[0]);
- }
- }
- alter(Wikifier.textPrimitives.variable, "state.history[0].variables.$1")
- // Old operators
- ("\\beq\\b", " == ")
- ("\\bneq\\b", " != ")
- ("\\bgt\\b", " > ")
- ("\\bgte\\b", " >= ")
- ("\\blt\\b", " < ")
- ("\\blte\\b", " <= ")
- ("\\band\\b", " && ")
- ("\\bor\\b", " || ")
- ("\\bnot\\b", " ! ")
- // New operators
- ("\\bis\\b", " == ")
- ("\\bto\\b", " = ");
- return b
- };
- Wikifier.formatHelpers = {
- charFormatHelper: function (a) {
- var b = insertElement(a.output, this.element);
- a.subWikify(b, this.terminator)
- },
- inlineCssHelper: function (w) {
- var s, v, lookaheadMatch, gotMatch,
- styles = [],
- lookahead = Wikifier.styleByCharFormatter.lookahead,
- lookaheadRegExp = new RegExp(lookahead, "mg"),
- hadStyle = false,
- unDash = function (str) {
- var s = str.split("-");
- if (s.length > 1) for (var t = 1; t < s.length; t++)
- s[t] = s[t].substr(0, 1).toUpperCase() + s[t].substr(1);
- return s.join("");
- };
-
- styles.className = "";
- do {
- lookaheadRegExp.lastIndex = w.nextMatch;
- lookaheadMatch = lookaheadRegExp.exec(w.source);
- gotMatch = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
- if (gotMatch) {
- hadStyle = true;
- if (lookaheadMatch[5]) {
- styles.className += lookaheadMatch[5].replace(/\./g," ") + " ";
- } else if (lookaheadMatch[1]) {
- s = unDash(lookaheadMatch[1]);
- v = lookaheadMatch[2];
- } else {
- s = unDash(lookaheadMatch[3]);
- v = lookaheadMatch[4];
- }
- switch (s) {
- case "bgcolor":
- s = "backgroundColor";
- break;
- case "float":
- s = "cssFloat";
- break
- }
- styles.push({
- style: s,
- value: v
- });
- w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- }
- } while (gotMatch);
- return styles;
- },
- monospacedByLineHelper: function (w) {
- var lookaheadRegExp = new RegExp(this.lookahead, "mg");
- lookaheadRegExp.lastIndex = w.matchStart;
- var lookaheadMatch = lookaheadRegExp.exec(w.source);
- if (lookaheadMatch && lookaheadMatch.index == w.matchStart) {
- insertElement(w.output, "pre", null, null, lookaheadMatch[1]);
- w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- }
- }
- };
- Wikifier.formatters = [
- {
- name: "table",
- match: "^\\|(?:[^\\n]*)\\|(?:[fhc]?)$",
- lookahead: "^\\|([^\\n]*)\\|([fhc]?)$",
- rowTerminator: "\\|(?:[fhc]?)$\\n?",
- cellPattern: "(?:\\|([^\\n\\|]*)\\|)|(\\|[fhc]?$\\n?)",
- cellTerminator: "(?:\\x20*)\\|",
- rowTypes: {
- "c": "caption",
- "h": "thead",
- "": "tbody",
- "f": "tfoot"
- },
- handler: function (w) {
- var rowContainer, rowElement,lookaheadMatch, matched,
- table = insertElement(w.output, "table"),
- lookaheadRegExp = new RegExp(this.lookahead, "mg"),
- currRowType = null,
- nextRowType,
- prevColumns = [],
- rowCount = 0;
- w.nextMatch = w.matchStart;
- do {
- lookaheadRegExp.lastIndex = w.nextMatch;
- lookaheadMatch = lookaheadRegExp.exec(w.source),
- matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
- if (matched) {
- nextRowType = lookaheadMatch[2];
- if (nextRowType != currRowType) rowContainer = insertElement(table, this.rowTypes[nextRowType]);
- currRowType = nextRowType;
- if (currRowType == "c") {
- if (rowCount == 0) rowContainer.setAttribute("align", "top");
- else rowContainer.setAttribute("align", "bottom");
- w.nextMatch = w.nextMatch + 1;
- w.subWikify(rowContainer, this.rowTerminator);
- } else {
- rowElement = insertElement(rowContainer, "tr");
- this.rowHandler(w, rowElement, prevColumns);
- }
- rowCount++;
- }
- } while (matched);
- },
- rowHandler: function (w, e, prevColumns) {
- var cellMatch, matched, col = 0,
- currColCount = 1,
- cellRegExp = new RegExp(this.cellPattern, "mg");
-
- do {
- cellRegExp.lastIndex = w.nextMatch;
- cellMatch = cellRegExp.exec(w.source);
- matched = cellMatch && cellMatch.index == w.nextMatch;
- if (matched) {
- if (cellMatch[1] == "~") {
- var last = prevColumns[col];
- if (last) {
- last.rowCount++;
- last.element.setAttribute("rowSpan", last.rowCount);
- last.element.setAttribute("rowspan", last.rowCount);
- last.element.valign = "center";
- }
- w.nextMatch = cellMatch.index + cellMatch[0].length - 1;
- } else if (cellMatch[1] == ">") {
- currColCount++;
- w.nextMatch = cellMatch.index + cellMatch[0].length - 1;
- } else if (cellMatch[2]) {
- w.nextMatch = cellMatch.index + cellMatch[0].length;
- break;
- } else {
- var spaceLeft = false,
- spaceRight = false,
- lastColCount, lastColElement, styles, cell, t;
- w.nextMatch++;
- styles = Wikifier.formatHelpers.inlineCssHelper(w);
- while (w.source.substr(w.nextMatch, 1) == " ") {
- spaceLeft = true;
- w.nextMatch++;
- }
- if (w.source.substr(w.nextMatch, 1) == "!") {
- cell = insertElement(e, "th");
- w.nextMatch++;
- } else cell = insertElement(e, "td");
- prevColumns[col] = {
- rowCount: 1,
- element: cell
- };
- lastColCount = 1;
- lastColElement = cell;
- if (currColCount > 1) {
- cell.setAttribute("colSpan", currColCount);
- cell.setAttribute("colspan", currColCount);
- currColCount = 1;
- }
- for (t = 0; t < styles.length; t++)
- cell.style[styles[t].style] = styles[t].value;
- w.subWikify(cell, this.cellTerminator);
- if (w.matchText.substr(w.matchText.length - 2, 1) == " ") spaceRight = true;
- if (spaceLeft && spaceRight) cell.align = "center";
- else if (spaceLeft) cell.align = "right";
- else if (spaceRight) cell.align = "left";
- w.nextMatch = w.nextMatch - 1;
- }
- col++;
- }
- } while (matched);
- }
- },
- {
- name: "rule",
- match: "^----$\\n?",
- handler: function (w) {
- insertElement(w.output, "hr");
- }
- },
- {
- name: "emdash",
- match: "--",
- becomes: String.fromCharCode(8212),
- handler: function (a) {
- insertElement(a.output, "span", null, "char", this.becomes).setAttribute("data-char","emdash");
- }
- },
- {
- name: "heading",
- match: "^!{1,5}",
- terminator: "\\n",
- handler: function (w) {
- var e = insertElement(w.output, "h" + w.matchLength);
- w.subWikify(e, this.terminator);
- }
- },
- {
- name: "monospacedByLine",
- match: "^\\{\\{\\{\\n",
- lookahead: "^\\{\\{\\{\\n((?:^[^\\n]*\\n)+?)(^\\}\\}\\}$\\n?)",
- handler: Wikifier.formatHelpers.monospacedByLineHelper
- },
- {
- name: "quoteByBlock",
- match: "^<<<\\n",
- terminator: "^<<<\\n",
- handler: function (w) {
- var e = insertElement(w.output, "blockquote");
- w.subWikify(e, this.terminator);
- }
- },
- {
- name: "list",
- match: "^(?:(?:\\*+)|(?:#+))",
- lookahead: "^(?:(\\*+)|(#+))",
- terminator: "\\n",
- handler: function (w) {
- var newType, newLevel, t, len, bulletType, lookaheadMatch, matched,
- lookaheadRegExp = new RegExp(this.lookahead, "mg"),
- placeStack = [w.output],
- currType = null,
- currLevel = 0;
-
- w.nextMatch = w.matchStart;
- do {
- lookaheadRegExp.lastIndex = w.nextMatch;
- lookaheadMatch = lookaheadRegExp.exec(w.source);
- matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
- if (matched) {
- newLevel = lookaheadMatch[0].length;
- if (lookaheadMatch[1]) {
- bulletType = lookaheadMatch[1].slice(-1);
- newType = "ul";
- }
- else if (lookaheadMatch[2]) {
- newType = "ol";
- }
- w.nextMatch += newLevel;
- if (newLevel > currLevel) {
- for (t = currLevel; t < newLevel; t++) {
- placeStack.push(insertElement(placeStack[placeStack.length - 1], newType));
- }
- } else if (newLevel < currLevel) {
- for (t = currLevel; t > newLevel; t--)
- placeStack.pop();
- } else if (newLevel == currLevel && newType != currType) {
- placeStack.pop();
- placeStack.push(insertElement(placeStack[placeStack.length - 1], newType));
- }
- currLevel = newLevel;
- currType = newType;
- t = insertElement(placeStack[placeStack.length - 1], "li");
- // Currently unused
- if (bulletType && bulletType != "*") {
- t.setAttribute("data-bullet", bulletType);
- }
- w.subWikify(t, this.terminator);
- }
- } while (matched);
- }
- },
- (Wikifier.urlFormatter = {
- name: "urlLink",
- match: "(?:https?|mailto|javascript|ftp|data):[^\\s'\"]+(?:/|\\b)",
- handler: function (w) {
- var e = Wikifier.createExternalLink(w.output, w.matchText);
- w.outputText(e, w.matchStart, w.nextMatch);
- }
- }),
- (Wikifier.linkFormatter = {
- name: "prettyLink",
- match: "\\[\\[",
- lookahead: "\\[\\[([^\\|]*?)(?:\\|(.*?))?\\](?:\\[(.*?)\])?\\]",
- makeInternalOrExternal: function(out,title,callback,type) {
- if (title && !tale.has(title) && (title.match(Wikifier.urlFormatter.match,"g") || ~title.search(/[\.\\\/#]/)))
- return Wikifier.createExternalLink(out, title, callback, type);
- else
- return Wikifier.createInternalLink(out, title, callback, type);
- },
- // This base callback executes the code in a setter
- makeCallback: function(code,callback) {
- return function() {
- macros.set.run(null, Wikifier.parse(code), null, code);
- typeof callback == "function" && callback.call(this);
- }
- },
- makeLink: function(out, match, callback2, type) {
- var link, title, callback;
- if (match[3]) { // Code
- callback = this.makeCallback(match[3],callback2);
- }
- else {
- typeof callback2 == "function" && (callback = callback2);
- }
- title = Wikifier.parsePassageTitle(match[2] || match[1]);
- link = this.makeInternalOrExternal(out,title,callback, type);
- setPageElement(link, null, match[2] ? match[1] : title);
- return link;
- },
- handler: function (w) {
- var lookaheadRegExp = new RegExp(this.lookahead, "mg");
- lookaheadRegExp.lastIndex = w.matchStart;
- var lookaheadMatch = lookaheadRegExp.exec(w.source)
- if (lookaheadMatch && lookaheadMatch.index == w.matchStart) {
- this.makeLink(w.output, lookaheadMatch)
- w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- }
- }
- }),
- (Wikifier.imageFormatter = {
- name: "image",
- match: "\\[(?:[<]{0,1})(?:[>]{0,1})[Ii][Mm][Gg]\\[",
- lookahead: "\\[([<]?)(>?)img\\[(?:([^\\|\\]]+)\\|)?([^\\[\\]\\|]+)\\](?:\\[([^\\]]*)\\]?)?(\\])",
- importedImage: function(img, passageName) {
- var imgPassages, imgname;
- // Try to parse it as a variable
- try {
- imgname = internalEval(Wikifier.parse(passageName));
- }
- catch(e) {
- }
- if (!imgname) {
- imgname = passageName;
- }
- // Base64 passage transclusion
- imgPassages = tale.lookup("tags", "Twine.image");
- for (j = 0; j < imgPassages.length; j++) {
- if (imgPassages[j].title == imgname) {
- img.src = imgPassages[j].text;
- break;
- }
- }
- },
- handler: function (w) {
- var e, img, j, lookaheadMatch,
- lookaheadRegExp = new RegExp(this.lookahead, "mig");
- lookaheadRegExp.lastIndex = w.matchStart;
- lookaheadMatch = lookaheadRegExp.exec(w.source);
- if (lookaheadMatch && lookaheadMatch.index == w.matchStart)
- {
- e = w.output, title = Wikifier.parsePassageTitle(lookaheadMatch[5])
- if (title) {
- e = Wikifier.linkFormatter.makeInternalOrExternal(w.output, title);
- }
- img = insertElement(e, "img");
- if (lookaheadMatch[1]) img.align = "left";
- else if (lookaheadMatch[2]) img.align = "right";
- if (lookaheadMatch[3]) img.title = lookaheadMatch[3];
- // Setup the image if it's referencing an image passage.
- this.importedImage(img,lookaheadMatch[4]);
- w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- }
- }
- }),
- {
- name: "macro",
- match: "<<",
- lookahead: /<<([^>\s]+)(?:\s*)((?:\\.|'(?:[^'\\]*\\.)*[^'\\]*'|"(?:[^"\\]*\\.)*[^"\\]*"|[^'"\\>]|>(?!>))*)>>/mg,
- handler: function (w) {
- var lookaheadRegExp = new RegExp(this.lookahead);
- lookaheadRegExp.lastIndex = w.matchStart;
- var lookaheadMatch = lookaheadRegExp.exec(w.source.replace(/\u200c/g,'\n'));
- if (lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
- var params = lookaheadMatch[2].readMacroParams();
- w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- var name = lookaheadMatch[1];
- try {
- var macro = macros[name];
- if (macro && typeof macro == "object" && macro.handler) {
- macro.handler(w.output, name, params, w);
- }
- // Variable?
- else if (name[0] == '$') {
- macros.print.handler(w.output, name, [name].concat(params), w);
- }
- // Passage
- else if (tale.has(name)) {
- macros.display.handler(w.output, name, [name].concat(params), w);
- }
- else throwError(w.output, 'No macro or passage called "' + name + '"', w.fullMatch());
- } catch (e) {
- throwError(w.output, 'Error executing macro ' + name + ': ' + e.toString(), w.fullMatch());
- }
- }
- }
- },
- {
- name: "html",
- match: "<html>",
- lookahead: "<html>((?:.|\\n)*?)</html>",
- handler: function (w) {
- var lookaheadRegExp = new RegExp(this.lookahead, "mg");
- lookaheadRegExp.lastIndex = w.matchStart;
- var lookaheadMatch = lookaheadRegExp.exec(w.source)
- if (lookaheadMatch && lookaheadMatch.index == w.matchStart) {
- var e = insertElement(w.output, "span");
- e.innerHTML = lookaheadMatch[1];
- w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- }
- }
- },
- {
- name: "commentByBlock",
- match: "/%",
- lookahead: "/%((?:.|\\n)*?)%/",
- handler: function (w) {
- var lookaheadRegExp = new RegExp(this.lookahead, "mg");
- lookaheadRegExp.lastIndex = w.matchStart;
- var lookaheadMatch = lookaheadRegExp.exec(w.source)
- if (lookaheadMatch && lookaheadMatch.index == w.matchStart) w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- }
- },
- {
- name: "boldByChar",
- match: "''",
- terminator: "''",
- element: "strong",
- handler: Wikifier.formatHelpers.charFormatHelper
- },
- {
- name: "strikeByChar",
- match: "==",
- terminator: "==",
- element: "strike",
- handler: Wikifier.formatHelpers.charFormatHelper
- },
- {
- name: "underlineByChar",
- match: "__",
- terminator: "__",
- element: "u",
- handler: Wikifier.formatHelpers.charFormatHelper
- },
- {
- name: "italicByChar",
- match: "//",
- terminator: "//",
- element: "em",
- handler: Wikifier.formatHelpers.charFormatHelper
- },
- {
- name: "subscriptByChar",
- match: "~~",
- terminator: "~~",
- element: "sub",
- handler: Wikifier.formatHelpers.charFormatHelper
- },
- {
- name: "superscriptByChar",
- match: "\\^\\^",
- terminator: "\\^\\^",
- element: "sup",
- handler: Wikifier.formatHelpers.charFormatHelper
- },
- {
- name: "monospacedByChar",
- match: "\\{\\{\\{",
- lookahead: "\\{\\{\\{((?:.|\\n)*?)\\}\\}\\}",
- handler: function (w) {
- var lookaheadRegExp = new RegExp(this.lookahead, "mg");
- lookaheadRegExp.lastIndex = w.matchStart;
- var lookaheadMatch = lookaheadRegExp.exec(w.source)
- if (lookaheadMatch && lookaheadMatch.index == w.matchStart) {
- var e = insertElement(w.output, "code", null, null, lookaheadMatch[1]);
- w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- }
- }
- },
- (Wikifier.styleByCharFormatter = {
- name: "styleByChar",
- match: "@@",
- terminator: "@@",
- lookahead: "(?:([^\\(@]+)\\(([^\\)\\|\\n]+)(?:\\):))|(?:([^\\.:@]+):([^;\\|\\n]+);)|(?:\\.([^;\\|\\n]+);)",
- handler: function (w) {
- var e = insertElement(w.output, "span", null, null, null);
- var styles = Wikifier.formatHelpers.inlineCssHelper(w);
- if (styles.length == 0) {
- e.className = "marked";
- }
- else {
- for (var t = 0; t < styles.length; t++) {
- e.style[styles[t].style] = styles[t].value;
- }
- if (typeof styles.className == "string") {
- e.className = styles.className;
- }
- }
- w.subWikify(e, this.terminator);
- }
- }),
- {
- name: "lineBreak",
- match: "\\n",
- handler: function (w) {
- insertElement(w.output, "br");
- }
- },
- {
- name: "continuedLine",
- match: "\\\\\\s*?\\n",
- handler: function(a) {
- a.nextMatch = a.matchStart+2;
- }
- },
- {
- name: "htmlCharacterReference",
- match: "(?:(?:&#?[a-zA-Z0-9]{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]));)+|&#?[a-zA-Z0-9]{2,8};)",
- handler: function(w)
- {
- var el = document.createElement("div");
- el.innerHTML = w.matchText;
- insertText(w.output, el.textContent);
- }
- },
- {
- name: "htmltag",
- match: "<(?:\\/?[\\w\\-]+|[\\w\\-]+(?:(?:\\s+[\\w\\-]+(?:\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)\\/?)>",
- tagname: "<(\\w+)",
- voids: ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"],
- tableElems: ["table","thead","tbody","tfoot","th","tr","td","colgroup","col","caption","figcaption"],
- cleanupTables: function (e) {
- var i, name, elems = [].slice.call(e.children);
- // Remove non-table child elements that aren't children of <td>s
- for (i = 0; i < elems.length; i++) {
- if (elems[i].tagName) {
- name = elems[i].tagName.toLowerCase();
- if (this.tableElems.indexOf(name)==-1) {
- elems[i].outerHTML = '';
- }
- else if (['col','caption','figcaption','td','th'].indexOf(name)==-1) {
- this.cleanupTables.call(this,elems[i]);
- }
- }
- }
- },
- handler: function (a) {
- var tmp, passage, setter, e, isvoid, isstyle, lookaheadRegExp, lookaheadMatch, lookahead,
- re = new RegExp(this.tagname).exec(a.matchText),
- tn = re && re[1] && re[1].toLowerCase();
- if(tn && tn != "html") {
- lookahead = "<\\/\\s*" + tn + "\\s*>";
- isvoid = (this.voids.indexOf(tn) != -1);
- isstyle = tn == "style" || tn == "script";
- lookaheadRegExp = new RegExp(lookahead, "mg");
- lookaheadRegExp.lastIndex = a.matchStart;
- lookaheadMatch = lookaheadRegExp.exec(a.source);
- if (lookaheadMatch || isvoid) {
- if (isstyle) {
- e = document.createElement(tn);
- e.type = "text/css"; // IE8 compatibility
- tmp = a.source.slice(a.nextMatch, lookaheadMatch.index);
- e.styleSheet ? (e.styleSheet.cssText = tmp) : (e.innerHTML = tmp);
- a.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
- }
- else {
- // Creating a loose <tr> element creates it wrapped inside a <tbody> element.
- e = document.createElement(a.output.tagName);
- e.innerHTML = a.matchText;
- while(e.firstChild) {
- e = e.firstChild;
- }
- if (!isvoid) {
- a.subWikify(e, lookahead);
- }
- }
- if (e.tagName.toLowerCase() == 'table') {
- this.cleanupTables.call(this,e);
- }
- // Special data-setter attribute
- if (setter = e.getAttribute("data-setter")) {
- setter = Wikifier.linkFormatter.makeCallback(setter);
- }
- // Special data-passage attribute
- if (passage = e.getAttribute("data-passage")) {
- if (tn != "img") {
- addClickHandler(e, Wikifier.linkFunction(Wikifier.parsePassageTitle(passage), e, setter));
- if (tn == "area" || tn == "a") {
- e.setAttribute("href", "javascript:;");
- }
- }
- else {
- Wikifier.imageFormatter.importedImage(e, passage);
- }
- }
- a.output.appendChild(e);
- } else {
- throwError(a.output,"HTML tag '"+tn+"' wasn't closed.", a.matchText);
- }
- }
- }
- }];
- // Optional - included if the ".char" selector appears anywhere in the story.
- Wikifier.charSpanFormatter = {
- name: "char",
- match: "[^\n]",
- handler: function (a) {
- // Line breaks do NOT get their own charspans
- insertElement(a.output, "span", null, "char", a.matchText).setAttribute("data-char", a.matchText == " " ? "space" :
- a.matchText == "\t" ? "tab" : a.matchText);
- }
- };
- Wikifier.parsePassageTitle = function(title) {
- if (title && !tale.has(title)) {
- try {
- title = (internalEval(this.parse(title)) || title)+"";
- }
- catch(e) {}
- }
- return title;
- };
- Wikifier.linkFunction = function(title, el, callback) {
- return function() {
- if (state.rewindTo) {
- var passage = findPassageParent(el);
- if (passage && passage.parentNode.lastChild != passage) {
- state.rewindTo(passage, true);
- }
- }
- if (title) {
- state.display(title, el, null, callback);
- }
- else if (typeof callback == "function") {
- callback();
- }
- };
- };
- Wikifier.createInternalLink = function (place, title, callback, type) {
- var tag = (type == "button" ? 'button' : 'a'),
- suffix = (type == "button" ? "Button" : "Link"),
- el = insertElement(place, tag);
- if (tale.has(title)) {
- el.className = 'internal'+suffix;
- if (visited(title)) el.className += ' visited'+suffix;
- }
- else el.className = 'broken'+suffix;
- addClickHandler(el, Wikifier.linkFunction(title, el, callback));
- if (place) place.appendChild(el);
- return el;
- };
- Wikifier.createExternalLink = function (place, url, callback, type) {
- var tag = (type == "button" ? 'button' : 'a'),
- el = insertElement(place, tag);
- el.href = url;
- el.className = "external"+(type == "button" ? "Button" : "Link");
- el.target = "_blank";
- if (typeof callback == "function") {
- addClickHandler(el,callback);
- }
-
- if (place) place.appendChild(el);
- return el;
- };
- // Functions usable solely by custom scripts
- // This includes restart(), above.
- function visited(e) {
- var ret = 0, i = 0;
- if (!state) {
- return 0;
- }
- e = e || state.history[0].passage.title;
- if (arguments.length > 1) {
- for (ret = state.history.length; i<arguments.length; i++) {
- ret = Math.min(ret, visited(arguments[i]));
- }
- }
- else for(; i<state.history.length && state.history[i].passage; i++) {
- if(e == state.history[i].passage.title) {
- ret++;
- }
- }
- return ret;
- }
- // Returns the number of times the player visited passages containing ALL
- // provided tags.
- // The tags can be several strings, or a single string with space-delimited tags.
- function visitedTag() {
- var i, j, sh, ret = 0, tags = Array.prototype.slice.call(arguments);
- if (tags.length == 1 && typeof tags[0] == "string") {
- tags = tags.split(" ");
- }
- if (!state) {
- return 0;
- }
- sh = state.history;
- for(i = 0; i<sh.length && sh[i].passage; i++) {
- for (j = 0; j < tags.length || void ret++; j++) {
- if(sh[i].passage.tags.indexOf(tags[j])==-1) {
- break;
- }
- }
- }
- return ret;
- }
- var visitedTags = visitedTag;
- function turns() {
- return state.history.length-1;
- }
- function passage() {
- return state.history[0].passage.title
- }
- function tags(e) {
- var ret = [], i = 0;
- if (!state) {
- return 0;
- }
- e = e || state.history[0].passage.title;
- if (arguments.length > 1) {
- for (i = arguments.length-1; i >= 1; i--) {
- ret = ret.concat(tags(arguments[i]));
- }
- }
- ret = ret.concat(tale.get(e).tags);
- return ret;
- }
- function previous() {
- if (state && state.history[1]) {
- for (var d = 1; d < state.history.length && state.history[d].passage; d++) {
- if (state.history[d].passage.title != state.history[0].passage.title) {
- return state.history[d].passage.title
- }
- }
- }
- return ""
- }
- // A random integer function
- // 1 argument: random int from 0 to a inclusive
- // 2 arguments: random int from a to b inclusive (order irrelevant)
- function random(a, b) {
- var from, to;
- if (!b) {
- from = 0;
- to = a;
- } else {
- from = Math.min(a, b);
- to = Math.max(a, b);
- }
- to += 1;
- return ~~((Math.random() * (to - from))) + from;
- }
- function either() {
- if (Array.isArray(arguments[0]) && arguments.length == 1) {
- return either.apply(this,arguments[0]);
- }
- return arguments[~~(Math.random()*arguments.length)];
- }
- function parameter(n) {
- n = n || 0;
- if (macros.display.parameters[n]) {
- return macros.display.parameters[n];
- }
- return 0
- }
- function bookmark() {
- return state.hash || "#";
- }
- /* Used to eval within Twine, but outside the context of a particular function */
- function internalEval(s) {
- // eval("{x:1,y:1}") fails miserably unless the obj. literal
- // is not the first expression in the line (hence, "0,").
- return eval("0,"+s);
- }
- /* Used to execute script passages */
- function scriptEval(s) {
- try {
- eval(s.text);
- } catch (e) {
- alert("There is a technical problem with this " + tale.identity() + " (" + s.title + ": " + e.message + ")."+softErrorMessage);
- }
- }
- /* Unload prompt */
- window.onbeforeunload = function() {
- if (tale && tale.storysettings.lookup("exitprompt",false) && state && state.history.length > 1) {
- return "You are about to end this " + tale.identity() + ".";
- }
- };
- /* Error reporting */
- var oldOnError = window.onerror || null,
- softErrorMessage = "You may be able to continue playing, but some parts may not work properly.";
- window.onerror = function (msg, a, b, c, error) {
- var s = (error && (".\n\n" + error.stack.replace(/\([^\)]+\)/g,'') + "\n\n")) || (" (" + msg + ").\n");
- alert("Sorry to interrupt, but this " + ((tale && tale.identity && tale.identity()) || "page") + "'s code has got itself in a mess" + s + softErrorMessage.slice(1));
- // Restore previous onerror
- window.onerror = oldOnError;
- if (typeof window.onerror == "function") {
- window.onerror(msg, a, b, c, error);
- }
- };
- /* Init function */
- var $;
- function main() {
- // Used by old custom scripts.
- // Cedes to jQuery if it exists.
- // Since jQuery is inserted after this script element,
- // wait until main() is called before doing this.
- $ = window.$ || function(a) {
- return (typeof a == "string" ? document.getElementById(a) : a);
- }
- var imgs, scripts, macro, style, i,
- styleText = "",
- passages = document.getElementById("passages");
-
- // Run checks after custom macros are installed
- function sanityCheck(thing) {
- var i, j, s = "NOTE: The " + thing,
- checks = { prerender: prerender, postrender: postrender, macros: macros };
- // Warn if prerender/postrender/macros aren't objects, and
- // prerender/postrender's own properties aren't functions.
- for (i in checks) {
- if (Object.prototype.hasOwnProperty.call(checks, i) && !sanityCheck[i]) {
- if (!checks[i] || typeof checks[i] != "object") {
- alert(s + " seems to have corrupted the " + i + " object."+softErrorMessage);
- sanityCheck[i] = true;
- continue;
- }
- if (i != "macros") {
- for (j in checks[i]) {
- if (Object.prototype.hasOwnProperty.call(checks[i], j)
- && typeof checks[i][j] != "function") {
- alert(s + " added a property '" + j + "' to " + i + ", "
- +"which is a "+typeof checks[i][j]+", not a function."+softErrorMessage);
- sanityCheck[i] = true;
- break;
- }
- }
- }
- }
- }
- }
-
- // Check for basic compatibility
- if (!window.JSON || !document.querySelector) {
- return (passages.innerHTML = "This " + tale.identity() + " requires a newer web browser. Sorry.");
- } else {
- passages.innerHTML = "";
- }
- // Initialise Tale
- tale = window.tale = new Tale();
-
- // Check for IE8 image compatibility
- if (~document.documentElement.className.indexOf("lt-ie9")) {
- imgs = tale.lookup("tags", "Twine.image");
- for (i = 0; i < imgs.length; i++) {
- if (imgs[i].text.length >= 32768) {
- alert("NOTE: This " + tale.identity() + "'s HTML file contains embedded images that may be too large for this browser to display."+softErrorMessage);
- break;
- }
- }
- }
- // Run all script passages
- scripts = tale.lookup("tags", "script");
- for (i = 0; i < scripts.length; i++) {
- scriptEval(scripts[i]);
- sanityCheck('script passage "'+scripts[i].title+'"');
- }
- // Need to create state now, since it's used by remember.init()
- state = window.state = new History();
- for (i in macros) {
- macro = macros[i];
- if (typeof macro.init == "function") {
- macro.init();
- sanityCheck('init() of the custom macro "'+i+'"');
- }
- }
- // Run all stylesheet passages
- style = document.getElementById("storyCSS");
- for (i in tale.passages) {
- i = tale.passages[i];
- if (i.tags.indexOf("stylesheet")==-1) {
- continue;
- }
- // No other tags?
- if (i.tags + "" == "stylesheet") {
- styleText += i.text;
- }
- else if (i.tags.length == 2 && i.tags.indexOf("transition") >-1) {
- setTransitionCSS(i.text);
- }
- }
- styleText = alterCSS(styleText);
- style.styleSheet ? (style.styleSheet.cssText = styleText) : (style.innerHTML = styleText);
-
- state.init();
- }
- setTimeout(function f() {
- var size, bar = document.getElementById("loadingbar"), store = document.getElementById("storeArea");
- if (!bar) {
- return;
- }
- if (store) {
- size = store.getAttribute("data-size");
- if (store.children.length <= size && !tale) {
- // +1 so that the bar can reach the end
- bar.style.width = ~~((store.children.length+1)/size*100)+"%";
- }
- else {
- bar.outerHTML = "";
- return;
- }
- }
- setTimeout(f,5);
- },5);
- /*
- **
- ** Sugarcane/Responsive specific code follows
- **
- */
- var hasPushState = !!window.history && (typeof window.history.pushState == "function") && (function(a) {
- // iOS Safari: setItem throws in private mode
- try {
- a.setItem("test", '1');
- a.removeItem("test");
- return true;
- } catch (e) {
- return false;
- }
- }(window.sessionStorage));
- Tale.prototype.canBookmark = function() {
- return this.canUndo() && !this.storysettings.lookup('hash') && (this.storysettings.lookup('bookmark',true) || !hasPushState);
- };
- History.prototype.init = function () {
- var a = this;
- if (!this.restore()) {
- if (tale.has("StoryInit")) {
- new Wikifier(insertElement(null, "span"), tale.get("StoryInit").text);
- }
- this.display("Start", null)
- }
- if (!hasPushState) {
- this.hash = window.location.hash;
- this.interval = window.setInterval(function () {
- a.watchHash()
- }, 250)
- }
- };
- hasPushState && (History.prototype.pushState = function(replace, uri) {
- window.history[replace ? "replaceState" : "pushState"]({ id: this.id, length: this.history.length }, document.title, uri);
- });
- History.prototype.display = function (title, source, type, callback) {
- var i, e, q, bookmark, hash, c = tale.get(title), p = document.getElementById("passages");
- if (c==null) {
- return;
- }
- if (type != "back") {
- this.saveVariables(c, source, callback);
- hash = (tale.storysettings.lookup('hash') && this.save()) || "";
- if (hasPushState && tale.canUndo()) {
- try {
- sessionStorage.setItem("Twine.History"+this.id, JSON.stringify(decompile(this.history)));
- this.pushState(this.history.length <= 2 && window.history.state == "", hash);
- } catch(e) {
- alert("Your browser couldn't save the state of the " + tale.identity() +".\n"+
- "You may continue playing, but it will no longer be possible to undo moves from here on in.");
- tale.storysettings.undo="off";
- }
- }
- }
- this.hash = hash || this.save();
- e = c.render();
- if (type != "quietly") {
- if (hasTransition) {
- for(i = 0; i < p.childNodes.length; i += 1) {
- q = p.childNodes[i];
- q.classList.add("transition-out");
- setTimeout((function(a) { return function () {
- if(a.parentNode) a.parentNode.removeChild(a);
- }}(q)), 1000);
- }
- e.classList.add("transition-in");
- setTimeout(function () { e.classList.remove("transition-in"); }, 1);
- e.style.visibility = "visible";
- p.appendChild(e);
- } else {
- removeChildren(p);
- p.appendChild(e);
- fade(e, {
- fade: "in"
- })
- }
- }
- else {
- p.appendChild(e);
- e.style.visibility = "visible"
- }
- tale.setPageElements();
- if (tale.canUndo()) {
- if (!hasPushState && type != "back") {
- window.location.hash = this.hash;
- } else if (tale.canBookmark()) {
- bookmark = document.getElementById("bookmark");
- bookmark && (bookmark.href = this.hash);
- }
- }
- window.scroll(0, 0)
- return e
- };
- History.prototype.watchHash = function () {
- if (window.location.hash != this.hash) {
- if (window.location.hash && (window.location.hash != "#")) {
- this.history = [{
- passage: null,
- variables: {}
- }];
- removeChildren(document.getElementById("passages"));
- if (!this.restore()) {
- alert("The passage you had previously visited could not be found.")
- }
- } else {
- window.location.reload()
- }
- this.hash = window.location.hash
- }
- };
- History.prototype.loadLinkVars = function() {
- for (var c in this.history[0].linkVars) {
- this.history[0].variables[c] = clone(this.history[0].linkVars[c]);
- }
- };
- Passage.prototype.render = function () {
- var b = insertElement(null, 'div', 'passage' + this.title, 'passage');
- b.style.visibility = 'hidden';
- this.setTags(b);
- this.setCSS();
- insertElement(b, 'div', '', 'header');
- var a = insertElement(b, 'div', '', 'body content');
- for (var i in prerender) {
- (typeof prerender[i] == "function") && prerender[i].call(this,a);
- }
- new Wikifier(a, this.processText());
- insertElement(b, 'div', '', 'footer');
- for (i in postrender) {
- (typeof postrender[i] == "function") && postrender[i].call(this,a);
- }
- return b;
- };
- Passage.prototype.excerpt = function () {
- var b = this.text.replace(/<<.*?>>/g, "");
- b = b.replace(/!.*?\n/g, "");
- b = b.replace(/[\[\]\/]/g, "");
- var a = b.split("\n");
- while (a.length && a[0].length == 0) a.shift();
- var c = '';
- if (a.length == 0 || a[0].length == 0) c = this.title;
- else c = a[0].substr(0, 30) + '...';
- return c;
- };
- Passage.transitionCache = "";
- Passage.prototype.setCSS = function() {
- var trans = false, text = "", tags = this.tags || [],
- c = document.getElementById('tagCSS'),
- c2 = document.getElementById('transitionCSS');
-
- if (c && c.getAttribute('data-tags') != tags.join(' ')) {
- tale.forEachStylesheet(tags, function(passage) {
- if (~passage.tags.indexOf("transition")) {
- if (!Passage.transitionCache && c2)
- Passage.transitionCache = c2.innerHTML;
- setTransitionCSS(passage.text);
- trans = true;
- }
- else text += alterCSS(passage.text);
- });
- if (!trans && Passage.transitionCache && c2) {
- setTransitionCSS(Passage.transitionCache);
- trans = false;
- Passage.transitionCache = "";
- }
- c.styleSheet ? (c.styleSheet.cssText = text) : (c.innerHTML = text);
- c.setAttribute('data-tags', tags.join(' '));
- }
- };
- var Interface = {
- init: function () {
- var snapback = document.getElementById("snapback"),
- restart = document.getElementById("restart"),
- bookmark = document.getElementById("bookmark");
- main();
- if (!tale) {
- return;
- }
- if (snapback) {
- if (!tale.lookup("tags", "bookmark").length) {
- snapback.parentNode.removeChild(snapback);
- } else addClickHandler(snapback, Interface.showSnapback);
- }
- if (bookmark && (!tale.canBookmark() || !hasPushState)) {
- bookmark.parentNode.removeChild(bookmark);
- }
- restart && addClickHandler(restart, Interface.restart);
- },
- restart: function () {
- if (confirm("Are you sure you want to restart this " + tale.identity() + "?")) {
- state.restart()
- }
- },
- showSnapback: function (a) {
- Interface.hideAllMenus();
- Interface.buildSnapback();
- Interface.showMenu(a, document.getElementById("snapbackMenu"))
- },
- buildSnapback: function () {
- var b, c = false,
- menuelem = document.getElementById("snapbackMenu");
- while (menuelem.hasChildNodes()) {
- menuelem.removeChild(menuelem.firstChild)
- }
- for(var a = state.history.length - 1; a >= 0; a--) {
- if(state.history[a].passage && state.history[a].passage.tags.indexOf("bookmark") != -1) {
- b = document.createElement("div");
- b.pos = a;
- addClickHandler(b, function () {
- return macros.back.onclick(true, this.pos);
- });
- b.innerHTML = state.history[a].passage.excerpt();
- menuelem.appendChild(b);
- c = true
- }
- }
- b = null
- if(!c) {
- b = document.createElement("div");
- b.innerHTML = "<i>No passages available</i>";
- document.getElementById("snapbackMenu").appendChild(b)
- }
- },
- hideAllMenus: function () {
- document.getElementById("snapbackMenu").style.display = "none"
- },
- showMenu: function (b, a) {
- if (!b) {
- b = window.event
- }
- var c = {
- x: 0,
- y: 0
- };
- if (b.pageX || b.pageY) {
- c.x = b.pageX;
- c.y = b.pageY
- } else {
- if (b.clientX || b.clientY) {
- c.x = b.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
- c.y = b.clientY + document.body.scrollTop + document.documentElement.scrollTop
- }
- }
- a.style.top = c.y + "px";
- a.style.left = c.x + "px";
- a.style.display = "block";
- addClickHandler(document, Interface.hideAllMenus);
- b.cancelBubble = true;
- if (b.stopPropagation) {
- b.stopPropagation()
- }
- }
- };
- window.onload = Interface.init;
- macros.back.onclick = function(back, steps) {
- var title;
- if (back) {
- if (tale.canUndo()) {
- window.history.go(-steps);
- return;
- }
- while(steps-- >= 0 && state.history.length>1) {
- title = state.history[0].passage.title;
- state.history.shift();
- }
- state.loadLinkVars();
- state.saveVariables(tale.get(title));
- state.display(title, null, "back");
- }
- else {
- state.display(state.history[steps].passage.title);
- }
- };
- window.onpopstate = function(e) {
- var title, hist, steps, i, s = e && e.state;
- if (s && s.id && s.length != null) {
- hist = recompile(JSON.parse(sessionStorage.getItem("Twine.History"+s.id)));
- if (hist) {
- steps = hist.length-s.length;
- }
- }
- if (steps != null) {
- state.history = hist;
- // Shift the position of history to match how far back we've gone
- while(steps-- >= 0 && state.history.length>1) {
- title = state.history[0].passage.title;
- state.history.shift();
- }
- state.loadLinkVars();
- state.saveVariables(tale.get(title));
- state.display(title, null, "back");
- }
- };
- testplay = "";
- }());
- </script>
- <script title="modules">
- </script>
- <style id="baseCSS">
- /* Sidebar */
- #sidebar {
- position: fixed;
- list-style: none;
- width: 12em;
- }
- #sidebar #title, #sidebar #credits {
- cursor: auto;
- }
- #sidebar #storySubtitle, #sidebar #storyMenu {
- display: block;
- }
- .menu {
- position: absolute;
- display: none;
- z-index: 5;
- }
- /* Passages container */
- #passages {
- margin-left: 18.2em;
- position:relative;
- }
- /* Links */
- .passage a {
- color: #4d6ad8;
- }
- a.internalLink, a.externalLink, a.back, a.return, [data-passage], .menu div {
- cursor: pointer;
- }
- a.brokenLink {
- background-color: red;
- color: #000;
- }
- .marked {
- background-color: #f66;
- color: #000;
- }
- .marked[title] {
- cursor: help;
- }
- .passage li[data-bullet] {
- list-style-type: none;
- }
- .passage li[data-bullet]:before {
- content: attr(data-bullet);
- position: relative;
- left: -1em;
- }
- #storeArea {
- display: none;
- }
- #noscript {
- margin-left: 18.2em;
- font-size: 1.2em;
- font-weight: bold;
- }
- /* HTML4 compatibility */
- img {
- vertical-align:bottom;
- }
- @media screen and (max-width: 640px) {
- #sidebar {
- position: static;
- margin: 0 auto;
- padding: 0;
- }
- body #sidebar li {
- text-align: center;
- }
- #passages {
- min-height: 100vh;
- margin-left: 0em;
- }
- }
- #loadingbar {
- position:fixed;
- top:0;
- left:0;
- border-top: solid #4d6ad8 6px;
- transition: width 0.5s;
- }
- </style>
- <style id="defaultCSS">
- body {
- background-color: #000;
- color: #fff;
- font-family: Verdana,sans-serif;
- font-size: 62.5%;
- margin: 4em 15% 5% 5em;
- }
- #sidebar {
- left: 7.5em;
- margin: 0;
- padding: 0 1em 0 0;
- font: bold 1.1em Verdana,sans-serif;
- }
- #sidebar ul {
- padding: 0;
- }
- #sidebar li {
- color: #333;
- text-align: right;
- background-repeat: no-repeat;
- margin-bottom: 1em;
- line-height: 1.4em;
- list-style: none;
- }
- #sidebar li a {
- color: #333;
- text-decoration: none;
- }
- #sidebar li a:hover, #sidebar #title a:hover, #snapback:hover, #restart:hover {
- color: #fff;
- cursor: pointer;
- text-decoration: none;
- }
- #sidebar #title {
- font-size: 150%;
- }
- #sidebar #title, #sidebar #title:hover, #sidebar #title a {
- color: #999;
- }
- #sidebar #storySubtitle {
- font-size: 75%;
- }
- #storyAuthor {
- font-size: 50%;
- }
- #sidebar #storyMenu {
- line-height: 2.5em;
- margin-bottom: .5em;
- color: #999;
- cursor: auto;
- }
- #sidebar #credits {
- padding-top: 2em;
- font-weight: normal;
- font-size: 80%;
- }
- #sidebar #credits:hover {
- color: #333;
- }
- #sidebar #credits a {
- text-decoration: none;
- }
- #passages {
- border-left: 1px solid #333;
- padding-left: 1.5em;
- }
- .menu {
- background-color: #343434;
- color: #fff;
- opacity: .9;
- border: 1px solid #fff;
- text-align: left;
- font: 1.1em Verdana;
- line-height: 2em;
- }
- .menu div {
- padding: 0 .4em;
- }
- .menu div:hover {
- cursor: pointer;
- background-color: #fff;
- color: #343434;
- }
- .passage {
- font-size: 1.2em;
- line-height: 175%;
- margin-bottom: 2em;
- text-align: left;
- }
- .passage a {
- font-weight: bold;
- text-decoration: none;
- }
- .passage a:hover {
- color: #8ea6ff;
- text-decoration: underline;
- }
- .content > ul {
- padding-top: 1.3em;
- }
- .passage ul, .passage ol {
- margin-left: .5em;
- padding-left: 1.5em;
- }
- .passage li {
- margin-right: 6em;
- }
- .passage table {
- border-collapse: collapse;
- font-size: 100%;
- margin: .8em 1.0em;
- }
- .passage th,.passage td,.passage tr,.passage caption {
- padding: 3px;
- }
- .passage hr {
- height: 1px;
- }
- .passage center {
- max-width:50%;
- margin:auto;
- }
- .marked {
- margin-right: 12px;
- padding: 3px;
- }
- .disabled {
- font-weight: bold;
- color: #333;
- }
- @media screen and (max-width: 640px) {
- body {
- margin: 5%;
- }
- #sidebar {
- width:100%;
- margin: 0;
- border-bottom: 1px solid #333;
- }
- #passages {
- padding-top: 2em;
- border-left: 0;
- }
- }
- </style>
- <style id="transitionCSS">
- .transition-in {
- opacity:0;
- position:absolute;
- }
- .passage:not(.transition-out) {
- transition: 1s;
- -webkit-transition: 1s;
- }
- .transition-out {
- opacity:0 !important;
- position:absolute;
- }
- </style>
- <style id="storyCSS"></style>
- <style id="tagCSS"></style>
- </head>
- <body>
- <div id="loadingbar"></div>
- <ul id="sidebar">
- <li id="title" class="storyElement"><span id="storyTitle" class="storyElement"></span><span id="storySubtitle" class="storyElement"></span><span id="titleSeparator"></span><span id="storyAuthor" class="storyElement"></span></li>
- <li id="storyMenu" class="storyElement" style="display:none"></li>
- </ul>
- <div id="snapbackMenu" class="menu"></div>
- <div id="passages">
- <noscript><div id="noscript">Please enable Javascript to play this story!</div></noscript>
- <style>
- #sidebar{display:none;}
- </style>
- </div>
- <div id="storeArea" data-size="11" hidden><div tiddler="StoryTitle" twine-position="0,0">a sandbox</div><div tiddler="StoryAuthor" twine-position="0,0">@modgethanc</div><div tiddler="StoryMenu" twine-position="0,0">[[inventory|inv]]</div><div tiddler="inv" tags="container" twine-position="0,0">you are carrying:\n<<print $inv.join(", ")>>\n\n<<back>></div><div tiddler="Start" twine-position="0,0"><<set $inv = []>>\nhey, you.\n\nlet's [[try something|1]]</div><div tiddler="1" tags="place" twine-position="0,0">under the fruit tree, there is a [[pile of objects]].\n\nif you want you can [[pick some fruit|passage()][$inv.push("a piece of fruit")]].</div><div tiddler="pile of objects" tags="container" twine-position="0,0">a pile of objects:\n<<set $item= "[[deck of cards]]">><<if $inv.indexOf($item) == -1>>* <<print $item>><<endif>>\s\n<<set $item= "[[lost keys]]">><<if $inv.indexOf($item) == -1>>* <<print $item>><<endif>>\s\n<<set $item= "[[crumpled bill]]">><<if $inv.indexOf($item) == -1>>* <<print $item>><<endif>>\s\n<<set $item= "[[broken watch]]">><<if $inv.indexOf($item) == -1>>* <<print $item>><<endif>>\s\n\n<<back>></div><div tiddler="deck of cards" tags="thing" twine-position="0,0"><<set $link = "[["+passage()+"]]">>\n''a deck of cards'', dog-eared and held together with a rubber band that's about to snap\n\n<<if previous() is "inv">><<back>><<else>> [[take it|previous()][$inv.push($link)]] or [[leave it|previous()]] <<endif>></div><div tiddler="lost keys" tags="thing" twine-position="0,0"><<set $link = "[["+passage()+"]]">>\n''a set of lost keys'', worn and shiny\n\n<<if previous() is "inv">><<back>><<else>> [[take it|previous()][$inv.push($link)]] or [[leave it|previous()]] <<endif>></div><div tiddler="crumpled bill" tags="thing" twine-position="0,0"><<set $link = "[["+passage()+"]]">>\n''some crumpled bills'', that might be enough to get you a cup of coffee\n\n<<if previous() is "inv">><<back>><<else>> [[take it|previous()][$inv.push($link)]] or [[leave it|previous()]] <<endif>></div><div tiddler="broken watch" tags="thing" twine-position="0,0"><<set $link = "[["+passage()+"]]">>\n''a broken watch'', that doesn't really tell you anything\n\n<<if previous() is "inv">><<back>><<else>> [[take it|previous()][$inv.push($link)]] or [[leave it|previous()]] <<endif>></div></div></body></html>
|