From 8803ef86cf095b8c0329c6f05f96dca9baffefa8 Mon Sep 17 00:00:00 2001 From: Chris Klimas Date: Mon, 15 Jan 2024 13:41:42 -0500 Subject: [PATCH 01/27] Add docs on how to see startup logs --- docs/en/src/troubleshooting/wont-start.md | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/en/src/troubleshooting/wont-start.md b/docs/en/src/troubleshooting/wont-start.md index e37fde5c0..69b363713 100644 --- a/docs/en/src/troubleshooting/wont-start.md +++ b/docs/en/src/troubleshooting/wont-start.md @@ -1,5 +1,7 @@ # If Twine Won't Start +This page only applies to app Twine. + If Twine shows an error message when first starting and immediately quits, it's most likely because it is having trouble loading either your preferences or stories. Twine tries its best to repair problems it finds in saved files at @@ -13,6 +15,44 @@ There are a few steps you can take that may fix this problem: when you add back a story, that story is the source of the problem. 3. Reinstall Twine. +## Getting More Detail on Startup Problems + +Twine logs information as it starts up and works that is not normally visible. +If you're having problems, though, these logs might tell you more about the +source of the problem. To see them, you'll need to start Twine from the command +line. Once you've started Twine from the command line, you'll see Twine's logs +in that window. + +### Linux + +How to do this depends on the distribution of Linux you use. In a desktop +environment, you will need to start a terminal session. Gnome and KDE have apps +(called "Gnome Terminal" and "Konsole") to do this. + +Once you've started a terminal session, you'll need to run Twine from wherever +it was installed. Unfortunately, this varies by distribution as well. + +### MacOS + +Open your Applications folder, then the Utilities folder. Open Terminal in this +folder, then type the following into the window that appears and press the Enter +key: + +`/Applications/Twine.app/Contents/MacOS/Twine` + +### Windows + +Open the Start menu, then run the Command Prompt application. This will open a +window. After it's opened, open the Start menu again and locate Twine, but +right-click on it instead of opening the entry. Choose the _Open file location_ +option from the context menu. This will open a folder containing the Twine icon. +Right-click this icon and choose _Copy as path_ from the context menu. + +Finally, go back to the Command Prompt window and right-click inside the window. +This will paste the location of Twine into the window. If you've copied the path +correctly, what you have pasted should end with `Twine.exe`. Don't edit what was +pasted; only press the Enter key to launch Twine. + ## Resetting Preferences in Browser Twine To reset your preferences, you'll need to [edit your browser local From c1400a33167f90b3c5f1efca342ed926a3fb7efc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Jan 2024 02:24:55 +0000 Subject: [PATCH 02/27] Bump vite from 4.4.12 to 4.5.2 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.12 to 4.5.2. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v4.5.2/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v4.5.2/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 403226337..55343218a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "Twine", - "version": "2.8.0", + "version": "2.8.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Twine", - "version": "2.8.0", + "version": "2.8.1", "license": "GPL-3.0", "dependencies": { "@popperjs/core": "^2.9.1", @@ -105,7 +105,7 @@ "tiny-invariant": "^1.3.1", "ts-jest": "^29.1.1", "typescript": "^4.9.5", - "vite": "^4.4.12", + "vite": "^4.5.2", "vite-plugin-checker": "^0.6.2", "vite-plugin-node-polyfills": "^0.15.0" }, @@ -20052,9 +20052,9 @@ } }, "node_modules/vite": { - "version": "4.4.12", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.12.tgz", - "integrity": "sha512-KtPlUbWfxzGVul8Nut8Gw2Qe8sBzWY+8QVc5SL8iRFnpnrcoCaNlzO40c1R6hPmcdTwIPEDkq0Y9+27a5tVbdQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", + "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", "dev": true, "dependencies": { "esbuild": "^0.18.10", diff --git a/package.json b/package.json index bddc849bf..0467129e1 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "tiny-invariant": "^1.3.1", "ts-jest": "^29.1.1", "typescript": "^4.9.5", - "vite": "^4.4.12", + "vite": "^4.5.2", "vite-plugin-checker": "^0.6.2", "vite-plugin-node-polyfills": "^0.15.0" }, From d25f6255f67c67a89b10ca593ffdc70d1887ddcb Mon Sep 17 00:00:00 2001 From: rubynguyen1510 Date: Fri, 2 Feb 2024 11:55:53 -0800 Subject: [PATCH 03/27] added data-tag attribute to passageCard --- .../passage/__tests__/passage-card.test.tsx | 11 ++++++++++- src/components/passage/passage-card.tsx | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/passage/__tests__/passage-card.test.tsx b/src/components/passage/__tests__/passage-card.test.tsx index 7177ee55b..88d487f07 100644 --- a/src/components/passage/__tests__/passage-card.test.tsx +++ b/src/components/passage/__tests__/passage-card.test.tsx @@ -6,7 +6,7 @@ import {fakePassage} from '../../../test-util'; import {passageIsEmpty} from '../../../util/passage-is-empty'; import {PassageCard, PassageCardProps} from '../passage-card'; -jest.mock('../../tag/tag-stripe'); +jest.mock('../../tag/tag-stripe'); jest.mock('../../../util/passage-is-empty'); describe('', () => { @@ -32,6 +32,15 @@ describe('', () => { ); } + it('should have a data-tag attribute with space-separated tags', () => { + const tags = ['mock-tag-1', 'mock-tag-2']; + const passage = fakePassage({tags}); + renderComponent({passage}); + + const passageElement = screen.getByTestId('passage-card'); + expect(passageElement).toHaveAttribute('data-tag', tags.join(' ')); + }); + it('displays the passage name', () => { const passage = fakePassage(); diff --git a/src/components/passage/passage-card.tsx b/src/components/passage/passage-card.tsx index b2809c15a..de9eeb6e2 100644 --- a/src/components/passage/passage-card.tsx +++ b/src/components/passage/passage-card.tsx @@ -107,7 +107,7 @@ export const PassageCard: React.FC = React.memo(props => { onDrag={onDrag} onStop={onDragStop} > -
+
Date: Mon, 5 Feb 2024 21:10:25 -0800 Subject: [PATCH 04/27] Made revisions based on pull request review comments --- .../passage/__tests__/passage-card.test.tsx | 23 ++++++++++++++----- src/components/passage/passage-card.tsx | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/components/passage/__tests__/passage-card.test.tsx b/src/components/passage/__tests__/passage-card.test.tsx index 88d487f07..cd6c37281 100644 --- a/src/components/passage/__tests__/passage-card.test.tsx +++ b/src/components/passage/__tests__/passage-card.test.tsx @@ -5,8 +5,9 @@ import * as React from 'react'; import {fakePassage} from '../../../test-util'; import {passageIsEmpty} from '../../../util/passage-is-empty'; import {PassageCard, PassageCardProps} from '../passage-card'; +import {lorem} from 'faker'; -jest.mock('../../tag/tag-stripe'); +jest.mock('../../tag/tag-stripe'); jest.mock('../../../util/passage-is-empty'); describe('', () => { @@ -32,13 +33,23 @@ describe('', () => { ); } - it('should have a data-tag attribute with space-separated tags', () => { - const tags = ['mock-tag-1', 'mock-tag-2']; + it('should include data-passage-tag attribute with space-separated tags', () => { + const tags = [lorem.slug(), lorem.slug()]; const passage = fakePassage({tags}); renderComponent({passage}); - - const passageElement = screen.getByTestId('passage-card'); - expect(passageElement).toHaveAttribute('data-tag', tags.join(' ')); + + // eslint-disable-next-line testing-library/no-node-access + const passageElement=document.querySelector('.passage-card') + expect(passageElement).toHaveAttribute('data-passage-tag', tags.join(' ')); + }); + + it('should include data-passage-tag with an empty string when passage has no tags', () => { + const passage = fakePassage({tags:[]}); + renderComponent({passage}); + + // eslint-disable-next-line testing-library/no-node-access + const passageElement=document.querySelector('.passage-card') + expect(passageElement).toHaveAttribute('data-passage-tag', ''); }); it('displays the passage name', () => { diff --git a/src/components/passage/passage-card.tsx b/src/components/passage/passage-card.tsx index de9eeb6e2..bbcdd0f3f 100644 --- a/src/components/passage/passage-card.tsx +++ b/src/components/passage/passage-card.tsx @@ -107,7 +107,7 @@ export const PassageCard: React.FC = React.memo(props => { onDrag={onDrag} onStop={onDragStop} > -
+
Date: Thu, 8 Feb 2024 21:40:33 -0800 Subject: [PATCH 05/27] Update passage-card.tsx --- src/components/passage/passage-card.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/passage/passage-card.tsx b/src/components/passage/passage-card.tsx index bbcdd0f3f..568a1a1cc 100644 --- a/src/components/passage/passage-card.tsx +++ b/src/components/passage/passage-card.tsx @@ -107,7 +107,7 @@ export const PassageCard: React.FC = React.memo(props => { onDrag={onDrag} onStop={onDragStop} > -
+
= React.memo(props => { ); }); -PassageCard.displayName = 'PassageCard'; \ No newline at end of file +PassageCard.displayName = 'PassageCard'; From d290b36d5af681b10736ae7f9d5cdd696b0aa08b Mon Sep 17 00:00:00 2001 From: Ngoc Nguyen <50710444+rubynguyen1510@users.noreply.github.com> Date: Sat, 10 Feb 2024 14:37:52 -0800 Subject: [PATCH 06/27] Update passage-card.test.tsx --- src/components/passage/__tests__/passage-card.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/passage/__tests__/passage-card.test.tsx b/src/components/passage/__tests__/passage-card.test.tsx index cd6c37281..1bc532082 100644 --- a/src/components/passage/__tests__/passage-card.test.tsx +++ b/src/components/passage/__tests__/passage-card.test.tsx @@ -40,7 +40,7 @@ describe('', () => { // eslint-disable-next-line testing-library/no-node-access const passageElement=document.querySelector('.passage-card') - expect(passageElement).toHaveAttribute('data-passage-tag', tags.join(' ')); + expect(passageElement).toHaveAttribute('data-passage-tags', tags.join(' ')); }); it('should include data-passage-tag with an empty string when passage has no tags', () => { @@ -49,7 +49,7 @@ describe('', () => { // eslint-disable-next-line testing-library/no-node-access const passageElement=document.querySelector('.passage-card') - expect(passageElement).toHaveAttribute('data-passage-tag', ''); + expect(passageElement).toHaveAttribute('data-passage-tags', ''); }); it('displays the passage name', () => { From fc391c5ec0af253e3c6a4c1efe713ed2bd30d52c Mon Sep 17 00:00:00 2001 From: Chris Klimas Date: Sat, 10 Feb 2024 22:19:04 -0500 Subject: [PATCH 07/27] Update credits --- src/dialogs/about-twine/credits.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dialogs/about-twine/credits.json b/src/dialogs/about-twine/credits.json index 836fad91b..0ff99266c 100644 --- a/src/dialogs/about-twine/credits.json +++ b/src/dialogs/about-twine/credits.json @@ -2,6 +2,7 @@ "code": [ "Chris Klimas", "Lorenzo Ancora", + "Siham Argaw", "Leon Arnott", "Ingrid Cheung", "Daithi O Crualaoich", @@ -9,6 +10,7 @@ "Micah Fitch", "Kate Fractal", "Juhana Leinonen", + "Ngoc Nguyen", "Michael Savich", "Ross Smith" ], From 7207c5c8c47158ea20d331f2db28de0957750cd9 Mon Sep 17 00:00:00 2001 From: Chris Klimas Date: Sun, 18 Feb 2024 10:50:08 -0500 Subject: [PATCH 08/27] Add documentation around publishing filename --- docs/en/src/publishing/publishing.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/en/src/publishing/publishing.md b/docs/en/src/publishing/publishing.md index d804c7602..c895c23ea 100644 --- a/docs/en/src/publishing/publishing.md +++ b/docs/en/src/publishing/publishing.md @@ -10,7 +10,12 @@ You can publish a story from both the _Story Library_ and _Story Map_ screens. tab. Twine will then ask you to choose a file name and location to save your -published file. +published file. The file name you choose doesn't affect the name of your story +in its published form. In other words, if you publish a story named "My Best +Story" in your library to a file named `my-worst-story.html`, the story will +still show its title as "My Best Story" in a web browser. If you'd like to +change the name of your story in its published form, [rename +it](../editing-stories/renaming.html) before publishing. Some versions of the Safari web browser may instead open a browser tab with an address that begins with `blob://`. If this happens, choose _Save As_ from From 60c3cadc308ec9ceafb0406c5c1ef58eaa828d2e Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 22 Feb 2024 22:06:20 +1000 Subject: [PATCH 09/27] Updated Harlowe to 3.3.9. --- public/story-formats/harlowe-3.3.8/format.js | 4 ---- public/story-formats/harlowe-3.3.9/format.js | 4 ++++ .../story-formats/{harlowe-3.3.8 => harlowe-3.3.9}/icon.svg | 0 src/store/prefs/defaults.ts | 2 +- src/store/story-formats/defaults.ts | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 public/story-formats/harlowe-3.3.8/format.js create mode 100644 public/story-formats/harlowe-3.3.9/format.js rename public/story-formats/{harlowe-3.3.8 => harlowe-3.3.9}/icon.svg (100%) diff --git a/public/story-formats/harlowe-3.3.8/format.js b/public/story-formats/harlowe-3.3.8/format.js deleted file mode 100644 index a21781d11..000000000 --- a/public/story-formats/harlowe-3.3.8/format.js +++ /dev/null @@ -1,4 +0,0 @@ -window.storyFormat({"name":"Harlowe","version":"3.3.8","author":"Leon Arnott","description":"The default story format for Twine 2, with numerous programming features and a rich passage editor. No HTML, JS or CSS experience required. Consult its documentation.","image":"icon.svg","url":"http://twinery.org/","license":"Zlib","proofing":false,"source":"\n\n\n\n\n{{STORY_NAME}}\n\n\n\n\n{{STORY_DATA}}\n\n\n\n\n","setup": function(){(function(){ -"use strict";function _toArray(e){return _arrayWithHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableRest()}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArrayLimit(e,t){var a=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var r,o,n,i,s=[],c=!0,l=!1;try{if(n=(a=a.call(e)).next,0===t){if(Object(a)!==a)return;c=!1}else for(;!(c=(r=n.call(a)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=a.return&&(i=a.return(),Object(i)!==i))return}finally{if(l)throw o}}return s}}function _arrayWithHoles(e){if(Array.isArray(e))return e}function _createForOfIteratorHelper(t,a){var r,o,i,c,l="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(l)return o=!(r=!0),{s:function s(){l=l.call(t)},n:function n(){var e=l.next();return r=e.done,e},e:function e(t){o=!0,i=t},f:function f(){try{r||null==l.return||l.return()}finally{if(o)throw i}}};if(Array.isArray(t)||(l=_unsupportedIterableToArray(t))||a&&t&&"number"==typeof t.length)return l&&(t=l),c=0,{s:a=function F(){},n:function n(){return c>=t.length?{done:!0}:{done:!1,value:t[c++]}},e:function e(t){throw t},f:a};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){var a;if(e)return"string"==typeof e?_arrayLikeToArray(e,t):"Map"===(a="Object"===(a=Object.prototype.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:a)||"Set"===a?Array.from(e):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(e,t):void 0}function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var a=0,r=new Array(t);a=n.length)&&!g.isFront)continue}s=this.end)return null;if(this.children.length)for(var t=0;t=this.children[t].start&&e=this.end)return[];var t=[];if(this.children.length)for(var a=0;a=this.children[a].start&&e=this.end?null:this.children?this.children.reduce(function(e,t){return e||(a>=t.start&&a|<=+|=+><=+|<==+>)"+o+l,l=o+"(=+\\|+|\\|+=+|=+\\|+=+|\\|=+\\|)"+o+l,p={opener:"\\[\\[(?!\\[)",text:"("+function notChars(){return"[^"+Array.apply(0,arguments).map(escape).join("")+"]*"}("]")+")",rightSeparator:t("\\->","\\|"),leftSeparator:"<\\-",closer:"\\]\\]",legacySeparator:"\\|",legacyText:"("+t("[^\\|\\]]","\\]"+a("\\]"))+"+)"},g=c+"*"+c.replace("\\w","a-zA-Z")+c+"*",y="\\$("+g+")",b="_("+g+")",f="'s"+n+a("_")+"("+g+")",w="("+g+")"+n+"of"+i+a("it\\b"),k="'s"+n,v=t("it","time","turns?","visits?","exits?","pos")+i,x="its"+n+"("+g+")",T="("+g+")"+n+"of"+n+"it"+i,C="of"+n+"it"+i,S={opener:"\\(",name:"("+t("\\$","_")+"?"+s+"+):"+a("\\/"),closer:"\\)"},A=t("=<","=>","[gl]te?\\b","n?eq\\b","isnot\\b","are\\b","x\\b","isa\\b","or"+n+"a"+i),N="[a-zA-Z][\\w\\-]*",_="(?:\"[^\"]*\"|'[^']*'|[^'\">])*?",O="\\|("+s+"+)(>|\\))",P="(<|\\()("+s+"+)\\|",L="((?:\\b\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+\\-]?\\d+)?)"+a("m?s")+i;p.main=p.opener+t(p.text+p.rightSeparator,p.text.replace("*","*?")+p.leftSeparator)+p.text,e={upperLetter:"[A-Z\\u00c0-\\u00de\\u0150\\u0170]",lowerLetter:"[a-z0-9_\\-\\u00df-\\u00ff\\u0151\\u0171]",anyLetter:s,anyLetterStrict:c,whitespace:n.replace("[","[\\n\\r"),escapedLine:"\\\\\\n\\\\?|\\n\\\\",br:"\\n(?!\\\\)",tag:"<\\/?"+N+_+">",scriptStyleTag:"<("+t("script","style","textarea")+")"+_+">[^]*?<\\/\\1>",scriptStyleTagOpener:"<",url:"("+t("https?","mailto","javascript","ftp","data")+":\\/\\/[^\\s<]+[^<.,:;\"')\\]\\s])",bullet:"\\*",hr:u,heading:"[ \\f\\t\\v\\u00a0\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000]*(#{1,6})[ \\f\\t\\v\\u00a0\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000]*",align:m,column:l,bulleted:h,numbered:d,verbatimOpener:"`+",hookAppendedFront:"\\["+a("=+"),hookPrependedFront:O+"\\["+a("=+"),hookFront:"\\["+a("=+"),hookBack:"\\]"+a(P),hookAppendedBack:"\\]"+P,unclosedHook:"\\[=+",unclosedHookPrepended:O+"\\[=+",unclosedCollapsed:"\\{=+",passageLink:p.main+p.closer,legacyLink:p.opener+p.legacyText+p.legacySeparator+p.legacyText+p.closer,simpleLink:p.opener+p.legacyText+p.closer,macroFront:S.opener+r(S.name),macroName:S.name,groupingFront:"\\("+a(S.name),twine1Macro:"<<[^>\\s]+\\s*(?:\\\\.|'(?:[^'\\\\]*\\\\.)*[^'\\\\]*'|\"(?:[^\"\\\\]*\\\\.)*[^\"\\\\]*\"|[^'\"\\\\>]|>(?!>))*>>",validPropertyName:g,property:f,belongingProperty:w,possessiveOperator:k,belongingOperator:"of\\b",itsOperator:"its\\b",belongingItOperator:C,variable:y,tempVariable:b,hookName:"\\?("+s+"+)\\b",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","Transparent"),"#[\\dA-Fa-f]{3}(?:[\\dA-Fa-f]{3})?"),datatype:t("alnum","alphanumeric","any(?:case)?","array","bool(?:ean)?","changer","codehook","colou?r","const","command","dm","data"+t("map","type","set"),"ds","digit","gradient","empty","even","int"+a("o")+"(?:eger)?","lambda","lowercase","macro","linebreak","newline","num(?:ber)?","odd","str(?:ing)?","uppercase","whitespace")+i,number:L,boolean:t("true","false")+i,identifier:v,itsProperty:x,belongingItProperty:T,escapedStringChar:"\\\\[^\\n]",singleStringOpener:"'",doubleStringOpener:'"',singleStringCloser:"'",doubleStringCloser:'"',is:"is"+a(n+"not"+i,n+"an?"+i,n+"in"+i,n+"<",n+">")+i,isNot:"is"+n+"not"+a(n+t("an?","in")+i)+i,isA:"is"+n+"an?"+i,isNotA:"is"+n+"not"+n+"an?"+i,matches:"matches\\b",doesNotMatch:"does"+n+"not"+n+"match"+i,and:"and\\b",or:"or\\b",not:"not\\b",inequality:"((?:is(?:"+n+"not)?"+o+")*)("+t("<(?!=)","<=",">(?!=)",">=")+")",isIn:"is"+n+"in"+i,contains:"contains\\b",doesNotContain:"does"+n+"not"+n+"contain"+i,isNotIn:"is"+n+"not"+n+"in"+i,addition:escape("+")+a("="),subtraction:escape("-")+a("=","type"),multiplication:escape("*")+a("="),division:t("/","%")+a("="),spread:"\\.\\.\\."+a("\\."),to:t("to\\b","="),into:"into\\b",making:"making\\b",where:"where\\b",when:"when\\b",via:"via\\b",each:"each\\b",augmentedAssign:t("\\+","\\-","\\*","\\/","%")+"=",bind:"2?bind\\b",typeSignature:escape("-type")+i,incorrectOperator:A,PlainCompare:{comma:",",commentFront:"\x3c!--",commentBack:"--\x3e",strikeOpener:"~~",italicOpener:"//",boldOpener:"''",supOpener:"^^",strongFront:"**",strongBack:"**",emFront:"*",emBack:"*",collapsedFront:"{",collapsedBack:"}",groupingBack:")"}},"object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports=e:"function"==typeof define&&define.amd?define("patterns",[],function(){return e}):this&&this.loaded?(this.modules||(this.modules={}),this.modules.Patterns=e):this.Patterns=e}.call(eval("this")||("undefined"!=typeof global?global:window)),!function(){Object.assign=Object.assign||function polyfilledAssign(e){for(var t=1;t<");return~a?25===(t=Math.round(a/(e.length-2)*50))&&(t="center"):"<"===e[0]&&">"===e.slice(-1)?t="justify":-1")?t="right":-1":">=","=<":"<=",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 "+(t?"'"+t+"'":"something else")+" instead of '"+e[0]+"'.",explanation:"In the interests of readability, I want certain operators to be in a specific form."}},cannotFollowText:!0}},["boolean","is","to","into","where","when","via","making","each","and","or","not","isNot","contains","doesNotContain","isIn","isA","isNotA","isNotIn","matches","doesNotMatch","bind"].reduce(function(e,t){return e[t]={fn:a,cannotFollowText:!0},e},{})),["comma","spread","typeSignature","addition","subtraction","multiplication","division"].reduce(function(e,t){return e[t]={fn:a},e},{}))),h=setupRules(o,{singleStringCloser:l.singleStringOpener,doubleStringCloser:l.doubleStringOpener,escapedStringChar:l.escapedStringChar}),d=(r.push.apply(r,_toConsumableArray(m(n)).concat(_toConsumableArray(m(c)),_toConsumableArray(m(s)))),t.push.apply(t,_toConsumableArray(m(c)).concat(_toConsumableArray(m(l)))),o.push.apply(o,_toConsumableArray(m(h))),_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({},n),s),c),l),h));return m(d).forEach(function(e){u.PlainCompare[e]?(d[e].pattern=u.PlainCompare[e],d[e].plainCompare=!0):d[e].pattern=RegExp("^(?:"+u[e]+")","i")}),p(e.rules,d),(s=e.modes).start=s.markup=r,s.macro=t,s.string=o,e}(e).lex,Patterns:u})}"object"===("undefined"==typeof module?"undefined":_typeof(module))?(u=require("./patterns"),module.exports=exporter(require("./lexer"))):"function"==typeof define&&define.amd?define("markup",["lexer","patterns"],function(e,t){return u=t,exporter(e)}):this&&this.loaded&&this.modules?(u=this.modules.Patterns,this.modules.Markup=exporter(this.modules.Lexer)):(u=this.Patterns,this.Markup=exporter(this.Lexer))}.call(eval("this")||("undefined"!=typeof global?global:window)),!function(){var t=Math.round,e=function insensitiveName(e){return(e+"").toLowerCase().replace(/-|_/g,"")},a={"#e61919":"red","#e68019":"orange","#e5e619":"yellow","#80e619":"lime","#19e619":"green","#19e5e6":"cyan","#197fe6":"blue","#1919e6":"navy","#7f19e6":"purple","#e619e5":"magenta","#ffffff":"white","#000000":"black","#888888":"grey"},r=function fontIcon(e){var t=1')},o=function GCD(e,t){return e?t?t
")}).join("")}}}(o,r,e)||function keywordCompletion(t,e,a){if(!1!==c().completionsForKeywords&&a.reduce(function(e,t){return void 0===e?"macro"===t.type||"hook"!==t.type&&"string"!==t.type&&e:e},void 0)){var r=_slicedToArray(/[^$\w?]([-2]?[a-zA-Z ]+)$/.exec(e)||[],2)[1];if(r&&"-"!==r&&""!==r[r.length-1].trim()){var o=r.trimLeft().toLowerCase(),n=C.filter(function(e){return e.name.startsWith(o)}).sort(function(e,t){return e.name.length-t.name.length});if(n.length)return k=function tooltipMenuCallback(e){t.replaceRange(n[e].name,x(t,-r.length),t.getCursor())},f=0,w=n.length,n.map(function(e,t){return"
").concat(e.name,'').concat(e.label||e.type,"
")}).join("")}}}(o,r,e);return o&&(p.innerHTML=o,positionTooltip(a,t,!(p.className="harlowe-3-tooltip harlowe-3-completion")),g=0,a.addKeyMap(v),f=0,1)}function Tooltips(e,t){var a=t.tree,t=t.lastAction,r=e.cm,o=(tooltipClear(r),r.display.wrapper),n=(p.parentNode!==o&&(o.append(p),o.addEventListener("mousemove",function(){"none"===p.style.display||o.querySelector(".harlowe-3-tooltip:hover")?0".concat(t,"")}),p.innerHTML=o+(0
Use the ".concat((document.querySelector('[aria-label^="Coding tooltips"],[title^="Coding tooltips"]')||{}).innerHTML||"tooltip"," toolbar button to toggle these popups!")):"")+"
",p.className="harlowe-3-tooltip harlowe-3-helpTooltip",positionTooltip(a,t,!0),p.style.display="none",g=50):void 0})(a,n,r)&&!e&&tooltipAppear()):g=0}this&&this.loaded?this.modules.Tooltips=Tooltips:this.window||(this.Tooltips=Tooltips)}.call(eval("this")),!function(){var P=JSON.stringify,L={},I={};if(this&&this.loaded)var e=this.modules,H=e.Markup.lex,a=e.Patterns,L=e.Utils;else{if(this.window)return;H=this.Markup.lex,a=this.Patterns,L=this.Utils}var e=L,M=e.twine23,n=e.builtinColourNames,E=e.buttonClass,R=e.toHarloweColour,F=e.toCSSColour,z=e.el,D=e.fontIcon,W="querySelector",B=W+"All",j="addEventListener",q="removeEventListener",i=[["#f8f9fa","#fff5f5","#fff0f6","#f8f0fc","#f3f0ff","#edf2ff","#e7f5ff","#e3fafc","#e6fcf5","#ebfbee","#f4fce3","#fff9db","#fff4e6"],["#f1f3f5","#ffe3e3","#ffdeeb","#f3d9fa","#e5dbff","#dbe4ff","#d0ebff","#c5f6fa","#c3fae8","#d3f9d8","#e9fac8","#fff3bf","#ffe8cc"],["#e9ecef","#ffc9c9","#fcc2d7","#eebefa","#d0bfff","#bac8ff","#a5d8ff","#99e9f2","#96f2d7","#b2f2bb","#d8f5a2","#ffec99","#ffd8a8"],["#dee2e6","#ffa8a8","#faa2c1","#e599f7","#b197fc","#91a7ff","#74c0fc","#66d9e8","#63e6be","#8ce99a","#c0eb75","#ffe066","#ffc078"],["#ced4da","#ff8787","#f783ac","#da77f2","#9775fa","#748ffc","#4dabf7","#3bc9db","#38d9a9","#69db7c","#a9e34b","#ffd43b","#ffa94d"],["#adb5bd","#ff6b6b","#f06595","#cc5de8","#845ef7","#5c7cfa","#339af0","#22b8cf","#20c997","#51cf66","#94d82d","#fcc419","#ff922b"],["#868e96","#fa5252","#e64980","#be4bdb","#7950f2","#4c6ef5","#228be6","#15aabf","#12b886","#40c057","#82c91e","#fab005","#fd7e14"],["#495057","#f03e3e","#d6336c","#ae3ec9","#7048e8","#4263eb","#1c7ed6","#1098ad","#0ca678","#37b24d","#74b816","#f59f00","#f76707"],["#343a40","#e03131","#c2255c","#9c36b5","#6741d9","#3b5bdb","#1971c2","#0c8599","#099268","#2f9e44","#66a80f","#f08c00","#e8590c"],["#212529","#c92a2a","#a61e4d","#862e9c","#5f3dc4","#364fc7","#1864ab","#0b7285","#087f5b","#2b8a3e","#5c940d","#e67700","#d9480f"]],V=function dataValueRow(){var r=0An array is a sequence of ordered datavalues that can be used without having to create separate variables for each. Use it to store similar values whose order and position matter, or to store an ever-changing quantity of similar values.
",model:function model(e,t){r(e,"(a:"+t+")")},renumber:function renumber(e,t){var a=((t+=1)+"").slice(-1);e.textContent=t+("1"===a?"st":"2"===a?"nd":"3"===a?"rd":"th")+": "},modelRegistry:e}],["datamap",{type:"datavalue-map",text:"
A datamap is a value that holds any number of other values, each of which is \"mapped\" to a unique name. Use it to store data values that represent parts of a larger game entity, or rows of a table.
",model:function model(e,t){t.every(function(e,t){return t%2!=0||'""'!==e&&"''"!==e})||(e.invalidSubrow=!0),r(e,"(dm:"+t+")")},renumber:function renumber(e){e.textContent=":"},modelRegistry:e}],[],["randomly chosen value",{type:"datavalue-rows",text:"
One of the following values is randomly chosen each time the macro is run.
",model:function model(e,t){t.length||(e.invalidSubrow=!0),r(e,"(either:"+t+")")},renumber:function renumber(e){e.textContent="\u2022",e.style.marginRight="0.5em"},modelRegistry:e}],["random number",z("
A number between these two values is randomly chosen each time the macro is run.
"),{type:"inline-number-textarea",width:"20%",text:"From",model:function model(){},modelRegistry:e},{type:"inline-number-textarea",width:"20%",text:"to",model:function model(e,t){r(e,"(random:"+(+t.previousElementSibling[W]("input").value||0)+","+(+t[W]("input").value||0)+")")},modelRegistry:e}]].concat(t?[]:[[],["itself + value",{type:"datavalue-inner",text:"
The following value is added to the existing value in the variable. NOTE: if the values aren't the same type of data, an error will result.
",model:function model(e,t){1!==t.length&&(e.invalidSubrow=!0),r(e,"it + "+t)},renumber:function renumber(e){(e||{}).textContent="it + "},modelRegistry:e}],["variable + value",{type:"inline-dropdown",text:" Other variable: ",options:["$","_"],model:function model(e,t){e.innerVariable=t[W]("select").value?"_":"$"}},{type:"inline-textarea",width:"25%",text:"",placeholder:"Variable name",model:function model(e,t){t=t[W]("input").value;t&&RegExp("^"+a.validPropertyName+"$").exec(t)&&!RegExp(/^\d/).exec(t)&&(e.innerVariable+=t)}},{type:"datavalue-inner",text:"
The above variable's value and the value below are added together. NOTE: if the values aren't the same type of data, an error will result.
",model:function model(e,t){1!==t.length&&(e.invalidSubrow=!0),r(e,e.innerVariable+" + "+t)},renumber:function renumber(e){(e||{}).textContent=""},modelRegistry:e}]]).concat([[],["coded expression",{type:"expression-textarea",width:"90%",text:"
Write a Harlowe code expression that should be computed to produce the desired value.
",placeholder:"Code",modelCallback:r,modelRegistry:e}]])}};I.Panel=function folddownPanel(){for(var e=arguments.length,t=new Array(e),a=0;a')),O=function makeColourPicker(e){var a=function makeSwatchRow(e,t,a){return z('")+e.map(function(e){return''}).join("")+"")},r=z('
'),e=z('')),o=e[W]("select");return r.append(a(Object.keys(n),"",!0)),i.forEach(function(e,t){r.append(a(e,t)),o.append(z("")))}),o[j]("change",function(){r[B]("[data-index]").forEach(function(e){return e.style.display="none"}),r[W]('[data-index="'.concat(o.value,'"]')).style.display="inline-block"}),r.append(e,z("
"),new Text("Opacity: "),z('')),r[j]("click",function(e){var t,e=e.target;e.classList.contains("harlowe-3-swatch")&&((t=r[W]("input")).value=e.getAttribute("style").slice(-7),t.dispatchEvent(new Event("change")))}),r},e=t.reduce(function reducer(o,n){var e,i,a,s,t,r,c,l,h,d,u,m,p,g,y,b,f,w,k,v,x,T,C="",S="label"===o.tagName.toLowerCase();return Object.getPrototypeOf(n)!==Object.prototype?i=n:k=(C=n.type).startsWith("inline"),C.endsWith("text")&&(i=z("<".concat(k?"span":"div",">").concat(n.text,""))),"notice"===C&&(i=z(''.concat(n.text,""))),"buttons"===C&&o.append.apply(o,_toConsumableArray(n.buttons.map(function(t){var a;return"tagName"in t?t:(a=z('")),t.onClick&&a[j]("click",t.onClick),t.update&&N.push(function(e){return t.update(e,a)}),a)}))),C.endsWith("preview")&&(v=n.tagName||"span",i=z('
<").concat(v,">").concat(n.text||"","").concat(C.startsWith("t8n")?"<".concat(v,">")+n.text2+""):"","
")),C.startsWith("t8n"))&&(i[j]("mouseup",update),i[j]("touchend",update),(e=i[W](":first-child"))[j]("animationend",function(){return e.style.visibility="hidden"})),(C.endsWith("checkbox")||C.endsWith("checkboxrow"))&&(i=z("").concat(n.text,"")),C.endsWith("w")&&(n.subrow.reduce(reducer,i),n.subrow.forEach(function(e){var a=e.model;e.model=function(e,t){return!i[W](":scope > input:checked")||S&&!o[W](":scope > input:checked")?e:a(e,t)}})),i[j]("change",update)),"checkboxes"===C&&(i=z('
").concat(n.name,"
")),n.options.forEach(function(e,t){var a=z("").concat(e,""));a[j]("change",update),i.append(a)})),"radios"===C&&(i=z('
").concat(n.name,"
")),n.options.forEach(function(e,t){t=z("").concat(e,""));t[j]("change",update),i.append(t)})),C.endsWith("textarea")&&(v="text",a=n.multiline?"textarea":"input",C.endsWith("expression-textarea")&&(n.update=function(e,t){!e.expression&&t[W](a).value?t.setAttribute("invalid","This doesn't seem to be valid code."):t.removeAttribute("invalid")},n.model=function(e,t){t=(t[W](a).value||"").trim();t&&(H(t,"","macro").children.every(function recur(e){return"text"!==e.type&&"error"!==e.type&&("string"===e.type||"hook"===e.type||e.children.every(recur))})?n.modelCallback(e,t):e.valid=!0)}),C.endsWith("string-textarea")&&!n.model&&(n.model=function(e,t){n.modelCallback(e,JSON.stringify(t[W](a).value||""))}),C.endsWith("number-textarea")&&(v="number",n.model||(n.model=function(e,t){n.modelCallback(e,+t[W](a).value||0)})),(i=z("<".concat(k?"span":"div",' class="harlowe-3-labeledInput">').concat(n.text,"<").concat(a," ").concat(n.useSelection?"data-use-selection":"").concat(C.includes("passage")?'list="harlowe-3-passages"':"",' style="width:').concat(n.width,";").concat(n.multiline?"max-width:".concat(n.width,";"):"","padding:var(--grid-size);margin").concat(k?":2px 0.5rem 0 0.5rem":"-left:1rem",";").concat(n.multiline&&k?"display:inline-block;height:40px":"",'" type=').concat(v," ").concat(n.persist?"data-persist":"",' placeholder="').concat(n.placeholder||"",'">")))[W](a)[j]("input",update)),(C.endsWith("number")||C.endsWith("range"))&&(i=z("<"+(k?"span":"div")+' class="harlowe-3-labeledInput">'+n.text+''+n.text+""),v=O(n.value),i.append(v),i[B]("input").forEach(function(e){return e[j]("change",update)})),C.endsWith("gradient")&&(s=(i=z("
")))[W](".harlowe-3-gradientBar"),t=function createColourStop(e,t,a){var r=z("
')+"
"),o=O(t),a=(o[B]("input").forEach(function(e){return e[j]("change",function(){var e=o[W]("[type=range]").value,t=o[W]("[type=color]").value;r.setAttribute("data-colour",F(t,e)),e<1&&r.setAttribute("data-harlowe-colour",R(t,e)),update()})}),z('")));a[j]("click",function(){r.remove(),update()}),o.append(a),r.firstChild.prepend(o),s.append(r),update()},setTimeout(function(){t(0,"#ffffff"),t(.5,"#000000",!0),t(1,"#ffffff")}),i[W]("button")[j]("click",function(){return t(.5,"#888888")}),i[j]("mousedown",v=function listener(e){var t,a,r,o,n=e.target;n.classList.contains("harlowe-3-colourStop")&&(t=document.documentElement,e=s.getBoundingClientRect(),a=e.left,r=e.right-a,e=function onMouseUp(){t[q]("mousemove",o),t[q]("mouseup",onMouseUp),t[q]("touchmove",o),t[q]("touchend",onMouseUp)},t[j]("mousemove",o=function onMouseMove(e){var t=e.pageX,e=e.touches;void 0!==(t=t||(null==e?void 0:e[0].pageX))&&(e=Math.min(1,Math.max(0,(t-window.scrollX-a)/r)),n.style.left="calc(".concat(100*e,"% - 8px)"),n.firstChild.style.left="".concat(-(M?464:384)*e-(M?0:40),"px"),n.setAttribute("data-pos",e),update())}),t[j]("mouseup",e),t[j]("touchmove",o),t[j]("touchend",e),Array.from(s[B]("[selected]")).forEach(function(e){return e.removeAttribute("selected")}),n.setAttribute("selected",!0))}),i[j]("touchstart",v),N.push(function(){s.style.background="linear-gradient(to right, ".concat(Array.from(s[B](".harlowe-3-colourStop")).sort(function(e,t){return e.getAttribute("data-pos")-t.getAttribute("data-pos")}).map(function(e){return e.getAttribute("data-colour")+" "+100*e.getAttribute("data-pos")+"%"}),")")})),C.endsWith("dropdown")&&(r=z("<".concat(k?"span":"div",' style="white-space:nowrap;').concat(k?"":"width:50%;",'position:relative;">').concat(n.text,'")),n.options.forEach(function(e,t){r[W]("select").append(z('
",onClick:function onClick(){return wrapSelection("''","''","Bold Text")}},{title:"Italic",html:"
I
",onClick:function onClick(){return wrapSelection("//","//","Italic Text")}},{title:"Strikethrough",html:"
S
",onClick:function onClick(){return wrapSelection("~~","~~","Strikethrough Text")}},{title:"Superscript",html:"
X2
",onClick:function onClick(){return wrapSelection("^^","^^","Superscript Text")}},{title:"Text and background colour",html:"
",onClick:function onClick(){return switchPanel("textcolor")}},{title:"Borders",html:y("border-style"),onClick:function onClick(){return switchPanel("borders")}},{title:"Rotated text",html:'
R
',onClick:function onClick(){return switchPanel("rotate")}},{title:"Special text style",html:"Styles\u2026",onClick:function onClick(){return switchPanel("textstyle")}},g(''),{title:"Heading",html:"
H
",onClick:function onClick(){return wrapSelection("\n#","","Heading Text")}},{title:"Bulleted list item",html:y("list-ul"),onClick:function onClick(){return wrapSelection("\n* ","")}},{title:"Numbered list item",html:y("list-ol"),onClick:function onClick(){return wrapSelection("\n0. ","")}},{title:"Horizontal rule",html:"\u2014",onClick:function onClick(){return wrapSelection("\n---\n","")}},{title:"Alignment",html:y("align-right"),onClick:function onClick(){return switchPanel("align")}},{title:"Columns",html:y("columns"),onClick:function onClick(){return switchPanel("columns")}},g(''),{title:"Collapse whitespace (in-game)",html:"{}",onClick:function onClick(){return switchPanel("collapse")}},{title:"Verbatim (ignore all markup)",html:"Vb",onClick:function onClick(){var e=(n.doc.getSelection().match(/`+/g)||[]).reduce(function(e,t){return Math.max(t.length,e)},0);wrapSelection("`".repeat(e+1),"`".repeat(e+1),"Verbatim Text")}},{title:"Comments",html:"<!--",onClick:function onClick(){return wrapSelection("\x3c!--","--\x3e","HTML Comments (Not Visible In-Game)")}},g(''),{title:"Link element",html:"Link\u2026",onClick:function onClick(){return switchPanel("passagelink")}},{title:"Only show a portion of text if a condition is met",html:"If\u2026",onClick:function onClick(){return switchPanel("if")}},{title:"Input element",html:"Input\u2026",onClick:function onClick(){return switchPanel("input")}},{title:"Hook (named section of the passage)",html:"Hook\u2026",onClick:function onClick(){return switchPanel("hook")}},{title:"Set a variable with a data value",html:"Var\u2026",onClick:function onClick(){return switchPanel("basicValue")}},{title:"Peruse a list of all built-in macros",html:"Macro\u2026",onClick:function onClick(){return switchPanel("macro")}},g(''),{title:"Proofreading view (dim all code except strings)",html:y("eye"),onClick:function onClick(e){e=e.target;n.display.wrapper.classList.toggle("harlowe-3-hideCode"),(e="svg"===e.tagName.toLowerCase()?e.parentNode:e).classList.toggle("active")}},{title:"Coding tooltips (show a tooltip when the cursor rests on code structures)",html:y("comment"),active:!0,onClick:function onClick(e){e=e.target;n.display.wrapper.classList.toggle("harlowe-3-hideHelpTooltip"),(e="svg"===e.tagName.toLowerCase()?e.parentNode:e).classList.toggle("active")}},g(''),{title:"Find and replace",html:y("search"),onClick:function onClick(){switchPanel("find");var e=n.doc.getSelection(),t=document[f](".harlowe-3-toolbarPanel textarea");t&&(t.focus(),e)&&(t.value=e,t.dispatchEvent(new Event("input")))}},{title:"Open the Harlowe documentation",html:"
?
",onClick:function onClick(){return window.open("https://twine2.neocities.org/","Harlowe Documentation","noopener,noreferrer")}},((T=g('"))[k]("click",function(){v.classList.toggle("harlowe-3-minimised");var e=T.firstChild.classList;e.toggle("fa-chevron-down"),e.toggle("fa-chevron-up")}),T)]}):h()},switchPanel();var P,H,M="data:image/svg+xml,",L=function svgURI(e){return"".concat(M).concat(window.escape("".concat(e,"")))},d=function t24Icon(e,t,a,r){return L("").concat(r,""))},t=function fontIconURI(e){return"".concat(M).concat(window.escape(y(e)))},_=navigator.userAgent.includes("Macintosh")?"Cmd-":"Ctrl-",E={},R=(_defineProperty(C={name:"harlowe-3-keymap"},_+"G",function(){r.find.parentNode&&n.constructor.signal(n,"harlowe-3-findNext",1)}),_defineProperty(C,"Shift-".concat(_,"G"),function ShiftG(){r.find.parentNode&&n.constructor.signal(n,"harlowe-3-findNext",-1)}),_defineProperty(C,_+"H",function(){var e;r.find.parentNode?(e=r.find[w]("textarea")[1],n.constructor.signal(n,"harlowe-3-replace",e.value,!1)):switchPanel("find")}),C),O=navigator.userAgent.includes("Macintosh")?"\u2318":"Ctrl+",F=u?[]:[{type:"menu",label:"Styles",iconOnly:!0,icon:L("BIS").replace("%2780%27","%27108%27"),items:[{type:"button",key:_+"B",command:function command(){wrapSelection("''","''","Bold Text")},label:"Bold\u2003[".concat(O,"B]")},{type:"button",key:_+"I",command:function command(){wrapSelection("//","//","Italic Text")},label:"Italic\u2003[".concat(O,"I]")},{type:"button",key:_+"-",command:function command(){wrapSelection("~~","~~","Strikethrough Text")},label:"Strikethrough\u2003[".concat(O,"-]")},{type:"button",key:_+".",command:function command(){wrapSelection("^^","^^","Superscript Text")},label:"Superscript\u2003[".concat(O,".]")},{type:"separator"},{type:"button",command:function command(){switchPanel("textstyle")},label:"More Styles\u2026"}]},{type:"button",command:function command(){switchPanel("textcolor")},label:"Colours",iconOnly:!0,icon:L('')},{type:"button",command:function command(){switchPanel("borders")},label:"Borders",iconOnly:!0,icon:t("border-style")},{type:"button",command:function command(){switchPanel("rotate")},label:"Rotated text",iconOnly:!0,icon:d(-3,14,"transform:rotate(-30deg);font-family:serif;","R")},{type:"menu",icon:t("list-ul"),label:"List and line items",iconOnly:!0,items:[{type:"button",command:function command(){wrapSelection("\n* ","")},label:"Bulleted List Item"},{type:"button",command:function command(){wrapSelection("\n0. ","")},label:"Numbered List Item"},{type:"separator"},{type:"button",command:function command(){wrapSelection("\n#","","Heading Text")},label:"Heading"},{type:"button",command:function command(){wrapSelection("\n---\n","")},label:"Horizontal Rule"}]},{type:"menu",icon:t("align-center"),label:"Alignment and columns",iconOnly:!0,items:[{type:"button",command:function command(){switchPanel("align")},label:"Alignment"},{type:"button",command:function command(){switchPanel("columns")},label:"Columns"}]},{type:"button",command:function command(){switchPanel("collapse")},label:"Collapse Whitespace (In-Game)",iconOnly:!0,icon:d(0,10,"font-weight:bold;font-size:12px","{ }")},{type:"button",command:function command(){var e=(n.doc.getSelection().match(/`+/g)||[]).reduce(function(e,t){return Math.max(t.length,e)},0);wrapSelection("`".repeat(e+1),"`".repeat(e+1),"Verbatim Text")},label:"Verbatim (Ignore All Markup Inside)",iconOnly:!0,icon:d(1,12,"font-size:11px","Vb")},{type:"button",command:function command(){wrapSelection("\x3c!--","--\x3e","Comment Text")},label:"HTML Comments (Not Run In-Game)",iconOnly:!0,icon:d(-1,10,"font-weight:bold","⟨!-")},{type:"menu",label:"(Macro:)",items:[{type:"button",command:function command(){switchPanel("passagelink")},label:"Link\u2026",icon:""},{type:"button",command:function command(){switchPanel("if")},label:"If\u2026",icon:""},{type:"button",command:function command(){switchPanel("input")},label:"Input\u2026",icon:""},{type:"button",command:function command(){switchPanel("hook")},label:"Hook\u2026",icon:""},{type:"button",command:function command(){switchPanel("basicValue")},label:"Value\u2026",icon:""},{type:"separator"},{type:"button",command:function command(){switchPanel("macro")},label:"List All Macros\u2026",icon:""}]},P={type:"button",command:function command(){n.display.wrapper.classList.toggle("harlowe-3-hideCode"),n.constructor.signal(n,"cursorActivity")},label:"Proofreading View (dim all code except strings)",iconOnly:!0,icon:t("eye")},H={type:"button",command:function command(){var e=n.display.wrapper;e.classList.toggle("harlowe-3-hideHelpTooltip"),e.classList.toggle("harlowe-3-showHelpTooltip"),l=e.classList.contains("harlowe-3-showHelpTooltip"),o.setPref("tooltips",l),n.constructor.signal(n,"cursorActivity")},label:"Coding Tooltips (when the cursor rests on code structures)",iconOnly:!0,icon:t("comment")},{type:"button",key:_+"F",command:function command(){switchPanel("find");var e=n.doc.getSelection(),t=r.find[f](".harlowe-3-toolbarPanel textarea");t&&(t.focus(),e)&&(t.value=e,t.dispatchEvent(new Event("input")))},label:"Find and Replace\u2003[".concat(O,"F]"),iconOnly:!0,icon:t("search")},{type:"button",command:function command(){window.open("https://twine2.neocities.org/","Harlowe Documentation","noopener,noreferrer")},label:"Show Manual (opens a new tab)",iconOnly:!0,icon:d(3,14,"font-weight:bold;font-size:19px;","?")},{type:"button",command:function command(){switchPanel("prefs")},label:"Editor Preferences",iconOnly:!0,icon:t("gear")}].map(function recur(e,a){var t;return"button"===e.type&&(t=e.command,E[a]=function(e){n=e,t()},e.key&&(R[e.key]=t),e.command=a+""),"menu"===e.type&&(e.items=e.items.map(function(e,t){return recur(e,a+"."+t)})),e});function Toolbar(e){var a=(1t||o.line=t)){if((n.linet||o.ch>a))return o.line>t?e.skipToEnd():e.pos=o.ch,C===r?"harlowe-3-findResultCurrent":"harlowe-3-findResult";if(n.line===t&&n.ch>a)return void(e.pos=n.ch)}}e.skipToEnd()}};function harlowe3Find(e){var t;if(x.removeOverlay(_),A=[],C=-1,e.matches=void 0,e.query){S=e;var a=x.doc,r=-1d.end&&(d=(h=n.pathAt(u))[0]);for(var m=void 0,m=0;m=Math.min(f,w)&&c+s:not(:last-child){display:none}.harlowe-3-toolbarPanel code:not(:empty){font-size:1rem;border:1px dotted hsl(0, 0%, 50%)}.harlowe-3-toolbarPanel [type=radio][disabled]~*{opacity:.5}.harlowe-3-stylePreview{text-align:center;user-select:none;background:black;color:white;font-family:\"Georgia\",serif;padding:8px;font-size:1.5rem;margin:8px auto;width:60%;position:sticky;top:0;z-index:1}.harlowe-3-stylePreview textarea{background:black;color:white}.harlowe-3-stylePreview>span{display:inline-block}.harlowe-3-stylePreview>span:first-child{position:absolute}.harlowe-3-stylePreview>span:last-child{position:relative}.harlowe-3-toolbarPanel>button{border-radius:.8rem;margin:0px 2px;padding:0px 4px;height:36px;font-size:1.2rem;min-width:28px}.harlowe-3-toolbarPanel>button:not(:active):not(.active):not(:last-child){border:1px solid hsla(0, 0%, 50%, 0.5);border-top:none;border-left:none}.harlowe-3-toolbarCheckboxes{border-bottom:1px solid hsla(0, 0%, 50%, 0.5);position:relative;padding-bottom:8px;margin-bottom:8px}.harlowe-3-toolbarPanel label:not(.harlowe-3-radioRow){white-space:nowrap}.harlowe-3-toolbarCheckboxes>label{min-width:20%;display:inline-block}.harlowe-3-swatch{width:24px;height:24px;display:inline-block;cursor:pointer;border-bottom:1px solid hsla(0, 0%, 50%, 0.5);border-right:1px solid hsla(0, 0%, 50%, 0.5)}.harlowe-3-labeledInput{position:relative;padding-bottom:8px}.harlowe-3-labeledInput>input[type=text]{display:inline-block;font-size:1rem}.harlowe-3-labeledInput>input[type=range]{vertical-align:middle}.harlowe-3-labeledInput>input[type=number]{box-shadow:0 1px 0 hsla(0, 0%, 50%, 0.5);background:transparent;color:inherit;border:none;font-family:\"Source Code Pro\",monospace;font-family:var(--font-monospaced);width:4rem;margin:0 .5rem;display:inline-block;font-size:1rem}.harlowe-3-radioRow{margin:8px 0px;display:block}.harlowe-3-radioRow .harlowe-3-radioRow{margin-left:2rem}.harlowe-3-toolbarPanel>*>.harlowe-3-radioRow{border-bottom:1px solid hsla(0, 0%, 50%, 0.5);padding-bottom:8px}.harlowe-3-confirmButtons>span{display:inline-block;align-items:center}.harlowe-3-resultCode{max-width:50%;overflow-x:auto;white-space:pre;display:inline-block;padding:1px 0px}.harlowe-3-resultCode *{white-space:nowrap}.harlowe-3-toolbarBullet{padding:0px 2px;color:hsla(0, 0%, 50%, 0.5)}.harlowe-3-toolbarBullet::before{content:\"\u2022\"}.harlowe-3-bgColourButton{display:inline-block;border-radius:8px;width:16px;height:16px;margin-bottom:-2px;background:linear-gradient(to right, hsla(0, 100%, 50%, 0.5), hsla(30, 100%, 50%, 0.5), hsla(60, 100%, 50%, 0.5), hsla(120, 100%, 50%, 0.5), hsla(180, 100%, 50%, 0.5), hsla(240, 100%, 50%, 0.5), hsla(300, 100%, 50%, 0.5), hsla(320, 100%, 50%, 0.5))}.harlowe-3-gradientBar{display:inline-block;position:relative;width:75%;height:32px;margin:12px 8px 96px 40px;border:1px solid hsla(0, 0%, 50%, 0.5);border-radius:5px}.harlowe-3-gradientBar+button{position:absolute;top:8px;right:8px}.harlowe-3-colourStop{position:absolute;height:48px;width:16px;background:hsla(0, 0%, 50%, 0.5);border-radius:5px;cursor:grab}.harlowe-3-colourStop:active{cursor:grabbing}.harlowe-3-colourStopButtons{display:none;position:relative;top:64px;width:540px;background:hsla(0, 0%, 50%, 0.5);padding:8px;cursor:auto}.harlowe-3-colourStop[selected]{border-bottom-right-radius:0px;border-bottom-left-radius:0px;height:64px}.harlowe-3-colourStop[selected]>.harlowe-3-colourStopButtons{display:block}.harlowe-3-singleColourPicker{display:inline-block}.harlowe-3-singleColourPicker select{position:relative;top:-4px;font-size:1rem;margin-left:8px}.harlowe-3-directionPicker{width:48px;height:48px;border-radius:24px;border:1px solid hsla(0, 0%, 50%, 0.5);display:inline-block}.harlowe-3-hideCode .cm-harlowe-3-root:not(.cm-harlowe-3-text):not(.cm-harlowe-3-string):not(.cm-harlowe-3-verbatim){opacity:.25}.harlowe-3-hideHelpTooltip .harlowe-3-helpTooltip{display:none}.harlowe-3-tooltip{font-family:var(--font-system);max-width:20vw;position:absolute;border:1px solid hsla(0, 0%, 50%, 0.5);padding:8px;display:block;z-index:8}[data-version^=\"2.3\"] .harlowe-3-tooltip{font-family:\"Source Sans Pro\",sans-serif}.theme-light .harlowe-3-tooltip,[data-app-theme=light] .harlowe-3-tooltip{background:white}.theme-dark .harlowe-3-tooltip,[data-app-theme=dark] .harlowe-3-tooltip{background:black}.harlowe-3-tooltipMacroSignature{display:block;padding-top:.5em;margin-top:.5em;border-top:1px solid hsla(0, 0%, 50%, 0.5)}.harlowe-3-tooltipTail{position:absolute;height:0;width:0;border:12px solid transparent;border-bottom-color:hsla(0, 0%, 50%, 0.5)}.harlowe-3-tooltipTail::after{content:\"\";position:absolute;height:0;width:0;left:-12px;top:-10px;border:12px solid transparent}.harlowe-3-completion{max-height:12em;overflow-y:scroll}.harlowe-3-tooltipItemSelected{background-color:#888;background-color:var(--light-gray-translucent)}.theme-light .harlowe-3-tooltipTail::after,[data-app-theme=light] .harlowe-3-tooltipTail::after{border-bottom-color:white}.theme-dark .harlowe-3-tooltipTail::after,[data-app-theme=dark] .harlowe-3-tooltipTail::after{border-bottom-color:black}.harlowe-3-dataEmptyRow:not(:last-child){display:none}.harlowe-3-dataRow .harlowe-3-dropdownRowLabel{font-family:\"Source Code Pro\",monospace;font-family:var(--font-monospaced)}.harlowe-3-textareaRows{margin-bottom:.5em}.harlowe-3-nonZeroRows>:first-child>.harlowe-3-rowMinus{display:none}.harlowe-3-datavalueRows{margin-left:6px;padding-left:6px;border-left:1px solid hsla(0, 0%, 50%, 0.5)}.harlowe-3-toolbarPanel [invalid]::after{display:block;position:absolute;content:attr(invalid);background-color:hsla(17, 100%, 50%, 0.5);right:0px;bottom:8px}.harlowe-3-datavalueRows .harlowe-3-datavalueRows .harlowe-3-datavalueRowHint{display:none}.story-format-toolbar .icon>img:only-child{margin-right:0px}.harlowe-3-toolbarPanel .harlowe-3-confirmButtons{display:flex;justify-content:end}.passage-edit-dialog.collapsed .harlowe-3-toolbarPanel{display:none}.harlowe-3-scrollWrapper{overflow:hidden auto;max-height:60vh}.harlowe-3-toolbarPanel a[href]{color:var(--dark-blue);font-weight:bold}.harlowe-3-toolbarPanel.card{position:absolute;width:576px;height:auto;top:0px;padding:8px}.story-format-toolbar+.harlowe-3-toolbarPanel .harlowe-3-confirmButtons{justify-content:start;flex-flow:row-reverse}.harlowe-3-toolbarPanel textarea,.harlowe-3-toolbarPanel [type=text]{background:var(--white-translucent);border-radius:var(--corner-round);border:1px solid var(--faint-gray);color:var(--dark-gray)}html:not([data-version^=\"2.3\"]) .harlowe-3-toolbarPanel [type=checkbox]{background:transparent;border:2px solid var(--dark-gray);width:16px;height:16px;appearance:none;position:relative;border-radius:2px;margin:0px 6px;vertical-align:middle}html:not([data-version^=\"2.3\"]) .harlowe-3-toolbarPanel [type=checkbox]:checked::before{content:\"\u2714\";position:absolute;right:-2px;top:-4px;margin-right:3px}select>option{background-color:var(--light-gray);color:var(--dark-gray) !important}.harlowe-3-radioRow{padding-left:0px;padding-right:0px;user-select:none;position:relative}.harlowe-3-radioRow>:first-child,.harlowe-3-radioRow>:nth-child(2){cursor:pointer}.harlowe-3-radioRow>div{padding:var(--grid-size)}.harlowe-3-toolbarPanel select{padding:var(--grid-size)}.harloweToolbar+.story-format-toolbar button{padding:calc(var(--grid-size) - 1px)}#root>.dialogs>:not(.passag-edit-stack){z-index:-1}\n",this.modules||(delete this.Markup,delete this.Toolbar,delete this.ToolbarCommands,delete this.Tooltips,delete this.ShortDefs)}.call(eval("this")); -}).call(this); -},"hydrate":"(function(){\n\"use strict\";function _toArray(e){return _arrayWithHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableRest()}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}function _iterableToArrayLimit(e,t){var a=null==e?null:\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(null!=a){var r,o,n,i,s=[],c=!0,l=!1;try{if(n=(a=a.call(e)).next,0===t){if(Object(a)!==a)return;c=!1}else for(;!(c=(r=n.call(a)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=a.return&&(i=a.return(),Object(i)!==i))return}finally{if(l)throw o}}return s}}function _arrayWithHoles(e){if(Array.isArray(e))return e}function _createForOfIteratorHelper(t,a){var r,o,i,c,l=\"undefined\"!=typeof Symbol&&t[Symbol.iterator]||t[\"@@iterator\"];if(l)return o=!(r=!0),{s:function s(){l=l.call(t)},n:function n(){var e=l.next();return r=e.done,e},e:function e(t){o=!0,i=t},f:function f(){try{r||null==l.return||l.return()}finally{if(o)throw i}}};if(Array.isArray(t)||(l=_unsupportedIterableToArray(t))||a&&t&&\"number\"==typeof t.length)return l&&(t=l),c=0,{s:a=function F(){},n:function n(){return c>=t.length?{done:!0}:{done:!1,value:t[c++]}},e:function e(t){throw t},f:a};throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}function _unsupportedIterableToArray(e,t){var a;if(e)return\"string\"==typeof e?_arrayLikeToArray(e,t):\"Map\"===(a=\"Object\"===(a=Object.prototype.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:a)||\"Set\"===a?Array.from(e):\"Arguments\"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(e,t):void 0}function _iterableToArray(e){if(\"undefined\"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e[\"@@iterator\"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var a=0,r=new Array(t);a=n.length)&&!g.isFront)continue}s=this.end)return null;if(this.children.length)for(var t=0;t=this.children[t].start&&e=this.end)return[];var t=[];if(this.children.length)for(var a=0;a=this.children[a].start&&e=this.end?null:this.children?this.children.reduce(function(e,t){return e||(a>=t.start&&a|<=+|=+><=+|<==+>)\"+o+l,l=o+\"(=+\\\\|+|\\\\|+=+|=+\\\\|+=+|\\\\|=+\\\\|)\"+o+l,p={opener:\"\\\\[\\\\[(?!\\\\[)\",text:\"(\"+function notChars(){return\"[^\"+Array.apply(0,arguments).map(escape).join(\"\")+\"]*\"}(\"]\")+\")\",rightSeparator:t(\"\\\\->\",\"\\\\|\"),leftSeparator:\"<\\\\-\",closer:\"\\\\]\\\\]\",legacySeparator:\"\\\\|\",legacyText:\"(\"+t(\"[^\\\\|\\\\]]\",\"\\\\]\"+a(\"\\\\]\"))+\"+)\"},g=c+\"*\"+c.replace(\"\\\\w\",\"a-zA-Z\")+c+\"*\",y=\"\\\\$(\"+g+\")\",b=\"_(\"+g+\")\",f=\"'s\"+n+a(\"_\")+\"(\"+g+\")\",w=\"(\"+g+\")\"+n+\"of\"+i+a(\"it\\\\b\"),k=\"'s\"+n,v=t(\"it\",\"time\",\"turns?\",\"visits?\",\"exits?\",\"pos\")+i,x=\"its\"+n+\"(\"+g+\")\",T=\"(\"+g+\")\"+n+\"of\"+n+\"it\"+i,C=\"of\"+n+\"it\"+i,S={opener:\"\\\\(\",name:\"(\"+t(\"\\\\$\",\"_\")+\"?\"+s+\"+):\"+a(\"\\\\/\"),closer:\"\\\\)\"},A=t(\"=<\",\"=>\",\"[gl]te?\\\\b\",\"n?eq\\\\b\",\"isnot\\\\b\",\"are\\\\b\",\"x\\\\b\",\"isa\\\\b\",\"or\"+n+\"a\"+i),N=\"[a-zA-Z][\\\\w\\\\-]*\",_=\"(?:\\\"[^\\\"]*\\\"|'[^']*'|[^'\\\">])*?\",O=\"\\\\|(\"+s+\"+)(>|\\\\))\",P=\"(<|\\\\()(\"+s+\"+)\\\\|\",L=\"((?:\\\\b\\\\d+(?:\\\\.\\\\d+)?|\\\\.\\\\d+)(?:[eE][+\\\\-]?\\\\d+)?)\"+a(\"m?s\")+i;p.main=p.opener+t(p.text+p.rightSeparator,p.text.replace(\"*\",\"*?\")+p.leftSeparator)+p.text,e={upperLetter:\"[A-Z\\\\u00c0-\\\\u00de\\\\u0150\\\\u0170]\",lowerLetter:\"[a-z0-9_\\\\-\\\\u00df-\\\\u00ff\\\\u0151\\\\u0171]\",anyLetter:s,anyLetterStrict:c,whitespace:n.replace(\"[\",\"[\\\\n\\\\r\"),escapedLine:\"\\\\\\\\\\\\n\\\\\\\\?|\\\\n\\\\\\\\\",br:\"\\\\n(?!\\\\\\\\)\",tag:\"<\\\\/?\"+N+_+\">\",scriptStyleTag:\"<(\"+t(\"script\",\"style\",\"textarea\")+\")\"+_+\">[^]*?<\\\\/\\\\1>\",scriptStyleTagOpener:\"<\",url:\"(\"+t(\"https?\",\"mailto\",\"javascript\",\"ftp\",\"data\")+\":\\\\/\\\\/[^\\\\s<]+[^<.,:;\\\"')\\\\]\\\\s])\",bullet:\"\\\\*\",hr:u,heading:\"[ \\\\f\\\\t\\\\v\\\\u00a0\\\\u2000-\\\\u200a\\\\u2028\\\\u2029\\\\u202f\\\\u205f\\\\u3000]*(#{1,6})[ \\\\f\\\\t\\\\v\\\\u00a0\\\\u2000-\\\\u200a\\\\u2028\\\\u2029\\\\u202f\\\\u205f\\\\u3000]*\",align:m,column:l,bulleted:h,numbered:d,verbatimOpener:\"`+\",hookAppendedFront:\"\\\\[\"+a(\"=+\"),hookPrependedFront:O+\"\\\\[\"+a(\"=+\"),hookFront:\"\\\\[\"+a(\"=+\"),hookBack:\"\\\\]\"+a(P),hookAppendedBack:\"\\\\]\"+P,unclosedHook:\"\\\\[=+\",unclosedHookPrepended:O+\"\\\\[=+\",unclosedCollapsed:\"\\\\{=+\",passageLink:p.main+p.closer,legacyLink:p.opener+p.legacyText+p.legacySeparator+p.legacyText+p.closer,simpleLink:p.opener+p.legacyText+p.closer,macroFront:S.opener+r(S.name),macroName:S.name,groupingFront:\"\\\\(\"+a(S.name),twine1Macro:\"<<[^>\\\\s]+\\\\s*(?:\\\\\\\\.|'(?:[^'\\\\\\\\]*\\\\\\\\.)*[^'\\\\\\\\]*'|\\\"(?:[^\\\"\\\\\\\\]*\\\\\\\\.)*[^\\\"\\\\\\\\]*\\\"|[^'\\\"\\\\\\\\>]|>(?!>))*>>\",validPropertyName:g,property:f,belongingProperty:w,possessiveOperator:k,belongingOperator:\"of\\\\b\",itsOperator:\"its\\\\b\",belongingItOperator:C,variable:y,tempVariable:b,hookName:\"\\\\?(\"+s+\"+)\\\\b\",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\",\"Transparent\"),\"#[\\\\dA-Fa-f]{3}(?:[\\\\dA-Fa-f]{3})?\"),datatype:t(\"alnum\",\"alphanumeric\",\"any(?:case)?\",\"array\",\"bool(?:ean)?\",\"changer\",\"codehook\",\"colou?r\",\"const\",\"command\",\"dm\",\"data\"+t(\"map\",\"type\",\"set\"),\"ds\",\"digit\",\"gradient\",\"empty\",\"even\",\"int\"+a(\"o\")+\"(?:eger)?\",\"lambda\",\"lowercase\",\"macro\",\"linebreak\",\"newline\",\"num(?:ber)?\",\"odd\",\"str(?:ing)?\",\"uppercase\",\"whitespace\")+i,number:L,boolean:t(\"true\",\"false\")+i,identifier:v,itsProperty:x,belongingItProperty:T,escapedStringChar:\"\\\\\\\\[^\\\\n]\",singleStringOpener:\"'\",doubleStringOpener:'\"',singleStringCloser:\"'\",doubleStringCloser:'\"',is:\"is\"+a(n+\"not\"+i,n+\"an?\"+i,n+\"in\"+i,n+\"<\",n+\">\")+i,isNot:\"is\"+n+\"not\"+a(n+t(\"an?\",\"in\")+i)+i,isA:\"is\"+n+\"an?\"+i,isNotA:\"is\"+n+\"not\"+n+\"an?\"+i,matches:\"matches\\\\b\",doesNotMatch:\"does\"+n+\"not\"+n+\"match\"+i,and:\"and\\\\b\",or:\"or\\\\b\",not:\"not\\\\b\",inequality:\"((?:is(?:\"+n+\"not)?\"+o+\")*)(\"+t(\"<(?!=)\",\"<=\",\">(?!=)\",\">=\")+\")\",isIn:\"is\"+n+\"in\"+i,contains:\"contains\\\\b\",doesNotContain:\"does\"+n+\"not\"+n+\"contain\"+i,isNotIn:\"is\"+n+\"not\"+n+\"in\"+i,addition:escape(\"+\")+a(\"=\"),subtraction:escape(\"-\")+a(\"=\",\"type\"),multiplication:escape(\"*\")+a(\"=\"),division:t(\"/\",\"%\")+a(\"=\"),spread:\"\\\\.\\\\.\\\\.\"+a(\"\\\\.\"),to:t(\"to\\\\b\",\"=\"),into:\"into\\\\b\",making:\"making\\\\b\",where:\"where\\\\b\",when:\"when\\\\b\",via:\"via\\\\b\",each:\"each\\\\b\",augmentedAssign:t(\"\\\\+\",\"\\\\-\",\"\\\\*\",\"\\\\/\",\"%\")+\"=\",bind:\"2?bind\\\\b\",typeSignature:escape(\"-type\")+i,incorrectOperator:A,PlainCompare:{comma:\",\",commentFront:\"\\x3c!--\",commentBack:\"--\\x3e\",strikeOpener:\"~~\",italicOpener:\"//\",boldOpener:\"''\",supOpener:\"^^\",strongFront:\"**\",strongBack:\"**\",emFront:\"*\",emBack:\"*\",collapsedFront:\"{\",collapsedBack:\"}\",groupingBack:\")\"}},\"object\"===(\"undefined\"==typeof module?\"undefined\":_typeof(module))?module.exports=e:\"function\"==typeof define&&define.amd?define(\"patterns\",[],function(){return e}):this&&this.loaded?(this.modules||(this.modules={}),this.modules.Patterns=e):this.Patterns=e}.call(eval(\"this\")||(\"undefined\"!=typeof global?global:window)),!function(){Object.assign=Object.assign||function polyfilledAssign(e){for(var t=1;t<\");return~a?25===(t=Math.round(a/(e.length-2)*50))&&(t=\"center\"):\"<\"===e[0]&&\">\"===e.slice(-1)?t=\"justify\":-1\")?t=\"right\":-1\":\">=\",\"=<\":\"<=\",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 \"+(t?\"'\"+t+\"'\":\"something else\")+\" instead of '\"+e[0]+\"'.\",explanation:\"In the interests of readability, I want certain operators to be in a specific form.\"}},cannotFollowText:!0}},[\"boolean\",\"is\",\"to\",\"into\",\"where\",\"when\",\"via\",\"making\",\"each\",\"and\",\"or\",\"not\",\"isNot\",\"contains\",\"doesNotContain\",\"isIn\",\"isA\",\"isNotA\",\"isNotIn\",\"matches\",\"doesNotMatch\",\"bind\"].reduce(function(e,t){return e[t]={fn:a,cannotFollowText:!0},e},{})),[\"comma\",\"spread\",\"typeSignature\",\"addition\",\"subtraction\",\"multiplication\",\"division\"].reduce(function(e,t){return e[t]={fn:a},e},{}))),h=setupRules(o,{singleStringCloser:l.singleStringOpener,doubleStringCloser:l.doubleStringOpener,escapedStringChar:l.escapedStringChar}),d=(r.push.apply(r,_toConsumableArray(m(n)).concat(_toConsumableArray(m(c)),_toConsumableArray(m(s)))),t.push.apply(t,_toConsumableArray(m(c)).concat(_toConsumableArray(m(l)))),o.push.apply(o,_toConsumableArray(m(h))),_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({},n),s),c),l),h));return m(d).forEach(function(e){u.PlainCompare[e]?(d[e].pattern=u.PlainCompare[e],d[e].plainCompare=!0):d[e].pattern=RegExp(\"^(?:\"+u[e]+\")\",\"i\")}),p(e.rules,d),(s=e.modes).start=s.markup=r,s.macro=t,s.string=o,e}(e).lex,Patterns:u})}\"object\"===(\"undefined\"==typeof module?\"undefined\":_typeof(module))?(u=require(\"./patterns\"),module.exports=exporter(require(\"./lexer\"))):\"function\"==typeof define&&define.amd?define(\"markup\",[\"lexer\",\"patterns\"],function(e,t){return u=t,exporter(e)}):this&&this.loaded&&this.modules?(u=this.modules.Patterns,this.modules.Markup=exporter(this.modules.Lexer)):(u=this.Patterns,this.Markup=exporter(this.Lexer))}.call(eval(\"this\")||(\"undefined\"!=typeof global?global:window)),!function(){var t=Math.round,e=function insensitiveName(e){return(e+\"\").toLowerCase().replace(/-|_/g,\"\")},a={\"#e61919\":\"red\",\"#e68019\":\"orange\",\"#e5e619\":\"yellow\",\"#80e619\":\"lime\",\"#19e619\":\"green\",\"#19e5e6\":\"cyan\",\"#197fe6\":\"blue\",\"#1919e6\":\"navy\",\"#7f19e6\":\"purple\",\"#e619e5\":\"magenta\",\"#ffffff\":\"white\",\"#000000\":\"black\",\"#888888\":\"grey\"},r=function fontIcon(e){var t=1')},o=function GCD(e,t){return e?t?t
\")}).join(\"\")}}}(o,r,e)||function keywordCompletion(t,e,a){if(!1!==c().completionsForKeywords&&a.reduce(function(e,t){return void 0===e?\"macro\"===t.type||\"hook\"!==t.type&&\"string\"!==t.type&&e:e},void 0)){var r=_slicedToArray(/[^$\\w?]([-2]?[a-zA-Z ]+)$/.exec(e)||[],2)[1];if(r&&\"-\"!==r&&\"\"!==r[r.length-1].trim()){var o=r.trimLeft().toLowerCase(),n=C.filter(function(e){return e.name.startsWith(o)}).sort(function(e,t){return e.name.length-t.name.length});if(n.length)return k=function tooltipMenuCallback(e){t.replaceRange(n[e].name,x(t,-r.length),t.getCursor())},f=0,w=n.length,n.map(function(e,t){return\"
\").concat(e.name,'').concat(e.label||e.type,\"
\")}).join(\"\")}}}(o,r,e);return o&&(p.innerHTML=o,positionTooltip(a,t,!(p.className=\"harlowe-3-tooltip harlowe-3-completion\")),g=0,a.addKeyMap(v),f=0,1)}function Tooltips(e,t){var a=t.tree,t=t.lastAction,r=e.cm,o=(tooltipClear(r),r.display.wrapper),n=(p.parentNode!==o&&(o.append(p),o.addEventListener(\"mousemove\",function(){\"none\"===p.style.display||o.querySelector(\".harlowe-3-tooltip:hover\")?0\".concat(t,\"\")}),p.innerHTML=o+(0
Use the \".concat((document.querySelector('[aria-label^=\"Coding tooltips\"],[title^=\"Coding tooltips\"]')||{}).innerHTML||\"tooltip\",\" toolbar button to toggle these popups!\")):\"\")+\"
\",p.className=\"harlowe-3-tooltip harlowe-3-helpTooltip\",positionTooltip(a,t,!0),p.style.display=\"none\",g=50):void 0})(a,n,r)&&!e&&tooltipAppear()):g=0}this&&this.loaded?this.modules.Tooltips=Tooltips:this.window||(this.Tooltips=Tooltips)}.call(eval(\"this\")),!function(){var P=JSON.stringify,L={},I={};if(this&&this.loaded)var e=this.modules,H=e.Markup.lex,a=e.Patterns,L=e.Utils;else{if(this.window)return;H=this.Markup.lex,a=this.Patterns,L=this.Utils}var e=L,M=e.twine23,n=e.builtinColourNames,E=e.buttonClass,R=e.toHarloweColour,F=e.toCSSColour,z=e.el,D=e.fontIcon,W=\"querySelector\",B=W+\"All\",j=\"addEventListener\",q=\"removeEventListener\",i=[[\"#f8f9fa\",\"#fff5f5\",\"#fff0f6\",\"#f8f0fc\",\"#f3f0ff\",\"#edf2ff\",\"#e7f5ff\",\"#e3fafc\",\"#e6fcf5\",\"#ebfbee\",\"#f4fce3\",\"#fff9db\",\"#fff4e6\"],[\"#f1f3f5\",\"#ffe3e3\",\"#ffdeeb\",\"#f3d9fa\",\"#e5dbff\",\"#dbe4ff\",\"#d0ebff\",\"#c5f6fa\",\"#c3fae8\",\"#d3f9d8\",\"#e9fac8\",\"#fff3bf\",\"#ffe8cc\"],[\"#e9ecef\",\"#ffc9c9\",\"#fcc2d7\",\"#eebefa\",\"#d0bfff\",\"#bac8ff\",\"#a5d8ff\",\"#99e9f2\",\"#96f2d7\",\"#b2f2bb\",\"#d8f5a2\",\"#ffec99\",\"#ffd8a8\"],[\"#dee2e6\",\"#ffa8a8\",\"#faa2c1\",\"#e599f7\",\"#b197fc\",\"#91a7ff\",\"#74c0fc\",\"#66d9e8\",\"#63e6be\",\"#8ce99a\",\"#c0eb75\",\"#ffe066\",\"#ffc078\"],[\"#ced4da\",\"#ff8787\",\"#f783ac\",\"#da77f2\",\"#9775fa\",\"#748ffc\",\"#4dabf7\",\"#3bc9db\",\"#38d9a9\",\"#69db7c\",\"#a9e34b\",\"#ffd43b\",\"#ffa94d\"],[\"#adb5bd\",\"#ff6b6b\",\"#f06595\",\"#cc5de8\",\"#845ef7\",\"#5c7cfa\",\"#339af0\",\"#22b8cf\",\"#20c997\",\"#51cf66\",\"#94d82d\",\"#fcc419\",\"#ff922b\"],[\"#868e96\",\"#fa5252\",\"#e64980\",\"#be4bdb\",\"#7950f2\",\"#4c6ef5\",\"#228be6\",\"#15aabf\",\"#12b886\",\"#40c057\",\"#82c91e\",\"#fab005\",\"#fd7e14\"],[\"#495057\",\"#f03e3e\",\"#d6336c\",\"#ae3ec9\",\"#7048e8\",\"#4263eb\",\"#1c7ed6\",\"#1098ad\",\"#0ca678\",\"#37b24d\",\"#74b816\",\"#f59f00\",\"#f76707\"],[\"#343a40\",\"#e03131\",\"#c2255c\",\"#9c36b5\",\"#6741d9\",\"#3b5bdb\",\"#1971c2\",\"#0c8599\",\"#099268\",\"#2f9e44\",\"#66a80f\",\"#f08c00\",\"#e8590c\"],[\"#212529\",\"#c92a2a\",\"#a61e4d\",\"#862e9c\",\"#5f3dc4\",\"#364fc7\",\"#1864ab\",\"#0b7285\",\"#087f5b\",\"#2b8a3e\",\"#5c940d\",\"#e67700\",\"#d9480f\"]],V=function dataValueRow(){var r=0An array is a sequence of ordered datavalues that can be used without having to create separate variables for each. Use it to store similar values whose order and position matter, or to store an ever-changing quantity of similar values.
\",model:function model(e,t){r(e,\"(a:\"+t+\")\")},renumber:function renumber(e,t){var a=((t+=1)+\"\").slice(-1);e.textContent=t+(\"1\"===a?\"st\":\"2\"===a?\"nd\":\"3\"===a?\"rd\":\"th\")+\": \"},modelRegistry:e}],[\"datamap\",{type:\"datavalue-map\",text:\"
A datamap is a value that holds any number of other values, each of which is \\\"mapped\\\" to a unique name. Use it to store data values that represent parts of a larger game entity, or rows of a table.
\",model:function model(e,t){t.every(function(e,t){return t%2!=0||'\"\"'!==e&&\"''\"!==e})||(e.invalidSubrow=!0),r(e,\"(dm:\"+t+\")\")},renumber:function renumber(e){e.textContent=\":\"},modelRegistry:e}],[],[\"randomly chosen value\",{type:\"datavalue-rows\",text:\"
One of the following values is randomly chosen each time the macro is run.
\",model:function model(e,t){t.length||(e.invalidSubrow=!0),r(e,\"(either:\"+t+\")\")},renumber:function renumber(e){e.textContent=\"\\u2022\",e.style.marginRight=\"0.5em\"},modelRegistry:e}],[\"random number\",z(\"
A number between these two values is randomly chosen each time the macro is run.
\"),{type:\"inline-number-textarea\",width:\"20%\",text:\"From\",model:function model(){},modelRegistry:e},{type:\"inline-number-textarea\",width:\"20%\",text:\"to\",model:function model(e,t){r(e,\"(random:\"+(+t.previousElementSibling[W](\"input\").value||0)+\",\"+(+t[W](\"input\").value||0)+\")\")},modelRegistry:e}]].concat(t?[]:[[],[\"itself + value\",{type:\"datavalue-inner\",text:\"
The following value is added to the existing value in the variable. NOTE: if the values aren't the same type of data, an error will result.
\",model:function model(e,t){1!==t.length&&(e.invalidSubrow=!0),r(e,\"it + \"+t)},renumber:function renumber(e){(e||{}).textContent=\"it + \"},modelRegistry:e}],[\"variable + value\",{type:\"inline-dropdown\",text:\" Other variable: \",options:[\"$\",\"_\"],model:function model(e,t){e.innerVariable=t[W](\"select\").value?\"_\":\"$\"}},{type:\"inline-textarea\",width:\"25%\",text:\"\",placeholder:\"Variable name\",model:function model(e,t){t=t[W](\"input\").value;t&&RegExp(\"^\"+a.validPropertyName+\"$\").exec(t)&&!RegExp(/^\\d/).exec(t)&&(e.innerVariable+=t)}},{type:\"datavalue-inner\",text:\"
The above variable's value and the value below are added together. NOTE: if the values aren't the same type of data, an error will result.
\",model:function model(e,t){1!==t.length&&(e.invalidSubrow=!0),r(e,e.innerVariable+\" + \"+t)},renumber:function renumber(e){(e||{}).textContent=\"\"},modelRegistry:e}]]).concat([[],[\"coded expression\",{type:\"expression-textarea\",width:\"90%\",text:\"
Write a Harlowe code expression that should be computed to produce the desired value.
\",placeholder:\"Code\",modelCallback:r,modelRegistry:e}]])}};I.Panel=function folddownPanel(){for(var e=arguments.length,t=new Array(e),a=0;a')),O=function makeColourPicker(e){var a=function makeSwatchRow(e,t,a){return z('\")+e.map(function(e){return''}).join(\"\")+\"\")},r=z('
'),e=z('')),o=e[W](\"select\");return r.append(a(Object.keys(n),\"\",!0)),i.forEach(function(e,t){r.append(a(e,t)),o.append(z(\"\")))}),o[j](\"change\",function(){r[B](\"[data-index]\").forEach(function(e){return e.style.display=\"none\"}),r[W]('[data-index=\"'.concat(o.value,'\"]')).style.display=\"inline-block\"}),r.append(e,z(\"
\"),new Text(\"Opacity: \"),z('')),r[j](\"click\",function(e){var t,e=e.target;e.classList.contains(\"harlowe-3-swatch\")&&((t=r[W](\"input\")).value=e.getAttribute(\"style\").slice(-7),t.dispatchEvent(new Event(\"change\")))}),r},e=t.reduce(function reducer(o,n){var e,i,a,s,t,r,c,l,h,d,u,m,p,g,y,b,f,w,k,v,x,T,C=\"\",S=\"label\"===o.tagName.toLowerCase();return Object.getPrototypeOf(n)!==Object.prototype?i=n:k=(C=n.type).startsWith(\"inline\"),C.endsWith(\"text\")&&(i=z(\"<\".concat(k?\"span\":\"div\",\">\").concat(n.text,\"\"))),\"notice\"===C&&(i=z(''.concat(n.text,\"\"))),\"buttons\"===C&&o.append.apply(o,_toConsumableArray(n.buttons.map(function(t){var a;return\"tagName\"in t?t:(a=z('\")),t.onClick&&a[j](\"click\",t.onClick),t.update&&N.push(function(e){return t.update(e,a)}),a)}))),C.endsWith(\"preview\")&&(v=n.tagName||\"span\",i=z('
<\").concat(v,\">\").concat(n.text||\"\",\"\").concat(C.startsWith(\"t8n\")?\"<\".concat(v,\">\")+n.text2+\"\"):\"\",\"
\")),C.startsWith(\"t8n\"))&&(i[j](\"mouseup\",update),i[j](\"touchend\",update),(e=i[W](\":first-child\"))[j](\"animationend\",function(){return e.style.visibility=\"hidden\"})),(C.endsWith(\"checkbox\")||C.endsWith(\"checkboxrow\"))&&(i=z(\"\").concat(n.text,\"\")),C.endsWith(\"w\")&&(n.subrow.reduce(reducer,i),n.subrow.forEach(function(e){var a=e.model;e.model=function(e,t){return!i[W](\":scope > input:checked\")||S&&!o[W](\":scope > input:checked\")?e:a(e,t)}})),i[j](\"change\",update)),\"checkboxes\"===C&&(i=z('
\").concat(n.name,\"
\")),n.options.forEach(function(e,t){var a=z(\"\").concat(e,\"\"));a[j](\"change\",update),i.append(a)})),\"radios\"===C&&(i=z('
\").concat(n.name,\"
\")),n.options.forEach(function(e,t){t=z(\"\").concat(e,\"\"));t[j](\"change\",update),i.append(t)})),C.endsWith(\"textarea\")&&(v=\"text\",a=n.multiline?\"textarea\":\"input\",C.endsWith(\"expression-textarea\")&&(n.update=function(e,t){!e.expression&&t[W](a).value?t.setAttribute(\"invalid\",\"This doesn't seem to be valid code.\"):t.removeAttribute(\"invalid\")},n.model=function(e,t){t=(t[W](a).value||\"\").trim();t&&(H(t,\"\",\"macro\").children.every(function recur(e){return\"text\"!==e.type&&\"error\"!==e.type&&(\"string\"===e.type||\"hook\"===e.type||e.children.every(recur))})?n.modelCallback(e,t):e.valid=!0)}),C.endsWith(\"string-textarea\")&&!n.model&&(n.model=function(e,t){n.modelCallback(e,JSON.stringify(t[W](a).value||\"\"))}),C.endsWith(\"number-textarea\")&&(v=\"number\",n.model||(n.model=function(e,t){n.modelCallback(e,+t[W](a).value||0)})),(i=z(\"<\".concat(k?\"span\":\"div\",' class=\"harlowe-3-labeledInput\">').concat(n.text,\"<\").concat(a,\" \").concat(n.useSelection?\"data-use-selection\":\"\").concat(C.includes(\"passage\")?'list=\"harlowe-3-passages\"':\"\",' style=\"width:').concat(n.width,\";\").concat(n.multiline?\"max-width:\".concat(n.width,\";\"):\"\",\"padding:var(--grid-size);margin\").concat(k?\":2px 0.5rem 0 0.5rem\":\"-left:1rem\",\";\").concat(n.multiline&&k?\"display:inline-block;height:40px\":\"\",'\" type=').concat(v,\" \").concat(n.persist?\"data-persist\":\"\",' placeholder=\"').concat(n.placeholder||\"\",'\">\")))[W](a)[j](\"input\",update)),(C.endsWith(\"number\")||C.endsWith(\"range\"))&&(i=z(\"<\"+(k?\"span\":\"div\")+' class=\"harlowe-3-labeledInput\">'+n.text+''+n.text+\"\"),v=O(n.value),i.append(v),i[B](\"input\").forEach(function(e){return e[j](\"change\",update)})),C.endsWith(\"gradient\")&&(s=(i=z(\"
\")))[W](\".harlowe-3-gradientBar\"),t=function createColourStop(e,t,a){var r=z(\"
')+\"
\"),o=O(t),a=(o[B](\"input\").forEach(function(e){return e[j](\"change\",function(){var e=o[W](\"[type=range]\").value,t=o[W](\"[type=color]\").value;r.setAttribute(\"data-colour\",F(t,e)),e<1&&r.setAttribute(\"data-harlowe-colour\",R(t,e)),update()})}),z('\")));a[j](\"click\",function(){r.remove(),update()}),o.append(a),r.firstChild.prepend(o),s.append(r),update()},setTimeout(function(){t(0,\"#ffffff\"),t(.5,\"#000000\",!0),t(1,\"#ffffff\")}),i[W](\"button\")[j](\"click\",function(){return t(.5,\"#888888\")}),i[j](\"mousedown\",v=function listener(e){var t,a,r,o,n=e.target;n.classList.contains(\"harlowe-3-colourStop\")&&(t=document.documentElement,e=s.getBoundingClientRect(),a=e.left,r=e.right-a,e=function onMouseUp(){t[q](\"mousemove\",o),t[q](\"mouseup\",onMouseUp),t[q](\"touchmove\",o),t[q](\"touchend\",onMouseUp)},t[j](\"mousemove\",o=function onMouseMove(e){var t=e.pageX,e=e.touches;void 0!==(t=t||(null==e?void 0:e[0].pageX))&&(e=Math.min(1,Math.max(0,(t-window.scrollX-a)/r)),n.style.left=\"calc(\".concat(100*e,\"% - 8px)\"),n.firstChild.style.left=\"\".concat(-(M?464:384)*e-(M?0:40),\"px\"),n.setAttribute(\"data-pos\",e),update())}),t[j](\"mouseup\",e),t[j](\"touchmove\",o),t[j](\"touchend\",e),Array.from(s[B](\"[selected]\")).forEach(function(e){return e.removeAttribute(\"selected\")}),n.setAttribute(\"selected\",!0))}),i[j](\"touchstart\",v),N.push(function(){s.style.background=\"linear-gradient(to right, \".concat(Array.from(s[B](\".harlowe-3-colourStop\")).sort(function(e,t){return e.getAttribute(\"data-pos\")-t.getAttribute(\"data-pos\")}).map(function(e){return e.getAttribute(\"data-colour\")+\" \"+100*e.getAttribute(\"data-pos\")+\"%\"}),\")\")})),C.endsWith(\"dropdown\")&&(r=z(\"<\".concat(k?\"span\":\"div\",' style=\"white-space:nowrap;').concat(k?\"\":\"width:50%;\",'position:relative;\">').concat(n.text,'\")),n.options.forEach(function(e,t){r[W](\"select\").append(z('