narrat 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // Version: 1.1.0 - June 25, 2022 09:56:51
1
+ // Version: 1.3.0 - June 25, 2022 18:05:43
2
2
  'use strict';
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -34,7 +34,7 @@ function styleInject(css, ref) {
34
34
  }
35
35
  }
36
36
 
37
- var css_248z = "/*! @import */\n\n/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */\n\n/*\nDocument\n========\n*/\n\n/**\nUse a better box model (opinionated).\n*/\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n/**\nUse a more readable tab size (opinionated).\n*/\n\n:root {\n -moz-tab-size: 4;\n -o-tab-size: 4;\n tab-size: 4;\n}\n\n/**\n1. Correct the line height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n*/\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/*\nSections\n========\n*/\n\n/**\nRemove the margin in all browsers.\n*/\n\nbody {\n margin: 0;\n}\n\n/**\nImprove consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n*/\n\nbody {\n font-family:\n\t\tsystem-ui,\n\t\t-apple-system, /* Firefox supports this but not yet `system-ui` */\n\t\t'Segoe UI',\n\t\tRoboto,\n\t\tHelvetica,\n\t\tArial,\n\t\tsans-serif,\n\t\t'Apple Color Emoji',\n\t\t'Segoe UI Emoji';\n}\n\n/*\nGrouping content\n================\n*/\n\n/**\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n}\n\n/*\nText-level semantics\n====================\n*/\n\n/**\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr[title] {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/**\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n2. Correct the odd 'em' font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family:\n\t\tui-monospace,\n\t\tSFMono-Regular,\n\t\tConsolas,\n\t\t'Liberation Mono',\n\t\tMenlo,\n\t\tmonospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/**\nPrevent 'sub' and 'sup' elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\nTabular data\n============\n*/\n\n/**\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n}\n\n/*\nForms\n=====\n*/\n\n/**\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\nRemove the inheritance of text transform in Edge and Firefox.\n1. Remove the inheritance of text transform in Firefox.\n*/\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\nCorrect the inability to style clickable types in iOS and Safari.\n*/\n\nbutton,\n[type='button'],\n[type='reset'] {\n -webkit-appearance: button;\n}\n\n/**\nRemove the inner border and padding in Firefox.\n*/\n\n/**\nRestore the focus styles unset by the previous rule.\n*/\n\n/**\nRemove the additional ':invalid' styles in Firefox.\nSee: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737\n*/\n\n/**\nRemove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.\n*/\n\nlegend {\n padding: 0;\n}\n\n/**\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n/**\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n/**\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to 'inherit' in Safari.\n*/\n\n/*\nInteractive\n===========\n*/\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/**\n * Manually forked from SUIT CSS Base: https://github.com/suitcss/base\n * A thin layer on top of normalize.css that provides a starting point more\n * suitable for web applications.\n */\n\n/**\n * Removes the default spacing and border for appropriate elements.\n */\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nbutton {\n background-color: transparent;\n background-image: none;\n}\n\n/**\n * Work around a Firefox/IE bug where the transparent `button` background\n * results in a loss of the default `button` focus styles.\n */\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nol,\nul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/**\n * Tailwind custom reset styles\n */\n\n/**\n * 1. Use the user's configured `sans` font-family (with Tailwind's default\n * sans-serif font stack as a fallback) as a sane default.\n * 2. Use Tailwind's default \"normal\" line-height so the user isn't forced\n * to override it to ensure consistency even when using the default theme.\n */\n\nhtml {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 1 */\n line-height: 1.5; /* 2 */\n}\n\n/**\n * Inherit font-family and line-height from `html` so users can set them as\n * a class directly on the `html` element.\n */\n\nbody {\n font-family: inherit;\n line-height: inherit;\n}\n\n/**\n * 1. Prevent padding and border from affecting element width.\n *\n * We used to set this in the html element and inherit from\n * the parent element for everything else. This caused issues\n * in shadow-dom-enhanced elements like <details> where the content\n * is wrapped by a div with box-sizing set to `content-box`.\n *\n * https://github.com/mozdevs/cssremedy/issues/4\n *\n *\n * 2. Allow adding a border to an element by just adding a border-width.\n *\n * By default, the way the browser specifies that an element should have no\n * border is by setting it's border-style to `none` in the user-agent\n * stylesheet.\n *\n * In order to easily add borders to elements by just setting the `border-width`\n * property, we change the default border-style for all elements to `solid`, and\n * use border-width to hide them instead. This way our `border` utilities only\n * need to set the `border-width` property instead of the entire `border`\n * shorthand, making our border utilities much more straightforward to compose.\n *\n * https://github.com/tailwindcss/tailwindcss/pull/116\n */\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n/*\n * Ensure horizontal rules are visible by default\n */\n\nhr {\n border-top-width: 1px;\n}\n\n/**\n * Undo the `border-style: none` reset that Normalize applies to images so that\n * our `border-{width}` utilities have the expected effect.\n *\n * The Normalize reset is unnecessary for us since we default the border-width\n * to 0 on all elements.\n *\n * https://github.com/tailwindcss/tailwindcss/issues/362\n */\n\nimg {\n border-style: solid;\n}\n\ntextarea {\n resize: vertical;\n}\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n color: #9ca3af;\n}\n\ninput:-ms-input-placeholder, textarea:-ms-input-placeholder {\n color: #9ca3af;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n color: #9ca3af;\n}\n\nbutton {\n cursor: pointer;\n}\n\ntable {\n border-collapse: collapse;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/**\n * Reset links to optimize for opt-in styling instead of\n * opt-out.\n */\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/**\n * Reset form element properties that are easy to forget to\n * style explicitly so you don't inadvertently introduce\n * styles that deviate from your design system. These styles\n * supplement a partial reset that is already applied by\n * normalize.css.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n padding: 0;\n line-height: inherit;\n color: inherit;\n}\n\n/**\n * Use the configured 'mono' font family for elements that\n * are expected to be rendered with a monospace font, falling\n * back to the system monospace stack if there is no configured\n * 'mono' font family.\n */\n\npre,\ncode,\nkbd,\nsamp {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n/**\n * Make replaced elements `display: block` by default as that's\n * the behavior you want almost all of the time. Inspired by\n * CSS Remedy, with `svg` added as well.\n *\n * https://github.com/mozdevs/cssremedy/issues/14\n */\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block;\n vertical-align: middle;\n}\n\n/**\n * Constrain images and videos to the parent width and preserve\n * their instrinsic aspect ratio.\n *\n * https://github.com/mozdevs/cssremedy/issues/14\n */\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n.container {\n width: 100%;\n}\n\n@media (min-width: 640px) {\n .container {\n max-width: 640px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 768px;\n }\n}\n\n@media (min-width: 1024px) {\n .container {\n max-width: 1024px;\n }\n}\n\n@media (min-width: 1280px) {\n .container {\n max-width: 1280px;\n }\n}\n\n@media (min-width: 1536px) {\n .container {\n max-width: 1536px;\n }\n}\n\n.bg-gray-800 {\n --tw-bg-opacity: 1;\n background-color: rgba(31, 41, 55, var(--tw-bg-opacity));\n}\n\n.border {\n border-width: 1px;\n}\n\n.flex {\n display: flex;\n}\n\n.table {\n display: table;\n}\n\n.grid {\n display: grid;\n}\n\n.hidden {\n display: none;\n}\n\n.flex-row {\n flex-direction: row;\n}\n\n.flex-col {\n flex-direction: column;\n}\n\n.flex-grow {\n flex-grow: 1;\n}\n\n.flex-shrink {\n flex-shrink: 1;\n}\n\n.list-disc {\n list-style-type: disc;\n}\n\n.absolute {\n position: absolute;\n}\n\n.resize {\n resize: both;\n}\n\n* {\n --tw-shadow: 0 0 #0000;\n}\n\n* {\n --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n}\n\n.table-auto {\n table-layout: auto;\n}\n\n.line-through {\n text-decoration: line-through;\n}\n\n.w-full {\n width: 100%;\n}\n\n.gap-4 {\n gap: 1rem;\n}\n\n.grid-cols-3 {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n}\n\n.transform {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.transition {\n transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n\n@-webkit-keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@-webkit-keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n@keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n@-webkit-keyframes pulse {\n 50% {\n opacity: .5;\n }\n}\n\n@keyframes pulse {\n 50% {\n opacity: .5;\n }\n}\n\n@-webkit-keyframes bounce {\n 0%, 100% {\n transform: translateY(-25%);\n -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);\n animation-timing-function: cubic-bezier(0.8,0,1,1);\n }\n\n 50% {\n transform: none;\n -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);\n animation-timing-function: cubic-bezier(0,0,0.2,1);\n }\n}\n\n@keyframes bounce {\n 0%, 100% {\n transform: translateY(-25%);\n -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);\n animation-timing-function: cubic-bezier(0.8,0,1,1);\n }\n\n 50% {\n transform: none;\n -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);\n animation-timing-function: cubic-bezier(0,0,0.2,1);\n }\n}\n\n:root {\n --bg-color: #131720;\n --text-color: #d9e1f2;\n --primary: hsl(255, 30%, 55%);\n --focus: hsl(210, 90%, 50%);\n --secondary: #42b983;\n --border-color: hsla(0, 0%, 100%, 0.2);\n --light-1: hsl(210, 30%, 40%);\n --light-2: hsl(255, 30%, 50%);\n --light-background: linear-gradient(to right, var(--light-1), var(--light-2));\n --shadow-1: hsla(236, 50%, 50%, 0.3);\n --shadow-2: hsla(236, 50%, 50%, 0.4);\n --hud-background: rgba(0, 0, 0, 0.4);\n --hud-text-color: var(--text-color);\n --notifications-bg: darkslateblue;\n --skills-text-background: rgba(0, 0, 0, 0.5);\n --skills-text-color: var(--text-color);\n --skills-level-background: rgba(0, 0, 0, 0.5);\n --skills-level-color: orange;\n --skills-xp-bar-height: 40px;\n --skill-check-name-color: orange;\n --skill-check-difficulty: orange;\n --skill-check-success: green;\n --skill-check-failed: red;\n --skill-check-color: orange;\n --dialog-choice-color: orange;\n --dialog-choice-hover-color: var(--text-color);\n}\n\n.list-item {\n display: inline-block;\n margin-right: 10px;\n}\n\n.list-enter-active,\r\n.list-leave-active {\n transition: all 0.3s ease;\n}\n\n/* .list-move {\r\n transition: transform 0.3s ease;\r\n} */\n\n.list-enter-from,\r\n.list-leave-to {\n opacity: 0;\n transform: translateX(300px);\n}\n\n.notification-item {\n display: inline-block;\n margin-right: 10px;\n}\n\n.notification-enter-active,\r\n.notification-leave-active {\n transition: all 0.3s ease;\n}\n\n/* .notification-move {\r\n transition: transform 0.3s ease;\r\n} */\n\n.notification-enter-from,\r\n.notification-leave-to {\n opacity: 0;\n transform: translateY(-300px);\n}\n\n.fade-enter-active,\r\n.fade-leave-active {\n transition: opacity 0.3s ease;\n}\n\n.fade-enter-from,\r\n.fade-leave-to {\n opacity: 0;\n}\n\n.fade-in-enter-active {\n transition: opacity 0.1s ease;\n}\n\n.fade-in-enter-from {\n opacity: 0;\n}\n\nbody {\n padding: 0;\n margin: 0;\n font-family: Arial, sans-serif;\n background-color: black;\n}\n\n.select {\n background: var(--light-background);\n padding: 10px;\n}\n\n.option {\n background-color: var(--light-2);\n padding: 5px;\n color: var(--text-color);\n}\n\n.button {\n background: var(--light-background);\n color: var(--text-color);\n box-shadow: 0.4rem 0.4rem 2.4rem 0.2rem var(--shadow-1);\n border-radius: 100px;\n padding: 10px;\n font-weight: 800;\n font-size: 16px;\n margin: 10px;\n transition: 0.2s;\n}\n\n.button:focus,\r\n.button:hover {\n transform: translateY(-0.2rem);\n box-shadow: 0 0 2.4rem 0.2rem var(--shadow-2);\n}\n\n.input {\n background: var(--light-background);\n color: var(--text-color);\n box-shadow: 0.4rem 0.4rem 2.4rem 0.2rem var(--shadow-1);\n border-radius: 100px;\n padding: 10px;\n font-weight: 800;\n font-size: 16px;\n margin: 10px;\n transition: 0.2s;\n}\n\n.input:focus,\r\n.input:hover {\n transform: translateY(-0.2rem);\n box-shadow: 0 0 2.4rem 0.2rem var(--shadow-2);\n}\n\na {\n color: pink;\n text-decoration: underline;\n}\n\nth,\r\ntd {\n padding: 4px;\n border: 1px solid var(--text-color);\n text-align: center;\n}\n\n#game-holder {\n width: 100vw;\n height: 100vh;\n padding: 0;\n margin: 0;\n top: 0;\n left: 0;\n background-color: black;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: -webkit-fill-available;\n}\n\n.title {\n font-size: 30px;\n font-weight: 700;\n text-align: center;\n}\n\n.container {\n padding: 20px;\n}\n\nh1,\r\nh2,\r\nh3,\r\nh4 {\n font-weight: 700;\n}\n\nh1 {\n font-size: 30px;\n}\n\nh2 {\n font-size: 26px;\n}\n\nh3 {\n font-size: 24px;\n}\n\nhr.solid {\n border: 1px solid var(--text-color);\n margin-top: 30px;\n margin-bottom: 30px;\n}\n\n.card-1 {\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);\n}\n\n.card-1:hover {\n box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n\n.card-2 {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n\n.card-3 {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n}\n\n.card-4 {\n box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n\n.card-5 {\n box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);\n}\n\n.dialog-choice {\n transition: 0.2s;\n}\n\n.dialog-choice:hover {\n transform: scale(1.05, 1.05);\n transform-origin: center;\n}\n\n/* Somewhat arcane CSS to force the hover color to override the child style.\r\nOtherwise hovering choices doesn't change the color of skill check prompts. */\n\n.dialog-choice:not(:hover) > .skill-check-name,\r\n.passive-skill-check > .skill-check-name {\n color: var(--skill-check-name-color);\n}\n\n.dialog-choice:not(:hover) > .skill-check-difficulty,\r\n.passive-skill-check > .skill-check-difficulty {\n color: var(--skill-check-difficulty);\n}\n\n.skill-check-difficulty {\n font-weight: 700;\n}\n\n.dialog-choice:not(:hover) > .skill-check-success,\r\n.passive-skill-check > .skill-check-success {\n color: var(--skill-check-success);\n}\n\n.dialog-choice:not(:hover) > .skill-check-failed,\r\n.passive-skill-check > .skill-check-failed {\n color: var(--skill-check-failed);\n}\n\n.dialog-choice:not(:hover) > .skill-check,\r\n.passive-skill-check.skill-check {\n color: var(--skill-check-color);\n}\n\n.narrat-canvas {\n position: absolute;\n height: 100%;\n top: 0;\n left: 0;\n}\n\n/* Looks ugly */\n\n/* @keyframes strike-anim {\r\n 0% {\r\n width: 0;\r\n }\r\n 100% {\r\n width: 100%;\r\n }\r\n}\r\n.strike-anim {\r\n position: relative;\r\n}\r\n.strike-anim::after {\r\n content: ' ';\r\n position: absolute;\r\n top: 50%;\r\n left: 0;\r\n width: 100%;\r\n height: 1px;\r\n background: var(--text-color);\r\n animation-name: strike-anim;\r\n animation-duration: 0.5s;\r\n animation-timing-function: linear;\r\n animation-iteration-count: 1;\r\n animation-fill-mode: forwards;\r\n} */\n\n#touchTrigger {\n pointer-events: none;\n}\n\n@media (min-width: 640px) {\n}\n\n@media (min-width: 768px) {\n}\n\n@media (min-width: 1024px) {\n}\n\n@media (min-width: 1280px) {\n}\n\n@media (min-width: 1536px) {\n}\r\n";
37
+ var css_248z = "/*! @import */\n\n/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */\n\n/*\nDocument\n========\n*/\n\n/**\nUse a better box model (opinionated).\n*/\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n/**\nUse a more readable tab size (opinionated).\n*/\n\n:root {\n -moz-tab-size: 4;\n -o-tab-size: 4;\n tab-size: 4;\n}\n\n/**\n1. Correct the line height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n*/\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/*\nSections\n========\n*/\n\n/**\nRemove the margin in all browsers.\n*/\n\nbody {\n margin: 0;\n}\n\n/**\nImprove consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n*/\n\nbody {\n font-family:\n\t\tsystem-ui,\n\t\t-apple-system, /* Firefox supports this but not yet `system-ui` */\n\t\t'Segoe UI',\n\t\tRoboto,\n\t\tHelvetica,\n\t\tArial,\n\t\tsans-serif,\n\t\t'Apple Color Emoji',\n\t\t'Segoe UI Emoji';\n}\n\n/*\nGrouping content\n================\n*/\n\n/**\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n}\n\n/*\nText-level semantics\n====================\n*/\n\n/**\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr[title] {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/**\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n2. Correct the odd 'em' font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family:\n\t\tui-monospace,\n\t\tSFMono-Regular,\n\t\tConsolas,\n\t\t'Liberation Mono',\n\t\tMenlo,\n\t\tmonospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/**\nPrevent 'sub' and 'sup' elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\nTabular data\n============\n*/\n\n/**\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n}\n\n/*\nForms\n=====\n*/\n\n/**\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\nRemove the inheritance of text transform in Edge and Firefox.\n1. Remove the inheritance of text transform in Firefox.\n*/\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\nCorrect the inability to style clickable types in iOS and Safari.\n*/\n\nbutton,\n[type='button'],\n[type='reset'] {\n -webkit-appearance: button;\n}\n\n/**\nRemove the inner border and padding in Firefox.\n*/\n\n/**\nRestore the focus styles unset by the previous rule.\n*/\n\n/**\nRemove the additional ':invalid' styles in Firefox.\nSee: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737\n*/\n\n/**\nRemove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.\n*/\n\nlegend {\n padding: 0;\n}\n\n/**\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n/**\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n/**\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to 'inherit' in Safari.\n*/\n\n/*\nInteractive\n===========\n*/\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/**\n * Manually forked from SUIT CSS Base: https://github.com/suitcss/base\n * A thin layer on top of normalize.css that provides a starting point more\n * suitable for web applications.\n */\n\n/**\n * Removes the default spacing and border for appropriate elements.\n */\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nbutton {\n background-color: transparent;\n background-image: none;\n}\n\n/**\n * Work around a Firefox/IE bug where the transparent `button` background\n * results in a loss of the default `button` focus styles.\n */\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nol,\nul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/**\n * Tailwind custom reset styles\n */\n\n/**\n * 1. Use the user's configured `sans` font-family (with Tailwind's default\n * sans-serif font stack as a fallback) as a sane default.\n * 2. Use Tailwind's default \"normal\" line-height so the user isn't forced\n * to override it to ensure consistency even when using the default theme.\n */\n\nhtml {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 1 */\n line-height: 1.5; /* 2 */\n}\n\n/**\n * Inherit font-family and line-height from `html` so users can set them as\n * a class directly on the `html` element.\n */\n\nbody {\n font-family: inherit;\n line-height: inherit;\n}\n\n/**\n * 1. Prevent padding and border from affecting element width.\n *\n * We used to set this in the html element and inherit from\n * the parent element for everything else. This caused issues\n * in shadow-dom-enhanced elements like <details> where the content\n * is wrapped by a div with box-sizing set to `content-box`.\n *\n * https://github.com/mozdevs/cssremedy/issues/4\n *\n *\n * 2. Allow adding a border to an element by just adding a border-width.\n *\n * By default, the way the browser specifies that an element should have no\n * border is by setting it's border-style to `none` in the user-agent\n * stylesheet.\n *\n * In order to easily add borders to elements by just setting the `border-width`\n * property, we change the default border-style for all elements to `solid`, and\n * use border-width to hide them instead. This way our `border` utilities only\n * need to set the `border-width` property instead of the entire `border`\n * shorthand, making our border utilities much more straightforward to compose.\n *\n * https://github.com/tailwindcss/tailwindcss/pull/116\n */\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n/*\n * Ensure horizontal rules are visible by default\n */\n\nhr {\n border-top-width: 1px;\n}\n\n/**\n * Undo the `border-style: none` reset that Normalize applies to images so that\n * our `border-{width}` utilities have the expected effect.\n *\n * The Normalize reset is unnecessary for us since we default the border-width\n * to 0 on all elements.\n *\n * https://github.com/tailwindcss/tailwindcss/issues/362\n */\n\nimg {\n border-style: solid;\n}\n\ntextarea {\n resize: vertical;\n}\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n color: #9ca3af;\n}\n\ninput:-ms-input-placeholder, textarea:-ms-input-placeholder {\n color: #9ca3af;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n color: #9ca3af;\n}\n\nbutton {\n cursor: pointer;\n}\n\ntable {\n border-collapse: collapse;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/**\n * Reset links to optimize for opt-in styling instead of\n * opt-out.\n */\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/**\n * Reset form element properties that are easy to forget to\n * style explicitly so you don't inadvertently introduce\n * styles that deviate from your design system. These styles\n * supplement a partial reset that is already applied by\n * normalize.css.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n padding: 0;\n line-height: inherit;\n color: inherit;\n}\n\n/**\n * Use the configured 'mono' font family for elements that\n * are expected to be rendered with a monospace font, falling\n * back to the system monospace stack if there is no configured\n * 'mono' font family.\n */\n\npre,\ncode,\nkbd,\nsamp {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n/**\n * Make replaced elements `display: block` by default as that's\n * the behavior you want almost all of the time. Inspired by\n * CSS Remedy, with `svg` added as well.\n *\n * https://github.com/mozdevs/cssremedy/issues/14\n */\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block;\n vertical-align: middle;\n}\n\n/**\n * Constrain images and videos to the parent width and preserve\n * their instrinsic aspect ratio.\n *\n * https://github.com/mozdevs/cssremedy/issues/14\n */\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n.container {\n width: 100%;\n}\n\n@media (min-width: 640px) {\n .container {\n max-width: 640px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 768px;\n }\n}\n\n@media (min-width: 1024px) {\n .container {\n max-width: 1024px;\n }\n}\n\n@media (min-width: 1280px) {\n .container {\n max-width: 1280px;\n }\n}\n\n@media (min-width: 1536px) {\n .container {\n max-width: 1536px;\n }\n}\n\n.bg-gray-800 {\n --tw-bg-opacity: 1;\n background-color: rgba(31, 41, 55, var(--tw-bg-opacity));\n}\n\n.border {\n border-width: 1px;\n}\n\n.flex {\n display: flex;\n}\n\n.table {\n display: table;\n}\n\n.grid {\n display: grid;\n}\n\n.hidden {\n display: none;\n}\n\n.flex-row {\n flex-direction: row;\n}\n\n.flex-col {\n flex-direction: column;\n}\n\n.flex-grow {\n flex-grow: 1;\n}\n\n.flex-shrink {\n flex-shrink: 1;\n}\n\n.list-disc {\n list-style-type: disc;\n}\n\n.absolute {\n position: absolute;\n}\n\n.resize {\n resize: both;\n}\n\n* {\n --tw-shadow: 0 0 #0000;\n}\n\n* {\n --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n}\n\n.table-auto {\n table-layout: auto;\n}\n\n.line-through {\n text-decoration: line-through;\n}\n\n.w-full {\n width: 100%;\n}\n\n.gap-4 {\n gap: 1rem;\n}\n\n.grid-cols-3 {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n}\n\n.transform {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.transition {\n transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n\n@-webkit-keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@-webkit-keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n@keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n@-webkit-keyframes pulse {\n 50% {\n opacity: .5;\n }\n}\n\n@keyframes pulse {\n 50% {\n opacity: .5;\n }\n}\n\n@-webkit-keyframes bounce {\n 0%, 100% {\n transform: translateY(-25%);\n -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);\n animation-timing-function: cubic-bezier(0.8,0,1,1);\n }\n\n 50% {\n transform: none;\n -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);\n animation-timing-function: cubic-bezier(0,0,0.2,1);\n }\n}\n\n@keyframes bounce {\n 0%, 100% {\n transform: translateY(-25%);\n -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);\n animation-timing-function: cubic-bezier(0.8,0,1,1);\n }\n\n 50% {\n transform: none;\n -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);\n animation-timing-function: cubic-bezier(0,0,0.2,1);\n }\n}\n\n:root {\n --bg-color: #131720;\n --text-color: #d9e1f2;\n --primary: hsl(255, 30%, 55%);\n --focus: hsl(210, 90%, 50%);\n --secondary: #42b983;\n --border-color: hsla(0, 0%, 100%, 0.2);\n --light-1: hsl(210, 30%, 40%);\n --light-2: hsl(255, 30%, 50%);\n --light-background: linear-gradient(to right, var(--light-1), var(--light-2));\n --shadow-1: hsla(236, 50%, 50%, 0.3);\n --shadow-2: hsla(236, 50%, 50%, 0.4);\n --hud-background: rgba(0, 0, 0, 0.4);\n --hud-text-color: var(--text-color);\n --notifications-bg: darkslateblue;\n --skills-text-background: rgba(0, 0, 0, 0.5);\n --skills-text-color: var(--text-color);\n --skills-level-background: rgba(0, 0, 0, 0.5);\n --skills-level-color: orange;\n --skills-xp-bar-height: 40px;\n --skill-check-name-color: orange;\n --skill-check-difficulty: orange;\n --skill-check-success: green;\n --skill-check-failed: red;\n --skill-check-color: orange;\n --dialog-choice-color: orange;\n --dialog-choice-hover-color: var(--text-color);\n --inventory-text-background: rgba(0, 0, 0, 0.5);\n --inventory-text-color: var(--text-color);\n --inventory-amount-background: rgba(0, 0, 0, 0.5);\n --inventory-amount-color: orange;\n --quest-title-color: yellow;\n --completed-quest-title-color: grey;\n --objective-in-progress-color: white;\n --objective-completed-color: grey;\n}\n\n.list-item {\n display: inline-block;\n margin-right: 10px;\n}\n\n.list-enter-active,\r\n.list-leave-active {\n transition: all 0.3s ease;\n}\n\n/* .list-move {\r\n transition: transform 0.3s ease;\r\n} */\n\n.list-enter-from,\r\n.list-leave-to {\n opacity: 0;\n transform: translateX(300px);\n}\n\n.notification-item {\n display: inline-block;\n margin-right: 10px;\n}\n\n.notification-enter-active,\r\n.notification-leave-active {\n transition: all 0.3s ease;\n}\n\n/* .notification-move {\r\n transition: transform 0.3s ease;\r\n} */\n\n.notification-enter-from,\r\n.notification-leave-to {\n opacity: 0;\n transform: translateY(-300px);\n}\n\n.fade-enter-active,\r\n.fade-leave-active {\n transition: opacity 0.3s ease;\n}\n\n.fade-enter-from,\r\n.fade-leave-to {\n opacity: 0;\n}\n\n.fade-in-enter-active {\n transition: opacity 0.1s ease;\n}\n\n.fade-in-enter-from {\n opacity: 0;\n}\n\nbody {\n padding: 0;\n margin: 0;\n font-family: Arial, sans-serif;\n background-color: black;\n}\n\n.select {\n background: var(--light-background);\n padding: 10px;\n}\n\n.option {\n background-color: var(--light-2);\n padding: 5px;\n color: var(--text-color);\n}\n\n.button {\n background: var(--light-background);\n color: var(--text-color);\n box-shadow: 0.4rem 0.4rem 2.4rem 0.2rem var(--shadow-1);\n border-radius: 100px;\n padding: 10px;\n font-weight: 800;\n font-size: 16px;\n margin: 10px;\n transition: 0.2s;\n}\n\n.button:focus,\r\n.button:hover {\n transform: translateY(-0.2rem);\n box-shadow: 0 0 2.4rem 0.2rem var(--shadow-2);\n}\n\n.input {\n background: var(--light-background);\n color: var(--text-color);\n box-shadow: 0.4rem 0.4rem 2.4rem 0.2rem var(--shadow-1);\n border-radius: 100px;\n padding: 10px;\n font-weight: 800;\n font-size: 16px;\n margin: 10px;\n transition: 0.2s;\n}\n\n.input:focus,\r\n.input:hover {\n transform: translateY(-0.2rem);\n box-shadow: 0 0 2.4rem 0.2rem var(--shadow-2);\n}\n\na {\n color: pink;\n text-decoration: underline;\n}\n\nth,\r\ntd {\n padding: 4px;\n border: 1px solid var(--text-color);\n text-align: center;\n}\n\n#game-holder {\n width: 100vw;\n height: 100vh;\n padding: 0;\n margin: 0;\n top: 0;\n left: 0;\n background-color: black;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: -webkit-fill-available;\n}\n\n.title {\n font-size: 30px;\n font-weight: 700;\n text-align: center;\n}\n\n.container {\n padding: 20px;\n}\n\nh1,\r\nh2,\r\nh3,\r\nh4 {\n font-weight: 700;\n}\n\nh1 {\n font-size: 30px;\n}\n\nh2 {\n font-size: 26px;\n}\n\nh3 {\n font-size: 24px;\n}\n\nhr.solid {\n border: 1px solid var(--text-color);\n margin-top: 30px;\n margin-bottom: 30px;\n}\n\n.card-1 {\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);\n}\n\n.card-1:hover {\n box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n\n.card-2 {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n\n.card-3 {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n}\n\n.card-4 {\n box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n\n.card-5 {\n box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);\n}\n\n.dialog-choice {\n transition: 0.2s;\n}\n\n.dialog-choice:hover {\n transform: scale(1.05, 1.05);\n transform-origin: center;\n}\n\n/* Somewhat arcane CSS to force the hover color to override the child style.\r\nOtherwise hovering choices doesn't change the color of skill check prompts. */\n\n.dialog-choice:not(:hover) > .skill-check-name,\r\n.passive-skill-check > .skill-check-name {\n color: var(--skill-check-name-color);\n}\n\n.dialog-choice:not(:hover) > .skill-check-difficulty,\r\n.passive-skill-check > .skill-check-difficulty {\n color: var(--skill-check-difficulty);\n}\n\n.skill-check-difficulty {\n font-weight: 700;\n}\n\n.dialog-choice:not(:hover) > .skill-check-success,\r\n.passive-skill-check > .skill-check-success {\n color: var(--skill-check-success);\n}\n\n.dialog-choice:not(:hover) > .skill-check-failed,\r\n.passive-skill-check > .skill-check-failed {\n color: var(--skill-check-failed);\n}\n\n.dialog-choice:not(:hover) > .skill-check,\r\n.passive-skill-check.skill-check {\n color: var(--skill-check-color);\n}\n\n.narrat-canvas {\n position: absolute;\n height: 100%;\n top: 0;\n left: 0;\n}\n\n/* Looks ugly */\n\n/* @keyframes strike-anim {\r\n 0% {\r\n width: 0;\r\n }\r\n 100% {\r\n width: 100%;\r\n }\r\n}\r\n.strike-anim {\r\n position: relative;\r\n}\r\n.strike-anim::after {\r\n content: ' ';\r\n position: absolute;\r\n top: 50%;\r\n left: 0;\r\n width: 100%;\r\n height: 1px;\r\n background: var(--text-color);\r\n animation-name: strike-anim;\r\n animation-duration: 0.5s;\r\n animation-timing-function: linear;\r\n animation-iteration-count: 1;\r\n animation-fill-mode: forwards;\r\n} */\n\n#touchTrigger {\n pointer-events: none;\n}\n\n@media (min-width: 640px) {\n}\n\n@media (min-width: 768px) {\n}\n\n@media (min-width: 1024px) {\n}\n\n@media (min-width: 1280px) {\n}\n\n@media (min-width: 1536px) {\n}\r\n";
38
38
  styleInject(css_248z);
