Your browser lacks required capabilities. Please upgrade it or switch to another to continue.
+
Loading…
+
+ <<set $allCards = {}>>
+
+<<set $allCards["Sugar1"] = {
+ precondition: 'false',
+ description: "Do you want to feed more sugar to your people?",
+ accept: "<<set $happiness = $happiness + 2>><<set $health = $health - 3>><<goto 'CoreLoop'>>",
+ acceptExplanation: "Sugar is bad for you.",
+ reject: "<<goto 'CoreLoop'>>",
+ rejectExplanation: "Sugar is bad for you.",
+}>>
+<<set $allCards["Sugar2"] = {
+ precondition: 'false',
+ description: "Do you want to feed more sugar to your people?",
+ accept: "<<set $happiness = $happiness + 2>><<set $health = $health - 3>><<goto 'CoreLoop'>>",
+ acceptExplanation: "Sugar is bad for you.",
+ reject: "<<goto 'CoreLoop'>>",
+ rejectExplanation: "Sugar is bad for you.",
+}>>
+<<set $allCards["Sugar3"] = {
+ precondition: 'false',
+ description: "Do you want to feed more sugar to your people?",
+ accept: "<<set $happiness = $happiness + 2>><<set $health = $health - 3>><<goto 'CoreLoop'>>",
+ acceptExplanation: "Sugar is bad for you.",
+ reject: "<<goto 'CoreLoop'>>",
+ rejectExplanation: "Sugar is bad for you.",
+}>>
+
+<<set $allEvents = Object.keys($allCards)>>
+
+<<set $cardArray = ['Sugar1']>>
+
+<<set $intelligence = 5>>
+<<set $health = 5>>
+<<set $happiness = 5>>
+
+<<set $explanation = 'undefined'>>
+<<set $cardName = 'undefined'>>Hello, Mr. Governor! You are the boss. Do stuff.
+
+Your population starts with 5 points in each category.
+
+<<link "Start Game" "CoreLoop">><</link>><<nobr>>
+ /* TODO: what to do if the available cards are empty? check a condition and win/lose? */
+
+ <<if $health <= 0 || $happiness <= 0 || $intelligence <= 0>>
+ <<goto 'GameOver'>>
+ <</if>>
+
+ <<if $allEvents.length === 0>>
+ <<goto 'Won'>>
+ <</if>>
+
+ <<if $explanation == 'undefined'>>
+ <<if $cardName != 'undefined'>>
+ <<set $allEvents.delete($cardName)>>
+ <</if>>
+
+ <<set $cardName = $cardArray.pluck()>> /* Pull a random card name from the deck. */
+
+ <<for eval($allCards[$cardName].precondition)>> /* Test the card. */
+ <<set $cardArray.push($cardName)>> /* Put the card back in the deck. */
+ <<set $cardName = $cardArray.pluck()>> /* Keep looking for a valid card. */
+ <</for>>
+ <</if>>
+
+ <<if $explanation != 'undefined'>>
+ <<set $cardArray.push($allEvents.random())>> /* Add a random event to the deck. */
+ <</if>>
+
+ <div>
+ <div class="flex flex-row justify-between bg-slate-100 px-4 py-2">
+ <div>INT: $intelligence/10</div>
+ <div>HEL: $health/10</div>
+ <div>HAP: $happiness/10</div>
+ </div>
+
+ <div class="p-8 rounded-xl border border-solid border-slate-500 shadow-xl bg-slate-200 mt-4 w-[300px] h-[400px] mx-auto flex flex-col justify-between">
+ <<if $explanation == 'undefined'>>
+ <div>
+ <<print $allCards[$cardName].description>>
+ </div>
+ <div class="flex flex-row justify-between">
+ <div class="text-green-600">
+ <<link "Accept">><<set $explanation = 'acceptExplanation'>><<run $.wiki($allCards[$cardName].accept)>><</link>>
+ </div>
+ <div class="text-red-600">
+ <<link "Reject">><<set $explanation = 'rejectExplanation'>><<run $.wiki($allCards[$cardName].reject)>><</link>>
+ </div>
+ </div>
+ <</if>>
+
+ <<if $explanation != 'undefined'>>
+ <div>
+ <<print $allCards[$cardName][$explanation]>>
+ </div>
+ <div class="flex flex-row justify-between">
+ <div>
+ </div>
+ <div class="text-green-600">
+ <<link "Next">><<set $explanation = 'undefined'>><<goto 'CoreLoop'>><</link>>
+ </div>
+ </div>
+ <</if>>
+ </div>
+ </div>
+<</nobr>>THE END!Congratulations, you won!
+
+
+
diff --git a/apps/card-game/example.twee b/apps/card-game/example.twee
new file mode 100644
index 00000000..c13681a1
--- /dev/null
+++ b/apps/card-game/example.twee
@@ -0,0 +1,148 @@
+:: StoryTitle
+Card Game Example
+
+
+:: StoryData
+{
+ "ifid": "61485CD7-104E-4035-BB96-6CBB1050405D",
+ "format": "SugarCube",
+ "format-version": "2.36.1",
+ "start": "Start"
+}
+
+
+:: UserScript [script]
+importScripts("https://cdn.tailwindcss.com");
+
+
+:: UserStylesheet [stylesheet]
+body {
+ background-color: white;
+ color: black;
+}
+
+
+:: StoryInit
+<>
+
+<><><>",
+ acceptExplanation: "Sugar is bad for you.",
+ reject: "<>",
+ rejectExplanation: "Sugar is bad for you.",
+}>>
+<><><>",
+ acceptExplanation: "Sugar is bad for you.",
+ reject: "<>",
+ rejectExplanation: "Sugar is bad for you.",
+}>>
+<><><>",
+ acceptExplanation: "Sugar is bad for you.",
+ reject: "<>",
+ rejectExplanation: "Sugar is bad for you.",
+}>>
+
+<>
+
+<>
+
+<>
+<>
+<>
+
+<>
+<>
+
+
+:: Start
+
+Hello, Mr. Governor! You are the boss. Do stuff.
+
+Your population starts with 5 points in each category.
+
+<><>
+
+
+:: CoreLoop
+<>
+ /* TODO: what to do if the available cards are empty? check a condition and win/lose? */
+
+ <>
+ <>
+ <>
+
+ <>
+ <>
+ <>
+
+ <>
+ <>
+ <>
+ <>
+
+ <> /* Pull a random card name from the deck. */
+
+ <> /* Test the card. */
+ <> /* Put the card back in the deck. */
+ <> /* Keep looking for a valid card. */
+ <>
+ <>
+
+ <>
+ <> /* Add a random event to the deck. */
+ <>
+
+
+
+
INT: $intelligence/10
+
HEL: $health/10
+
HAP: $happiness/10
+
+
+
+ <>
+
+ <>
+
+
+
+ <><><><>
+
+
+ <><><><>
+
+
+ <>
+
+ <>
+
+ <>
+
+
+
+
+
+ <><><><>
+
+
+ <>
+
+
+<>
+
+:: GameOver
+
+THE END!
+
+
+:: Won
+
+Congratulations, you won!
diff --git a/apps/card-game/storyformats/chapbook-1/LICENSE b/apps/card-game/storyformats/chapbook-1/LICENSE
new file mode 100644
index 00000000..f858fa1c
--- /dev/null
+++ b/apps/card-game/storyformats/chapbook-1/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2018-9 Chris Klimas
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/apps/card-game/storyformats/chapbook-1/format.js b/apps/card-game/storyformats/chapbook-1/format.js
new file mode 100644
index 00000000..fbe70d14
--- /dev/null
+++ b/apps/card-game/storyformats/chapbook-1/format.js
@@ -0,0 +1 @@
+window.storyFormat({"author":"Chris Klimas","description":"A Twine story format emphasizing ease of authoring, multimedia, and playability on many different types of devices.","image":"logo.svg","name":"Chapbook","proofing":false,"source":"{{STORY_NAME}}{{STORY_DATA}}","version":"1.0.0"});
\ No newline at end of file
diff --git a/apps/card-game/storyformats/chapbook-1/logo.svg b/apps/card-game/storyformats/chapbook-1/logo.svg
new file mode 100644
index 00000000..1c2dec32
--- /dev/null
+++ b/apps/card-game/storyformats/chapbook-1/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/card-game/storyformats/harlowe-1/format.js b/apps/card-game/storyformats/harlowe-1/format.js
new file mode 100644
index 00000000..c4d9e89f
--- /dev/null
+++ b/apps/card-game/storyformats/harlowe-1/format.js
@@ -0,0 +1 @@
+window.storyFormat({"name":"Harlowe","version":"1.2.4","author":"Leon Arnott","description":"The default story format for Twine 2. See its documentation.","image":"icon.svg","url":"http://twinery.org/","license":"Zlib","proofing":false,"source":"\n\n\n\n{{STORY_NAME}}\n\n\n\n\n\n\n\n{{STORY_DATA}}\n\n\n\n\n\n\n","setup": function(){"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t-1)||e.cannotFollow&&(-1!==e.cannotFollow.indexOf(n&&n.type)||e.cannotFollow.indexOf("text")>-1&&o)||e.peek&&e.peek!==t.slice(0,e.peek.length))}function o(e){for(var t=e.innerText,o=[],i=0,l=i,s=t.length,c=null;s>i;){for(var u=t.slice(i),p=(o.length?o[0]:e).innerMode,d=0,f=p.length;f>d;d+=1){var h=a[p[d]];if(n(h,u,c,i>l)&&h.pattern.test(u)){var m=h.pattern.exec(u),g=h.fn(m),k=!1,y=0;if(g.matches){for(;y-1&&(y=o.length-1)}if(y>=o.length&&!g.isFront)continue}i>l&&e.addChild({type:"text",text:t.slice(l,i),innerMode:p}),c=e.addChild(g),i+=c.text.length,l=i,k&&(r(e,c,o[y]),o=o.slice(y+1)),c.isFrontToken()&&o.unshift(c);break}}d===f&&(i+=1,null===c&&(c={type:"text"}))}for(i>l&&e.addChild({type:"text",text:t.slice(l,i),innerMode:(o.length?o[0]:e).innerMode});o.length>0;)o.shift().demote();return e}function r(e,n,o){var r=e.children.indexOf(n),i=e.children.indexOf(o);n.children=e.children.splice(i+1,r-(i+1)),n.children.forEach(function(e){t(n,e)}),n.type=n.matches[o.type],n.innerText="";for(var a=0,l=n.children.length;l>a;a++)n.innerText+=n.children[a].text;n.start=o.start,n.text=o.text+n.innerText+n.text,Object.keys(o).forEach(function(e){Object.hasOwnProperty.call(n,e)||(n[e]=o[e])}),n.isFront&&(n.isFront=!1),e.children.splice(i,1),t(e,n)}var i=void 0,a={};e.prototype={constructor:e,addChild:function(n){var r=this.lastChildEnd(),i=new e({start:r,end:n.text&&r+n.text.length,children:[]},n);return i.innerText&&o(i),this.children.push(i),t(this,i),i},lastChild:function(){return this.children?this.children[this.children.length-1]||null:null},lastChildEnd:function(){var e=this.lastChild();return e?e.end:this.start+Math.max(0,this.text.indexOf(this.innerText))},tokenAt:function(e){if(e=this.end)return null;if(this.childAt)return this.childAt[e]&&this.childAt[e].tokenAt(e)||this;if(this.children.length)for(var t=0;t=this.end)return[];if(this.childAt)return(this.childAt[e]&&this.childAt[e].pathAt(e)||[]).concat(this);var t=[];if(this.children.length)for(var n=0;n=this.end?null:this.children?this.children.reduce(function(t,n){return t||(e>=n.start&&e0&&(e+="["+this.children+"]"),e}},i={lex:function(t,n){return o(new e({type:"root",start:n||0,end:t.length,text:t,innerText:t,children:[],childAt:{},innerMode:i.startMode}))},rules:a},"object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports=i:"function"==typeof define&&define.amd?define("lexer",[],function(){return i}):this&&this.loaded?(this.modules||(this.modules={}),this.modules.Lexer=i):this.TwineLexer=i}).call(eval("this")||("undefined"!=typeof global?global:window)),function(){function e(t){return t&&"object"===("undefined"==typeof t?"undefined":_typeof(t))?(Object.keys(t).forEach(function(n){t[n]=e(t[n])}),t):(t+"").replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function t(){return"[^"+Array.apply(0,arguments).map(e).join("")+"]*"}function n(e){return function(){return"("+e+Array.apply(0,arguments).join("|")+")"}}var o=void 0,r=n("?:"),i=n("?!"),a=n("?="),l="[ \\f\\t\\v\xa0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]*",s=l.replace("*","+"),c="\\b",u="\\\\\\n\\\\?|\\n\\\\",p="\\n(?!\\\\)",d="[\\w\\-\xc0-\xde\xdf-\xff\u0150\u0170\u0151\u0171]",f="[\\w\xc0-\xde\xdf-\xff\u0150\u0170\u0151\u0171]",h=r("\\n","$"),m="("+r(u,"[^\\n]")+"+)",g="\\*",k=l+"("+g+"+)"+s+m+h,y="(?:0\\.)",b=l+"("+y+"+)"+s+m+h,v=l+"-{3,}"+l+h,x=l+"(#{1,6})"+l+m+h,w=l+"(==+>|<=+|=+><=+|<==+>)"+l+h,O={opener:"\\[\\[(?!\\[)",text:"("+t("]")+")",rightSeparator:r("\\->","\\|"),leftSeparator:"<\\-",closer:"\\]\\]",legacySeparator:"\\|",legacyText:"("+r("[^\\|\\]]","\\]"+i("\\]"))+"+)"},F=d.replace("\\-","")+"*"+d.replace("\\-","").replace("\\w","a-zA-Z")+d.replace("\\-","")+"*",A="\\$("+F+")",P="'s"+s+"("+F+")",T="("+F+")"+s+"of"+c+i("it"+c),C="'s"+s,L="of"+c,j=r("it","time")+c,S="its"+s+"("+F+")",M="its"+s,B="("+F+")"+s+"of"+s+"it"+c,E="of"+c+s+"it"+c,I={opener:"\\(",name:"("+r(d.replace("]","\\/]")+d+"*",A)+"):",closer:"\\)"},R="<<[^>\\s]+\\s*(?:\\\\.|'(?:[^'\\\\]*\\\\.)*[^'\\\\]*'|\"(?:[^\"\\\\]*\\\\.)*[^\"\\\\]*\"|[^'\"\\\\>]|>(?!>))*>>",_={name:"[a-zA-Z][\\w\\-]*",attrs:"(?:\"[^\"]*\"|'[^']*'|[^'\">])*?"},N="\\|("+d.replace("]","_]")+"*)>",q="<("+d.replace("]","_]")+"*)\\|",z="\\b(\\d+(?:\\.\\d+)?(?:[eE][+\\-]?\\d+)?|NaN)"+i("m?s")+"\\b";O.main=O.opener+r(O.text+O.rightSeparator,O.text.replace("*","*?")+O.leftSeparator)+O.text,o={upperLetter:"[A-Z\xc0-\xde\u0150\u0170]",lowerLetter:"[a-z0-9_\\-\xdf-\xff\u0151\u0171]",anyLetter:d,anyLetterStrict:f,whitespace:s,escapedLine:u,br:p,commentFront:"",tag:"<\\/?"+_.name+_.attrs+">",tagPeek:"<",scriptStyleTag:"<("+r("script","style")+")"+_.attrs+">[^]*?<\\/\\1>",scriptStyleTagOpener:"<",url:"("+r("https?","mailto","javascript","ftp","data")+":\\/\\/[^\\s<]+[^<.,:;\"')\\]\\s])",bullet:g,hr:v,heading:x,align:w,bulleted:k,numbered:b,delOpener:e("~~"),italicOpener:e("//"),boldOpener:e("''"),supOpener:e("^^"),strongFront:e("**"),strongBack:e("**"),emFront:e("*"),emBack:e("*"),verbatimOpener:"`+",collapsedFront:"{",collapsedBack:"}",hookAppendedFront:"\\[",hookPrependedFront:N+"\\[",hookAnonymousFront:"\\[",hookBack:"\\]"+i(q),hookAppendedBack:"\\]"+q,passageLink:O.main+O.closer,passageLinkPeek:"[[",legacyLink:O.opener+O.legacyText+O.legacySeparator+O.legacyText+O.closer,legacyLinkPeek:"[[",simpleLink:O.opener+O.legacyText+O.closer,simpleLinkPeek:"[[",macroFront:I.opener+a(I.name),macroFrontPeek:"(",macroName:I.name,groupingFront:"\\("+i(I.name),groupingFrontPeek:"(",groupingBack:"\\)",twine1Macro:R,twine1MacroPeek:"<<",property:P,propertyPeek:"'s",belongingProperty:T,possessiveOperator:C,belongingOperator:L,belongingOperatorPeek:"of",itsOperator:M,itsOperatorPeek:"its",belongingItOperator:E,belongingItOperatorPeek:"of",variable:A,variablePeek:"$",hookRef:"\\?("+d+"+)\\b",hookRefPeek:"?",cssTime:"(\\d+\\.?\\d*|\\d*\\.?\\d+)(m?s)"+c,colour:r(r("Red","Orange","Yellow","Lime","Green","Cyan","Aqua","Blue","Navy","Purple","Fuchsia","Magenta","White","Gray","Grey","Black"),"#[\\dA-Fa-f]{3}(?:[\\dA-Fa-f]{3})?"),number:z,boolean:r("true","false")+c,identifier:j,itsProperty:S,itsPropertyPeek:"its",belongingItProperty:B,escapedStringChar:"\\\\[^\\n]",singleStringOpener:"'",doubleStringOpener:'"',is:"is"+i(" not"," in")+c,isNot:"is not"+c,and:"and"+c,or:"or"+c,not:"not"+c,inequality:r("<(?!=)","<=",">(?!=)",">="),isIn:"is in"+c,contains:"contains"+c,addition:e("+")+i("="),subtraction:e("-")+i("="),multiplication:e("*")+i("="),division:r("/","%")+i("="),comma:",",spread:"\\.\\.\\."+i("\\."),to:r("to"+c,"="),into:"into"+c,augmentedAssign:r("\\+","\\-","\\*","\\/","%")+"="},"object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports=o:"function"==typeof define&&define.amd?define("patterns",[],function(){return o}):this&&this.loaded?(this.modules||(this.modules={}),this.modules.Patterns=o):this.Patterns=o}.call(eval("this")||("undefined"!=typeof global?global:window)),function(){function e(e){function t(e){return e=e||"innerText",function(t){var n=t.reduceRight(function(e,t,n){return e||(n?t:"")},""),o={};return o[e]=n,o}}function o(e,t){var n={};return n[e]=t,function(){return{isFront:!0,matches:n,cannotCross:["verbatimOpener"]}}}function r(e,t){return Object.keys(t).forEach(function(n){var o=t[n].fn;t[n].fn=function(t){var r=o(t);return r.text||(r.text=t[0]),r.type||(r.type=n),r.innerMode||(r.innerMode=e),r}}),t}var i=Object.bind(0,null),a=[],l=[],s=r(a,{hr:{fn:i},bulleted:{fn:function(e){return{depth:e[1].length,innerText:e[2]}}},numbered:{fn:function(e){return{depth:e[1].length/2,innerText:e[2]}}},heading:{fn:function(e){return{depth:e[1].length,innerText:e[2]}}},align:{fn:function(e){var t=void 0,n=e[1],o=n.indexOf("><");return~o?(t=Math.round(o/(n.length-2)*50),25===t&&(t="center")):"<"===n[0]&&">"===n.slice(-1)?t="justify":n.indexOf(">")>-1?t="right":n.indexOf("<")>-1&&(t="left"),{align:t}}}});Object.keys(s).forEach(function(e){s[e].canFollow=[null,"br","hr","bulleted","numbered","heading","align"],s[e].cannotFollow=["text"]});var c=r(a,{twine1Macro:{fn:function(){return{type:"error",message:"Harlowe macros use a different syntax to Twine 1 and SugarCube macros."}}},br:{fn:i},emBack:{fn:function(){return{matches:{emFront:"em"},cannotCross:["verbatimOpener"]}}},strongBack:{fn:function(){return{matches:{strongFront:"strong"},cannotCross:["verbatimOpener"]}}},strongFront:{fn:function(){return{isFront:!0}}},emFront:{fn:function(){return{isFront:!0}}},boldOpener:{fn:o("boldOpener","bold")},italicOpener:{fn:o("italicOpener","italic")},delOpener:{fn:o("delOpener","del")},supOpener:{fn:o("supOpener","sup")},commentFront:{fn:function(){return{isFront:!0}}},commentBack:{fn:function(){return{matches:{commentFront:"comment"}}}},scriptStyleTag:{fn:i},tag:{fn:i},url:{fn:i},passageLink:{fn:function(e){var t=e[1],n=e[2],o=e[3];return{type:"twineLink",innerText:n?o:t,passage:t?o:n}}},simpleLink:{fn:function(e){return{type:"twineLink",innerText:e[1],passage:e[1]}}},hookPrependedFront:{fn:function(e){return{name:e[1],isFront:!0,tagPosition:"prepended"}}},hookAnonymousFront:{fn:function(){return{isFront:!0,demote:function(){this.error("This tagged hook doesn't have a matching ].")}}},canFollow:["macro","variable"]},hookAppendedFront:{fn:function(){return{isFront:!0}},cannotFollow:["macro","variable"]},hookBack:{fn:function(){return{type:"hookAppendedBack",matches:{hookPrependedFront:"hook",hookAnonymousFront:"hook"},cannotCross:["verbatimOpener"]}}},hookAppendedBack:{fn:function(e){return{name:e[1],tagPosition:"appended",matches:{hookAppendedFront:"hook"},cannotCross:["verbatimOpener"]}}},verbatimOpener:{fn:function(e){var t=e[0].length,n={};return n["verbatim"+t]="verbatim",{type:"verbatim"+t,isFront:!0,matches:n}}},collapsedFront:{fn:function(){return{isFront:!0}}},collapsedBack:{fn:function(){return{matches:{collapsedFront:"collapsed"},cannotCross:["verbatimOpener"]}}},escapedLine:{fn:i},legacyLink:{fn:function(e){return{type:"twineLink",innerText:e[1],passage:e[2]}}}}),u=r(l,{macroFront:{fn:function(e){return{isFront:!0,name:e[1]}}},groupingBack:{fn:function(){return{matches:{groupingFront:"grouping",macroFront:"macro"},cannotCross:["singleStringOpener","doubleStringOpener"]}}},hookRef:{fn:t("name")},variable:{fn:t("name")},whitespace:{fn:i,cannotFollow:"text"}}),p=r(l,Object.assign({macroName:{canFollow:["macroFront"],fn:function(e){return e[2]?{isMethodCall:!0,innerText:e[2]}:{isMethodCall:!1}}},groupingFront:{fn:function(){return{isFront:!0}}},property:{fn:t("name"),canFollow:["variable","hookRef","property","itsProperty","belongingItProperty","macro","grouping","string","boolean","number"]},possessiveOperator:{fn:i},itsProperty:{cannotFollow:["text"],fn:t("name")},itsOperator:{cannotFollow:["text"],fn:i},belongingItProperty:{cannotFollow:["text"],fn:t("name")},belongingItOperator:{cannotFollow:["text"],fn:i},belongingProperty:{cannotFollow:["text"],fn:t("name")},belongingOperator:{cannotFollow:["text"],fn:i},escapedStringChar:{fn:function(){return{type:"text"}}},singleStringOpener:{fn:function(){return{isFront:!0,matches:{singleStringOpener:"string"}}}},doubleStringOpener:{fn:function(){return{isFront:!0,matches:{doubleStringOpener:"string"}}}},cssTime:{fn:function(e){return{value:+e[1]*("s"===e[2].toLowerCase()?1e3:1)}}},colour:{cannotFollow:["text"],fn:function(e){var t,n=e[0].toLowerCase(),o={red:"e61919",orange:"e68019",yellow:"e5e619",lime:"80e619",green:"19e619",cyan:"19e5e6",aqua:"19e5e6",blue:"197fe6",navy:"1919e6",purple:"7f19e6",fuchsia:"e619e5",magenta:"e619e5",white:"fff",black:"000",gray:"888",grey:"888"};return t=Object.hasOwnProperty.call(o,n)?"#"+o[n]:n,{colour:t}}},number:{fn:function(e){return{value:parseFloat(e[0])}}},addition:{fn:i},subtraction:{fn:i},multiplication:{fn:i},division:{fn:i},inequality:{fn:function(e){return{operator:e[0]}}},augmentedAssign:{fn:function(e){return{operator:e[0][0]}}},identifier:{fn:t("name"),cannotFollow:["text"]}},["boolean","is","to","into","and","or","not","isNot","contains","isIn"].reduce(function(e,t){return e[t]={fn:i,cannotFollow:["text"]},e},{}),["comma","spread","addition","subtraction","multiplication","division"].reduce(function(e,t){return e[t]={fn:i},e},{})));a.push.apply(a,_toConsumableArray(Object.keys(s)).concat(_toConsumableArray(Object.keys(c)),_toConsumableArray(Object.keys(u)))),l.push.apply(l,_toConsumableArray(Object.keys(u)).concat(_toConsumableArray(Object.keys(p))));var d=Object.assign({},s,c,u,p);return Object.keys(d).forEach(function(e){var t=n[e];d[e].pattern="string"!=typeof t?t:new RegExp("^(?:"+t+")","i"),n[e+"Peek"]&&(d[e].peek=n[e+"Peek"])}),Object.assign(e.rules,d),e.startMode=a,e}function t(t){var o=Object.freeze({lex:e(t).lex,Patterns:n});return o}var n=void 0;Object.assign=Object.assign||function(e){for(var t=1;tHTML tags
are available.","To display special symbols without them being transformed, put them between `backticks`.","To link to another passage, write the link text and the passage name like this: [[link text->passage name]]\nor this: [[passage name<-link text]]\nor this: [[link text]].","Macros like (set:) and (display:) are the programming of your passage. If you've (set:) a $variable, you can just enter its name to print it out.","To make a 'hook', put [single square brackets] around text - or leave it empty [] - then put a macro like (if:), a $variable, or a |nametag> outside the front, |like>[so].","Hooks can be used for many things: showing text (if:) something happened, applying a (text-style:), making a place to (append:) text later on, and much more!","Consult the Harlowe documentation for more information."].join("\n\n"))),{pos:0}},blankLine:function(e){e.pos++},token:function(n,o){c&&c();var r=a.pathAt(o.pos),i=r[0];if(!i)return o.pos++,n.next(),null;for(;i===i.tokenAt(o.pos)&&!n.eol();)o.pos++,n.next();n.eol()&&o.pos++;for(var l={},s="",u=0;u1&&(d+="-"+l[d]),p){case"macroName":-1===t.indexOf(e(r[u].text.slice(0,-1)))&&(d+=" harlowe-1-error")}s+=d+" "}return s}}});var o=document.querySelector("style#cm-harlowe-1");o||(o=document.createElement("style"),o.setAttribute("id","cm-harlowe-1"),document.head.appendChild(o)),o.innerHTML=function(){function e(e,t,n){return function(o){return"background-color: hsla("+e+","+t+"%,"+n+"%,"+o+");"}}var t=e(40,100,50),n=e(220,100,50),o=function(t){return e(320,44,50)(t)+"color: #a84186;"},r="color: firebrick !important; background-color: hsla(17, 100%, 74%, 0.74) !important;",i="font-weight:100; color: hsla(0,0,0,0.5)";return{root:"box-sizing:border-box;",cursor:"border-bottom: 2px solid darkgray;",hook:t(.05),"hook-2":t(.1),"hook-3":t(.15),"hook-4":t(.2),"hook-5":t(.25),"hook-6":t(.3),"hook-7":t(.35),"hook-8":t(.4),"^=hook , ^=hook-":"font-weight:bold;",error:r,macro:o(.05),"macro-2":o(.1),"macro-3":o(.15),"macro-4":o(.2),"macro-5":o(.25),"macro-6":o(.3),"macro-7":o(.35),"macro-8":o(.4),macroName:"font-style:italic;","^=macro ":"font-weight:bold;","bold, strong":"font-weight:bold;","italic, em":"font-style:italic;",sup:"vertical-align: super;font-size:0.8em;",verbatim:"background-color: hsla(0,0%,50%,0.1);","^=bold, ^=strong, ^=italic, ^=em, ^=sup, ^=verbatim":i,"^=collapsed":"font-weight:bold; color: hsl(201, 100%, 30%);",collapsed:n(.025),"collapsed.hook":n(.05),"collapsed.hook-2":n(.1),"collapsed.hook-3":n(.15),"collapsed.hook-4":n(.2),"collapsed.hook-5":n(.25),"collapsed.hook-6":n(.3),"collapsed.hook-7":n(.35),"collapsed.hook-8":n(.4),"twineLink:not(.text)":"color: #3333cc;",tag:"color: #4d4d9d;",boolean:"color: #626262;",string:"color: #008282;",number:"color: #A15000;",variable:"color: #005682;",hookRef:"color: #007f54;","variableOccurrence, hookOccurrence":"background: #7fffd4 !important;",heading:"font-weight:bold;",hr:"display:block; background-image: linear-gradient(0deg, transparent, transparent 45%, silver 45%, transparent 55%, transparent);",align:"display:block; color: hsl(14, 99%, 27%); background-color: hsla(14, 99%, 87%, 0.2);",escapedLine:"font-weight:bold; color: hsl(51, 100%, 30%);","identifier, property, belongingProperty, itsProperty, belongingItProperty, belongingItOperator":"color: #0076b2;",toString:function(){var e=this;return Object.keys(this).reduce(function(t,n){var o;return"toString"===n?t:(o=n.split(", ").map(function e(t){return t.indexOf(".")>-1?t.split(/\./g).map(e).join(""):0===t.indexOf("^=")?"[class^='cm-harlowe-1-"+t.slice(2)+"']":".cm-harlowe-1-"+t}),t+o.join(", ")+"{"+e[n]+"}")},"")}}+""}()}.call(eval("this"));}});
diff --git a/apps/card-game/storyformats/harlowe-1/icon.svg b/apps/card-game/storyformats/harlowe-1/icon.svg
new file mode 100644
index 00000000..cbad8781
--- /dev/null
+++ b/apps/card-game/storyformats/harlowe-1/icon.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/apps/card-game/storyformats/harlowe-2/format.js b/apps/card-game/storyformats/harlowe-2/format.js
new file mode 100644
index 00000000..10cf167b
--- /dev/null
+++ b/apps/card-game/storyformats/harlowe-2/format.js
@@ -0,0 +1,2 @@
+window.storyFormat({"name":"Harlowe","version":"2.1.0","author":"Leon Arnott","description":"The default story format for Twine 2. See its documentation.","image":"icon.svg","url":"http://twinery.org/","license":"Zlib","proofing":false,"source":"\n\n\n\n{{STORY_NAME}}\n\n\n\n\n\n\n\n{{STORY_DATA}}\n\n\n\n\n\n\n","setup": function(){"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var r=0,n=Array(e.length);r-1)||e.cannotFollow&&(-1!==e.cannotFollow.indexOf(n&&n.type)||e.cannotFollow.indexOf("text")>-1&&t)||e.peek&&e.peek.toLowerCase()!==r.slice(0,e.peek.length).toLowerCase())}function t(e){for(var r=e.innerText,t=[],o=0,s=o,u=r.length,l=null;u>o;){for(var m=r.slice(o),c=(t.length?t[0]:e).innerMode,g=0,p=c.length;p>g;g+=1){var d=i[c[g]];if(n(d,m,l,o>s)&&d.pattern.test(m)){var h=d.pattern.exec(m),f=d.fn(h),y=!1,k=0;if(f.matches){for(;k-1&&(k=t.length-1)}if(k>=t.length&&!f.isFront)continue}o>s&&e.addChild({type:"text",text:r.slice(s,o),innerMode:c}),l=e.addChild(f),o+=l.text.length,s=o,y&&(a(e,l,t[k]),t=t.slice(k+1)),l.isFrontToken()&&t.unshift(l);break}}g===p&&(o+=1,null===l&&(l={type:"text"}))}for(o>s&&e.addChild({type:"text",text:r.slice(s,o),innerMode:(t.length?t[0]:e).innerMode});t.length>0;)t.shift().demote();return e}function a(e,n,t){var a=e.children.indexOf(n),o=e.children.indexOf(t);n.children=e.children.splice(o+1,a-(o+1)),n.children.forEach(function(e){r(n,e)}),n.type=n.matches[t.type],n.innerText="";for(var i=0,s=n.children.length;s>i;i++)n.innerText+=n.children[i].text;n.start=t.start,n.text=t.text+n.innerText+n.text,Object.keys(t).forEach(function(e){Object.hasOwnProperty.call(n,e)||(n[e]=t[e])}),n.isFront&&(n.isFront=!1),e.children.splice(o,1),r(e,n)}var o=void 0,i={};e.prototype={constructor:e,addChild:function(n){var a=this.lastChildEnd(),o=new e({start:a,end:n.text&&a+n.text.length,children:[]},n);return o.innerText&&t(o),this.children.push(o),r(this,o),o},lastChild:function(){return this.children?this.children[this.children.length-1]||null:null},lastChildEnd:function(){var e=this.lastChild();return e?e.end:this.start+Math.max(0,this.text.indexOf(this.innerText))},tokenAt:function(e){if(e=this.end)return null;if(this.childAt)return this.childAt[e]&&this.childAt[e].tokenAt(e)||this;if(this.children.length)for(var r=0;r=this.end)return[];if(this.childAt)return(this.childAt[e]&&this.childAt[e].pathAt(e)||[]).concat(this);var r=[];if(this.children.length)for(var n=0;n=this.end?null:this.children?this.children.reduce(function(r,n){return r||(e>=n.start&&e0&&(e+="["+this.children+"]"),e}},o={lex:function(r,n){return t(new e({type:"root",start:n||0,end:r.length,text:r,innerText:r,children:[],childAt:{},innerMode:o.modes.start}))},rules:i,modes:{}},"object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports=o:"function"==typeof define&&define.amd?define("lexer",[],function(){return o}):this&&this.loaded?(this.modules||(this.modules={}),this.modules.Lexer=o):this.TwineLexer=o}).call(eval("this")||("undefined"!=typeof global?global:window)),function(){function e(r){return r&&"object"===("undefined"==typeof r?"undefined":_typeof(r))?(Object.keys(r).forEach(function(n){r[n]=e(r[n])}),r):(r+"").replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function r(){return"[^"+Array.apply(0,arguments).map(e).join("")+"]*"}function n(e){return function(){return"("+e+Array.apply(0,arguments).join("|")+")"}}var t=void 0,a=n("?:"),o=n("?!"),i=n("?="),s="[ \\f\\t\\v\\u00a0\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000]*",u=s.replace("*","+"),l="\\b",m="\\\\\\n\\\\?|\\n\\\\",c="\\n(?!\\\\)",g="[\\w\\-\\u00c0-\\u00de\\u00df-\\u00ff\\u0150\\u0170\\u0151\\u0171\\uD800-\\uDFFF]",p=g.replace("\\-",""),d=a("\\n","$"),h="("+a(m,"[^\\n]")+"+)",f="\\*",y=s+"("+f+"+)"+u+h+d,k="(?:0\\.)",b=s+"("+k+"+)"+u+h+d,N=s+"-{3,}"+s+d,C=s+"(#{1,6})"+s+h+d,T=s+"(==+>|<=+|=+><=+|<==+>)"+s+d,S=s+"(=+\\|+|\\|+=+|=+\\|+=+|\\|=+\\|)"+s+d,v={opener:"\\[\\[(?!\\[)",text:"("+r("]")+")",rightSeparator:a("\\->","\\|"),leftSeparator:"<\\-",closer:"\\]\\]",legacySeparator:"\\|",legacyText:"("+a("[^\\|\\]]","\\]"+o("\\]"))+"+)"},x=p+"*"+p.replace("\\w","a-zA-Z")+p+"*",A="\\$("+x+")",w="'s"+u+"("+x+")",O="("+x+")"+u+"of"+l+o("it"+l),F="'s"+u,L="of"+l,P=a("it","time")+l,H="its"+u+"("+x+")",j="its"+u,B="("+x+")"+u+"of"+u+"it"+l,M="of"+l+u+"it"+l,V={opener:"\\(",name:"("+a(g+"+",A)+"):"+o("\\/"),closer:"\\)"},I="<<[^>\\s]+\\s*(?:\\\\.|'(?:[^'\\\\]*\\\\.)*[^'\\\\]*'|\"(?:[^\"\\\\]*\\\\.)*[^\"\\\\]*\"|[^'\"\\\\>]|>(?!>))*>>",D=a("=<","=>","[gl]te?"+l,"n?eq"+l,"isnot"+l,"are"+l,"x"+l),E={name:"[a-zA-Z][\\w\\-]*",attrs:"(?:\"[^\"]*\"|'[^']*'|[^'\">])*?"},_="\\|("+g+"+)(>|\\))",R="(<|\\()("+g+"+)\\|",q="_("+x+")"+l,$="\\b(\\d+(?:\\.\\d+)?(?:[eE][+\\-]?\\d+)?)"+o("m?s")+l;v.main=v.opener+a(v.text+v.rightSeparator,v.text.replace("*","*?")+v.leftSeparator)+v.text,t={upperLetter:"[A-Z\\u00c0-\\u00de\\u0150\\u0170]",lowerLetter:"[a-z0-9_\\-\\u00df-\\u00ff\\u0151\\u0171]",anyLetter:g,anyLetterStrict:p,whitespace:u,escapedLine:m,br:c,commentFront:"",tag:"<\\/?"+E.name+E.attrs+">",tagPeek:"<",scriptStyleTag:"<("+a("script","style")+")"+E.attrs+">[^]*?<\\/\\1>",scriptStyleTagOpener:"<",url:"("+a("https?","mailto","javascript","ftp","data")+":\\/\\/[^\\s<]+[^<.,:;\"')\\]\\s])",bullet:f,hr:N,heading:C,align:T,column:S,bulleted:y,numbered:b,strikeOpener:e("~~"),italicOpener:e("//"),boldOpener:e("''"),supOpener:e("^^"),strongFront:e("**"),strongBack:e("**"),emFront:e("*"),emBack:e("*"),verbatimOpener:"`+",collapsedFront:"{",collapsedBack:"}",hookAppendedFront:"\\[",hookPrependedFront:_+"\\[",hookFront:"\\[",hookBack:"\\]"+o(R),hookAppendedBack:"\\]"+R,passageLink:v.main+v.closer,passageLinkPeek:"[[",legacyLink:v.opener+v.legacyText+v.legacySeparator+v.legacyText+v.closer,legacyLinkPeek:"[[",simpleLink:v.opener+v.legacyText+v.closer,simpleLinkPeek:"[[",macroFront:V.opener+i(V.name),macroFrontPeek:"(",macroName:V.name,groupingFront:"\\("+o(V.name),groupingFrontPeek:"(",groupingBack:"\\)",twine1Macro:I,twine1MacroPeek:"<<",property:w,propertyPeek:"'s",belongingProperty:O,possessiveOperator:F,belongingOperator:L,belongingOperatorPeek:"of",itsOperator:j,itsOperatorPeek:"its",belongingItOperator:M,belongingItOperatorPeek:"of",variable:A,variablePeek:"$",tempVariable:q,tempVariablePeek:"_",hookRef:"\\?("+g+"+)\\b",hookRefPeek:"?",cssTime:"(\\d+\\.?\\d*|\\d*\\.?\\d+)(m?s)"+l,colour:a(a("Red","Orange","Yellow","Lime","Green","Cyan","Aqua","Blue","Navy","Purple","Fuchsia","Magenta","White","Gray","Grey","Black"),"#[\\dA-Fa-f]{3}(?:[\\dA-Fa-f]{3})?"),number:$,boolean:a("true","false")+l,identifier:P,itsProperty:H,itsPropertyPeek:"its",belongingItProperty:B,escapedStringChar:"\\\\[^\\n]",singleStringOpener:"'",doubleStringOpener:'"',is:"is"+o(u+"not",u+"in",u+"<",u+">")+l,isNot:"is"+u+"not"+l,and:"and"+l,or:"or"+l,not:"not"+l,inequality:"((?:is(?:"+u+"not)?"+s+")*)("+a("<(?!=)","<=",">(?!=)",">=")+")",isIn:"is"+u+"in"+l,contains:"contains"+l,addition:e("+")+o("="),subtraction:e("-")+o("="),multiplication:e("*")+o("="),division:a("/","%")+o("="),comma:",",spread:"\\.\\.\\."+o("\\."),to:a("to"+l,"="),into:"into"+l,making:"making"+l,where:"where"+l,via:"via"+l,with:"with"+l,each:"each"+l,augmentedAssign:a("\\+","\\-","\\*","\\/","%")+"=",incorrectOperator:D},"object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports=t:"function"==typeof define&&define.amd?define("patterns",[],function(){return t}):this&&this.loaded?(this.modules||(this.modules={}),this.modules.Patterns=t):this.Patterns=t}.call(eval("this")||("undefined"!=typeof global?global:window)),function(){function e(e){function r(e){return e=e||"innerText",function(r){var n=r.reduceRight(function(e,r,n){return e||(n?r:"")},""),t={};return t[e]=n,t}}function t(e,r){var n={};return n[e]=r,function(){return{isFront:!0,matches:n,cannotCross:["verbatimOpener"]}}}function a(e,r){return Object.keys(r).forEach(function(n){var t=r[n].fn;r[n].fn=function(r){var a=t(r);return a.text||(a.text=r[0]),a.type||(a.type=n),a.innerMode||(a.innerMode=e),a}}),r}var o=Object.bind(0,null),i=[],s=[],u=a(i,{hr:{fn:o},bulleted:{fn:function(e){return{depth:e[1].length,innerText:e[2]}}},numbered:{fn:function(e){return{depth:e[1].length/2,innerText:e[2]}}},heading:{fn:function(e){return{depth:e[1].length,innerText:e[2]}}},align:{fn:function(e){var r=void 0,n=e[1],t=n.indexOf("><");return~t?(r=Math.round(t/(n.length-2)*50),25===r&&(r="center")):"<"===n[0]&&">"===n.slice(-1)?r="justify":n.indexOf(">")>-1?r="right":n.indexOf("<")>-1&&(r="left"),{align:r}}},column:{fn:function(e){var r=void 0,n=e[1],t=n.indexOf("|");return t&&t-1}}},augmentedAssign:{fn:function(e){return{operator:e[0][0]}}},identifier:{fn:r("name"),cannotFollow:["text"]},whitespace:{fn:o,cannotFollow:"text"},incorrectOperator:{fn:function(e){var r={"=>":">=","=<":"<=",gte:">=",lte:"<=",gt:">",lt:"<",eq:"is",isnot:"is not",neq:"is not",are:"is",x:"*"}[e[0].toLowerCase()];return{type:"error",message:"Please say "+(r?"'"+r+"'":"something else")+" instead of '"+e[0]+"'."}},cannotFollow:"text"}},["boolean","is","to","into","where","via","with","making","each","and","or","not","isNot","contains","isIn"].reduce(function(e,r){return e[r]={fn:o,cannotFollow:["text"]},e},{}),["comma","spread","addition","subtraction","multiplication","division"].reduce(function(e,r){return e[r]={fn:o},e},{})));i.push.apply(i,_toConsumableArray(Object.keys(u)).concat(_toConsumableArray(Object.keys(m)),_toConsumableArray(Object.keys(l)))),s.push.apply(s,_toConsumableArray(Object.keys(m)).concat(_toConsumableArray(Object.keys(c))));var g=Object.assign({},u,l,m,c);return Object.keys(g).forEach(function(e){var r=n[e];g[e].pattern="string"!=typeof r?r:new RegExp("^(?:"+r+")","i"),n[e+"Peek"]&&(g[e].peek=n[e+"Peek"])}),Object.assign(e.rules,g),e.modes.start=e.modes.markup=i,e.modes.macro=s,e}function r(r){return Object.freeze({lex:e(r).lex,Patterns:n})}var n=void 0;Object.assign=Object.assign||function(e){for(var r=1;r Command":{name:"display",sig:" String",returnType:"Command",aka:[]},"(print: Any) -> Command":{name:"print",sig:" Any",returnType:"Command",aka:[]},"(show: ...HookName) -> Command":{name:"show",sig:" ...HookName",returnType:"Command",aka:[]},"(go-to: String) -> Command":{name:"go-to",sig:" String",returnType:"Command",aka:[]},"(undo:) -> Command":{name:"undo",sig:"",returnType:"Command",aka:[]},"(live: [Number]) -> Changer":{name:"live",sig:" [Number]",returnType:"Changer",aka:[]},"(stop:) -> Command":{name:"stop",sig:"",returnType:"Command",aka:[]},"(save-game: String, [String]) -> Boolean":{name:"save-game",sig:" String, [String]",returnType:"Boolean",aka:[]},"(load-game: String) -> Command":{name:"load-game",sig:" String",returnType:"Command",aka:[]},"(alert: String) -> Command":{name:"alert",sig:" String",returnType:"Command",aka:[]},"(prompt: String, String) -> String":{name:"prompt",sig:" String, String",returnType:"String",aka:[]},"(confirm: String) -> Boolean":{name:"confirm",sig:" String",returnType:"Boolean",aka:[]},"(open-url: String) -> Command":{name:"open-url",sig:" String",returnType:"Command",aka:[]},"(reload:) -> Command":{name:"reload",sig:"",returnType:"Command",aka:[]},"(goto-url: String) -> Command":{name:"goto-url",sig:" String",returnType:"Command",aka:[]},"(page-url:) -> String":{name:"page-url",sig:"",returnType:"String",aka:[]},"(set: ...VariableToValue) -> Instant":{name:"set",sig:" ...VariableToValue",returnType:"Instant",aka:[]},"(put: ...VariableToValue) -> Instant":{name:"put",sig:" ...VariableToValue",returnType:"Instant",aka:[]},"(move: ...VariableToValue) -> Instant":{name:"move",sig:" ...VariableToValue",returnType:"Instant",aka:[]},"(a: [...Any]) -> Array":{name:"a",sig:" [...Any]",returnType:"Array",aka:[]},"(range: Number, Number) -> Array":{name:"range",sig:" Number, Number",returnType:"Array",aka:[]},"(subarray: Array, Number, Number) -> Array":{name:"subarray",sig:" Array, Number, Number",returnType:"Array",aka:[]},"(shuffled: Any, Any, [...Any]) -> Array":{name:"shuffled",sig:" Any, Any, [...Any]",returnType:"Array",aka:[]},"(sorted: Number or String, ...Number or String) -> Array":{name:"sorted",sig:" Number or String, ...Number or String",returnType:"Array",aka:[]},"(rotated: Number, [...Any]) -> Array":{name:"rotated",sig:" Number, [...Any]",returnType:"Array",aka:[]},"(repeated: Number, ...Any) -> Array":{name:"repeated",sig:" Number, ...Any",returnType:"Array",aka:[]},"(interlaced: Array, ...Array) -> Array":{name:"interlaced",sig:" Array, ...Array",returnType:"Array",aka:[]},"(altered: Lambda, ...Any) -> Array":{name:"altered",sig:" Lambda, ...Any",returnType:"Array",aka:[]},"(find: Lambda, ...Any) -> Array":{name:"find",sig:" Lambda, ...Any",returnType:"Array",aka:[]},"(all-pass: Lambda, ...Any) -> Boolean":{name:"all-pass",sig:" Lambda, ...Any",returnType:"Boolean",aka:[]},"(some-pass: Lambda, ...Any) -> Boolean":{name:"some-pass",sig:" Lambda, ...Any",returnType:"Boolean",aka:[]},"(none-pass: Lambda, ...Any) -> Boolean":{name:"none-pass",sig:" Lambda, ...Any",returnType:"Boolean",aka:[]},"(folded: Lambda, ...Any) -> Any":{name:"folded",sig:" Lambda, ...Any",returnType:"Any",aka:[]},"(datanames: Datamap) -> Array":{name:"datanames",sig:" Datamap",returnType:"Array",aka:[]},"(datavalues: Datamap) -> Array":{name:"datavalues",sig:" Datamap",returnType:"Array",aka:[]},"(dataentries: Datamap) -> Array":{name:"dataentries",sig:" Datamap",returnType:"Array",aka:[]},"(history:) -> Array":{name:"history",sig:"",returnType:"Array",aka:[]},"(passage: [String]) -> Datamap":{name:"passage",sig:" [String]",returnType:"Datamap",aka:[]},"(saved-games:) -> Datamap":{name:"saved-games",sig:"",returnType:"Datamap",aka:[]},"(dm: [...Any]) -> Datamap":{name:"dm",sig:" [...Any]",returnType:"Datamap",aka:[]},"(ds: [...Any]) -> Dataset":{name:"ds",sig:" [...Any]",returnType:"Dataset",aka:[]},"(count: Array or String, ...Any) -> Number":{name:"count",sig:" Array or String, ...Any",returnType:"Number",aka:[]},"(enchant: HookName or String, Changer) -> Command":{name:"enchant",sig:" HookName or String, Changer",returnType:"Command",aka:[]},"(replace: ...HookName or String) -> Changer":{name:"replace",sig:" ...HookName or String",returnType:"Changer",aka:[]},"(append: ...HookName or String) -> Changer":{name:"append",sig:" ...HookName or String",returnType:"Changer",aka:[]},"(prepend: ...HookName or String) -> Changer":{name:"prepend",sig:" ...HookName or String",returnType:"Changer",aka:[]},"(click: HookName or String) -> Changer":{name:"click",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseover: HookName or String) -> Changer":{name:"mouseover",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseout: HookName or String) -> Changer":{name:"mouseout",sig:" HookName or String",returnType:"Changer",aka:[]},"(click-replace: HookName or String) -> Changer":{name:"click-replace",sig:" HookName or String",returnType:"Changer",aka:[]},"(click-append: HookName or String) -> Changer":{name:"click-append",sig:" HookName or String",returnType:"Changer",aka:[]},"(click-prepend: HookName or String) -> Changer":{name:"click-prepend",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseover-replace: HookName or String) -> Changer":{name:"mouseover-replace",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseover-append: HookName or String) -> Changer":{name:"mouseover-append",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseover-prepend: HookName or String) -> Changer":{name:"mouseover-prepend",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseout-replace: HookName or String) -> Changer":{name:"mouseout-replace",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseout-append: HookName or String) -> Changer":{name:"mouseout-append",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseout-prepend: HookName or String) -> Changer":{name:"mouseout-prepend",sig:" HookName or String",returnType:"Changer",aka:[]},"(link: String) -> Changer":{name:"link",sig:" String",returnType:"Changer",aka:[]},"(link-reveal: String) -> Changer":{name:"link-reveal",sig:" String",returnType:"Changer",aka:[]},"(link-repeat: String) -> Changer":{name:"link-repeat",sig:" String",returnType:"Changer",aka:[]},"(link-goto: String, [String]) -> Command":{name:"link-goto",sig:" String, [String]",returnType:"Command",aka:[]},"(link-undo: String) -> Command":{name:"link-undo",sig:" String",returnType:"Command",aka:[]},"(if: Boolean) -> Changer":{name:"if",sig:" Boolean",returnType:"Changer",aka:[]},"(unless: Boolean) -> Changer":{name:"unless",sig:" Boolean",returnType:"Changer",aka:[]},"(else-if: Boolean) -> Changer":{name:"else-if",sig:" Boolean",returnType:"Changer",aka:[]},"(else:) -> Changer":{name:"else",sig:"",returnType:"Changer",aka:[]},"(hidden:) -> Changer":{name:"hidden",sig:"",returnType:"Changer",aka:[]},"(hook: String) -> Changer":{name:"hook",sig:" String",returnType:"Changer",aka:[]},"(for: Lambda, ...Any) -> Changer":{name:"for",sig:" Lambda, ...Any",returnType:"Changer",aka:[]},"(transition: String) -> Changer":{name:"transition",sig:" String",returnType:"Changer",aka:[]},"(transition-time: Number) -> Changer":{name:"transition-time",sig:" Number",returnType:"Changer",aka:[]},"(font: String) -> Changer":{name:"font",sig:" String",returnType:"Changer",aka:[]},"(align: String) -> Changer":{name:"align",sig:" String",returnType:"Changer",aka:[]},"(text-colour: String or Colour) -> Changer":{name:"text-colour",sig:" String or Colour",returnType:"Changer",aka:["text-color","color"]},"(text-rotate: Number) -> Changer":{name:"text-rotate",sig:" Number",returnType:"Changer",aka:[]},"(background: Colour or String) -> Changer":{name:"background",sig:" Colour or String",returnType:"Changer",aka:[]},"(text-style: String) -> Changer":{name:"text-style",sig:" String",returnType:"Changer",aka:[]},"(hover-style: Changer) -> Changer":{name:"hover-style",sig:" Changer",returnType:"Changer",aka:[]},"(css: String) -> Changer":{name:"css",sig:" String",returnType:"Changer",aka:[]},"(text: ...[Number or String or Boolean or Array]) -> String":{name:"text",sig:" ...[Number or String or Boolean or Array]",returnType:"String",aka:[]},"(substring: String, Number, Number) -> String":{name:"substring",sig:" String, Number, Number",returnType:"String",aka:[]},"(lowercase: String) -> String":{name:"lowercase",sig:" String",returnType:"String",aka:[]},"(uppercase: String) -> String":{name:"uppercase",sig:" String",returnType:"String",aka:[]},"(lowerfirst: String) -> String":{name:"lowerfirst",sig:" String",returnType:"String",aka:[]},"(upperfirst: String) -> String":{name:"upperfirst",sig:" String",returnType:"String",aka:[]},"(words: String) -> Array":{name:"words",sig:" String",returnType:"Array",aka:[]},"(num: String) -> Number":{name:"num",sig:" String",returnType:"Number",aka:[]},"(rgb: Number, Number, Number) -> Colour":{name:"rgb",sig:" Number, Number, Number",returnType:"Colour",aka:[]},"(rgba: Number, Number, Number, Number) -> Colour":{name:"rgba",sig:" Number, Number, Number, Number",returnType:"Colour",aka:[]},"(hsl: Number, Number, Number) -> Colour":{name:"hsl",sig:" Number, Number, Number",returnType:"Colour",aka:[]},"(hsla: Number, Number, Number, Number) -> Colour":{name:"hsla",sig:" Number, Number, Number, Number",returnType:"Colour",aka:[]},"(weekday:) -> String":{name:"weekday",sig:"",returnType:"String",aka:[]},"(monthday:) -> Number":{name:"monthday",sig:"",returnType:"Number",aka:[]},"(current-time:) -> String":{name:"current-time",sig:"",returnType:"String",aka:[]},"(current-date:) -> String":{name:"current-date",sig:"",returnType:"String",aka:[]},"(min: ...Number) -> Number":{name:"min",sig:" ...Number",returnType:"Number",aka:[]},"(max: ...Number) -> Number":{name:"max",sig:" ...Number",returnType:"Number",aka:[]},"(abs: Number) -> Number":{name:"abs",sig:" Number",returnType:"Number",aka:[]},"(sign: Number) -> Number":{name:"sign",sig:" Number",returnType:"Number",aka:[]},"(sin: Number) -> Number":{name:"sin",sig:" Number",returnType:"Number",aka:[]},"(cos: Number) -> Number":{name:"cos",sig:" Number",returnType:"Number",aka:[]},"(tan: Number) -> Number":{name:"tan",sig:" Number",returnType:"Number",aka:[]},"(floor: Number) -> Number":{name:"floor",sig:" Number",returnType:"Number",aka:[]},"(round: Number) -> Number":{name:"round",sig:" Number",returnType:"Number",aka:[]},"(ceil: Number) -> Number":{name:"ceil",sig:" Number",returnType:"Number",aka:[]},"(pow: Number, Number) -> Number":{name:"pow",sig:" Number, Number",returnType:"Number",aka:[]},"(exp: Number) -> Number":{name:"exp",sig:" Number",returnType:"Number",aka:[]},"(sqrt: Number) -> Number":{name:"sqrt",sig:" Number",returnType:"Number",aka:[]},"(log: Number) -> Number":{name:"log",sig:" Number",returnType:"Number",aka:[]},"(log10: Number) -> Number":{name:"log10",sig:" Number",returnType:"Number",aka:[]},"(log2: Number) -> Number":{name:"log2",sig:" Number",returnType:"Number",aka:[]},"(random: Number, [Number]) -> Number":{name:"random",sig:" Number, [Number]",returnType:"Number",aka:[]},"(either: ...Any) -> Any":{name:"either",sig:" ...Any",returnType:"Any",aka:[]}},n=r instanceof Object&&Object.keys(r).reduce(function(e,n){return e.concat.apply(e,[r[n].name].concat(_toConsumableArray(r[n].aka)))},[]).map(e),t=void 0;"function"==typeof define&&define.amd?define("markup",[],function(e){t=e.lex}):this&&this.loaded&&this.modules&&(t=this.modules.Markup.lex),window.CodeMirror&&CodeMirror.defineMode("harlowe-2",function(){function r(e,r){if(e.update){var n=e.from.line,t=r.split("\n").slice(0,e.from.line+1);return t[n]=t[n].slice(0,e.from.ch)+e.text[0],t=t.concat(e.text.slice(1)),e.update({line:0,ch:0},e.to,t),t.join("\n")}}function a(e){u.length&&(u.forEach(function(e){return e.clear()}),u=[]);var r=i.tokenAt(e.indexFromPos(e.getCursor()));if(r){if(u.push(e.markText(e.posFromIndex(r.start),e.posFromIndex(r.end),{className:"cm-harlowe-2-cursor"})),"variable"===r.type||"tempVariable"===r.type||"hookRef"===r.type||"hook"===r.type){var n="hook"===r.type?"hookRef":r.type;s[n].forEach(function(n){n!==r&&n.name===r.name&&u.push(e.markText(e.posFromIndex(n.start),e.posFromIndex(n.end),{className:"cm-harlowe-2-variableOccurrence"}))})}("hookRef"===r.type||"hook"===r.type)&&s.hook.forEach(function(n){if(n!==r&&n.name===r.name){var t="appended"===n.tagPosition?n.end-n.name.length-1:n.start+1;u.push(e.markText(e.posFromIndex(t),e.posFromIndex(t+n.name.length),{className:"cm-harlowe-2-hookOccurrence"}))}})}}var o=void 0,i=void 0,s={variable:[],tempVariable:[],hook:[],hookRef:[],populate:function(){var e=this;this.variable=[],this.tempVariable=[],this.hook=[],this.hookRef=[];var r=function r(n){("variable"===n.type||"tempVariable"===n.type||"hook"===n.type||"hookRef"===n.type)&&e[n.type].push(n),n.children.forEach(r)};i.children.forEach(r)}},u=[],l=function(){var e=o.doc;i=t(e.getValue()),s.populate(),e.on("beforeChange",function(n,t){var a=e.getValue();r(t,a)}),e.on("change",function(){var r=e.getValue();i=t(r),s.populate()}),e.on("swapDoc",l),e.on("cursorActivity",a),l=null};return{startState:function(){return o||(o=CodeMirror.modes["harlowe-2"].cm,o.setOption("placeholder",["Enter the body text of your passage here.","''Bold'', //italics//, ^^superscript^^, ~~strikethrough~~, and
HTML tags
are available.","To display special symbols without them being transformed, put them between `backticks`.","To link to another passage, write the link text and the passage name like this: [[link text->passage name]]\nor this: [[passage name<-link text]]\nor this: [[link text]].","Macros like (set:) and (display:) are the programming of your passage. If you've (set:) a $variable, you can just enter its name to print it out.","To make a 'hook', put [single square brackets] around text - or leave it empty [] - then put a macro like (if:), a $variable, or a |nametag> outside the front, |like>[so].","Hooks can be used for many things: showing text (if:) something happened, applying a (text-style:), making a place to (append:) text later on, and much more!","Consult the Harlowe documentation for more information."].join("\n\n")),o.setOption("lineNumbers",!0),o.setOption("lineNumberFormatter",function(){return"\u2022"})),{pos:0}},blankLine:function(e){e.pos++},token:function(r,t){l&&l();var a=i.pathAt(t.pos),o=a[0];if(!o)return t.pos++,r.next(),null;for(;o===o.tokenAt(t.pos)&&!r.eol();)t.pos++,r.next();r.eol()&&t.pos++;for(var s={},u="",m=0;m1&&(g+="-"+s[g]),c){case"macroName":-1===n.indexOf(e(a[m].text.slice(0,-1)))&&(g+=" harlowe-2-error")}u+=g+" "}return u}}});var a=document.querySelector("style#cm-harlowe-2");a||(a=document.createElement("style"),a.setAttribute("id","cm-harlowe-2"),document.head.appendChild(a)),a.innerHTML=function(){var e=function(e,r,n){return function(t){return"background-color: hsla("+e+","+r+"%,"+n+"%,"+t+");"}},r=e(40,100,50),n=e(220,100,50),t=function(r){return e(320,44,50)(r)+"color: #a84186;"},a="color: firebrick !important; background-color: hsla(17, 100%, 74%, 0.74) !important;",o="font-weight:100; color: hsla(0,0,0,0.5)";return{root:"box-sizing:border-box;","cursor:not([class^='cm-harlowe-2-text cm-harlowe-2-root'])":"border-bottom: 2px solid darkgray;",CodeMirror:"padding: 0 !important","CodeMirror-linenumber":"color: #ccc;","CodeMirror-gutters":"left: 0px !important;",hook:r(.05),"hook-2":r(.1),"hook-3":r(.15),"hook-4":r(.2),"hook-5":r(.25),"hook-6":r(.3),"hook-7":r(.35),"hook-8":r(.4),"^=hook , ^=hook-":"font-weight:bold;","error:not([class*='cm-harlowe-2-string'])":a,macro:t(.05),"macro-2":t(.1),"macro-3":t(.15),"macro-4":t(.2),"macro-5":t(.25),"macro-6":t(.3),"macro-7":t(.35),"macro-8":t(.4),macroName:"font-style:italic;","^=macro ":"font-weight:bold;","bold, strong":"font-weight:bold;","italic, em":"font-style:italic;",sup:"vertical-align: super;font-size:0.8em;",strike:"text-decoration: line-through;",verbatim:"background-color: hsla(0,0%,50%,0.1);","^=bold, ^=strong, ^=italic, ^=em, ^=sup, ^=verbatim, ^=strike":o,
+"^=string":"font-style:italic; display:inline-block; transform: scaleX(-1);","string + ^=string":"transform: none;","^=collapsed":"font-weight:bold; color: hsl(201, 100%, 30%);",collapsed:n(.025),"collapsed.hook":n(.05),"collapsed.hook-2":n(.1),"collapsed.hook-3":n(.15),"collapsed.hook-4":n(.2),"collapsed.hook-5":n(.25),"collapsed.hook-6":n(.3),"collapsed.hook-7":n(.35),"collapsed.hook-8":n(.4),"twineLink:not(.text)":"color: #3333cc;",tag:"color: #4d4d9d;",boolean:"color: #626262;",string:"color: #008282;",number:"color: #A15000;",variable:"color: #0076b2;",tempVariable:"color: #1a6e97;",hookRef:"color: #007f54;","variableOccurrence, hookOccurrence":"background: #9fdfc9 !important;",where:"color: #007f00; font-style:italic;",via:"color: #007f00; font-style:italic;",with:"color: #007f00; font-style:italic;",making:"color: #007f00; font-style:italic;",each:"color: #007f00; font-style:italic;",heading:"font-weight:bold;",hr:"display:block; background-image: linear-gradient(0deg, transparent, transparent 45%, silver 45%, transparent 55%, transparent);",align:"display:block; color: hsl(14, 99%, 37%); background-color: hsla(14, 99%, 87%, 0.2);",column:"display:block; color: hsl(204, 99%, 37%); background-color: hsla(204, 99%, 87%, 0.2);",escapedLine:"font-weight:bold; color: hsl(51, 100%, 30%);","identifier, property, belongingProperty, itsProperty, belongingItProperty, belongingItOperator":"color: #0076b2;",toString:function(){var e=this;return Object.keys(this).reduce(function(r,n){var t;return"toString"===n?r:"CodeMirror"===n.slice(0,10)?r+"."+n+"{"+e[n]+"}":(t=n.split(", ").map(function e(r){return r.indexOf(".")>-1?r.split(/\./g).map(e).join(""):r.indexOf(" + ")>-1?r.split(/ \+ /g).map(e).join(" + "):0===r.indexOf("^=")?"[class^='cm-harlowe-2-"+r.slice(2)+"']":".cm-harlowe-2-"+r}),r+t.join(", ")+"{"+e[n]+"}")},"")}}+""}()}.call(eval("this"));}});
\ No newline at end of file
diff --git a/apps/card-game/storyformats/harlowe-2/icon.svg b/apps/card-game/storyformats/harlowe-2/icon.svg
new file mode 100644
index 00000000..cbad8781
--- /dev/null
+++ b/apps/card-game/storyformats/harlowe-2/icon.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/apps/card-game/storyformats/harlowe-3/format.js b/apps/card-game/storyformats/harlowe-3/format.js
new file mode 100644
index 00000000..c3ee1599
--- /dev/null
+++ b/apps/card-game/storyformats/harlowe-3/format.js
@@ -0,0 +1,3 @@
+window.storyFormat({"name":"Harlowe","version":"3.1.0","author":"Leon Arnott","description":"The default story format for Twine 2. See its documentation.","image":"icon.svg","url":"http://twinery.org/","license":"Zlib","proofing":false,"source":"\n\n\n\n{{STORY_NAME}}\n\n\n\n\n\n\n\n{{STORY_DATA}}\n\n\n\n\n\n\n","setup": function(){"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var r=0,n=Array(e.length);r-1)||e.cannotFollow&&(-1!==e.cannotFollow.indexOf(n&&n.type)||e.cannotFollow.indexOf("text")>-1&&t)||e.peek&&e.peek.toLowerCase()!==r.slice(0,e.peek.length).toLowerCase())}function t(e){for(var r=e.innerText,t=[],o=0,s=o,u=r.length,m=null;o-1&&(k=t.length-1)}if(k>=t.length&&!y.isFront)continue}s0;)t.shift().demote();return e}function a(e,n,t){var a=e.children.indexOf(n),o=e.children.indexOf(t);n.children=e.children.splice(o+1,a-(o+1)),n.children.forEach(function(e){r(n,e)}),n.type=n.matches[t.type],n.innerText="";for(var i=0,s=n.children.length;i=this.end)return null;if(this.childAt)return this.childAt[e]&&this.childAt[e].tokenAt(e)||this;if(this.children.length)for(var r=0;r=this.end)return[];if(this.childAt)return(this.childAt[e]&&this.childAt[e].pathAt(e)||[]).concat(this);var r=[];if(this.children.length)for(var n=0;n=this.end?null:this.children?this.children.reduce(function(r,n){return r||(e>=n.start&&e0&&(e+="["+this.children+"]"),e}},o={lex:function(r,n){return t(new e({type:"root",start:n||0,end:r.length,text:r,innerText:r,children:[],childAt:{},innerMode:o.modes.start}))},rules:i,modes:{}},"object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports=o:"function"==typeof define&&define.amd?define("lexer",[],function(){return o}):this&&this.loaded?(this.modules||(this.modules={}),this.modules.Lexer=o):this.TwineLexer=o}).call(eval("this")||("undefined"!=typeof global?global:window)),function(){function e(r){return r&&"object"===(void 0===r?"undefined":_typeof(r))?(Object.keys(r).forEach(function(n){r[n]=e(r[n])}),r):(r+"").replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function r(e){return function(){return"("+e+Array.apply(0,arguments).join("|")+")"}}var n=void 0,t=r("?:"),a=r("?!"),o=r("?="),i="[ \\f\\t\\v\\u00a0\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000]*",s=i.replace("*","+"),u="\\b",m="[\\w\\-\\u00c0-\\u00de\\u00df-\\u00ff\\u0150\\u0170\\u0151\\u0171\\uD800-\\uDFFF]",l=m.replace("\\-",""),g=t("\\n","$"),c="("+t("\\\\\\n\\\\?|\\n\\\\","[^\\n]")+"+)",p=i+"(\\*+)"+s+c+g,d=i+"((?:0\\.)+)"+s+c+g,h=i+"-{3,}"+i+g,y=i+"(#{1,6})"+i+c+g,f=i+"(==+>|<=+|=+><=+|<==+>)"+i+g,k=i+"(=+\\|+|\\|+=+|=+\\|+=+|\\|=+\\|)"+i+g,b={opener:"\\[\\[(?!\\[)",text:"("+function(){return"[^"+Array.apply(0,arguments).map(e).join("")+"]*"}("]")+")",rightSeparator:t("\\->","\\|"),leftSeparator:"<\\-",closer:"\\]\\]",legacySeparator:"\\|",legacyText:"("+t("[^\\|\\]]","\\]"+a("\\]"))+"+)"},S=l+"*"+l.replace("\\w","a-zA-Z")+l+"*",C="\\$("+S+")",N="'s"+s+"("+S+")",T="("+S+")"+s+"of"+u+a("it\\b"),v="'s"+s,x=t("it","time","visits?","exits?")+u,A="its"+s+"("+S+")",w="its"+s,O="("+S+")"+s+"of"+s+"it"+u,F="of\\b"+s+"it"+u,L={opener:"\\(",name:"("+t(m+"+",C)+"):"+a("\\/"),closer:"\\)"},H=t("=<","=>","[gl]te?\\b","n?eq\\b","isnot\\b","are\\b","x\\b","isa\\b","or"+s+"a"+u),P={name:"[a-zA-Z][\\w\\-]*",attrs:"(?:\"[^\"]*\"|'[^']*'|[^'\">])*?"},B="\\|("+m+"+)(>|\\))",j="(<|\\()("+m+"+)\\|",M="_("+S+")"+u,I="\\b(\\d+(?:\\.\\d+)?(?:[eE][+\\-]?\\d+)?)"+a("m?s")+u;b.main=b.opener+t(b.text+b.rightSeparator,b.text.replace("*","*?")+b.leftSeparator)+b.text,n={upperLetter:"[A-Z\\u00c0-\\u00de\\u0150\\u0170]",lowerLetter:"[a-z0-9_\\-\\u00df-\\u00ff\\u0151\\u0171]",anyLetter:m,anyLetterStrict:l,whitespace:s,escapedLine:"\\\\\\n\\\\?|\\n\\\\",br:"\\n(?!\\\\)",commentFront:"\x3c!--",commentBack:"--\x3e",tag:"<\\/?"+P.name+P.attrs+">",tagPeek:"<",scriptStyleTag:"<("+t("script","style","textarea")+")"+P.attrs+">[^]*?<\\/\\1>",scriptStyleTagOpener:"<",url:"("+t("https?","mailto","javascript","ftp","data")+":\\/\\/[^\\s<]+[^<.,:;\"')\\]\\s])",bullet:"\\*",hr:h,heading:y,align:f,column:k,bulleted:p,numbered:d,strikeOpener:e("~~"),italicOpener:e("//"),boldOpener:e("''"),supOpener:e("^^"),strongFront:e("**"),strongBack:e("**"),emFront:e("*"),emBack:e("*"),verbatimOpener:"`+",collapsedFront:"{",collapsedBack:"}",hookAppendedFront:"\\["+a("=+"),hookPrependedFront:B+"\\["+a("=+"),hookFront:"\\["+a("=+"),hookBack:"\\]"+a(j),hookAppendedBack:"\\]"+j,unclosedHook:"\\[=+",unclosedHookPrepended:B+"\\[=+",passageLink:b.main+b.closer,passageLinkPeek:"[[",legacyLink:b.opener+b.legacyText+b.legacySeparator+b.legacyText+b.closer,legacyLinkPeek:"[[",simpleLink:b.opener+b.legacyText+b.closer,simpleLinkPeek:"[[",macroFront:L.opener+o(L.name),macroFrontPeek:"(",macroName:L.name,groupingFront:"\\("+a(L.name),groupingFrontPeek:"(",groupingBack:"\\)",twine1Macro:"<<[^>\\s]+\\s*(?:\\\\.|'(?:[^'\\\\]*\\\\.)*[^'\\\\]*'|\"(?:[^\"\\\\]*\\\\.)*[^\"\\\\]*\"|[^'\"\\\\>]|>(?!>))*>>",twine1MacroPeek:"<<",property:N,propertyPeek:"'s",belongingProperty:T,possessiveOperator:v,belongingOperator:"of\\b",belongingOperatorPeek:"of",itsOperator:w,itsOperatorPeek:"its",belongingItOperator:F,belongingItOperatorPeek:"of",variable:C,variablePeek:"$",tempVariable:M,tempVariablePeek:"_",hookRef:"\\?("+m+"+)\\b",hookRefPeek:"?",cssTime:"(\\d+\\.?\\d*|\\d*\\.?\\d+)(m?s)\\b",colour:t(t("Red","Orange","Yellow","Lime","Green","Cyan","Aqua","Blue","Navy","Purple","Fuchsia","Magenta","White","Gray","Grey","Black"),"#[\\dA-Fa-f]{3}(?:[\\dA-Fa-f]{3})?"),datatype:t("array","boolean","changer","colour","gradient","color","command","dm","datamap","ds","dataset","number","num","string","str"),number:I,boolean:t("true","false")+u,identifier:x,itsProperty:A,itsPropertyPeek:"its",belongingItProperty:O,escapedStringChar:"\\\\[^\\n]",singleStringOpener:"'",doubleStringOpener:'"',is:"is"+a(s+"not"+u,s+"an?"+u,s+"in"+u,s+"<",s+">")+u,isNot:"is"+s+"not"+a(s+"a"+u)+u,isA:"is"+s+"an?"+u,isNotA:"is"+s+"not"+s+"an?"+u,matches:"matches"+s,and:"and\\b",or:"or\\b",not:"not\\b",inequality:"((?:is(?:"+s+"not)?"+i+")*)("+t("<(?!=)","<=",">(?!=)",">=")+")",isIn:"is"+s+"in"+u,contains:"contains\\b",addition:e("+")+a("="),subtraction:e("-")+a("="),multiplication:e("*")+a("="),division:t("/","%")+a("="),comma:",",spread:"\\.\\.\\."+a("\\."),to:t("to\\b","="),into:"into\\b",making:"making\\b",where:"where\\b",when:"when\\b",via:"via\\b",with:"with\\b",each:"each\\b",augmentedAssign:t("\\+","\\-","\\*","\\/","%")+"=",bind:"bind\\b",incorrectOperator:H},"object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports=n:"function"==typeof define&&define.amd?define("patterns",[],function(){return n}):this&&this.loaded?(this.modules||(this.modules={}),this.modules.Patterns=n):this.Patterns=n}.call(eval("this")||("undefined"!=typeof global?global:window)),function(){function e(e){function r(e){return e=e||"innerText",function(r){var n=r.reduceRight(function(e,r,n){return e||(n?r:"")},""),t={};return t[e]=n,t}}function t(e,r){var n={};return n[e]=r,function(){return{isFront:!0,matches:n,cannotCross:["verbatimOpener"]}}}function a(e,r){return Object.keys(r).forEach(function(n){var t=r[n].fn;r[n].fn=function(r){var a=t(r);return a.text||(a.text=r[0]),a.type||(a.type=n),a.innerMode||(a.innerMode=e),a}}),r}var o=Object.bind(0,null),i=[],s=[],u=a(i,{hr:{fn:o},bulleted:{fn:function(e){return{depth:e[1].length,innerText:e[2]}}},numbered:{fn:function(e){return{depth:e[1].length/2,innerText:e[2]}}},heading:{fn:function(e){return{depth:e[1].length,innerText:e[2]}}},align:{fn:function(e){var r=void 0,n=e[1],t=n.indexOf("><");return~t?25===(r=Math.round(t/(n.length-2)*50))&&(r="center"):"<"===n[0]&&">"===n.slice(-1)?r="justify":n.indexOf(">")>-1?r="right":n.indexOf("<")>-1&&(r="left"),{align:r}}},column:{fn:function(e){var r=void 0,n=e[1],t=n.indexOf("|");return t&&t-1}}},augmentedAssign:{fn:function(e){return{operator:e[0][0]}}},identifier:{fn:r("name"),cannotFollow:["text"]},whitespace:{fn:o,cannotFollow:"text"},incorrectOperator:{fn:function(e){var r={"=>":">=","=<":"<=",gte:">=",lte:"<=",gt:">",lt:"<",eq:"is",isnot:"is not",neq:"is not",isa:"is a",are:"is",x:"*","or a":"or"}[e[0].toLowerCase().replace(/\s+/g," ")];return{type:"error",message:"Please say "+(r?"'"+r+"'":"something else")+" instead of '"+e[0]+"'.",explanation:"In the interests of readability, I want certain operators to be in a specific form."}},cannotFollow:"text"}},["boolean","is","to","into","where","when","via","with","making","each","and","or","not","isNot","contains","isIn","isA","isNotA","matches","bind"].reduce(function(e,r){return e[r]={fn:o,cannotFollow:["text"]},e},{}),["comma","spread","addition","subtraction","multiplication","division"].reduce(function(e,r){return e[r]={fn:o},e},{})));i.push.apply(i,_toConsumableArray(Object.keys(u)).concat(_toConsumableArray(Object.keys(l)),_toConsumableArray(Object.keys(m)))),s.push.apply(s,_toConsumableArray(Object.keys(l)).concat(_toConsumableArray(Object.keys(g))));var c=Object.assign({},u,m,l,g);return Object.keys(c).forEach(function(e){var r=n[e];c[e].pattern="string"!=typeof r?r:new RegExp("^(?:"+r+")","i"),n[e+"Peek"]&&(c[e].peek=n[e+"Peek"])}),Object.assign(e.rules,c),e.modes.start=e.modes.markup=i,e.modes.macro=s,e}function r(r){return Object.freeze({lex:e(r).lex,Patterns:n})}var n=void 0;Object.assign=Object.assign||function(e){for(var r=1;r Command":{name:"display",sig:" String",returnType:"Command",aka:[]},"(print: Any) -> Command":{name:"print",sig:" Any",returnType:"Command",aka:[]},"(go-to: String) -> Command":{name:"go-to",sig:" String",returnType:"Command",aka:[]},"(undo:) -> Command":{name:"undo",sig:"",returnType:"Command",aka:[]},"(cycling-link: [Bind], ...String) -> Command":{name:"cycling-link",sig:" [Bind], ...String",returnType:"Command",aka:[]},"(dropdown: Bind, ...String) -> Command":{name:"dropdown",sig:" Bind, ...String",returnType:"Command",aka:[]},"(show: ...HookName) -> Command":{name:"show",sig:" ...HookName",returnType:"Command",aka:[]},"(stop:) -> Command":{name:"stop",sig:"",returnType:"Command",aka:[]},"(load-game: String) -> Command":{name:"load-game",sig:" String",returnType:"Command",aka:[]},"(alert: String) -> Command":{name:"alert",sig:" String",returnType:"Command",aka:[]},"(open-url: String) -> Command":{name:"open-url",sig:" String",returnType:"Command",aka:[]},"(reload:) -> Command":{name:"reload",sig:"",returnType:"Command",aka:[]},"(goto-url: String) -> Command":{name:"goto-url",sig:" String",returnType:"Command",aka:[]},"(save-game: String, [String]) -> Boolean":{name:"save-game",sig:" String, [String]",returnType:"Boolean",aka:[]},"(prompt: String, String) -> String":{name:"prompt",sig:" String, String",returnType:"String",aka:[]},"(confirm: String) -> Boolean":{name:"confirm",sig:" String",returnType:"Boolean",aka:[]},"(page-url:) -> String":{name:"page-url",sig:"",returnType:"String",aka:[]},"(set: ...VariableToValue) -> Instant":{name:"set",sig:" ...VariableToValue",returnType:"Instant",aka:[]},"(put: ...VariableToValue) -> Instant":{name:"put",sig:" ...VariableToValue",returnType:"Instant",aka:[]},"(move: ...VariableToValue) -> Instant":{name:"move",sig:" ...VariableToValue",returnType:"Instant",aka:[]},"(a: [...Any]) -> Array":{name:"a",sig:" [...Any]",returnType:"Array",aka:["array"]},"(range: Number, Number) -> Array":{name:"range",sig:" Number, Number",returnType:"Array",aka:[]},"(subarray: Array, Number, Number) -> Array":{name:"subarray",sig:" Array, Number, Number",returnType:"Array",aka:[]},"(reversed: [...Any]) -> Array":{name:"reversed",sig:" [...Any]",returnType:"Array",aka:[]},"(shuffled: Any, ...Any) -> Array":{name:"shuffled",sig:" Any, ...Any",returnType:"Array",aka:[]},"(sorted: Number or String, ...Number or String) -> Array":{name:"sorted",sig:" Number or String, ...Number or String",returnType:"Array",aka:[]},"(rotated: Number, [...Any]) -> Array":{name:"rotated",sig:" Number, [...Any]",returnType:"Array",aka:[]},"(repeated: Number, ...Any) -> Array":{name:"repeated",sig:" Number, ...Any",returnType:"Array",aka:[]},"(interlaced: Array, ...Array) -> Array":{name:"interlaced",sig:" Array, ...Array",returnType:"Array",aka:[]},"(altered: Lambda, [...Any]) -> Array":{name:"altered",sig:" Lambda, [...Any]",returnType:"Array",aka:[]},"(find: Lambda, [...Any]) -> Array":{name:"find",sig:" Lambda, [...Any]",returnType:"Array",aka:[]},"(all-pass: Lambda, [...Any]) -> Boolean":{name:"all-pass",sig:" Lambda, [...Any]",returnType:"Boolean",aka:[]},"(some-pass: Lambda, ...Any) -> Boolean":{name:"some-pass",sig:" Lambda, ...Any",returnType:"Boolean",aka:[]},"(none-pass: Lambda, ...Any) -> Boolean":{name:"none-pass",sig:" Lambda, ...Any",returnType:"Boolean",aka:[]},"(folded: Lambda, ...Any) -> Any":{name:"folded",sig:" Lambda, ...Any",returnType:"Any",aka:[]},"(datanames: Datamap) -> Array":{name:"datanames",sig:" Datamap",returnType:"Array",aka:[]},"(datavalues: Datamap) -> Array":{name:"datavalues",sig:" Datamap",returnType:"Array",aka:[]},"(dataentries: Datamap) -> Array":{name:"dataentries",sig:" Datamap",returnType:"Array",aka:[]},"(history: [Lambda]) -> Array":{name:"history",sig:" [Lambda]",returnType:"Array",aka:[]},"(passage: [String]) -> Datamap":{name:"passage",sig:" [String]",returnType:"Datamap",aka:[]},"(passages: [Lambda]) -> Array":{name:"passages",sig:" [Lambda]",returnType:"Array",aka:[]},"(saved-games:) -> Datamap":{name:"saved-games",sig:"",returnType:"Datamap",aka:[]},"(dm: [...Any]) -> Datamap":{name:"dm",sig:" [...Any]",returnType:"Datamap",aka:["datamap"]},"(ds: [...Any]) -> Dataset":{name:"ds",sig:" [...Any]",returnType:"Dataset",aka:["dataset"]},"(count: Array or String, ...Any) -> Number":{name:"count",sig:" Array or String, ...Any",returnType:"Number",aka:[]},"(enchant: HookName or String, Changer) -> Command":{name:"enchant",sig:" HookName or String, Changer",returnType:"Command",aka:[]},"(replace: ...HookName or String) -> Changer":{name:"replace",sig:" ...HookName or String",returnType:"Changer",aka:[]},"(append: ...HookName or String) -> Changer":{name:"append",sig:" ...HookName or String",returnType:"Changer",aka:[]},"(prepend: ...HookName or String) -> Changer":{name:"prepend",sig:" ...HookName or String",returnType:"Changer",aka:[]},"(click: HookName or String) -> Changer":{name:"click",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseover: HookName or String) -> Changer":{name:"mouseover",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseout: HookName or String) -> Changer":{name:"mouseout",sig:" HookName or String",returnType:"Changer",aka:[]},"(click-replace: HookName or String) -> Changer":{name:"click-replace",sig:" HookName or String",returnType:"Changer",aka:[]},"(click-append: HookName or String) -> Changer":{name:"click-append",sig:" HookName or String",returnType:"Changer",aka:[]},"(click-prepend: HookName or String) -> Changer":{name:"click-prepend",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseover-replace: HookName or String) -> Changer":{name:"mouseover-replace",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseover-append: HookName or String) -> Changer":{name:"mouseover-append",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseover-prepend: HookName or String) -> Changer":{name:"mouseover-prepend",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseout-replace: HookName or String) -> Changer":{name:"mouseout-replace",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseout-append: HookName or String) -> Changer":{name:"mouseout-append",sig:" HookName or String",returnType:"Changer",aka:[]},"(mouseout-prepend: HookName or String) -> Changer":{name:"mouseout-prepend",sig:" HookName or String",returnType:"Changer",aka:[]},"(click-goto: HookName or String, String) -> Command":{name:"click-goto",sig:" HookName or String, String",returnType:"Command",aka:[]},"(mouseover-goto: HookName or String, String) -> Command":{name:"mouseover-goto",sig:" HookName or String, String",returnType:"Command",aka:[]},"(mouseout-goto: HookName or String, String) -> Command":{name:"mouseout-goto",sig:" HookName or String, String",returnType:"Command",aka:[]},"(link: String) -> Changer":{name:"link",sig:" String",returnType:"Changer",aka:["link-replace"]},"(link-reveal: String) -> Changer":{name:"link-reveal",sig:" String",returnType:"Changer",aka:[]},"(link-repeat: String) -> Changer":{name:"link-repeat",sig:" String",returnType:"Changer",aka:[]},"(link-goto: String, [String]) -> Command":{name:"link-goto",sig:" String, [String]",returnType:"Command",aka:[]},"(link-undo: String) -> Command":{name:"link-undo",sig:" String",returnType:"Command",aka:[]},"(link-show: String, ...HookName) -> Command":{name:"link-show",sig:" String, ...HookName",returnType:"Command",aka:[]},"(link-reveal-goto: String, [String]) -> Changer":{name:"link-reveal-goto",sig:" String, [String]",returnType:"Changer",aka:[]},"(if: Boolean) -> Changer":{name:"if",sig:" Boolean",returnType:"Changer",aka:[]},"(unless: Boolean) -> Changer":{name:"unless",sig:" Boolean",returnType:"Changer",aka:[]},"(else-if: Boolean) -> Changer":{name:"else-if",sig:" Boolean",returnType:"Changer",aka:[]},"(else:) -> Changer":{name:"else",sig:"",returnType:"Changer",aka:[]},"(hidden:) -> Changer":{name:"hidden",sig:"",returnType:"Changer",aka:[]},"(live: [Number]) -> Changer":{name:"live",sig:" [Number]",returnType:"Changer",aka:[]},"(event: Lambda) -> Changer":{name:"event",sig:" Lambda",returnType:"Changer",aka:[]},"(more:) -> Changer":{name:"more",sig:"",returnType:"Changer",aka:[]},"(hook: String) -> Changer":{name:"hook",sig:" String",returnType:"Changer",aka:[]},"(for: Lambda, [...Any]) -> Changer":{name:"for",sig:" Lambda, [...Any]",returnType:"Changer",aka:["loop"]},"(transition: String) -> Changer":{name:"transition",sig:" String",returnType:"Changer",aka:["t8n"]},"(transition-time: Number) -> Changer":{name:"transition-time",sig:" Number",returnType:"Changer",aka:["t8n-time"]},"(transition-depart: String) -> Changer":{name:"transition-depart",sig:" String",returnType:"Changer",aka:["t8n-depart"]},"(transition-arrive: String) -> Changer":{name:"transition-arrive",sig:" String",returnType:"Changer",aka:["t8n-arrive"]},"(font: String) -> Changer":{name:"font",sig:" String",returnType:"Changer",aka:[]},"(align: String) -> Changer":{name:"align",sig:" String",returnType:"Changer",aka:[]},"(text-colour: String or Colour) -> Changer":{name:"text-colour",sig:" String or Colour",returnType:"Changer",aka:["colour","text-color","color"]},"(text-rotate: Number) -> Changer":{name:"text-rotate",sig:" Number",returnType:"Changer",aka:[]},"(background: Colour or String or Gradient) -> Changer":{name:"background",sig:" Colour or String or Gradient",returnType:"Changer",aka:[]},"(text-style: String) -> Changer":{name:"text-style",sig:" String",returnType:"Changer",aka:[]},"(hover-style: Changer) -> Changer":{name:"hover-style",sig:" Changer",returnType:"Changer",aka:[]},"(css: String) -> Changer":{name:"css",sig:" String",returnType:"Changer",aka:[]},"(str: ...[Number or String or Boolean or Array]) -> String":{name:"str",sig:" ...[Number or String or Boolean or Array]",returnType:"String",aka:["string","text"]},"(substring: String, Number, Number) -> String":{name:"substring",sig:" String, Number, Number",returnType:"String",aka:[]},"(lowercase: String) -> String":{name:"lowercase",sig:" String",returnType:"String",aka:[]},"(uppercase: String) -> String":{name:"uppercase",sig:" String",returnType:"String",aka:[]},"(lowerfirst: String) -> String":{name:"lowerfirst",sig:" String",returnType:"String",aka:[]},"(upperfirst: String) -> String":{name:"upperfirst",sig:" String",returnType:"String",aka:[]},"(words: String) -> Array":{name:"words",sig:" String",returnType:"Array",aka:[]},"(str-repeated: Number, String) -> String":{name:"str-repeated",sig:" Number, String",returnType:"String",aka:["string-repeated"]},"(str-reversed: String) -> String":{name:"str-reversed",sig:" String",returnType:"String",aka:["string-reversed"]},"(num: String) -> Number":{name:"num",sig:" String",returnType:"Number",aka:["number"]},"(rgb: Number, Number, Number, [Number]) -> Colour":{name:"rgb",sig:" Number, Number, Number, [Number]",returnType:"Colour",aka:["rgba"]},"(hsl: Number, Number, [Number]) -> Colour":{name:"hsl",sig:" Number, Number, [Number]",returnType:"Colour",aka:["hsla"]},"(gradient: Number, ...Number, Colour) -> Gradient":{name:"gradient",sig:" Number, ...Number, Colour",returnType:"Gradient",aka:[]},"(cond: Boolean, Any, ...Any) -> Any":{name:"cond",sig:" Boolean, Any, ...Any",returnType:"Any",aka:[]},"(weekday:) -> String":{name:"weekday",sig:"",returnType:"String",aka:[]},"(monthday:) -> Number":{name:"monthday",sig:"",returnType:"Number",aka:[]},"(current-time:) -> String":{name:"current-time",sig:"",returnType:"String",aka:[]},"(current-date:) -> String":{name:"current-date",sig:"",returnType:"String",aka:[]},"(min: ...Number) -> Number":{name:"min",sig:" ...Number",returnType:"Number",aka:[]},"(max: ...Number) -> Number":{name:"max",sig:" ...Number",returnType:"Number",aka:[]},"(abs: Number) -> Number":{name:"abs",sig:" Number",returnType:"Number",aka:[]},"(sign: Number) -> Number":{name:"sign",sig:" Number",returnType:"Number",aka:[]},"(sin: Number) -> Number":{name:"sin",sig:" Number",returnType:"Number",aka:[]},"(cos: Number) -> Number":{name:"cos",sig:" Number",returnType:"Number",aka:[]},"(tan: Number) -> Number":{name:"tan",sig:" Number",returnType:"Number",aka:[]},"(floor: Number) -> Number":{name:"floor",sig:" Number",returnType:"Number",aka:[]},"(round: Number) -> Number":{name:"round",sig:" Number",returnType:"Number",aka:[]},"(ceil: Number) -> Number":{name:"ceil",sig:" Number",returnType:"Number",aka:[]},"(pow: Number, Number) -> Number":{name:"pow",sig:" Number, Number",returnType:"Number",aka:[]},"(exp: Number) -> Number":{name:"exp",sig:" Number",returnType:"Number",aka:[]},"(sqrt: Number) -> Number":{name:"sqrt",sig:" Number",returnType:"Number",aka:[]},"(log: Number) -> Number":{name:"log",sig:" Number",returnType:"Number",aka:[]},"(log10: Number) -> Number":{name:"log10",sig:" Number",returnType:"Number",aka:[]},"(log2: Number) -> Number":{name:"log2",sig:" Number",returnType:"Number",aka:[]},"(random: Number, [Number]) -> Number":{name:"random",sig:" Number, [Number]",returnType:"Number",aka:[]},"(either: ...Any) -> Any":{name:"either",sig:" ...Any",returnType:"Any",aka:[]},"(nth: Number, ...Any) -> Any":{name:"nth",sig:" Number, ...Any",returnType:"Any",aka:[]}},n=r instanceof Object&&Object.keys(r).reduce(function(e,n){return e.concat.apply(e,[r[n].name].concat(_toConsumableArray(r[n].aka)))},[]).map(e),t=void 0;"function"==typeof define&&define.amd?define("markup",[],function(e){t=e.lex}):this&&this.loaded&&this.modules&&(t=this.modules.Markup.lex),window.CodeMirror&&CodeMirror.defineMode("harlowe-3",function(){function r(e,r){if(e.update){var n=e.from.line,t=r.split("\n").slice(0,e.from.line+1);return t[n]=t[n].slice(0,e.from.ch)+e.text[0],t=t.concat(e.text.slice(1)),e.update({line:0,ch:0},e.to,t),t.join("\n")}}function a(e){u.length&&(u.forEach(function(e){return e.clear()}),u=[]);var r=i.tokenAt(e.indexFromPos(e.getCursor()));if(r){if(u.push(e.markText(e.posFromIndex(r.start),e.posFromIndex(r.end),{className:"cm-harlowe-3-cursor"})),"variable"===r.type||"tempVariable"===r.type||"hookRef"===r.type||"hook"===r.type){var n="hook"===r.type?"hookRef":r.type;s[n].forEach(function(n){n!==r&&n.name===r.name&&u.push(e.markText(e.posFromIndex(n.start),e.posFromIndex(n.end),{className:"cm-harlowe-3-variableOccurrence"}))})}"hookRef"!==r.type&&"hook"!==r.type||s.hook.forEach(function(n){if(n!==r&&n.name===r.name){var t="appended"===n.tagPosition?n.end-n.name.length-1:n.start+1;u.push(e.markText(e.posFromIndex(t),e.posFromIndex(t+n.name.length),{className:"cm-harlowe-3-hookOccurrence"}))}})}}var o=void 0,i=void 0,s={variable:[],tempVariable:[],hook:[],hookRef:[],populate:function(){var e=this;this.variable=[],this.tempVariable=[],this.hook=[],this.hookRef=[];var r=function r(n){"variable"!==n.type&&"tempVariable"!==n.type&&"hook"!==n.type&&"hookRef"!==n.type||e[n.type].push(n),n.children.forEach(r)};i.children.forEach(r)}},u=[],m=function(){var e=o.doc;i=t(e.getValue()),s.populate(),e.on("beforeChange",function(n,t){r(t,e.getValue())}),e.on("change",function(){var r=e.getValue();i=t(r),s.populate()}),e.on("swapDoc",m),e.on("cursorActivity",a),m=null};return{startState:function(){return o||(o=CodeMirror.modes["harlowe-3"].cm,
+o.setOption("placeholder",["Enter the body text of your passage here.","''Bold'', //italics//, ^^superscript^^, ~~strikethrough~~, and
HTML tags
are available.","To display special symbols without them being transformed, put them between `backticks`.","To link to another passage, write the link text and the passage name like this: [[link text->passage name]]\nor this: [[passage name<-link text]]\nor this: [[link text]].","Macros like (set:) and (display:) are the programming of your passage. If you've (set:) a $variable, you can just enter its name to print it out.","To make a 'hook', put [single square brackets] around text - or leave it empty [] - then put a macro like (if:), a $variable, or a |nametag> outside the front, |like>[so].","Hooks can be used for many things: showing text (if:) something happened, applying a (text-style:), making a place to (append:) text later on, and much more!","Consult the Harlowe documentation for more information."].join("\n\n")),o.setOption("lineNumbers",!0),o.setOption("lineNumberFormatter",function(){return"\u2022"})),{pos:0}},blankLine:function(e){e.pos++},token:function(r,t){m&&m();var a=i.pathAt(t.pos),o=a[0];if(!o)return t.pos++,r.next(),null;for(;o===o.tokenAt(t.pos)&&!r.eol();)t.pos++,r.next();r.eol()&&t.pos++;for(var s={},u="",l=0;l1&&(c+="-"+s[c]),g){case"macroName":-1===n.indexOf(e(a[l].text.slice(0,-1)))&&(c+=" harlowe-3-error")}u+=c+" "}return u}}});var a=document.querySelector("style#cm-harlowe-3");a||(a=document.createElement("style"),a.setAttribute("id","cm-harlowe-3"),document.head.appendChild(a)),a.innerHTML=function(){var e=function(e,r,n){return function(t){return"background-color: hsla("+e+","+r+"%,"+n+"%,"+t+");"}},r=e(40,100,50),n=e(220,100,50),t=function(r){return e(320,44,50)(r)+"color: #a84186;"};return{root:"box-sizing:border-box;","cursor:not([class^='cm-harlowe-3-text cm-harlowe-3-root'])":"border-bottom: 2px solid darkgray;",CodeMirror:"padding: 0 !important","CodeMirror-linenumber":"color: #ccc;","CodeMirror-gutters":"left: 0px !important;",hook:r(.05),"hook-2":r(.1),"hook-3":r(.15),"hook-4":r(.2),"hook-5":r(.25),"hook-6":r(.3),"hook-7":r(.35),"hook-8":r(.4),"^=hook , ^=hook-":"font-weight:bold;",unclosedHook:r(.05)+"font-weight:bold;","error:not([class*='cm-harlowe-3-string'])":"color: firebrick !important; background-color: hsla(17, 100%, 74%, 0.74) !important;",macro:t(.05),"macro-2":t(.1),"macro-3":t(.15),"macro-4":t(.2),"macro-5":t(.25),"macro-6":t(.3),"macro-7":t(.35),"macro-8":t(.4),macroName:"font-style:italic;","^=macro ":"font-weight:bold;","bold, strong":"font-weight:bold;","italic, em":"font-style:italic;",sup:"vertical-align: super;font-size:0.8em;",strike:"text-decoration: line-through;",verbatim:"background-color: hsla(0,0%,50%,0.1);","^=bold, ^=strong, ^=italic, ^=em, ^=sup, ^=verbatim, ^=strike":"font-weight:100; color: hsla(0,0,0,0.5)","^=collapsed":"font-weight:bold; color: hsl(201, 100%, 30%);",collapsed:n(.025),"collapsed.hook":n(.05),"collapsed.hook-2":n(.1),"collapsed.hook-3":n(.15),"collapsed.hook-4":n(.2),"collapsed.hook-5":n(.25),"collapsed.hook-6":n(.3),"collapsed.hook-7":n(.35),"collapsed.hook-8":n(.4),"twineLink:not(.text)":"color: #3333cc;",".theme-dark twineLink:not(.text)":"color: #5555ee;",tag:"color: #4d4d9d;",boolean:"color: #626262;",string:"color: #158383;",number:"color: #A15000;",variable:"color: #0076b2;",tempVariable:"color: #218abe;",hookRef:"color: #007f54;","variableOccurrence, hookOccurrence":"background: #9fdfc9 !important;","^=where, ^=via, ^=with, ^=making, ^=each, ^=when":"color: #007f00; font-style:italic;",heading:"font-weight:bold;",hr:"display:block; background-image: linear-gradient(0deg, transparent, transparent 45%, silver 45%, transparent 55%, transparent);",align:"display:block; color: hsl(14, 99%, 37%); background-color: hsla(14, 99%, 87%, 0.1);",column:"display:block; color: hsl(204, 99%, 37%); background-color: hsla(204, 99%, 87%, 0.1);",escapedLine:"font-weight:bold; color: hsl(51, 100%, 30%);","identifier, property, belongingProperty, itsProperty, belongingItProperty, belongingItOperator":"color: #0076b2;",toString:function(){var e=this;return Object.keys(this).reduce(function(r,n){var t;return"toString"===n?r:"CodeMirror"===n.slice(0,10)?r+"."+n+"{"+e[n]+"}":(t=n.split(", ").map(function e(r){return 0===r.indexOf(".theme-dark")?r.slice(0,11)+" "+e(r.slice(11).trim()):r.indexOf(".")>-1?r.split(/\./g).map(e).join(""):0===r.indexOf("^=")?"[class^='cm-harlowe-3-"+r.slice(2)+"']":".cm-harlowe-3-"+r}),r+t.join(", ")+"{"+e[n]+"}")},"")}}+""}()}.call(eval("this"));
+}});
\ No newline at end of file
diff --git a/apps/card-game/storyformats/harlowe-3/icon.svg b/apps/card-game/storyformats/harlowe-3/icon.svg
new file mode 100644
index 00000000..cbad8781
--- /dev/null
+++ b/apps/card-game/storyformats/harlowe-3/icon.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/apps/card-game/storyformats/paperthin-1/format.js b/apps/card-game/storyformats/paperthin-1/format.js
new file mode 100644
index 00000000..aaec67f1
--- /dev/null
+++ b/apps/card-game/storyformats/paperthin-1/format.js
@@ -0,0 +1 @@
+window.storyFormat({"name":"Paperthin","version":"1.0.0","description":"The default proofing format for Twine 2. Icon designed by Simon Child from the Noun Project","author":"Chris Klimas","image":"icon.svg","url":"http://twinery.org/","license":"ZLib/Libpng","proofing":true,"source":"\n\n\n{{STORY_NAME}}\n\n\n\n\n\n\n\n
{{STORY_NAME}}\n
\n{{STORY_DATA}}\n\n\n\n\n"});
diff --git a/apps/card-game/storyformats/paperthin-1/icon.svg b/apps/card-game/storyformats/paperthin-1/icon.svg
new file mode 100644
index 00000000..62e9760f
--- /dev/null
+++ b/apps/card-game/storyformats/paperthin-1/icon.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/apps/card-game/storyformats/snowman-1/format.js b/apps/card-game/storyformats/snowman-1/format.js
new file mode 100644
index 00000000..c0aff649
--- /dev/null
+++ b/apps/card-game/storyformats/snowman-1/format.js
@@ -0,0 +1 @@
+window.storyFormat({"author":"Dan Cox","description":"A minimal story format for authors experienced with HTML, CSS, and JavaScript. See its documentation.","image":"icon.svg","name":"Snowman","proofing":false,"source":"\n\n\t\n\t\t{{STORY_NAME}}\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t{{STORY_DATA}}\n\t\t\n\t\n\n","url":"https://github.com/videlais/snowman/tree/1.X","version":"1.4.0"});
\ No newline at end of file
diff --git a/apps/card-game/storyformats/snowman-1/icon.svg b/apps/card-game/storyformats/snowman-1/icon.svg
new file mode 100644
index 00000000..fd7ae5b5
--- /dev/null
+++ b/apps/card-game/storyformats/snowman-1/icon.svg
@@ -0,0 +1,436 @@
+
+
+
+
diff --git a/apps/card-game/storyformats/snowman-2/format.js b/apps/card-game/storyformats/snowman-2/format.js
new file mode 100644
index 00000000..bd2cd777
--- /dev/null
+++ b/apps/card-game/storyformats/snowman-2/format.js
@@ -0,0 +1 @@
+window.storyFormat({"author":"Dan Cox","description":"A minimal story format for authors more experienced with HTML, CSS, and JavaScript. See its documentation.","image":"icon.svg","name":"Snowman","proofing":false,"source":"\n\n\t\n\t\t\n\t\t\n\t\t{{STORY_NAME}}\n\t\t\n\t\n\t\n\t\t\n\t\t{{STORY_DATA}}\n\t\t\n\t\n\n","url":"https://github.com/videlais/snowman/","version":"2.0.2"});
\ No newline at end of file
diff --git a/apps/card-game/storyformats/snowman-2/icon.svg b/apps/card-game/storyformats/snowman-2/icon.svg
new file mode 100644
index 00000000..fd7ae5b5
--- /dev/null
+++ b/apps/card-game/storyformats/snowman-2/icon.svg
@@ -0,0 +1,436 @@
+
+
+
+
diff --git a/apps/card-game/storyformats/sugarcube-1/LICENSE b/apps/card-game/storyformats/sugarcube-1/LICENSE
new file mode 100644
index 00000000..16c827dd
--- /dev/null
+++ b/apps/card-game/storyformats/sugarcube-1/LICENSE
@@ -0,0 +1,23 @@
+
+Copyright (c) 2013-2016 Thomas Michael Edwards .
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. 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.
+
+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.
diff --git a/apps/card-game/storyformats/sugarcube-1/format.js b/apps/card-game/storyformats/sugarcube-1/format.js
new file mode 100644
index 00000000..771fa2fd
--- /dev/null
+++ b/apps/card-game/storyformats/sugarcube-1/format.js
@@ -0,0 +1 @@
+window.storyFormat({"name":"SugarCube","version":"1.0.35","description":"A Twine 2 port of the Twine 1 story format by the same name. See its documentation.","author":"Thomas Michael Edwards","image":"icon.svg","url":"http://www.motoslave.net/sugarcube/","license":"Simplified BSD License","proofing":false,"source":"\n\n\n\n{{STORY_NAME}}\n\n\n\n\n\n\n\n\n\n\n\n\t
\n\t\t\n\t\t
Apologies! Your web browser lacks required capabilities. Please consider upgrading it or switching to a more modern web browser.
\n\t\t
Initializing. Please wait…
\n\t
\n\t
{{STORY_DATA}}
\n\t\n\n\n"});
\ No newline at end of file
diff --git a/apps/card-game/storyformats/sugarcube-1/icon.svg b/apps/card-game/storyformats/sugarcube-1/icon.svg
new file mode 100644
index 00000000..2893c9df
--- /dev/null
+++ b/apps/card-game/storyformats/sugarcube-1/icon.svg
@@ -0,0 +1,56 @@
+
+
+
diff --git a/apps/card-game/storyformats/sugarcube-2/LICENSE b/apps/card-game/storyformats/sugarcube-2/LICENSE
new file mode 100644
index 00000000..9908a48d
--- /dev/null
+++ b/apps/card-game/storyformats/sugarcube-2/LICENSE
@@ -0,0 +1,23 @@
+
+Copyright (c) 2013-2019 Thomas Michael Edwards .
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. 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.
+
+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.
diff --git a/apps/card-game/storyformats/sugarcube-2/format.js b/apps/card-game/storyformats/sugarcube-2/format.js
new file mode 100644
index 00000000..6191fcbc
--- /dev/null
+++ b/apps/card-game/storyformats/sugarcube-2/format.js
@@ -0,0 +1 @@
+window.storyFormat({"name":"SugarCube","version":"2.30.0","description":"A full featured, highly customizable story format. See its documentation.","author":"Thomas Michael Edwards","image":"icon.svg","url":"http://www.motoslave.net/sugarcube/","license":"BSD-2-Clause","proofing":false,"source":"\n\n\n\n{{STORY_NAME}}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t
\n\t\t\n\t\t
Your browser lacks required capabilities. Please upgrade it or switch to another to continue.