@patterkit/ops 0.26.1 → 0.26.3

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.
Files changed (2) hide show
  1. package/dist/index.js +4 -3
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -2704,7 +2704,7 @@ import { canonicalStringify as canonicalStringify5 } from "@patterkit/core";
2704
2704
  import { DEFAULT_PAD_AFTER } from "@patterkit/model";
2705
2705
 
2706
2706
  // src/playable-runtime.ts
2707
- var PLAYABLE_RUNTIME_JS = 'var Patterplay=(()=>{var pe=Object.defineProperty;var xt=Object.getOwnPropertyDescriptor;var kt=Object.getOwnPropertyNames;var Et=Object.prototype.hasOwnProperty;var Dt=(r,e)=>{for(var t in e)pe(r,t,{get:e[t],enumerable:!0})},Ct=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of kt(e))!Et.call(r,s)&&s!==t&&pe(r,s,{get:()=>e[s],enumerable:!(n=xt(e,s))||n.enumerable});return r};var It=r=>Ct(pe({},"__esModule",{value:!0}),r);var rn={};Dt(rn,{Checkpoint:()=>K,DEFAULT_PAD_AFTER:()=>O,Engine:()=>ce,Flow:()=>A,buildTagIndex:()=>oe,compareStages:()=>F,describeBundle:()=>gt,effectiveGameData:()=>ht,estimateLineDuration:()=>Ve,extensionDecls:()=>mt,extensionsOf:()=>yt,gameDataFields:()=>ft,gameDataValue:()=>Ee,nextStage:()=>L,resolveSceneRef:()=>re,sceneAddressIndex:()=>Se,stageIndex:()=>B});function M(r,e){return r!==void 0&&Object.prototype.hasOwnProperty.call(r,e)?r[e]:void 0}function R(r){switch(r[0]){case"b":return{kind:"bool",value:r[1]};case"n":return{kind:"number",value:r[1]};case"s":return{kind:"string",value:r[1]};case"sv":return{kind:"scopedvar",scope:r[1],name:r[2]};case"u":return{kind:"unary",op:r[1],operand:R(r[2])};case"bin":return{kind:"binary",op:r[1],left:R(r[2]),right:R(r[3])};case"call":{let e=r.slice(2).map(R);return{kind:"call",name:r[1],args:e}}case"fd":return{kind:"flagdelta",sign:r[1],name:r[2]}}}var u=class extends Error{constructor(e){super(e),this.name="EvalError"}};function Y(r,e,t){let n=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),s=i=>{switch(i.kind){case"bool":return i.value;case"number":return i.value;case"string":return i.value;case"scopedvar":{let o=M(e.scopes,i.scope);if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):M(o,i.name);if(a===void 0){if(n.get(i.scope)==="throw")throw new u(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{if(i.name==="advance"&&!M(t.functions,i.name)){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new u(`advance() takes exactly 1 argument, got ${i.args.length}`);let c=ue(a,e);if(c===void 0)throw new u("advance() needs a quality reference (@scope.name of a quality property)");let l=v(s(a),c,"advance");return c[Math.min(l+1,c.length-1)]}let o=M(t.functions,i.name);if(!o)throw new u(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:s,ctx:e})}case"flagdelta":throw new u("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=s(i.operand);if(typeof a!="boolean")throw new u(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=s(i.operand);if(typeof o!="number")throw new u(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let g=s(i.left);if(typeof g!="boolean")throw new u(`\'and\' requires boolean operands, left is ${typeof g}`);if(!g)return!1;let f=s(i.right);if(typeof f!="boolean")throw new u(`\'and\' requires boolean operands, right is ${typeof f}`);return f}if(i.op==="or"){let g=s(i.left);if(typeof g!="boolean")throw new u(`\'or\' requires boolean operands, left is ${typeof g}`);if(g)return!0;let f=s(i.right);if(typeof f!="boolean")throw new u(`\'or\' requires boolean operands, right is ${typeof f}`);return f}let o=s(i.left),a=s(i.right),c=ue(i.left,e),l=ue(i.right,e),d=c??l;if(d!==void 0){if(c&&l&&!Rt(c,l)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new u(`\'${i.op}\' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return v(o,d,">")>v(a,d,">");case">=":return v(o,d,">=")>=v(a,d,">=");case"<":return v(o,d,"<")<v(a,d,"<");case"<=":return v(o,d,"<=")<=v(a,d,"<=");case"+":case"-":case"*":case"/":throw new u(`\'${i.op}\' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(i.op){case"==":return Oe(o,a);case"!=":return!Oe(o,a);case">":return P(o,a,">"),o>a;case">=":return P(o,a,">="),o>=a;case"<":return P(o,a,"<"),o<a;case"<=":return P(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new u(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return P(o,a,"-"),o-a;case"*":return P(o,a,"*"),o*a;case"/":if(P(o,a,"/"),a===0)throw new u("division by zero");return o/a}}}};return s(r)}function Oe(r,e){if(Array.isArray(r)||Array.isArray(e)){if(!Array.isArray(r)||!Array.isArray(e)||r.length!==e.length)return!1;let t=[...r].sort(),n=[...e].sort();for(let s=0;s<t.length;s++)if(t[s]!==n[s])return!1;return!0}return r===e}function P(r,e,t){if(typeof r!="number"||typeof e!="number")throw new u(`\'${t}\' requires numeric operands, got ${typeof r} and ${typeof e}`)}function ue(r,e){if(!(r.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(r.scope,r.name)}function v(r,e,t){if(typeof r!="string")throw new u(`\'${t}\' on a quality compares stages, got ${typeof r}`);let n=e.indexOf(r);if(n<0)throw new u(`"${r}" is not a stage of this quality (stages: ${e.join(", ")})`);return n}var Rt=(r,e)=>r.length===e.length&&r.every((t,n)=>t===e[n]);function j(r){if(Number.isNaN(r)||!Number.isFinite(r))return 0;let e=Math.trunc(r)%4294967296;return e<0?e+4294967296:e}function ge(r){let e=j(r);return{next(){e=e+1831565813>>>0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296},state(){return e}}}var he=r=>Array.isArray(r)?r:r.stages??[],Pt=r=>Array.isArray(r)?"flags":r==null?"nothing":typeof r;function B(r,e){return typeof e=="string"?he(r).indexOf(e):-1}function fe(r,e){if(typeof e!="string")throw new u(`a stage is a name, got ${Pt(e)}`);let t=r.indexOf(e);if(t<0)throw new u(`"${e}" is not a stage of this quality (stages: ${r.join(", ")})`);return t}function F(r,e,t){let n=he(r),s=fe(n,e)-fe(n,t);return s<0?-1:s>0?1:0}function L(r,e){let t=he(r);return t[Math.min(fe(t,e)+1,t.length-1)]}function $(r,e,t){switch(r.type){case"boolean":return typeof e=="boolean";case"number":return typeof e=="number";case"string":case"text":case"multiline":return typeof e=="string";case"enum":return typeof e!="string"?!1:e===""&&t?.noneChosen?!0:!Array.isArray(r.values)||r.values.includes(e);case"flags":return Array.isArray(e)&&e.every(n=>typeof n=="string"&&(!Array.isArray(r.values)||r.values.includes(n)));case"quality":return typeof e=="string"&&(!Array.isArray(r.stages)||r.stages.includes(e));default:return!0}}var Ot={name:"check_flags",count:r=>Math.max(1,r.args.length-1)},Nt=[Ot];function Ne(r,e,t){let n=t?.countingCalls??Nt;return Z(r,t?.want??!0,e,n)}function Z(r,e,t,n){if(r.kind==="binary"&&(r.op==="and"||r.op==="or")){let s=Z(r.left,e,t,n),i=Z(r.right,e,t,n);return r.op==="and"===e?s>0&&i>0?s+i:0:Math.max(s,i)}if(r.kind==="unary"&&r.op==="not")return Z(r.operand,!e,t,n);if(r.kind==="call"){let s=n.find(i=>i.name===r.name);if(s){let i=s.count(r),o=t(r);return e?o?i:0:o?0:1}}return t(r)===e?1:0}var E=class r{values=Object.create(null);decls=new Map;subscribers=new Set;auditors=new Set;norm;pathPrefix;constructor(e=[],t){this.norm=t?.normalise??(n=>n.toLowerCase()),this.pathPrefix=t?.pathPrefix??"",this.seed(e)}seed(e){for(let t of e){let n=this.norm(t.name);this.decls.set(n,t),this.values[n]=structuredClone(t.default??T(t))}}get(e){return this.values[this.norm(e)]}normalise(e){return this.norm(e)}writable(e){return this.decls.get(this.norm(e))?.writable!==!1}set(e,t,n){let s=this.norm(e);if(!n?.host&&!this.writable(s))throw new Error(`\'${e}\' is read-only`);let i={name:s,prev:this.values[s],next:t,silent:n?.silent??!1,reason:n?.reason};this.values[s]=t;for(let o of[...this.auditors])o(i);if(!i.silent)for(let o of[...this.subscribers])o(i);return i}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}onAudit(e){return this.auditors.add(e),()=>this.auditors.delete(e)}rows(){return[...this.decls.entries()].map(([e,t])=>Be(t,this.get(e),void 0,e,this.pathPrefix))}declarations(){return[...this.decls.values()]}clone(){let e=new r([],{normalise:this.norm,pathPrefix:this.pathPrefix});return e.decls=new Map(this.decls),Object.assign(e.values,structuredClone(this.values)),e}reseed(e){for(let t of Object.keys(this.values))delete this.values[t];this.decls.clear(),this.seed(e)}save(){return structuredClone(this.values)}load(e,t){let n=new Map;for(let[i,o]of Object.entries(e)){let a=this.norm(i);this.values[a]=structuredClone(o),n.set(a,o)}let s=[];if(!t?.refit)return s;for(let[i,o]of this.decls){if(!n.has(i))continue;let a=n.get(i);$(o,a,{noneChosen:o.type==="enum"&&o.default===""})||(this.values[i]=structuredClone(T(o)),s.push({name:i,value:a}))}return s}};function Be(r,e,t,n,s=""){let i=n??r.name.toLowerCase();return{name:i,path:s+i,type:r.type,value:e,default:r.default??T(r),...r.values!==void 0?{values:r.values}:{},...r.stages!==void 0?{stages:r.stages}:{},writable:t??r.writable??!0}}var At=r=>r.toLowerCase(),me=1,ee=class{scopes=new Map;parked=new Map;parkedRefit=new Set;misfits=[];rev=0;get revision(){return this.rev}defineOwned(e,t,n){let s=typeof n=="string"?{pathPrefix:n}:n??{},i=new E(t,{pathPrefix:s.pathPrefix??`${e}.`,...s.normalise?{normalise:s.normalise}:{}});return this.mountOwned(e,i,s.owner!==void 0?{owner:s.owner}:void 0)}mountOwned(e,t,n){this.assertFree(e,n?.owner),this.scopes.set(e,{kind:"owned",bag:t,...n?.owner!==void 0?{owner:n.owner}:{}}),this.rev++;let s=this.parked.get(e);return s&&(this.note(e,t.load(s,{refit:this.parkedRefit.has(e)})),this.parked.delete(e),this.parkedRefit.delete(e)),this}remove(e,t){let n=this.scopes.get(e);if(!n)throw new Error(`unknown scope \'@${e}\'`);return t?.keep&&n.kind==="owned"&&(this.parked.set(e,n.bag.save()),this.parkedRefit.delete(e)),this.scopes.delete(e),this.rev++,this}discardParked(e){if(e===void 0)this.parked.clear(),this.parkedRefit.clear();else for(let t of[...this.parked.keys()])t.startsWith(e)&&(this.parked.delete(t),this.parkedRefit.delete(t));return this}takeMisfits(e){if(!e){let n=this.misfits;return this.misfits=[],n}let t=this.misfits.filter(n=>e(n.scope));return this.misfits=this.misfits.filter(n=>!e(n.scope)),t}note(e,t){for(let n of t)this.misfits.push({scope:e,name:n.name,value:n.value})}ownedBag(e){let t=this.scopes.get(e);if(!t||t.kind!=="owned")throw new Error(`\'@${e}\' is not an owned scope`);return t.bag}reseedOwned(e,t){return this.ownedBag(e).reseed(t),this}defineForeign(e,t,n=[],s=!0){let i=typeof s=="boolean"?{writable:s}:s;this.assertFree(e,i.owner);let o=i.normalise??At,a=new Map;for(let c of n)a.set(o(c.name),c);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:a,scopeWritable:i.writable??!0,norm:o,...i.owner!==void 0?{owner:i.owner}:{}}),this.rev++,this}has(e){return this.scopes.has(e)}get(e,t){let n=this.scopes.get(e);if(n)return n.kind==="owned"?n.bag.get(t):n.resolver.get(n.norm(t))}set(e,t,n,s){let i=this.scopes.get(e);if(!i)throw new Error(`unknown scope \'@${e}\'`);if(i.kind==="owned"){if(!s?.host&&!i.bag.writable(t))throw new Error(`\'@${e}.${t}\' is read-only`);i.bag.set(t,n,s?.host?{host:!0}:void 0);return}let o=i.norm(t);if(!i.resolver.set)throw new Error(`\'@${e}.${t}\' is read-only`);if(!s?.host&&!this.foreignWritable(i,o))throw new Error(`\'@${e}.${t}\' is read-only`);i.resolver.set(o,n)}foreignWritable(e,t){return e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}listProperties(){let e=[];for(let[t,n]of this.scopes){let s=n.owner!==void 0?{owner:n.owner}:{};if(n.kind==="owned")for(let i of n.bag.rows())e.push({scope:t,...s,...i});else for(let[i,o]of n.decls)e.push({scope:t,...s,...Be(o,n.resolver.get(i),this.foreignWritable(n,i),i,`${t}.`)})}return e}toEvalContext(e,t){let n=this.view(t?.aliases),s={};for(let[o,a]of n)s[o]=a.kind==="owned"?a.bag.values:a.resolver;let i=this.qualityLadders(n);return i.size===0?{scopes:s,host:e}:{scopes:s,host:e,qualities:(o,a)=>{let c=n.get(o);return c?i.get(o)?.get(Bt(c)(a)):void 0}}}view(e){let t=new Map(this.scopes);for(let[n,s]of Object.entries(e??{})){let i=this.scopes.get(s);if(!i)throw new Error(`alias \'@${n}\' names \'${s}\', which is not registered`);t.set(n,i)}return t}qualityLadders(e){let t=new Map;for(let[n,s]of e)for(let[i,o]of Ae(s)){if(o.type!=="quality"||o.stages===void 0)continue;let a=t.get(n);a||(a=new Map,t.set(n,a)),a.set(i,o.stages)}return t}toSchema(e){let t=new Map;for(let[n,s]of this.view(e?.aliases)){let i=Ae(s);if(i.length===0)continue;let o=new Map;for(let[a,c]of i)o.set(a,{type:c.type,enumValues:c.values,...c.stages!==void 0?{stages:c.stages}:{}});t.set(n,o)}return{properties:t}}save(){let e={};for(let[t,n]of this.scopes)n.kind==="owned"&&(e[t]=n.bag.save());for(let[t,n]of this.parked)e[t]=structuredClone(n);return e}load(e,t){t?.keepParked||(this.parked.clear(),this.parkedRefit.clear());let n=t?.refit===!0;for(let[s,i]of Object.entries(e)){let o=this.scopes.get(s);o?.kind==="owned"?this.note(s,o.bag.load(i,{refit:n})):o||(this.parked.set(s,structuredClone(i)),n?this.parkedRefit.add(s):this.parkedRefit.delete(s))}}saveFragment(){return{version:me,scopes:this.save()}}loadFragment(e){if(e.version!==me)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${me})`);this.load(e.scopes)}assertFree(e,t){let n=this.scopes.get(e);if(!n)return;let s=n.owner!==void 0?` by ${n.owner}`:"",i=t!==void 0?` (wanted by ${t})`:"";throw new Error(`scope \'@${e}\' is already registered${s}${i}`)}};function Ae(r){return r.kind==="foreign"?[...r.decls.entries()]:r.bag.declarations().map(e=>[r.bag.normalise(e.name),e])}function Bt(r){return r.kind==="foreign"?r.norm:e=>r.bag.normalise(e)}function T(r){if(r.default!==void 0)return r.default;switch(r.type){case"boolean":return!1;case"number":return 0;case"string":case"text":case"multiline":return"";case"enum":return r.values?.[0]??"";case"flags":return[];case"quality":return r.stages?.[0]??"";default:return!1}}var Fe=[{token:"patter",engine:"Patterplay",means:"Patter\'s shared globals"},{token:"story",engine:"Storylet Engine",means:"the Storylet Engine\'s shared @story properties"}];function G(r){return r.ctx.host??{}}var ye={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(r,e){if(r.length!==2)throw new u("random(a, b) requires exactly 2 arguments");let t=G(e).nextRandom;if(!t)throw new u("random() called without a PRNG in context");let n=e.evaluate(r[0]),s=e.evaluate(r[1]);if(typeof n!="number"||typeof s!="number")throw new u("random(a, b) arguments must be numbers");if(!Number.isInteger(n)||!Number.isInteger(s))throw new u("random(a, b) arguments must be integers");let i=Math.min(n,s),o=Math.max(n,s);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:Te("check_flags"),eval(r,e){let t=Le(r[0],e,"check_flags");for(let n=1;n<r.length;n++){let s=r[n];if(s.kind!=="flagdelta")throw new u("check_flags() flag args must be +flagName or -flagName");if(s.sign==="+"?!t.includes(s.name):t.includes(s.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:Te("set_flags"),eval(r,e){let t=[...Le(r[0],e,"set_flags")];for(let n=1;n<r.length;n++){let s=r[n];if(s.kind!=="flagdelta")throw new u("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let i=t.indexOf(s.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:ne("visits"),eval:(r,e)=>G(e).visits?.(te(r,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:ne("seen"),eval:(r,e)=>(G(e).visits?.(te(r,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:ne("patter_visits"),eval:(r,e)=>G(e).patterVisits?.(te(r,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:ne("patter_seen"),eval:(r,e)=>(G(e).patterVisits?.(te(r,e,"patter_seen"))??0)>0}}},An=Fe.map(r=>r.token).filter(r=>r!=="patter"&&r!=="scene");function Me(r,e){let t=r.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function te(r,e,t){let n=e.evaluate(r[0]);if(typeof n!="string")throw new u(`${t}(id) requires a string node id`);return n}function ne(r){return(e,t)=>{let n=e[0];n&&n.kind!=="string"&&t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${r}(id): the argument must be a string id literal (a scene / block / node id)`})}}function Le(r,e,t){if(!r)throw new u(`${t}() requires at least one argument (the flags variable)`);let n=e.evaluate(r);if(Array.isArray(n))return n;if(n===!1||n===null||n===void 0)return[];throw new u(`${t}() first argument must be a flags property`)}function Te(r){return(e,t)=>{if(e.length===0)return;let n=e[0];if(n.kind!=="scopedvar"){t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${r}(): first argument must be a flags property reference (@name or @scope.name)`});return}let s=t.schema.properties.get(n.scope)?.get(n.name);if(s&&s.type!=="flags"){let i=n.scope===t.defaultScope?n.name:`${n.scope}.${n.name}`;t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${r}(): \'@${i}\' is not a flags property (got ${s.type})`});return}for(let i=1;i<e.length;i++){let o=e[i];o.kind!=="flagdelta"?t.report({path:[...t.path,"args",i],kind:"wrong-arg-type",severity:"error",message:`${r}(): argument ${i+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${r}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var Ft=/^@[A-Za-z0-9_.]+$/;function*Lt(r){let e="",t=0;for(;t<r.length;){let n=r[t];if(n==="{"&&r[t+1]==="{"){e+="{",t+=2;continue}if(n==="}"&&r[t+1]==="}"){e+="}",t+=2;continue}if(n==="{"){let s=r.indexOf("}",t+1);if(s!==-1){let i=r.slice(t,s+1),o=r.slice(t+1,s).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:Ft.test(o)?o:void 0},t=s+1;continue}e+=i,t=s+1;continue}}e+=n,t+=1}e&&(yield{kind:"text",value:e})}function Tt(r){return Array.isArray(r)?r.join(", "):typeof r=="boolean"?r?"true":"false":String(r)}function Mt(r){return r===" "||r===" "||r===`\n`||r==="\\r"||r==="\\f"||r==="\\v"}function jt(r){let e="",t=!1;for(let n of r){if(Mt(n)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=n}return e}function je(r,e,t){if(e.length===0||r.indexOf(e)<0)return r;let n="",s=0,i=!1;for(;s<r.length;){if(r.startsWith(e,s)){let o=r.indexOf(t,s+e.length);if(o>=0){s=o+t.length,i=!0;continue}n+=r.slice(s);break}n+=r[s],s+=1}return i?jt(n):r}function $e(r,e){if(r.indexOf("{")<0)return r;let t="";for(let n of Lt(r)){if(n.kind==="text"){t+=n.value;continue}if(!n.ref){t+=n.raw;continue}let s=e(n.ref);t+=s===void 0?"":Tt(s)}return t}function Ge(r){return r.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function D(r,e){for(let t of r){e(t);let n=t.children;n&&D(n,e)}}function y(r){let e=r.gameId?.trim();return e||Ge(r.name)}function Se(r){let e=new Map;for(let[t,n]of Object.entries(r))e.set(y(n),t);return e}function re(r,e,t){return(t??Se(r)).get(e)??(Object.hasOwn(r,e)?e:void 0)}var O=.6;var $t=14,Gt=1.5,Vt=18;function Ve(r,e){let t=0;for(let n of r??"")n!=="\\xAD"&&t++;return Math.min(Math.max(t/$t,Gt),Vt)}function se(r){return`cast:${r}`}function ie(r){return`qualifier:${r}`}function qe(r,e){return`speaker:${r}:${e}`}var _e="speaker:pattern",He="{name} ({qualifier})";function Ue(r,e,t){return r.split("{name}").map(n=>n.split("{qualifier}").join(t)).join(e)}var we={open:"[",close:"]"},We="SFX";var V=4;function q(r){let e=new Set,t=[];for(let n of r)e.has(n)||(e.add(n),t.push(n));return t}function oe(r){let e=new Map,t=(n,s)=>{let i=q([...s,...n.tags??[]]);if(e.set(n.id,i),n.type==="group"&&n.prompt&&e.set(n.prompt.id,q([...i,...n.prompt.tags??[]])),n.type==="group")for(let o of n.children)t(o,i);else for(let o of n.beats??[])e.set(o.id,q([...i,...o.tags??[]]))};for(let n of Object.values(r.scenes)){let s=q(n.tags??[]);e.set(n.id,s);for(let i of n.blocks){let o=q([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var Ke=r=>r.kind==="line"||r.kind==="text",_=r=>typeof r=="number"&&Number.isFinite(r)?r:void 0;function Je(r){let e=new Map,t=(i,o,a)=>{let c=i.kind==="gameEvent"?void 0:_(i.padAfter),l=c??o;a&&l<0&&(l=0),e.set(i.id,c!==void 0?{own:c,resolved:l}:{resolved:l})},n=(i,o)=>{let a=_(i.padAfterDefault)??o;if(i.type==="group"){i.prompt&&t(i.prompt,a,!1);for(let d of i.children)n(d,a);return}let c=i.beats??[],l=-1;c.forEach((d,g)=>{Ke(d)&&(l=g)}),c.forEach((d,g)=>{Ke(d)&&t(d,a,g===l)})},s=_(r.padAfterDefault)??O;for(let i of Object.values(r.scenes)){let o=_(i.padAfterDefault)??s;for(let a of i.blocks){let c=_(a.padAfterDefault)??o;for(let l of a.children)n(l,c)}}return e}var Qe=new WeakMap,ze=new WeakMap;function qt(r){let e=ze.get(r);return e||(e=oe(r),ze.set(r,e)),e}var Xe=new WeakMap;function _t(r){let e=Xe.get(r);return e||(e=Je(r),Xe.set(r,e)),e}var Ye=new WeakMap;function Ht(r){let e=Ye.get(r);if(e)return e;e=new Map;for(let t of Object.values(r.scenes))for(let n of t.blocks)D(n.children,s=>{if(s.type==="group"&&s.selector==="choice")for(let i of s.children)e.set(i.id,s.id)});return Ye.set(r,e),e}var Ze=new WeakMap;function Ut(r){let e=Ze.get(r);if(e)return e;e=new Map;for(let t of Object.values(r.scenes))for(let n of t.blocks)D(n.children,s=>{if(s.type==="group"){s.prompt&&e.set(s.prompt.id,s.prompt);return}for(let i of s.beats??[])e.set(i.id,i)});return Ze.set(r,e),e}function b(r){if(r===void 0)return;let e={};for(let[t,n]of Object.entries(r))e[t]=Array.isArray(n)?[...n]:n;return e}function N(r,e){return r.tagIndex.get(e)?.slice()}var U="Patter",H=r=>r.replace(/%/g,"%25").replace(/\\//g,"%2F"),Wt=r=>r.replace(/%2F/g,"/").replace(/%25/g,"%"),et=Symbol("ownsRegistry"),tt=Symbol("setupReported"),w={stage:r=>`patter/scene/${H(r)}`,flow:r=>`patter/flow/${H(r)}/`,flowGlobals:r=>`patter/flow/${H(r)}/patter`,flowScene:(r,e)=>`patter/flow/${H(r)}/scene/${H(e)}`},K=class{constructor(e){this.journal=e}journal},ce=class r{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;requestedLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineSeq=0;engineTraceHandlers=new Set;constructor(e,t={}){this.creationOptions=t;let n=[];for(let p of Object.keys(t))Jt.has(p)||n.push({node:p,message:p==="world"?\'the engine option "world" has gone: bind the scope as hostScopes: { world }\':`"${p}" isn\'t an engine option, so it\'s ignored`});let s=e.strings;this.allStrings=s,this.requestedLocale=t.locale,this.currentLocale=be(e,t.locale),this.currentLocale.problem&&n.push({node:t.locale,message:this.currentLocale.problem});let i=ot(s,this.currentLocale),o=s[e.locales.default]??{},a=e.localisation,c=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let l=new Map;for(let p of e.cast??[])p.displayName&&l.set(p.name,p.displayName);let d=new Map;for(let p of e.qualifiers??[])p?.gameId&&d.set(p.gameId,p.name);let g=new Map;for(let p of e.cast??[])for(let[m,h]of Object.entries(p.qualifierLabels??{}))typeof h=="string"&&g.set(`${p.name}\\0${m}`,h);let f=e.speakerPattern??He;this.defaultSeed=(t.seed??2654435769)>>>0;let I=new Map,Q=new Map,De=new Map;for(let[p,m]of Object.entries(e.scenes)){this.sceneGameIdToId.set(y(m),p);let h=new Map;for(let S of m.blocks)Q.set(S.id,{sceneId:p}),De.set(S.id,S),h.set(y(S),S.id),D(S.children,k=>I.set(k.id,k));this.blockGameIdToId.set(p,h)}let Ce=e.properties??[],le=Ce.filter(p=>p.shared??!0).map(it),St=Ce.filter(p=>!(p.shared??!0)).map(it),wt=new Set(le.map(p=>p.name.toLowerCase())),x=t.registry??new ee,Ie=!t.registry||t[et]===!0,Re=new E(le,{pathPrefix:"@patter."}),de=[],z=[];try{x.mountOwned("patter",Re,{owner:U}),z.push("patter");let p=new Set,m=e.scopeRegistry?.scopes??[];for(let[h,S]of Object.entries(t.hostScopes??{})){let k=m.find(X=>X.token===h);if(!k&&!(e.externalScopes??[]).includes(h)){let X=m.find(vt=>vt.token.toLowerCase()===h.toLowerCase());n.push({node:h,message:X?`hostScopes binds "${h}", which this bundle doesn\'t declare: it declares "${X.token}", and a scope\'s token is case-sensitive`:`hostScopes binds "${h}", which this bundle doesn\'t declare`})}let bt=(k?.declarations??[]).map(pt);x.defineForeign(h,S,bt,{writable:k?.writable??!0,owner:U}),z.push(h),p.add(h)}for(let h of Ie?e.scopeRegistry?.scopes??[]:[]){if(p.has(h.token)||x.has(h.token))continue;let S=(h.declarations??[]).map(k=>Xt(k,h.writable));x.defineOwned(h.token,S,{owner:U}),z.push(h.token),de.push(h.token)}}catch(p){for(let m of z)x.remove(m,{keep:!0});throw p}let Pe=new Map;for(let[p,m]of Object.entries(e.scenes)){let h=new Set((m.sceneProps??[]).filter(S=>S.shared??!1).map(S=>S.name.toLowerCase()));Pe.set(p,h)}if(this.host={logEnabled:t.log??!1,tracing:t.log??!1,emitEngine:(p,m,h)=>this.emitEngine(p,m,h),bundle:e,emitIds:c,strings:i,defaultStrings:o,castDisplay:l,qualifierDisplay:d,speakerLabels:g,speakerPattern:f,nodeIndex:I,blockIndex:Q,blockById:De,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:qt(e),padIndex:_t(e),registry:x,ownsRegistry:Ie,patterBag:Re,hostScopes:de,patterSharedDecls:le,patterLocalDecls:St,patterSharedNames:wt,sceneSharedNames:Pe,sharedVisits:new Map,qualityLadders:new Map,sharedSelectors:new Map,stageBags:new Map,journal:null,customRng:t.rng,onDryChoice:t.onDryChoice,onError:t.onError??(p=>console.warn(p.kind==="setup"?`Patterplay: ${p.message}`:p.kind==="save"?`Patterplay: flow \'${p.flow}\': ${p.message}`:`Patterplay: ${p.kind} on ${p.node} in flow \'${p.flow}\' failed, played through: ${p.message}`)),reportRefits:()=>{let p=x.takeMisfits(m=>m==="patter"||m.startsWith("patter/")||de.includes(m));if(p.length!==0)if(t.onRefit)t.onRefit(p);else for(let m of p)console.warn(`Patterplay: the save\'s ${m.scope}.${m.name} was ${JSON.stringify(m.value)}, which no longer fits its declaration; it is back at its default`)},replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??we).open,captionClose:(e.closedCaptions??we).close,captionCharacter:e.closedCaptions?.character||We,refSplitCache:new Map,refSplitRevision:x.revision},this.host.reportRefits(),t[tt]!==!0)for(let p of n)this.reportSetup(p.node,p.message)}reportSetup(e,t){this.host.onError({flow:"",kind:"setup",node:e,message:t}),this.host.tracing&&this.emitEngine("",{type:"diagnostic",kind:"setup",node:e,message:t})}get locale(){return this.currentLocale.locale}get locales(){let{default:e,included:t}=this.host.bundle.locales;return{default:e,included:[...t]}}get isSourceDebug(){return this.sourceDebug}get buildId(){return this.host.bundle.content?.hash??""}setLocale(e){this.requestedLocale=e,this.useLocale(be(this.host.bundle,e)),this.currentLocale.problem&&this.reportSetup(e,this.currentLocale.problem)}useLocale(e){this.currentLocale=e,this.host.strings=ot(this.allStrings,e)}replaceStrings(e){this.allStrings=e.strings;let t=this.currentLocale.problem;this.useLocale(be(e,this.requestedLocale)),this.host.defaultStrings=this.allStrings[this.host.bundle.locales.default]??{};let n=this.currentLocale.problem;n&&n!==t&&this.reportSetup(this.requestedLocale,n)}hotSwap(e){this.refuseInCheckpoint("hotSwap");let t=this.saveGame(),n=l=>(l.setClosedCaptions(this.host.captionsOn),l),s=this.requestedLocale,i=(l=!1)=>new r(e,{...this.creationOptions,...s!==void 0?{locale:s}:{},registry:this.host.registry,[et]:this.host.ownsRegistry,[tt]:l}),o=new Set(["patter",...this.host.hostScopes]),a=this.host.ownsRegistry?void 0:Object.fromEntries(Object.entries(this.host.registry.save()).filter(([l])=>o.has(l)||l.startsWith("patter/")));this.release(!0),a&&this.host.registry.load(a,{keepParked:!0,refit:!0});let c=i();try{return c.loadGame(t),n(c)}catch{c.release(!0);let l=this.host.ownsRegistry?t.registry:a;l&&this.host.registry.load(l,{keepParked:!0,refit:!0});let d=i(!0);for(let[g,f]of Object.entries(t.flows)){let I=f.cursor.currentSceneId;try{d.openFlow(g,I!==null?{scene:I}:{})}catch{}}return n(d)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){this.assertExternalScopes();let{sceneId:n,blockId:s}=this.resolveOpenAddress(t.scene,t.block),i=this.flowsById.get(e),o=this.host.journal;if(o&&i&&!i.isClosed)throw new Error(`openFlow would replace the open flow \'${e}\', which can\'t be undone while a checkpoint is open`);i?.close();let a=new A(e,this.host,t.seed??this.defaultSeed);return o&&(o.flows.add(a),o.opened.add(a),o.undo.push(()=>{a.close(),i?this.flowsById.set(e,i):this.flowsById.delete(e)})),this.flowsById.set(e,a),a.begin(n,s),a}runFlow(e,t,n){let s=this.flowsById.get(e);if(!s)return this.openFlow(e,{scene:t,block:n}).advanceToStop().played;if(!s.goto(t,n))throw new Error(`runFlow: address not found: ${t}${n===void 0?"":` / ${n}`}`);return s.advanceToStop().played}assertExternalScopes(){for(let e of this.host.bundle.externalScopes??[])if(!this.host.registry.has(e))throw new Error(`this content names @${e}, which no engine on this registry registered: give every engine the game\'s one registry`)}resolveOpenAddress(e,t){if(e!==void 0){let n=ve(this.host,e);if(n===void 0)throw new Error(`unknown scene: ${e}`);if(t===void 0)return{sceneId:n};let s=xe(this.host,n,t);if(s===void 0)throw new Error(`unknown block: ${t}`);return{sceneId:n,blockId:s}}if(t!==void 0){if(!this.host.blockIndex.has(t))throw new Error(`unknown block: ${t}`);return{blockId:t}}if(Object.keys(this.host.bundle.scenes).length===0)throw new Error("no scenes in bundle");return{}}resolveSceneRef(e){if(e!=null)return ve(this.host,e)??e}resolveBlockRef(e,t){if(t!=null)return e==null?t:xe(this.host,e,t)}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?y(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?y(t):void 0}tagsForBeat(e){return N(this.host,e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?N(this.host,t):void 0)??[]}tagsForBlock(e,t){let n=this.resolveSceneRef(e),s=this.resolveBlockRef(n,t);return(s!=null?N(this.host,s):void 0)??[]}gameDataForScene(e){let t=this.resolveSceneRef(e),n=t!=null?this.host.bundle.scenes[t]:void 0;return b(n?.gameData)??{}}gameDataForBlock(e,t){let n=this.resolveBlockRef(this.resolveSceneRef(e),t),s=n!=null?this.host.blockById.get(n):void 0;return b(s?.gameData)??{}}extensionsForScene(e){let t=this.resolveSceneRef(e);return{...(t!=null?this.host.bundle.scenes[t]:void 0)?.extensions}}extensionsForBlock(e,t){let n=this.resolveBlockRef(this.resolveSceneRef(e),t);return{...(n!=null?this.host.blockById.get(n):void 0)?.extensions}}extensionsForSnippet(e){let t=this.host.nodeIndex.get(e);return t?.type==="snippet"?{...t.extensions}:{}}getCast(){let e=[];for(let t of this.host.bundle.cast??[])t?.name&&e.push(t.name);return e}castForScene(e){let t=this.resolveSceneRef(e),n=t!=null?this.host.bundle.scenes[t]:void 0;if(!n)return[];let s=new Set;for(let i of n.blocks)nt(i.children,s);return[...s]}castForBlock(e,t){let n=this.resolveSceneRef(e),s=this.resolveBlockRef(n,t),i=s!=null?this.host.blockById.get(s):void 0;if(!i)return[];let o=new Set;return nt(i.children,o),[...o]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...y(e)?{gameId:y(e)}:{},name:e.name,...rt(e.gameData),...C(e.extensions),...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...y(t)?{gameId:y(t)}:{},name:t.name,...rt(t.gameData),...C(t.extensions),...this.tagsField(t.id),children:t.children.map(n=>this.outlineNode(n))}))}))}getBeatSequence(){let e=[];for(let t of Object.values(this.host.bundle.scenes))for(let n of t.blocks)D(n.children,s=>{if(s.type==="snippet")for(let i of s.beats??[])e.push({sceneId:t.id,blockId:n.id,snippetId:s.id,beat:this.beatInfo(i)})});return e}outlineNode(e){return e.type==="group"?{type:"group",id:e.id,...this.tagsField(e.id),...e.selector?{selector:e.selector}:{},...e.prompt?{prompt:this.beatInfo(e.prompt)}:{},children:e.children.map(t=>this.outlineNode(t))}:{type:"snippet",id:e.id,...this.tagsField(e.id),beats:(e.beats??[]).map(t=>this.beatInfo(t)),...e.jump?{jumpTo:e.jump.to,...e.jump.mode?{jumpMode:e.jump.mode}:{}}:{}}}beatInfo(e){let t=N(this.host,e.id),n={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){n.character=e.character;let i=this.host.defaultStrings[se(e.character)]??this.host.castDisplay.get(e.character);i!==void 0&&(n.characterName=i)}if(e.direction!==void 0&&(n.direction=e.direction),e.qualifier!==void 0){n.qualifier=e.qualifier;let i=this.host.defaultStrings[ie(e.qualifier)]??this.host.qualifierDisplay.get(e.qualifier);i!==void 0&&(n.qualifierName=i)}let s=ae(this.host,e.character,e.qualifier,!0);s!==void 0&&(n.speakerLabel=s)}if(e.kind==="line"||e.kind==="text"){let s=this.host.padIndex.get(e.id);n.padAfter=s?.resolved??O,s?.own!==void 0&&(n.ownPadAfter=s.own);let i=this.host.defaultStrings[e.id];i!==void 0&&(n.text=i)}return e.gameData&&Object.keys(e.gameData).length&&(n.gameData=b(e.gameData)),e.extensions&&Object.keys(e.extensions).length&&(n.extensions=e.extensions),t&&t.length&&(n.tags=t),n}tagsField(e){let t=N(this.host,e);return t&&t.length?{tags:t}:{}}getFlow(e){return this.flowsById.get(e)}flows(){return[...this.flowsById.values()]}listBags(){let e=[{bag:this.host.patterBag}];for(let[t,n]of this.host.stageBags)e.push({bag:n,pathPrefix:`@scene:${t}.`});return e}checkpoint(){if(this.host.journal)throw new Error("a checkpoint is already open: roll it back or commit it first");let e={undo:[],flows:new Set,opened:new Set,selectors:new Set,flowSelectors:new Map};return this.host.journal=e,new K(e)}rollback(e){this.endCheckpoint(e);let t=e.journal.undo;for(let n=t.length-1;n>=0;n--)t[n]();r.forget(e.journal)}commit(e){this.endCheckpoint(e),r.forget(e.journal)}get inCheckpoint(){return this.host.journal!==null}endCheckpoint(e){if(this.host.journal!==e.journal)throw new Error("that checkpoint is not the open one");this.host.journal=null}static forget(e){e.undo=[],e.flows.clear(),e.opened.clear(),e.selectors.clear(),e.flowSelectors.clear()}refuseInCheckpoint(e){if(this.host.journal)throw new Error(`${e} can\'t be undone, so it isn\'t allowed while a checkpoint is open`)}captureFlow(e){let t=this.flowsById.get(e);if(!t)throw new Error(`no open flow \'${e}\' to capture`);return{version:V,...t.snapshot(),...Zt(e,this.host.registry.save())}}restoreFlow(e,t){this.refuseInCheckpoint("restoreFlow");let n=t.version;if(n!==3&&n!==V)throw new Error(`unsupported flow state version: ${String(n)}`);let s=t.cursor;if(typeof s!="object"||s===null)throw new Error("malformed flow state: no cursor");if(this.flowsById.has(e))throw new Error(`a flow \'${e}\' is already open; close it before restoring another under that id`);this.assertExternalScopes();let i=w.flow(e);this.host.registry.discardParked(i),this.host.registry.load(Yt(e,t),{keepParked:!0,refit:!0});let o=new A(e,this.host,this.defaultSeed);try{o.restore(t)}catch(a){throw o.close(),this.host.registry.discardParked(i),a}return this.flowsById.set(e,o),this.host.reportRefits(),o}closeFlow(e){this.refuseInCheckpoint("closeFlow"),this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){this.refuseInCheckpoint("reset");for(let e of this.flowsById.values())e.close();this.flowsById.clear(),this.host.patterBag.reseed(this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear();for(let e of this.host.stageBags.keys())this.host.registry.remove(w.stage(e));this.host.stageBags.clear(),this.host.registry.discardParked("patter/")}release(e){for(let n of this.flowsById.values())n.releaseBags(e),n.close();this.flowsById.clear();let t=this.host.registry;for(let n of this.host.stageBags.keys())t.remove(w.stage(n),{keep:e});this.host.stageBags.clear();for(let n of["patter",...this.host.hostScopes])t.has(n)&&t.remove(n,{keep:e});for(let n of Object.keys(this.creationOptions.hostScopes??{}))t.has(n)&&t.remove(n)}getProperty(e){let{scope:t,name:n}=this.splitShared(e);return this.host.registry.get(t,n)}setProperty(e,t){let{scope:n,name:s}=this.splitShared(e);dt(this.host,n,s,t,null);let i=this.host.journal?this.host.registry.get(n,s):void 0;this.host.registry.set(n,s,t,{host:!0}),this.host.journal&&i!==void 0&&this.host.journal.undo.push(()=>this.host.registry.set(n,s,i,{host:!0}))}stageIndex(e,t){return B(this.ladderOf(e),t)}compareStages(e,t,n){return F(this.ladderOf(e),t,n)}nextStage(e,t){return L(this.ladderOf(e),t)}ladderOf(e){let{scope:t,name:n}=this.splitShared(e),s=zt(this.host,t,n);if(!s)throw new Error(`\'${e}\' is not a quality`);return s}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),this.host.tracing=!0,()=>{this.engineTraceHandlers.delete(e),this.host.tracing=this.host.logEnabled||this.engineTraceHandlers.size>0}}emitEngine(e,t,n){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineSeq++,...n?{scene:n}:{}})}getVisitCounts(){return Object.fromEntries(this.host.sharedVisits)}listProperties(){return this.host.patterSharedDecls.map(e=>({name:e.name,path:`@patter.${e.name}`,type:e.type,values:e.values,stages:e.stages,value:this.getProperty(`@${e.name}`),default:T(e),writable:e.writable??!0}))}splitShared(e){let t=ut(this.host,e);if(t.scope==="scene")throw new Error(`\'${e}\': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);return t}saveGame(){let e={};for(let[t,n]of this.flowsById)e[t]=n.snapshot();return{version:V,...this.host.ownsRegistry?{registry:this.host.registry.save()}:{},sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:ct(this.host.sharedSelectors),flows:e}}loadGame(e){this.refuseInCheckpoint("loadGame");let t=e.version;if(t!==3&&t!==V)throw new Error(`unsupported save version: ${String(t)}`);let n=e.flows;if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("malformed save: no flows");this.assertExternalScopes();let s=this.host.registry;for(let[o,a]of this.flowsById)a.releaseBags(o in e.flows),a.close();this.flowsById.clear();for(let o of this.host.stageBags.keys())s.remove(w.stage(o),{keep:!0});this.host.stageBags.clear();let i=e.registry;i&&(this.host.ownsRegistry?s.load(i,{refit:!0}):s.load(i,{keepParked:!0,refit:!0})),this.host.sharedVisits.clear();for(let[o,a]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(o,a);this.host.sharedSelectors.clear();for(let[o,a]of lt(e.sharedSelectors))this.host.sharedSelectors.set(o,a);for(let[o,a]of Object.entries(e.flows)){let c=new A(o,this.host,this.defaultSeed);c.restore(a),this.flowsById.set(o,c)}this.host.reportRefits()}},A=class{id;host;local;registered=new Set;rngState;started=!1;flowEnded=!1;dryChoice=null;ranDry=null;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPrompt=null;pendingPromptOwnerId=null;selectors=new Map;visitCounts=new Map;sceneBags=new Map;patterResolver={get:e=>this.host.patterSharedNames.has(e)?this.host.patterBag.get(e):this.local.get(e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.registry.set("patter",e,t):this.local.set(e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;if(t!==null)return this.sceneBagFor(t,e)?.get(e)},set:(e,t)=>{let n=this.currentSceneId;if(n===null)return;let s=this.sceneBagFor(n,e);s&&s.set(e,t)}};evalCtx;ctxRevision=-1;registryQualities;flowLog=[];flowSeq=0;constructor(e,t,n){this.id=e,this.host=t,this.rngState=j(n),this.local=this.newLocal(),this.evalCtx={scopes:{},host:{nextRandom:this.rng,visits:s=>this.visitCounts.get(s)??0,patterVisits:s=>this.host.sharedVisits.get(s)??0},qualities:(s,i)=>this.stagesFor(s,i)}}context(){let e=this.host.registry;if(e.revision!==this.ctxRevision){let t=e.toEvalContext(),n=this.evalCtx.scopes;for(let s of Object.keys(n))delete n[s];Object.assign(n,t.scopes),n.patter=this.patterResolver,n.scene=this.sceneResolver,this.registryQualities=t.qualities,this.ctxRevision=e.revision}return this.evalCtx}stagesFor(e,t){let n=t.toLowerCase();if(e==="patter")return W(this.host,"patter",()=>[...this.host.patterSharedDecls,...this.host.patterLocalDecls]).get(n);if(e==="scene"){let s=this.currentSceneId;return s==null?void 0:W(this.host,`scene/${s}`,()=>this.host.bundle.scenes[s]?.sceneProps).get(n)}return this.registryQualities?.(e,t)??W(this.host,`host/${e}`,()=>this.host.bundle.scopeRegistry?.scopes.find(s=>s.token===e)?.declarations).get(n)}begin(e,t){let n=this.host.bundle.start;if(e===void 0&&t===void 0&&n&&this.host.bundle.scenes[n.scene]&&(e=n.scene,n.block!==void 0&&this.host.blockIndex.get(n.block)?.sceneId===n.scene&&(t=n.block)),this.host.journal&&!this.host.journal.opened.has(this))throw new Error("a flow can\'t be started or reset while a checkpoint is open");if(this.releaseBags(!1),this.host.registry.discardParked(w.flow(this.id)),this.mountLocal(),this.selectors.clear(),this.visitCounts.clear(),this.stack=[],this.currentSceneId=null,this.flowEnded=!1,this.dryChoice=null,this.ranDry=null,this.activeSnippet=null,this.beatIndex=0,this.clearPending(),this.started=!0,t){let s=this.host.blockIndex.get(t);if(!s)throw new Error(`unknown block: ${t}`);this.enterSceneSetup(s.sceneId),this.stack=[{sceneId:s.sceneId,containerId:t,index:0}],this.enter(t)}else{let s=e??Object.keys(this.host.bundle.scenes)[0],i=s?this.host.bundle.scenes[s]:void 0;if(!i)throw new Error(s?`unknown scene: ${s}`:"no scenes in bundle");this.enterSceneSetup(s);let o=i.blocks[0];o&&(this.stack=[{sceneId:s,containerId:o.id,index:0}],this.enter(o.id))}this.settle()}reset(e,t){this.begin(e,t)}goto(e,t){if(this.closed)return!1;if(this.touch(),e==="END")return this.started=!0,this.clearPending(),this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],this.dryChoice=null,this.ranDry=null,!0;let n=ve(this.host,e);if(n===void 0)return!1;let s;return t!==void 0&&(s=xe(this.host,n,t),s===void 0)?!1:this.started?(this.clearPending(),this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.dryChoice=null,this.ranDry=null,this.enterTarget(s??n,"jump"),this.settle(),!0):(this.begin(n,s),!0)}close(){this.releaseBags(!1),this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.clearPending()}clearPending(){this.pendingChoice=null,this.pendingPrompt=null,this.pendingPromptOwnerId=null}touch(){let e=this.host.journal;if(!e||e.flows.has(this))return;e.flows.add(this);let{rngState:t,started:n,flowEnded:s,dryChoice:i,ranDry:o,currentSceneId:a,activeSnippet:c,beatIndex:l,pendingChoice:d,pendingPrompt:g,pendingPromptOwnerId:f}=this,I=this.stack.map(Q=>({...Q}));e.undo.push(()=>{Object.assign(this,{rngState:t,started:n,flowEnded:s,dryChoice:i,ranDry:o,currentSceneId:a,activeSnippet:c,beatIndex:l,pendingChoice:d,pendingPrompt:g,pendingPromptOwnerId:f,stack:I})})}get isClosed(){return this.closed}get currentScene(){return this.currentSceneId}advance(){if(this.closed)return{type:"end",reason:"ended"};if(!this.started)throw new Error("flow has not been started");if(this.touch(),this.pendingPrompt){let e=this.pendingPrompt;return this.pendingPrompt=null,this.pendingPromptOwnerId=null,e.shown?this.promptResult(e.beat,e.shown):this.beatResult(e.beat)}return this.settle(),!this.flowEnded&&!this.activeSnippet&&!this.pendingChoice&&(this.flowEnded=!0),this.flowEnded?this.endResult():(this.dryChoice=null,this.pendingChoice?{type:"choice",groupId:this.pendingChoice.groupId,options:this.offer(this.pendingChoice)}:this.beatResult(this.activeSnippet.beats[this.beatIndex++]))}endResult(){if(this.dryChoice!==null){let e=this.dryChoice;this.dryChoice=null,this.ranDry=e,this.report({flow:this.id,kind:"dry-choice",node:e,message:`choice \'${e}\' ran dry (no option left to take, and no fallback) with nothing after it, so the flow ended there`})}return{type:"end",reason:this.ranDry!==null?"ran-dry":"ended"}}advanceToStop(){let e=[];for(;;){let t=this.advance();if(t.type==="choice"||t.type==="end")return{played:e,stop:t};e.push(t)}}settle(){let e=0;for(;;){if(++e>1e4)throw new Error("flow did not settle after 10000 transitions - likely a jump cycle with no deliverable content");if(this.flowEnded||this.pendingChoice)return;if(this.activeSnippet){if(this.beatIndex<(this.activeSnippet.beats?.length??0))return;this.runEffects(this.activeSnippet.onExit,this.activeSnippet.id);let i=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(i);continue}let t=this.stack[this.stack.length-1];if(!t){this.flowEnded=!0;return}t.sceneId!==this.currentSceneId&&(this.currentSceneId=t.sceneId);let n=this.childrenOf(t.containerId);if(!n){this.stack.pop();continue}let s=t.index;for(;t.index<n.length&&!this.eligible(n[t.index]);)t.index++;if(this.host.tracing&&t.index!==s&&this.emit({type:"select",group:t.containerId,selector:"run",children:n.slice(s,t.index+1).map((i,o)=>({id:i.id,eligible:s+o===t.index})),picked:n[t.index]?.id??null}),t.index>=n.length){this.stack.pop();continue}this.enterChild(n[t.index++])}}listBags(){let e=[{bag:this.local,pathPrefix:`${this.id}/@patter.`}];for(let[t,n]of this.sceneBags)e.push({bag:n,pathPrefix:`${this.id}/@scene:${t}.`});return e}log(){return this.flowLog}clearLog(){this.flowLog.length=0}emit(e){let t=this.currentSceneId??void 0;this.host.emitEngine(this.id,e,t),this.host.logEnabled&&this.flowLog.push({...e,seq:this.flowSeq++,...t?{scene:t}:{}})}getVisitCounts(){return Object.fromEntries(this.visitCounts)}stepFor(e){let t=Ut(this.host.bundle).get(e);return t?this.beatResult(t):void 0}getChoices(){return this.pendingChoice?this.offer(this.pendingChoice):[]}offer(e){return e.options.map(t=>{let n=e.byId.get(t.id),s=this.promptFor(n);return e.shown.set(t.id,s),{id:t.id,prompt:s,eligible:t.eligible,gameData:b(t.gameData),...C(n.extensions)}})}choose(e){let t=this.pendingChoice;if(!t)throw new Error("no choice is pending");let n=t.options.find(a=>a.id===e);if(!n)throw new Error(`unknown choice option: ${e}`);if(!n.eligible)throw new Error(`choice option is not eligible: ${e}`);this.touch();let s=t.byId.get(e);this.host.tracing&&this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null;let i=this.host.replayPromptOnChoose?this.authoredPromptOf(s):void 0,o=i?t.shown.has(e)?t.shown.get(e):this.promptFor(s):void 0;this.pendingPrompt=i&&o?{beat:i,shown:{...o}}:null,this.pendingPromptOwnerId=this.pendingPrompt?s.id:null,this.enterChild(s)}isEnded(){return this.flowEnded}getProperty(e){let{scope:t,name:n}=this.splitRef(e);return t==="patter"?this.patterResolver.get(n):t==="scene"?this.sceneResolver.get(n):this.host.registry.get(t,n)}setProperty(e,t){this.writeProperty(e,t,!0)}stageIndex(e,t){return B(this.ladderOf(e),t)}compareStages(e,t,n){return F(this.ladderOf(e),t,n)}nextStage(e,t){return L(this.ladderOf(e),t)}ladderOf(e){let{scope:t,name:n}=this.splitRef(e);this.context();let s=this.stagesFor(t,n);if(!s)throw new Error(`\'${e}\' is not a quality`);return s}writeProperty(e,t,n){let{scope:s,name:i}=this.splitRef(e);if(n){if(s==="scene"&&this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);dt(this.host,s,i,t,this.currentSceneId)}let o=this.host.journal;if(s==="patter"){if(o){let a=this.host.patterSharedNames.has(i),c=a?this.host.patterBag.get(i):this.local.get(i),l=this.local;c!==void 0&&o.undo.push(a?()=>this.host.registry.set("patter",i,c):()=>l.set(i,c))}this.patterResolver.set(i,t)}else if(s==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);if(o){let a=this.sceneBagFor(this.currentSceneId,i),c=a?.get(i);a&&c!==void 0&&o.undo.push(()=>a.set(i,c))}this.sceneResolver.set(i,t)}else{let a=o?this.host.registry.get(s,i):void 0;this.host.registry.set(s,i,t,n?{host:!0}:void 0),o&&a!==void 0&&o.undo.push(()=>this.host.registry.set(s,i,a,{host:!0}))}}snapshot(){let e=Ht(this.host.bundle),t=this.activeSnippet?.beats?.[this.beatIndex]?.id;return{rngState:this.rngState,visits:Object.fromEntries(this.visitCounts),cursor:{flowEnded:this.flowEnded,...this.ranDry!==null?{ranDry:this.ranDry}:{},currentSceneId:this.currentSceneId,stack:this.stack.map(n=>{let s=this.childrenOf(n.containerId)?.[n.index],i=e.get(n.containerId);return{...n,...s?{nextId:s.id}:{},...i!==void 0?{choiceId:i}:{}}}),activeSnippetId:this.activeSnippet?.id??null,...t!==void 0?{beatId:t}:{},pendingChoice:this.pendingChoice?{groupId:this.pendingChoice.groupId,options:this.pendingChoice.options.map(n=>({id:n.id,eligible:n.eligible,...n.gameData!==void 0?{gameData:b(n.gameData)}:{}}))}:null,pendingPromptOwnerId:this.pendingPromptOwnerId,...this.pendingPrompt?.shown?{pendingPrompt:Kt(this.pendingPrompt.shown)}:{},selectors:ct(this.selectors)}}}restore(e){if(this.host.journal)throw new Error("a flow can\'t be restored while a checkpoint is open");let t=this.restoreCursor(e);this.releaseBags(!0),this.mountLocal();for(let n of new Set([this.currentSceneId,...this.stack.map(s=>s.sceneId)]))n!==null&&this.host.bundle.scenes[n]&&this.ensureSceneBags(n);t&&(this.report({flow:this.id,kind:"save",node:t.node,message:`the save\'s place has gone from this build: ${t.instead}`}),t.reoffer&&this.setupChoice(t.reoffer))}restoreCursor(e){this.rngState=j(e.rngState),this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;this.started=!0,this.flowEnded=t.flowEnded,this.dryChoice=null,this.ranDry=t.flowEnded&&typeof t.ranDry=="string"?t.ranDry:null,this.currentSceneId=t.currentSceneId;let n=null;this.stack=[];for(let s of t.stack){let{nextId:i,choiceId:o,...a}=s,c=this.childrenOf(a.containerId),l=!c&&o!==void 0?this.host.nodeIndex.get(o):void 0;if(l?.type==="group"&&l.selector==="choice"){n={node:t.activeSnippetId??t.pendingChoice?.groupId??a.containerId,instead:`option ${a.containerId} has gone, so choice ${l.id} is offered again`,reoffer:l};break}let d=i!==void 0?c?.findIndex(g=>g.id===i)??-1:-1;this.stack.push(d>=0?{...a,index:d}:{...a})}if(this.activeSnippet=null,this.beatIndex=0,!n?.reoffer&&t.activeSnippetId!==null){let s=this.host.nodeIndex.get(t.activeSnippetId);if(s&&s.type==="snippet"){let i=s.beats??[];if(this.activeSnippet=s,t.beatId!==void 0){let o=i.findIndex(a=>a.id===t.beatId);this.beatIndex=o>=0?o:i.length,o<0&&(n={node:t.activeSnippetId,instead:`beat ${t.beatId} has gone from snippet ${t.activeSnippetId}, so the snippet ends there`})}else this.beatIndex=t.beatIndex??i.length}else n={node:t.activeSnippetId,instead:`snippet ${t.activeSnippetId} has gone, so play carries on after it`}}if(this.selectors=lt(t.selectors),this.pendingChoice=null,!n?.reoffer&&t.pendingChoice!==null){let s=new Map,i=[];for(let o of t.pendingChoice.options){let a=this.host.nodeIndex.get(o.id);a&&(s.set(o.id,a),i.push({id:o.id,eligible:o.eligible,...o.gameData!==void 0?{gameData:o.gameData}:{}}))}if(i.length>0)this.pendingChoice={groupId:t.pendingChoice.groupId,options:i,byId:s,shown:new Map};else{let o=this.host.nodeIndex.get(t.pendingChoice.groupId);n=o?.type==="group"&&o.selector==="choice"?{node:t.pendingChoice.groupId,instead:`none of choice ${o.id}\'s options is left, so it\'s offered again`,reoffer:o}:{node:t.pendingChoice.groupId,instead:`choice ${t.pendingChoice.groupId} has gone, so play carries on after it`}}}if(this.pendingPrompt=null,this.pendingPromptOwnerId=n?.reoffer?null:t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let s=this.host.nodeIndex.get(this.pendingPromptOwnerId),i=s?this.authoredPromptOf(s):void 0,o=t.pendingPrompt,a=o?.kind==="line"&&o.speakerLabel===void 0?ae(this.host,o.character,o.qualifier):void 0;i?this.pendingPrompt={beat:i,...o?{shown:{...o,padAfter:o.padAfter??this.padOf(i.id),...a!==void 0?{speakerLabel:a}:{}}}:{}}:this.pendingPromptOwnerId=null}return n}enterSceneSetup(e){let t=this.host.bundle.scenes[e];if(!t)throw new Error(`unknown scene: ${e}`);this.currentSceneId=e,this.enter(e),this.seedScene(t),this.runEffects(t.onEntry,t.id)}enterChild(e){if(this.enter(e.id),e.type==="snippet"){this.beginSnippet(e);return}let t=e.selector??"run";if(t==="run"){this.stack.push({sceneId:this.currentSceneId,containerId:e.id,index:0});return}if(t==="choice"){this.setupChoice(e);return}let n=this.selectChild(e);n&&this.enterChild(n)}childrenOf(e){let t=this.host.blockById.get(e);if(t)return t.children;let n=this.host.nodeIndex.get(e);if(n&&n.type==="group")return n.children}beginSnippet(e){this.runEffects(e.onEnter,e.id),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],n=new Map,s=[];for(let o of e.children){if(o.fallback===!0){s.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),c=o.secretUntilEligible===!0;!a&&c||(t.push({id:o.id,eligible:a,...o.gameData!==void 0?{gameData:o.gameData}:{}}),n.set(o.id,o))}if(t.some(o=>o.eligible)){this.host.tracing&&this.emit({type:"choice",group:e.id,options:t.map(o=>({id:o.id,eligible:o.eligible}))}),this.pendingChoice={groupId:e.id,options:t,byId:n,shown:new Map};return}let i=s.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.host.tracing&&this.emit({type:"dry",group:e.id}),this.host.onDryChoice?.(e.id),this.dryChoice=e.id}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(this.host.tracing&&this.emit({type:"jump",to:e,mode:t}),e==="END"){this.flowEnded=!0,this.stack=[];return}let n,s,i=this.host.bundle.scenes[e];if(i){this.enterSceneSetup(e);let a=i.blocks[0];if(!a){t==="jump"&&(this.stack=[]);return}n=e,s=a.id}else{let a=this.host.blockIndex.get(e);if(!a)throw new Error(`jump target not found: ${e}`);a.sceneId!==this.currentSceneId&&this.enterSceneSetup(a.sceneId),n=a.sceneId,s=e}this.enter(s);let o={sceneId:n,containerId:s,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.map(c=>({id:c.id,eligible:this.eligible(c)})),n=e.children.filter((c,l)=>t[l].eligible),s=e.options?.order??"sequential",i=e.options?.exhaust??"once",o=c=>(this.host.tracing&&this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:i}:{},children:t,picked:c?.id??null}),c);if(n.length===0)return o(null);let a=this.selectorState(e);switch(e.selector){case"branch":return o(n[0]);case"sequence":return o(s==="shuffle"?this.pickShuffle(n,i,a):s==="specificity"?this.pickSpecificity(n,i,a):this.pickSequential(n,i,a));default:return null}}pickSequential(e,t,n){let s=e.length,i=n.seq??0;return n.seq=i+1,t==="repeat"?e[i%s]:i<s?e[i]:t==="stick"?e[s-1]:null}pickShuffle(e,t,n){let s=e.length,i=t==="stick",o=()=>(i?e.slice(0,s-1):e).map(f=>f.id),a=new Set(e.map(f=>f.id));if(n.bag===void 0&&(n.bag=o()),!n.bag.some(f=>a.has(f))){if(t==="once")return null;if(i){let f=e[s-1];return n.last=f.id,f}if(n.bag=o(),n.bag.length===0)return null}let c=n.bag.filter(f=>a.has(f)),l=n.last!==void 0&&c.length>1?c.indexOf(n.last):-1,d=Math.floor(this.rng()*(l>=0?c.length-1:c.length));l>=0&&d>=l&&d++;let g=c[d];return n.bag.splice(n.bag.indexOf(g),1),n.last=g,e.find(f=>f.id===g)}pickSpecificity(e,t,n){let s=e;if(t!=="repeat"){n.bag===void 0&&(n.bag=e.map(d=>d.id));let l=new Set(n.bag);if(s=e.filter(d=>l.has(d.id)),s.length===0)return t==="stick"&&n.last!==void 0?e.find(d=>d.id===n.last)??null:null}let i=-1,a=s.map(l=>{let d=this.specScore(l);return d>i&&(i=d),{c:l,s:d}}).filter(l=>l.s===i).map(l=>l.c),c;if(a.length===1)c=a[0];else{let l=n.last!==void 0?a.findIndex(g=>g.id===n.last):-1,d=Math.floor(this.rng()*(l>=0?a.length-1:a.length));l>=0&&d>=l&&d++,c=a[d]}return t!=="repeat"&&(n.bag=n.bag.filter(l=>l!==c.id)),n.last=c.id,c}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0,e):0}matchedSpec(e,t,n){return Ne(e,i=>{try{return at(Y(i,this.context(),ye))}catch(o){return this.reportError("best-match",n.id,n.condition,o),!1}},{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,n=this.host.journal,s;if(n&&(s=e.shared?n.selectors:n.flowSelectors.get(this),s||(s=new Set,n.flowSelectors.set(this,s))),n&&s&&!s.has(e.id)){s.add(e.id);let o=t.get(e.id),a=o?{...o,...o.bag?{bag:[...o.bag]}:{}}:void 0;n.undo.push(()=>{a?t.set(e.id,a):t.delete(e.id)})}let i=t.get(e.id);return i||(i={},t.set(e.id,i)),i}runEffects(e,t){for(let n of e??[]){let s;try{s=this.evalExpr(n.value);let i=this.host.tracing?this.getProperty(n.target):void 0;this.writeProperty(n.target,s,!1),this.host.tracing&&this.emit({type:"write",target:n.target,value:s,...i!==void 0?{prev:i}:{}})}catch(i){this.reportError("effect",t,n.value,i)}}}eligible(e){if(!e.condition)return!0;try{return at(this.evalExpr(e.condition))}catch(t){return this.reportError("condition",e.id,e.condition,t),!1}}reportError(e,t,n,s){let i=s instanceof Error?s.message:String(s),o=n?.src;this.report({flow:this.id,kind:e,node:t,...o?{source:o}:{},message:i})}report(e){this.host.onError(e),this.host.tracing&&this.emit({type:"diagnostic",kind:e.kind,node:e.node,...e.source?{source:e.source}:{},message:e.message})}evalExpr(e){return Y(this.conditionAst(e),this.context(),ye)}conditionAst(e){let t=Qe.get(e);return t||(t=R(e.ast),Qe.set(e,t)),t}enter(e){let t=this.visitCounts,n=t.get(e);t.set(e,(n??0)+1);let s=this.host.sharedVisits,i=s.get(e);s.set(e,(i??0)+1),this.host.journal&&this.host.journal.undo.push(()=>{n===void 0?t.delete(e):t.set(e,n),i===void 0?s.delete(e):s.set(e,i)})}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=ge(this.rngState),t=e.next();return this.rngState=e.state(),t};beatResult(e){let t=N(this.host,e.id),n=t&&t.length?{tags:t}:{};switch(e.kind){case"gameEvent":return{type:"gameEvent",id:e.id,gameData:b(e.gameData),...C(e.extensions),...n};case"text":return{type:"text",id:e.id,text:this.interpolate(this.resolveString(e.id)),padAfter:this.padOf(e.id),...e.action?{action:!0}:{},gameData:b(e.gameData),...C(e.extensions),...n};case"line":{let s=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=i&&a.length===0;return{type:"line",id:e.id,text:a,character:c?void 0:e.character,characterName:c?void 0:this.resolveCharacterName(e.character),direction:c?void 0:e.direction,qualifier:c?void 0:e.qualifier,qualifierName:c?void 0:this.resolveQualifierName(e.qualifier),speakerLabel:c?void 0:ae(this.host,e.character,e.qualifier),padAfter:this.padOf(e.id),gameData:b(e.gameData),...C(e.extensions),...n}}}}interpolate(e){return $e(e,t=>this.getProperty(t))}stripCaptions(e){return je(e,this.host.captionOpen,this.host.captionClose)}captionLine(e){return this.host.captionsOn?e:this.stripCaptions(e)}promptFor(e){let t=this.promptBeatOf(e);if(!t)return;let n=this.interpolate(this.resolveString(t.id)),s=this.padOf(t.id);return t.kind==="line"?{kind:"line",text:this.captionLine(n),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction,qualifier:t.qualifier,qualifierName:this.resolveQualifierName(t.qualifier),speakerLabel:ae(this.host,t.character,t.qualifier),padAfter:s}:{kind:"text",text:n,padAfter:s}}authoredPromptOf(e){return e.type==="group"?e.prompt:void 0}promptResult(e,t){let n=N(this.host,e.id),s=n&&n.length?{tags:n}:{};return t.kind==="text"?{type:"text",id:e.id,text:t.text,padAfter:this.padOf(e.id),gameData:b(e.gameData),...C(e.extensions),...s}:{type:"line",id:e.id,text:t.text,character:t.character,characterName:t.characterName,direction:t.direction,qualifier:t.qualifier,qualifierName:t.qualifierName,speakerLabel:t.speakerLabel,padAfter:this.padOf(e.id),gameData:b(e.gameData),...C(e.extensions),...s}}promptBeatOf(e){return e.type==="group"&&e.prompt?e.prompt:((e.type==="snippet"?e:this.firstTextSnippetIn(e.children))?.beats??[]).find(n=>n.kind==="line"||n.kind==="text")}firstTextSnippetIn(e){let t;return D(e,n=>{!t&&n.type==="snippet"&&(n.beats??[]).some(s=>s.kind==="line"||s.kind==="text")&&(t=n)}),t}resolveString(e){if(this.host.emitIds)return e;let t=this.host.strings[e];if(t!==void 0)return t;let n=this.host.defaultStrings[e];return n!==void 0?`<Untranslated: ${e}> ${n}`:e}resolveCharacterName(e){if(e===void 0||this.host.emitIds)return;let t=se(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}padOf(e){return this.host.padIndex.get(e)?.resolved??O}resolveQualifierName(e){if(e===void 0||this.host.emitIds)return;let t=ie(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.qualifierDisplay.get(e)}splitRef(e){return ut(this.host,e)}newLocal(){return new E(this.host.patterLocalDecls,{pathPrefix:"@patter."})}mountLocal(){this.local=this.newLocal();let e=w.flowGlobals(this.id);this.host.registry.mountOwned(e,this.local,{owner:U}),this.registered.add(e),this.host.reportRefits()}releaseBags(e){for(let t of this.registered)this.host.registry.remove(t,{keep:e});this.registered.clear(),this.sceneBags.clear()}sceneBagFor(e,t){if(this.host.bundle.scenes[e])return this.ensureSceneBags(e),this.host.sceneSharedNames.get(e)?.has(t.toLowerCase())?this.host.stageBags.get(e):this.sceneBags.get(e)}ensureSceneBags(e){let t=this.host.sceneSharedNames.get(e)??new Set,n=this.host.bundle.scenes[e]?.sceneProps??[],s=this.host.journal,i=!this.sceneBags.has(e)||!this.host.stageBags.has(e);if(!this.sceneBags.has(e)){let o=new E(n.filter(l=>!t.has(l.name.toLowerCase())),{pathPrefix:"@scene."}),a=w.flowScene(this.id,e),c=st(this.host.registry,a,o,s!==null);this.registered.add(a),this.sceneBags.set(e,o),s&&s.undo.push(()=>{this.sceneBags.get(e)===o&&(this.host.registry.remove(a,c?{keep:!0}:void 0),this.registered.delete(a),this.sceneBags.delete(e))})}if(!this.host.stageBags.has(e)){let o=new E(n.filter(c=>t.has(c.name.toLowerCase())),{pathPrefix:"@scene."}),a=st(this.host.registry,w.stage(e),o,s!==null);this.host.stageBags.set(e,o),s&&s.undo.push(()=>{this.host.stageBags.get(e)===o&&(this.host.registry.remove(w.stage(e),a?{keep:!0}:void 0),this.host.stageBags.delete(e))})}i&&this.host.reportRefits()}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set;this.ensureSceneBags(e.id);for(let n of e.sceneProps??[]){if(!n.temporary)continue;let s=n.name.toLowerCase(),i=t.has(s)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);if(!i)continue;let o=this.host.journal?i.get(s):void 0;o!==void 0&&this.host.journal.undo.push(()=>i.set(s,o)),i.set(s,T(n))}}};function nt(r,e){D(r,t=>{if(t.type==="group"){t.prompt?.kind==="line"&&t.prompt.character&&e.add(t.prompt.character);return}for(let n of t.beats??[])n.kind==="line"&&n.character&&e.add(n.character)})}function ae(r,e,t,n=!1){if(!e||r.emitIds)return;let s=c=>(n?void 0:r.strings[c])??r.defaultStrings[c],i=s(se(e))??r.castDisplay.get(e)??e;if(t===void 0)return i;let o=r.speakerLabels.get(`${e}\\0${t}`);if(o!==void 0)return s(qe(e,t))??o;let a=s(ie(t))??r.qualifierDisplay.get(t)??t;return Ue(s(_e)??r.speakerPattern,i,a)}function rt(r){return r&&Object.keys(r).length?{gameData:b(r)}:{}}function C(r){return r&&Object.keys(r).length?{extensions:r}:{}}function Kt(r){let e={kind:r.kind,text:r.text};return r.character!==void 0&&(e.character=r.character),r.characterName!==void 0&&(e.characterName=r.characterName),r.direction!==void 0&&(e.direction=r.direction),r.qualifier!==void 0&&(e.qualifier=r.qualifier),r.qualifierName!==void 0&&(e.qualifierName=r.qualifierName),r.speakerLabel!==void 0&&(e.speakerLabel=r.speakerLabel),typeof r.padAfter=="number"&&(e.padAfter=r.padAfter),e}function ct(r){let e={};for(let[t,n]of r){let s={};n.seq!==void 0&&(s.seq=n.seq),n.bag&&(s.bag=[...n.bag]),n.last!==void 0&&(s.last=n.last),e[t]=s}return e}function lt(r){let e=new Map;for(let[t,n]of Object.entries(r??{})){let s={};n.seq!==void 0&&(s.seq=n.seq),n.bag&&(s.bag=[...n.bag]),n.last!==void 0&&(s.last=n.last),e.set(t,s)}return e}function st(r,e,t,n){let s=n?JSON.stringify(t.save()):"";return r.mountOwned(e,t,{owner:U}),n&&JSON.stringify(t.save())!==s}function it(r){return{name:r.name,type:r.type,values:r.values,stages:r.stages,default:r.default}}var Jt=new Set(["rng","seed","locale","hostScopes","registry","replayPromptOnChoose","closedCaptions","onDryChoice","onError","onRefit","log"]);function be(r,e){let t=r.locales.default;if(e===void 0)return{locale:t,table:t};if(r.localisation?.mode==="ids")return{locale:e,table:e};let n=[...new Set([t,...r.locales.included,...Object.keys(r.strings)])];if(n.includes(e))return{locale:e,table:e};let s=c=>c.toLowerCase().replace(/_/g,"-"),i=n.find(c=>s(c)===s(e));if(i!==void 0)return{locale:i,table:i,problem:`the locale "${e}" is spelled "${i}" in this bundle, so it\'s using "${i}"`};let o=s(e).split("-")[0],a=n.find(c=>s(c)===o);return a!==void 0?{locale:a,table:a,problem:`this bundle has no locale "${e}", so it\'s using its language, "${a}"`}:{locale:t,problem:`this bundle has no locale "${e}", so it\'s using the default, "${t}", with every string marked untranslated`}}function ot(r,e){return e.table!==void 0?r[e.table]??{}:{}}function dt(r,e,t,n,s){let i=c=>c?.find(l=>l.name.toLowerCase()===t),o;if(e==="patter")o=i(r.bundle.properties);else if(e==="scene")o=i(s!==null?r.bundle.scenes[s]?.sceneProps:void 0);else{let c=r.bundle.scopeRegistry?.scopes.find(l=>l.token===e);if(!c||c.declarations===void 0)return;o=i(c.declarations)}let a=`@${e}.${t}`;if(o===void 0)throw new Error(`no property at "${a}": the content declares no ${a}`);if(!$(o,n,{noneChosen:o.type==="enum"&&o.default===""}))throw new Error(`"${a}" takes ${Qt(o)}; ${JSON.stringify(n)} doesn\'t fit`)}function Qt(r){let e=t=>(t??[]).map(n=>JSON.stringify(n)).join(", ");switch(r.type){case"number":return"a number";case"boolean":return"true or false";case"enum":return`one of ${e(r.values)}`;case"flags":return r.values!==void 0&&r.values.length>0?`a list of flags from ${e(r.values)}`:"a list of flags";case"quality":return`one of its stages ${e(r.stages)}`;default:return"text"}}function W(r,e,t){let n=r.qualityLadders.get(e);if(!n){n=new Map;for(let s of t()??[]){let i=s.name.toLowerCase();s.type==="quality"&&s.stages&&!n.has(i)&&n.set(i,s.stages)}r.qualityLadders.set(e,n)}return n}function zt(r,e,t){let n=t.toLowerCase();return e==="patter"?W(r,"patter",()=>[...r.patterSharedDecls,...r.patterLocalDecls]).get(n):r.registry.toEvalContext().qualities?.(e,t)??W(r,`host/${e}`,()=>r.bundle.scopeRegistry?.scopes.find(s=>s.token===e)?.declarations).get(n)}function pt(r){return{name:r.name,type:r.type,values:r.values,stages:r.stages,default:r.default,writable:r.writable}}function Xt(r,e){let t=pt(r),n=r.writable??e;return n===void 0?t:{...t,writable:n}}function ve(r,e){return re(r.bundle.scenes,e,r.sceneGameIdToId)}function xe(r,e,t){return r.blockGameIdToId.get(e)?.get(t)??(r.blockIndex.get(t)?.sceneId===e?t:void 0)}function ut(r,e){r.refSplitRevision!==r.registry.revision&&(r.refSplitCache.clear(),r.refSplitRevision=r.registry.revision);let t=r.refSplitCache.get(e);return t||(t=Me(e,n=>n==="scene"||r.registry.has(n)||(r.bundle.externalScopes?.includes(n)??!1)),r.refSplitCache.set(e,t)),t}function Yt(r,e){let t={};e.scopes?.patter&&(t[w.flowGlobals(r)]=e.scopes.patter);for(let[n,s]of Object.entries(e.sceneBags??{}))t[w.flowScene(r,n)]=s;return t}function Zt(r,e){let t={scopes:{},sceneBags:{}},n=w.flow(r);for(let[s,i]of Object.entries(e)){if(!s.startsWith(n))continue;let o=s.slice(n.length);o==="patter"?t.scopes.patter=i:o.startsWith("scene/")&&(t.sceneBags[Wt(o.slice(6))]=i)}return t}function at(r){return typeof r=="boolean"?r:typeof r=="number"?r!==0:typeof r=="string"?r!=="":r.length>0}var en=(r,e)=>r.shared??e;function ke(r,e){return{name:r.name,type:r.type,hasDefault:r.default!==void 0,...r.default!==void 0?{default:r.default}:{},shared:en(r,e)}}function tn(r){return{name:r.name,type:r.type,hasDefault:r.default!==void 0,...r.values?{values:[...r.values]}:{},...r.purpose?{purpose:r.purpose}:{}}}function nn(r,e){e.blocks++;let t=[...r.children];for(;t.length;){let n=t.pop();if(n.type==="group"){e.groups++,n.prompt&&e.prompts++,t.push(...n.children);continue}e.snippets++;for(let s of n.beats??[])e.beats++,s.kind==="gameEvent"&&e.gameEvents++}}function gt(r){let e={scenes:0,blocks:0,groups:0,snippets:0,beats:0,prompts:0,gameEvents:0,cast:r.cast?.length??0},t=[],n=[];for(let o of Object.values(r.scenes)){e.scenes++;let a=y(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(c=>({gameId:y(c),name:c.name}))});for(let c of o.blocks)nn(c,e);o.sceneProps?.length&&n.push({gameId:a,properties:o.sceneProps.map(c=>ke(c,!1))})}let s=(r.scopeRegistry?.scopes??[]).map(o=>({token:o.token,writable:o.writable??!0,opaque:o.declarations===void 0,properties:(o.declarations??[]).map(a=>ke(a,!0))})),i=Object.entries(r.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(tn)}));return{identity:{schema:r.schema,project:r.content.project,...r.content.version!==void 0?{version:r.content.version}:{},...r.content.hash!==void 0?{hash:r.content.hash}:{},...r.content.structureHash!==void 0?{structureHash:r.content.structureHash}:{},voiced:r.voiced,defaultLocale:r.locales.default,locales:[...r.locales.included],localisation:r.localisation?.mode??"embedded",sourceDebug:r.localisation?.sourceDebug??!1},addresses:t,hostScopes:s,properties:{patter:(r.properties??[]).map(o=>ke(o,!0)),scene:n},gameData:i,counts:e}}var J=(r,e)=>Object.prototype.hasOwnProperty.call(r,e);function ft(r,e){return r.gameDataFields?.[e]??[]}function Ee(r,e,t){return e&&J(e,t)?e[t]:r.find(n=>n.name===t)?.default}function ht(r,e){let t={};for(let n of r){let s=Ee(r,e,n.name);s!==void 0&&(t[n.name]=s)}for(let[n,s]of Object.entries(e??{}))J(t,n)||(t[n]=s);return t}function mt(r,e,t){let n=r.extensions!==void 0&&J(r.extensions,e)?r.extensions[e]:void 0;return n!==void 0&&J(n.fields,t)?n.fields[t]??[]:[]}function yt(r,e,t=""){let n=o=>({...o?.extensions??{}}),s=Object.values(r.scenes??{}),i=o=>(J(r.scenes??{},o)?r.scenes[o]:void 0)??s.find(a=>y(a)===o);switch(e){case"project":{let o={};for(let[a,c]of Object.entries(r.extensions??{}))c.project!==void 0&&(o[a]=c.project);return o}case"scene":return n(i(t));case"block":{let o=t.indexOf("/");if(o<0)return{};let a=i(t.slice(0,o))?.blocks??[],c=t.slice(o+1);return n(a.find(l=>l.id===c)??a.find(l=>y(l)===c))}case"snippet":case"option":case"line":case"text":case"gameEvent":{let o,a=(c,l)=>{for(let d of c??[]){if(o!==void 0)return;if(d.type==="group"){if(l&&d.id===t&&e==="option"){o=d;return}if(l&&d.prompt?.id===t&&d.prompt.kind===e){o=d.prompt;return}a(d.children??[],d.selector==="choice");continue}if(d.id===t&&e==="snippet"){o=d;return}let g=(d.beats??[]).find(f=>f.id===t);if(g!==void 0){g.kind===e&&(o=g);return}}};for(let c of s)for(let l of c.blocks??[])o===void 0&&a(l.children??[],!1);return n(o)}default:return{}}}return It(rn);})();\n';
2707
+ var PLAYABLE_RUNTIME_JS = 'var Patterplay=(()=>{var we=Object.defineProperty;var _t=Object.getOwnPropertyDescriptor;var Gt=Object.getOwnPropertyNames;var jt=Object.prototype.hasOwnProperty;var $t=(r,e)=>{for(var t in e)we(r,t,{get:e[t],enumerable:!0})},Vt=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Gt(e))!jt.call(r,s)&&s!==t&&we(r,s,{get:()=>e[s],enumerable:!(n=_t(e,s))||n.enumerable});return r};var qt=r=>Vt(we({},"__esModule",{value:!0}),r);var In={};$t(In,{Checkpoint:()=>ie,DEFAULT_ESTIMATE_SYLLABLES_PER_SECOND:()=>X,DEFAULT_PAD_AFTER:()=>G,Engine:()=>Ee,Flow:()=>$,buildTagIndex:()=>Se,compareStages:()=>q,countSyllables:()=>Be,describeBundle:()=>Rt,effectiveGameData:()=>Nt,estimateLineDuration:()=>it,extensionDecls:()=>Pt,extensionsOf:()=>Lt,gameDataFields:()=>Ot,gameDataValue:()=>Me,nextStage:()=>H,resolveSceneRef:()=>he,sceneAddressIndex:()=>Re,speechUnits:()=>K,stageIndex:()=>V});function W(r,e){return r!==void 0&&Object.prototype.hasOwnProperty.call(r,e)?r[e]:void 0}function M(r){switch(r[0]){case"b":return{kind:"bool",value:r[1]};case"n":return{kind:"number",value:r[1]};case"s":return{kind:"string",value:r[1]};case"sv":return{kind:"scopedvar",scope:r[1],name:r[2]};case"u":return{kind:"unary",op:r[1],operand:M(r[2])};case"bin":return{kind:"binary",op:r[1],left:M(r[2]),right:M(r[3])};case"call":{let e=r.slice(2).map(M);return{kind:"call",name:r[1],args:e}}case"fd":return{kind:"flagdelta",sign:r[1],name:r[2]}}}var E=class extends Error{constructor(e){super(e),this.name="EvalError"}};function le(r,e,t){let n=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),s=i=>{switch(i.kind){case"bool":return i.value;case"number":return i.value;case"string":return i.value;case"scopedvar":{let o=W(e.scopes,i.scope);if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):W(o,i.name);if(a===void 0){if(n.get(i.scope)==="throw")throw new E(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{if(i.name==="advance"&&!W(t.functions,i.name)){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new E(`advance() takes exactly 1 argument, got ${i.args.length}`);let c=ve(a,e);if(c===void 0)throw new E("advance() needs a quality reference (@scope.name of a quality property)");let l=O(s(a),c,"advance");return c[Math.min(l+1,c.length-1)]}let o=W(t.functions,i.name);if(!o)throw new E(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:s,ctx:e})}case"flagdelta":throw new E("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=s(i.operand);if(typeof a!="boolean")throw new E(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=s(i.operand);if(typeof o!="number")throw new E(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let m=s(i.left);if(typeof m!="boolean")throw new E(`\'and\' requires boolean operands, left is ${typeof m}`);if(!m)return!1;let S=s(i.right);if(typeof S!="boolean")throw new E(`\'and\' requires boolean operands, right is ${typeof S}`);return S}if(i.op==="or"){let m=s(i.left);if(typeof m!="boolean")throw new E(`\'or\' requires boolean operands, left is ${typeof m}`);if(m)return!0;let S=s(i.right);if(typeof S!="boolean")throw new E(`\'or\' requires boolean operands, right is ${typeof S}`);return S}let o=s(i.left),a=s(i.right),c=ve(i.left,e),l=ve(i.right,e),p=c??l;if(p!==void 0){if(c&&l&&!Ht(c,l)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new E(`\'${i.op}\' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return O(o,p,">")>O(a,p,">");case">=":return O(o,p,">=")>=O(a,p,">=");case"<":return O(o,p,"<")<O(a,p,"<");case"<=":return O(o,p,"<=")<=O(a,p,"<=");case"+":case"-":case"*":case"/":throw new E(`\'${i.op}\' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(i.op){case"==":return je(o,a);case"!=":return!je(o,a);case">":return _(o,a,">"),o>a;case">=":return _(o,a,">="),o>=a;case"<":return _(o,a,"<"),o<a;case"<=":return _(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new E(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return _(o,a,"-"),o-a;case"*":return _(o,a,"*"),o*a;case"/":if(_(o,a,"/"),a===0)throw new E("division by zero");return o/a}}}};return s(r)}function je(r,e){if(Array.isArray(r)||Array.isArray(e)){if(!Array.isArray(r)||!Array.isArray(e)||r.length!==e.length)return!1;let t=[...r].sort(),n=[...e].sort();for(let s=0;s<t.length;s++)if(t[s]!==n[s])return!1;return!0}return r===e}function _(r,e,t){if(typeof r!="number"||typeof e!="number")throw new E(`\'${t}\' requires numeric operands, got ${typeof r} and ${typeof e}`)}function ve(r,e){if(!(r.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(r.scope,r.name)}function O(r,e,t){if(typeof r!="string")throw new E(`\'${t}\' on a quality compares stages, got ${typeof r}`);let n=e.indexOf(r);if(n<0)throw new E(`"${r}" is not a stage of this quality (stages: ${e.join(", ")})`);return n}var Ht=(r,e)=>r.length===e.length&&r.every((t,n)=>t===e[n]);function J(r){if(Number.isNaN(r)||!Number.isFinite(r))return 0;let e=Math.trunc(r)%4294967296;return e<0?e+4294967296:e}function Fe(r){let e=J(r);return{next(){e=e+1831565813>>>0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296},state(){return e}}}var Ae=r=>Array.isArray(r)?r:r.stages??[],Ut=r=>Array.isArray(r)?"flags":r==null?"nothing":typeof r;function V(r,e){return typeof e=="string"?Ae(r).indexOf(e):-1}function ke(r,e){if(typeof e!="string")throw new E(`a stage is a name, got ${Ut(e)}`);let t=r.indexOf(e);if(t<0)throw new E(`"${e}" is not a stage of this quality (stages: ${r.join(", ")})`);return t}function q(r,e,t){let n=Ae(r),s=ke(n,e)-ke(n,t);return s<0?-1:s>0?1:0}function H(r,e){let t=Ae(r);return t[Math.min(ke(t,e)+1,t.length-1)]}function Q(r,e,t){switch(r.type){case"boolean":return typeof e=="boolean";case"number":return typeof e=="number";case"string":case"text":case"multiline":return typeof e=="string";case"enum":return typeof e!="string"?!1:e===""&&t?.noneChosen?!0:!Array.isArray(r.values)||r.values.includes(e);case"flags":return Array.isArray(e)&&e.every(n=>typeof n=="string"&&(!Array.isArray(r.values)||r.values.includes(n)));case"quality":return typeof e=="string"&&(!Array.isArray(r.stages)||r.stages.includes(e));default:return!0}}var Kt={name:"check_flags",count:r=>Math.max(1,r.args.length-1)},Wt=[Kt];function $e(r,e,t){let n=t?.countingCalls??Wt;return de(r,t?.want??!0,e,n)}function de(r,e,t,n){if(r.kind==="binary"&&(r.op==="and"||r.op==="or")){let s=de(r.left,e,t,n),i=de(r.right,e,t,n);return r.op==="and"===e?s>0&&i>0?s+i:0:Math.max(s,i)}if(r.kind==="unary"&&r.op==="not")return de(r.operand,!e,t,n);if(r.kind==="call"){let s=n.find(i=>i.name===r.name);if(s){let i=s.count(r),o=t(r);return e?o?i:0:o?0:1}}return t(r)===e?1:0}var P=class r{values=Object.create(null);decls=new Map;subscribers=new Set;auditors=new Set;norm;pathPrefix;constructor(e=[],t){this.norm=t?.normalise??(n=>n.toLowerCase()),this.pathPrefix=t?.pathPrefix??"",this.seed(e)}seed(e){for(let t of e){let n=this.norm(t.name);this.decls.set(n,t),this.values[n]=structuredClone(t.default??U(t))}}get(e){return this.values[this.norm(e)]}normalise(e){return this.norm(e)}writable(e){return this.decls.get(this.norm(e))?.writable!==!1}set(e,t,n){let s=this.norm(e);if(!n?.host&&!this.writable(s))throw new Error(`\'${e}\' is read-only`);let i={name:s,prev:this.values[s],next:t,silent:n?.silent??!1,reason:n?.reason};this.values[s]=t;for(let o of[...this.auditors])o(i);if(!i.silent)for(let o of[...this.subscribers])o(i);return i}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}onAudit(e){return this.auditors.add(e),()=>this.auditors.delete(e)}rows(){return[...this.decls.entries()].map(([e,t])=>qe(t,this.get(e),void 0,e,this.pathPrefix))}declarations(){return[...this.decls.values()]}clone(){let e=new r([],{normalise:this.norm,pathPrefix:this.pathPrefix});return e.decls=new Map(this.decls),Object.assign(e.values,structuredClone(this.values)),e}reseed(e){for(let t of Object.keys(this.values))delete this.values[t];this.decls.clear(),this.seed(e)}save(){return structuredClone(this.values)}load(e,t){let n=new Map;for(let[i,o]of Object.entries(e)){let a=this.norm(i);this.values[a]=structuredClone(o),n.set(a,o)}let s=[];if(!t?.refit)return s;for(let[i,o]of this.decls){if(!n.has(i))continue;let a=n.get(i);Q(o,a,{noneChosen:o.type==="enum"&&o.default===""})||(this.values[i]=structuredClone(U(o)),s.push({name:i,value:a}))}return s}};function qe(r,e,t,n,s=""){let i=n??r.name.toLowerCase();return{name:i,path:s+i,type:r.type,value:e,default:r.default??U(r),...r.values!==void 0?{values:r.values}:{},...r.stages!==void 0?{stages:r.stages}:{},writable:t??r.writable??!0}}var Jt=r=>r.toLowerCase(),De=1,pe=class{scopes=new Map;parked=new Map;parkedRefit=new Set;misfits=[];rev=0;get revision(){return this.rev}defineOwned(e,t,n){let s=typeof n=="string"?{pathPrefix:n}:n??{},i=new P(t,{pathPrefix:s.pathPrefix??`${e}.`,...s.normalise?{normalise:s.normalise}:{}});return this.mountOwned(e,i,s.owner!==void 0?{owner:s.owner}:void 0)}mountOwned(e,t,n){this.assertFree(e,n?.owner),this.scopes.set(e,{kind:"owned",bag:t,...n?.owner!==void 0?{owner:n.owner}:{}}),this.rev++;let s=this.parked.get(e);return s&&(this.note(e,t.load(s,{refit:this.parkedRefit.has(e)})),this.parked.delete(e),this.parkedRefit.delete(e)),this}remove(e,t){let n=this.scopes.get(e);if(!n)throw new Error(`unknown scope \'@${e}\'`);return t?.keep&&n.kind==="owned"&&(this.parked.set(e,n.bag.save()),this.parkedRefit.delete(e)),this.scopes.delete(e),this.rev++,this}discardParked(e){if(e===void 0)this.parked.clear(),this.parkedRefit.clear();else for(let t of[...this.parked.keys()])t.startsWith(e)&&(this.parked.delete(t),this.parkedRefit.delete(t));return this}takeMisfits(e){if(!e){let n=this.misfits;return this.misfits=[],n}let t=this.misfits.filter(n=>e(n.scope));return this.misfits=this.misfits.filter(n=>!e(n.scope)),t}note(e,t){for(let n of t)this.misfits.push({scope:e,name:n.name,value:n.value})}ownedBag(e){let t=this.scopes.get(e);if(!t||t.kind!=="owned")throw new Error(`\'@${e}\' is not an owned scope`);return t.bag}reseedOwned(e,t){return this.ownedBag(e).reseed(t),this}defineForeign(e,t,n=[],s=!0){let i=typeof s=="boolean"?{writable:s}:s;this.assertFree(e,i.owner);let o=i.normalise??Jt,a=new Map;for(let c of n)a.set(o(c.name),c);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:a,scopeWritable:i.writable??!0,norm:o,...i.owner!==void 0?{owner:i.owner}:{}}),this.rev++,this}has(e){return this.scopes.has(e)}get(e,t){let n=this.scopes.get(e);if(n)return n.kind==="owned"?n.bag.get(t):n.resolver.get(n.norm(t))}set(e,t,n,s){let i=this.scopes.get(e);if(!i)throw new Error(`unknown scope \'@${e}\'`);if(i.kind==="owned"){if(!s?.host&&!i.bag.writable(t))throw new Error(`\'@${e}.${t}\' is read-only`);i.bag.set(t,n,s?.host?{host:!0}:void 0);return}let o=i.norm(t);if(!i.resolver.set)throw new Error(`\'@${e}.${t}\' is read-only`);if(!s?.host&&!this.foreignWritable(i,o))throw new Error(`\'@${e}.${t}\' is read-only`);i.resolver.set(o,n)}foreignWritable(e,t){return e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}listProperties(){let e=[];for(let[t,n]of this.scopes){let s=n.owner!==void 0?{owner:n.owner}:{};if(n.kind==="owned")for(let i of n.bag.rows())e.push({scope:t,...s,...i});else for(let[i,o]of n.decls)e.push({scope:t,...s,...qe(o,n.resolver.get(i),this.foreignWritable(n,i),i,`${t}.`)})}return e}toEvalContext(e,t){let n=this.view(t?.aliases),s={};for(let[o,a]of n)s[o]=a.kind==="owned"?a.bag.values:a.resolver;let i=this.qualityLadders(n);return i.size===0?{scopes:s,host:e}:{scopes:s,host:e,qualities:(o,a)=>{let c=n.get(o);return c?i.get(o)?.get(Qt(c)(a)):void 0}}}view(e){let t=new Map(this.scopes);for(let[n,s]of Object.entries(e??{})){let i=this.scopes.get(s);if(!i)throw new Error(`alias \'@${n}\' names \'${s}\', which is not registered`);t.set(n,i)}return t}qualityLadders(e){let t=new Map;for(let[n,s]of e)for(let[i,o]of Ve(s)){if(o.type!=="quality"||o.stages===void 0)continue;let a=t.get(n);a||(a=new Map,t.set(n,a)),a.set(i,o.stages)}return t}toSchema(e){let t=new Map;for(let[n,s]of this.view(e?.aliases)){let i=Ve(s);if(i.length===0)continue;let o=new Map;for(let[a,c]of i)o.set(a,{type:c.type,enumValues:c.values,...c.stages!==void 0?{stages:c.stages}:{}});t.set(n,o)}return{properties:t}}save(){let e={};for(let[t,n]of this.scopes)n.kind==="owned"&&(e[t]=n.bag.save());for(let[t,n]of this.parked)e[t]=structuredClone(n);return e}load(e,t){t?.keepParked||(this.parked.clear(),this.parkedRefit.clear());let n=t?.refit===!0;for(let[s,i]of Object.entries(e)){let o=this.scopes.get(s);o?.kind==="owned"?this.note(s,o.bag.load(i,{refit:n})):o||(this.parked.set(s,structuredClone(i)),n?this.parkedRefit.add(s):this.parkedRefit.delete(s))}}saveFragment(){return{version:De,scopes:this.save()}}loadFragment(e){if(e.version!==De)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${De})`);this.load(e.scopes)}assertFree(e,t){let n=this.scopes.get(e);if(!n)return;let s=n.owner!==void 0?` by ${n.owner}`:"",i=t!==void 0?` (wanted by ${t})`:"";throw new Error(`scope \'@${e}\' is already registered${s}${i}`)}};function Ve(r){return r.kind==="foreign"?[...r.decls.entries()]:r.bag.declarations().map(e=>[r.bag.normalise(e.name),e])}function Qt(r){return r.kind==="foreign"?r.norm:e=>r.bag.normalise(e)}function U(r){if(r.default!==void 0)return r.default;switch(r.type){case"boolean":return!1;case"number":return 0;case"string":case"text":case"multiline":return"";case"enum":return r.values?.[0]??"";case"flags":return[];case"quality":return r.stages?.[0]??"";default:return!1}}var He=[{token:"patter",engine:"Patterplay",means:"Patter\'s shared globals"},{token:"story",engine:"Storylet Engine",means:"the Storylet Engine\'s shared @story properties"}];function Y(r){return r.ctx.host??{}}var Ce={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(r,e){if(r.length!==2)throw new E("random(a, b) requires exactly 2 arguments");let t=Y(e).nextRandom;if(!t)throw new E("random() called without a PRNG in context");let n=e.evaluate(r[0]),s=e.evaluate(r[1]);if(typeof n!="number"||typeof s!="number")throw new E("random(a, b) arguments must be numbers");if(!Number.isInteger(n)||!Number.isInteger(s))throw new E("random(a, b) arguments must be integers");let i=Math.min(n,s),o=Math.max(n,s);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:Ke("check_flags"),eval(r,e){let t=Ue(r[0],e,"check_flags");for(let n=1;n<r.length;n++){let s=r[n];if(s.kind!=="flagdelta")throw new E("check_flags() flag args must be +flagName or -flagName");if(s.sign==="+"?!t.includes(s.name):t.includes(s.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:Ke("set_flags"),eval(r,e){let t=[...Ue(r[0],e,"set_flags")];for(let n=1;n<r.length;n++){let s=r[n];if(s.kind!=="flagdelta")throw new E("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let i=t.indexOf(s.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:ge("visits"),eval:(r,e)=>Y(e).visits?.(ue(r,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:ge("seen"),eval:(r,e)=>(Y(e).visits?.(ue(r,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:ge("patter_visits"),eval:(r,e)=>Y(e).patterVisits?.(ue(r,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:ge("patter_seen"),eval:(r,e)=>(Y(e).patterVisits?.(ue(r,e,"patter_seen"))??0)>0}}},rr=He.map(r=>r.token).filter(r=>r!=="patter"&&r!=="scene");function We(r,e){let t=r.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function ue(r,e,t){let n=e.evaluate(r[0]);if(typeof n!="string")throw new E(`${t}(id) requires a string node id`);return n}function ge(r){return(e,t)=>{let n=e[0];n&&n.kind!=="string"&&t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${r}(id): the argument must be a string id literal (a scene / block / node id)`})}}function Ue(r,e,t){if(!r)throw new E(`${t}() requires at least one argument (the flags variable)`);let n=e.evaluate(r);if(Array.isArray(n))return n;if(n===!1||n===null||n===void 0)return[];throw new E(`${t}() first argument must be a flags property`)}function Ke(r){return(e,t)=>{if(e.length===0)return;let n=e[0];if(n.kind!=="scopedvar"){t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${r}(): first argument must be a flags property reference (@name or @scope.name)`});return}let s=t.schema.properties.get(n.scope)?.get(n.name);if(s&&s.type!=="flags"){let i=n.scope===t.defaultScope?n.name:`${n.scope}.${n.name}`;t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${r}(): \'@${i}\' is not a flags property (got ${s.type})`});return}for(let i=1;i<e.length;i++){let o=e[i];o.kind!=="flagdelta"?t.report({path:[...t.path,"args",i],kind:"wrong-arg-type",severity:"error",message:`${r}(): argument ${i+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${r}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var Yt=/^@[A-Za-z0-9_.]+$/;function*zt(r){let e="",t=0;for(;t<r.length;){let n=r[t];if(n==="{"&&r[t+1]==="{"){e+="{",t+=2;continue}if(n==="}"&&r[t+1]==="}"){e+="}",t+=2;continue}if(n==="{"){let s=r.indexOf("}",t+1);if(s!==-1){let i=r.slice(t,s+1),o=r.slice(t+1,s).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:Yt.test(o)?o:void 0},t=s+1;continue}e+=i,t=s+1;continue}}e+=n,t+=1}e&&(yield{kind:"text",value:e})}function Xt(r){return Array.isArray(r)?r.join(", "):typeof r=="boolean"?r?"true":"false":String(r)}function Zt(r){return r===" "||r===" "||r===`\n`||r==="\\r"||r==="\\f"||r==="\\v"}function en(r){let e="",t=!1;for(let n of r){if(Zt(n)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=n}return e}function Je(r,e,t){if(e.length===0||r.indexOf(e)<0)return r;let n="",s=0,i=!1;for(;s<r.length;){if(r.startsWith(e,s)){let o=r.indexOf(t,s+e.length);if(o>=0){s=o+t.length,i=!0;continue}n+=r.slice(s);break}n+=r[s],s+=1}return i?en(n):r}function Qe(r,e){if(r.indexOf("{")<0)return r;let t="";for(let n of zt(r)){if(n.kind==="text"){t+=n.value;continue}if(!n.ref){t+=n.raw;continue}let s=e(n.ref);t+=s===void 0?"":Xt(s)}return t}function Ye(r){return r.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}var f={NONE:0,LATIN_VOWEL:1,LATIN_LETTER:2,CYRILLIC_VOWEL:3,CYRILLIC_LETTER:4,HAN:5,KANA:6,KANA_SMALL:7,KANA_SOKUON:8,KANA_LONG:9,HANGUL:10,ARABIC_LETTER:11,ARABIC_VOWEL:12,THAI_CONSONANT:13,THAI_LEAD:14,THAI_VOWEL:15,MARK:16,OTHER_LETTER:17,DIGIT:18,PAUSE_SHORT:19,PAUSE_LONG:20,JOINER:21,SPACE:22},z=[9,13,22,32,32,22,33,33,20,39,39,21,44,44,19,46,46,20,48,57,18,58,59,19,63,63,20,65,65,1,66,68,2,69,69,1,70,72,2,73,73,1,74,78,2,79,79,1,80,84,2,85,85,1,86,88,2,89,89,1,90,90,2,97,97,1,98,100,2,101,101,1,102,104,2,105,105,1,106,110,2,111,111,1,112,116,2,117,117,1,118,120,2,121,121,1,122,122,2,133,133,22,160,160,22,170,170,2,173,173,21,181,181,17,186,186,2,192,198,1,199,199,2,200,207,1,208,209,2,210,214,1,216,221,1,222,223,2,224,230,1,231,231,2,232,239,1,240,241,2,242,246,1,248,253,1,254,254,2,255,261,1,262,273,2,274,283,1,284,295,2,296,305,1,306,331,2,332,339,1,340,359,2,360,371,1,372,373,2,374,376,1,377,415,2,416,417,1,418,430,2,431,432,1,433,460,2,461,476,1,477,477,2,478,483,1,484,489,2,490,493,1,494,505,2,506,527,1,528,531,2,532,535,1,536,549,2,550,563,1,564,696,2,697,699,17,700,700,21,701,705,17,710,721,17,736,740,2,748,748,17,750,750,17,768,879,16,880,884,17,886,893,17,895,895,17,902,902,17,904,1013,17,1015,1023,17,1024,1025,3,1026,1027,4,1028,1028,3,1029,1029,4,1030,1031,3,1032,1036,4,1037,1038,3,1039,1039,4,1040,1040,3,1041,1044,4,1045,1045,3,1046,1047,4,1048,1048,3,1049,1053,4,1054,1054,3,1055,1058,4,1059,1059,3,1060,1066,4,1067,1067,3,1068,1068,4,1069,1072,3,1073,1076,4,1077,1077,3,1078,1079,4,1080,1080,3,1081,1085,4,1086,1086,3,1087,1090,4,1091,1091,3,1092,1098,4,1099,1099,3,1100,1100,4,1101,1105,3,1106,1107,4,1108,1108,3,1109,1109,4,1110,1111,3,1112,1116,4,1117,1118,3,1119,1153,4,1155,1161,16,1162,1231,4,1232,1235,3,1236,1237,4,1238,1239,3,1240,1249,4,1250,1255,3,1256,1259,4,1260,1267,3,1268,1271,4,1272,1273,3,1274,1327,4,1329,1369,17,1376,1416,17,1425,1469,17,1471,1471,17,1473,1474,17,1476,1477,17,1479,1522,17,1548,1548,19,1552,1562,16,1563,1563,19,1567,1567,20,1568,1599,11,1600,1600,16,1601,1610,11,1611,1616,12,1617,1631,16,1632,1641,18,1646,1647,11,1648,1648,12,1649,1747,11,1748,1748,20,1749,1749,11,1750,1756,16,1759,1764,16,1765,1766,11,1767,1768,16,1770,1773,16,1774,1775,11,1776,1785,18,1786,1788,11,1791,1791,11,1808,1871,17,1872,1919,11,1920,2037,17,2042,2045,17,2048,2093,17,2112,2139,17,2144,2154,17,2160,2183,11,2185,2191,11,2199,2207,16,2208,2249,11,2250,2273,16,2275,2303,16,2304,2384,17,2385,2388,16,2389,2403,17,2404,2405,20,2406,2415,17,2417,2545,17,2556,2556,17,2558,2677,17,2689,2799,17,2809,2927,17,2929,2929,17,2946,3055,17,3072,3183,17,3200,3203,17,3205,3406,17,3412,3415,17,3423,3439,17,3450,3571,17,3585,3630,13,3631,3631,16,3632,3641,15,3642,3642,16,3648,3652,14,3653,3654,16,3655,3655,15,3656,3660,16,3661,3661,15,3662,3662,16,3664,3673,18,3713,3840,17,3864,3865,17,3872,3881,17,3893,3893,17,3895,3895,17,3897,3897,17,3902,3972,17,3974,4028,17,4038,4038,17,4096,4169,17,4176,4253,17,4256,4346,17,4348,4959,17,4992,5007,17,5024,5117,17,5121,5740,17,5743,5759,17,5760,5760,22,5761,5786,17,5792,5866,17,5873,5940,17,5952,6099,17,6103,6103,17,6108,6121,17,6155,6157,17,6159,6459,17,6470,6617,17,6656,6683,17,6688,6809,17,6823,6823,17,6832,6891,16,6912,6988,17,6992,7001,17,7019,7027,17,7040,7155,17,7168,7223,17,7232,7293,17,7296,7306,4,7312,7359,17,7376,7378,16,7380,7392,16,7393,7393,17,7394,7400,16,7401,7404,17,7405,7405,16,7406,7411,17,7412,7412,16,7413,7415,17,7416,7417,16,7418,7418,17,7424,7461,2,7462,7466,17,7467,7467,4,7468,7516,2,7517,7521,17,7522,7525,2,7526,7530,17,7531,7543,2,7544,7544,4,7545,7614,2,7615,7615,17,7616,7679,16,7680,7681,1,7682,7699,2,7700,7709,1,7710,7723,2,7724,7727,1,7728,7755,2,7756,7763,1,7764,7793,2,7794,7803,1,7804,7821,2,7822,7823,1,7824,7832,2,7833,7833,1,7834,7839,2,7840,7929,1,7930,7935,2,7936,8124,17,8126,8126,17,8130,8140,17,8144,8155,17,8160,8172,17,8178,8188,17,8192,8202,22,8204,8205,21,8211,8212,19,8217,8217,21,8230,8230,20,8232,8233,22,8239,8239,22,8253,8253,20,8263,8265,20,8287,8287,22,8305,8305,2,8319,8319,2,8336,8348,2,8400,8432,16,8450,8450,17,8455,8455,17,8458,8467,17,8469,8469,17,8473,8477,17,8484,8484,17,8486,8486,17,8488,8488,17,8490,8490,2,8491,8491,1,8492,8493,17,8495,8497,17,8498,8498,2,8499,8505,17,8508,8511,17,8517,8521,17,8526,8526,2,8579,8580,2,11264,11359,17,11360,11391,2,11392,11492,17,11499,11507,17,11520,11631,17,11647,11742,17,11744,11775,16,11823,11823,17,12288,12288,22,12289,12289,19,12290,12290,20,12293,12293,5,12294,12294,17,12330,12335,16,12337,12341,17,12347,12347,5,12348,12348,17,12353,12353,7,12354,12354,6,12355,12355,7,12356,12356,6,12357,12357,7,12358,12358,6,12359,12359,7,12360,12360,6,12361,12361,7,12362,12386,6,12387,12387,8,12388,12418,6,12419,12419,7,12420,12420,6,12421,12421,7,12422,12422,6,12423,12423,7,12424,12429,6,12430,12430,7,12431,12436,6,12437,12438,7,12441,12444,16,12445,12447,6,12449,12449,7,12450,12450,6,12451,12451,7,12452,12452,6,12453,12453,7,12454,12454,6,12455,12455,7,12456,12456,6,12457,12457,7,12458,12482,6,12483,12483,8,12484,12514,6,12515,12515,7,12516,12516,6,12517,12517,7,12518,12518,6,12519,12519,7,12520,12525,6,12526,12526,7,12527,12538,6,12540,12540,9,12541,12543,6,12549,12686,17,12704,12735,17,12784,12799,7,13312,19903,5,19968,40959,5,40960,42124,17,42192,42237,17,42240,42508,17,42512,42539,17,42560,42606,4,42607,42610,16,42612,42621,16,42623,42653,4,42654,42655,16,42656,42725,17,42736,42737,17,42775,42783,17,42786,42887,2,42888,42888,17,42891,43007,2,43008,43047,17,43052,43052,17,43072,43123,17,43136,43205,17,43216,43255,17,43259,43259,17,43261,43309,17,43312,43347,17,43360,43456,17,43471,43481,17,43488,43609,17,43616,43638,17,43642,43741,17,43744,43759,17,43762,43822,17,43824,43866,2,43868,43876,2,43877,43877,17,43878,43881,2,43888,44010,17,44012,44025,17,44032,55203,10,55216,55291,17,63744,64217,5,64256,64262,2,64275,64296,17,64298,64335,17,64336,64433,11,64467,64829,11,64848,64911,11,64914,64967,11,65008,65019,11,65024,65039,16,65056,65071,16,65104,65105,19,65136,65276,11,65281,65281,20,65292,65292,19,65294,65294,20,65296,65305,18,65306,65307,19,65311,65311,20,65313,65338,2,65345,65370,2,65377,65377,20,65380,65380,19,65382,65382,6,65383,65390,7,65391,65391,8,65392,65392,9,65393,65437,6,65438,65439,16,65440,65500,17,65536,65786,17,66045,66045,16,66176,66256,17,66272,66272,16,66304,66335,17,66349,66368,17,66370,66377,17,66384,66461,17,66464,66511,17,66560,66915,17,66928,67431,17,67456,67514,2,67584,67669,17,67680,67702,17,67712,67742,17,67808,67829,17,67840,67861,17,67872,67897,17,67904,68023,17,68030,68031,17,68096,68159,17,68192,68220,17,68224,68252,17,68288,68295,17,68297,68326,17,68352,68405,17,68416,68437,17,68448,68466,17,68480,68497,17,68608,68850,17,68864,68973,17,68975,68997,17,69248,69292,17,69296,69297,17,69314,69319,11,69370,69375,16,69376,69404,17,69415,69456,17,69488,69509,17,69552,69572,17,69600,69702,17,69734,69818,17,69826,69826,17,69840,69951,17,69956,70003,17,70006,70084,17,70089,70092,17,70094,70106,17,70108,70108,17,70144,70199,17,70206,70312,17,70320,70457,17,70459,70459,16,70460,70611,17,70625,70730,17,70736,70745,17,70750,70853,17,70855,71104,17,71128,71232,17,71236,71257,17,71296,71352,17,71360,71481,17,71488,71738,17,71840,71913,17,71935,72003,17,72016,72161,17,72163,72254,17,72263,72345,17,72349,72349,17,72368,72440,17,72544,72672,17,72688,72768,17,72784,72793,17,72818,73462,17,73472,73538,17,73552,73648,17,73728,74649,17,74880,77808,17,77824,78895,17,78912,92777,17,92784,92916,17,92928,92982,17,92992,92995,17,93008,93017,17,93027,93548,17,93552,93823,17,93856,94177,17,94179,94179,5,94180,94180,17,94192,94193,16,94194,94195,5,94208,101874,17,110576,110951,6,110960,113817,17,113821,113822,17,118e3,118009,17,118528,118598,16,119141,119142,17,119143,119145,16,119149,119154,17,119163,119170,16,119173,119179,16,119210,119213,16,119362,119364,17,119808,120512,17,120514,120538,17,120540,120570,17,120572,120596,17,120598,120628,17,120630,120654,17,120656,120686,17,120688,120712,17,120714,120744,17,120746,120770,17,120772,120831,17,121344,121398,17,121403,121452,17,121461,121461,17,121476,121476,17,121499,121519,17,122624,122666,2,122880,122922,17,122928,122989,4,123023,123023,16,123136,123214,17,123536,123641,17,124112,124410,17,124608,125124,17,125136,125273,17,126464,126651,11,130032,130041,17,131072,210041,5,917760,917999,16];var nt=1.5,rt=2,Ie=1,st=2,x=(r,e)=>r[e]??-1;function tn(r){let e=0,t=z.length/3-1;for(;e<=t;){let n=e+t>>1;if(r<x(z,n*3))t=n-1;else if(r>x(z,n*3+1))e=n+1;else return x(z,n*3+2)}return f.NONE}function nn(r){return((r??"").split(/[-_]/)[0]??"").toLowerCase()}var ze=r=>r>=65&&r<=90||r>=97&&r<=122,rn=r=>r>=48&&r<=57;function sn(r,e){let t=n=>x(r,n);if(t(e)===60){let n=e+1;t(n)===47&&n++;let s=n;for(;ze(t(n));)n++;return n>s&&t(n)===62?n+1:e}if(t(e)===38){let n=e+1,s=t(n)===35;s&&n++;let i=n;for(;s?rn(t(n)):ze(t(n));)n++;return n>i&&t(n)===59?n+1:e}return e}var Xe=new Set([f.LATIN_VOWEL,f.LATIN_LETTER]),Ze=new Set([f.CYRILLIC_VOWEL,f.CYRILLIC_LETTER]),et=new Set([f.ARABIC_LETTER,f.ARABIC_VOWEL]),fe=new Set([f.THAI_CONSONANT,f.THAI_LEAD,f.THAI_VOWEL]),tt=new Set([f.OTHER_LETTER]),on=new Set([f.KANA,f.KANA_SMALL,f.KANA_SOKUON,f.KANA_LONG]);function K(r,e){let t=Array.from(r??"",h=>h.codePointAt(0)),n=t.map(tn),s=t.length,i=nn(e),o=i==="ja"||n.some(h=>on.has(h)),a=[],c=(h,A,d=1)=>{a.push({kind:"syllable",weight:d,start:h,end:A})},l=h=>h>=0&&h<s?x(n,h):f.NONE,p=h=>{for(;h<s&&x(n,h)===f.MARK;)h++;return h},m=(h,A)=>{let d=h+1;for(;d<s&&(A.has(x(n,d))||x(n,d)===f.MARK||x(n,d)===f.JOINER&&A.has(l(d+1)));)d++;return d},S=(h,A,d)=>{let y=[...new Set(d.map(b=>Math.min(p(b+1),A)-1))].sort((b,v)=>b-v);y.forEach((b,v)=>c(v===0?h:x(y,v-1)+1,v===y.length-1?A:b+1))},B=(h,A,d)=>Array.from({length:A},(y,b)=>x(h,Math.min(d*b+d-1,h.length-1))),u=0;for(;u<s;){let h=x(n,u),A=sn(t,u);if(A>u){u=A;continue}if(Xe.has(h)){let d=m(u,Xe),y=[],b=[],v=!1;for(let R=u;R<d;R++)x(n,R)===f.LATIN_VOWEL?(v?(y[y.length-1]=R,b[b.length-1]=x(b,b.length-1)+1):(y.push(R),b.push(1)),v=!0):x(n,R)!==f.MARK&&(v=!1);y.length>=2&&x(b,b.length-1)===1&&cn(t,n,u,d,x(y,y.length-1),i)&&y.pop(),S(u,d,y.length?y:[d-1]),u=d}else if(Ze.has(h)){let d=m(u,Ze),y=[];for(let b=u;b<d;b++)x(n,b)===f.CYRILLIC_VOWEL&&y.push(b);S(u,d,y.length?y:[d-1]),u=d}else if(et.has(h)){let d=m(u,et),y=[],b=[];for(let v=u;v<d;v++)x(n,v)===f.ARABIC_VOWEL?y.push(v):x(n,v)===f.ARABIC_LETTER&&b.push(v);S(u,d,y.length?y:B(b,Math.max(1,Math.ceil(b.length/2)),2)),u=d}else if(fe.has(h)){let d=m(u,fe);S(u,d,ln(n,u,d)),u=d}else if(tt.has(h)){let d=m(u,tt),y=[];for(let b=u;b<d;b++)x(n,b)===f.OTHER_LETTER&&y.push(b);S(u,d,B(y,Math.max(1,Math.ceil(y.length/3)),3)),u=d}else if(h===f.HAN){let d=p(u+1);c(u,d,o?rt:1),u=d}else if(h===f.KANA||h===f.HANGUL){let d=p(u+1);c(u,d),u=d}else if(h===f.KANA_SMALL||h===f.KANA_LONG){let d=p(u+1),y=a[a.length-1];y&&y.kind==="syllable"&&y.end===u?(y.end=d,h===f.KANA_LONG&&(y.weight+=1)):h===f.KANA_SMALL&&c(u,d),u=d}else if(h===f.KANA_SOKUON){let d=p(u+1);a.push({kind:"closed",weight:1,start:u,end:d}),u=d}else if(h===f.DIGIT){let d=p(u+1);c(u,d,nt),u=d}else if(h===f.PAUSE_SHORT||h===f.PAUSE_LONG)(x(t,u)===46||x(t,u)===44)&&l(u-1)===f.DIGIT&&l(u+1)===f.DIGIT||a.push({kind:"pause",weight:h===f.PAUSE_LONG?st:Ie,start:u,end:u+1}),u++;else if(h===f.SPACE){let d=u+1;for(;d<s&&x(n,d)===f.SPACE;)d++;an(n,u-1)&&fe.has(l(d))&&a.push({kind:"pause",weight:Ie,start:u,end:d}),u=d}else u++}return dn(a)}function an(r,e){for(;e>=0&&x(r,e)===f.MARK;)e--;return e>=0&&fe.has(x(r,e))}function cn(r,e,t,n,s,i){if(i!=="en"&&i!=="fr"||x(r,s)!==101&&x(r,s)!==69)return!1;let o=s+1;return!(o<n&&x(e,o)===f.MARK||(i==="fr"&&o<n&&(x(r,o)===115||x(r,o)===83)&&o++,o!==n)||i==="en"&&s-2>=t&&(x(r,s-1)===108||x(r,s-1)===76)&&x(e,s-2)===f.LATIN_LETTER)}function ln(r,e,t){let n=[],s=[],i=!1,o=()=>{for(let a=0;a<Math.floor((s.length-1)/2);a++)n.push(x(s,2*a+1))};for(let a=e;a<t;a++){let c=x(r,a);if(c===f.THAI_CONSONANT)s.push(a);else if(c===f.THAI_LEAD)o(),n.push(a+1<t&&x(r,a+1)===f.THAI_CONSONANT?a+1:a),s=[],i=!0;else if(c===f.THAI_VOWEL){if(s.length===0)continue;if(i&&s.length<=2){i=!1,s=[];continue}o(),n.push(a),s=[],i=!1}}if(n.length===0){let a=Math.max(1,Math.ceil(s.length/2));for(let c=0;c<a;c++)n.push(s.length?x(s,Math.min(2*c+1,s.length-1)):t-1)}else o();return n}function dn(r){let e=[];for(let t of r){let n=e[e.length-1];t.kind==="pause"&&n?.kind==="pause"?(n.weight=Math.max(n.weight,t.weight),n.end=t.end):e.push({...t})}for(;e[0]?.kind==="pause";)e.shift();for(;e[e.length-1]?.kind==="pause";)e.pop();return e}function Be(r,e){let t=0;for(let n of K(r,e))n.kind!=="pause"&&(t+=n.weight);return t}function L(r,e){for(let t of r){e(t);let n=t.children;n&&L(n,e)}}function k(r){let e=r.gameId?.trim();return e||Ye(r.name)}function Re(r){let e=new Map;for(let[t,n]of Object.entries(r))e.set(k(n),t);return e}function he(r,e,t){return(t??Re(r)).get(e)??(Object.hasOwn(r,e)?e:void 0)}var G=.6;var X=4;var pn=1.5,un=18;function it(r,e,t){let n=typeof t=="number"&&Number.isFinite(t)&&t>0?t:X,s=0;for(let i of K(r??"",e))s+=i.weight;return Math.min(Math.max(s/n,pn),un)}function xe(r){return`cast:${r}`}function me(r){return`qualifier:${r}`}function ot(r,e){return`speaker:${r}:${e}`}var at="speaker:pattern",ct="{name} ({qualifier})";function lt(r,e,t){return r.split("{name}").map(n=>n.split("{qualifier}").join(t)).join(e)}var Oe={open:"[",close:"]"},dt="SFX";var Z=4;function ee(r){let e=new Set,t=[];for(let n of r)e.has(n)||(e.add(n),t.push(n));return t}function Se(r){let e=new Map,t=(n,s)=>{let i=ee([...s,...n.tags??[]]);if(e.set(n.id,i),n.type==="group"&&n.prompt&&e.set(n.prompt.id,ee([...i,...n.prompt.tags??[]])),n.type==="group")for(let o of n.children)t(o,i);else for(let o of n.beats??[])e.set(o.id,ee([...i,...o.tags??[]]))};for(let n of Object.values(r.scenes)){let s=ee(n.tags??[]);e.set(n.id,s);for(let i of n.blocks){let o=ee([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var pt=r=>r.kind==="line"||r.kind==="text",te=r=>typeof r=="number"&&Number.isFinite(r)?r:void 0;function ut(r){let e=new Map,t=(i,o,a)=>{let c=i.kind==="gameEvent"?void 0:te(i.padAfter),l=c??o;a&&l<0&&(l=0),e.set(i.id,c!==void 0?{own:c,resolved:l}:{resolved:l})},n=(i,o)=>{let a=te(i.padAfterDefault)??o;if(i.type==="group"){i.prompt&&t(i.prompt,a,!1);for(let p of i.children)n(p,a);return}let c=i.beats??[],l=-1;c.forEach((p,m)=>{pt(p)&&(l=m)}),c.forEach((p,m)=>{pt(p)&&t(p,a,m===l)})},s=te(r.padAfterDefault)??G;for(let i of Object.values(r.scenes)){let o=te(i.padAfterDefault)??s;for(let a of i.blocks){let c=te(a.padAfterDefault)??o;for(let l of a.children)n(l,c)}}return e}var gt=new WeakMap,ft=new WeakMap;function gn(r){let e=ft.get(r);return e||(e=Se(r),ft.set(r,e)),e}var ht=new WeakMap;function fn(r){let e=ht.get(r);return e||(e=ut(r),ht.set(r,e)),e}var xt=new WeakMap;function hn(r){let e=xt.get(r);if(e)return e;e=new Map;for(let t of Object.values(r.scenes))for(let n of t.blocks)L(n.children,s=>{if(s.type==="group"&&s.selector==="choice")for(let i of s.children)e.set(i.id,s.id)});return xt.set(r,e),e}var mt=new WeakMap;function xn(r){let e=mt.get(r);if(e)return e;e=new Map;for(let t of Object.values(r.scenes))for(let n of t.blocks)L(n.children,s=>{if(s.type==="group"){s.prompt&&e.set(s.prompt.id,s.prompt);return}for(let i of s.beats??[])e.set(i.id,i)});return mt.set(r,e),e}function I(r){if(r===void 0)return;let e={};for(let[t,n]of Object.entries(r))e[t]=Array.isArray(n)?[...n]:n;return e}function j(r,e){return r.tagIndex.get(e)?.slice()}var re="Patter",ne=r=>r.replace(/%/g,"%25").replace(/\\//g,"%2F"),mn=r=>r.replace(/%2F/g,"/").replace(/%25/g,"%"),St=Symbol("ownsRegistry"),yt=Symbol("setupReported"),C={stage:r=>`patter/scene/${ne(r)}`,flow:r=>`patter/flow/${ne(r)}/`,flowGlobals:r=>`patter/flow/${ne(r)}/patter`,flowScene:(r,e)=>`patter/flow/${ne(r)}/scene/${ne(e)}`},ie=class{constructor(e){this.journal=e}journal},Ee=class r{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;requestedLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineSeq=0;engineTraceHandlers=new Set;constructor(e,t={}){this.creationOptions=t;let n=[];for(let g of Object.keys(t))yn.has(g)||n.push({node:g,message:g==="world"?\'the engine option "world" has gone: bind the scope as hostScopes: { world }\':`"${g}" isn\'t an engine option, so it\'s ignored`});let s=e.strings;this.allStrings=s,this.requestedLocale=t.locale,this.currentLocale=Ne(e,t.locale),this.currentLocale.problem&&n.push({node:t.locale,message:this.currentLocale.problem});let i=Ft(s,this.currentLocale),o=s[e.locales.default]??{},a=e.localisation,c=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let l=new Map;for(let g of e.cast??[])g.displayName&&l.set(g.name,g.displayName);let p=new Map;for(let g of e.qualifiers??[])g?.gameId&&p.set(g.gameId,g.name);let m=new Map;for(let g of e.cast??[])for(let[F,w]of Object.entries(g.qualifierLabels??{}))typeof w=="string"&&m.set(`${g.name}\\0${F}`,w);let S=e.speakerPattern??ct;this.defaultSeed=(t.seed??2654435769)>>>0;let B=new Map,u=new Map,h=new Map;for(let[g,F]of Object.entries(e.scenes)){this.sceneGameIdToId.set(k(F),g);let w=new Map;for(let D of F.blocks)u.set(D.id,{sceneId:g}),h.set(D.id,D),w.set(k(D),D.id),L(D.children,N=>B.set(N.id,N));this.blockGameIdToId.set(g,w)}let A=e.properties??[],d=A.filter(g=>g.shared??!0).map(vt),y=A.filter(g=>!(g.shared??!0)).map(vt),b=new Set(d.map(g=>g.name.toLowerCase())),v=t.registry??new pe,R=!t.registry||t[St]===!0,_e=new P(d,{pathPrefix:"@patter."}),be=[],ae=[];try{v.mountOwned("patter",_e,{owner:re}),ae.push("patter");let g=new Set,F=e.scopeRegistry?.scopes??[];for(let[w,D]of Object.entries(t.hostScopes??{})){let N=F.find(ce=>ce.token===w);if(!N&&!(e.externalScopes??[]).includes(w)){let ce=F.find(Mt=>Mt.token.toLowerCase()===w.toLowerCase());n.push({node:w,message:ce?`hostScopes binds "${w}", which this bundle doesn\'t declare: it declares "${ce.token}", and a scope\'s token is case-sensitive`:`hostScopes binds "${w}", which this bundle doesn\'t declare`})}let Tt=(N?.declarations??[]).map(It);v.defineForeign(w,D,Tt,{writable:N?.writable??!0,owner:re}),ae.push(w),g.add(w)}for(let w of R?e.scopeRegistry?.scopes??[]:[]){if(g.has(w.token)||v.has(w.token))continue;let D=(w.declarations??[]).map(N=>vn(N,w.writable));v.defineOwned(w.token,D,{owner:re}),ae.push(w.token),be.push(w.token)}}catch(g){for(let F of ae)v.remove(F,{keep:!0});throw g}let Ge=new Map;for(let[g,F]of Object.entries(e.scenes)){let w=new Set((F.sceneProps??[]).filter(D=>D.shared??!1).map(D=>D.name.toLowerCase()));Ge.set(g,w)}if(this.host={logEnabled:t.log??!1,tracing:t.log??!1,emitEngine:(g,F,w)=>this.emitEngine(g,F,w),bundle:e,emitIds:c,strings:i,defaultStrings:o,castDisplay:l,qualifierDisplay:p,speakerLabels:m,speakerPattern:S,nodeIndex:B,blockIndex:u,blockById:h,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:gn(e),padIndex:fn(e),registry:v,ownsRegistry:R,patterBag:_e,hostScopes:be,patterSharedDecls:d,patterLocalDecls:y,patterSharedNames:b,sceneSharedNames:Ge,sharedVisits:new Map,qualityLadders:new Map,sharedSelectors:new Map,stageBags:new Map,journal:null,customRng:t.rng,onDryChoice:t.onDryChoice,steer:En(t.steer,n),onError:t.onError??(g=>console.warn(g.kind==="setup"?`Patterplay: ${g.message}`:g.kind==="save"?`Patterplay: flow \'${g.flow}\': ${g.message}`:`Patterplay: ${g.kind} on ${g.node} in flow \'${g.flow}\' failed, played through: ${g.message}`)),reportRefits:()=>{let g=v.takeMisfits(F=>F==="patter"||F.startsWith("patter/")||be.includes(F));if(g.length!==0)if(t.onRefit)t.onRefit(g);else for(let F of g)console.warn(`Patterplay: the save\'s ${F.scope}.${F.name} was ${JSON.stringify(F.value)}, which no longer fits its declaration; it is back at its default`)},replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??Oe).open,captionClose:(e.closedCaptions??Oe).close,captionCharacter:e.closedCaptions?.character||dt,refSplitCache:new Map,refSplitRevision:v.revision},this.host.reportRefits(),t[yt]!==!0)for(let g of n)this.reportSetup(g.node,g.message)}reportSetup(e,t){this.host.onError({flow:"",kind:"setup",node:e,message:t}),this.host.tracing&&this.emitEngine("",{type:"diagnostic",kind:"setup",node:e,message:t})}get locale(){return this.currentLocale.locale}get locales(){let{default:e,included:t}=this.host.bundle.locales;return{default:e,included:[...t]}}get isSourceDebug(){return this.sourceDebug}get buildId(){return this.host.bundle.content?.hash??""}setLocale(e){this.requestedLocale=e,this.useLocale(Ne(this.host.bundle,e)),this.currentLocale.problem&&this.reportSetup(e,this.currentLocale.problem)}useLocale(e){this.currentLocale=e,this.host.strings=Ft(this.allStrings,e)}replaceStrings(e){this.allStrings=e.strings;let t=this.currentLocale.problem;this.useLocale(Ne(e,this.requestedLocale)),this.host.defaultStrings=this.allStrings[this.host.bundle.locales.default]??{};let n=this.currentLocale.problem;n&&n!==t&&this.reportSetup(this.requestedLocale,n)}hotSwap(e){this.refuseInCheckpoint("hotSwap");let t=this.saveGame(),n=l=>(l.setClosedCaptions(this.host.captionsOn),l),s=this.requestedLocale,i=(l=!1)=>new r(e,{...this.creationOptions,...s!==void 0?{locale:s}:{},registry:this.host.registry,[St]:this.host.ownsRegistry,[yt]:l}),o=new Set(["patter",...this.host.hostScopes]),a=this.host.ownsRegistry?void 0:Object.fromEntries(Object.entries(this.host.registry.save()).filter(([l])=>o.has(l)||l.startsWith("patter/")));this.release(!0),a&&this.host.registry.load(a,{keepParked:!0,refit:!0});let c=i();try{return c.loadGame(t),n(c)}catch{c.release(!0);let l=this.host.ownsRegistry?t.registry:a;l&&this.host.registry.load(l,{keepParked:!0,refit:!0});let p=i(!0);for(let[m,S]of Object.entries(t.flows)){let B=S.cursor.currentSceneId;try{p.openFlow(m,B!==null?{scene:B}:{})}catch{}}return n(p)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){this.assertExternalScopes();let{sceneId:n,blockId:s}=this.resolveOpenAddress(t.scene,t.block),i=this.flowsById.get(e),o=this.host.journal;if(o&&i&&!i.isClosed)throw new Error(`openFlow would replace the open flow \'${e}\', which can\'t be undone while a checkpoint is open`);i?.close();let a=new $(e,this.host,t.seed??this.defaultSeed);return o&&(o.flows.add(a),o.opened.add(a),o.undo.push(()=>{a.close(),i?this.flowsById.set(e,i):this.flowsById.delete(e)})),this.flowsById.set(e,a),a.begin(n,s),a}runFlow(e,t,n){let s=this.flowsById.get(e);if(!s)return this.openFlow(e,{scene:t,block:n}).advanceToStop().played;if(!s.goto(t,n))throw new Error(`runFlow: address not found: ${t}${n===void 0?"":` / ${n}`}`);return s.advanceToStop().played}assertExternalScopes(){for(let e of this.host.bundle.externalScopes??[])if(!this.host.registry.has(e))throw new Error(`this content names @${e}, which no engine on this registry registered: give every engine the game\'s one registry`)}resolveOpenAddress(e,t){if(e!==void 0){let n=Pe(this.host,e);if(n===void 0)throw new Error(`unknown scene: ${e}`);if(t===void 0)return{sceneId:n};let s=Le(this.host,n,t);if(s===void 0)throw new Error(`unknown block: ${t}`);return{sceneId:n,blockId:s}}if(t!==void 0){if(!this.host.blockIndex.has(t))throw new Error(`unknown block: ${t}`);return{blockId:t}}if(Object.keys(this.host.bundle.scenes).length===0)throw new Error("no scenes in bundle");return{}}resolveSceneRef(e){if(e!=null)return Pe(this.host,e)??e}resolveBlockRef(e,t){if(t!=null)return e==null?t:Le(this.host,e,t)}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?k(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?k(t):void 0}tagsForBeat(e){return j(this.host,e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?j(this.host,t):void 0)??[]}tagsForBlock(e,t){let n=this.resolveSceneRef(e),s=this.resolveBlockRef(n,t);return(s!=null?j(this.host,s):void 0)??[]}gameDataForScene(e){let t=this.resolveSceneRef(e),n=t!=null?this.host.bundle.scenes[t]:void 0;return I(n?.gameData)??{}}gameDataForBlock(e,t){let n=this.resolveBlockRef(this.resolveSceneRef(e),t),s=n!=null?this.host.blockById.get(n):void 0;return I(s?.gameData)??{}}extensionsForScene(e){let t=this.resolveSceneRef(e);return{...(t!=null?this.host.bundle.scenes[t]:void 0)?.extensions}}extensionsForBlock(e,t){let n=this.resolveBlockRef(this.resolveSceneRef(e),t);return{...(n!=null?this.host.blockById.get(n):void 0)?.extensions}}extensionsForSnippet(e){let t=this.host.nodeIndex.get(e);return t?.type==="snippet"?{...t.extensions}:{}}getCast(){let e=[];for(let t of this.host.bundle.cast??[])t?.name&&e.push(t.name);return e}castForScene(e){let t=this.resolveSceneRef(e),n=t!=null?this.host.bundle.scenes[t]:void 0;if(!n)return[];let s=new Set;for(let i of n.blocks)Et(i.children,s);return[...s]}castForBlock(e,t){let n=this.resolveSceneRef(e),s=this.resolveBlockRef(n,t),i=s!=null?this.host.blockById.get(s):void 0;if(!i)return[];let o=new Set;return Et(i.children,o),[...o]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...k(e)?{gameId:k(e)}:{},name:e.name,...bt(e.gameData),...T(e.extensions),...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...k(t)?{gameId:k(t)}:{},name:t.name,...bt(t.gameData),...T(t.extensions),...this.tagsField(t.id),children:t.children.map(n=>this.outlineNode(n))}))}))}getBeatSequence(){let e=[];for(let t of Object.values(this.host.bundle.scenes))for(let n of t.blocks)L(n.children,s=>{if(s.type==="snippet")for(let i of s.beats??[])e.push({sceneId:t.id,blockId:n.id,snippetId:s.id,beat:this.beatInfo(i)})});return e}outlineNode(e){return e.type==="group"?{type:"group",id:e.id,...this.tagsField(e.id),...e.selector?{selector:e.selector}:{},...e.prompt?{prompt:this.beatInfo(e.prompt)}:{},children:e.children.map(t=>this.outlineNode(t))}:{type:"snippet",id:e.id,...this.tagsField(e.id),beats:(e.beats??[]).map(t=>this.beatInfo(t)),...e.jump?{jumpTo:e.jump.to,...e.jump.mode?{jumpMode:e.jump.mode}:{}}:{}}}beatInfo(e){let t=j(this.host,e.id),n={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){n.character=e.character;let i=this.host.defaultStrings[xe(e.character)]??this.host.castDisplay.get(e.character);i!==void 0&&(n.characterName=i)}if(e.direction!==void 0&&(n.direction=e.direction),e.qualifier!==void 0){n.qualifier=e.qualifier;let i=this.host.defaultStrings[me(e.qualifier)]??this.host.qualifierDisplay.get(e.qualifier);i!==void 0&&(n.qualifierName=i)}let s=ye(this.host,e.character,e.qualifier,!0);s!==void 0&&(n.speakerLabel=s)}if(e.kind==="line"||e.kind==="text"){let s=this.host.padIndex.get(e.id);n.padAfter=s?.resolved??G,s?.own!==void 0&&(n.ownPadAfter=s.own);let i=this.host.defaultStrings[e.id];i!==void 0&&(n.text=i)}return e.gameData&&Object.keys(e.gameData).length&&(n.gameData=I(e.gameData)),e.extensions&&Object.keys(e.extensions).length&&(n.extensions=e.extensions),t&&t.length&&(n.tags=t),n}tagsField(e){let t=j(this.host,e);return t&&t.length?{tags:t}:{}}getFlow(e){return this.flowsById.get(e)}flows(){return[...this.flowsById.values()]}listBags(){let e=[{bag:this.host.patterBag}];for(let[t,n]of this.host.stageBags)e.push({bag:n,pathPrefix:`@scene:${t}.`});return e}checkpoint(){if(this.host.journal)throw new Error("a checkpoint is already open: roll it back or commit it first");let e={undo:[],flows:new Set,opened:new Set,selectors:new Set,flowSelectors:new Map};return this.host.journal=e,new ie(e)}rollback(e){this.endCheckpoint(e);let t=e.journal.undo;for(let n=t.length-1;n>=0;n--)t[n]();r.forget(e.journal)}commit(e){this.endCheckpoint(e),r.forget(e.journal)}get inCheckpoint(){return this.host.journal!==null}endCheckpoint(e){if(this.host.journal!==e.journal)throw new Error("that checkpoint is not the open one");this.host.journal=null}static forget(e){e.undo=[],e.flows.clear(),e.opened.clear(),e.selectors.clear(),e.flowSelectors.clear()}refuseInCheckpoint(e){if(this.host.journal)throw new Error(`${e} can\'t be undone, so it isn\'t allowed while a checkpoint is open`)}captureFlow(e){let t=this.flowsById.get(e);if(!t)throw new Error(`no open flow \'${e}\' to capture`);return{version:Z,...t.snapshot(),...kn(e,this.host.registry.save())}}restoreFlow(e,t){this.refuseInCheckpoint("restoreFlow");let n=t.version;if(n!==3&&n!==Z)throw new Error(`unsupported flow state version: ${String(n)}`);let s=t.cursor;if(typeof s!="object"||s===null)throw new Error("malformed flow state: no cursor");if(this.flowsById.has(e))throw new Error(`a flow \'${e}\' is already open; close it before restoring another under that id`);this.assertExternalScopes();let i=C.flow(e);this.host.registry.discardParked(i),this.host.registry.load(Fn(e,t),{keepParked:!0,refit:!0});let o=new $(e,this.host,this.defaultSeed);try{o.restore(t)}catch(a){throw o.close(),this.host.registry.discardParked(i),a}return this.flowsById.set(e,o),this.host.reportRefits(),o}closeFlow(e){this.refuseInCheckpoint("closeFlow"),this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){this.refuseInCheckpoint("reset");for(let e of this.flowsById.values())e.close();this.flowsById.clear(),this.host.patterBag.reseed(this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear();for(let e of this.host.stageBags.keys())this.host.registry.remove(C.stage(e));this.host.stageBags.clear(),this.host.registry.discardParked("patter/")}release(e){for(let n of this.flowsById.values())n.releaseBags(e),n.close();this.flowsById.clear();let t=this.host.registry;for(let n of this.host.stageBags.keys())t.remove(C.stage(n),{keep:e});this.host.stageBags.clear();for(let n of["patter",...this.host.hostScopes])t.has(n)&&t.remove(n,{keep:e});for(let n of Object.keys(this.creationOptions.hostScopes??{}))t.has(n)&&t.remove(n)}getProperty(e){let{scope:t,name:n}=this.splitShared(e);return this.host.registry.get(t,n)}setProperty(e,t){let{scope:n,name:s}=this.splitShared(e);Ct(this.host,n,s,t,null);let i=this.host.journal?this.host.registry.get(n,s):void 0;this.host.registry.set(n,s,t,{host:!0}),this.host.journal&&i!==void 0&&this.host.journal.undo.push(()=>this.host.registry.set(n,s,i,{host:!0}))}stageIndex(e,t){return V(this.ladderOf(e),t)}compareStages(e,t,n){return q(this.ladderOf(e),t,n)}nextStage(e,t){return H(this.ladderOf(e),t)}ladderOf(e){let{scope:t,name:n}=this.splitShared(e),s=wn(this.host,t,n);if(!s)throw new Error(`\'${e}\' is not a quality`);return s}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),this.host.tracing=!0,()=>{this.engineTraceHandlers.delete(e),this.host.tracing=this.host.logEnabled||this.engineTraceHandlers.size>0}}emitEngine(e,t,n){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineSeq++,...n?{scene:n}:{}})}getVisitCounts(){return Object.fromEntries(this.host.sharedVisits)}listProperties(){return this.host.patterSharedDecls.map(e=>({name:e.name,path:`@patter.${e.name}`,type:e.type,values:e.values,stages:e.stages,value:this.getProperty(`@${e.name}`),default:U(e),writable:e.writable??!0}))}splitShared(e){let t=Bt(this.host,e);if(t.scope==="scene")throw new Error(`\'${e}\': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);return t}saveGame(){let e={};for(let[t,n]of this.flowsById)e[t]=n.snapshot();return{version:Z,...this.host.ownsRegistry?{registry:this.host.registry.save()}:{},sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:At(this.host.sharedSelectors),flows:e}}loadGame(e){this.refuseInCheckpoint("loadGame");let t=e.version;if(t!==3&&t!==Z)throw new Error(`unsupported save version: ${String(t)}`);let n=e.flows;if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("malformed save: no flows");this.assertExternalScopes();let s=this.host.registry;for(let[o,a]of this.flowsById)a.releaseBags(o in e.flows),a.close();this.flowsById.clear();for(let o of this.host.stageBags.keys())s.remove(C.stage(o),{keep:!0});this.host.stageBags.clear();let i=e.registry;i&&(this.host.ownsRegistry?s.load(i,{refit:!0}):s.load(i,{keepParked:!0,refit:!0})),this.host.sharedVisits.clear();for(let[o,a]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(o,a);this.host.sharedSelectors.clear();for(let[o,a]of Dt(e.sharedSelectors))this.host.sharedSelectors.set(o,a);for(let[o,a]of Object.entries(e.flows)){let c=new $(o,this.host,this.defaultSeed);c.restore(a),this.flowsById.set(o,c)}this.host.reportRefits()}},$=class{id;host;local;registered=new Set;rngState;started=!1;flowEnded=!1;dryChoice=null;ranDry=null;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPrompt=null;pendingPromptOwnerId=null;selectors=new Map;visitCounts=new Map;sceneBags=new Map;patterResolver={get:e=>this.host.patterSharedNames.has(e)?this.host.patterBag.get(e):this.local.get(e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.registry.set("patter",e,t):this.local.set(e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;if(t!==null)return this.sceneBagFor(t,e)?.get(e)},set:(e,t)=>{let n=this.currentSceneId;if(n===null)return;let s=this.sceneBagFor(n,e);s&&s.set(e,t)}};evalCtx;ctxRevision=-1;registryQualities;flowLog=[];flowSeq=0;constructor(e,t,n){this.id=e,this.host=t,this.rngState=J(n),this.local=this.newLocal(),this.evalCtx={scopes:{},host:{nextRandom:this.rng,visits:s=>this.visitCounts.get(s)??0,patterVisits:s=>this.host.sharedVisits.get(s)??0},qualities:(s,i)=>this.stagesFor(s,i)}}context(){let e=this.host.registry;if(e.revision!==this.ctxRevision){let t=e.toEvalContext(),n=this.evalCtx.scopes;for(let s of Object.keys(n))delete n[s];Object.assign(n,t.scopes),n.patter=this.patterResolver,n.scene=this.sceneResolver,this.registryQualities=t.qualities,this.ctxRevision=e.revision}return this.evalCtx}stagesFor(e,t){let n=t.toLowerCase();if(e==="patter")return se(this.host,"patter",()=>[...this.host.patterSharedDecls,...this.host.patterLocalDecls]).get(n);if(e==="scene"){let s=this.currentSceneId;return s==null?void 0:se(this.host,`scene/${s}`,()=>this.host.bundle.scenes[s]?.sceneProps).get(n)}return this.registryQualities?.(e,t)??se(this.host,`host/${e}`,()=>this.host.bundle.scopeRegistry?.scopes.find(s=>s.token===e)?.declarations).get(n)}begin(e,t){let n=this.host.bundle.start;if(e===void 0&&t===void 0&&n&&this.host.bundle.scenes[n.scene]&&(e=n.scene,n.block!==void 0&&this.host.blockIndex.get(n.block)?.sceneId===n.scene&&(t=n.block)),this.host.journal&&!this.host.journal.opened.has(this))throw new Error("a flow can\'t be started or reset while a checkpoint is open");if(this.releaseBags(!1),this.host.registry.discardParked(C.flow(this.id)),this.mountLocal(),this.selectors.clear(),this.visitCounts.clear(),this.stack=[],this.currentSceneId=null,this.flowEnded=!1,this.dryChoice=null,this.ranDry=null,this.activeSnippet=null,this.beatIndex=0,this.clearPending(),this.started=!0,t){let s=this.host.blockIndex.get(t);if(!s)throw new Error(`unknown block: ${t}`);this.enterSceneSetup(s.sceneId),this.stack=[{sceneId:s.sceneId,containerId:t,index:0}],this.enter(t)}else{let s=e??Object.keys(this.host.bundle.scenes)[0],i=s?this.host.bundle.scenes[s]:void 0;if(!i)throw new Error(s?`unknown scene: ${s}`:"no scenes in bundle");this.enterSceneSetup(s);let o=i.blocks[0];o&&(this.stack=[{sceneId:s,containerId:o.id,index:0}],this.enter(o.id))}this.settle()}reset(e,t){this.begin(e,t)}goto(e,t){if(this.closed)return!1;if(this.touch(),e==="END")return this.started=!0,this.clearPending(),this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],this.dryChoice=null,this.ranDry=null,!0;let n=Pe(this.host,e);if(n===void 0)return!1;let s;return t!==void 0&&(s=Le(this.host,n,t),s===void 0)?!1:this.started?(this.clearPending(),this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.dryChoice=null,this.ranDry=null,this.enterTarget(s??n,"jump"),this.settle(),!0):(this.begin(n,s),!0)}close(){this.releaseBags(!1),this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.clearPending()}clearPending(){this.pendingChoice=null,this.pendingPrompt=null,this.pendingPromptOwnerId=null}touch(){let e=this.host.journal;if(!e||e.flows.has(this))return;e.flows.add(this);let{rngState:t,started:n,flowEnded:s,dryChoice:i,ranDry:o,currentSceneId:a,activeSnippet:c,beatIndex:l,pendingChoice:p,pendingPrompt:m,pendingPromptOwnerId:S}=this,B=this.stack.map(u=>({...u}));e.undo.push(()=>{Object.assign(this,{rngState:t,started:n,flowEnded:s,dryChoice:i,ranDry:o,currentSceneId:a,activeSnippet:c,beatIndex:l,pendingChoice:p,pendingPrompt:m,pendingPromptOwnerId:S,stack:B})})}get isClosed(){return this.closed}get currentScene(){return this.currentSceneId}advance(){if(this.closed)return{type:"end",reason:"ended"};if(!this.started)throw new Error("flow has not been started");if(this.touch(),this.pendingPrompt){let e=this.pendingPrompt;return this.pendingPrompt=null,this.pendingPromptOwnerId=null,e.shown?this.promptResult(e.beat,e.shown):this.beatResult(e.beat)}return this.settle(),!this.flowEnded&&!this.activeSnippet&&!this.pendingChoice&&(this.flowEnded=!0),this.flowEnded?this.endResult():(this.dryChoice=null,this.pendingChoice?{type:"choice",groupId:this.pendingChoice.groupId,options:this.offer(this.pendingChoice)}:this.beatResult(this.activeSnippet.beats[this.beatIndex++]))}endResult(){if(this.dryChoice!==null){let e=this.dryChoice;this.dryChoice=null,this.ranDry=e,this.report({flow:this.id,kind:"dry-choice",node:e,message:`choice \'${e}\' ran dry (no option left to take, and no fallback) with nothing after it, so the flow ended there`})}return{type:"end",reason:this.ranDry!==null?"ran-dry":"ended"}}advanceToStop(){let e=[];for(;;){let t=this.advance();if(t.type==="choice"||t.type==="end")return{played:e,stop:t};e.push(t)}}settle(){let e=0;for(;;){if(++e>1e4)throw new Error("flow did not settle after 10000 transitions - likely a jump cycle with no deliverable content");if(this.flowEnded||this.pendingChoice)return;if(this.activeSnippet){if(this.beatIndex<(this.activeSnippet.beats?.length??0))return;this.runEffects(this.activeSnippet.onExit,this.activeSnippet.id);let i=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(i);continue}let t=this.stack[this.stack.length-1];if(!t){this.flowEnded=!0;return}t.sceneId!==this.currentSceneId&&(this.currentSceneId=t.sceneId);let n=this.childrenOf(t.containerId);if(!n){this.stack.pop();continue}let s=t.index;for(;t.index<n.length&&!this.eligible(n[t.index],"run");)t.index++;if(this.host.tracing&&t.index!==s&&this.emit({type:"select",group:t.containerId,selector:"run",children:n.slice(s,t.index+1).map((i,o)=>({id:i.id,eligible:s+o===t.index})),picked:n[t.index]?.id??null}),t.index>=n.length){this.stack.pop();continue}this.enterChild(n[t.index++])}}listBags(){let e=[{bag:this.local,pathPrefix:`${this.id}/@patter.`}];for(let[t,n]of this.sceneBags)e.push({bag:n,pathPrefix:`${this.id}/@scene:${t}.`});return e}log(){return this.flowLog}clearLog(){this.flowLog.length=0}emit(e){let t=this.currentSceneId??void 0;this.host.emitEngine(this.id,e,t),this.host.logEnabled&&this.flowLog.push({...e,seq:this.flowSeq++,...t?{scene:t}:{}})}getVisitCounts(){return Object.fromEntries(this.visitCounts)}stepFor(e){let t=xn(this.host.bundle).get(e);return t?this.beatResult(t):void 0}getChoices(){return this.pendingChoice?this.offer(this.pendingChoice):[]}offer(e){return e.options.map(t=>{let n=e.byId.get(t.id),s=this.promptFor(n);return e.shown.set(t.id,s),{id:t.id,prompt:s,eligible:t.eligible,gameData:I(t.gameData),...T(n.extensions)}})}choose(e){let t=this.pendingChoice;if(!t)throw new Error("no choice is pending");let n=t.options.find(a=>a.id===e);if(!n)throw new Error(`unknown choice option: ${e}`);if(!n.eligible)throw new Error(`choice option is not eligible: ${e}`);this.touch();let s=t.byId.get(e);this.host.tracing&&this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null;let i=this.host.replayPromptOnChoose?this.authoredPromptOf(s):void 0,o=i?t.shown.has(e)?t.shown.get(e):this.promptFor(s):void 0;this.pendingPrompt=i&&o?{beat:i,shown:{...o}}:null,this.pendingPromptOwnerId=this.pendingPrompt?s.id:null,this.enterChild(s)}isEnded(){return this.flowEnded}getProperty(e){let{scope:t,name:n}=this.splitRef(e);return t==="patter"?this.patterResolver.get(n):t==="scene"?this.sceneResolver.get(n):this.host.registry.get(t,n)}setProperty(e,t){this.writeProperty(e,t,!0)}stageIndex(e,t){return V(this.ladderOf(e),t)}compareStages(e,t,n){return q(this.ladderOf(e),t,n)}nextStage(e,t){return H(this.ladderOf(e),t)}ladderOf(e){let{scope:t,name:n}=this.splitRef(e);this.context();let s=this.stagesFor(t,n);if(!s)throw new Error(`\'${e}\' is not a quality`);return s}writeProperty(e,t,n){let{scope:s,name:i}=this.splitRef(e);if(n){if(s==="scene"&&this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);Ct(this.host,s,i,t,this.currentSceneId)}let o=this.host.journal;if(s==="patter"){if(o){let a=this.host.patterSharedNames.has(i),c=a?this.host.patterBag.get(i):this.local.get(i),l=this.local;c!==void 0&&o.undo.push(a?()=>this.host.registry.set("patter",i,c):()=>l.set(i,c))}this.patterResolver.set(i,t)}else if(s==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);if(o){let a=this.sceneBagFor(this.currentSceneId,i),c=a?.get(i);a&&c!==void 0&&o.undo.push(()=>a.set(i,c))}this.sceneResolver.set(i,t)}else{let a=o?this.host.registry.get(s,i):void 0;this.host.registry.set(s,i,t,n?{host:!0}:void 0),o&&a!==void 0&&o.undo.push(()=>this.host.registry.set(s,i,a,{host:!0}))}}snapshot(){let e=hn(this.host.bundle),t=this.activeSnippet?.beats?.[this.beatIndex]?.id;return{rngState:this.rngState,visits:Object.fromEntries(this.visitCounts),cursor:{flowEnded:this.flowEnded,...this.ranDry!==null?{ranDry:this.ranDry}:{},currentSceneId:this.currentSceneId,stack:this.stack.map(n=>{let s=this.childrenOf(n.containerId)?.[n.index],i=e.get(n.containerId);return{...n,...s?{nextId:s.id}:{},...i!==void 0?{choiceId:i}:{}}}),activeSnippetId:this.activeSnippet?.id??null,...t!==void 0?{beatId:t}:{},pendingChoice:this.pendingChoice?{groupId:this.pendingChoice.groupId,options:this.pendingChoice.options.map(n=>({id:n.id,eligible:n.eligible,...n.gameData!==void 0?{gameData:I(n.gameData)}:{}}))}:null,pendingPromptOwnerId:this.pendingPromptOwnerId,...this.pendingPrompt?.shown?{pendingPrompt:Sn(this.pendingPrompt.shown)}:{},selectors:At(this.selectors)}}}restore(e){if(this.host.journal)throw new Error("a flow can\'t be restored while a checkpoint is open");let t=this.restoreCursor(e);this.releaseBags(!0),this.mountLocal();for(let n of new Set([this.currentSceneId,...this.stack.map(s=>s.sceneId)]))n!==null&&this.host.bundle.scenes[n]&&this.ensureSceneBags(n);t&&(this.report({flow:this.id,kind:"save",node:t.node,message:`the save\'s place has gone from this build: ${t.instead}`}),t.reoffer&&this.setupChoice(t.reoffer))}restoreCursor(e){this.rngState=J(e.rngState),this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;this.started=!0,this.flowEnded=t.flowEnded,this.dryChoice=null,this.ranDry=t.flowEnded&&typeof t.ranDry=="string"?t.ranDry:null,this.currentSceneId=t.currentSceneId;let n=null;this.stack=[];for(let s of t.stack){let{nextId:i,choiceId:o,...a}=s,c=this.childrenOf(a.containerId),l=!c&&o!==void 0?this.host.nodeIndex.get(o):void 0;if(l?.type==="group"&&l.selector==="choice"){n={node:t.activeSnippetId??t.pendingChoice?.groupId??a.containerId,instead:`option ${a.containerId} has gone, so choice ${l.id} is offered again`,reoffer:l};break}let p=i!==void 0?c?.findIndex(m=>m.id===i)??-1:-1;this.stack.push(p>=0?{...a,index:p}:{...a})}if(this.activeSnippet=null,this.beatIndex=0,!n?.reoffer&&t.activeSnippetId!==null){let s=this.host.nodeIndex.get(t.activeSnippetId);if(s&&s.type==="snippet"){let i=s.beats??[];if(this.activeSnippet=s,t.beatId!==void 0){let o=i.findIndex(a=>a.id===t.beatId);this.beatIndex=o>=0?o:i.length,o<0&&(n={node:t.activeSnippetId,instead:`beat ${t.beatId} has gone from snippet ${t.activeSnippetId}, so the snippet ends there`})}else this.beatIndex=t.beatIndex??i.length}else n={node:t.activeSnippetId,instead:`snippet ${t.activeSnippetId} has gone, so play carries on after it`}}if(this.selectors=Dt(t.selectors),this.pendingChoice=null,!n?.reoffer&&t.pendingChoice!==null){let s=new Map,i=[];for(let o of t.pendingChoice.options){let a=this.host.nodeIndex.get(o.id);a&&(s.set(o.id,a),i.push({id:o.id,eligible:o.eligible,...o.gameData!==void 0?{gameData:o.gameData}:{}}))}if(i.length>0)this.pendingChoice={groupId:t.pendingChoice.groupId,options:i,byId:s,shown:new Map};else{let o=this.host.nodeIndex.get(t.pendingChoice.groupId);n=o?.type==="group"&&o.selector==="choice"?{node:t.pendingChoice.groupId,instead:`none of choice ${o.id}\'s options is left, so it\'s offered again`,reoffer:o}:{node:t.pendingChoice.groupId,instead:`choice ${t.pendingChoice.groupId} has gone, so play carries on after it`}}}if(this.pendingPrompt=null,this.pendingPromptOwnerId=n?.reoffer?null:t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let s=this.host.nodeIndex.get(this.pendingPromptOwnerId),i=s?this.authoredPromptOf(s):void 0,o=t.pendingPrompt,a=o?.kind==="line"&&o.speakerLabel===void 0?ye(this.host,o.character,o.qualifier):void 0;i?this.pendingPrompt={beat:i,...o?{shown:{...o,padAfter:o.padAfter??this.padOf(i.id),...a!==void 0?{speakerLabel:a}:{}}}:{}}:this.pendingPromptOwnerId=null}return n}enterSceneSetup(e){let t=this.host.bundle.scenes[e];if(!t)throw new Error(`unknown scene: ${e}`);this.currentSceneId=e,this.enter(e),this.seedScene(t),this.runEffects(t.onEntry,t.id)}enterChild(e){if(this.enter(e.id),e.type==="snippet"){this.beginSnippet(e);return}let t=e.selector??"run";if(t==="run"){this.stack.push({sceneId:this.currentSceneId,containerId:e.id,index:0});return}if(t==="choice"){this.setupChoice(e);return}let n=this.selectChild(e);n&&this.enterChild(n)}childrenOf(e){let t=this.host.blockById.get(e);if(t)return t.children;let n=this.host.nodeIndex.get(e);if(n&&n.type==="group")return n.children}beginSnippet(e){this.runEffects(e.onEnter,e.id),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],n=new Map,s=[];for(let o of e.children){if(o.fallback===!0){s.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o,"option"),c=o.secretUntilEligible===!0;!a&&c||(t.push({id:o.id,eligible:a,...o.gameData!==void 0?{gameData:o.gameData}:{}}),n.set(o.id,o))}if(t.some(o=>o.eligible)){this.host.tracing&&this.emit({type:"choice",group:e.id,options:t.map(o=>({id:o.id,eligible:o.eligible}))}),this.pendingChoice={groupId:e.id,options:t,byId:n,shown:new Map};return}let i=s.find(o=>this.eligible(o,"fallback"));if(i){this.enterChild(i);return}this.host.tracing&&this.emit({type:"dry",group:e.id}),this.host.onDryChoice?.(e.id),this.dryChoice=e.id}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(this.host.tracing&&this.emit({type:"jump",to:e,mode:t}),e==="END"){this.flowEnded=!0,this.stack=[];return}let n,s,i=this.host.bundle.scenes[e];if(i){this.enterSceneSetup(e);let a=i.blocks[0];if(!a){t==="jump"&&(this.stack=[]);return}n=e,s=a.id}else{let a=this.host.blockIndex.get(e);if(!a)throw new Error(`jump target not found: ${e}`);a.sceneId!==this.currentSceneId&&this.enterSceneSetup(a.sceneId),n=a.sceneId,s=e}this.enter(s);let o={sceneId:n,containerId:s,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.map(c=>({id:c.id,eligible:this.holds(c)})),n=e.children.filter((c,l)=>t[l].eligible),s=e.options?.order??"sequential",i=e.options?.exhaust??"once",o=c=>(this.host.tracing&&this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:i}:{},children:t,picked:c?.id??null}),c),a=null;if(n.length>0){let c=this.selectorState(e);switch(e.selector){case"branch":a=n[0];break;case"sequence":a=s==="shuffle"?this.pickShuffle(n,i,c):s==="specificity"?this.pickSpecificity(n,i,c):this.pickSequential(n,i,c);break;default:return null}}return this.host.steer?.pick&&(e.selector==="branch"||e.selector==="sequence")&&(a=this.steerPick(e,e.selector,t,a)),o(a)}steerPick(e,t,n,s){let i=s?.id??"",o=this.host.steer.pick({flow:this.id,group:e.id,selector:t,children:n.map(c=>({...c})),default:i});if(typeof o!="string")throw new Error(`steer: pick for ${e.id} answered ${String(o)}, not a child id or ""`);if(o===i)return s;let a=o===""?null:e.children.find(c=>c.id===o);if(a===void 0)throw new Error(`steer: pick for ${e.id} answered "${o}", which isn\'t one of its children`);return this.host.tracing&&this.emit({type:"steered",node:e.id,kind:"pick",default:i,answer:o}),a}pickSequential(e,t,n){let s=e.length,i=n.seq??0;return n.seq=i+1,t==="repeat"?e[i%s]:i<s?e[i]:t==="stick"?e[s-1]:null}pickShuffle(e,t,n){let s=e.length,i=t==="stick",o=()=>(i?e.slice(0,s-1):e).map(S=>S.id),a=new Set(e.map(S=>S.id));if(n.bag===void 0&&(n.bag=o()),!n.bag.some(S=>a.has(S))){if(t==="once")return null;if(i){let S=e[s-1];return n.last=S.id,S}if(n.bag=o(),n.bag.length===0)return null}let c=n.bag.filter(S=>a.has(S)),l=n.last!==void 0&&c.length>1?c.indexOf(n.last):-1,p=Math.floor(this.rng()*(l>=0?c.length-1:c.length));l>=0&&p>=l&&p++;let m=c[p];return n.bag.splice(n.bag.indexOf(m),1),n.last=m,e.find(S=>S.id===m)}pickSpecificity(e,t,n){let s=e;if(t!=="repeat"){n.bag===void 0&&(n.bag=e.map(p=>p.id));let l=new Set(n.bag);if(s=e.filter(p=>l.has(p.id)),s.length===0)return t==="stick"&&n.last!==void 0?e.find(p=>p.id===n.last)??null:null}let i=-1,a=s.map(l=>{let p=this.specScore(l);return p>i&&(i=p),{c:l,s:p}}).filter(l=>l.s===i).map(l=>l.c),c;if(a.length===1)c=a[0];else{let l=n.last!==void 0?a.findIndex(m=>m.id===n.last):-1,p=Math.floor(this.rng()*(l>=0?a.length-1:a.length));l>=0&&p>=l&&p++,c=a[p]}return t!=="repeat"&&(n.bag=n.bag.filter(l=>l!==c.id)),n.last=c.id,c}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0,e):0}matchedSpec(e,t,n){return $e(e,i=>{try{return kt(le(i,this.context(),Ce))}catch(o){return this.reportError("best-match",n.id,n.condition,o),!1}},{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,n=this.host.journal,s;if(n&&(s=e.shared?n.selectors:n.flowSelectors.get(this),s||(s=new Set,n.flowSelectors.set(this,s))),n&&s&&!s.has(e.id)){s.add(e.id);let o=t.get(e.id),a=o?{...o,...o.bag?{bag:[...o.bag]}:{}}:void 0;n.undo.push(()=>{a?t.set(e.id,a):t.delete(e.id)})}let i=t.get(e.id);return i||(i={},t.set(e.id,i)),i}runEffects(e,t){for(let n of e??[]){let s;try{s=this.evalExpr(n.value);let i=this.host.tracing?this.getProperty(n.target):void 0;this.writeProperty(n.target,s,!1),this.host.tracing&&this.emit({type:"write",target:n.target,value:s,...i!==void 0?{prev:i}:{}})}catch(i){this.reportError("effect",t,n.value,i)}}}holds(e){if(!e.condition)return!0;try{return kt(this.evalExpr(e.condition))}catch(t){return this.reportError("condition",e.id,e.condition,t),!1}}eligible(e,t){let n=this.holds(e),s=this.host.steer?.gate;if(!s||!e.condition)return n;let i=s({flow:this.id,node:e.id,where:t,source:e.condition.src??"",default:n});if(typeof i!="boolean")throw new Error(`steer: gate for ${e.id} answered ${String(i)}, not true or false`);return i!==n&&this.host.tracing&&this.emit({type:"steered",node:e.id,kind:"gate",default:n,answer:i}),i}reportError(e,t,n,s){let i=s instanceof Error?s.message:String(s),o=n?.src;this.report({flow:this.id,kind:e,node:t,...o?{source:o}:{},message:i})}report(e){this.host.onError(e),this.host.tracing&&this.emit({type:"diagnostic",kind:e.kind,node:e.node,...e.source?{source:e.source}:{},message:e.message})}evalExpr(e){return le(this.conditionAst(e),this.context(),Ce)}conditionAst(e){let t=gt.get(e);return t||(t=M(e.ast),gt.set(e,t)),t}enter(e){let t=this.visitCounts,n=t.get(e);t.set(e,(n??0)+1);let s=this.host.sharedVisits,i=s.get(e);s.set(e,(i??0)+1),this.host.journal&&this.host.journal.undo.push(()=>{n===void 0?t.delete(e):t.set(e,n),i===void 0?s.delete(e):s.set(e,i)})}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=Fe(this.rngState),t=e.next();return this.rngState=e.state(),t};beatResult(e){let t=j(this.host,e.id),n=t&&t.length?{tags:t}:{};switch(e.kind){case"gameEvent":return{type:"gameEvent",id:e.id,gameData:I(e.gameData),...T(e.extensions),...n};case"text":return{type:"text",id:e.id,text:this.interpolate(this.resolveString(e.id)),padAfter:this.padOf(e.id),...e.action?{action:!0}:{},...this.spokenOf(e),gameData:I(e.gameData),...T(e.extensions),...n};case"line":{let s=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=i&&a.length===0;return{type:"line",id:e.id,text:a,character:c?void 0:e.character,characterName:c?void 0:this.resolveCharacterName(e.character),direction:c?void 0:e.direction,qualifier:c?void 0:e.qualifier,qualifierName:c?void 0:this.resolveQualifierName(e.qualifier),speakerLabel:c?void 0:ye(this.host,e.character,e.qualifier),padAfter:this.padOf(e.id),...this.spokenOf(e),gameData:I(e.gameData),...T(e.extensions),...n}}}}interpolate(e){return Qe(e,t=>this.getProperty(t))}stripCaptions(e){return Je(e,this.host.captionOpen,this.host.captionClose)}captionLine(e){return this.host.captionsOn?e:this.stripCaptions(e)}spokenOf(e){let t=this.host.bundle.estimateSyllablesPerSecond??X,n=this.host.emitIds?void 0:this.host.defaultStrings[e.id];if(n===void 0)return{estimateRate:t};let s;return e.kind==="text"?s=this.interpolate(n):e.character===this.host.captionCharacter?s="":s=this.stripCaptions(this.host.bundle.voiced?n:this.interpolate(n)),{spokenText:s,spokenLocale:this.host.bundle.locales.default,estimateRate:t}}promptFor(e){let t=this.promptBeatOf(e);if(!t)return;let n=this.interpolate(this.resolveString(t.id)),s=this.padOf(t.id);return t.kind==="line"?{kind:"line",text:this.captionLine(n),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction,qualifier:t.qualifier,qualifierName:this.resolveQualifierName(t.qualifier),speakerLabel:ye(this.host,t.character,t.qualifier),padAfter:s}:{kind:"text",text:n,padAfter:s}}authoredPromptOf(e){return e.type==="group"?e.prompt:void 0}promptResult(e,t){let n=j(this.host,e.id),s=n&&n.length?{tags:n}:{};return t.kind==="text"?{type:"text",id:e.id,text:t.text,padAfter:this.padOf(e.id),...this.spokenOf(e),gameData:I(e.gameData),...T(e.extensions),...s}:{type:"line",id:e.id,text:t.text,character:t.character,characterName:t.characterName,direction:t.direction,qualifier:t.qualifier,qualifierName:t.qualifierName,speakerLabel:t.speakerLabel,padAfter:this.padOf(e.id),...this.spokenOf(e),gameData:I(e.gameData),...T(e.extensions),...s}}promptBeatOf(e){return e.type==="group"&&e.prompt?e.prompt:((e.type==="snippet"?e:this.firstTextSnippetIn(e.children))?.beats??[]).find(n=>n.kind==="line"||n.kind==="text")}firstTextSnippetIn(e){let t;return L(e,n=>{!t&&n.type==="snippet"&&(n.beats??[]).some(s=>s.kind==="line"||s.kind==="text")&&(t=n)}),t}resolveString(e){if(this.host.emitIds)return e;let t=this.host.strings[e];if(t!==void 0)return t;let n=this.host.defaultStrings[e];return n!==void 0?`<Untranslated: ${e}> ${n}`:e}resolveCharacterName(e){if(e===void 0||this.host.emitIds)return;let t=xe(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}padOf(e){return this.host.padIndex.get(e)?.resolved??G}resolveQualifierName(e){if(e===void 0||this.host.emitIds)return;let t=me(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.qualifierDisplay.get(e)}splitRef(e){return Bt(this.host,e)}newLocal(){return new P(this.host.patterLocalDecls,{pathPrefix:"@patter."})}mountLocal(){this.local=this.newLocal();let e=C.flowGlobals(this.id);this.host.registry.mountOwned(e,this.local,{owner:re}),this.registered.add(e),this.host.reportRefits()}releaseBags(e){for(let t of this.registered)this.host.registry.remove(t,{keep:e});this.registered.clear(),this.sceneBags.clear()}sceneBagFor(e,t){if(this.host.bundle.scenes[e])return this.ensureSceneBags(e),this.host.sceneSharedNames.get(e)?.has(t.toLowerCase())?this.host.stageBags.get(e):this.sceneBags.get(e)}ensureSceneBags(e){let t=this.host.sceneSharedNames.get(e)??new Set,n=this.host.bundle.scenes[e]?.sceneProps??[],s=this.host.journal,i=!this.sceneBags.has(e)||!this.host.stageBags.has(e);if(!this.sceneBags.has(e)){let o=new P(n.filter(l=>!t.has(l.name.toLowerCase())),{pathPrefix:"@scene."}),a=C.flowScene(this.id,e),c=wt(this.host.registry,a,o,s!==null);this.registered.add(a),this.sceneBags.set(e,o),s&&s.undo.push(()=>{this.sceneBags.get(e)===o&&(this.host.registry.remove(a,c?{keep:!0}:void 0),this.registered.delete(a),this.sceneBags.delete(e))})}if(!this.host.stageBags.has(e)){let o=new P(n.filter(c=>t.has(c.name.toLowerCase())),{pathPrefix:"@scene."}),a=wt(this.host.registry,C.stage(e),o,s!==null);this.host.stageBags.set(e,o),s&&s.undo.push(()=>{this.host.stageBags.get(e)===o&&(this.host.registry.remove(C.stage(e),a?{keep:!0}:void 0),this.host.stageBags.delete(e))})}i&&this.host.reportRefits()}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set;this.ensureSceneBags(e.id);for(let n of e.sceneProps??[]){if(!n.temporary)continue;let s=n.name.toLowerCase(),i=t.has(s)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);if(!i)continue;let o=this.host.journal?i.get(s):void 0;o!==void 0&&this.host.journal.undo.push(()=>i.set(s,o)),i.set(s,U(n))}}};function Et(r,e){L(r,t=>{if(t.type==="group"){t.prompt?.kind==="line"&&t.prompt.character&&e.add(t.prompt.character);return}for(let n of t.beats??[])n.kind==="line"&&n.character&&e.add(n.character)})}function ye(r,e,t,n=!1){if(!e||r.emitIds)return;let s=c=>(n?void 0:r.strings[c])??r.defaultStrings[c],i=s(xe(e))??r.castDisplay.get(e)??e;if(t===void 0)return i;let o=r.speakerLabels.get(`${e}\\0${t}`);if(o!==void 0)return s(ot(e,t))??o;let a=s(me(t))??r.qualifierDisplay.get(t)??t;return lt(s(at)??r.speakerPattern,i,a)}function bt(r){return r&&Object.keys(r).length?{gameData:I(r)}:{}}function T(r){return r&&Object.keys(r).length?{extensions:r}:{}}function Sn(r){let e={kind:r.kind,text:r.text};return r.character!==void 0&&(e.character=r.character),r.characterName!==void 0&&(e.characterName=r.characterName),r.direction!==void 0&&(e.direction=r.direction),r.qualifier!==void 0&&(e.qualifier=r.qualifier),r.qualifierName!==void 0&&(e.qualifierName=r.qualifierName),r.speakerLabel!==void 0&&(e.speakerLabel=r.speakerLabel),typeof r.padAfter=="number"&&(e.padAfter=r.padAfter),e}function At(r){let e={};for(let[t,n]of r){let s={};n.seq!==void 0&&(s.seq=n.seq),n.bag&&(s.bag=[...n.bag]),n.last!==void 0&&(s.last=n.last),e[t]=s}return e}function Dt(r){let e=new Map;for(let[t,n]of Object.entries(r??{})){let s={};n.seq!==void 0&&(s.seq=n.seq),n.bag&&(s.bag=[...n.bag]),n.last!==void 0&&(s.last=n.last),e.set(t,s)}return e}function wt(r,e,t,n){let s=n?JSON.stringify(t.save()):"";return r.mountOwned(e,t,{owner:re}),n&&JSON.stringify(t.save())!==s}function vt(r){return{name:r.name,type:r.type,values:r.values,stages:r.stages,default:r.default}}var yn=new Set(["rng","seed","locale","hostScopes","registry","replayPromptOnChoose","closedCaptions","onDryChoice","steer","onError","onRefit","log"]);function En(r,e){if(r==null)return;let t=r;if(typeof r=="object"&&(t.gate===void 0||typeof t.gate=="function")&&(t.pick===void 0||typeof t.pick=="function"))return r;e.push({node:"steer",message:`the engine option "steer" isn\'t a steerer (an object with gate and pick methods), so it\'s ignored`})}function Ne(r,e){let t=r.locales.default;if(e===void 0)return{locale:t,table:t};if(r.localisation?.mode==="ids")return{locale:e,table:e};let n=[...new Set([t,...r.locales.included,...Object.keys(r.strings)])];if(n.includes(e))return{locale:e,table:e};let s=c=>c.toLowerCase().replace(/_/g,"-"),i=n.find(c=>s(c)===s(e));if(i!==void 0)return{locale:i,table:i,problem:`the locale "${e}" is spelled "${i}" in this bundle, so it\'s using "${i}"`};let o=s(e).split("-")[0],a=n.find(c=>s(c)===o);return a!==void 0?{locale:a,table:a,problem:`this bundle has no locale "${e}", so it\'s using its language, "${a}"`}:{locale:t,problem:`this bundle has no locale "${e}", so it\'s using the default, "${t}", with every string marked untranslated`}}function Ft(r,e){return e.table!==void 0?r[e.table]??{}:{}}function Ct(r,e,t,n,s){let i=c=>c?.find(l=>l.name.toLowerCase()===t),o;if(e==="patter")o=i(r.bundle.properties);else if(e==="scene")o=i(s!==null?r.bundle.scenes[s]?.sceneProps:void 0);else{let c=r.bundle.scopeRegistry?.scopes.find(l=>l.token===e);if(!c||c.declarations===void 0)return;o=i(c.declarations)}let a=`@${e}.${t}`;if(o===void 0)throw new Error(`no property at "${a}": the content declares no ${a}`);if(!Q(o,n,{noneChosen:o.type==="enum"&&o.default===""}))throw new Error(`"${a}" takes ${bn(o)}; ${JSON.stringify(n)} doesn\'t fit`)}function bn(r){let e=t=>(t??[]).map(n=>JSON.stringify(n)).join(", ");switch(r.type){case"number":return"a number";case"boolean":return"true or false";case"enum":return`one of ${e(r.values)}`;case"flags":return r.values!==void 0&&r.values.length>0?`a list of flags from ${e(r.values)}`:"a list of flags";case"quality":return`one of its stages ${e(r.stages)}`;default:return"text"}}function se(r,e,t){let n=r.qualityLadders.get(e);if(!n){n=new Map;for(let s of t()??[]){let i=s.name.toLowerCase();s.type==="quality"&&s.stages&&!n.has(i)&&n.set(i,s.stages)}r.qualityLadders.set(e,n)}return n}function wn(r,e,t){let n=t.toLowerCase();return e==="patter"?se(r,"patter",()=>[...r.patterSharedDecls,...r.patterLocalDecls]).get(n):r.registry.toEvalContext().qualities?.(e,t)??se(r,`host/${e}`,()=>r.bundle.scopeRegistry?.scopes.find(s=>s.token===e)?.declarations).get(n)}function It(r){return{name:r.name,type:r.type,values:r.values,stages:r.stages,default:r.default,writable:r.writable}}function vn(r,e){let t=It(r),n=r.writable??e;return n===void 0?t:{...t,writable:n}}function Pe(r,e){return he(r.bundle.scenes,e,r.sceneGameIdToId)}function Le(r,e,t){return r.blockGameIdToId.get(e)?.get(t)??(r.blockIndex.get(t)?.sceneId===e?t:void 0)}function Bt(r,e){r.refSplitRevision!==r.registry.revision&&(r.refSplitCache.clear(),r.refSplitRevision=r.registry.revision);let t=r.refSplitCache.get(e);return t||(t=We(e,n=>n==="scene"||r.registry.has(n)||(r.bundle.externalScopes?.includes(n)??!1)),r.refSplitCache.set(e,t)),t}function Fn(r,e){let t={};e.scopes?.patter&&(t[C.flowGlobals(r)]=e.scopes.patter);for(let[n,s]of Object.entries(e.sceneBags??{}))t[C.flowScene(r,n)]=s;return t}function kn(r,e){let t={scopes:{},sceneBags:{}},n=C.flow(r);for(let[s,i]of Object.entries(e)){if(!s.startsWith(n))continue;let o=s.slice(n.length);o==="patter"?t.scopes.patter=i:o.startsWith("scene/")&&(t.sceneBags[mn(o.slice(6))]=i)}return t}function kt(r){return typeof r=="boolean"?r:typeof r=="number"?r!==0:typeof r=="string"?r!=="":r.length>0}var An=(r,e)=>r.shared??e;function Te(r,e){return{name:r.name,type:r.type,hasDefault:r.default!==void 0,...r.default!==void 0?{default:r.default}:{},shared:An(r,e)}}function Dn(r){return{name:r.name,type:r.type,hasDefault:r.default!==void 0,...r.values?{values:[...r.values]}:{},...r.purpose?{purpose:r.purpose}:{}}}function Cn(r,e){e.blocks++;let t=[...r.children];for(;t.length;){let n=t.pop();if(n.type==="group"){e.groups++,n.prompt&&e.prompts++,t.push(...n.children);continue}e.snippets++;for(let s of n.beats??[])e.beats++,s.kind==="gameEvent"&&e.gameEvents++}}function Rt(r){let e={scenes:0,blocks:0,groups:0,snippets:0,beats:0,prompts:0,gameEvents:0,cast:r.cast?.length??0},t=[],n=[];for(let o of Object.values(r.scenes)){e.scenes++;let a=k(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(c=>({gameId:k(c),name:c.name}))});for(let c of o.blocks)Cn(c,e);o.sceneProps?.length&&n.push({gameId:a,properties:o.sceneProps.map(c=>Te(c,!1))})}let s=(r.scopeRegistry?.scopes??[]).map(o=>({token:o.token,writable:o.writable??!0,opaque:o.declarations===void 0,properties:(o.declarations??[]).map(a=>Te(a,!0))})),i=Object.entries(r.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(Dn)}));return{identity:{schema:r.schema,project:r.content.project,...r.content.version!==void 0?{version:r.content.version}:{},...r.content.hash!==void 0?{hash:r.content.hash}:{},...r.content.structureHash!==void 0?{structureHash:r.content.structureHash}:{},voiced:r.voiced,defaultLocale:r.locales.default,locales:[...r.locales.included],localisation:r.localisation?.mode??"embedded",sourceDebug:r.localisation?.sourceDebug??!1},addresses:t,hostScopes:s,properties:{patter:(r.properties??[]).map(o=>Te(o,!0)),scene:n},gameData:i,counts:e}}var oe=(r,e)=>Object.prototype.hasOwnProperty.call(r,e);function Ot(r,e){return r.gameDataFields?.[e]??[]}function Me(r,e,t){return e&&oe(e,t)?e[t]:r.find(n=>n.name===t)?.default}function Nt(r,e){let t={};for(let n of r){let s=Me(r,e,n.name);s!==void 0&&(t[n.name]=s)}for(let[n,s]of Object.entries(e??{}))oe(t,n)||(t[n]=s);return t}function Pt(r,e,t){let n=r.extensions!==void 0&&oe(r.extensions,e)?r.extensions[e]:void 0;return n!==void 0&&oe(n.fields,t)?n.fields[t]??[]:[]}function Lt(r,e,t=""){let n=o=>({...o?.extensions??{}}),s=Object.values(r.scenes??{}),i=o=>(oe(r.scenes??{},o)?r.scenes[o]:void 0)??s.find(a=>k(a)===o);switch(e){case"project":{let o={};for(let[a,c]of Object.entries(r.extensions??{}))c.project!==void 0&&(o[a]=c.project);return o}case"scene":return n(i(t));case"block":{let o=t.indexOf("/");if(o<0)return{};let a=i(t.slice(0,o))?.blocks??[],c=t.slice(o+1);return n(a.find(l=>l.id===c)??a.find(l=>k(l)===c))}case"snippet":case"option":case"line":case"text":case"gameEvent":{let o,a=(c,l)=>{for(let p of c??[]){if(o!==void 0)return;if(p.type==="group"){if(l&&p.id===t&&e==="option"){o=p;return}if(l&&p.prompt?.id===t&&p.prompt.kind===e){o=p.prompt;return}a(p.children??[],p.selector==="choice");continue}if(p.id===t&&e==="snippet"){o=p;return}let m=(p.beats??[]).find(S=>S.id===t);if(m!==void 0){m.kind===e&&(o=m);return}}};for(let c of s)for(let l of c.blocks??[])o===void 0&&a(l.children??[],!1);return n(o)}default:return{}}}return qt(In);})();\n';
2708
2708
 