39
39
 
40
40
  const f=vue.ref([]),v=vue.ref(null),m=vue.ref(null),g=vue.ref(null),h=vue.reactive({current:""}),y=[],b=vue.ref(!1),k=vue.readonly(f),w=vue.readonly(v),M=vue.readonly(m),q=vue.readonly(g),x=vue.readonly(h),$=(e=w.value)=>{h.current=e;const t=k.value.findIndex((t=>t.name===e)),n=k.value.map((e=>e.name));for(let a=0;a<n.length;a++){if(a>0&&a<n.length-1){const e=n[a]+"Minus",r=n[a]+"Plus";h[e]=t<=a,h[r]=t>=a;}h[n[a]]=n[a]===e;}},V=(e=M.value)=>{h.orientation=e,h.isLandscape="landscape"===e,h.isPortrait="portrait"===e;},O=(e=q.value||"light")=>{h.theme=e,h.isDark="dark"===e,h.isLight="light"===e;};function j(e,t){if("undefined"==typeof window||!window.matchMedia)return !1;if("undefined"!=typeof window&&!window.matchMedia)return console.error("Vue3 Mq: No MatchMedia support detected in this browser. Responsive breakpoints not available."),!1;{b.value=!0;const n=window.matchMedia(e),a=({matches:e})=>{e&&t();};y.push({mql:n,cb:a});n.addEventListener&&"function"==typeof n.addEventListener?n.addEventListener("change",a):n.addListener(a),a(n);}}var L=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",bootstrap5:{xs:0,sm:576,md:768,lg:992,xl:1200,xxl:1400},bootstrap4:{xs:0,sm:576,md:768,lg:992,xl:1200},bootstrap3:{xs:0,sm:768,md:992,lg:1200},vuetify:{xs:0,sm:600,md:960,lg:1264,xl:1904},tailwind:{xs:0,sm:640,md:768,lg:1024,xl:1280,xxl:1536},devices:{phone:0,tablet:768,laptop:1370,desktop:1906}});const T=e=>{if(!e||"object"!=typeof e)return !1;const t=[];for(let n in e){const a=parseFloat(e[n]);n&&"string"==typeof n?/^[^a-z]/i.test(n)||/[^a-zA-Z0-9_]/.test(n)?console.warn(`Vue3 Mq: "${n}" is an invalid breakpoint key. Breakpoint keys must start with a letter and contain only alphanumeric characters and underscores. Skipping.`):!a&&0!==a||isNaN(a)||a<0?console.warn(`Vue3 Mq: "${n}: ${e[n]}" is not a valid breakpoint. Breakpoints should be a number of zero or above. Skipping.`):t.push({name:n,min:a}):console.warn(`Vue3 Mq: Invalid or missing breakpoint key (${JSON.stringify(n)}). Skipping.`);}t.some((e=>0===e.min))||console.warn("Vue3 Mq: You have not declared a breakpoint with a minimum value of 0. There may be screen sizes to which Vue3Mq does not respond.");return new Set(t.map((e=>e.min))).size<t.length&&console.warn("Vue3 Mq: Your breakpoint configuration contains duplicate values. Behaviour may be unpredictable."),0!==t.length&&t.sort(((e,t)=>e.min-t.min))};function R({breakpoints:e,preset:t}){const n=(e=>{if("string"==typeof e&&L[e])return L[e];{const t=Object.keys(L);return console.error(`Vue3 Mq: "${e}" is not a valid preset. Available options are: ${t.join(", ")}`),!1}})(t),a=T(e);if(!1===n&&!a)throw new TypeError("Vue3 Mq: You must provide a valid preset, or valid breakpoint settings.");var r;r=a||T(n),f.value=r,function(){for(;y.length>0;){const e=y.shift();if(e&&"object"==typeof e){const{mql:t,cb:n}=e;t.addEventListener&&"function"==typeof t.addEventListener?t.removeEventListener("change",n):t.removeListener(n);}}}(),(()=>{const e=Object.keys(h);for(let t of e)delete h[t];$(),V(),O();})();const o=k.value.reduce(((e,t,n,a)=>{const r=`(min-width: ${t.min}px)`,o=n<a.length-1?`(max-width: ${a[n+1].min-1}px)`:null,i=r+(o?" and "+o:"");return Object.assign(e,{[t.name]:i})}),{});for(const i in o){j(o[i],(()=>{$(i);}));}["portrait","landscape"].forEach((e=>{j(`(orientation: ${e})`,(()=>{V(e);}));})),["light","dark"].forEach((e=>{j(`(prefers-color-scheme: ${e})`,(()=>{O(e);}));}));}var N={install:(e,{preset:t="bootstrap5",breakpoints:n,defaultBreakpoint:a,defaultOrientation:r="landscape",defaultTheme:o}={})=>{try{const l=!1===["landscape","portrait"].includes(s=r)?(console.error(`Vue3 Mq: "${s}" is not a valid default orientation. Reverting to unset value.`),null):s,u=((e=null)=>!1===["dark","light"].includes(e)&&null!==e?(console.error(`Vue3 Mq: "${e}" is not a valid default theme. Reverting to unset value.`),null):e)(o);i=a,v.value=i,(e=>{m.value=e;})(l),(e=>{g.value=e;})(u),e.provide("mq",x),e.provide("updateBreakpoints",R),R({breakpoints:n,preset:t});}catch(l){console.error(l);}var i,s;}};
@@ -101,6 +101,8 @@ const defaultConfig = {
101
101
  timeOnScreen: 3,
102
102
  },
103
103
  hudStats: {},
104
+ items: {},
105
+ quests: {},
104
106
  };
105
107
 
106
108
  function parserError(ctx, line, text) {
@@ -127,6 +129,19 @@ function getSkillConfig(id) {
127
129
  error(`Skill config for skill ${id} doesn't exist`);
128
130
  }
129
131
  return skill;
132
+ }
133
+ function getItemConfig(id) {
134
+ const item = config.items[id];
135
+ if (!item) {
136
+ error(`Item config for skill ${id} doesn't exist`);
137
+ }
138
+ return item;
139
+ }
140
+ function getQuestConfig(questId) {
141
+ return config.quests[questId];
142
+ }
143
+ function getObjectiveConfig(quest, objectiveId) {
144
+ return getQuestConfig(quest).objectives[objectiveId];
130
145
  }
131
146
 
132
147
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -3421,6 +3436,9 @@ const useAudio = pinia.defineStore('audio', {
3421
3436
  loadSaveData(data) {
3422
3437
  this.currentMusic = data.currentMusic;
3423
3438
  },
3439
+ reset() {
3440
+ this.stopMusic();
3441
+ },
3424
3442
  },
3425
3443
  });