2709
2709
  // src/play-timeline.ts
2710
2710
  function createTimeline(defaultPad) {
@@ -2771,7 +2771,8 @@ var PLAYER_JS = String.raw`
2771
2771
  function esc(s) { return String(s == null ? "" : s).replace(/[&<>]/g, function (c) { return { "&": "&amp;", "<": "&lt;", ">": "&gt;" }[c]; }); }
2772
2772
 
2773
2773
  // Pacing (line padding): a source-only reader carries no audio, so each line is timed by Patter's own rule
2774
- // for a line with no recording (estimateLineDuration, from the runtime), and the step's padAfter
2774
+ // for a line with no recording (estimateLineDuration, from the runtime: the line as spoken in the project's main
2775
+ // language, at its rate, whatever language the page shows), and the step's padAfter
2775
2776
  // says when the next one starts: after a pause, at once, or cutting in before this one ends. The player
2776
2777
  // rules are play-timeline.ts's, inlined below by their source: the first line starts at once, as does the
2777
2778
  // reply to a choice; a cut-in never starts before the line it cuts into; a game event is never held here,
@@ -2917,7 +2918,7 @@ var PLAYER_JS = String.raw`
2917
2918
  if (s.type === "choice") { renderChoice(s); return; }
2918
2919
  // Action text (a direction for whoever stages the scene, never shown to the player) takes no time of its
2919
2920
  // own, only its pause, and reads as a direction.
2920
- timeline.place(s, s.action ? 0 : estimate(s.text));
2921
+ timeline.place(s, s.action ? 0 : estimate(s.spokenText != null ? s.spokenText : s.text, s.spokenLocale, s.estimateRate));
2921
2922
  if (s.type === "line") {
2922
2923
  // The speaker's label as the runtime resolved it (TAM (O.S.), or a pair's own label): this page never
2923
2924
  // puts a name and a qualifier together itself. (Its bundle always carries the strings, so a line with a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patterkit/ops",
3
- "version": "0.26.1",
3
+ "version": "0.26.3",
4
4
  "description": "The shared operations layer: every project operation (load, validate, export, format, play, ...) as a pure function, consumed by the patter CLI and Patterpad alike.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -33,11 +33,11 @@
33
33
  "@fontsource/noto-sans": "^5.3.0",
34
34
  "@fontsource/noto-sans-math": "^5.3.0",
35
35
  "@ibm/plex-mono": "1.0.0",
36
- "@patterkit/compiler": "0.15.2",
37
- "@patterkit/core": "0.11.0",
38
- "@patterkit/dialect": "0.2.20",
39
- "@patterkit/model": "0.23.0",
40
- "@patterkit/runtime": "0.38.0",
36
+ "@patterkit/compiler": "0.16.0",
37
+ "@patterkit/core": "0.12.0",
38
+ "@patterkit/dialect": "0.2.21",
39
+ "@patterkit/model": "0.24.0",
40
+ "@patterkit/runtime": "0.40.0",
41
41
  "@wildwinter/expr": "^0.6.0",
42
42
  "@wildwinter/toolkit": "^0.4.0",
43
43
  "@xmldom/xmldom": "^0.8.15",