3426
3444
 
@@ -3546,29 +3564,178 @@ function randomId() {
3546
3564
  return `${Date.now() - Math.floor(Math.random() * 99999999)}`;
3547
3565
  }
3548
3566
 
3549
- // Create a pinia store named dialog with a state using the type DialogState, with actions addDialog and clearDialog
3550
- const useDialogStore = pinia.defineStore('dialog', {
3567
+ // Generate a pinia store named notifications with a state using the type NotificationsState, and save type NotificationsSave, with actions:
3568
+ // addNotification(text: string): Adds a new notification to the state, and deletes it after a timeout
3569
+ // deleteNotification(id: string): Deletes a notification from the state
3570
+ const useNotifications = pinia.defineStore('notifications', {
3571
+ state: () => ({ notifications: {} }),
3572
+ actions: {
3573
+ async addNotification(text) {
3574
+ const id = `${Date.now()}-${Math.random() * 10000}`;
3575
+ this.notifications[id] = {
3576
+ text,
3577
+ };
3578
+ if (getConfig().notifications.alsoPrintInDialogue) {
3579
+ writeText(`[NOTIFICATION] ${text}`);
3580
+ }
3581
+ await timeout(getConfig().notifications.timeOnScreen * 1000);
3582
+ this.deleteNotification(id);
3583
+ },
3584
+ deleteNotification(id) {
3585
+ delete this.notifications[id];
3586
+ },
3587
+ },
3588
+ });
3589
+
3590
+ // create a pinia store named inventory with a state containing items and actions to add and delete items
3591
+ // create a pinia store named inventory with a state of type ItemState and actions to add and delete items. Adding items should increase the amount of any existing item that matches the id.
3592
+ const useInventory = pinia.defineStore('inventory', {
3551
3593
  state: () => ({
3552
- dialog: [],
3594
+ items: {},
3553
3595
  }),
3554
3596
  actions: {
3555
3597
  generateSaveData() {
3556
3598
  return {
3557
- dialog: this.dialog,
3599
+ items: this.items,
3558
3600
  };
3559
3601
  },
3560
- loadSaveData(data) {
3561
- this.dialog = data.dialog;
3602
+ loadSaveData(save) {
3603
+ this.items = { ...this.items, ...save.items };
3562
3604
  },
3563
- addDialog(dialog) {
3564
- this.dialog.push({
3565
- ...dialog,
3566
- interactive: dialog.interactive ?? false,
3567
- id: randomId(),
3605
+ setupItems(items) {
3606
+ Object.keys(items).forEach((key) => {
3607
+ this.items[key] = {
3608
+ amount: 0,
3609
+ id: key,
3610
+ };
3568
3611
  });
3569
3612
  },
3570
- clearDialog() {
3571
- this.dialog.splice(0, this.dialog.length);
3613
+ getExistingItem(id) {
3614
+ return this.items[id];
3615
+ },
3616
+ getItemAmount(id) {
3617
+ return this.getExistingItem(id)?.amount || 0;
3618
+ },
3619
+ add(item) {
3620
+ const existingItem = this.getExistingItem(item.id);
3621
+ if (existingItem) {
3622
+ existingItem.amount += item.amount;
3623
+ }
3624
+ else {
3625
+ this.items[item.id] = { ...item };
3626
+ }
3627
+ useNotifications().addNotification(`Received item: ${getItemConfig(item.id).name} x ${item.amount}`);
3628
+ },
3629
+ remove(item) {
3630
+ const existingItem = this.getExistingItem(item.id);
3631
+ if (existingItem) {
3632
+ existingItem.amount -= item.amount;
3633
+ useNotifications().addNotification(`Lost item: ${getItemConfig(item.id).name} x ${item.amount}`);
3634
+ if (existingItem.amount <= 0) {
3635
+ this.deleteItem(item.id);
3636
+ }
3637
+ }
3638
+ },
3639
+ deleteItem(id) {
3640
+ const existingItem = this.getExistingItem(id);
3641
+ if (existingItem) {
3642
+ this.items[id].amount = 0;
3643
+ }
3644
+ },
3645
+ },
3646
+ });
3647
+
3648
+ const everyObject = (object, predicate) => {
3649
+ for (const key in object) {
3650
+ if (!predicate(object[key])) {
3651
+ return false;
3652
+ }
3653
+ }
3654
+ return true;
3655
+ };
3656
+ const filterObject = (object, predicate) => {
3657
+ const result = {};
3658
+ for (const key in object) {
3659
+ if (predicate(object[key])) {
3660
+ result[key] = object[key];
3661
+ }
3662
+ }
3663
+ return result;
3664
+ };
3665
+
3666
+ const useQuests = pinia.defineStore('quests', {
3667
+ state: () => ({
3668
+ quests: {},
3669
+ }),
3670
+ actions: {
3671
+ getQuest(questId) {
3672
+ const quest = this.quests[questId];
3673
+ if (quest) {
3674
+ return quest;
3675
+ }
3676
+ error(`Quest ${questId} doesn't exist!`);
3677
+ },
3678
+ getObjective(quest, objectiveId) {
3679
+ const questObjective = this.getQuest(quest).objectives[objectiveId];
3680
+ if (questObjective) {
3681
+ return questObjective;
3682
+ }
3683
+ error(`Objective ${objectiveId} doesn't exist in quest ${quest}!`);
3684
+ },
3685
+ setupQuests(quests) {
3686
+ // iterate through quests to generate quest states to add to this.quests object
3687
+ for (const key of Object.keys(quests)) {
3688
+ const data = quests[key];
3689
+ this.quests[key] = {
3690
+ id: key,
3691
+ state: 'hidden',
3692
+ objectives: {},
3693
+ };
3694
+ // iterate through data.objectives to populate the objectives array of this.quests[key]
3695
+ for (const objectiveKey of Object.keys(data.objectives)) {
3696
+ const objective = data.objectives[objectiveKey];
3697
+ this.quests[key].objectives[objectiveKey] = {
3698
+ id: objectiveKey,
3699
+ state: objective.hidden ? 'hidden' : 'unlocked',
3700
+ };
3701
+ }
3702
+ }
3703
+ },
3704
+ startQuest(questId) {
3705
+ this.getQuest(questId).state = 'unlocked';
3706
+ useNotifications().addNotification(`Started quest: ${getQuestConfig(questId).title}`);
3707
+ },
3708
+ startObjective(questId, objectiveId) {
3709
+ this.getObjective(questId, objectiveId).state = 'unlocked';
3710
+ useNotifications().addNotification(`New quest objective: ${getObjectiveConfig(questId, objectiveId).description}`);
3711
+ },
3712
+ completeObjective(questId, objectiveId) {
3713
+ this.getObjective(questId, objectiveId).state = 'completed';
3714
+ useNotifications().addNotification(`Objective completed!`);
3715
+ },
3716
+ completeQuest(questId, ending) {
3717
+ this.getQuest(questId).state = 'completed';
3718
+ if (ending) {
3719
+ this.getQuest(questId).ending = ending;
3720
+ }
3721
+ useNotifications().addNotification(`Quest completed: ${getQuestConfig(questId).title}`);
3722
+ },
3723
+ isQuestCompleted(questId) {
3724
+ const quest = this.getQuest(questId);
3725
+ return everyObject(quest.objectives, (objective) => objective.state === 'completed');
3726
+ },
3727
+ removeQuest(id) {
3728
+ delete this.quests[id];
3729
+ },
3730
+ generateSaveData() {
3731
+ return {
3732
+ quests: {
3733
+ ...this.quests,
3734
+ },
3735
+ };
3736
+ },
3737
+ loadSaveData(data) {
3738
+ this.quests = data.quests;
3572
3739
  },
3573
3740
  },
3574
3741
  });
@@ -3705,64 +3872,6 @@ var deepmerge_1 = deepmerge;
3705
3872
 
3706
3873
  var cjs = deepmerge_1;
3707
3874
 
3708
- // Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
3709
- // setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
3710
- // setStat(stat: string, value: number): Sets the value of a stat
3711
- // addStat(stat: string, value: number): Adds a value to a stat
3712
- // generateSaveData(): Function that generates a HudSave object from the data in the state
3713
- // loadSaveData(data: HudSave): Function that loads the data into the state
3714
- const useHud = pinia.defineStore('hud', {
3715
- state: () => ({
3716
- hudStats: {},
3717
- }),
3718
- actions: {
3719
- setupHudStats(stats) {
3720
- for (const stat in stats) {
3721
- this.hudStats[stat] = {
3722
- value: stats[stat].startingValue,
3723
- };
3724
- }
3725
- },
3726
- setStat(stat, value) {
3727
- this.hudStats[stat].value = value;
3728
- },
3729
- addStat(stat, value) {
3730
- this.hudStats[stat].value += value;
3731
- },
3732
- generateSaveData() {
3733
- return {
3734
- hudStats: this.hudStats,
3735
- };
3736
- },
3737
- loadSaveData(data) {
3738
- this.hudStats = cjs(this.hudStats, data.hudStats);
3739
- },
3740
- },
3741
- });
3742
-
3743
- // Generate a pinia store named notifications with a state using the type NotificationsState, and save type NotificationsSave, with actions:
3744
- // addNotification(text: string): Adds a new notification to the state, and deletes it after a timeout
3745
- // deleteNotification(id: string): Deletes a notification from the state
3746
- const useNotifications = pinia.defineStore('notifications', {
3747
- state: () => ({ notifications: {} }),
3748
- actions: {
3749
- async addNotification(text) {
3750
- const id = `${Date.now()}-${Math.random() * 10000}`;
3751
- this.notifications[id] = {
3752
- text,
3753
- };
3754
- if (getConfig().notifications.alsoPrintInDialogue) {
3755
- writeText(`[NOTIFICATION] ${text}`);
3756
- }
3757
- await timeout(getConfig().notifications.timeOnScreen * 1000);
3758
- this.deleteNotification(id);
3759
- },
3760
- deleteNotification(id) {
3761
- delete this.notifications[id];
3762
- },
3763
- },
3764
- });
3765
-
3766
3875
  // Create a pinia store named skills with a state using the type Skills, with actions:
3767
3876
  // setupSkillCheck(skillCheck: SkillCheckState, id: string)
3768
3877
  // passSkillCheck(skillCheckId: string)
@@ -3810,6 +3919,9 @@ const useSkills = pinia.defineStore('skills', {
3810
3919
  },
3811
3920
  addXp(skill, xp) {
3812
3921
  const skillData = this.skills[skill];
3922
+ if (!skillData) {
3923
+ error(`Skill ${skill} doesn't exist`);
3924
+ }
3813
3925
  skillData.xp += xp;
3814
3926
  if (skillData.xp >= getConfig().skillOptions.xpPerLevel) {
3815
3927
  skillData.xp = 0;
@@ -3917,10 +4029,13 @@ function getModifiableDataPinia() {
3917
4029
  const vm = useVM();
3918
4030
  const skills = useSkills();
3919
4031
  const screens = useScreens();
4032
+ const inventory = useInventory();
3920
4033
  return {
3921
4034
  data: vm.data,
3922
4035
  skills: skills.skills,
3923
4036
  buttons: screens.buttons,
4037
+ items: inventory.items,
4038
+ quests: useQuests().quests,
3924
4039
  };
3925
4040
  }
3926
4041
 
@@ -4138,6 +4253,7 @@ const useVM = pinia.defineStore('vm', {
4138
4253
  data: {},
4139
4254
  lastLabel: 'main',
4140
4255
  script: {},
4256
+ labelStack: ['main'],
4141
4257
  }),
4142
4258
  actions: {
4143
4259
  generateSaveData() {
@@ -4254,6 +4370,19 @@ const useVM = pinia.defineStore('vm', {
4254
4370
  const cmd = this.currentLine;
4255
4371
  await runCommand(cmd);
4256
4372
  },
4373
+ async runLabelFunction(label) {
4374
+ const branch = this.script[label];
4375
+ if (!branch) {
4376
+ console.error(`Label ${branch} doesn't exist`);
4377
+ }
4378
+ const stack = {
4379
+ currentIndex: 0,
4380
+ branch: branch,
4381
+ label,
4382
+ };
4383
+ this.addStack(stack);
4384
+ await this.runLine();
4385
+ },
4257
4386
  runLabel(label) {
4258
4387
  const branch = this.script[label];
4259
4388
  if (!branch) {
@@ -4282,6 +4411,88 @@ const useVM = pinia.defineStore('vm', {
4282
4411
  },
4283
4412
  });
4284
4413
 
4414
+ function processText(text) {
4415
+ const vmStore = useVM();
4416
+ const skillStore = useSkills();
4417
+ return text.replace(/%{[^}]*}/g, (match) => {
4418
+ const key = match.substr(2, match.length - 3);
4419
+ const searchableState = {
4420
+ data: vmStore.data,
4421
+ skills: skillStore.skills,
4422
+ items: useInventory().items,
4423
+ quests: useQuests().quests,
4424
+ };
4425
+ const [obj, newKey] = findDataHelper(searchableState, key);
4426
+ return obj[newKey];
4427
+ });
4428
+ }
4429
+
4430
+ // Create a pinia store named dialog with a state using the type DialogState, with actions addDialog and clearDialog
4431
+ const useDialogStore = pinia.defineStore('dialog', {
4432
+ state: () => ({
4433
+ dialog: [],
4434
+ }),
4435
+ actions: {
4436
+ generateSaveData() {
4437
+ return {
4438
+ dialog: this.dialog,
4439
+ };
4440
+ },
4441
+ loadSaveData(data) {
4442
+ this.dialog = data.dialog;
4443
+ },
4444
+ addDialog(dialog) {
4445
+ this.dialog.push({
4446
+ ...dialog,
4447
+ interactive: dialog.interactive ?? false,
4448
+ id: randomId(),
4449
+ text: processText(dialog.text),
4450
+ });
4451
+ },
4452
+ clearDialog() {
4453
+ this.dialog.splice(0, this.dialog.length);
4454
+ },
4455
+ reset() {
4456
+ this.dialog = [];
4457
+ },
4458
+ },
4459
+ });
4460
+
4461
+ // Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
4462
+ // setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
4463
+ // setStat(stat: string, value: number): Sets the value of a stat
4464
+ // addStat(stat: string, value: number): Adds a value to a stat
4465
+ // generateSaveData(): Function that generates a HudSave object from the data in the state
4466
+ // loadSaveData(data: HudSave): Function that loads the data into the state
4467
+ const useHud = pinia.defineStore('hud', {
4468
+ state: () => ({
4469
+ hudStats: {},
4470
+ }),
4471
+ actions: {
4472
+ setupHudStats(stats) {
4473
+ for (const stat in stats) {
4474
+ this.hudStats[stat] = {
4475
+ value: stats[stat].startingValue,
4476
+ };
4477
+ }
4478
+ },
4479
+ setStat(stat, value) {
4480
+ this.hudStats[stat].value = value;
4481
+ },
4482
+ addStat(stat, value) {
4483
+ this.hudStats[stat].value += value;
4484
+ },
4485
+ generateSaveData() {
4486
+ return {
4487
+ hudStats: this.hudStats,
4488
+ };
4489
+ },
4490
+ loadSaveData(data) {
4491
+ this.hudStats = cjs(this.hudStats, data.hudStats);
4492
+ },
4493
+ },
4494
+ });
4495
+
4285
4496
  function createSkillCheckState() {
4286
4497
  const skillCheck = {
4287
4498
  passed: false,
@@ -4428,11 +4639,16 @@ function runCondition(condition) {
4428
4639
  function conditionFunction(condition) {
4429
4640
  const skillStore = useSkills();
4430
4641
  const vm = useVM();
4642
+ const inventory = useInventory();
4431
4643
  const context = {
4432
4644
  data: vm.data,
4433
4645
  skills: skillStore.skills,
4434
4646
  skillChecks: skillStore.skillChecks,
4435
4647
  stats: useHud().hudStats,
4648
+ items: inventory.items,
4649
+ itemAmount: (id) => {
4650
+ return useInventory().getItemAmount(id);
4651
+ },
4436
4652
  roll: (checkId, skill, value) => {
4437
4653
  const skillCheckState = getSkillCheckState(checkId);
4438
4654
  if (skillCheckState) {
@@ -4637,6 +4853,10 @@ const useMain = pinia.defineStore('main', {
4637
4853
  skillsStore.setupSkills(config.skills);
4638
4854
  const hudStore = useHud();
4639
4855
  hudStore.setupHudStats(config.hudStats);
4856
+ const inventoryStore = useInventory();
4857
+ inventoryStore.setupItems(config.items);
4858
+ const questsStore = useQuests();
4859
+ questsStore.setupQuests(config.quests);
4640
4860
  },
4641
4861
  startMachine() {
4642
4862
  const vmStore = useVM();
@@ -4709,11 +4929,13 @@ const useMain = pinia.defineStore('main', {
4709
4929
  },
4710
4930
  reset() {
4711
4931
  this.ready = false;
4712
- this.playing = false;
4713
4932
  this.errors = [];
4714
- this.flowState = 'menu';
4715
4933
  this.modal = false;
4716
4934
  this.paused = false;
4935
+ useVM().reset();
4936
+ useAudio().reset();
4937
+ this.playing = false;
4938
+ this.ready = true;
4717
4939
  },
4718
4940
  generateSaveData() {
4719
4941
  return {
@@ -4731,6 +4953,7 @@ const useMain = pinia.defineStore('main', {
4731
4953
  const mainStore = useMain();
4732
4954
  const hudStore = useHud();
4733
4955
  const audioStore = useAudio();
4956
+ const inventoryStore = useInventory();
4734
4957
  const save = {
4735
4958
  version: '1.0.0',
4736
4959
  screen: screensStore.generateSaveData(),
@@ -4740,6 +4963,8 @@ const useMain = pinia.defineStore('main', {
4740
4963
  main: mainStore.generateSaveData(),
4741
4964
  hud: hudStore.generateSaveData(),
4742
4965
  audio: audioStore.generateSaveData(),
4966
+ inventory: inventoryStore.generateSaveData(),
4967
+ quests: useQuests().generateSaveData(),
4743
4968
  };
4744
4969
  localStorage.setItem(SAVE_FILE, JSON.stringify(save));
4745
4970
  },
@@ -4751,6 +4976,7 @@ const useMain = pinia.defineStore('main', {
4751
4976
  const mainStore = useMain();
4752
4977
  const hudStore = useHud();
4753
4978
  const audioStore = useAudio();
4979
+ const inventoryStore = useInventory();
4754
4980
  screensStore.loadSaveData(save.screen);
4755
4981
  skillsStore.loadSaveData(save.skills);
4756
4982
  dialogStore.loadSaveData(save.dialog);
@@ -4758,6 +4984,8 @@ const useMain = pinia.defineStore('main', {
4758
4984
  mainStore.loadSaveData(save.main);
4759
4985
  hudStore.loadSaveData(save.hud);
4760
4986
  audioStore.loadSaveData(save.audio);
4987
+ inventoryStore.loadSaveData(save.inventory);
4988
+ useQuests().loadSaveData(save.quests);
4761
4989
  },
4762
4990
  getAllStates() {
4763
4991
  return {
@@ -4770,6 +4998,8 @@ const useMain = pinia.defineStore('main', {
4770
4998
  audio: useAudio(),
4771
4999
  rendering: useRenderingStore(),
4772
5000
  notifications: useNotifications(),
5001
+ inventory: useInventory(),
5002
+ quests: useQuests(),
4773
5003
  };
4774
5004
  },
4775
5005
  overrideStates(override) {
@@ -7517,7 +7747,7 @@ function render$7(_ctx, _cache, $props, $setup, $data, $options) {
7517
7747
  class: "notification",
7518
7748
  key: id
7519
7749
  }, [
7520
- vue.createElementVNode("h2", null, vue.toDisplayString(notification.text), 1)
7750
+ vue.createElementVNode("h3", null, vue.toDisplayString(notification.text), 1)
7521
7751
  ]))
7522
7752
  }), 128))
7523
7753
  ]),
@@ -7525,25 +7755,11 @@ function render$7(_ctx, _cache, $props, $setup, $data, $options) {
7525
7755
  }))
7526
7756
  }
7527
7757
 
7528
- var css_248z$8 = ".notifications-holder {\n position: fixed;\n top: 0;\n left: 0;\n padding: 10px;\n display: flex;\n flex-direction: column-reverse;\n align-items: center;\n pointer-events: none;\n}\n\n.notification {\n margin-top: 10px;\n margin-bottom: 10px;\n border-radius: 10px;\n padding: 15px;\n background: var(--notifications-bg);\n width: 40vh;\n text-align: center;\n}\r\n";
7758
+ var css_248z$8 = ".notifications-holder {\n position: fixed;\n top: 0;\n right: 0;\n padding: 10px;\n display: flex;\n flex-direction: column-reverse;\n align-items: center;\n pointer-events: none;\n}\n\n.notification {\n margin-top: 10px;\n margin-bottom: 10px;\n border-radius: 10px;\n padding: 15px;\n background: var(--notifications-bg);\n width: 40vh;\n text-align: center;\n}\r\n";
7529
7759
  styleInject(css_248z$8);
7530
7760
 
7531
7761
  script$7.render = render$7;
7532
7762
 
7533
- function processText(text) {
7534
- const vmStore = useVM();
7535
- const skillStore = useSkills();
7536
- return text.replace(/%{[^}]*}/g, (match) => {
7537
- const key = match.substr(2, match.length - 3);
7538
- const searchableState = {
7539
- data: vmStore.data,
7540
- skills: skillStore.skills,
7541
- };
7542
- const [obj, newKey] = findDataHelper(searchableState, key);
7543
- return obj[newKey];
7544
- });
7545
- }
7546
-
7547
7763
  function aspectRatioFit(screenWidth, screenHeight, gameWidth, gameHeight) {
7548
7764
  const widthRatio = screenWidth / gameWidth;
7549
7765
  const heightRatio = screenHeight / gameHeight;
@@ -7677,6 +7893,12 @@ var script$8 = vue.defineComponent({
7677
7893
  openSkills() {
7678
7894
  useMain().openModal('skills');
7679
7895
  },
7896
+ openInventory() {
7897
+ useMain().openModal('inventory');
7898
+ },
7899
+ openQuests() {
7900
+ useMain().openModal('quests');
7901
+ },
7680
7902
  closeMenu() {
7681
7903
  useMain().closeModal();
7682
7904
  },
@@ -7691,6 +7913,18 @@ var script$8 = vue.defineComponent({
7691
7913
  }
7692
7914
  return false;
7693
7915
  },
7916
+ showInventory() {
7917
+ if (Object.entries(getConfig().items).length > 0) {
7918
+ return true;
7919
+ }
7920
+ return false;
7921
+ },
7922
+ showQuests() {
7923
+ if (Object.entries(getConfig().quests).length > 0) {
7924
+ return true;
7925
+ }
7926
+ return false;
7927
+ },
7694
7928
  },
7695
7929
  });
7696
7930
 
@@ -7710,6 +7944,22 @@ function render$8(_ctx, _cache, $props, $setup, $data, $options) {
7710
7944
  id: "skills-menu-button",
7711
7945
  onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.openSkills && _ctx.openSkills(...args)))
7712
7946
  }, " Skills "))
7947
+ : vue.createCommentVNode("", true),
7948
+ (_ctx.showInventory)
7949
+ ? (vue.openBlock(), vue.createElementBlock("button", {
7950
+ key: 1,
7951
+ class: "button menu-toggle-button",
7952
+ id: "inventory-menu-button",
7953
+ onClick: _cache[2] || (_cache[2] = (...args) => (_ctx.openInventory && _ctx.openInventory(...args)))
7954
+ }, " Items "))
7955
+ : vue.createCommentVNode("", true),
7956
+ (_ctx.showQuests)
7957
+ ? (vue.openBlock(), vue.createElementBlock("button", {
7958
+ key: 2,
7959
+ class: "button menu-toggle-button",
7960
+ id: "quests-menu-button",
7961
+ onClick: _cache[3] || (_cache[3] = (...args) => (_ctx.openQuests && _ctx.openQuests(...args)))
7962
+ }, " Quests "))
7713
7963
  : vue.createCommentVNode("", true)
7714
7964
  ]))
7715
7965
  }
@@ -7933,11 +8183,284 @@ styleInject(css_248z$b);
7933
8183
  script$a.render = render$a;
7934
8184
 
7935
8185
  var script$b = vue.defineComponent({
8186
+ setup() {
8187
+ const store = useInventory();
8188
+ const items = vue.computed(() => store.items);
8189
+ return { items };
8190
+ },
8191
+ components: {
8192
+ Modal: script$2,
8193
+ },
8194
+ props: {
8195
+ close: (() => { }),
8196
+ },
8197
+ data() {
8198
+ return {
8199
+ chosenId: false,
8200
+ };
8201
+ },
8202
+ mounted() { },
8203
+ methods: {
8204
+ getItemStyle(item) {
8205
+ return {
8206
+ backgroundImage: `url(${this.itemConf[item].icon})`,
8207
+ };
8208
+ },
8209
+ getItemName(item) {
8210
+ return this.itemConf[item].name;
8211
+ },
8212
+ clickItem(item) {
8213
+ this.chosenId = item;
8214
+ },
8215
+ closeItem() {
8216
+ this.chosenId = false;
8217
+ },
8218
+ },
8219
+ computed: {
8220
+ itemsToDisplay() {
8221
+ const items = {};
8222
+ for (const key in this.items) {
8223
+ if (this.items[key].amount > 0) {
8224
+ items[key] = this.items[key];
8225
+ }
8226
+ }
8227
+ return items;
8228
+ },
8229
+ chosenItem() {
8230
+ if (this.chosenId) {
8231
+ return this.items[this.chosenId];
8232
+ }
8233
+ return null;
8234
+ },
8235
+ chosenItemConf() {
8236
+ if (this.chosenId) {
8237
+ return this.itemConf[this.chosenId];
8238
+ }
8239
+ return null;
8240
+ },
8241
+ itemConf() {
8242
+ return getConfig().items;
8243
+ },
8244
+ },
8245
+ });
8246
+
8247
+ const _hoisted_1$a = /*#__PURE__*/vue.createElementVNode("h3", { class: "title" }, "Inventory", -1);
8248
+ const _hoisted_2$8 = { class: "menu-content" };
8249
+ const _hoisted_3$5 = {
8250
+ key: 0,
8251
+ class: "inventory-container"
8252
+ };
8253
+ const _hoisted_4$4 = ["onClick"];
8254
+ const _hoisted_5$4 = { class: "item-title" };
8255
+ const _hoisted_6$4 = { class: "item-amount" };
8256
+ const _hoisted_7$3 = {
8257
+ key: 1,
8258
+ class: "flex flex-row item-description-container"
8259
+ };
8260
+ const _hoisted_8$2 = { class: "flex item-left" };
8261
+ const _hoisted_9$2 = { class: "flex item-right" };
8262
+ const _hoisted_10$2 = /*#__PURE__*/vue.createElementVNode("hr", { class: "hr-solid" }, null, -1);
8263
+ const _hoisted_11$2 = { key: 2 };
8264
+ const _hoisted_12$2 = /*#__PURE__*/vue.createElementVNode("h2", null, "The inventory is empty!", -1);
8265
+ const _hoisted_13$1 = [
8266
+ _hoisted_12$2
8267
+ ];
8268
+
8269
+ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8270
+ const _component_modal = vue.resolveComponent("modal");
8271
+
8272
+ return (vue.openBlock(), vue.createBlock(_component_modal, {
8273
+ class: "menu",
8274
+ onClose: _ctx.close,
8275
+ containerCssClass: "inventory-modal"
8276
+ }, {
8277
+ header: vue.withCtx(() => [
8278
+ _hoisted_1$a
8279
+ ]),
8280
+ body: vue.withCtx(() => [
8281
+ vue.createElementVNode("div", _hoisted_2$8, [
8282
+ (!_ctx.chosenItem && Object.keys(_ctx.itemsToDisplay).length > 0)
8283
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$5, [
8284
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.itemsToDisplay, (item) => {
8285
+ return (vue.openBlock(), vue.createElementBlock("button", {
8286
+ onClick: () => _ctx.clickItem(item.id),
8287
+ class: "item-display",
8288
+ style: vue.normalizeStyle(_ctx.getItemStyle(item.id)),
8289
+ key: item.id
8290
+ }, [
8291
+ vue.createElementVNode("h3", _hoisted_5$4, vue.toDisplayString(_ctx.getItemName(item.id)), 1),
8292
+ vue.createElementVNode("h3", _hoisted_6$4, vue.toDisplayString(item.amount), 1)
8293
+ ], 12, _hoisted_4$4))
8294
+ }), 128))
8295
+ ]))
8296
+ : (typeof _ctx.chosenId === 'string')
8297
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$3, [
8298
+ vue.createElementVNode("div", _hoisted_8$2, [
8299
+ vue.createElementVNode("button", {
8300
+ class: "button",
8301
+ onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.closeItem && _ctx.closeItem(...args)))
8302
+ }, "Back"),
8303
+ vue.createElementVNode("div", {
8304
+ class: "item-display",
8305
+ style: vue.normalizeStyle(_ctx.getItemStyle(_ctx.chosenId))
8306
+ }, null, 4)
8307
+ ]),
8308
+ vue.createElementVNode("div", _hoisted_9$2, [
8309
+ vue.createElementVNode("h2", null, vue.toDisplayString(_ctx.getItemName(_ctx.chosenId)), 1),
8310
+ _hoisted_10$2,
8311
+ vue.createElementVNode("h3", null, "Amount: " + vue.toDisplayString(_ctx.chosenItem.amount), 1),
8312
+ vue.createElementVNode("p", null, vue.toDisplayString(_ctx.chosenItemConf.description), 1)
8313
+ ])
8314
+ ]))
8315
+ : (vue.openBlock(), vue.createElementBlock("div", _hoisted_11$2, _hoisted_13$1))
8316
+ ])
8317
+ ]),
8318
+ _: 1
8319
+ }, 8, ["onClose"]))
8320
+ }
8321
+
8322
+ var css_248z$c = ".inventory-modal {\n width: 800px;\n min-height: 50%;\n}\n\n.inventory-container {\n display: grid;\n grid-auto-rows: auto;\n grid-template-columns: repeat(3, 1fr);\n grid-gap: 20px 20px;\n}\n\n.item-display {\n width: 200px;\n height: 300px;\n position: relative;\n background-repeat: no-repeat;\n background-size: contain;\n}\n\n.item-title {\n position: absolute;\n bottom: 0px;\n text-align: center;\n width: 100%;\n color: var(--inventory-text-color);\n background: var(--inventory-text-background);\n}\n\n.item-amount {\n position: absolute;\n top: 0;\n right: 0;\n font-weight: 700;\n font-size: 25px;\n color: var(--inventory-amount-color);\n width: 40px;\n height: 40px;\n background-color: var(--inventory-amount-background);\n}\n\n.item-description-container {\n justify-content: space-between;\n align-items: center;\n}\n\n.item-left {\n flex-direction: column;\n}\n\n.item-right {\n flex-direction: column;\n align-items: baseline;\n}\r\n";
8323
+ styleInject(css_248z$c);
8324
+
8325
+ script$b.render = render$b;
8326
+
8327
+ var script$c = vue.defineComponent({
8328
+ setup() {
8329
+ const questsStore = useQuests();
8330
+ const quests = vue.computed(() => questsStore.quests);
8331
+ return { quests };
8332
+ },
8333
+ computed: {
8334
+ questsToDisplay() {
8335
+ return filterObject(this.quests, (quest) => quest.state !== 'hidden');
8336
+ },
8337
+ },
8338
+ props: {
8339
+ close: (() => { }),
8340
+ },
8341
+ methods: {
8342
+ getQuestData(questId) {
8343
+ return getQuestConfig(questId);
8344
+ },
8345
+ getObjectiveData(questId, objectiveId) {
8346
+ return getObjectiveConfig(questId, objectiveId);
8347
+ },
8348
+ getDisplayTextForQuestState(quest) {
8349
+ switch (quest.state) {
8350
+ case 'hidden':
8351
+ return ' Hidden';
8352
+ case 'unlocked':
8353
+ return '';
8354
+ case 'completed':
8355
+ return ' (Completed)';
8356
+ default:
8357
+ return ' Unknown';
8358
+ }
8359
+ },
8360
+ getQuestDescription(quest) {
8361
+ if (quest.ending) {
8362
+ return quest.ending;
8363
+ }
8364
+ return this.getQuestData(quest.id).description;
8365
+ },
8366
+ getAvailableObjectives(quest) {
8367
+ return filterObject(quest.objectives, (objective) => {
8368
+ return objective.state !== 'hidden';
8369
+ });
8370
+ },
8371
+ },
8372
+ components: {
8373
+ Modal: script$2,
8374
+ VolumeControls: script$4,
8375
+ },
8376
+ });
8377
+
8378
+ const _hoisted_1$b = /*#__PURE__*/vue.createElementVNode("h3", { class: "title" }, "Quests", -1);
8379
+ const _hoisted_2$9 = {
8380
+ key: 0,
8381
+ class: "quests-container"
8382
+ };
8383
+ const _hoisted_3$6 = { class: "quest-title" };
8384
+ const _hoisted_4$5 = { class: "quest-description" };
8385
+ const _hoisted_5$5 = {
8386
+ key: 0,
8387
+ class: "quest-objectives-container list-disc"
8388
+ };
8389
+ const _hoisted_6$5 = {
8390
+ key: 1,
8391
+ class: "menu-container"
8392
+ };
8393
+ const _hoisted_7$4 = /*#__PURE__*/vue.createElementVNode("h2", { class: "title" }, "There are no quests!", -1);
8394
+ const _hoisted_8$3 = [
8395
+ _hoisted_7$4
8396
+ ];
8397
+
8398
+ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
8399
+ const _component_modal = vue.resolveComponent("modal");
8400
+
8401
+ return (vue.openBlock(), vue.createBlock(_component_modal, {
8402
+ class: "quests",
8403
+ onClose: _ctx.close,
8404
+ containerCssClass: "quests-modal"
8405
+ }, {
8406
+ header: vue.withCtx(() => [
8407
+ _hoisted_1$b
8408
+ ]),
8409
+ body: vue.withCtx(() => [
8410
+ (Object.keys(_ctx.questsToDisplay).length > 0)
8411
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$9, [
8412
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.questsToDisplay, (quest) => {
8413
+ return (vue.openBlock(), vue.createElementBlock("div", {
8414
+ class: "quest-display",
8415
+ key: quest.id
8416
+ }, [
8417
+ vue.createElementVNode("div", {
8418
+ class: vue.normalizeClass(["quest-header",
8419
+ quest.state === 'completed'
8420
+ ? 'quest-completed'
8421
+ : 'quest-in-progress'
8422
+ ])
8423
+ }, [
8424
+ vue.createElementVNode("h3", _hoisted_3$6, vue.toDisplayString(_ctx.getQuestData(quest.id).title) + " " + vue.toDisplayString(_ctx.getDisplayTextForQuestState(quest)), 1)
8425
+ ], 2),
8426
+ vue.createElementVNode("p", _hoisted_4$5, vue.toDisplayString(_ctx.getQuestDescription(quest)), 1),
8427
+ (quest.state !== 'completed')
8428
+ ? (vue.openBlock(), vue.createElementBlock("ul", _hoisted_5$5, [
8429
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.getAvailableObjectives(quest), (objective) => {
8430
+ return (vue.openBlock(), vue.createElementBlock("li", {
8431
+ class: "quest-objective-display",
8432
+ key: objective.id
8433
+ }, [
8434
+ vue.createElementVNode("p", {
8435
+ class: vue.normalizeClass(["quest-objective-description",
8436
+ objective.state === 'completed'
8437
+ ? 'quest-objective-completed'
8438
+ : 'quest-objctive-in-progress'
8439
+ ])
8440
+ }, vue.toDisplayString(_ctx.getObjectiveData(quest.id, objective.id).description), 3)
8441
+ ]))
8442
+ }), 128))
8443
+ ]))
8444
+ : vue.createCommentVNode("", true)
8445
+ ]))
8446
+ }), 128))
8447
+ ]))
8448
+ : (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$5, _hoisted_8$3))
8449
+ ]),
8450
+ _: 1
8451
+ }, 8, ["onClose"]))
8452
+ }
8453
+
8454
+ var css_248z$d = "/* Write CSS for this vue component */\n\n.quests-modal {\n width: 100%;\n min-height: 50%;\n}\n\n/* CSS for .quest-header with row flex */\n\n.quest-header {\n display: flex;\n flex-direction: row;\n align-items: center;\n}\n\n.quest-display {\n}\n\n.quest-title {\n font-size: 1.5rem;\n font-weight: bold;\n margin-bottom: 0.5rem;\n}\n\n.quest-completed {\n color: var(--completed-quest-title-color);\n}\n\n.quest-in-progress {\n color: var(--quest-title-color);\n}\n\n.quest-state {\n font-size: 1.25rem;\n font-weight: bold;\n margin-bottom: 0.5rem;\n}\n\n.quest-description {\n font-size: 1.1rem;\n text-align: justify;\n font-style: italic;\n margin-bottom: 0.5rem;\n}\n\n.quest-objectives-container {\n margin-left: 10px;\n}\n\n.quest-objective-completed {\n color: var(--objective-completed-color);\n text-decoration: line-through;\n}\n\n.quest-objective-in-progress {\n color: var(--objective-in-progress-color);\n}\n\n.quest-objective-description {\n font-size: 1rem;\n margin-bottom: 0.5rem;\n}\r\n";
8455
+ styleInject(css_248z$d);
8456
+
8457
+ script$c.render = render$c;
8458
+
8459
+ var script$d = vue.defineComponent({
7936
8460
  setup() {
7937
8461
  const dialogStore = useDialogStore();
7938
8462
  const vmStore = useVM();
7939
8463
  const mainStore = useMain();
7940
- const renderingStore = useRenderingStore();
7941
8464
  return {
7942
8465
  dialog: vue.computed(() => dialogStore.dialog),
7943
8466
  stack: vue.computed(() => vmStore.stack),
@@ -7959,6 +8482,8 @@ var script$b = vue.defineComponent({
7959
8482
  Menu: script$8,
7960
8483
  MainMenu: script$9,
7961
8484
  Skills: script$a,
8485
+ Inventory: script$b,
8486
+ Quests: script$c,
7962
8487
  },
7963
8488
  data() {
7964
8489
  return {
@@ -8216,7 +8741,7 @@ var script$b = vue.defineComponent({
8216
8741
  }
8217
8742
  return {
8218
8743
  title,
8219
- text: processText(dialogKey.text),
8744
+ text: dialogKey.text,
8220
8745
  styleId: dialogKey.speaker,
8221
8746
  choices: dialogKey.choices,
8222
8747
  old: index < this.dialog.length - 1,
@@ -8226,22 +8751,24 @@ var script$b = vue.defineComponent({
8226
8751
  },
8227
8752
  });
8228
8753
 
8229
- const _hoisted_1$a = ["width", "height"];
8230
- const _hoisted_2$8 = /*#__PURE__*/vue.createElementVNode("div", { class: "anchor" }, null, -1);
8231
- const _hoisted_3$5 = {
8754
+ const _hoisted_1$c = ["width", "height"];
8755
+ const _hoisted_2$a = /*#__PURE__*/vue.createElementVNode("div", { class: "anchor" }, null, -1);
8756
+ const _hoisted_3$7 = {
8232
8757
  key: 2,
8233
8758
  class: "flex flex-col",
8234
8759
  style: {"height":"100%","padding":"20px"}
8235
8760
  };
8236
- const _hoisted_4$4 = { id: "game-title-container" };
8237
- const _hoisted_5$4 = { id: "game-title-text" };
8238
- const _hoisted_6$4 = { class: "flex flex-col" };
8239
- const _hoisted_7$3 = { key: 3 };
8761
+ const _hoisted_4$6 = { id: "game-title-container" };
8762
+ const _hoisted_5$6 = { id: "game-title-text" };
8763
+ const _hoisted_6$6 = { class: "flex flex-col" };
8764
+ const _hoisted_7$5 = { key: 3 };
8240
8765
 
8241
- function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8766
+ function render$d(_ctx, _cache, $props, $setup, $data, $options) {
8242
8767
  const _component_Hud = vue.resolveComponent("Hud");
8243
8768
  const _component_Menu = vue.resolveComponent("Menu");
8244
8769
  const _component_Skills = vue.resolveComponent("Skills");
8770
+ const _component_Inventory = vue.resolveComponent("Inventory");
8771
+ const _component_Quests = vue.resolveComponent("Quests");
8245
8772
  const _component_MainMenu = vue.resolveComponent("MainMenu");
8246
8773
  const _component_DialogPicture = vue.resolveComponent("DialogPicture");
8247
8774
  const _component_DialogBox = vue.resolveComponent("DialogBox");
@@ -8269,9 +8796,21 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8269
8796
  onClose: _ctx.closeModal
8270
8797
  }, null, 8, ["onClose"]))
8271
8798
  : vue.createCommentVNode("", true),
8799
+ (_ctx.modal === 'inventory')
8800
+ ? (vue.openBlock(), vue.createBlock(_component_Inventory, {
8801
+ key: 1,
8802
+ onClose: _ctx.closeModal
8803
+ }, null, 8, ["onClose"]))
8804
+ : vue.createCommentVNode("", true),
8805
+ (_ctx.modal === 'quests')
8806
+ ? (vue.openBlock(), vue.createBlock(_component_Quests, {
8807
+ key: 2,
8808
+ onClose: _ctx.closeModal
8809
+ }, null, 8, ["onClose"]))
8810
+ : vue.createCommentVNode("", true),
8272
8811
  (_ctx.modal === 'menu')
8273
8812
  ? (vue.openBlock(), vue.createBlock(_component_MainMenu, {
8274
- key: 1,
8813
+ key: 3,
8275
8814
  onClose: _ctx.closeModal
8276
8815
  }, null, 8, ["onClose"]))
8277
8816
  : vue.createCommentVNode("", true),
@@ -8288,7 +8827,7 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8288
8827
  }),
8289
8828
  (_ctx.inGame)
8290
8829
  ? (vue.openBlock(), vue.createElementBlock("div", {
8291
- key: 2,
8830
+ key: 4,
8292
8831
  class: "background",
8293
8832
  style: vue.normalizeStyle(_ctx.backgroundStyle)
8294
8833
  }, [
@@ -8297,12 +8836,12 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8297
8836
  height: _ctx.layoutHeight,
8298
8837
  id: "background-canvas",
8299
8838
  class: "narrat-canvas"
8300
- }, null, 8, _hoisted_1$a)
8839
+ }, null, 8, _hoisted_1$c)
8301
8840
  ], 4))
8302
8841
  : vue.createCommentVNode("", true),
8303
8842
  (_ctx.inGame)
8304
8843
  ? (vue.openBlock(), vue.createElementBlock("div", {
8305
- key: 3,
8844
+ key: 5,
8306
8845
  class: "dialog override",
8307
8846
  ref: "dialog",
8308
8847
  style: vue.normalizeStyle(_ctx.dialogStyle)
@@ -8324,16 +8863,16 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8324
8863
  ]),
8325
8864
  _: 1
8326
8865
  }, 8, ["style"]),
8327
- _hoisted_2$8
8866
+ _hoisted_2$a
8328
8867
  ], 4))
8329
8868
  : vue.createCommentVNode("", true)
8330
8869
  ], 4))
8331
8870
  : (_ctx.gameLoaded)
8332
- ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$5, [
8333
- vue.createElementVNode("div", _hoisted_4$4, [
8334
- vue.createElementVNode("h1", _hoisted_5$4, vue.toDisplayString(_ctx.gameTitle), 1)
8871
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$7, [
8872
+ vue.createElementVNode("div", _hoisted_4$6, [
8873
+ vue.createElementVNode("h1", _hoisted_5$6, vue.toDisplayString(_ctx.gameTitle), 1)
8335
8874
  ]),
8336
- vue.createElementVNode("div", _hoisted_6$4, [
8875
+ vue.createElementVNode("div", _hoisted_6$6, [
8337
8876
  vue.createElementVNode("button", {
8338
8877
  class: "button menu-button start-button override",
8339
8878
  onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.startGame && _ctx.startGame(...args)))
@@ -8347,7 +8886,7 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8347
8886
  : vue.createCommentVNode("", true)
8348
8887
  ])
8349
8888
  ]))
8350
- : (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$3, [
8889
+ : (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$5, [
8351
8890
  vue.createVNode(_component_LoadingBar, {
8352
8891
  percentage: _ctx.loadingPercentage,
8353
8892
  step: _ctx.loadingStep
@@ -8360,10 +8899,10 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8360
8899
  ], 4))
8361
8900
  }
8362
8901
 
8363
- var css_248z$c = "#app {\n background-color: var(--bg-color);\n width: 100%;\n height: 100%;\n position: absolute;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n color: var(--text-color);\n box-sizing: border-box;\n overflow: hidden;\n transform-origin: center center;\n}\n\n.game {\n background-color: var(--bg-color);\n position: relative;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n overflow: hidden;\n}\n\n.interact-button {\n height: 50px;\n border: 1px solid black;\n font-weight: bold;\n font-size: 20px;\n text-align: center;\n flex-grow: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n.interact-button:not(:last-child) {\n margin-right: 10px;\n}\n\n.dialog-container {\n flex-shrink: 2;\n /* padding: 20px; */\n min-height: 100%;\n width: 100%;\n background-color: (var(--bg-color));\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n overflow-x: hidden;\n}\n\n.dialog {\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n -ms-overflow-style: none; /* IE and Edge */\n scrollbar-width: none; /* Firefox */\n}\n\n.dialog::-webkit-scrollbar {\n display: none; /* webkit */\n}\n\n.dialog * {\n overflow-anchor: none;\n}\n\n.background {\n margin: 0;\n}\n\n#background-canvas {\n height: 100%;\n}\n\n.anchor {\n overflow-anchor: auto;\n height: 1px;\n}\n\n.menu-toggle {\n position: fixed;\n bottom: 0px;\n right: 15%;\n z-index: 2;\n}\n\n#game-title-container {\n margin-bottom: 50px;\n}\n\n#game-title-text {\n text-align: center;\n font-size: 50px;\n}\n\n.menu-button {\n font-size: 25px;\n}\r\n";
8364
- styleInject(css_248z$c);
8902
+ var css_248z$e = "#app {\n background-color: var(--bg-color);\n width: 100%;\n height: 100%;\n position: absolute;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n color: var(--text-color);\n box-sizing: border-box;\n overflow: hidden;\n transform-origin: center center;\n}\n\n.game {\n background-color: var(--bg-color);\n position: relative;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n overflow: hidden;\n}\n\n.interact-button {\n height: 50px;\n border: 1px solid black;\n font-weight: bold;\n font-size: 20px;\n text-align: center;\n flex-grow: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n.interact-button:not(:last-child) {\n margin-right: 10px;\n}\n\n.dialog-container {\n flex-shrink: 2;\n /* padding: 20px; */\n min-height: 100%;\n width: 100%;\n background-color: (var(--bg-color));\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n overflow-x: hidden;\n}\n\n.dialog {\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n -ms-overflow-style: none; /* IE and Edge */\n scrollbar-width: none; /* Firefox */\n}\n\n.dialog::-webkit-scrollbar {\n display: none; /* webkit */\n}\n\n.dialog * {\n overflow-anchor: none;\n}\n\n.background {\n margin: 0;\n}\n\n#background-canvas {\n height: 100%;\n}\n\n.anchor {\n overflow-anchor: auto;\n height: 1px;\n}\n\n.menu-toggle {\n position: fixed;\n bottom: 0px;\n right: 15%;\n z-index: 2;\n}\n\n#game-title-container {\n margin-bottom: 50px;\n}\n\n#game-title-text {\n text-align: center;\n font-size: 50px;\n}\n\n.menu-button {\n font-size: 25px;\n}\r\n";
8903
+ styleInject(css_248z$e);
8365
8904
 
8366
- script$b.render = render$b;
8905
+ script$d.render = render$d;
8367
8906
 
8368
8907
  let canvas;
8369
8908
  let ctx;
@@ -8863,7 +9402,76 @@ const waitParser = (ctx) => {
8863
9402
  };
8864
9403
  const waitCommand = new CommandPlugin('wait', wait, waitParser);
8865
9404
 
9405
+ // Write a CommandPlugin for adding items to the inventory store
9406
+ const addItemPlugin = new CommandPlugin('add_item', async (cmd) => {
9407
+ const id = cmd.args[0];
9408
+ const amount = cmd.args[1];
9409
+ const inventory = useInventory();
9410
+ inventory.add({
9411
+ id,
9412
+ amount,
9413
+ });
9414
+ return useVM().nextLine();
9415
+ }, generateParser('add_item'));
9416
+
9417
+ // Write a CommandPlugin for removeing items to the inventory store
9418
+ const removeItemPlugin = new CommandPlugin('remove_item', async (cmd) => {
9419
+ const id = cmd.args[0];
9420
+ const amount = cmd.args[1];
9421
+ const inventory = useInventory();
9422
+ inventory.remove({
9423
+ id,
9424
+ amount,
9425
+ });
9426
+ return useVM().nextLine();
9427
+ }, generateParser('remove_item'));
9428
+
9429
+ // Write a CommandPlugin for starting a quest with the useQuests quests store
9430
+ const startQuestPlugin = new CommandPlugin('start_quest', async (cmd) => {
9431
+ const questId = cmd.args[0];
9432
+ const quests = useQuests();
9433
+ quests.startQuest(questId);
9434
+ return useVM().nextLine();
9435
+ }, generateParser('start_quest'));
9436
+ // Write a CommandPlugin for starting a quest objective with the cmd having arguments questId and objectiveId, using the useQuests store's startObjective method
9437
+ const startObjectivePlugin = new CommandPlugin('start_objective', async (cmd) => {
9438
+ const questId = cmd.args[0];
9439
+ const objectiveId = cmd.args[1];
9440
+ const quests = useQuests();
9441
+ quests.startObjective(questId, objectiveId);
9442
+ return useVM().nextLine();
9443
+ }, generateParser('start_objective'));
9444
+ // Write a CommandPlugin for completing a quest objective with the cmd having arguments questId and objectiveId, using the useQuests store's completeObjective method
9445
+ const completeObjectivePlugin = new CommandPlugin('complete_objective', async (cmd) => {
9446
+ const questId = cmd.args[0];
9447
+ const objectiveId = cmd.args[1];
9448
+ const quests = useQuests();
9449
+ quests.completeObjective(questId, objectiveId);
9450
+ return useVM().nextLine();
9451
+ }, generateParser('complete_objective'));
9452
+ // Write a CommandPlugin for completing a quest with the cmd having arguments questId, using the useQuests store's completeQuest method
9453
+ const completeQuestPlugin = new CommandPlugin('complete_quest', async (cmd) => {
9454
+ const questId = cmd.args[0];
9455
+ let ending;
9456
+ if (cmd.args.length > 1) {
9457
+ ending = cmd.args[1];
9458
+ }
9459
+ const quests = useQuests();
9460
+ quests.completeQuest(questId, ending);
9461
+ return useVM().nextLine();
9462
+ }, generateParser('complete_quest'));
9463
+
9464
+ // Write a CommandPlugin for running a label using the runLabelFunction of the useVM store
9465
+ const runLabelPlugin = new CommandPlugin('run_label', async (cmd) => {
9466
+ const label = cmd.args[0];
9467
+ if (!label) {
9468
+ error(`run_label command needs a label to argument run`);
9469
+ }
9470
+ await useVM().runLabelFunction(label);
9471
+ }, generateParser('run_label'));
9472
+
8866
9473
  function registerBaseCommands(vm) {
9474
+ vm.addCommand(addItemPlugin);
8867
9475
  vm.addCommand(addLevelPlugin);
8868
9476
  vm.addCommand(addStatPlugin);
8869
9477
  vm.addCommand(addXpPlugin);
@@ -8875,6 +9483,7 @@ function registerBaseCommands(vm) {
8875
9483
  vm.addCommand(notifyPlugin);
8876
9484
  vm.addCommand(pauseCommand);
8877
9485
  vm.addCommand(playCommand);
9486
+ vm.addCommand(removeItemPlugin);
8878
9487
  vm.addCommand(setButtonCommand);
8879
9488
  vm.addCommand(setScreenCommand);
8880
9489
  vm.addCommand(setStatCommand);
@@ -8883,6 +9492,14 @@ function registerBaseCommands(vm) {
8883
9492
  vm.addCommand(talkCommand);
8884
9493
  vm.addCommand(textCommandPlugin);
8885
9494
  vm.addCommand(waitCommand);
9495
+ // functions and labels
9496
+ vm.addCommand(jumpCommand);
9497
+ vm.addCommand(runLabelPlugin);
9498
+ // Quests
9499
+ vm.addCommand(startQuestPlugin);
9500
+ vm.addCommand(startObjectivePlugin);
9501
+ vm.addCommand(completeObjectivePlugin);
9502
+ vm.addCommand(completeQuestPlugin);
8886
9503
  }
8887
9504
 
8888
9505
  class NarratPlugin {
@@ -8908,7 +9525,7 @@ vm.callHook('onPageLoaded');
8908
9525
  async function startApp(config, options) {
8909
9526
  const configFile = await getFile('data/config.json');
8910
9527
  setConfig(JSON.parse(configFile));
8911
- app = vue.createApp(script$b, {
9528
+ app = vue.createApp(script$d, {
8912
9529
  config,
8913
9530
  options,
8914
9531
  });
@@ -8925,7 +9542,7 @@ async function startApp(config, options) {
8925
9542
  });
8926
9543
  registerBaseCommands(vm);
8927
9544
  logManager.setupDebugger(options.debug);
8928
- console.log('%c Narrat game engine – 1.1.0 - June 25, 2022 09:56:51', 'background: #222; color: #bada55');
9545
+ console.log('%c Narrat game engine – 1.3.0 - June 25, 2022 18:05:43', 'background: #222; color: #bada55');
8929
9546
  vm.callHook('onNarratSetup');
8930
9547
  app.mount('#game-holder');
8931
9548
  if (options.debug) {
@@ -8955,6 +9572,9 @@ exports.addCommand = addCommand;
8955
9572
  exports.aspectRatioFit = aspectRatioFit;
8956
9573
  exports.generateParser = generateParser;
8957
9574
  exports.getConfig = getConfig;
9575
+ exports.getItemConfig = getItemConfig;
9576
+ exports.getObjectiveConfig = getObjectiveConfig;
9577
+ exports.getQuestConfig = getQuestConfig;
8958
9578
  exports.getSkillConfig = getSkillConfig;
8959
9579
  exports.registerPlugin = registerPlugin;
8960
9580
  exports.setConfig = setConfig;