@konoui/mjimage 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +10 -10
- package/dist/index.d.cts +22 -43
- package/dist/index.d.ts +22 -43
- package/dist/index.js +602 -610
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Ze="MS Gothic, sans-serif",rt={WIDTH:66,HEIGHT:90,TEXT_SCALE:.8,BLOCK_MARGIN_SCALE:.3},Ce={WIDTH:125,HEIGHT:27.5},Bn={BASE:40},V=",",p={M:"m",P:"p",S:"s",Z:"z",BACK:"_"},g={TSUMO:"t",RON:"v",IMAGE_DORA:"d",HORIZONTAL:"-",RED:"r",COLOR_GRAYSCALE:"^"},E={PON:"pon",CHI:"chi",SHO_KAN:"shokan",DAI_KAN:"daikan",AN_KAN:"ankan",TSUMO:"tsumo",PAIR:"pair",ISOLATED:"isolated",THREE:"three",RUN:"run",HAND:"hand",IMAGE_DORA:"dora",IMAGE_DISCARD:"simple-discard",UNKNOWN:"unknown"},_={E:"1z",S:"2z",W:"3z",N:"4z"},k={E1:"1z1",E2:"1z2",E3:"1z3",E4:"1z4",S1:"2z1",S2:"2z2",S3:"2z3",S4:"2z4",W1:"3z1",W2:"3z2",W3:"3z3",W4:"3z4",N1:"4z1",N2:"4z2",N3:"4z3",N4:"4z4"},ye={[_.E]:"東",[_.S]:"南",[_.W]:"西",[_.N]:"北"},Ye={[k.E1]:"東1局",[k.E2]:"東2局",[k.E3]:"東3局",[k.E4]:"東4局",[k.S1]:"南1局",[k.S2]:"南2局",[k.S3]:"南3局",[k.S4]:"南4局",[k.W1]:"西1局",[k.W2]:"西2局",[k.W3]:"西3局",[k.W4]:"西4局",[k.N1]:"北1局",[k.N2]:"北2局",[k.N3]:"北3局",[k.N4]:"北4局"};function I(s,t){if(!s)throw new Error(t)}class Ws{ctx=null;strText;numText;constructor(t="東",e="2"){this.strText=t,this.numText=e}measure=(t,e)=>{this.ctx==null&&(this.ctx=document.createElement("canvas").getContext("2d"),I(this.ctx,"context is null"));const n=this.ctx;n.font=e;const i=n.measureText(t);let r=i.width,o=i.actualBoundingBoxAscent+i.actualBoundingBoxDescent;return[r,o]};measureFontContext=(t,e)=>{const n={family:t,size:e},i=`${n.size}px ${n.family}`,[r,o]=this.measure(this.strText,i),[a,c]=this.measure(this.numText,i);return{font:{family:t,size:e},textWidth:r,textHeight:o,numWidth:a,numHeight:c}};measureTableFontContext=t=>{const e=this.measureFontContext(Ze,Bn.BASE*t);return e.textHeight=e.textWidth,e.numHeight=e.numWidth,e}}class Ds{input;position;nextPosition;char;eof="\0";constructor(t){this.input=t,this.position=0,this.nextPosition=0,this.char=this.readChar()}readChar(){return this.nextPosition>=this.input.length?(this.char=this.eof,this.char):(this.char=this.input[this.nextPosition],this.position=this.nextPosition,this.nextPosition++,this.char)}peekChar(){return this.nextPosition>=this.input.length?this.eof:this.input[this.nextPosition]}peekCharN(t){if(t<0)throw new Error("arg must be positive value");return this.position+t>=this.input.length?this.eof:this.input[this.position+t]}prevChar(){return this.position>=this.input.length?this.eof:this.position>0?this.input[this.position-1]:this.eof}skipWhitespace(){for(;this.isWhitespace(this.char);)this.readChar()}isWhitespace(t){return/\s/.test(t)}}const Qt=(s,t)=>{if(s.t==t.t){if(S(s)&&S(t)){if(s.has(g.RED))return-1;if(t.has(g.RED))return 1}return s.n-t.n}const e=[p.M,p.P,p.S,p.Z,p.BACK];return e.indexOf(s.t)-e.indexOf(t.t)},Ls=(s,t)=>{const e=[g.HORIZONTAL,g.TSUMO,g.RON,g.IMAGE_DORA,g.COLOR_GRAYSCALE,g.RED];return e.indexOf(s)-e.indexOf(t)},Wn=s=>{const t=[];s.forEach((n,i)=>{n.has(g.HORIZONTAL)&&t.push(i)});const e=s.filter(n=>!n.has(g.HORIZONTAL)).sort(Qt);return t.forEach(n=>{e.splice(n,0,s[n])}),e};function S(s){return s.isNum()&&s.n==5}function Ks(s){const t=Object.values(p).find(e=>e===s);return t?[t,!0]:[p.BACK,!1]}class y{constructor(t,e,n=[]){this.t=t,this.n=e,this.ops=n}static from(t){const e=new D(t).tiles();if(e.length!=1)throw new Error(`input must be a single tile: ${t}`);return e[0]}toString(){return this.t===p.BACK?this.t:`${[...this.ops].sort(Ls).join("")}${this.n}${this.t}`}toJSON(){return this.toString()}clone(t){const e=t?.t??this.t,n=t?.n??this.n,i=t?.removeAll?[]:this.ops.filter(o=>Array.isArray(t?.remove)?!t.remove.includes(o):t?.remove!=o),r=new Set([...i]);return t?.add&&(Array.isArray(t.add)?t.add.forEach(o=>r.add(o)):r.add(t.add)),new y(e,n,Array.from(r))}has(t){return this.ops.includes(t)}isNum(){return this.t==p.M||this.t==p.P||this.t==p.S}equals(t){return t.t==p.BACK&&this.t==p.BACK?!0:this.t==t.t&&this.n==t.n}}class N{_tiles;_type;constructor(t,e){if(this._tiles=t,this._type=e,this.isCalled()){this._tiles=Wn(this._tiles);return}if(this._type!=E.IMAGE_DISCARD){this._tiles=[...this._tiles].sort(Qt);return}}static from(t){const e=new D(t,{enableImplicitTsumoBlock:!1}).parse();if(e.length!=1)throw new Error(`expected exactly 1 block but got ${e.length}: ${t}`);return e[0]}static deserialize(t){const e=N.from(t.tiles),n=e.type;if(!(t.type==E.PAIR||t.type==E.ISOLATED||t.type==E.THREE||t.type==E.RUN)&&n!=t.type)throw new Error(`"expected type ${t.type} but got ${n}: ${t.tiles}`);return ce(e.tiles,t.type)}serialize(){return{tiles:this.toString(),type:this.type}}toJSON(){return this.serialize()}get type(){return this._type}get tiles(){return this._tiles}is(t){return this._type==t}isCalled(){switch(this._type){case E.PON:case E.CHI:case E.DAI_KAN:case E.SHO_KAN:case E.AN_KAN:return!0;default:return!1}}clone(t){const e=t?.replace,n=[...this.tiles];return e&&(n[e.idx]=e.tile),ce(n,this._type)}}const vt=s=>s[0].t===p.BACK?s.join(""):`${s.map(e=>e.toString().slice(0,-1)).join("")}${s[0].t}`,Ve=s=>{if(s.length==0)return"";let t=s[0].t,e="";for(const i of s){const r=i.t,o=r==p.BACK?i.toString():i.toString().slice(0,-1);r!=t&&t!=p.BACK&&(e+=t),t=r,e+=o}const n=s.at(-1);return n.t!=p.BACK&&(e+=n.t),e};class F extends N{constructor(t){super(t,E.CHI)}static from(t){return N.deserialize({tiles:t,type:E.CHI})}toString(){return vt(this.tiles)}}class U extends N{constructor(t){super(t,E.PON)}static from(t){return N.deserialize({tiles:t,type:E.PON})}toString(){return vt(this.tiles)}}class R extends N{constructor(t){const e=t.filter(i=>i.t!=p.BACK),n=e[0];if(e.length<t.length){if(S(n)){const i=new y(n.t,5);super([i.clone({add:g.RED}),i,i,i],E.AN_KAN);return}super([n,n,n,n],E.AN_KAN);return}super(t,E.AN_KAN)}get tiles(){return super.tiles}get tilesWithBack(){const t=this.tiles[0].clone({remove:g.RED}),e=S(t)?t.clone({add:g.RED}):t;return[new y(p.BACK,0),e,t,new y(p.BACK,0)]}static from(t){return N.deserialize({tiles:t,type:E.AN_KAN})}toString(){return Ve(this.tilesWithBack)}}class K extends N{constructor(t){super(t,E.DAI_KAN)}static from(t){return N.deserialize({tiles:t,type:E.DAI_KAN})}toString(){return vt(this.tiles)}}class M extends N{constructor(t){super(t,E.SHO_KAN)}static from(t){return N.deserialize({tiles:t,type:E.SHO_KAN})}static fromPon(t,e){const n=t.tiles.findIndex(r=>r.has(g.HORIZONTAL)),i=[...t.tiles];return i.splice(n,0,e.clone({add:g.HORIZONTAL})),new M(i)}toString(){return vt(this.tiles)}}class C extends N{constructor(t,e){super([t,e],E.PAIR)}toString(){return vt(this.tiles)}static from(t){return N.deserialize({tiles:t,type:E.PAIR})}}class L extends N{constructor(t){super(t,E.THREE)}static from(t){return N.deserialize({tiles:t,type:E.THREE})}toString(){return vt(this.tiles)}}class nt extends N{constructor(t){super(t,E.RUN)}static from(t){return N.deserialize({tiles:t,type:E.RUN})}toString(){return vt(this.tiles)}}class Je extends N{constructor(t){super([t],E.ISOLATED)}static from(t){return N.deserialize({tiles:t,type:E.ISOLATED})}toString(){return this.tiles[0].toString()}}class _t extends N{constructor(t){super(t,E.HAND)}static from(t){return N.deserialize({tiles:t,type:E.HAND})}toString(){return Ve(this.tiles)}}class we extends N{constructor(t,e){super(t,e)}toString(){return this.is(E.IMAGE_DISCARD)?this.tiles.join(""):Ve(this.tiles)}}const ce=(s,t)=>{switch(t){case E.CHI:const e=s.find(i=>i.has(g.HORIZONTAL));I(e!=null,`chi block does not have horizontal ops: ${s}`);const n=s.filter(i=>!i.has(g.HORIZONTAL));return new F([e,n[0],n[1]]);case E.PON:return new U([s[0],s[1],s[2]]);case E.AN_KAN:return new R(s);case E.DAI_KAN:return new K(s);case E.SHO_KAN:return new M(s);case E.THREE:return new L(s);case E.RUN:return new nt(s);case E.PAIR:return new C(s[0],s[1]);case E.ISOLATED:return new Je(s[0]);case E.HAND:return new _t(s);default:return new we(s,t)}};class D{constructor(t,e={enableImplicitTsumoBlock:!0}){this.input=t,this.options=e,this.input=t.replace(/\s/g,"")}maxInputLength=600;parse(){const t=this.tileSeparators();return this.makeBlocks(t)}tiles(){return this.tileSeparators().filter(t=>t!=V)}tileSeparators(){const t=new Ds(this.input),e=[];let n=[];for(this.validate(this.input);;){t.skipWhitespace();const i=t.char;if(i===t.eof)break;if(i==V){e.push(V),t.readChar();continue}const[r,o]=wn(i,n);if(o){if(r==p.BACK){e.push(new y(r,0)),t.readChar();continue}e.push(...Us(n,r)),n=[],t.readChar();continue}else{const[a,c]=js(t);if(c){n.push(a),t.readChar();continue}const[l,h]=Dn(i);if(!h)throw new Error(`expected a number but got: ${i}`);n.push({n:l})}t.readChar()}if(n.length>0)throw new Error(`unexpected remaining values: ${n.toString()}`);return this.options.enableImplicitTsumoBlock?this.reconstruct(e):e}reconstruct(t){if(t.length>18)return t;const e=t.findIndex(a=>a instanceof y&&a.has(g.TSUMO));if(e<0)return t;const n=t.findIndex(a=>a===V);if(n>-1&&e>n)return t;const i=n<0?t.length:n,r=t.slice(0,i),o=r[e];return r.some(a=>a instanceof y&&a.has(g.HORIZONTAL))?t:[...r.slice(0,e),...r.slice(e+1,i),V,o,...t.slice(i)]}makeBlocks(t){let e=[];const n=[];if(t.length==0)return n;for(const o of t){if(o==V){const a=yn(e),c=ce(e,a);n.push(c),e=[];continue}e.push(o)}const i=yn(e),r=ce(e,i);return n.push(r),e=[],n}validate(t){if(t.length==0)return;if(t.length>this.maxInputLength)throw new Error(`exceeded maximum input length (${t.length})`);const e=t.charAt(t.length-1),[n,i]=wn(e,[new y(p.BACK,1)]);if(!i)throw new Error(`last character must be a tile type: ${e} in ${t}`)}}function yn(s){if(s.length===0)return E.UNKNOWN;if(s.length===1)return s[0].has(g.IMAGE_DORA)?E.IMAGE_DORA:s[0].has(g.TSUMO)?E.TSUMO:E.HAND;const t=s.every(r=>r.equals(s[0])),e=s.filter(r=>r.has(g.HORIZONTAL)).length,n=s.filter(r=>r.has(g.TSUMO)||r.has(g.IMAGE_DORA)).length,i=s.filter(r=>r.t==p.BACK).length;if(n>0)return E.UNKNOWN;if(e==0&&i==0)return E.HAND;if(s.length===3&&i===0)return t?E.PON:e==1&&zs(s)?E.CHI:E.IMAGE_DISCARD;if(s.length==4&&i==2)return E.AN_KAN;if(s.length==4&&t){if(e==1)return E.DAI_KAN;if(e==2)return E.SHO_KAN}return e==1||n==0?E.IMAGE_DISCARD:E.UNKNOWN}function zs(s){const t=[...s].sort(Qt);if(t.some(n=>t[0].t!=n.t))return!1;const e=t.map(n=>n.n);for(let n=0;n<e.length-1;n++)if(e[n]!=e[n+1]-1)return!1;return!0}function Us(s,t){return s.map(e=>{let n=new y(t,e.n,e.ops);return n.isNum()&&n.n==0&&(n=n.clone({n:5,add:g.RED})),n})}function wn(s,t){const[e,n]=Ks(s);if(n)return[e,!0];if((s==="w"||s==="d")&&t.length>0){for(let r=0;r<t.length;r++){const o=t[r];s==="d"&&(t[r].n=o.n+4)}return[p.Z,!0]}return[p.BACK,!1]}function Dn(s){const t=Number(s),e=0<=t&&t<=9;return[t,e]}function js(s){const t=Object.values(g);if(!t.includes(s.char))return[new y(p.BACK,0),!1];const e=[];for(let n=0;n<4;n++){const i=s.peekCharN(n);if(t.includes(i))e.push(i);else{const[r,o]=Dn(i);if(!o)break;for(const c of e)s.readChar();const a=new y(p.BACK,r,e);if(a.has(g.RED)&&a.n!=5)throw new Error(`red dora operator can only be used with 5, got: ${r}`);if(a.has(g.IMAGE_DORA)&&a.has(g.TSUMO))throw new Error("cannot specify both dora and tsumo operators");return[a,!0]}}return[new y(p.BACK,0),!1]}function H(s,t=!1){const e={[_.E]:s,[_.S]:s,[_.W]:s,[_.N]:s};if(t)for(let n of Object.values(_))e[n]=structuredClone(s);return e}const Vt=s=>{let t=s.substring(0,2),e=Number(s.substring(2,3));return e==4?(e=1,t=bt(t)):e++,`${t}${e}`},Fs=s=>Vt(Vt(Vt(s))),Ln=s=>s.substring(0,2),bt=s=>{let t=Number(s.toString()[0]);return t=t%4+1,`${t}${p.Z}`},Ee=s=>{let t=Number(s.toString()[0]);const e=[1,4,3,2],n=e.indexOf(t);return`${e[(n+1)%e.length]}${p.Z}`},Re=(s,t,e)=>{const n=Math.abs(Number(s[0])-Number(t[0]));return I(n==1||n==2||n==3),e==E.PON?n==3?0:n==2?1:2:n==3?0:n==1?3:2};function En(s){return typeof s>"u"}function Me(s,t=0){return{a:1,c:0,e:s,b:0,d:1,f:t}}function Xe(...s){s=Array.isArray(s[0])?s[0]:s;const t=(e,n)=>({a:e.a*n.a+e.c*n.b,c:e.a*n.c+e.c*n.d,e:e.a*n.e+e.c*n.f+e.e,b:e.b*n.a+e.d*n.b,d:e.b*n.c+e.d*n.d,f:e.b*n.e+e.d*n.f+e.f});switch(s.length){case 0:throw new Error("no matrices provided");case 1:return s[0];case 2:return t(s[0],s[1]);default:{const[e,n,...i]=s,r=t(e,n);return Xe(r,...i)}}}function Gs(...s){return Xe(...s)}const{cos:Zs,sin:Ys,PI:Vs}=Math;function Js(s,t,e){const n=Zs(s),i=Ys(s),r={a:n,c:-i,e:0,b:i,d:n,f:0};return En(t)||En(e)?r:Xe([Me(t,e),r,Me(-t,-e)])}function Xs(s,t=void 0,e=void 0){return Js(s*Vs/180,t,e)}function qs(s){return Qs(s)}function Qs(s){return`matrix(${s.a},${s.b},${s.c},${s.d},${s.e},${s.f})`}const Kn=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",ti=Kn+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040",ei="["+Kn+"]["+ti+"]*",ni=new RegExp("^"+ei+"$");function zn(s,t){const e=[];let n=t.exec(s);for(;n;){const i=[];i.startIndex=t.lastIndex-n[0].length;const r=n.length;for(let o=0;o<r;o++)i.push(n[o]);e.push(i),n=t.exec(s)}return e}const _e=function(s){const t=ni.exec(s);return!(t===null||typeof t>"u")};function si(s){return typeof s<"u"}const ii={allowBooleanAttributes:!1,unpairedTags:[]};function ri(s,t){t=Object.assign({},ii,t);const e=[];let n=!1,i=!1;s[0]==="\uFEFF"&&(s=s.substr(1));for(let r=0;r<s.length;r++)if(s[r]==="<"&&s[r+1]==="?"){if(r+=2,r=bn(s,r),r.err)return r}else if(s[r]==="<"){let o=r;if(r++,s[r]==="!"){r=An(s,r);continue}else{let a=!1;s[r]==="/"&&(a=!0,r++);let c="";for(;r<s.length&&s[r]!==">"&&s[r]!==" "&&s[r]!==" "&&s[r]!==`
|
|
2
|
-
`&&s[r]!=="\r";r++)c+=s[r];if(c=c.trim(),c[c.length-1]==="/"&&(c=c.substring(0,c.length-1),r--),!
|
|
3
|
-
`||s==="\r"}function bn(s,t){const e=t;for(;t<s.length;t++)if(s[t]=="?"||s[t]==" "){const n=s.substr(e,t-e);if(t>5&&n==="xml")return v("InvalidXml","XML declaration allowed only at the start of the document.",P(s,t));if(s[t]=="?"&&s[t+1]==">"){t++;break}else continue}return t}function An(s,t){if(s.length>t+5&&s[t+1]==="-"&&s[t+2]==="-"){for(t+=3;t<s.length;t++)if(s[t]==="-"&&s[t+1]==="-"&&s[t+2]===">"){t+=2;break}}else if(s.length>t+8&&s[t+1]==="D"&&s[t+2]==="O"&&s[t+3]==="C"&&s[t+4]==="T"&&s[t+5]==="Y"&&s[t+6]==="P"&&s[t+7]==="E"){let e=1;for(t+=8;t<s.length;t++)if(s[t]==="<")e++;else if(s[t]===">"&&(e--,e===0))break}else if(s.length>t+9&&s[t+1]==="["&&s[t+2]==="C"&&s[t+3]==="D"&&s[t+4]==="A"&&s[t+5]==="T"&&s[t+6]==="A"&&s[t+7]==="["){for(t+=8;t<s.length;t++)if(s[t]==="]"&&s[t+1]==="]"&&s[t+2]===">"){t+=2;break}}return t}const oi='"',ai="'";function ci(s,t){let e="",n="",i=!1;for(;t<s.length;t++){if(s[t]===oi||s[t]===ai)n===""?n=s[t]:n!==s[t]||(n="");else if(s[t]===">"&&n===""){i=!0;break}e+=s[t]}return n!==""?!1:{value:e,index:t,tagClosed:i}}const li=new RegExp(`(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['"])(([\\s\\S])*?)\\5)?`,"g");function In(s,t){const e=zn(s,li),n={};for(let i=0;i<e.length;i++){if(e[i][1].length===0)return v("InvalidAttr","Attribute '"+e[i][2]+"' has no space in starting.",zt(e[i]));if(e[i][3]!==void 0&&e[i][4]===void 0)return v("InvalidAttr","Attribute '"+e[i][2]+"' is without value.",zt(e[i]));if(e[i][3]===void 0&&!t.allowBooleanAttributes)return v("InvalidAttr","boolean attribute '"+e[i][2]+"' is not allowed.",zt(e[i]));const r=e[i][2];if(!ui(r))return v("InvalidAttr","Attribute '"+r+"' is an invalid name.",zt(e[i]));if(!n.hasOwnProperty(r))n[r]=1;else return v("InvalidAttr","Attribute '"+r+"' is repeated.",zt(e[i]))}return!0}function di(s,t){let e=/\d/;for(s[t]==="x"&&(t++,e=/[\da-fA-F]/);t<s.length;t++){if(s[t]===";")return t;if(!s[t].match(e))break}return-1}function hi(s,t){if(t++,s[t]===";")return-1;if(s[t]==="#")return t++,di(s,t);let e=0;for(;t<s.length;t++,e++)if(!(s[t].match(/\w/)&&e<20)){if(s[t]===";")break;return-1}return t}function v(s,t,e){return{err:{code:s,msg:t,line:e.line||e,col:e.col}}}function ui(s){return _e(s)}function fi(s){return _e(s)}function P(s,t){const e=s.substring(0,t).split(/\r?\n/);return{line:e.length,col:e[e.length-1].length+1}}function zt(s){return s.startIndex+s[1].length}const pi={preserveOrder:!1,attributeNamePrefix:"@_",attributesGroupName:!1,textNodeName:"#text",ignoreAttributes:!0,removeNSPrefix:!1,allowBooleanAttributes:!1,parseTagValue:!0,parseAttributeValue:!1,trimValues:!0,cdataPropName:!1,numberParseOptions:{hex:!0,leadingZeros:!0,eNotation:!0},tagValueProcessor:function(s,t){return t},attributeValueProcessor:function(s,t){return t},stopNodes:[],alwaysCreateTextNode:!1,isArray:()=>!1,commentPropName:!1,unpairedTags:[],processEntities:!0,htmlEntities:!1,ignoreDeclaration:!1,ignorePiTags:!1,transformTagName:!1,transformAttributeName:!1,updateTag:function(s,t,e){return s},captureMetaData:!1},gi=function(s){return Object.assign({},pi,s)};let le;typeof Symbol!="function"?le="@@xmlMetadata":le=Symbol("XML Node Metadata");class mt{constructor(t){this.tagname=t,this.child=[],this[":@"]={}}add(t,e){t==="__proto__"&&(t="#__proto__"),this.child.push({[t]:e})}addChild(t,e){t.tagname==="__proto__"&&(t.tagname="#__proto__"),t[":@"]&&Object.keys(t[":@"]).length>0?this.child.push({[t.tagname]:t.child,":@":t[":@"]}):this.child.push({[t.tagname]:t.child}),e!==void 0&&(this.child[this.child.length-1][le]={startIndex:e})}static getMetaDataSymbol(){return le}}class mi{constructor(t){this.suppressValidationErr=!t}readDocType(t,e){const n={};if(t[e+3]==="O"&&t[e+4]==="C"&&t[e+5]==="T"&&t[e+6]==="Y"&&t[e+7]==="P"&&t[e+8]==="E"){e=e+9;let i=1,r=!1,o=!1,a="";for(;e<t.length;e++)if(t[e]==="<"&&!o){if(r&&ut(t,"!ENTITY",e)){e+=7;let c,l;[c,l,e]=this.readEntityExp(t,e+1,this.suppressValidationErr),l.indexOf("&")===-1&&(n[c]={regx:RegExp(`&${c};`,"g"),val:l})}else if(r&&ut(t,"!ELEMENT",e)){e+=8;const{index:c}=this.readElementExp(t,e+1);e=c}else if(r&&ut(t,"!ATTLIST",e))e+=8;else if(r&&ut(t,"!NOTATION",e)){e+=9;const{index:c}=this.readNotationExp(t,e+1,this.suppressValidationErr);e=c}else if(ut(t,"!--",e))o=!0;else throw new Error("Invalid DOCTYPE");i++,a=""}else if(t[e]===">"){if(o?t[e-1]==="-"&&t[e-2]==="-"&&(o=!1,i--):i--,i===0)break}else t[e]==="["?r=!0:a+=t[e];if(i!==0)throw new Error("Unclosed DOCTYPE")}else throw new Error("Invalid Tag instead of DOCTYPE");return{entities:n,i:e}}readEntityExp(t,e){e=B(t,e);let n="";for(;e<t.length&&!/\s/.test(t[e])&&t[e]!=='"'&&t[e]!=="'";)n+=t[e],e++;if(Ut(n),e=B(t,e),!this.suppressValidationErr){if(t.substring(e,e+6).toUpperCase()==="SYSTEM")throw new Error("External entities are not supported");if(t[e]==="%")throw new Error("Parameter entities are not supported")}let i="";return[e,i]=this.readIdentifierVal(t,e,"entity"),e--,[n,i,e]}readNotationExp(t,e){e=B(t,e);let n="";for(;e<t.length&&!/\s/.test(t[e]);)n+=t[e],e++;!this.suppressValidationErr&&Ut(n),e=B(t,e);const i=t.substring(e,e+6).toUpperCase();if(!this.suppressValidationErr&&i!=="SYSTEM"&&i!=="PUBLIC")throw new Error(`Expected SYSTEM or PUBLIC, found "${i}"`);e+=i.length,e=B(t,e);let r=null,o=null;if(i==="PUBLIC")[e,r]=this.readIdentifierVal(t,e,"publicIdentifier"),e=B(t,e),(t[e]==='"'||t[e]==="'")&&([e,o]=this.readIdentifierVal(t,e,"systemIdentifier"));else if(i==="SYSTEM"&&([e,o]=this.readIdentifierVal(t,e,"systemIdentifier"),!this.suppressValidationErr&&!o))throw new Error("Missing mandatory system identifier for SYSTEM notation");return{notationName:n,publicIdentifier:r,systemIdentifier:o,index:--e}}readIdentifierVal(t,e,n){let i="";const r=t[e];if(r!=='"'&&r!=="'")throw new Error(`Expected quoted string, found "${r}"`);for(e++;e<t.length&&t[e]!==r;)i+=t[e],e++;if(t[e]!==r)throw new Error(`Unterminated ${n} value`);return e++,[e,i]}readElementExp(t,e){e=B(t,e);let n="";for(;e<t.length&&!/\s/.test(t[e]);)n+=t[e],e++;if(!this.suppressValidationErr&&!_e(n))throw new Error(`Invalid element name: "${n}"`);e=B(t,e);let i="";if(t[e]==="E"&&ut(t,"MPTY",e))e+=4;else if(t[e]==="A"&&ut(t,"NY",e))e+=2;else if(t[e]==="("){for(e++;e<t.length&&t[e]!==")";)i+=t[e],e++;if(t[e]!==")")throw new Error("Unterminated content model")}else if(!this.suppressValidationErr)throw new Error(`Invalid Element Expression, found "${t[e]}"`);return{elementName:n,contentModel:i.trim(),index:e}}readAttlistExp(t,e){e=B(t,e);let n="";for(;e<t.length&&!/\s/.test(t[e]);)n+=t[e],e++;Ut(n),e=B(t,e);let i="";for(;e<t.length&&!/\s/.test(t[e]);)i+=t[e],e++;if(!Ut(i))throw new Error(`Invalid attribute name: "${i}"`);e=B(t,e);let r="";if(t.substring(e,e+8).toUpperCase()==="NOTATION"){if(r="NOTATION",e+=8,e=B(t,e),t[e]!=="(")throw new Error(`Expected '(', found "${t[e]}"`);e++;let a=[];for(;e<t.length&&t[e]!==")";){let c="";for(;e<t.length&&t[e]!=="|"&&t[e]!==")";)c+=t[e],e++;if(c=c.trim(),!Ut(c))throw new Error(`Invalid notation name: "${c}"`);a.push(c),t[e]==="|"&&(e++,e=B(t,e))}if(t[e]!==")")throw new Error("Unterminated list of notations");e++,r+=" ("+a.join("|")+")"}else{for(;e<t.length&&!/\s/.test(t[e]);)r+=t[e],e++;const a=["CDATA","ID","IDREF","IDREFS","ENTITY","ENTITIES","NMTOKEN","NMTOKENS"];if(!this.suppressValidationErr&&!a.includes(r.toUpperCase()))throw new Error(`Invalid attribute type: "${r}"`)}e=B(t,e);let o="";return t.substring(e,e+8).toUpperCase()==="#REQUIRED"?(o="#REQUIRED",e+=8):t.substring(e,e+7).toUpperCase()==="#IMPLIED"?(o="#IMPLIED",e+=7):[e,o]=this.readIdentifierVal(t,e,"ATTLIST"),{elementName:n,attributeName:i,attributeType:r,defaultValue:o,index:e}}}const B=(s,t)=>{for(;t<s.length&&/\s/.test(s[t]);)t++;return t};function ut(s,t,e){for(let n=0;n<t.length;n++)if(t[n]!==s[e+n+1])return!1;return!0}function Ut(s){if(_e(s))return s;throw new Error(`Invalid entity name ${s}`)}const yi=/^[-+]?0x[a-fA-F0-9]+$/,wi=/^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/,Ei={hex:!0,leadingZeros:!0,decimalPoint:".",eNotation:!0};function _i(s,t={}){if(t=Object.assign({},Ei,t),!s||typeof s!="string")return s;let e=s.trim();if(t.skipLike!==void 0&&t.skipLike.test(e))return s;if(s==="0")return 0;if(t.hex&&yi.test(e))return Ti(e,16);if(e.search(/.+[eE].+/)!==-1)return Ai(s,e,t);{const n=wi.exec(e);if(n){const i=n[1]||"",r=n[2];let o=Ii(n[3]);const a=i?s[r.length+1]===".":s[r.length]===".";if(!t.leadingZeros&&(r.length>1||r.length===1&&!a))return s;{const c=Number(e),l=String(c);if(c===0)return c;if(l.search(/[eE]/)!==-1)return t.eNotation?c:s;if(e.indexOf(".")!==-1)return l==="0"||l===o||l===`${i}${o}`?c:s;let h=r?o:e;return r?h===l||i+h===l?c:s:h===l||h===i+l?c:s}}else return s}}const bi=/^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;function Ai(s,t,e){if(!e.eNotation)return s;const n=t.match(bi);if(n){let i=n[1]||"";const r=n[3].indexOf("e")===-1?"E":"e",o=n[2],a=i?s[o.length+1]===r:s[o.length]===r;return o.length>1&&a?s:o.length===1&&(n[3].startsWith(`.${r}`)||n[3][0]===r)?Number(t):e.leadingZeros&&!a?(t=(n[1]||"")+n[3],Number(t)):s}else return s}function Ii(s){return s&&s.indexOf(".")!==-1&&(s=s.replace(/0+$/,""),s==="."?s="0":s[0]==="."?s="0"+s:s[s.length-1]==="."&&(s=s.substring(0,s.length-1))),s}function Ti(s,t){if(parseInt)return parseInt(s,t);if(Number.parseInt)return Number.parseInt(s,t);if(window&&window.parseInt)return window.parseInt(s,t);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}function Un(s){return typeof s=="function"?s:Array.isArray(s)?t=>{for(const e of s)if(typeof e=="string"&&t===e||e instanceof RegExp&&e.test(t))return!0}:()=>!1}class Ni{constructor(t){if(this.options=t,this.currentNode=null,this.tagsNodeStack=[],this.docTypeEntities={},this.lastEntities={apos:{regex:/&(apos|#39|#x27);/g,val:"'"},gt:{regex:/&(gt|#62|#x3E);/g,val:">"},lt:{regex:/&(lt|#60|#x3C);/g,val:"<"},quot:{regex:/&(quot|#34|#x22);/g,val:'"'}},this.ampEntity={regex:/&(amp|#38|#x26);/g,val:"&"},this.htmlEntities={space:{regex:/&(nbsp|#160);/g,val:" "},cent:{regex:/&(cent|#162);/g,val:"¢"},pound:{regex:/&(pound|#163);/g,val:"£"},yen:{regex:/&(yen|#165);/g,val:"¥"},euro:{regex:/&(euro|#8364);/g,val:"€"},copyright:{regex:/&(copy|#169);/g,val:"©"},reg:{regex:/&(reg|#174);/g,val:"®"},inr:{regex:/&(inr|#8377);/g,val:"₹"},num_dec:{regex:/&#([0-9]{1,7});/g,val:(e,n)=>String.fromCodePoint(Number.parseInt(n,10))},num_hex:{regex:/&#x([0-9a-fA-F]{1,6});/g,val:(e,n)=>String.fromCodePoint(Number.parseInt(n,16))}},this.addExternalEntities=vi,this.parseXml=Ri,this.parseTextData=Si,this.resolveNameSpace=Oi,this.buildAttributesMap=Ci,this.isItStopNode=Pi,this.replaceEntitiesValue=xi,this.readStopNodeData=Bi,this.saveTextToParentTag=$i,this.addChild=Mi,this.ignoreAttributesFn=Un(this.options.ignoreAttributes),this.options.stopNodes&&this.options.stopNodes.length>0){this.stopNodesExact=new Set,this.stopNodesWildcard=new Set;for(let e=0;e<this.options.stopNodes.length;e++){const n=this.options.stopNodes[e];typeof n=="string"&&(n.startsWith("*.")?this.stopNodesWildcard.add(n.substring(2)):this.stopNodesExact.add(n))}}}}function vi(s){const t=Object.keys(s);for(let e=0;e<t.length;e++){const n=t[e];this.lastEntities[n]={regex:new RegExp("&"+n+";","g"),val:s[n]}}}function Si(s,t,e,n,i,r,o){if(s!==void 0&&(this.options.trimValues&&!n&&(s=s.trim()),s.length>0)){o||(s=this.replaceEntitiesValue(s));const a=this.options.tagValueProcessor(t,s,e,i,r);return a==null?s:typeof a!=typeof s||a!==s?a:this.options.trimValues?$e(s,this.options.parseTagValue,this.options.numberParseOptions):s.trim()===s?$e(s,this.options.parseTagValue,this.options.numberParseOptions):s}}function Oi(s){if(this.options.removeNSPrefix){const t=s.split(":"),e=s.charAt(0)==="/"?"/":"";if(t[0]==="xmlns")return"";t.length===2&&(s=e+t[1])}return s}const ki=new RegExp(`([^\\s=]+)\\s*(=\\s*(['"])([\\s\\S]*?)\\3)?`,"gm");function Ci(s,t,e){if(this.options.ignoreAttributes!==!0&&typeof s=="string"){const n=zn(s,ki),i=n.length,r={};for(let o=0;o<i;o++){const a=this.resolveNameSpace(n[o][1]);if(this.ignoreAttributesFn(a,t))continue;let c=n[o][4],l=this.options.attributeNamePrefix+a;if(a.length)if(this.options.transformAttributeName&&(l=this.options.transformAttributeName(l)),l==="__proto__"&&(l="#__proto__"),c!==void 0){this.options.trimValues&&(c=c.trim()),c=this.replaceEntitiesValue(c);const h=this.options.attributeValueProcessor(a,c,t);h==null?r[l]=c:typeof h!=typeof c||h!==c?r[l]=h:r[l]=$e(c,this.options.parseAttributeValue,this.options.numberParseOptions)}else this.options.allowBooleanAttributes&&(r[l]=!0)}if(!Object.keys(r).length)return;if(this.options.attributesGroupName){const o={};return o[this.options.attributesGroupName]=r,o}return r}}const Ri=function(s){s=s.replace(/\r\n?/g,`
|
|
4
|
-
`);const t=new mt("!xml");let e=t,n="",i="";const r=new
|
|
5
|
-
`;function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Ze="MS Gothic, sans-serif",rt={WIDTH:66,HEIGHT:90,TEXT_SCALE:.8,BLOCK_MARGIN_SCALE:.3},Ce={WIDTH:125,HEIGHT:27.5},Bn={BASE:40},V=",",p={M:"m",P:"p",S:"s",Z:"z",BACK:"_"},g={TSUMO:"t",RON:"v",IMAGE_DORA:"d",HORIZONTAL:"-",RED:"r",COLOR_GRAYSCALE:"^"},E={PON:"pon",CHI:"chi",SHO_KAN:"shokan",DAI_KAN:"daikan",AN_KAN:"ankan",TSUMO:"tsumo",PAIR:"pair",ISOLATED:"isolated",THREE:"three",RUN:"run",HAND:"hand",IMAGE_DORA:"dora",IMAGE_DISCARD:"simple-discard",UNKNOWN:"unknown"},_={E:"1z",S:"2z",W:"3z",N:"4z"},k={E1:"1z1",E2:"1z2",E3:"1z3",E4:"1z4",S1:"2z1",S2:"2z2",S3:"2z3",S4:"2z4",W1:"3z1",W2:"3z2",W3:"3z3",W4:"3z4",N1:"4z1",N2:"4z2",N3:"4z3",N4:"4z4"},ye={[_.E]:"東",[_.S]:"南",[_.W]:"西",[_.N]:"北"},Ye={[k.E1]:"東1局",[k.E2]:"東2局",[k.E3]:"東3局",[k.E4]:"東4局",[k.S1]:"南1局",[k.S2]:"南2局",[k.S3]:"南3局",[k.S4]:"南4局",[k.W1]:"西1局",[k.W2]:"西2局",[k.W3]:"西3局",[k.W4]:"西4局",[k.N1]:"北1局",[k.N2]:"北2局",[k.N3]:"北3局",[k.N4]:"北4局"};function I(s,t){if(!s)throw new Error(t)}class Ds{ctx=null;strText;numText;constructor(t="東",e="2"){this.strText=t,this.numText=e}measure=(t,e)=>{this.ctx==null&&(this.ctx=document.createElement("canvas").getContext("2d"),I(this.ctx,"context is null"));const n=this.ctx;n.font=e;const i=n.measureText(t);let r=i.width,o=i.actualBoundingBoxAscent+i.actualBoundingBoxDescent;return[r,o]};measureFontContext=(t,e)=>{const n={family:t,size:e},i=`${n.size}px ${n.family}`,[r,o]=this.measure(this.strText,i),[a,c]=this.measure(this.numText,i);return{font:{family:t,size:e},textWidth:r,textHeight:o,numWidth:a,numHeight:c}};measureTableFontContext=t=>{const e=this.measureFontContext(Ze,Bn.BASE*t);return e.textHeight=e.textWidth,e.numHeight=e.numWidth,e}}class Ls{input;position;nextPosition;char;eof="\0";constructor(t){this.input=t,this.position=0,this.nextPosition=0,this.char=this.readChar()}readChar(){return this.nextPosition>=this.input.length?(this.char=this.eof,this.char):(this.char=this.input[this.nextPosition],this.position=this.nextPosition,this.nextPosition++,this.char)}peekChar(){return this.nextPosition>=this.input.length?this.eof:this.input[this.nextPosition]}peekCharN(t){if(t<0)throw new Error("arg must be positive value");return this.position+t>=this.input.length?this.eof:this.input[this.position+t]}prevChar(){return this.position>=this.input.length?this.eof:this.position>0?this.input[this.position-1]:this.eof}skipWhitespace(){for(;this.isWhitespace(this.char);)this.readChar()}isWhitespace(t){return/\s/.test(t)}}const Qt=(s,t)=>{if(s.t==t.t){if(S(s)&&S(t)){if(s.has(g.RED))return-1;if(t.has(g.RED))return 1}return s.n-t.n}const e=[p.M,p.P,p.S,p.Z,p.BACK];return e.indexOf(s.t)-e.indexOf(t.t)},Ks=(s,t)=>{const e=[g.HORIZONTAL,g.TSUMO,g.RON,g.IMAGE_DORA,g.COLOR_GRAYSCALE,g.RED];return e.indexOf(s)-e.indexOf(t)},Wn=s=>{const t=[];s.forEach((n,i)=>{n.has(g.HORIZONTAL)&&t.push(i)});const e=s.filter(n=>!n.has(g.HORIZONTAL)).sort(Qt);return t.forEach(n=>{e.splice(n,0,s[n])}),e};function S(s){return s.isNum()&&s.n==5}function zs(s){const t=Object.values(p).find(e=>e===s);return t?[t,!0]:[p.BACK,!1]}class y{constructor(t,e,n=[]){this.t=t,this.n=e,this.ops=n}static from(t){const e=new D(t).tiles();if(e.length!=1)throw new Error(`input must be a single tile: ${t}`);return e[0]}toString(){return this.t===p.BACK?this.t:`${[...this.ops].sort(Ks).join("")}${this.n}${this.t}`}toJSON(){return this.toString()}clone(t){const e=t?.t??this.t,n=t?.n??this.n,i=t?.removeAll?[]:this.ops.filter(o=>Array.isArray(t?.remove)?!t.remove.includes(o):t?.remove!=o),r=new Set([...i]);return t?.add&&(Array.isArray(t.add)?t.add.forEach(o=>r.add(o)):r.add(t.add)),new y(e,n,Array.from(r))}has(t){return this.ops.includes(t)}isNum(){return this.t==p.M||this.t==p.P||this.t==p.S}equals(t){return t.t==p.BACK&&this.t==p.BACK?!0:this.t==t.t&&this.n==t.n}}class N{_tiles;_type;constructor(t,e){if(this._tiles=t,this._type=e,this.isCalled()){this._tiles=Wn(this._tiles);return}if(this._type!=E.IMAGE_DISCARD){this._tiles=[...this._tiles].sort(Qt);return}}static from(t){const e=new D(t,{enableImplicitTsumoBlock:!1}).parse();if(e.length!=1)throw new Error(`expected exactly 1 block but got ${e.length}: ${t}`);return e[0]}static deserialize(t){const e=N.from(t.tiles),n=e.type;if(!(t.type==E.PAIR||t.type==E.ISOLATED||t.type==E.THREE||t.type==E.RUN)&&n!=t.type)throw new Error(`"expected type ${t.type} but got ${n}: ${t.tiles}`);return ce(e.tiles,t.type)}serialize(){return{tiles:this.toString(),type:this.type}}toJSON(){return this.serialize()}get type(){return this._type}get tiles(){return this._tiles}is(t){return this._type==t}isCalled(){switch(this._type){case E.PON:case E.CHI:case E.DAI_KAN:case E.SHO_KAN:case E.AN_KAN:return!0;default:return!1}}clone(t){const e=t?.replace,n=[...this.tiles];return e&&(n[e.idx]=e.tile),ce(n,this._type)}}const vt=s=>s[0].t===p.BACK?s.join(""):`${s.map(e=>e.toString().slice(0,-1)).join("")}${s[0].t}`,Ve=s=>{if(s.length==0)return"";let t=s[0].t,e="";for(const i of s){const r=i.t,o=r==p.BACK?i.toString():i.toString().slice(0,-1);r!=t&&t!=p.BACK&&(e+=t),t=r,e+=o}const n=s.at(-1);return n.t!=p.BACK&&(e+=n.t),e};class F extends N{constructor(t){super(t,E.CHI)}static from(t){return N.deserialize({tiles:t,type:E.CHI})}toString(){return vt(this.tiles)}}class U extends N{constructor(t){super(t,E.PON)}static from(t){return N.deserialize({tiles:t,type:E.PON})}toString(){return vt(this.tiles)}}class R extends N{constructor(t){const e=t.filter(i=>i.t!=p.BACK),n=e[0];if(e.length<t.length){if(S(n)){const i=new y(n.t,5);super([i.clone({add:g.RED}),i,i,i],E.AN_KAN);return}super([n,n,n,n],E.AN_KAN);return}super(t,E.AN_KAN)}get tiles(){return super.tiles}get tilesWithBack(){const t=this.tiles[0].clone({remove:g.RED}),e=S(t)?t.clone({add:g.RED}):t;return[new y(p.BACK,0),e,t,new y(p.BACK,0)]}static from(t){return N.deserialize({tiles:t,type:E.AN_KAN})}toString(){return Ve(this.tilesWithBack)}}class K extends N{constructor(t){super(t,E.DAI_KAN)}static from(t){return N.deserialize({tiles:t,type:E.DAI_KAN})}toString(){return vt(this.tiles)}}class M extends N{constructor(t){super(t,E.SHO_KAN)}static from(t){return N.deserialize({tiles:t,type:E.SHO_KAN})}static fromPon(t,e){const n=t.tiles.findIndex(r=>r.has(g.HORIZONTAL)),i=[...t.tiles];return i.splice(n,0,e.clone({add:g.HORIZONTAL})),new M(i)}toString(){return vt(this.tiles)}}class C extends N{constructor(t,e){super([t,e],E.PAIR)}toString(){return vt(this.tiles)}static from(t){return N.deserialize({tiles:t,type:E.PAIR})}}class L extends N{constructor(t){super(t,E.THREE)}static from(t){return N.deserialize({tiles:t,type:E.THREE})}toString(){return vt(this.tiles)}}class nt extends N{constructor(t){super(t,E.RUN)}static from(t){return N.deserialize({tiles:t,type:E.RUN})}toString(){return vt(this.tiles)}}class Je extends N{constructor(t){super([t],E.ISOLATED)}static from(t){return N.deserialize({tiles:t,type:E.ISOLATED})}toString(){return this.tiles[0].toString()}}class bt extends N{constructor(t){super(t,E.HAND)}static from(t){return N.deserialize({tiles:t,type:E.HAND})}toString(){return Ve(this.tiles)}}class we extends N{constructor(t,e){super(t,e)}toString(){return this.is(E.IMAGE_DISCARD)?this.tiles.join(""):Ve(this.tiles)}}const ce=(s,t)=>{switch(t){case E.CHI:const e=s.find(i=>i.has(g.HORIZONTAL));I(e!=null,`chi block does not have horizontal ops: ${s}`);const n=s.filter(i=>!i.has(g.HORIZONTAL));return new F([e,n[0],n[1]]);case E.PON:return new U([s[0],s[1],s[2]]);case E.AN_KAN:return new R(s);case E.DAI_KAN:return new K(s);case E.SHO_KAN:return new M(s);case E.THREE:return new L(s);case E.RUN:return new nt(s);case E.PAIR:return new C(s[0],s[1]);case E.ISOLATED:return new Je(s[0]);case E.HAND:return new bt(s);default:return new we(s,t)}};class D{constructor(t,e={enableImplicitTsumoBlock:!0}){this.input=t,this.options=e,this.input=t.replace(/\s/g,"")}maxInputLength=600;parse(){const t=this.tileSeparators();return this.makeBlocks(t)}tiles(){return this.tileSeparators().filter(t=>t!=V)}tileSeparators(){const t=new Ls(this.input),e=[];let n=[];for(this.validate(this.input);;){t.skipWhitespace();const i=t.char;if(i===t.eof)break;if(i==V){e.push(V),t.readChar();continue}const[r,o]=wn(i,n);if(o){if(r==p.BACK){e.push(new y(r,0)),t.readChar();continue}e.push(...js(n,r)),n=[],t.readChar();continue}else{const[a,c]=Fs(t);if(c){n.push(a),t.readChar();continue}const[l,d]=Dn(i);if(!d)throw new Error(`expected a number but got: ${i}`);n.push({n:l})}t.readChar()}if(n.length>0)throw new Error(`unexpected remaining values: ${n.toString()}`);return this.options.enableImplicitTsumoBlock?this.reconstruct(e):e}reconstruct(t){if(t.length>18)return t;const e=t.findIndex(a=>a instanceof y&&a.has(g.TSUMO));if(e<0)return t;const n=t.findIndex(a=>a===V);if(n>-1&&e>n)return t;const i=n<0?t.length:n,r=t.slice(0,i),o=r[e];return r.some(a=>a instanceof y&&a.has(g.HORIZONTAL))?t:[...r.slice(0,e),...r.slice(e+1,i),V,o,...t.slice(i)]}makeBlocks(t){let e=[];const n=[];if(t.length==0)return n;for(const o of t){if(o==V){const a=yn(e),c=ce(e,a);n.push(c),e=[];continue}e.push(o)}const i=yn(e),r=ce(e,i);return n.push(r),e=[],n}validate(t){if(t.length==0)return;if(t.length>this.maxInputLength)throw new Error(`exceeded maximum input length (${t.length})`);const e=t.charAt(t.length-1),[n,i]=wn(e,[new y(p.BACK,1)]);if(!i)throw new Error(`last character must be a tile type: ${e} in ${t}`)}}function yn(s){if(s.length===0)return E.UNKNOWN;if(s.length===1)return s[0].has(g.IMAGE_DORA)?E.IMAGE_DORA:s[0].has(g.TSUMO)?E.TSUMO:E.HAND;const t=s.every(r=>r.equals(s[0])),e=s.filter(r=>r.has(g.HORIZONTAL)).length,n=s.filter(r=>r.has(g.TSUMO)||r.has(g.IMAGE_DORA)).length,i=s.filter(r=>r.t==p.BACK).length;if(n>0)return E.UNKNOWN;if(e==0&&i==0)return E.HAND;if(s.length===3&&i===0)return t?E.PON:e==1&&Us(s)?E.CHI:E.IMAGE_DISCARD;if(s.length==4&&i==2)return E.AN_KAN;if(s.length==4&&t){if(e==1)return E.DAI_KAN;if(e==2)return E.SHO_KAN}return e==1||n==0?E.IMAGE_DISCARD:E.UNKNOWN}function Us(s){const t=[...s].sort(Qt);if(t.some(n=>t[0].t!=n.t))return!1;const e=t.map(n=>n.n);for(let n=0;n<e.length-1;n++)if(e[n]!=e[n+1]-1)return!1;return!0}function js(s,t){return s.map(e=>{let n=new y(t,e.n,e.ops);return n.isNum()&&n.n==0&&(n=n.clone({n:5,add:g.RED})),n})}function wn(s,t){const[e,n]=zs(s);if(n)return[e,!0];if((s==="w"||s==="d")&&t.length>0){for(let r=0;r<t.length;r++){const o=t[r];s==="d"&&(t[r].n=o.n+4)}return[p.Z,!0]}return[p.BACK,!1]}function Dn(s){const t=Number(s),e=0<=t&&t<=9;return[t,e]}function Fs(s){const t=Object.values(g);if(!t.includes(s.char))return[new y(p.BACK,0),!1];const e=[];for(let n=0;n<4;n++){const i=s.peekCharN(n);if(t.includes(i))e.push(i);else{const[r,o]=Dn(i);if(!o)break;for(const c of e)s.readChar();const a=new y(p.BACK,r,e);if(a.has(g.RED)&&a.n!=5)throw new Error(`red dora operator can only be used with 5, got: ${r}`);if(a.has(g.IMAGE_DORA)&&a.has(g.TSUMO))throw new Error("cannot specify both dora and tsumo operators");return[a,!0]}}return[new y(p.BACK,0),!1]}function H(s){return{[_.E]:s(),[_.S]:s(),[_.W]:s(),[_.N]:s()}}const Vt=s=>{let t=s.substring(0,2),e=Number(s.substring(2,3));return e==4?(e=1,t=_t(t)):e++,`${t}${e}`},Gs=s=>Vt(Vt(Vt(s))),Ln=s=>s.substring(0,2),_t=s=>{let t=Number(s.toString()[0]);return t=t%4+1,`${t}${p.Z}`},Ee=s=>{let t=Number(s.toString()[0]);const e=[1,4,3,2],n=e.indexOf(t);return`${e[(n+1)%e.length]}${p.Z}`},Re=(s,t,e)=>{const n=Math.abs(Number(s[0])-Number(t[0]));return I(n==1||n==2||n==3),e==E.PON?n==3?0:n==2?1:2:n==3?0:n==1?3:2};function En(s){return typeof s>"u"}function Me(s,t=0){return{a:1,c:0,e:s,b:0,d:1,f:t}}function Xe(...s){s=Array.isArray(s[0])?s[0]:s;const t=(e,n)=>({a:e.a*n.a+e.c*n.b,c:e.a*n.c+e.c*n.d,e:e.a*n.e+e.c*n.f+e.e,b:e.b*n.a+e.d*n.b,d:e.b*n.c+e.d*n.d,f:e.b*n.e+e.d*n.f+e.f});switch(s.length){case 0:throw new Error("no matrices provided");case 1:return s[0];case 2:return t(s[0],s[1]);default:{const[e,n,...i]=s,r=t(e,n);return Xe(r,...i)}}}function Zs(...s){return Xe(...s)}const{cos:Ys,sin:Vs,PI:Js}=Math;function Xs(s,t,e){const n=Ys(s),i=Vs(s),r={a:n,c:-i,e:0,b:i,d:n,f:0};return En(t)||En(e)?r:Xe([Me(t,e),r,Me(-t,-e)])}function qs(s,t=void 0,e=void 0){return Xs(s*Js/180,t,e)}function Qs(s){return ti(s)}function ti(s){return`matrix(${s.a},${s.b},${s.c},${s.d},${s.e},${s.f})`}const Kn=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",ei=Kn+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040",ni="["+Kn+"]["+ei+"]*",si=new RegExp("^"+ni+"$");function zn(s,t){const e=[];let n=t.exec(s);for(;n;){const i=[];i.startIndex=t.lastIndex-n[0].length;const r=n.length;for(let o=0;o<r;o++)i.push(n[o]);e.push(i),n=t.exec(s)}return e}const be=function(s){const t=si.exec(s);return!(t===null||typeof t>"u")};function ii(s){return typeof s<"u"}const ri={allowBooleanAttributes:!1,unpairedTags:[]};function oi(s,t){t=Object.assign({},ri,t);const e=[];let n=!1,i=!1;s[0]==="\uFEFF"&&(s=s.substr(1));for(let r=0;r<s.length;r++)if(s[r]==="<"&&s[r+1]==="?"){if(r+=2,r=_n(s,r),r.err)return r}else if(s[r]==="<"){let o=r;if(r++,s[r]==="!"){r=An(s,r);continue}else{let a=!1;s[r]==="/"&&(a=!0,r++);let c="";for(;r<s.length&&s[r]!==">"&&s[r]!==" "&&s[r]!==" "&&s[r]!==`
|
|
2
|
+
`&&s[r]!=="\r";r++)c+=s[r];if(c=c.trim(),c[c.length-1]==="/"&&(c=c.substring(0,c.length-1),r--),!pi(c)){let h;return c.trim().length===0?h="Invalid space after '<'.":h="Tag '"+c+"' is an invalid name.",v("InvalidTag",h,P(s,r))}const l=li(s,r);if(l===!1)return v("InvalidAttr","Attributes for '"+c+"' have open quote.",P(s,r));let d=l.value;if(r=l.index,d[d.length-1]==="/"){const h=r-d.length;d=d.substring(0,d.length-1);const u=In(d,t);if(u===!0)n=!0;else return v(u.err.code,u.err.msg,P(s,h+u.err.line))}else if(a)if(l.tagClosed){if(d.trim().length>0)return v("InvalidTag","Closing tag '"+c+"' can't have attributes or invalid starting.",P(s,o));if(e.length===0)return v("InvalidTag","Closing tag '"+c+"' has not been opened.",P(s,o));{const h=e.pop();if(c!==h.tagName){let u=P(s,h.tagStartPos);return v("InvalidTag","Expected closing tag '"+h.tagName+"' (opened in line "+u.line+", col "+u.col+") instead of closing tag '"+c+"'.",P(s,o))}e.length==0&&(i=!0)}}else return v("InvalidTag","Closing tag '"+c+"' doesn't have proper closing.",P(s,r));else{const h=In(d,t);if(h!==!0)return v(h.err.code,h.err.msg,P(s,r-d.length+h.err.line));if(i===!0)return v("InvalidXml","Multiple possible root nodes found.",P(s,r));t.unpairedTags.indexOf(c)!==-1||e.push({tagName:c,tagStartPos:o}),n=!0}for(r++;r<s.length;r++)if(s[r]==="<")if(s[r+1]==="!"){r++,r=An(s,r);continue}else if(s[r+1]==="?"){if(r=_n(s,++r),r.err)return r}else break;else if(s[r]==="&"){const h=ui(s,r);if(h==-1)return v("InvalidChar","char '&' is not expected.",P(s,r));r=h}else if(i===!0&&!bn(s[r]))return v("InvalidXml","Extra text at the end",P(s,r));s[r]==="<"&&r--}}else{if(bn(s[r]))continue;return v("InvalidChar","char '"+s[r]+"' is not expected.",P(s,r))}if(n){if(e.length==1)return v("InvalidTag","Unclosed tag '"+e[0].tagName+"'.",P(s,e[0].tagStartPos));if(e.length>0)return v("InvalidXml","Invalid '"+JSON.stringify(e.map(r=>r.tagName),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1})}else return v("InvalidXml","Start tag expected.",1);return!0}function bn(s){return s===" "||s===" "||s===`
|
|
3
|
+
`||s==="\r"}function _n(s,t){const e=t;for(;t<s.length;t++)if(s[t]=="?"||s[t]==" "){const n=s.substr(e,t-e);if(t>5&&n==="xml")return v("InvalidXml","XML declaration allowed only at the start of the document.",P(s,t));if(s[t]=="?"&&s[t+1]==">"){t++;break}else continue}return t}function An(s,t){if(s.length>t+5&&s[t+1]==="-"&&s[t+2]==="-"){for(t+=3;t<s.length;t++)if(s[t]==="-"&&s[t+1]==="-"&&s[t+2]===">"){t+=2;break}}else if(s.length>t+8&&s[t+1]==="D"&&s[t+2]==="O"&&s[t+3]==="C"&&s[t+4]==="T"&&s[t+5]==="Y"&&s[t+6]==="P"&&s[t+7]==="E"){let e=1;for(t+=8;t<s.length;t++)if(s[t]==="<")e++;else if(s[t]===">"&&(e--,e===0))break}else if(s.length>t+9&&s[t+1]==="["&&s[t+2]==="C"&&s[t+3]==="D"&&s[t+4]==="A"&&s[t+5]==="T"&&s[t+6]==="A"&&s[t+7]==="["){for(t+=8;t<s.length;t++)if(s[t]==="]"&&s[t+1]==="]"&&s[t+2]===">"){t+=2;break}}return t}const ai='"',ci="'";function li(s,t){let e="",n="",i=!1;for(;t<s.length;t++){if(s[t]===ai||s[t]===ci)n===""?n=s[t]:n!==s[t]||(n="");else if(s[t]===">"&&n===""){i=!0;break}e+=s[t]}return n!==""?!1:{value:e,index:t,tagClosed:i}}const hi=new RegExp(`(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['"])(([\\s\\S])*?)\\5)?`,"g");function In(s,t){const e=zn(s,hi),n={};for(let i=0;i<e.length;i++){if(e[i][1].length===0)return v("InvalidAttr","Attribute '"+e[i][2]+"' has no space in starting.",zt(e[i]));if(e[i][3]!==void 0&&e[i][4]===void 0)return v("InvalidAttr","Attribute '"+e[i][2]+"' is without value.",zt(e[i]));if(e[i][3]===void 0&&!t.allowBooleanAttributes)return v("InvalidAttr","boolean attribute '"+e[i][2]+"' is not allowed.",zt(e[i]));const r=e[i][2];if(!fi(r))return v("InvalidAttr","Attribute '"+r+"' is an invalid name.",zt(e[i]));if(!n.hasOwnProperty(r))n[r]=1;else return v("InvalidAttr","Attribute '"+r+"' is repeated.",zt(e[i]))}return!0}function di(s,t){let e=/\d/;for(s[t]==="x"&&(t++,e=/[\da-fA-F]/);t<s.length;t++){if(s[t]===";")return t;if(!s[t].match(e))break}return-1}function ui(s,t){if(t++,s[t]===";")return-1;if(s[t]==="#")return t++,di(s,t);let e=0;for(;t<s.length;t++,e++)if(!(s[t].match(/\w/)&&e<20)){if(s[t]===";")break;return-1}return t}function v(s,t,e){return{err:{code:s,msg:t,line:e.line||e,col:e.col}}}function fi(s){return be(s)}function pi(s){return be(s)}function P(s,t){const e=s.substring(0,t).split(/\r?\n/);return{line:e.length,col:e[e.length-1].length+1}}function zt(s){return s.startIndex+s[1].length}const gi={preserveOrder:!1,attributeNamePrefix:"@_",attributesGroupName:!1,textNodeName:"#text",ignoreAttributes:!0,removeNSPrefix:!1,allowBooleanAttributes:!1,parseTagValue:!0,parseAttributeValue:!1,trimValues:!0,cdataPropName:!1,numberParseOptions:{hex:!0,leadingZeros:!0,eNotation:!0},tagValueProcessor:function(s,t){return t},attributeValueProcessor:function(s,t){return t},stopNodes:[],alwaysCreateTextNode:!1,isArray:()=>!1,commentPropName:!1,unpairedTags:[],processEntities:!0,htmlEntities:!1,ignoreDeclaration:!1,ignorePiTags:!1,transformTagName:!1,transformAttributeName:!1,updateTag:function(s,t,e){return s},captureMetaData:!1},mi=function(s){return Object.assign({},gi,s)};let le;typeof Symbol!="function"?le="@@xmlMetadata":le=Symbol("XML Node Metadata");class mt{constructor(t){this.tagname=t,this.child=[],this[":@"]={}}add(t,e){t==="__proto__"&&(t="#__proto__"),this.child.push({[t]:e})}addChild(t,e){t.tagname==="__proto__"&&(t.tagname="#__proto__"),t[":@"]&&Object.keys(t[":@"]).length>0?this.child.push({[t.tagname]:t.child,":@":t[":@"]}):this.child.push({[t.tagname]:t.child}),e!==void 0&&(this.child[this.child.length-1][le]={startIndex:e})}static getMetaDataSymbol(){return le}}class yi{constructor(t){this.suppressValidationErr=!t}readDocType(t,e){const n={};if(t[e+3]==="O"&&t[e+4]==="C"&&t[e+5]==="T"&&t[e+6]==="Y"&&t[e+7]==="P"&&t[e+8]==="E"){e=e+9;let i=1,r=!1,o=!1,a="";for(;e<t.length;e++)if(t[e]==="<"&&!o){if(r&&ut(t,"!ENTITY",e)){e+=7;let c,l;[c,l,e]=this.readEntityExp(t,e+1,this.suppressValidationErr),l.indexOf("&")===-1&&(n[c]={regx:RegExp(`&${c};`,"g"),val:l})}else if(r&&ut(t,"!ELEMENT",e)){e+=8;const{index:c}=this.readElementExp(t,e+1);e=c}else if(r&&ut(t,"!ATTLIST",e))e+=8;else if(r&&ut(t,"!NOTATION",e)){e+=9;const{index:c}=this.readNotationExp(t,e+1,this.suppressValidationErr);e=c}else if(ut(t,"!--",e))o=!0;else throw new Error("Invalid DOCTYPE");i++,a=""}else if(t[e]===">"){if(o?t[e-1]==="-"&&t[e-2]==="-"&&(o=!1,i--):i--,i===0)break}else t[e]==="["?r=!0:a+=t[e];if(i!==0)throw new Error("Unclosed DOCTYPE")}else throw new Error("Invalid Tag instead of DOCTYPE");return{entities:n,i:e}}readEntityExp(t,e){e=B(t,e);let n="";for(;e<t.length&&!/\s/.test(t[e])&&t[e]!=='"'&&t[e]!=="'";)n+=t[e],e++;if(Ut(n),e=B(t,e),!this.suppressValidationErr){if(t.substring(e,e+6).toUpperCase()==="SYSTEM")throw new Error("External entities are not supported");if(t[e]==="%")throw new Error("Parameter entities are not supported")}let i="";return[e,i]=this.readIdentifierVal(t,e,"entity"),e--,[n,i,e]}readNotationExp(t,e){e=B(t,e);let n="";for(;e<t.length&&!/\s/.test(t[e]);)n+=t[e],e++;!this.suppressValidationErr&&Ut(n),e=B(t,e);const i=t.substring(e,e+6).toUpperCase();if(!this.suppressValidationErr&&i!=="SYSTEM"&&i!=="PUBLIC")throw new Error(`Expected SYSTEM or PUBLIC, found "${i}"`);e+=i.length,e=B(t,e);let r=null,o=null;if(i==="PUBLIC")[e,r]=this.readIdentifierVal(t,e,"publicIdentifier"),e=B(t,e),(t[e]==='"'||t[e]==="'")&&([e,o]=this.readIdentifierVal(t,e,"systemIdentifier"));else if(i==="SYSTEM"&&([e,o]=this.readIdentifierVal(t,e,"systemIdentifier"),!this.suppressValidationErr&&!o))throw new Error("Missing mandatory system identifier for SYSTEM notation");return{notationName:n,publicIdentifier:r,systemIdentifier:o,index:--e}}readIdentifierVal(t,e,n){let i="";const r=t[e];if(r!=='"'&&r!=="'")throw new Error(`Expected quoted string, found "${r}"`);for(e++;e<t.length&&t[e]!==r;)i+=t[e],e++;if(t[e]!==r)throw new Error(`Unterminated ${n} value`);return e++,[e,i]}readElementExp(t,e){e=B(t,e);let n="";for(;e<t.length&&!/\s/.test(t[e]);)n+=t[e],e++;if(!this.suppressValidationErr&&!be(n))throw new Error(`Invalid element name: "${n}"`);e=B(t,e);let i="";if(t[e]==="E"&&ut(t,"MPTY",e))e+=4;else if(t[e]==="A"&&ut(t,"NY",e))e+=2;else if(t[e]==="("){for(e++;e<t.length&&t[e]!==")";)i+=t[e],e++;if(t[e]!==")")throw new Error("Unterminated content model")}else if(!this.suppressValidationErr)throw new Error(`Invalid Element Expression, found "${t[e]}"`);return{elementName:n,contentModel:i.trim(),index:e}}readAttlistExp(t,e){e=B(t,e);let n="";for(;e<t.length&&!/\s/.test(t[e]);)n+=t[e],e++;Ut(n),e=B(t,e);let i="";for(;e<t.length&&!/\s/.test(t[e]);)i+=t[e],e++;if(!Ut(i))throw new Error(`Invalid attribute name: "${i}"`);e=B(t,e);let r="";if(t.substring(e,e+8).toUpperCase()==="NOTATION"){if(r="NOTATION",e+=8,e=B(t,e),t[e]!=="(")throw new Error(`Expected '(', found "${t[e]}"`);e++;let a=[];for(;e<t.length&&t[e]!==")";){let c="";for(;e<t.length&&t[e]!=="|"&&t[e]!==")";)c+=t[e],e++;if(c=c.trim(),!Ut(c))throw new Error(`Invalid notation name: "${c}"`);a.push(c),t[e]==="|"&&(e++,e=B(t,e))}if(t[e]!==")")throw new Error("Unterminated list of notations");e++,r+=" ("+a.join("|")+")"}else{for(;e<t.length&&!/\s/.test(t[e]);)r+=t[e],e++;const a=["CDATA","ID","IDREF","IDREFS","ENTITY","ENTITIES","NMTOKEN","NMTOKENS"];if(!this.suppressValidationErr&&!a.includes(r.toUpperCase()))throw new Error(`Invalid attribute type: "${r}"`)}e=B(t,e);let o="";return t.substring(e,e+8).toUpperCase()==="#REQUIRED"?(o="#REQUIRED",e+=8):t.substring(e,e+7).toUpperCase()==="#IMPLIED"?(o="#IMPLIED",e+=7):[e,o]=this.readIdentifierVal(t,e,"ATTLIST"),{elementName:n,attributeName:i,attributeType:r,defaultValue:o,index:e}}}const B=(s,t)=>{for(;t<s.length&&/\s/.test(s[t]);)t++;return t};function ut(s,t,e){for(let n=0;n<t.length;n++)if(t[n]!==s[e+n+1])return!1;return!0}function Ut(s){if(be(s))return s;throw new Error(`Invalid entity name ${s}`)}const wi=/^[-+]?0x[a-fA-F0-9]+$/,Ei=/^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/,bi={hex:!0,leadingZeros:!0,decimalPoint:".",eNotation:!0};function _i(s,t={}){if(t=Object.assign({},bi,t),!s||typeof s!="string")return s;let e=s.trim();if(t.skipLike!==void 0&&t.skipLike.test(e))return s;if(s==="0")return 0;if(t.hex&&wi.test(e))return Ni(e,16);if(e.includes("e")||e.includes("E"))return Ii(s,e,t);{const n=Ei.exec(e);if(n){const i=n[1]||"",r=n[2];let o=Ti(n[3]);const a=i?s[r.length+1]===".":s[r.length]===".";if(!t.leadingZeros&&(r.length>1||r.length===1&&!a))return s;{const c=Number(e),l=String(c);if(c===0)return c;if(l.search(/[eE]/)!==-1)return t.eNotation?c:s;if(e.indexOf(".")!==-1)return l==="0"||l===o||l===`${i}${o}`?c:s;let d=r?o:e;return r?d===l||i+d===l?c:s:d===l||d===i+l?c:s}}else return s}}const Ai=/^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;function Ii(s,t,e){if(!e.eNotation)return s;const n=t.match(Ai);if(n){let i=n[1]||"";const r=n[3].indexOf("e")===-1?"E":"e",o=n[2],a=i?s[o.length+1]===r:s[o.length]===r;return o.length>1&&a?s:o.length===1&&(n[3].startsWith(`.${r}`)||n[3][0]===r)?Number(t):e.leadingZeros&&!a?(t=(n[1]||"")+n[3],Number(t)):s}else return s}function Ti(s){return s&&s.indexOf(".")!==-1&&(s=s.replace(/0+$/,""),s==="."?s="0":s[0]==="."?s="0"+s:s[s.length-1]==="."&&(s=s.substring(0,s.length-1))),s}function Ni(s,t){if(parseInt)return parseInt(s,t);if(Number.parseInt)return Number.parseInt(s,t);if(window&&window.parseInt)return window.parseInt(s,t);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}function Un(s){return typeof s=="function"?s:Array.isArray(s)?t=>{for(const e of s)if(typeof e=="string"&&t===e||e instanceof RegExp&&e.test(t))return!0}:()=>!1}class vi{constructor(t){if(this.options=t,this.currentNode=null,this.tagsNodeStack=[],this.docTypeEntities={},this.lastEntities={apos:{regex:/&(apos|#39|#x27);/g,val:"'"},gt:{regex:/&(gt|#62|#x3E);/g,val:">"},lt:{regex:/&(lt|#60|#x3C);/g,val:"<"},quot:{regex:/&(quot|#34|#x22);/g,val:'"'}},this.ampEntity={regex:/&(amp|#38|#x26);/g,val:"&"},this.htmlEntities={space:{regex:/&(nbsp|#160);/g,val:" "},cent:{regex:/&(cent|#162);/g,val:"¢"},pound:{regex:/&(pound|#163);/g,val:"£"},yen:{regex:/&(yen|#165);/g,val:"¥"},euro:{regex:/&(euro|#8364);/g,val:"€"},copyright:{regex:/&(copy|#169);/g,val:"©"},reg:{regex:/&(reg|#174);/g,val:"®"},inr:{regex:/&(inr|#8377);/g,val:"₹"},num_dec:{regex:/&#([0-9]{1,7});/g,val:(e,n)=>String.fromCodePoint(Number.parseInt(n,10))},num_hex:{regex:/&#x([0-9a-fA-F]{1,6});/g,val:(e,n)=>String.fromCodePoint(Number.parseInt(n,16))}},this.addExternalEntities=Si,this.parseXml=Mi,this.parseTextData=Oi,this.resolveNameSpace=ki,this.buildAttributesMap=Ri,this.isItStopNode=Hi,this.replaceEntitiesValue=$i,this.readStopNodeData=Wi,this.saveTextToParentTag=Pi,this.addChild=xi,this.ignoreAttributesFn=Un(this.options.ignoreAttributes),this.options.stopNodes&&this.options.stopNodes.length>0){this.stopNodesExact=new Set,this.stopNodesWildcard=new Set;for(let e=0;e<this.options.stopNodes.length;e++){const n=this.options.stopNodes[e];typeof n=="string"&&(n.startsWith("*.")?this.stopNodesWildcard.add(n.substring(2)):this.stopNodesExact.add(n))}}}}function Si(s){const t=Object.keys(s);for(let e=0;e<t.length;e++){const n=t[e];this.lastEntities[n]={regex:new RegExp("&"+n+";","g"),val:s[n]}}}function Oi(s,t,e,n,i,r,o){if(s!==void 0&&(this.options.trimValues&&!n&&(s=s.trim()),s.length>0)){o||(s=this.replaceEntitiesValue(s));const a=this.options.tagValueProcessor(t,s,e,i,r);return a==null?s:typeof a!=typeof s||a!==s?a:this.options.trimValues?$e(s,this.options.parseTagValue,this.options.numberParseOptions):s.trim()===s?$e(s,this.options.parseTagValue,this.options.numberParseOptions):s}}function ki(s){if(this.options.removeNSPrefix){const t=s.split(":"),e=s.charAt(0)==="/"?"/":"";if(t[0]==="xmlns")return"";t.length===2&&(s=e+t[1])}return s}const Ci=new RegExp(`([^\\s=]+)\\s*(=\\s*(['"])([\\s\\S]*?)\\3)?`,"gm");function Ri(s,t){if(this.options.ignoreAttributes!==!0&&typeof s=="string"){const e=zn(s,Ci),n=e.length,i={};for(let r=0;r<n;r++){const o=this.resolveNameSpace(e[r][1]);if(this.ignoreAttributesFn(o,t))continue;let a=e[r][4],c=this.options.attributeNamePrefix+o;if(o.length)if(this.options.transformAttributeName&&(c=this.options.transformAttributeName(c)),c==="__proto__"&&(c="#__proto__"),a!==void 0){this.options.trimValues&&(a=a.trim()),a=this.replaceEntitiesValue(a);const l=this.options.attributeValueProcessor(o,a,t);l==null?i[c]=a:typeof l!=typeof a||l!==a?i[c]=l:i[c]=$e(a,this.options.parseAttributeValue,this.options.numberParseOptions)}else this.options.allowBooleanAttributes&&(i[c]=!0)}if(!Object.keys(i).length)return;if(this.options.attributesGroupName){const r={};return r[this.options.attributesGroupName]=i,r}return i}}const Mi=function(s){s=s.replace(/\r\n?/g,`
|
|
4
|
+
`);const t=new mt("!xml");let e=t,n="",i="";const r=new yi(this.options.processEntities);for(let o=0;o<s.length;o++)if(s[o]==="<")if(s[o+1]==="/"){const c=wt(s,">",o,"Closing Tag is not closed.");let l=s.substring(o+2,c).trim();if(this.options.removeNSPrefix){const u=l.indexOf(":");u!==-1&&(l=l.substr(u+1))}this.options.transformTagName&&(l=this.options.transformTagName(l)),e&&(n=this.saveTextToParentTag(n,e,i));const d=i.substring(i.lastIndexOf(".")+1);if(l&&this.options.unpairedTags.indexOf(l)!==-1)throw new Error(`Unpaired tag can not be used as closing tag: </${l}>`);let h=0;d&&this.options.unpairedTags.indexOf(d)!==-1?(h=i.lastIndexOf(".",i.lastIndexOf(".")-1),this.tagsNodeStack.pop()):h=i.lastIndexOf("."),i=i.substring(0,h),e=this.tagsNodeStack.pop(),n="",o=c}else if(s[o+1]==="?"){let c=xe(s,o,!1,"?>");if(!c)throw new Error("Pi Tag is not closed.");if(n=this.saveTextToParentTag(n,e,i),!(this.options.ignoreDeclaration&&c.tagName==="?xml"||this.options.ignorePiTags)){const l=new mt(c.tagName);l.add(this.options.textNodeName,""),c.tagName!==c.tagExp&&c.attrExpPresent&&(l[":@"]=this.buildAttributesMap(c.tagExp,i)),this.addChild(e,l,i,o)}o=c.closeIndex+1}else if(s.substr(o+1,3)==="!--"){const c=wt(s,"-->",o+4,"Comment is not closed.");if(this.options.commentPropName){const l=s.substring(o+4,c-2);n=this.saveTextToParentTag(n,e,i),e.add(this.options.commentPropName,[{[this.options.textNodeName]:l}])}o=c}else if(s.substr(o+1,2)==="!D"){const c=r.readDocType(s,o);this.docTypeEntities=c.entities,o=c.i}else if(s.substr(o+1,2)==="!["){const c=wt(s,"]]>",o,"CDATA is not closed.")-2,l=s.substring(o+9,c);n=this.saveTextToParentTag(n,e,i);let d=this.parseTextData(l,e.tagname,i,!0,!1,!0,!0);d==null&&(d=""),this.options.cdataPropName?e.add(this.options.cdataPropName,[{[this.options.textNodeName]:l}]):e.add(this.options.textNodeName,d),o=c+2}else{let c=xe(s,o,this.options.removeNSPrefix),l=c.tagName;const d=c.rawTagName;let h=c.tagExp,u=c.attrExpPresent,m=c.closeIndex;if(this.options.transformTagName){const b=this.options.transformTagName(l);h===l&&(h=b),l=b}e&&n&&e.tagname!=="!xml"&&(n=this.saveTextToParentTag(n,e,i,!1));const f=e;f&&this.options.unpairedTags.indexOf(f.tagname)!==-1&&(e=this.tagsNodeStack.pop(),i=i.substring(0,i.lastIndexOf("."))),l!==t.tagname&&(i+=i?"."+l:l);const w=o;if(this.isItStopNode(this.stopNodesExact,this.stopNodesWildcard,i,l)){let b="";if(h.length>0&&h.lastIndexOf("/")===h.length-1)l[l.length-1]==="/"?(l=l.substr(0,l.length-1),i=i.substr(0,i.length-1),h=l):h=h.substr(0,h.length-1),o=c.closeIndex;else if(this.options.unpairedTags.indexOf(l)!==-1)o=c.closeIndex;else{const O=this.readStopNodeData(s,d,m+1);if(!O)throw new Error(`Unexpected end of ${d}`);o=O.i,b=O.tagContent}const A=new mt(l);l!==h&&u&&(A[":@"]=this.buildAttributesMap(h,i)),b&&(b=this.parseTextData(b,l,i,!0,u,!0,!0)),i=i.substr(0,i.lastIndexOf(".")),A.add(this.options.textNodeName,b),this.addChild(e,A,i,w)}else{if(h.length>0&&h.lastIndexOf("/")===h.length-1){if(l[l.length-1]==="/"?(l=l.substr(0,l.length-1),i=i.substr(0,i.length-1),h=l):h=h.substr(0,h.length-1),this.options.transformTagName){const A=this.options.transformTagName(l);h===l&&(h=A),l=A}const b=new mt(l);l!==h&&u&&(b[":@"]=this.buildAttributesMap(h,i)),this.addChild(e,b,i,w),i=i.substr(0,i.lastIndexOf("."))}else{const b=new mt(l);this.tagsNodeStack.push(e),l!==h&&u&&(b[":@"]=this.buildAttributesMap(h,i)),this.addChild(e,b,i,w),e=b}n="",o=m}}else n+=s[o];return t.child};function xi(s,t,e,n){this.options.captureMetaData||(n=void 0);const i=this.options.updateTag(t.tagname,e,t[":@"]);i===!1||(typeof i=="string"&&(t.tagname=i),s.addChild(t,n))}const $i=function(s){if(this.options.processEntities){for(let t in this.docTypeEntities){const e=this.docTypeEntities[t];s=s.replace(e.regx,e.val)}for(let t in this.lastEntities){const e=this.lastEntities[t];s=s.replace(e.regex,e.val)}if(this.options.htmlEntities)for(let t in this.htmlEntities){const e=this.htmlEntities[t];s=s.replace(e.regex,e.val)}s=s.replace(this.ampEntity.regex,this.ampEntity.val)}return s};function Pi(s,t,e,n){return s&&(n===void 0&&(n=t.child.length===0),s=this.parseTextData(s,t.tagname,e,!1,t[":@"]?Object.keys(t[":@"]).length!==0:!1,n),s!==void 0&&s!==""&&t.add(this.options.textNodeName,s),s=""),s}function Hi(s,t,e,n){return!!(t&&t.has(n)||s&&s.has(e))}function Bi(s,t,e=">"){let n,i="";for(let r=t;r<s.length;r++){let o=s[r];if(n)o===n&&(n="");else if(o==='"'||o==="'")n=o;else if(o===e[0])if(e[1]){if(s[r+1]===e[1])return{data:i,index:r}}else return{data:i,index:r};else o===" "&&(o=" ");i+=o}}function wt(s,t,e,n){const i=s.indexOf(t,e);if(i===-1)throw new Error(n);return i+t.length-1}function xe(s,t,e,n=">"){const i=Bi(s,t+1,n);if(!i)return;let r=i.data;const o=i.index,a=r.search(/\s/);let c=r,l=!0;a!==-1&&(c=r.substring(0,a),r=r.substring(a+1).trimStart());const d=c;if(e){const h=c.indexOf(":");h!==-1&&(c=c.substr(h+1),l=c!==i.data.substr(h+1))}return{tagName:c,tagExp:r,closeIndex:o,attrExpPresent:l,rawTagName:d}}function Wi(s,t,e){const n=e;let i=1;for(;e<s.length;e++)if(s[e]==="<")if(s[e+1]==="/"){const r=wt(s,">",e,`${t} is not closed`);if(s.substring(e+2,r).trim()===t&&(i--,i===0))return{tagContent:s.substring(n,e),i:r};e=r}else if(s[e+1]==="?")e=wt(s,"?>",e+1,"StopNode is not closed.");else if(s.substr(e+1,3)==="!--")e=wt(s,"-->",e+3,"StopNode is not closed.");else if(s.substr(e+1,2)==="![")e=wt(s,"]]>",e,"StopNode is not closed.")-2;else{const r=xe(s,e,">");r&&((r&&r.tagName)===t&&r.tagExp[r.tagExp.length-1]!=="/"&&i++,e=r.closeIndex)}}function $e(s,t,e){if(t&&typeof s=="string"){const n=s.trim();return n==="true"?!0:n==="false"?!1:_i(s,e)}else return ii(s)?s:""}const Te=mt.getMetaDataSymbol();function Di(s,t){return jn(s,t)}function jn(s,t,e){let n;const i={};for(let r=0;r<s.length;r++){const o=s[r],a=Li(o);let c="";if(e===void 0?c=a:c=e+"."+a,a===t.textNodeName)n===void 0?n=o[a]:n+=""+o[a];else{if(a===void 0)continue;if(o[a]){let l=jn(o[a],t,c);const d=zi(l,t);o[Te]!==void 0&&(l[Te]=o[Te]),o[":@"]?Ki(l,o[":@"],c,t):Object.keys(l).length===1&&l[t.textNodeName]!==void 0&&!t.alwaysCreateTextNode?l=l[t.textNodeName]:Object.keys(l).length===0&&(t.alwaysCreateTextNode?l[t.textNodeName]="":l=""),i[a]!==void 0&&i.hasOwnProperty(a)?(Array.isArray(i[a])||(i[a]=[i[a]]),i[a].push(l)):t.isArray(a,c,d)?i[a]=[l]:i[a]=l}}}return typeof n=="string"?n.length>0&&(i[t.textNodeName]=n):n!==void 0&&(i[t.textNodeName]=n),i}function Li(s){const t=Object.keys(s);for(let e=0;e<t.length;e++){const n=t[e];if(n!==":@")return n}}function Ki(s,t,e,n){if(t){const i=Object.keys(t),r=i.length;for(let o=0;o<r;o++){const a=i[o];n.isArray(a,e+"."+a,!0,!0)?s[a]=[t[a]]:s[a]=t[a]}}}function zi(s,t){const{textNodeName:e}=t,n=Object.keys(s).length;return!!(n===0||n===1&&(s[e]||typeof s[e]=="boolean"||s[e]===0))}class Ui{constructor(t){this.externalEntities={},this.options=mi(t)}parse(t,e){if(typeof t!="string"&&t.toString)t=t.toString();else if(typeof t!="string")throw new Error("XML data is accepted in String or Bytes[] form.");if(e){e===!0&&(e={});const r=oi(t,e);if(r!==!0)throw Error(`${r.err.msg}:${r.err.line}:${r.err.col}`)}const n=new vi(this.options);n.addExternalEntities(this.externalEntities);const i=n.parseXml(t);return this.options.preserveOrder||i===void 0?i:Di(i,this.options)}addEntity(t,e){if(e.indexOf("&")!==-1)throw new Error("Entity value can't have '&'");if(t.indexOf("&")!==-1||t.indexOf(";")!==-1)throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '
'");if(e==="&")throw new Error("An entity with value '&' is not permitted");this.externalEntities[t]=e}static getMetaDataSymbol(){return mt.getMetaDataSymbol()}}const ji=`
|
|
5
|
+
`;function Fi(s,t){let e="";return t.format&&t.indentBy.length>0&&(e=ji),Fn(s,t,"",e)}function Fn(s,t,e,n){let i="",r=!1;for(let o=0;o<s.length;o++){const a=s[o],c=Gi(a);if(c===void 0)continue;let l="";if(e.length===0?l=c:l=`${e}.${c}`,c===t.textNodeName){let f=a[c];Zi(l,t)||(f=t.tagValueProcessor(c,f),f=Gn(f,t)),r&&(i+=n),i+=f,r=!1;continue}else if(c===t.cdataPropName){r&&(i+=n),i+=`<![CDATA[${a[c][0][t.textNodeName]}]]>`,r=!1;continue}else if(c===t.commentPropName){i+=n+`<!--${a[c][0][t.textNodeName]}-->`,r=!0;continue}else if(c[0]==="?"){const f=Tn(a[":@"],t),w=c==="?xml"?"":n;let b=a[c][0][t.textNodeName];b=b.length!==0?" "+b:"",i+=w+`<${c}${b}${f}?>`,r=!0;continue}let d=n;d!==""&&(d+=t.indentBy);const h=Tn(a[":@"],t),u=n+`<${c}${h}`,m=Fn(a[c],t,l,d);t.unpairedTags.indexOf(c)!==-1?t.suppressUnpairedNode?i+=u+">":i+=u+"/>":(!m||m.length===0)&&t.suppressEmptyNode?i+=u+"/>":m&&m.endsWith(">")?i+=u+`>${m}${n}</${c}>`:(i+=u+">",m&&n!==""&&(m.includes("/>")||m.includes("</"))?i+=n+t.indentBy+m+n:i+=m,i+=`</${c}>`),r=!0}return i}function Gi(s){const t=Object.keys(s);for(let e=0;e<t.length;e++){const n=t[e];if(s.hasOwnProperty(n)&&n!==":@")return n}}function Tn(s,t){let e="";if(s&&!t.ignoreAttributes)for(let n in s){if(!s.hasOwnProperty(n))continue;let i=t.attributeValueProcessor(n,s[n]);i=Gn(i,t),i===!0&&t.suppressBooleanAttributes?e+=` ${n.substr(t.attributeNamePrefix.length)}`:e+=` ${n.substr(t.attributeNamePrefix.length)}="${i}"`}return e}function Zi(s,t){s=s.substr(0,s.length-t.textNodeName.length-1);let e=s.substr(s.lastIndexOf(".")+1);for(let n in t.stopNodes)if(t.stopNodes[n]===s||t.stopNodes[n]==="*."+e)return!0;return!1}function Gn(s,t){if(s&&s.length>0&&t.processEntities)for(let e=0;e<t.entities.length;e++){const n=t.entities[e];s=s.replace(n.regex,n.val)}return s}const Yi={attributeNamePrefix:"@_",attributesGroupName:!1,textNodeName:"#text",ignoreAttributes:!0,cdataPropName:!1,format:!1,indentBy:" ",suppressEmptyNode:!1,suppressUnpairedNode:!0,suppressBooleanAttributes:!0,tagValueProcessor:function(s,t){return t},attributeValueProcessor:function(s,t){return t},preserveOrder:!1,commentPropName:!1,unpairedTags:[],entities:[{regex:new RegExp("&","g"),val:"&"},{regex:new RegExp(">","g"),val:">"},{regex:new RegExp("<","g"),val:"<"},{regex:new RegExp("'","g"),val:"'"},{regex:new RegExp('"',"g"),val:"""}],processEntities:!0,stopNodes:[],oneListGroup:!1};function ct(s){this.options=Object.assign({},Yi,s),this.options.ignoreAttributes===!0||this.options.attributesGroupName?this.isAttribute=function(){return!1}:(this.ignoreAttributesFn=Un(this.options.ignoreAttributes),this.attrPrefixLen=this.options.attributeNamePrefix.length,this.isAttribute=Xi),this.processTextOrObjNode=Vi,this.options.format?(this.indentate=Ji,this.tagEndChar=`>
|
|
6
6
|
`,this.newLine=`
|
|
7
|
-
`):(this.indentate=function(){return""},this.tagEndChar=">",this.newLine="")}ct.prototype.build=function(s){return this.options.preserveOrder?ji(s,this.options):(Array.isArray(s)&&this.options.arrayNodeName&&this.options.arrayNodeName.length>1&&(s={[this.options.arrayNodeName]:s}),this.j2x(s,0,[]).val)};ct.prototype.j2x=function(s,t,e){let n="",i="";const r=e.join(".");for(let o in s)if(Object.prototype.hasOwnProperty.call(s,o))if(typeof s[o]>"u")this.isAttribute(o)&&(i+="");else if(s[o]===null)this.isAttribute(o)||o===this.options.cdataPropName?i+="":o[0]==="?"?i+=this.indentate(t)+"<"+o+"?"+this.tagEndChar:i+=this.indentate(t)+"<"+o+"/"+this.tagEndChar;else if(s[o]instanceof Date)i+=this.buildTextValNode(s[o],o,"",t);else if(typeof s[o]!="object"){const a=this.isAttribute(o);if(a&&!this.ignoreAttributesFn(a,r))n+=this.buildAttrPairStr(a,""+s[o]);else if(!a)if(o===this.options.textNodeName){let c=this.options.tagValueProcessor(o,""+s[o]);i+=this.replaceEntitiesValue(c)}else i+=this.buildTextValNode(s[o],o,"",t)}else if(Array.isArray(s[o])){const a=s[o].length;let c="",l="";for(let h=0;h<a;h++){const d=s[o][h];if(!(typeof d>"u"))if(d===null)o[0]==="?"?i+=this.indentate(t)+"<"+o+"?"+this.tagEndChar:i+=this.indentate(t)+"<"+o+"/"+this.tagEndChar;else if(typeof d=="object")if(this.options.oneListGroup){const u=this.j2x(d,t+1,e.concat(o));c+=u.val,this.options.attributesGroupName&&d.hasOwnProperty(this.options.attributesGroupName)&&(l+=u.attrStr)}else c+=this.processTextOrObjNode(d,o,t,e);else if(this.options.oneListGroup){let u=this.options.tagValueProcessor(o,d);u=this.replaceEntitiesValue(u),c+=u}else c+=this.buildTextValNode(d,o,"",t)}this.options.oneListGroup&&(c=this.buildObjectNode(c,o,l,t)),i+=c}else if(this.options.attributesGroupName&&o===this.options.attributesGroupName){const a=Object.keys(s[o]),c=a.length;for(let l=0;l<c;l++)n+=this.buildAttrPairStr(a[l],""+s[o][a[l]])}else i+=this.processTextOrObjNode(s[o],o,t,e);return{attrStr:n,val:i}};ct.prototype.buildAttrPairStr=function(s,t){return t=this.options.attributeValueProcessor(s,""+t),t=this.replaceEntitiesValue(t),this.options.suppressBooleanAttributes&&t==="true"?" "+s:" "+s+'="'+t+'"'};function Yi(s,t,e,n){const i=this.j2x(s,e+1,n.concat(t));return s[this.options.textNodeName]!==void 0&&Object.keys(s).length===1?this.buildTextValNode(s[this.options.textNodeName],t,i.attrStr,e):this.buildObjectNode(i.val,t,i.attrStr,e)}ct.prototype.buildObjectNode=function(s,t,e,n){if(s==="")return t[0]==="?"?this.indentate(n)+"<"+t+e+"?"+this.tagEndChar:this.indentate(n)+"<"+t+e+this.closeTag(t)+this.tagEndChar;{let i="</"+t+this.tagEndChar,r="";return t[0]==="?"&&(r="?",i=""),(e||e==="")&&s.indexOf("<")===-1?this.indentate(n)+"<"+t+e+r+">"+s+i:this.options.commentPropName!==!1&&t===this.options.commentPropName&&r.length===0?this.indentate(n)+`<!--${s}-->`+this.newLine:this.indentate(n)+"<"+t+e+r+this.tagEndChar+s+this.indentate(n)+i}};ct.prototype.closeTag=function(s){let t="";return this.options.unpairedTags.indexOf(s)!==-1?this.options.suppressUnpairedNode||(t="/"):this.options.suppressEmptyNode?t="/":t=`></${s}`,t};ct.prototype.buildTextValNode=function(s,t,e,n){if(this.options.cdataPropName!==!1&&t===this.options.cdataPropName)return this.indentate(n)+`<![CDATA[${s}]]>`+this.newLine;if(this.options.commentPropName!==!1&&t===this.options.commentPropName)return this.indentate(n)+`<!--${s}-->`+this.newLine;if(t[0]==="?")return this.indentate(n)+"<"+t+e+"?"+this.tagEndChar;{let i=this.options.tagValueProcessor(t,s);return i=this.replaceEntitiesValue(i),i===""?this.indentate(n)+"<"+t+e+this.closeTag(t)+this.tagEndChar:this.indentate(n)+"<"+t+e+">"+i+"</"+t+this.tagEndChar}};ct.prototype.replaceEntitiesValue=function(s){if(s&&s.length>0&&this.options.processEntities)for(let t=0;t<this.options.entities.length;t++){const e=this.options.entities[t];s=s.replace(e.regex,e.val)}return s};function Vi(s){return this.options.indentBy.repeat(s)}function Ji(s){return s.startsWith(this.options.attributeNamePrefix)&&s!==this.options.textNodeName?s.substr(this.attrPrefixLen):!1}class lt{type;attrs={};styles={};deleteMarker=!1;constructor(t){this.type=t}dx(t){return this.attrs.x==null?this.attrs.x=t:this.attrs.x+=t,this}dy(t){return this.attrs.y==null?this.attrs.y=t:this.attrs.y+=t,this}x(t){return this.attrs.x=t,this}y(t){return this.attrs.y=t,this}size(t,e){return this.attrs.width=t,this.attrs.height=e,this}remove(){this.deleteMarker=!0}left(...t){return`<${[this.type,Vn(this.attrs),ar(this.styles),...t].filter(e=>e!="").join(" ")}>`}right(){return`</${this.type}>`}center(){return""}toString(){return this.deleteMarker?"":`${this.left()}${this.center()}${this.right()}`}attr(t){if(typeof t=="string")return this.attrs[t]??"";for(const[e,n]of Object.entries(t))this.attrs[e]=n;return this}css(t){return this.styles={...this.styles,...t},this}svg(){return this.toString()}}class qe extends lt{attrs={};constructor(t){super("image"),this.attrs={...this.attrs,href:t}}load(t){return this.attrs.href=t,this}}class be extends lt{attrs={};constructor(t){super("use"),this.attrs={...this.attrs,href:this.make(t)}}use(t){return this.attrs.href=`#${t}`,this}make(t){return t==null?t:`#${t}`}}class Qe extends lt{attrs={};constructor(){super("rect")}fill(t){return this.attrs.fill=t,this}stroke(t){return this.attrs.stroke=t,this}}class At extends lt{attrs;_text="";constructor(t=""){super("text"),this._text=t,this.attrs={}}plain(t){return this._text=t,this}font(t){return this.attrs.fontFamily=t.family,this.attrs.fontSize=t.size,this}center(){return this._text}}let tn=class extends lt{raw;constructor(t){super("symbol"),this.raw=t}id(){return this.attr("id")}center(){return this.raw}};class T extends lt{children=[];rotateMatrix;translateMatrix;constructor(){super("g")}add(t){return this.children.push(t),this}rotate(t,e,n){return this.rotateMatrix=Xs(t,e,n),this}translate(t,e){return this.translateMatrix=Me(t,e),this}center(){return this.children.map(t=>t.toString()).join("")}left(...t){const e=[this.translateMatrix,this.rotateMatrix].filter(n=>n!=null);return e.length==0?super.left():super.left(or(Gs(e)))}each(t,e){for(let n=0;n<this.children.length;n++){const i=this.children[n];i instanceof T&&e&&i.each(t,!0),t(n,this.children)}}}const Xi=['xmlns="http://www.w3.org/2000/svg"','version="1.1"','xmlns:xlink="http://www.w3.org/1999/xlink"'];class Zn extends lt{children=[];constructor(){super("svg")}viewBox;add(t){return this.children.push(t),this}center(){return this.children.map(t=>t.toString()).join("")}left(...t){return`<${[this.type,...Xi,Vn(this.attrs),rr(this.viewBox)].filter(e=>e!="").join(" ")}>`}viewbox(t,e,n,i){return this.viewBox={x:t,y:e,width:n,height:i},this}importSymbol(t){for(const e of cr(t))this.add(e);return this}x(t){throw new Error("unimplemented")}y(t){throw new Error("unimplemented")}dx(t){throw new Error("unimplemented")}dy(t){throw new Error("unimplemented")}each(t,e){for(let n=0;n<this.children.length;n++){const i=this.children[n];i instanceof T&&e&&i.each(t,!0),t(n,this.children)}}}function Yn(){return new Zn}const qi=Yn,Qi=T,tr=qe,er=be,nr=Qe,sr=At;function ir(s){return s.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}function rr(s){return s==null?"":`viewBox="${s.x} ${s.y} ${s.width} ${s.height}"`}function or(s){return s==null?"":`transform="${qs(s)}"`}function Vn(s){return Object.entries(s).filter(([t,e])=>e!==void 0).map(([t,e])=>`${ir(t)}="${e}"`).join(" ")}function ar(s){const t=Object.entries(s).map(([e,n])=>`${e}: ${n};`).join(" ");return t!=""?`style="${t}"`:""}function*cr(s){const t=new zi({ignoreAttributes:!1}),e=new ct({ignoreAttributes:!1}),n=t.parse(s);for(const i of n.svg.symbol){const r=e.build(i),o=new tn(r);for(const[a,c]of Object.entries(i))a.startsWith("@_")&&(o.attrs[a.substring(2)]=c);yield o}}const Ne=(s,t)=>{const e=q(s.tiles[0],t),n=e.baseHeight,i=e.baseWidth;if(s.is(E.SHO_KAN))return{width:i*2+n,height:Math.max(i*2,n)};const r=s.tiles.reduce((a,c)=>{const l=q(c,t).height;return l>a?l:a},0);return{width:s.tiles.reduce((a,c)=>a+q(c,t).width,0),height:r}},q=(s,t)=>{const e=parseFloat((rt.HEIGHT*t).toPrecision(5)),n=parseFloat((rt.WIDTH*t).toPrecision(5)),i=s.has(g.HORIZONTAL)?{width:e,height:n,baseWidth:n,baseHeight:e}:{width:n,height:e,w:n,baseWidth:n,baseHeight:e};return(s.has(g.TSUMO)||s.has(g.IMAGE_DORA))&&(i.width+=n*rt.TEXT_SCALE),i};class Mt{tileWidth;tileHeight;imageHostUrl;imageExt;scale;svgSprite;constructor(t={}){this.scale=t.scale??1,this.imageHostUrl=t.imageHostUrl??"",this.imageExt=t.imageExt??"svg",this.tileWidth=rt.WIDTH*this.scale,this.tileHeight=rt.HEIGHT*this.scale,this.svgSprite=t.svgSprite??!1}getHorizontalTileYOffset(t){const e=q(t,this.scale);return(e.baseHeight-e.baseWidth)/2}image(t){let e=this.svgSprite?new be().use(Mt.buildID(t)):new qe().load(this.buildURL(t));return t instanceof y&&t.has(g.COLOR_GRAYSCALE)&&e.css({filter:"contrast(65%)"}),e}createImage(t,e,n){const i=q(t,this.scale);return this.image(t).dx(e).dy(n).size(i.baseWidth,i.baseHeight)}createTextImage(t,e,n,i){const r=this.createImage(t,e,n),o=q(t,this.scale),a=o.baseHeight*.2,c=o.baseWidth,l=o.baseHeight,h=new At().plain(i);h.size(o.baseWidth,o.baseHeight).font({family:Ze,size:a}).dx(c).dy(l);const d=new T;return d.add(r).add(h).translate(e,n),d}createRotate90Image(t,e,n,i=!1){const r=this.createImage(t,0,0),o=q(t,this.scale),a=o.baseWidth/2,c=o.baseHeight/2,l=e+this.getHorizontalTileYOffset(t),h=i?n-this.getHorizontalTileYOffset(t):n,d=new T;return d.add(r).translate(l,h).rotate(90,a,c),d}createStick(t){return this.image(t)}static buildID(t){if(t===100)return"stick100";if(t===1e3)return"stick1000";const e=t.t==p.BACK||t.has(g.RED)?0:t.n;return`${t.t}${e}`}buildURL(t){const e=`${Mt.buildID(t)}.${this.imageExt}`;return this.imageHostUrl!=""?`${this.imageHostUrl}${e}`:e}}class en extends Mt{blockMargin=rt.WIDTH*rt.BLOCK_MARGIN_SCALE*this.scale;createBlockDiscard(t){return this.createHorizontalBlock(t.tiles)}createBlockHand(t){return this.createHorizontalBlock(t.tiles)}createBlockChi(t){return this.findHorizontalIndex(t),this.createHorizontalBlock(t.tiles)}createBlockPon(t){return this.findHorizontalIndex(t),this.createHorizontalBlock(t.tiles)}createBlockShoKan(t){const e=this.findHorizontalIndex(t);let n=0;const i=new T,r=t.tiles.reduce((o,a,c)=>a.has(g.HORIZONTAL)?c:o,e);for(let o=0;o<t.tiles.length;o++){const a=q(t.tiles[o],this.scale);if(o==r)continue;if(o==e){const h=t.tiles[e],d=t.tiles[r],u=q(h,this.scale),m=this.createRotate90Image(h,0,0,!0),f=this.createRotate90Image(d,0,u.height,!0);i.add(new T().translate(n,0).add(m).add(f)),n+=u.width;continue}const c=a.width*2-a.height,l=this.createImage(t.tiles[o],n,c);n+=a.width,i.add(l)}return i}createBlockDaiKan(t){return this.findHorizontalIndex(t),this.createHorizontalBlock(t.tiles)}createBlockAnKan(t){return this.createHorizontalBlock(t.tilesWithBack)}createBlockDora(t,e=!0){return this.createBlockSingleText(t,"(ドラ)",e)}createBlockTsumo(t,e=!0){return this.createBlockSingleText(t,"(ツモ)",e)}createBlockSingleText(t,e,n=!0){const i=new T,r=n===!1?this.createImage(t.tiles[0],0,0):this.createTextImage(t.tiles[0],0,0,e);return i.add(r),i}createHorizontalBlock(t){let e=0;const n=new T;for(const i of t){const r=q(i,this.scale);let o;if(i.has(g.HORIZONTAL)){const a=this.getHorizontalTileYOffset(i);o=this.createRotate90Image(i,e,a)}else o=this.createImage(i,e,0);n.add(o),e+=r.width}return n}findHorizontalIndex(t){const e=t.tiles.findIndex(n=>n.has(g.HORIZONTAL));if(e<0)throw new Error(`unable to find horizontal operator in block: ${t}`);return e}}function lr(s,t,e){const{enableDoraText:n,enableTsumoText:i}=e;let r=Ne(s,t.scale),o;if(s instanceof U)o=t.createBlockPon(s);else if(s instanceof F)o=t.createBlockChi(s);else if(s instanceof R)o=t.createBlockAnKan(s);else if(s instanceof M)o=t.createBlockShoKan(s);else if(s instanceof K)o=t.createBlockDaiKan(s);else if(s instanceof _t)o=t.createBlockHand(s);else if(s instanceof we)switch(s.type){case E.IMAGE_DISCARD:o=t.createBlockDiscard(s);break;case E.IMAGE_DORA:{const a=n==!1?new _t([s.tiles[0].clone({remove:g.IMAGE_DORA})]):s;r=Ne(a,t.scale),o=t.createBlockDora(a,n);break}case E.TSUMO:{const a=i==!1?new _t([s.tiles[0].clone({remove:g.TSUMO})]):s;r=Ne(a,t.scale),o=t.createBlockTsumo(a,i);break}default:if(s.tiles.some(a=>a.has(g.TSUMO)||a.has(g.IMAGE_DORA)))throw new Error(`found an unknown block with operator tiles. block: ${s}, type: ${s.type}`);o=t.createBlockDiscard(s)}else throw new Error(`unsupported block type. type: ${s.type}, block: ${s}, instance ${s.constructor.name}`);return{...r,e:o}}const kt=(s,t,e=Jn)=>{const n=t.map(h=>lr(h,s,e)),i=n.reduce((h,d)=>h+d.width,0),o=n.reduce((h,d)=>Math.max(h,d.height),0),a=i+(t.length-1)*s.blockMargin,c=new T;let l=0;for(const h of n){const d=o-h.height,u=new T().translate(l,d);u.add(h.e),c.add(u),l+=h.width+s.blockMargin}return{e:c,width:a,height:o}},Jn={enableDoraText:!0,enableTsumoText:!0},dr=(s,t,e={},n=Jn)=>{const i=new en(e),r=kt(i,t,n);n.responsive||s.size(r.width,r.height),s.viewbox(0,0,r.width,r.height),s.add(r.e)},Xn=()=>{const s=[0,1,2,3,4,5,6,7,8,9];return Object.values(p).flatMap(t=>t===p.BACK?[Mt.buildID(new y(t,0))]:s.map(e=>Mt.buildID(new y(t,e))))},hr=s=>{const t=Xn(),e=[];return s.each((n,i)=>{const r=i[n];if(r instanceof be){const a=r.attr("href").substring(1);t.includes(a)&&e.push(a)}},!0),e},ur=s=>{const t=Xn(),e=hr(s);s.each((n,i)=>{const r=i[n];r instanceof tn&&(t.includes(r.id())&&e.includes(r.id())||r.remove())},!0)},fr=(s,t=6)=>Array.from({length:Math.ceil(s.length/t)},(e,n)=>s.slice(n*t,(n+1)*t)),G=(s,t,e,n,i=0,r=0)=>{const o=new T().add(s);if(n==90){const a=i,c=r-e;return o.rotate(n,0,e).translate(a,c),new T().add(o)}if(n==180){const a=i+t,c=r-e;return o.rotate(n,0,e).translate(a,c),new T().add(o)}if(n==270){const a=i+e,c=r+(t-e);return o.rotate(n,0,e).translate(a,c),new T().add(o)}return new T().add(o)},se=(s,t)=>{const e=new T,n=fr(s);for(let i=0;i<n.length;i++){const r=n[i],o=i*t.tileHeight,a=t.createBlockDiscard(new we(r,E.IMAGE_DISCARD)).translate(0,o);e.add(a)}return{e,width:t.tileWidth*5+t.tileHeight*1,height:t.tileHeight*n.length}},pr=(s,t,e)=>{const n=t.font,i=t.textWidth,r=t.textHeight,o=e.sticks.dead,a=e.sticks.reach,c=Ce.WIDTH*s.scale,l=Ce.HEIGHT*s.scale,h=i*3,d=r+25*s.scale,u=(c+s.tileWidth+i-h)/2,m=new At().plain(e.round).font(n).x(u).y(0),f=s.tileHeight,w=new T().size(c,f).translate(0,d),b={family:n.family,size:n.size*.7},A=s.createStick(1e3).size(c,l).x(0).y(0),O=new At().plain(a.toString()).font(b).dx(c).dy(l),$=s.createStick(100).size(c,l).x(0).y(l+l),dt=new At().plain(o.toString()).font(b).dx(c).dy(l*3);w.add(A),w.add(O),w.add($),w.add(dt);const tt=s.createImage(e.doras[0],0,0).x(c+i).y(0);w.add(tt);const et=new T;return et.add(m),et.add(w),{e:et,width:c+s.tileWidth+i,height:d+s.tileHeight}},gr=(s,t,e=0)=>{const n=kt(s,t.front),i=kt(s,t.right),r=kt(s,t.opposite),o=kt(s,t.left),a=[n.width,i.width,r.width,o.width].reduce((w,b)=>Math.max(w,b)),c=Math.max(e+s.tileHeight*2+s.blockMargin*2,a+s.tileWidth*2+s.blockMargin),l=c,h=G(n.e,n.width,n.height,0).translate((c-n.width)/2,l-n.height),d=G(i.e,i.width,i.height,270).translate(c-i.height,(c-i.width)/2),u=G(r.e,r.width,r.height,180).translate((c-r.width)/2,0),m=G(o.e,o.width,o.height,90).translate(0,(c-o.width)/2),f=new T().size(c,l);return f.add(h),f.add(d),f.add(u),f.add(m),{e:new T().add(f),width:c,height:l}},mr=s=>{const t=Object.values(ye),e=t.indexOf(s);return[...t.slice(e),...t.slice(0,e)]},yr=(s,t,e)=>{const n=s.tileWidth*5+s.tileHeight*1,i=t.font,r=t.textWidth,o=t.textHeight,a=t.numWidth,c=pr(s,t,e);c.e.translate(n/2-c.width/2,n/2-c.height/2);const l=($s,mn,Ps)=>{const Hs=`${$s} ${mn}`,Bs=new At().plain(Hs).font(i).attr(Ps);return{e:new T().add(Bs),width:r+a*mn.toString().length,height:o}},[h,d,u,m]=mr(e.frontPlace),f=e.scores,b=l(h,f.front,{x:n/2,y:n,"dominant-baseline":"text-after-edge","text-anchor":"middle"}).e,A=l(d,f.right,{"dominant-baseline":"text-after-edge","text-anchor":"middle"}),O=G(A.e,A.width,A.height,270).translate(n,n/2-A.width);let $=l(u,f.opposite,{"text-anchor":"middle","dominant-baseline":"text-after-edge"});const dt=G($.e,$.width,$.height,180).translate(n/2-$.width,-$.height),tt=l(m,f.left,{"dominant-baseline":"ideographic","text-anchor":"middle"}),et=G(tt.e,tt.width,tt.height,90).translate(-tt.height,n/2),ht=new T,xs=new Qe().size(n,n).x(0).y(0).fill("none").stroke("#000000");return ht.add(xs),ht.add(c.e),ht.add(b),ht.add(O),ht.add(dt),ht.add(et),{e:ht,width:n,height:n}},wr=(s,t)=>{const e=se(t.front,s),n=se(t.right,s),i=se(t.opposite,s),r=se(t.left,s),o=[e.height,n.height,i.height,r.height].reduce((O,$)=>Math.max(O,$)),a=s.tileWidth*5+s.tileHeight*1,c=o,l=a+o*2+s.blockMargin,h=l,d=new T().size(l,h),u=l/2-a/2,m=h/2-a/2,f=G(e.e,a,c,0).translate(u,h-c),w=G(n.e,a,c,270).translate(l-c,m),b=G(i.e,a,c,180).translate(u,0),A=G(r.e,a,c,90).translate(0,m);return d.add(f),d.add(w),d.add(b),d.add(A),{e:new T().add(d),width:l,height:h}},qn=(s,t,e,n,i)=>{const r=new T,o=wr(s,n),a=gr(s,e,o.height),c=yr(s,t,i);return o.e.translate((a.width-o.width)/2,(a.height-o.height)/2),c.e.translate((a.width-c.width)/2,(a.height-c.height)/2),r.add(a.e),r.add(o.e),r.add(c.e),{e:r,width:a.width,height:a.height}},Er=(s,t,e={},n,i={responsive:!1})=>{const r=new en(e),o=n,{discards:a,hands:c,scoreBoard:l}=es(t),h=qn(r,o,c,a,l);i.responsive||s.size(h.width,h.height),s.viewbox(0,0,h.width,h.height),s.add(h.e)};var ve;function Qn(s){return{lang:s?.lang??ve?.lang,message:s?.message,abortEarly:s?.abortEarly??ve?.abortEarly,abortPipeEarly:s?.abortPipeEarly??ve?.abortPipeEarly}}var _r;function br(s){return _r?.get(s)}var Ar;function Ir(s){return Ar?.get(s)}var Tr;function Nr(s,t){return Tr?.get(s)?.get(t)}function xt(s){const t=typeof s;return t==="string"?`"${s}"`:t==="number"||t==="bigint"||t==="boolean"?`${s}`:t==="object"||t==="function"?(s&&Object.getPrototypeOf(s)?.constructor?.name)??"null":t}function ot(s,t,e,n,i){const r=i&&"input"in i?i.input:e.value,o=i?.expected??s.expects??null,a=i?.received??xt(r),c={kind:s.kind,type:s.type,input:r,expected:o,received:a,message:`Invalid ${t}: ${o?`Expected ${o} but r`:"R"}eceived ${a}`,requirement:s.requirement,path:i?.path,issues:i?.issues,lang:n.lang,abortEarly:n.abortEarly,abortPipeEarly:n.abortPipeEarly},l=s.kind==="schema",h=i?.message??s.message??Nr(s.reference,c.lang)??(l?Ir(c.lang):null)??n.message??br(c.lang);h!==void 0&&(c.message=typeof h=="function"?h(c):h),l&&(e.typed=!1),e.issues?e.issues.push(c):e.issues=[c]}function Kt(s){return{version:1,vendor:"valibot",validate(t){return s["~run"]({value:t},Qn())}}}function vr(s,t){const e=[...new Set(s)];return e.length>1?`(${e.join(` ${t} `)})`:e[0]??"never"}function Pe(s,t){return{kind:"validation",type:"max_value",reference:Pe,async:!1,expects:`<=${s instanceof Date?s.toJSON():xt(s)}`,requirement:s,message:t,"~run"(e,n){return e.typed&&!(e.value<=this.requirement)&&ot(this,"value",e,n,{received:e.value instanceof Date?e.value.toJSON():xt(e.value)}),e}}}function He(s,t){return{kind:"validation",type:"min_value",reference:He,async:!1,expects:`>=${s instanceof Date?s.toJSON():xt(s)}`,requirement:s,message:t,"~run"(e,n){return e.typed&&!(e.value>=this.requirement)&&ot(this,"value",e,n,{received:e.value instanceof Date?e.value.toJSON():xt(e.value)}),e}}}function Sr(s,t,e){return typeof s.fallback=="function"?s.fallback(t,e):s.fallback}function ts(s,t,e){return typeof s.default=="function"?s.default(t,e):s.default}function de(s){return{kind:"schema",type:"number",reference:de,expects:"number",async:!1,message:s,get"~standard"(){return Kt(this)},"~run"(t,e){return typeof t.value=="number"&&!isNaN(t.value)?t.typed=!0:ot(this,"type",t,e),t}}}function z(s,t){return{kind:"schema",type:"optional",reference:z,expects:`(${s.expects} | undefined)`,async:!1,wrapped:s,default:t,get"~standard"(){return Kt(this)},"~run"(e,n){return e.value===void 0&&(this.default!==void 0&&(e.value=ts(this,e,n)),e.value===void 0)?(e.typed=!0,e):this.wrapped["~run"](e,n)}}}function Be(s,t){return{kind:"schema",type:"picklist",reference:Be,expects:vr(s.map(xt),"|"),async:!1,options:s,message:t,get"~standard"(){return Kt(this)},"~run"(e,n){return this.options.includes(e.value)?e.typed=!0:ot(this,"type",e,n),e}}}function $t(s,t){return{kind:"schema",type:"strict_object",reference:$t,expects:"Object",async:!1,entries:s,message:t,get"~standard"(){return Kt(this)},"~run"(e,n){const i=e.value;if(i&&typeof i=="object"){e.typed=!0,e.value={};for(const r in this.entries){const o=this.entries[r];if(r in i||(o.type==="exact_optional"||o.type==="optional"||o.type==="nullish")&&o.default!==void 0){const a=r in i?i[r]:ts(o),c=o["~run"]({value:a},n);if(c.issues){const l={type:"object",origin:"value",input:i,key:r,value:a};for(const h of c.issues)h.path?h.path.unshift(l):h.path=[l],e.issues?.push(h);if(e.issues||(e.issues=c.issues),n.abortEarly){e.typed=!1;break}}c.typed||(e.typed=!1),e.value[r]=c.value}else if(o.fallback!==void 0)e.value[r]=Sr(o);else if(o.type!=="exact_optional"&&o.type!=="optional"&&o.type!=="nullish"&&(ot(this,"key",e,n,{input:void 0,expected:`"${r}"`,path:[{type:"object",origin:"key",input:i,key:r,value:i[r]}]}),n.abortEarly))break}if(!e.issues||!n.abortEarly){for(const r in i)if(!(r in this.entries)){ot(this,"key",e,n,{input:r,expected:"never",path:[{type:"object",origin:"key",input:i,key:r,value:i[r]}]});break}}}else ot(this,"type",e,n);return e}}}function he(s){return{kind:"schema",type:"string",reference:he,expects:"string",async:!1,message:s,get"~standard"(){return Kt(this)},"~run"(t,e){return typeof t.value=="string"?t.typed=!0:ot(this,"type",t,e),t}}}function Nn(...s){return{...s[0],pipe:s,get"~standard"(){return Kt(this)},"~run"(t,e){for(const n of s)if(n.kind!=="metadata"){if(t.issues&&(n.kind==="schema"||n.kind==="transformation")){t.typed=!1;break}(!t.issues||!e.abortEarly&&!e.abortPipeEarly)&&(t=n["~run"](t,e))}return t}}}function Or(s,t,e){const n=s["~run"]({value:t},Qn(e));return{typed:n.typed,success:!n.issues,output:n.value,issues:n.issues}}const ie=z($t({discard:z(he(),""),hand:z(he(),""),score:z(de(),25e3)}),{discard:"",hand:"",score:25e3}),kr=$t({[_.E]:ie,[_.S]:ie,[_.W]:ie,[_.N]:ie}),ft={round:k.E1,sticks:{reach:0,dead:0},doras:_.S,front:_.E},Cr=z($t({round:z(Be(Object.keys(Ye)),ft.round),sticks:z($t({reach:z(Nn(de(),He(0,""),Pe(9,"")),ft.sticks.reach),dead:z(Nn(de(),He(0,""),Pe(9,"")),ft.sticks.dead)}),ft.sticks),doras:z(he(),ft.doras),front:z(Be(Object.keys(ye)),ft.front)}),ft),Rr=$t({...kr.entries,board:Cr}),es=s=>{const t=ns(s);return ss(t)},ns=s=>{const t=Mr(s),e=Or(Rr,t);if(!e.success)throw e.issues;return e.output},Mr=s=>{const t="table",e="board",n=s.split(`
|
|
8
|
-
`).map(a=>a.trim()).filter(a=>a!="");if(n.length==0)throw new Error("empty input");const i=n.shift();if(!i.startsWith(t))throw new Error(`input does not start with table: ${i}`);const r={};let o=[_.E,_.S,_.W,_.N,e];for(;;){const a=n.shift();if(a==null)break;const c=o.find(l=>a.startsWith(l));if(c==null)throw new Error(`encountered unexpected line ${a}`);if(o=o.filter(l=>!a.startsWith(l)),c==e){const[l,h]=$r([...n]);r.board=l,n.splice(0,h)}else{const[l,h]=xr([...n]);r[c]=l,n.splice(0,h)}}return r},Y=(s,t)=>s.replace(t,"").replace(":","").trim(),xr=s=>{const t="hand",e="discard",n="score",i={};let r=0;for(;r<s.length;r++){const o=s[r];if(o.startsWith(t))i.hand=Y(o,t);else if(o.startsWith(e))i.discard=Y(o,e);else if(o.startsWith(n))i.score=Number(Y(o,n));else break}return[i,r]},$r=s=>{const t="doras",e="round",n="front",i="sticks",r="reach",o="dead",a={};let c=0;for(;c<s.length;c++){const l=s[c];if(l.startsWith(t))a.doras=Y(l,t);else if(l.startsWith(e))a.round=Y(l,e);else if(l.startsWith(n))a.front=Y(l,n);else if(l.startsWith(i)){a.sticks={};const h=s[c+1]??"",d=s[c+2]??"";h.startsWith(r)&&(a.sticks.reach=Number(Y(h,r))),h.startsWith(o)&&(a.sticks.dead=Number(Y(h,o))),d.startsWith(r)&&(a.sticks.reach=Number(Y(d,r))),d.startsWith(o)&&(a.sticks.dead=Number(Y(d,o))),a.sticks.dead!=null&&c++,a.sticks.reach!=null&&c++}else break}return[a,c]},ss=s=>{const t=s.board.front,e=Pr(t),n=a=>s[a].discard.replace(/\r?\n/g,""),i={front:new D(n(e.front)).tiles(),right:new D(n(e.right)).tiles(),opposite:new D(n(e.opposite)).tiles(),left:new D(n(e.left)).tiles()},r={front:new D(s[e.front].hand).parse(),right:new D(s[e.right].hand).parse(),opposite:new D(s[e.opposite].hand).parse(),left:new D(s[e.left].hand).parse()},o={round:Ye[s.board.round],frontPlace:ye[t],sticks:s.board.sticks,doras:new D(s.board.doras).tiles(),scores:{front:s[e.front].score,right:s[e.right].score,opposite:s[e.opposite].score,left:s[e.left].score}};return{discards:i,hands:r,scoreBoard:o}},Pr=s=>({front:s,right:bt(s),opposite:bt(bt(s)),left:Ee(s)});function*j(s){const t=s?.filterBy&&s.filterBy.length>0?s?.filterBy:Object.values(p);for(const e of t){if(s?.skipBack&&e==p.BACK)continue;const n=e==p.Z?7:e==p.BACK?1:9;for(let i=1;i<=n;i++)yield[e,i]}}class Ae{data;constructor(t,e=!1){this.data={[p.M]:[0,0,0,0,0,0,0,0,0,0],[p.P]:[0,0,0,0,0,0,0,0,0,0],[p.S]:[0,0,0,0,0,0,0,0,0,0],[p.Z]:[0,0,0,0,0,0,0,0],[p.BACK]:["untouchable",0],called:[],reached:!1,tsumo:null},this.init(t,e)}init(t,e){const n=typeof t=="string"?new D(t).parse():t;for(const i of n){if(i.isCalled()){this.data.called=[...this.called,i];continue}else if(i.is(E.TSUMO)){const r=i.tiles[0];this.inc([r]),this.data.tsumo=r;continue}else if(i.is(E.HAND)){this.inc(i.tiles);continue}else if(typeof t=="string"&&t.split("").every(r=>r===p.BACK)){this.inc(i.tiles);continue}else if(e){this.inc(i.tiles);continue}throw new Error(`unexpected block ${i.type} ${i.toString()}`)}}get hands(){const t=[];for(const[e,n]of j()){let i=this.get(e,n);e!=p.Z&&n==5&&this.get(e,0)>0&&(i-=this.get(e,0),t.push(new y(e,n,[g.RED])));for(let r=0;r<i;r++)t.push(new y(e,n))}if(this.drawn!=null){const e=this.drawn,n=t.findIndex(i=>i.equals(e)&&e.has(g.RED)==i.has(g.RED));I(n>=0,`drawn tile ${this.drawn} not found in hand: ${t.join("")}`),t[n]=t[n].clone({add:g.TSUMO})}return t}toString(){const t=this.called.length>0?`${V}${this.called.join(V)}`:"",e=this.drawn?`${V}${this.drawn.toString()}`:"",n=this.hands.filter(r=>!r.has(g.TSUMO));return`${new _t(n).toString()}${e}${t}`}get called(){return this.data.called}get reached(){return this.data.reached}get drawn(){return this.data.tsumo}get menzen(){return!this.called.some(t=>!(t instanceof R))}sum(t){return Array.from(j({filterBy:[t]})).reduce((e,[n,i])=>e+this.get(n,i),0)}get(t,e){return t==p.BACK?this.data[t][1]:this.data[t][e]}inc(t){const e=[];for(const n of t){const i=n.t!=p.BACK&&this.get(n.t,n.n)>=4,r=n.has(g.RED)&&this.get(n.t,0)>0;if(i||r){this.dec(e);const o=i?`tile ${n} exists more than 4 times`:`red tile ${n} appears more than once`;throw new Error(`invalid hand: ${o} in hand: ${this.toString()}`)}e.push(n),n.t==p.BACK?this.data[n.t][1]+=1:(this.data[n.t][n.n]+=1,n.has(g.RED)&&(this.data[n.t][0]+=1))}return e}dec(t){const e=[];for(const n of t){const i=this.get(n.t,n.n)<1,r=n.has(g.RED)&&this.get(n.t,0)<=0;if(i||r){this.inc(e);const o=i?`tile ${n} does not exist`:`red tile ${n} does not exist`;throw new Error(`invalid hand: ${o} in hand: ${this.toString()}`)}if(e.push(n),n.t==p.BACK?this.data[n.t][1]-=1:(this.data[n.t][n.n]-=1,n.has(g.RED)&&(this.data[n.t][0]-=1)),S(n)&&this.get(n.t,5)==0&&this.get(n.t,0)>0){this.data[n.t][0]=0;const o=e.pop().clone({add:g.RED});e.push(o)}}return e}draw(t){const e=t.clone({add:g.TSUMO});this.inc([e]),this.data.tsumo=e}discard(t){this.dec([t]),this.data.tsumo=null}reach(){if(!this.menzen)throw new Error("cannot declare reach due to called");if(this.data.reached)throw new Error("already declared reach");this.data.reached=!0}call(t){const e=t.tiles.filter(n=>!n.has(g.HORIZONTAL));if(e.length!=t.tiles.length-1)throw new Error(`invalid block: removal tiles: ${e}, block: ${t}`);this.dec(e),this.data.called=[...this.called,t],this.data.tsumo=null}kan(t){if(t instanceof R){this.dec(t.tiles),this.data.called=[...this.called,t],this.data.tsumo=null;return}if(t instanceof M){const e=this.data.called.findIndex(i=>i.is(E.PON)&&i.tiles[0].equals(t.tiles[0]));if(e==-1)throw new Error(`cannot find pon block ${t.tiles[0]} to call shokan: ${t}`);let n=t.tiles[0];n=S(n)?n.clone({remove:g.RED}):n,this.dec([n]),this.data.called=[...this.called.slice(0,e),...this.called.slice(e+1),t],this.data.tsumo=null;return}throw new Error(`unexpected block type ${t}`)}clone(){const t=new Ae(this.toString());return t.data.reached=this.data.reached,t}}class te{hand;constructor(t){this.hand=t}calc(){return Math.min(this.sevenPairs(),this.thirteenOrphans(),this.standardType())}sevenPairs(){if(this.hand.called.length>0)return Number.POSITIVE_INFINITY;let t=0,e=0;for(const[n,i]of j({skipBack:!0}))this.hand.get(n,i)>=2&&t++,this.hand.get(n,i)==1&&e++;return t>7&&(t=7),t+e>=7&&(e=7-t),13-2*t-e}thirteenOrphans(){if(this.hand.called.length>0)return Number.POSITIVE_INFINITY;let t=0,e=0;for(const n of Object.values(p)){if(n==p.BACK)continue;const i=n==p.Z?Pt:J;for(const r of i)this.hand.get(n,r)>=1&&t++,this.hand.get(n,r)>=2&&e++}return e>=1?12-t:13-t}standardType(){const t=n=>{const i=[0,0,0];for(const[u,m]of j({filterBy:[p.Z]}))this.hand.get(u,m)>=3?i[0]++:this.hand.get(u,m)==2?i[1]++:this.hand.get(u,m)==1&&i[2]++;const r=[0,0,0],o=this.hand.get(p.BACK,0),a=o%3;r[0]=Math.floor(o/3),a==2?r[1]=1:a==1&&(r[2]=1);let c=13;const l=this.calcNumberTilePatterns(p.M),h=this.calcNumberTilePatterns(p.P),d=this.calcNumberTilePatterns(p.S);for(const u of[l.patternA,l.patternB])for(const m of[h.patternA,h.patternB])for(const f of[d.patternA,d.patternB]){const w=[this.hand.called.length,0,0];for(let A=0;A<3;A++)w[A]+=u[A]+m[A]+f[A]+i[A]+r[A];const b=this.getStandardTypeShanten(w[0],w[1],w[2],n);b<c&&(c=b)}return c};let e=t(!1);for(const[n,i]of j())if(this.hand.get(n,i)>=2){const r=this.hand.dec(new Array(2).fill(new y(n,i))),o=t(!0);this.hand.inc(r),o<e&&(e=o)}return e}calcNumberTilePatterns(t,e=1){if(e>9)return this.groupRemainingTiles(t);let n=this.calcNumberTilePatterns(t,e+1);if(e<=7&&this.hand.get(t,e)>0&&this.hand.get(t,e+1)>0&&this.hand.get(t,e+2)>0){const i=this.hand.dec([new y(t,e),new y(t,e+1),new y(t,e+2)]),r=this.calcNumberTilePatterns(t,e);this.hand.inc(i),r.patternA[0]++,r.patternB[0]++,(r.patternA[2]<n.patternA[2]||r.patternA[2]==n.patternA[2]&&r.patternA[1]<n.patternA[1])&&(n.patternA=r.patternA),(r.patternB[0]>n.patternB[0]||r.patternB[0]==n.patternB[0]&&r.patternB[1]>n.patternB[1])&&(n.patternB=r.patternB)}if(this.hand.get(t,e)>=3){const i=this.hand.dec(new Array(3).fill(new y(t,e))),r=this.calcNumberTilePatterns(t,e);this.hand.inc(i),r.patternA[0]++,r.patternB[0]++,(r.patternA[2]<n.patternA[2]||r.patternA[2]==n.patternA[2]&&r.patternA[1]<n.patternA[1])&&(n.patternA=r.patternA),(r.patternB[0]>n.patternB[0]||r.patternB[0]==n.patternB[0]&&r.patternB[1]>n.patternB[1])&&(n.patternB=r.patternB)}return n}groupRemainingTiles(t){let e=0,n=0,i=0;for(const[r,o]of j({filterBy:[t]}))i+=this.hand.get(r,o),o<=7&&this.hand.get(r,o+1)==0&&this.hand.get(r,o+2)==0&&(e+=i>>1,n+=i%2,i=0);return e+=i>>1,n+=i%2,{patternA:[0,e,n],patternB:[0,e,n]}}getStandardTypeShanten(t,e,n,i){let r=i?4:5;return t>4&&(e+=t-4,t=4),t+e>4&&(n+=t+e-4,e=4-t),t+e+n>r&&(n=r-t-e),i&&e++,13-t*3-e*2-n}}class is{hand;constructor(t){this.hand=t}calc(t){return this.markedHands([...this.sevenPairs(),...this.thirteenOrphans(),...this.nineGates(),...this.standardType()],t)}markedHands(t,e){return t.length==0?[]:t.map(n=>this.markedHand(n,e)).flat()}markedHand(t,e){if(t.length==0)return[];const n=this.hand.drawn!=null||e.has(g.TSUMO)?g.TSUMO:g.RON,i=[],r={};for(let a=0;a<t.length;a++){const c=t[a];if(c.isCalled())continue;const l=c.tiles.findIndex(d=>d.equals(e)&&e.has(g.RED)==d.has(g.RED));if(l<0)continue;const h=Gt(c);r[h]||(r[h]=!0,i.push([a,l]))}if(i.length==0)throw new Error(`tile ${e.toString()} not found in hand: ${t.toString()}`);const o=[];for(const[a,c]of i){const l=[...t],h=l[a],d=h.tiles[c].clone({add:n});l[a]=h.clone({replace:{idx:c,tile:d}}),o.push(l)}return o}sevenPairs(){if(this.hand.called.length>0)return[];const t=[];for(const[e,n]of j({skipBack:!0})){const i=this.hand.get(e,n);if(i!=0)if(i==2){const r=this.hand.dec(new Array(2).fill(new y(e,n)));t.push(new C(r[0],r[1])),this.hand.inc(r)}else return[]}return[t]}thirteenOrphans(){const t=[];let e=!1;for(const n of Object.values(p)){if(n==p.BACK)continue;const i=n==p.Z?Pt:J;for(let r of i)if(this.hand.get(n,r)==1)t.push(new Je(new y(n,r)));else if(this.hand.get(n,r)==2&&e==!1)t.unshift(new C(new y(n,r),new y(n,r))),e=!0;else return[]}return[t]}nineGates(){const t=(e,n,i)=>i.includes(this.hand.get(e,n));for(const e of Object.values(p)){if(e==p.BACK||e==p.Z)continue;const n=t(e,1,[3,4])&&t(e,9,[3,4])&&t(e,2,[1,2])&&t(e,3,[1,2])&&t(e,4,[1,2])&&t(e,5,[1,2])&&t(e,6,[1,2])&&t(e,7,[1,2])&&t(e,8,[1,2]),i=this.hand.sum(e)==14;if(n&&i)return[[new _t(this.hand.hands)]]}return[]}standardType(){let t=[];for(const[e,n]of j())if(this.hand.get(e,n)>=2){const i=new Array(2).fill(new y(e,n));n==5&&this.hand.get(e,0)>0&&this.hand.get(e,n)>=3&&(i[1]=new y(e,n,[g.RED]));const r=this.hand.dec(i),o=this.calcAllBlockCombinations().filter(a=>a.length==4).map(a=>[new C(r[0],r[1]),...a]);t=[...t,...o],this.hand.inc(r)}return t}calcAllBlockCombinations(){return[this.addRedPatterns(p.M,this.handleNumType(p.M)),this.addRedPatterns(p.P,this.handleNumType(p.P)),this.addRedPatterns(p.S,this.handleNumType(p.S)),this.handleZ(),this.handleBack(),[this.hand.called.concat()]].sort((n,i)=>i.length-n.length).reduce((n,i)=>i.length===0?n:n.flatMap(r=>i.map(o=>[...r,...o])),[[]])}handleBack(){const t=p.BACK,e=this.hand.get(t,0);if(e<3)return[];const n=new y(t,0),i=Array(Math.floor(e/3)).fill(new L([n,n,n]));return i.length==0?[]:[i]}handleZ(){const t=[];for(const[e,n]of j({filterBy:[p.Z]})){if(this.hand.get(e,n)==0)continue;if(this.hand.get(e,n)!=3)return[];const i=new y(e,n);t.push(new L([i,i,i]))}return t.length==0?[]:[t]}addRedPattern(t,e){const n=new y(t,5),i=new y(t,5,[g.RED]),r=[];let o=null;const a={};for(let l=0;l<e.length;l++){const h=e[l],d=h.tiles.findIndex(f=>S(f)&&!f.has(g.RED)),u=h.tiles.findIndex(f=>S(f)&&f.has(g.RED));if(u>-1&&(o=[l,u]),u>-1&&d>-1||d<0)continue;const m=Gt(h);a[m]||(a[m]=!0,r.push([l,d]))}if(o==null)return[e];const c=[e];for(const[l,h]of r){const d=[...e],u=d[l];d[l]=u.clone({replace:{idx:h,tile:i}});const m=d[o[0]];d[o[0]]=m.clone({replace:{idx:o[1],tile:n}}),Gt(u)!=Gt(m)&&c.push(d)}return c}addRedPatterns(t,e){return this.hand.get(t,0)>0&&this.hand.get(t,5)>=2?e.map(n=>this.addRedPattern(t,n)).flat():e}handleNumType(t,e=1){if(e>9)return[];if(this.hand.get(t,e)==0)return this.handleNumType(t,e+1);const n=[];if(e<=7&&this.hand.get(t,e)>0&&this.hand.get(t,e+1)>0&&this.hand.get(t,e+2)>0){const i=this.hand.dec([new y(t,e),new y(t,e+1),new y(t,e+2)]);let r=this.handleNumType(t,e);this.hand.inc(i),r.length==0&&(r=[[]]);for(const o of r)n.push([new nt([i[0],i[1],i[2]]),...o])}if(this.hand.get(t,e)==3){const i=this.hand.dec(new Array(3).fill(new y(t,e)));let r=this.handleNumType(t,e);this.hand.inc(i),r.length==0&&(r=[[]]);for(const o of r)n.push([new L([i[0],i[1],i[2]]),...o])}return n}}const Pt=[1,2,3,4,5,6,7],J=[1,9],Ft=s=>{const t=s.boardContext;return{...s,hand:s.hand.map(N.deserialize),boardContext:{...t,doraIndicators:t.doraIndicators.map(y.from),hiddenDoraIndicators:t.hiddenDoraIndicators?.map(y.from)}}},ue=s=>JSON.parse(JSON.stringify(s)),x={MANGAN:2e3,HANEMAN:3e3,DOUBLE:4e3,TRIPLE:6e3,YAKUMAN:8e3,DOUBLE_YAKUMAN:16e3,DEAD_STICK:300,REACH_STICK:1e3},Hr=[{minHan:26,points:x.DOUBLE_YAKUMAN},{minHan:13,points:x.YAKUMAN},{minHan:11,points:x.TRIPLE},{minHan:8,points:x.DOUBLE},{minHan:6,points:x.HANEMAN},{minHan:5,points:x.MANGAN}],Br={[x.MANGAN]:"満貫",[x.HANEMAN]:"跳満",[x.DOUBLE]:"倍満",[x.TRIPLE]:"三倍満"},X={PARENT_RON:6,CHILD_RON:4,PARENT_TSUMO:2,CHILD_TUMO_FROM_PARENT:2,CHILD_TUMO_FROM_CHILD:1};function rs(s){if(s.isYakuman)return"役満";if(s.isCountableYakuman)return"数え役満";const t=Wr(s.base,s.isTsumo,s.isParent),e=Br[s.base];return e?`${s.fu}符${s.han}飜 ${e}${t}`:`${s.fu}符${s.han}飜 ${t}`}function Wr(s,t,e){if(t)return e?`${st(s*X.PARENT_TSUMO)}`:`${st(s*X.CHILD_TUMO_FROM_CHILD)}-${st(s*X.CHILD_TUMO_FROM_PARENT)}`;{const n=e?X.PARENT_RON:X.CHILD_RON;return`${st(s*n)}`}}const st=(s,t=100)=>Math.ceil(s/t)*t;class nn{hand;cfg;constructor(t,e){this.hand=t,this.cfg={doras:e.doraIndicators.map(n=>We(n)),hiddenDoras:e.hiddenDoraIndicators==null?[]:e.hiddenDoraIndicators.map(n=>We(n)),roundWind:y.from(Ln(e.round)),myWind:y.from(e.myWind),reached:e.doubleReached?2:t.reached?1:0,sticks:e.sticks??{dead:0,reach:0},replacementWin:e.replacementWin??!1,quadWin:e.quadWin??!1,finalWallWin:e.finalWallWin??!1,finalDiscardWin:e.finalDiscardWin??!1,oneShotWin:e.oneShotWin??!1,enableRoundUpMangan:e.enableRoundUpMangan??!1,disableCountableYakuman:e.disableCountableYakuman??!1,disableDoubleYakuman:e.disableDoubleYakuman??!1,orig:e}}calc(...t){const e=this.getWinningHands(t);if(e.length===0)return!1;const n=this.selectBestHand(e),i=this.calculateScore(n),r=this.calculateDeltas(i.base,i.isTsumo,i.isParent,i.myWind,this.cfg.orig.ronWind),o=r[i.myWind];this.addStickPoints(r,i.myWind,this.cfg.orig.ronWind);const a=rs({base:i.base,fu:i.fu,han:i.han,isTsumo:i.isTsumo,isParent:i.isParent,isYakuman:i.isYakuman,isCountableYakuman:i.isCountableYakuman});return{...n,fu:i.fu,deltas:r,points:r[i.myWind],basePoints:o,boardContext:this.cfg.orig,description:a}}getWinningHands(t){const e=[];if(t.length==0)return e;for(const n of t){const i=[...this.dA13(n),...this.dB13(n),...this.dC13(n),...this.dD13(n),...this.dE13(n),...this.dF13(n),...this.dG13(n),...this.dH13(n),...this.dI13(n),...this.dJ13(n),...this.dK13(n)].map(r=>(this.cfg.disableDoubleYakuman&&r.han>13&&(r.han=13),r));i.length!=0&&e.push({yakus:i,han:i.reduce((r,o)=>r+o.han,0),fu:30,hand:n,isYakuman:!0})}if(e.length>0)return e;for(const n of t){const i=this.calcFu(n),r=[...this.dA1(n),...this.dB1(n),...this.dC1(n),...this.dD1(n),...this.dE1(n),...this.dF1(n),...this.dG1(n),...this.dH1(n),...this.dI1(n),...this.dJ1(n),...this.dK1(n),...this.dA2(n),...this.dB2(n),...this.dC2(n),...this.dD2(n),...this.dE2(n),...this.dF2(n),...this.dG2(n),...this.dH2(n),...this.dI2(n),...this.dJ2(n),...this.dA3(n),...this.dB3(n),...this.dC3(n),...this.dA6(n)];r.length!=0&&(r.push(...this.dX1(n)),e.push({yakus:r,han:r.reduce((o,a)=>o+a.han,0),fu:i,hand:n}))}return e}selectBestHand(t){return t.reduce((e,n)=>{const{han:i,fu:r}=n,{han:o,fu:a}=e;return i>o||i===o&&r>a?n:e})}calculateScore(t){const{han:e}=t,n=t.fu!==25?st(t.fu,10):25,i=t.isYakuman??!1;let r=this.getBasePoints(e,n),o=!1;e>=13&&e<26&&!this.hasYakuman(t.yakus)&&(r=this.cfg.disableCountableYakuman?x.TRIPLE:x.YAKUMAN,o=!this.cfg.disableCountableYakuman),this.cfg.enableRoundUpMangan&&this.isRoundUpMangan(n,e)&&(r=x.MANGAN);const a=this.isTsumoWin(t.hand),c=this.cfg.orig.myWind,l=c===_.E;return{base:r,fu:n,han:e,isYakuman:o?!0:i,isCountableYakuman:o,isTsumo:a,myWind:c,isParent:l}}hasYakuman(t){return t.some(e=>e.isYakuman)}isRoundUpMangan(t,e){return t===30&&e===4||t===60&&e===3}isTsumoWin(t){return t.some(e=>e.tiles.some(n=>n.has(g.TSUMO)))}calculateDeltas(t,e,n,i,r){const o=H(0);return e?this.calculateTsumoDeltas(o,t,n,i):(I(r!=null,"tumo is false but ron wind is null"),this.calculateRonDeltas(o,t,n,i,r)),o}calculateRonDeltas(t,e,n,i,r){const o=n?X.PARENT_RON:X.CHILD_RON,a=st(e*o);t[i]+=a,t[r]-=a}calculateTsumoDeltas(t,e,n,i){if(n){const r=st(e*X.PARENT_TSUMO);t[_.E]+=r*3,t[_.S]-=r,t[_.W]-=r,t[_.N]-=r;return}for(const r of Object.values(_)){if(r==i)continue;const o=r==_.E?X.CHILD_TUMO_FROM_PARENT:X.CHILD_TUMO_FROM_CHILD,a=st(e*o);t[r]-=a,t[i]+=a}}addStickPoints(t,e,n){t[e]+=x.REACH_STICK*this.cfg.sticks.reach;const i=x.DEAD_STICK*this.cfg.sticks.dead;if(n!=null){t[e]+=i,t[n]-=i;return}for(const r of Object.values(_))r==e?t[r]+=i:t[r]-=i/3}getBasePoints(t,e){for(const{minHan:n,points:i}of Hr)if(t>=n)return i;return Math.min(e*2**(t+2),x.MANGAN)}getCalledPenalty(){return this.hand.menzen?0:1}dA1(t){return this.cfg.reached==1?[{name:"立直",han:1}]:this.cfg.reached==2?[{name:"ダブル立直",han:2}]:[]}dB1(t){return this.hand.drawn==null,this.getCalledPenalty()!=0?[]:t.some(n=>n.tiles.some(i=>i.has(g.TSUMO)))?[{name:"門前清自摸和",han:1}]:[]}dC1(t){if(this.getCalledPenalty()!=0)return[];const e="平和",n=this.calcFu(t);return n==20?[{name:e,han:1}]:!t.some(i=>i.tiles.some(r=>r.has(g.TSUMO)))&&n==30?[{name:e,han:1}]:[]}dD1(t){return t.some(n=>n.tiles.some(i=>i.t==p.Z||J.includes(i.n)))?[]:[{name:"断么九",han:1}]}dE1(t){return this.getCalledPenalty()!=0?[]:vn(t)==1?[{name:"一盃口",han:1}]:[]}dF1(t){const e=[];return t.forEach(n=>{if(n instanceof C)return;const i=n.tiles[0];i.t==p.Z&&(i.equals(this.cfg.myWind)&&e.push({name:"自風",han:1}),i.equals(this.cfg.roundWind)?e.push({name:"場風",han:1}):i.n==5?e.push({name:"白",han:1}):i.n==6?e.push({name:"發",han:1}):i.n==7&&e.push({name:"中",han:1}))}),e}dG1(t){return this.cfg.oneShotWin?[{name:"一発",han:1}]:[]}dH1(t){return this.cfg.replacementWin?[{name:"嶺上開花",han:1}]:[]}dI1(t){return this.cfg.quadWin?[{name:"搶槓",han:1}]:[]}dJ1(t){return this.cfg.finalWallWin?[{name:"海底摸月",han:1}]:[]}dK1(t){return this.cfg.finalDiscardWin?[{name:"河底撈魚",han:1}]:[]}dX1(t){const e=t.flatMap(a=>a.tiles),n=e.reduce((a,c)=>a+this.cfg.doras.filter(l=>c.equals(l)).length,0),i=e.reduce((a,c)=>a+this.cfg.hiddenDoras.filter(l=>c.equals(l)).length,0),r=e.filter(a=>a.has(g.RED)).length,o=[];return n>0&&o.push({name:"ドラ",han:n}),r>0&&o.push({name:"赤ドラ",han:r}),this.hand.reached&&i>0&&o.push({name:"裏ドラ",han:i}),o}dA2(t){return t.length==7?[{name:"七対子",han:2}]:[]}dB2(t){const e=n=>n instanceof nt||n instanceof F;for(const n of t){if(!e(n)||n.tiles[0].t==p.Z)continue;const i=pt(n),r=[p.M,p.P,p.S].filter(c=>c!=i.t),o=t.some(c=>{const l=new y(r[0],i.n);return e(c)&&l.equals(pt(c))}),a=t.some(c=>{const l=new y(r[1],i.n);return e(c)&&l.equals(pt(c))});if(o&&a)return[{name:"三色同順",han:2-this.getCalledPenalty()}]}return[]}dC2(t){return t.length==7?[]:t.every(n=>n instanceof R||n instanceof M||n instanceof K||n instanceof L||n instanceof U||n instanceof C)?[{name:"対々和",han:2}]:[]}dD2(t){return t.filter(n=>(n instanceof R||n instanceof L)&&!n.tiles.some(i=>i.has(g.RON))).length>=3?[{name:"三暗刻",han:2}]:[]}dE2(t){return t.filter(n=>n instanceof R||n instanceof M||n instanceof K).length>=3?[{name:"三槓子",han:2}]:[]}dF2(t){const e=n=>n instanceof R||n instanceof M||n instanceof K||n instanceof L||n instanceof U;for(const n of t){if(!e(n))continue;const i=pt(n);if(i.t==p.Z)continue;const r=[p.M,p.P,p.S].filter(c=>c!=i.t),o=t.some(c=>{const l=new y(r[0],i.n);return e(c)&&l.equals(pt(c))}),a=t.some(c=>{const l=new y(r[1],i.n);return e(c)&&l.equals(pt(c))});if(o&&a)return[{name:"三色同刻",han:2}]}return[]}dG2(t){return t.length==7?[]:t.filter(n=>{const i=n.tiles[0];return i.t==p.Z&&[5,6,7].includes(i.n)}).length==3?[{name:"小三元",han:2}]:[]}dH2(t){return t.every(n=>{const i=n.tiles[0],r=i.t==p.Z?Pt:J;return(n instanceof R||n instanceof M||n instanceof K||n instanceof L||n instanceof U||n instanceof C)&&r.includes(i.n)})?[{name:"混老頭",han:2}]:[]}dI2(t){return t.length==7?[]:t.some(n=>n instanceof nt||n instanceof F)?t.some(n=>n.tiles[0].t==p.Z)?t.every(n=>{const i=n.tiles[0].t==p.Z?Pt:J;return n.tiles.some(r=>i.includes(r.n))})?[{name:"混全帯么九",han:2-this.getCalledPenalty()}]:[]:[]:[]}dJ2(t){const e={[p.M]:[0,0,0],[p.S]:[0,0,0],[p.P]:[0,0,0]};for(const n of t){const i=pt(n);i.t!=p.BACK&&i.t!=p.Z&&(n instanceof nt||n instanceof F)&&(i.n==1?e[i.t][0]++:i.n==4?e[i.t][1]++:i.n==7&&e[i.t][2]++)}for(const n of Object.values(e))if(n[0]>0&&n[1]>0&&n[2]>0)return[{name:"一気通貫",han:2-this.getCalledPenalty()}];return[]}dA3(t){if(!t.some(n=>n.tiles[0].t==p.Z))return[];for(const n of Object.values(p))if(t.every(r=>r.tiles[0].t==p.Z||r.tiles[0].t==n))return[{name:"混一色",han:3-this.getCalledPenalty()}];return[]}dB3(t){return t.length==7?[]:t.some(n=>n instanceof nt||n instanceof F)?t.some(n=>n.tiles[0].t==p.Z)?[]:t.every(n=>n.tiles.some(i=>J.includes(i.n)))?[{name:"純全帯么九色",han:3-this.getCalledPenalty()}]:[]:[]}dC3(t){return this.getCalledPenalty()!=0?[]:vn(t)==2?[{name:"ニ盃口",han:3}]:[]}dA6(t){if(t.some(e=>e.tiles[0].t==p.Z))return[];for(const e of Object.values(p)){if(e==p.Z)continue;if(t.every(i=>i.tiles[0].t==e))return[{name:"清一色",han:6-this.getCalledPenalty()}]}return[]}dA13(t){return t.length!=13?[]:t.some(n=>n instanceof C&&n.tiles.some(i=>i.has(g.TSUMO)||i.has(g.RON)))?[{name:"国士無双13面待ち",han:26,isYakuman:!0}]:[{name:"国士無双",han:13,isYakuman:!0}]}dB13(t){return t.length==1?[{name:"九蓮宝燈",han:13,isYakuman:!0}]:[]}dC13(t){return t.length==7?[]:t.every(i=>i instanceof R||i instanceof L&&i.tiles.every(r=>!r.has(g.RON))||i instanceof C)?t.some(i=>i instanceof C&&i.tiles.some(r=>r.has(g.TSUMO)||r.has(g.RON)))?[{name:"四暗刻単騎待ち",han:26,isYakuman:!0}]:[{name:"四暗刻",han:13,isYakuman:!0}]:[]}dD13(t){if(t.length==13)return[];const e=[5,6,7];return t.filter(i=>!(i instanceof C)&&i.tiles.some(r=>r.t==p.Z&&e.includes(r.n))).length==3?[{name:"大三元",han:13,isYakuman:!0}]:[]}dE13(t){return t.every(n=>n.tiles[0].t==p.Z)?[{name:"字一色",han:13,isYakuman:!0}]:[]}dF13(t){return t.every(n=>(n instanceof R||n instanceof M||n instanceof K||n instanceof L||n instanceof U||n instanceof C)&&J.includes(n.tiles[0].n))?[{name:"清老頭",han:13,isYakuman:!0}]:[]}dG13(t){return t.length==7?[]:t.every(n=>n instanceof R||n instanceof M||n instanceof K||n instanceof C)?[{name:"四槓子",han:13,isYakuman:!0}]:[]}dH13(t){if(t.length==13)return[];if(t.length==7)return[];const e=[1,2,3,4];return t.filter(r=>{const o=r.tiles[0];return o.t==p.Z&&e.includes(o.n)}).length==4?t.find(r=>r instanceof C).tiles.some(r=>r.t==p.Z&&e.includes(r.n))?[{name:"小四喜",han:13,isYakuman:!0}]:[{name:"大四喜",han:13,isYakuman:!0}]:[]}dI13(t){const e=n=>!!(n.equals(new y(p.Z,6))||n.t==p.S&&[2,3,4,6,8].includes(n.n));return t.every(n=>n.tiles.every(i=>e(i)))?[{name:"緑一色",han:13,isYakuman:!0}]:[]}dJ13(t){return[]}dK13(t){return[]}calcFu(t){if(t.length==7)return 25;const e=20;let n=e;const i=this.cfg.myWind.n,r=this.cfg.roundWind.n,o=t.find(f=>f.tiles.some(w=>w.has(g.TSUMO)||w.has(g.RON))),a=this.getCalledPenalty()==1,c=o.tiles.some(f=>f.has(g.TSUMO)),l=(f,w)=>{const b=f.tiles[0];return b.t==p.Z||J.includes(b.n)?w*2:w};for(const f of t)switch(!0){case f instanceof L:const w=f.tiles.some(b=>b.has(g.RON))?2:4;n+=l(f,w);break;case f instanceof U:n+=l(f,2);break;case(f instanceof K||f instanceof M):n+=l(f,8);break;case f instanceof R:n+=l(f,16);break}n+=(f=>{if(f instanceof L)return 0;if(f instanceof C)return 2;const w=f.tiles,b=w.findIndex(A=>A.has(g.TSUMO)||A.has(g.RON));return b==1||b==0&&w[2].n==9||b==2&&w[0].n==1?2:0})(o);const u=t.find(f=>f instanceof C).tiles[0];u.t==p.Z&&([5,6,7].includes(u.n)&&(n+=2),(u.n==r||u.n==i)&&(n+=2));let m=!1;return!a&&n==e&&(m=!0),c&&!m&&(n+=2),!c&&!a&&(n+=10),!c&&!a&&n==30&&(m=!0),a&&n==e&&(n=30),n}}const Gt=s=>s.tiles.reduce((t,e)=>`${t}${e.n}${e.t}`,""),vn=s=>{const t=s.filter(e=>e instanceof nt).reduce((e,n)=>{const i=Gt(n);return e[i]=(e[i]||0)+1,e},{});return Object.values(t).filter(e=>e>=2).length},pt=s=>[...s.tiles].sort(Qt)[0],We=s=>{const t=s.n,e=s.t;if(e==p.Z){if(t==4)return new y(e,1);if(t==7)return new y(e,5)}return new y(e,t%9+1)};class Ht{static calcEffectiveTiles(t,e,n){if(e.length==0)throw new Error("no tiles available to discard");const i=new Map;let r=Number.POSITIVE_INFINITY;for(const o of e){const a=t.dec([o]),c=Ht.getEffectiveTiles(t,n);t.inc(a);const l=n?.arrangeRed&&o.has(g.RED)?o.clone({removeAll:!0}):o.has(g.RED)?o.clone({removeAll:!0,add:g.RED}):o.clone({removeAll:!0});c.shanten<r?(i.clear(),i.set(l.toString(),{shanten:c.shanten,effectiveTiles:c.effectiveTiles,tile:l}),r=c.shanten):c.shanten==r&&i.set(l.toString(),{shanten:c.shanten,effectiveTiles:c.effectiveTiles,tile:l})}return Array.from(i.values())}static getEffectiveTiles(t,e){let n=Number.POSITIVE_INFINITY,i=[];const r=new te(t);for(const[o,a]of j({skipBack:!0,filterBy:e?.typeFilter})){if(t.get(o,a)>=4)continue;const c=new y(o,a),l=t.inc([c]),h=e?.standardTypeOnly?r.standardType():r.calc();t.dec(l),h<n?(n=h,i=[c]):h==n&&i.push(c)}return{shanten:n,effectiveTiles:i}}}const De=()=>{const s=new Set;return{on(t){s.add(t)},off(t){s.delete(t)},offAll(){s.clear()},emit(t){s.forEach(e=>e(t))}}};function os(s){const t=["RON","DAI_KAN","PON","CHI"],e=s.map(r=>r.choices),i=cs(e,t).map(r=>s[r]);return{events:i,type:ls(t,i[0]?.choices)}}function as(s){const t=["TSUMO","REACH","AN_KAN","SHO_KAN","DRAWN_GAME_BY_NINE_TERMINALS","DISCARD"],e=s.map(r=>r.choices),i=cs(e,t).map(r=>s[r]);return{events:i,type:ls(t,i[0]?.choices)}}function cs(s,t){let e=[],n=Number.POSITIVE_INFINITY;for(let i=0;i<s.length;i++){const r=s[i];if(Dr(r,t)){const o=Lr(t,r);o<n?(n=o,e=[i]):o===n&&e.push(i)}}return e}function Dr(s,t){return t.some(e=>!!s[e])}function Lr(s,t){for(let e=0;e<s.length;e++){const n=s[e];if(t[n])return e}return Number.POSITIVE_INFINITY}function ls(s,t){if(t==null)return!1;for(const e of s)if(t[e])return e;return!1}const Zt=()=>{const s=De(),t=De(),e={emit:s.emit,on:i=>t.on(i)},n={emit:t.emit,on:i=>s.on(i)};return[e,n]},ds=()=>{const s=De();return{emit:n=>{s.emit(n)},on:n=>{s.on(n)}}};class Jt{reachValue=1e3;m;constructor(t){this.m=structuredClone(t)}get summary(){return this.m}reach(t){this.m[t]-=this.reachValue}update(t,e){for(let n in e){const i=e[n],r=t[i];this.m[n]+=r}}}class Xt{playerToWind={};windToPlayer=H("");_round;_sticks;constructor(t,e){this._round=e?.round??k.E1,this._sticks=structuredClone(e?.sticks)??{reach:0,dead:0},this.playerToWind=structuredClone(t);for(let n in this.playerToWind)this.windToPlayer[this.playerToWind[n]]=n}get sticks(){return this._sticks}get round(){return this._round}update(){for(let t in this.playerToWind){const e=Ee(this.playerToWind[t]);this.playerToWind[t]=e,this.windToPlayer[e]=t}}incrementDeadStick(){this._sticks.dead++}incrementReachStick(){this._sticks.reach++}nextRound(){const t=Vt(this.round);this._round=t,this.update()}resetDeadStick(){this._sticks.dead=0}resetReachStick(){this._sticks.reach=0}is(t){return this.round==t}wind(t){return this.playerToWind[t]}playerID(t){return this.windToPlayer[t]}get playerMap(){return this.playerToWind}}function sn(s){for(let t=s.length-1;t>0;t--){const e=Math.floor(Math.random()*(t+1));[s[t],s[e]]=[s[e],s[t]]}return s}class hs{constructor(t=!1){this.disabled=t,this.c=this.initial()}c;safeTileMap=H({},!0);get(t){return t.t==p.BACK?0:this.c[t.t][t.n]}dec(...t){if(!this.disabled){for(let e of t)if(e.t!=p.BACK){if(this.get(e)<=0)throw new Error(`[counter] tile ${e} appears more than 4 times`);if(this.c[e.t][e.n]-=1,e.has(g.RED)){if(this.c[e.t][0]<=0)throw new Error(`[counter] red tile ${e} appears more than once`);this.c[e.t][0]-=1}}}}addTileToSafeMap(t,e){this.disabled||(this.safeTileMap[e][this.key(t.t,t.n)]=!0)}isSafeTile(t,e,n){return this.safeTileMap[n][this.key(t,e)]}key(t,e){return`${t}${e}`}reset(){this.c=this.initial()}initial(){return{[p.M]:[1,4,4,4,4,4,4,4,4,4],[p.S]:[1,4,4,4,4,4,4,4,4,4],[p.P]:[1,4,4,4,4,4,4,4,4,4],[p.Z]:[0,4,4,4,4,4,4,4]}}}class rn{m=[];constructor(){}discard(t,e){this.m.push({w:e,t})}discards(t){return t==null?[...this.m]:this.m.filter(e=>e.w==t)}get lastTile(){const t=this.m.at(-1);return I(t!=null,`lastTile is null(${t}). river: ${JSON.stringify(this.m,null,2)}`),t}markCalled(){this.lastTile.callMarker=!0}isFourWindsAbort(){const t=this.discards();if(t.length!=4)return!1;let e=t[0].t;if(e.isNum())return!1;for(let n=0;n<4;n++)if(!e.equals(t[n].t))return!1;return!0}}function Kr(){if(typeof globalThis<"u")return globalThis;if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global}function zr(){const s=Kr();if(s.__xstate__)return s.__xstate__}const Ur=s=>{if(typeof window>"u")return;const t=zr();t&&t.register(s)};class Sn{constructor(t){this._process=t,this._active=!1,this._current=null,this._last=null}start(){this._active=!0,this.flush()}clear(){this._current&&(this._current.next=null,this._last=this._current)}enqueue(t){const e={value:t,next:null};if(this._current){this._last.next=e,this._last=e;return}this._current=e,this._last=e,this._active&&this.flush()}flush(){for(;this._current;){const t=this._current;this._process(t.value),this._current=t.next}this._last=null}}const us=".",jr="",fs="",Fr="#",Gr="*",ps="xstate.init",Le="xstate.stop";function Zr(s,t){return{type:`xstate.after.${s}.${t}`}}function Ke(s,t){return{type:`xstate.done.state.${s}`,output:t}}function Yr(s,t){return{type:`xstate.done.actor.${s}`,output:t,actorId:s}}function Vr(s,t){return{type:`xstate.error.actor.${s}`,error:t,actorId:s}}function gs(s){return{type:ps,input:s}}function Z(s){setTimeout(()=>{throw s})}const Jr=typeof Symbol=="function"&&Symbol.observable||"@@observable";function ms(s,t){const e=On(s),n=On(t);return typeof n=="string"?typeof e=="string"?n===e:!1:typeof e=="string"?e in n:Object.keys(e).every(i=>i in n?ms(e[i],n[i]):!1)}function on(s){if(ws(s))return s;const t=[];let e="";for(let n=0;n<s.length;n++){switch(s.charCodeAt(n)){case 92:e+=s[n+1],n++;continue;case 46:t.push(e),e="";continue}e+=s[n]}return t.push(e),t}function On(s){if(Ro(s))return s.value;if(typeof s!="string")return s;const t=on(s);return Xr(t)}function Xr(s){if(s.length===1)return s[0];const t={};let e=t;for(let n=0;n<s.length-1;n++)if(n===s.length-2)e[s[n]]=s[n+1];else{const i=e;e={},i[s[n]]=e}return t}function kn(s,t){const e={},n=Object.keys(s);for(let i=0;i<n.length;i++){const r=n[i];e[r]=t(s[r],r,s,i)}return e}function ys(s){return ws(s)?s:[s]}function it(s){return s===void 0?[]:ys(s)}function ze(s,t,e,n){return typeof s=="function"?s({context:t,event:e,self:n}):s}function ws(s){return Array.isArray(s)}function qr(s){return s.type.startsWith("xstate.error.actor")}function Ot(s){return ys(s).map(t=>typeof t>"u"||typeof t=="string"?{target:t}:t)}function Es(s){if(!(s===void 0||s===jr))return it(s)}function Ue(s,t,e){const n=typeof s=="object",i=n?s:void 0;return{next:(n?s.next:s)?.bind(i),error:(n?s.error:t)?.bind(i),complete:(n?s.complete:e)?.bind(i)}}function Cn(s,t){return`${t}.${s}`}function an(s,t){const e=t.match(/^xstate\.invoke\.(\d+)\.(.*)/);if(!e)return s.implementations.actors[t];const[,n,i]=e,o=s.getStateNodeById(i).config.invoke;return(Array.isArray(o)?o[n]:o).src}function Rn(s,t){return`${s.sessionId}.${t}`}let Qr=0;function to(s,t){const e=new Map,n=new Map,i=new WeakMap,r=new Set,o={},{clock:a,logger:c}=t,l={schedule:(u,m,f,w,b=Math.random().toString(36).slice(2))=>{const A={source:u,target:m,event:f,delay:w,id:b,startedAt:Date.now()},O=Rn(u,b);d._snapshot._scheduledEvents[O]=A;const $=a.setTimeout(()=>{delete o[O],delete d._snapshot._scheduledEvents[O],d._relay(u,m,f)},w);o[O]=$},cancel:(u,m)=>{const f=Rn(u,m),w=o[f];delete o[f],delete d._snapshot._scheduledEvents[f],w!==void 0&&a.clearTimeout(w)},cancelAll:u=>{for(const m in d._snapshot._scheduledEvents){const f=d._snapshot._scheduledEvents[m];f.source===u&&l.cancel(u,f.id)}}},h=u=>{if(!r.size)return;const m={...u,rootId:s.sessionId};r.forEach(f=>f.next?.(m))},d={_snapshot:{_scheduledEvents:(t?.snapshot&&t.snapshot.scheduler)??{}},_bookId:()=>`x:${Qr++}`,_register:(u,m)=>(e.set(u,m),u),_unregister:u=>{e.delete(u.sessionId);const m=i.get(u);m!==void 0&&(n.delete(m),i.delete(u))},get:u=>n.get(u),getAll:()=>Object.fromEntries(n.entries()),_set:(u,m)=>{const f=n.get(u);if(f&&f!==m)throw new Error(`Actor with system ID '${u}' already exists.`);n.set(u,m),i.set(m,u)},inspect:u=>{const m=Ue(u);return r.add(m),{unsubscribe(){r.delete(m)}}},_sendInspectionEvent:h,_relay:(u,m,f)=>{d._sendInspectionEvent({type:"@xstate.event",sourceRef:u,actorRef:m,event:f}),m._send(f)},scheduler:l,getSnapshot:()=>({_scheduledEvents:{...d._snapshot._scheduledEvents}}),start:()=>{const u=d._snapshot._scheduledEvents;d._snapshot._scheduledEvents={};for(const m in u){const{source:f,target:w,event:b,delay:A,id:O}=u[m];l.schedule(f,w,b,A,O)}},_clock:a,_logger:c};return d}let Se=!1;const cn=1;let W=(function(s){return s[s.NotStarted=0]="NotStarted",s[s.Running=1]="Running",s[s.Stopped=2]="Stopped",s})({});const eo={clock:{setTimeout:(s,t)=>setTimeout(s,t),clearTimeout:s=>clearTimeout(s)},logger:console.log.bind(console),devTools:!1};class no{constructor(t,e){this.logic=t,this._snapshot=void 0,this.clock=void 0,this.options=void 0,this.id=void 0,this.mailbox=new Sn(this._process.bind(this)),this.observers=new Set,this.eventListeners=new Map,this.logger=void 0,this._processingStatus=W.NotStarted,this._parent=void 0,this._syncSnapshot=void 0,this.ref=void 0,this._actorScope=void 0,this.systemId=void 0,this.sessionId=void 0,this.system=void 0,this._doneEvent=void 0,this.src=void 0,this._deferred=[];const n={...eo,...e},{clock:i,logger:r,parent:o,syncSnapshot:a,id:c,systemId:l,inspect:h}=n;this.system=o?o.system:to(this,{clock:i,logger:r}),h&&!o&&this.system.inspect(Ue(h)),this.sessionId=this.system._bookId(),this.id=c??this.sessionId,this.logger=e?.logger??this.system._logger,this.clock=e?.clock??this.system._clock,this._parent=o,this._syncSnapshot=a,this.options=n,this.src=n.src??t,this.ref=this,this._actorScope={self:this,id:this.id,sessionId:this.sessionId,logger:this.logger,defer:d=>{this._deferred.push(d)},system:this.system,stopChild:d=>{if(d._parent!==this)throw new Error(`Cannot stop child actor ${d.id} of ${this.id} because it is not a child`);d._stop()},emit:d=>{const u=this.eventListeners.get(d.type),m=this.eventListeners.get("*");if(!u&&!m)return;const f=[...u?u.values():[],...m?m.values():[]];for(const w of f)try{w(d)}catch(b){Z(b)}},actionExecutor:d=>{const u=()=>{if(this._actorScope.system._sendInspectionEvent({type:"@xstate.action",actorRef:this,action:{type:d.type,params:d.params}}),!d.exec)return;const m=Se;try{Se=!0,d.exec(d.info,d.params)}finally{Se=m}};this._processingStatus===W.Running?u():this._deferred.push(u)}},this.send=this.send.bind(this),this.system._sendInspectionEvent({type:"@xstate.actor",actorRef:this}),l&&(this.systemId=l,this.system._set(l,this)),this._initState(e?.snapshot??e?.state),l&&this._snapshot.status!=="active"&&this.system._unregister(this)}_initState(t){try{this._snapshot=t?this.logic.restoreSnapshot?this.logic.restoreSnapshot(t,this._actorScope):t:this.logic.getInitialSnapshot(this._actorScope,this.options?.input)}catch(e){this._snapshot={status:"error",output:void 0,error:e}}}update(t,e){this._snapshot=t;let n;for(;n=this._deferred.shift();)try{n()}catch(i){this._deferred.length=0,this._snapshot={...t,status:"error",error:i}}switch(this._snapshot.status){case"active":for(const i of this.observers)try{i.next?.(t)}catch(r){Z(r)}break;case"done":for(const i of this.observers)try{i.next?.(t)}catch(r){Z(r)}this._stopProcedure(),this._complete(),this._doneEvent=Yr(this.id,this._snapshot.output),this._parent&&this.system._relay(this,this._parent,this._doneEvent);break;case"error":this._error(this._snapshot.error);break}this.system._sendInspectionEvent({type:"@xstate.snapshot",actorRef:this,event:e,snapshot:t})}subscribe(t,e,n){const i=Ue(t,e,n);if(this._processingStatus!==W.Stopped)this.observers.add(i);else switch(this._snapshot.status){case"done":try{i.complete?.()}catch(r){Z(r)}break;case"error":{const r=this._snapshot.error;if(!i.error)Z(r);else try{i.error(r)}catch(o){Z(o)}break}}return{unsubscribe:()=>{this.observers.delete(i)}}}on(t,e){let n=this.eventListeners.get(t);n||(n=new Set,this.eventListeners.set(t,n));const i=e.bind(void 0);return n.add(i),{unsubscribe:()=>{n.delete(i)}}}start(){if(this._processingStatus===W.Running)return this;this._syncSnapshot&&this.subscribe({next:n=>{n.status==="active"&&this.system._relay(this,this._parent,{type:`xstate.snapshot.${this.id}`,snapshot:n})},error:()=>{}}),this.system._register(this.sessionId,this),this.systemId&&this.system._set(this.systemId,this),this._processingStatus=W.Running;const t=gs(this.options.input);switch(this.system._sendInspectionEvent({type:"@xstate.event",sourceRef:this._parent,actorRef:this,event:t}),this._snapshot.status){case"done":return this.update(this._snapshot,t),this;case"error":return this._error(this._snapshot.error),this}if(this._parent||this.system.start(),this.logic.start)try{this.logic.start(this._snapshot,this._actorScope)}catch(n){return this._snapshot={...this._snapshot,status:"error",error:n},this._error(n),this}return this.update(this._snapshot,t),this.options.devTools&&this.attachDevTools(),this.mailbox.start(),this}_process(t){let e,n;try{e=this.logic.transition(this._snapshot,t,this._actorScope)}catch(i){n={err:i}}if(n){const{err:i}=n;this._snapshot={...this._snapshot,status:"error",error:i},this._error(i);return}this.update(e,t),t.type===Le&&(this._stopProcedure(),this._complete())}_stop(){return this._processingStatus===W.Stopped?this:(this.mailbox.clear(),this._processingStatus===W.NotStarted?(this._processingStatus=W.Stopped,this):(this.mailbox.enqueue({type:Le}),this))}stop(){if(this._parent)throw new Error("A non-root actor cannot be stopped directly.");return this._stop()}_complete(){for(const t of this.observers)try{t.complete?.()}catch(e){Z(e)}this.observers.clear()}_reportError(t){if(!this.observers.size){this._parent||Z(t);return}let e=!1;for(const n of this.observers){const i=n.error;e||=!i;try{i?.(t)}catch(r){Z(r)}}this.observers.clear(),e&&Z(t)}_error(t){this._stopProcedure(),this._reportError(t),this._parent&&this.system._relay(this,this._parent,Vr(this.id,t))}_stopProcedure(){return this._processingStatus!==W.Running?this:(this.system.scheduler.cancelAll(this),this.mailbox.clear(),this.mailbox=new Sn(this._process.bind(this)),this._processingStatus=W.Stopped,this.system._unregister(this),this)}_send(t){this._processingStatus!==W.Stopped&&this.mailbox.enqueue(t)}send(t){this.system._relay(void 0,this,t)}attachDevTools(){const{devTools:t}=this.options;t&&(typeof t=="function"?t:Ur)(this)}toJSON(){return{xstate$$type:cn,id:this.id}}getPersistedSnapshot(t){return this.logic.getPersistedSnapshot(this._snapshot,t)}[Jr](){return this}getSnapshot(){return this._snapshot}}function Bt(s,...[t]){return new no(s,t)}function so(s,t,e,n,{sendId:i}){const r=typeof i=="function"?i(e,n):i;return[t,{sendId:r},void 0]}function io(s,t){s.defer(()=>{s.system.scheduler.cancel(s.self,t.sendId)})}function ro(s){function t(e,n){}return t.type="xstate.cancel",t.sendId=s,t.resolve=so,t.execute=io,t}function oo(s,t,e,n,{id:i,systemId:r,src:o,input:a,syncSnapshot:c}){const l=typeof o=="string"?an(t.machine,o):o,h=typeof i=="function"?i(e):i;let d,u;return l&&(u=typeof a=="function"?a({context:t.context,event:e.event,self:s.self}):a,d=Bt(l,{id:h,src:o,parent:s.self,syncSnapshot:c,systemId:r,input:u})),[Tt(t,{children:{...t.children,[h]:d}}),{id:i,systemId:r,actorRef:d,src:o,input:u},void 0]}function ao(s,{actorRef:t}){t&&s.defer(()=>{t._processingStatus!==W.Stopped&&t.start()})}function co(...[s,{id:t,systemId:e,input:n,syncSnapshot:i=!1}={}]){function r(o,a){}return r.type="xstate.spawnChild",r.id=t,r.systemId=e,r.src=s,r.input=n,r.syncSnapshot=i,r.resolve=oo,r.execute=ao,r}function lo(s,t,e,n,{actorRef:i}){const r=typeof i=="function"?i(e,n):i,o=typeof r=="string"?t.children[r]:r;let a=t.children;return o&&(a={...a},delete a[o.id]),[Tt(t,{children:a}),o,void 0]}function ho(s,t){if(t){if(s.system._unregister(t),t._processingStatus!==W.Running){s.stopChild(t);return}s.defer(()=>{s.stopChild(t)})}}function _s(s){function t(e,n){}return t.type="xstate.stopChild",t.actorRef=s,t.resolve=lo,t.execute=ho,t}function ln(s,t,e,n){const{machine:i}=n,r=typeof s=="function",o=r?s:i.implementations.guards[typeof s=="string"?s:s.type];if(!r&&!o)throw new Error(`Guard '${typeof s=="string"?s:s.type}' is not implemented.'.`);if(typeof o!="function")return ln(o,t,e,n);const a={context:t,event:e},c=r||typeof s=="string"?void 0:"params"in s?typeof s.params=="function"?s.params({context:t,event:e}):s.params:void 0;return"check"in o?o.check(n,a,o):o(a,c)}const dn=s=>s.type==="atomic"||s.type==="final";function Wt(s){return Object.values(s.states).filter(t=>t.type!=="history")}function ee(s,t){const e=[];if(t===s)return e;let n=s.parent;for(;n&&n!==t;)e.push(n),n=n.parent;return e}function fe(s){const t=new Set(s),e=As(t);for(const n of t)if(n.type==="compound"&&(!e.get(n)||!e.get(n).length))Mn(n).forEach(i=>t.add(i));else if(n.type==="parallel"){for(const i of Wt(n))if(i.type!=="history"&&!t.has(i)){const r=Mn(i);for(const o of r)t.add(o)}}for(const n of t){let i=n.parent;for(;i;)t.add(i),i=i.parent}return t}function bs(s,t){const e=t.get(s);if(!e)return{};if(s.type==="compound"){const i=e[0];if(i){if(dn(i))return i.key}else return{}}const n={};for(const i of e)n[i.key]=bs(i,t);return n}function As(s){const t=new Map;for(const e of s)t.has(e)||t.set(e,[]),e.parent&&(t.has(e.parent)||t.set(e.parent,[]),t.get(e.parent).push(e));return t}function Is(s,t){const e=fe(t);return bs(s,As(e))}function hn(s,t){return t.type==="compound"?Wt(t).some(e=>e.type==="final"&&s.has(e)):t.type==="parallel"?Wt(t).every(e=>hn(s,e)):t.type==="final"}const Ie=s=>s[0]===Fr;function uo(s,t){return s.transitions.get(t)||[...s.transitions.keys()].filter(n=>{if(n===Gr)return!0;if(!n.endsWith(".*"))return!1;const i=n.split("."),r=t.split(".");for(let o=0;o<i.length;o++){const a=i[o],c=r[o];if(a==="*")return o===i.length-1;if(a!==c)return!1}return!0}).sort((n,i)=>i.length-n.length).flatMap(n=>s.transitions.get(n))}function fo(s){const t=s.config.after;if(!t)return[];const e=i=>{const r=Zr(i,s.id),o=r.type;return s.entry.push(Ko(r,{id:o,delay:i})),s.exit.push(ro(o)),o};return Object.keys(t).flatMap(i=>{const r=t[i],o=typeof r=="string"?{target:r}:r,a=Number.isNaN(+i)?i:+i,c=e(a);return it(o).map(l=>({...l,event:c,delay:a}))}).map(i=>{const{delay:r}=i;return{...yt(s,i.event,i),delay:r}})}function yt(s,t,e){const n=Es(e.target),i=e.reenter??!1,r=mo(s,n),o={...e,actions:it(e.actions),guard:e.guard,target:r,source:s,reenter:i,eventType:t,toJSON:()=>({...o,source:`#${s.id}`,target:r?r.map(a=>`#${a.id}`):void 0})};return o}function po(s){const t=new Map;if(s.config.on)for(const e of Object.keys(s.config.on)){if(e===fs)throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.');const n=s.config.on[e];t.set(e,Ot(n).map(i=>yt(s,e,i)))}if(s.config.onDone){const e=`xstate.done.state.${s.id}`;t.set(e,Ot(s.config.onDone).map(n=>yt(s,e,n)))}for(const e of s.invoke){if(e.onDone){const n=`xstate.done.actor.${e.id}`;t.set(n,Ot(e.onDone).map(i=>yt(s,n,i)))}if(e.onError){const n=`xstate.error.actor.${e.id}`;t.set(n,Ot(e.onError).map(i=>yt(s,n,i)))}if(e.onSnapshot){const n=`xstate.snapshot.${e.id}`;t.set(n,Ot(e.onSnapshot).map(i=>yt(s,n,i)))}}for(const e of s.after){let n=t.get(e.eventType);n||(n=[],t.set(e.eventType,n)),n.push(e)}return t}function go(s,t){const e=typeof t=="string"?s.states[t]:t?s.states[t.target]:void 0;if(!e&&t)throw new Error(`Initial state node "${t}" not found on parent state node #${s.id}`);const n={source:s,actions:!t||typeof t=="string"?[]:it(t.actions),eventType:null,reenter:!1,target:e?[e]:[],toJSON:()=>({...n,source:`#${s.id}`,target:e?[`#${e.id}`]:[]})};return n}function mo(s,t){if(t!==void 0)return t.map(e=>{if(typeof e!="string")return e;if(Ie(e))return s.machine.getStateNodeById(e);const n=e[0]===us;if(n&&!s.parent)return pe(s,e.slice(1));const i=n?s.key+e:e;if(s.parent)try{return pe(s.parent,i)}catch(r){throw new Error(`Invalid transition definition for state node '${s.id}':
|
|
9
|
-
${r.message}`)}else throw new Error(`Invalid target: "${e}" is not a valid target from the root node. Did you mean ".${e}"?`)})}function Ts(s){const t=Es(s.config.target);return t?{target:t.map(e=>typeof e=="string"?pe(s.parent,e):e)}:s.parent.initial}function Et(s){return s.type==="history"}function Mn(s){const t=Ns(s);for(const e of t)for(const n of ee(e,s))t.add(n);return t}function Ns(s){const t=new Set;function e(n){if(!t.has(n)){if(t.add(n),n.type==="compound")e(n.initial.target[0]);else if(n.type==="parallel")for(const i of Wt(n))e(i)}}return e(s),t}function Dt(s,t){if(Ie(t))return s.machine.getStateNodeById(t);if(!s.states)throw new Error(`Unable to retrieve child state '${t}' from '${s.id}'; no child states exist.`);const e=s.states[t];if(!e)throw new Error(`Child state '${t}' does not exist on '${s.id}'`);return e}function pe(s,t){if(typeof t=="string"&&Ie(t))try{return s.machine.getStateNodeById(t)}catch{}const e=on(t).slice();let n=s;for(;e.length;){const i=e.shift();if(!i.length)break;n=Dt(n,i)}return n}function ge(s,t){if(typeof t=="string"){const i=s.states[t];if(!i)throw new Error(`State '${t}' does not exist on '${s.id}'`);return[s,i]}const e=Object.keys(t),n=e.map(i=>Dt(s,i)).filter(Boolean);return[s.machine.root,s].concat(n,e.reduce((i,r)=>{const o=Dt(s,r);if(!o)return i;const a=ge(o,t[r]);return i.concat(a)},[]))}function yo(s,t,e,n){const r=Dt(s,t).next(e,n);return!r||!r.length?s.next(e,n):r}function wo(s,t,e,n){const i=Object.keys(t),r=Dt(s,i[0]),o=un(r,t[i[0]],e,n);return!o||!o.length?s.next(e,n):o}function Eo(s,t,e,n){const i=[];for(const r of Object.keys(t)){const o=t[r];if(!o)continue;const a=Dt(s,r),c=un(a,o,e,n);c&&i.push(...c)}return i.length?i:s.next(e,n)}function un(s,t,e,n){return typeof t=="string"?yo(s,t,e,n):Object.keys(t).length===1?wo(s,t,e,n):Eo(s,t,e,n)}function _o(s){return Object.keys(s.states).map(t=>s.states[t]).filter(t=>t.type==="history")}function at(s,t){let e=s;for(;e.parent&&e.parent!==t;)e=e.parent;return e.parent===t}function bo(s,t){const e=new Set(s),n=new Set(t);for(const i of e)if(n.has(i))return!0;for(const i of n)if(e.has(i))return!0;return!1}function vs(s,t,e){const n=new Set;for(const i of s){let r=!1;const o=new Set;for(const a of n)if(bo(je([i],t,e),je([a],t,e)))if(at(i.source,a.source))o.add(a);else{r=!0;break}if(!r){for(const a of o)n.delete(a);n.add(i)}}return Array.from(n)}function Ao(s){const[t,...e]=s;for(const n of ee(t,void 0))if(e.every(i=>at(i,n)))return n}function fn(s,t){if(!s.target)return[];const e=new Set;for(const n of s.target)if(Et(n))if(t[n.id])for(const i of t[n.id])e.add(i);else for(const i of fn(Ts(n),t))e.add(i);else e.add(n);return[...e]}function Ss(s,t){const e=fn(s,t);if(!e)return;if(!s.reenter&&e.every(i=>i===s.source||at(i,s.source)))return s.source;const n=Ao(e.concat(s.source));if(n)return n;if(!s.reenter)return s.source.machine.root}function je(s,t,e){const n=new Set;for(const i of s)if(i.target?.length){const r=Ss(i,e);i.reenter&&i.source===r&&n.add(r);for(const o of t)at(o,r)&&n.add(o)}return[...n]}function Io(s,t){if(s.length!==t.size)return!1;for(const e of s)if(!t.has(e))return!1;return!0}function Fe(s,t,e,n,i,r){if(!s.length)return t;const o=new Set(t._nodes);let a=t.historyValue;const c=vs(s,o,a);let l=t;i||([l,a]=So(l,n,e,c,o,a,r,e.actionExecutor)),l=Lt(l,n,e,c.flatMap(d=>d.actions),r,void 0),l=No(l,n,e,c,o,r,a,i);const h=[...o];l.status==="done"&&(l=Lt(l,n,e,h.sort((d,u)=>u.order-d.order).flatMap(d=>d.exit),r,void 0));try{return a===t.historyValue&&Io(t._nodes,o)?l:Tt(l,{_nodes:h,historyValue:a})}catch(d){throw d}}function To(s,t,e,n,i){if(n.output===void 0)return;const r=Ke(i.id,i.output!==void 0&&i.parent?ze(i.output,s.context,t,e.self):void 0);return ze(n.output,s.context,r,e.self)}function No(s,t,e,n,i,r,o,a){let c=s;const l=new Set,h=new Set;vo(n,o,h,l),a&&h.add(s.machine.root);const d=new Set;for(const u of[...l].sort((m,f)=>m.order-f.order)){i.add(u);const m=[];m.push(...u.entry);for(const f of u.invoke)m.push(co(f.src,{...f,syncSnapshot:!!f.onSnapshot}));if(h.has(u)){const f=u.initial.actions;m.push(...f)}if(c=Lt(c,t,e,m,r,u.invoke.map(f=>f.id)),u.type==="final"){const f=u.parent;let w=f?.type==="parallel"?f:f?.parent,b=w||u;for(f?.type==="compound"&&r.push(Ke(f.id,u.output!==void 0?ze(u.output,c.context,t,e.self):void 0));w?.type==="parallel"&&!d.has(w)&&hn(i,w);)d.add(w),r.push(Ke(w.id)),b=w,w=w.parent;if(w)continue;c=Tt(c,{status:"done",output:To(c,t,e,c.machine.root,b)})}}return c}function vo(s,t,e,n){for(const i of s){const r=Ss(i,t);for(const a of i.target||[])!Et(a)&&(i.source!==a||i.source!==r||i.reenter)&&(n.add(a),e.add(a)),Ct(a,t,e,n);const o=fn(i,t);for(const a of o){const c=ee(a,r);r?.type==="parallel"&&c.push(r),Os(n,t,e,c,!i.source.parent&&i.reenter?void 0:r)}}}function Ct(s,t,e,n){if(Et(s))if(t[s.id]){const i=t[s.id];for(const r of i)n.add(r),Ct(r,t,e,n);for(const r of i)Oe(r,s.parent,n,t,e)}else{const i=Ts(s);for(const r of i.target)n.add(r),i===s.parent?.initial&&e.add(s.parent),Ct(r,t,e,n);for(const r of i.target)Oe(r,s.parent,n,t,e)}else if(s.type==="compound"){const[i]=s.initial.target;Et(i)||(n.add(i),e.add(i)),Ct(i,t,e,n),Oe(i,s,n,t,e)}else if(s.type==="parallel")for(const i of Wt(s).filter(r=>!Et(r)))[...n].some(r=>at(r,i))||(Et(i)||(n.add(i),e.add(i)),Ct(i,t,e,n))}function Os(s,t,e,n,i){for(const r of n)if((!i||at(r,i))&&s.add(r),r.type==="parallel")for(const o of Wt(r).filter(a=>!Et(a)))[...s].some(a=>at(a,o))||(s.add(o),Ct(o,t,e,s))}function Oe(s,t,e,n,i){Os(e,n,i,ee(s,t))}function So(s,t,e,n,i,r,o,a){let c=s;const l=je(n,i,r);l.sort((d,u)=>u.order-d.order);let h;for(const d of l)for(const u of _o(d)){let m;u.history==="deep"?m=f=>dn(f)&&at(f,d):m=f=>f.parent===d,h??={...r},h[u.id]=Array.from(i).filter(m)}for(const d of l)c=Lt(c,t,e,[...d.exit,...d.invoke.map(u=>_s(u.id))],o,void 0),i.delete(d);return[c,h||r]}function Oo(s,t){return s.implementations.actions[t]}function ks(s,t,e,n,i,r){const{machine:o}=s;let a=s;for(const c of n){const l=typeof c=="function",h=l?c:Oo(o,typeof c=="string"?c:c.type),d={context:a.context,event:t,self:e.self,system:e.system},u=l||typeof c=="string"?void 0:"params"in c?typeof c.params=="function"?c.params({context:a.context,event:t}):c.params:void 0;if(!h||!("resolve"in h)){e.actionExecutor({type:typeof c=="string"?c:typeof c=="object"?c.type:c.name||"(anonymous)",info:d,params:u,exec:h});continue}const m=h,[f,w,b]=m.resolve(e,a,d,u,h,i);a=f,"retryResolve"in m&&r?.push([m,w]),"execute"in m&&e.actionExecutor({type:m.type,info:d,params:w,exec:m.execute.bind(null,e,w)}),b&&(a=ks(a,t,e,b,i,r))}return a}function Lt(s,t,e,n,i,r){const o=r?[]:void 0,a=ks(s,t,e,n,{internalQueue:i,deferredActorIds:r},o);return o?.forEach(([c,l])=>{c.retryResolve(e,a,l)}),a}function ke(s,t,e,n){let i=s;const r=[];function o(l,h,d){e.system._sendInspectionEvent({type:"@xstate.microstep",actorRef:e.self,event:h,snapshot:l,_transitions:d}),r.push(l)}if(t.type===Le)return i=Tt(xn(i,t,e),{status:"stopped"}),o(i,t,[]),{snapshot:i,microstates:r};let a=t;if(a.type!==ps){const l=a,h=qr(l),d=$n(l,i);if(h&&!d.length)return i=Tt(s,{status:"error",error:l.error}),o(i,l,[]),{snapshot:i,microstates:r};i=Fe(d,s,e,a,!1,n),o(i,l,d)}let c=!0;for(;i.status==="active";){let l=c?ko(i,a):[];const h=l.length?i:void 0;if(!l.length){if(!n.length)break;a=n.shift(),l=$n(a,i)}i=Fe(l,i,e,a,!1,n),c=i!==h,o(i,a,l)}return i.status!=="active"&&xn(i,a,e),{snapshot:i,microstates:r}}function xn(s,t,e){return Lt(s,t,e,Object.values(s.children).map(n=>_s(n)),[],void 0)}function $n(s,t){return t.machine.getTransitionData(t,s)}function ko(s,t){const e=new Set,n=s._nodes.filter(dn);for(const i of n)t:for(const r of[i].concat(ee(i,void 0)))if(r.always){for(const o of r.always)if(o.guard===void 0||ln(o.guard,s.context,t,s)){e.add(o);break t}}return vs(Array.from(e),new Set(s._nodes),s.historyValue)}function Co(s,t){const e=fe(ge(s,t));return Is(s,[...e])}function Ro(s){return!!s&&typeof s=="object"&&"machine"in s&&"value"in s}const Mo=function(t){return ms(t,this.value)},xo=function(t){return this.tags.has(t)},$o=function(t){const e=this.machine.getTransitionData(this,t);return!!e?.length&&e.some(n=>n.target!==void 0||n.actions.length)},Po=function(){const{_nodes:t,tags:e,machine:n,getMeta:i,toJSON:r,can:o,hasTag:a,matches:c,...l}=this;return{...l,tags:Array.from(e)}},Ho=function(){return this._nodes.reduce((t,e)=>(e.meta!==void 0&&(t[e.id]=e.meta),t),{})};function ae(s,t){return{status:s.status,output:s.output,error:s.error,machine:t,context:s.context,_nodes:s._nodes,value:Is(t.root,s._nodes),tags:new Set(s._nodes.flatMap(e=>e.tags)),children:s.children,historyValue:s.historyValue||{},matches:Mo,hasTag:xo,can:$o,getMeta:Ho,toJSON:Po}}function Tt(s,t={}){return ae({...s,...t},s.machine)}function Bo(s){if(typeof s!="object"||s===null)return{};const t={};for(const e in s){const n=s[e];Array.isArray(n)&&(t[e]=n.map(i=>({id:i.id})))}return t}function Wo(s,t){const{_nodes:e,tags:n,machine:i,children:r,context:o,can:a,hasTag:c,matches:l,getMeta:h,toJSON:d,...u}=s,m={};for(const w in r){const b=r[w];m[w]={snapshot:b.getPersistedSnapshot(t),src:b.src,systemId:b.systemId,syncSnapshot:b._syncSnapshot}}return{...u,context:Cs(o),children:m,historyValue:Bo(u.historyValue)}}function Cs(s){let t;for(const e in s){const n=s[e];if(n&&typeof n=="object")if("sessionId"in n&&"send"in n&&"ref"in n)t??=Array.isArray(s)?s.slice():{...s},t[e]={xstate$$type:cn,id:n.id};else{const i=Cs(n);i!==n&&(t??=Array.isArray(s)?s.slice():{...s},t[e]=i)}}return t??s}function Do(s,t,e,n,{event:i,id:r,delay:o},{internalQueue:a}){const c=t.machine.implementations.delays;if(typeof i=="string")throw new Error(`Only event objects may be used with raise; use raise({ type: "${i}" }) instead`);const l=typeof i=="function"?i(e,n):i;let h;if(typeof o=="string"){const d=c&&c[o];h=typeof d=="function"?d(e,n):d}else h=typeof o=="function"?o(e,n):o;return typeof h!="number"&&a.push(l),[t,{event:l,id:r,delay:h},void 0]}function Lo(s,t){const{event:e,delay:n,id:i}=t;if(typeof n=="number"){s.defer(()=>{const r=s.self;s.system.scheduler.schedule(r,r,e,n,i)});return}}function Ko(s,t){function e(n,i){}return e.type="xstate.raise",e.event=s,e.id=t?.id,e.delay=t?.delay,e.resolve=Do,e.execute=Lo,e}function zo(s,{machine:t,context:e},n,i){const r=(o,a)=>{if(typeof o=="string"){const c=an(t,o);if(!c)throw new Error(`Actor logic '${o}' not implemented in machine '${t.id}'`);const l=Bt(c,{id:a?.id,parent:s.self,syncSnapshot:a?.syncSnapshot,input:typeof a?.input=="function"?a.input({context:e,event:n,self:s.self}):a?.input,src:o,systemId:a?.systemId});return i[l.id]=l,l}else return Bt(o,{id:a?.id,parent:s.self,syncSnapshot:a?.syncSnapshot,input:a?.input,src:o,systemId:a?.systemId})};return(o,a)=>{const c=r(o,a);return i[c.id]=c,s.defer(()=>{c._processingStatus!==W.Stopped&&c.start()}),c}}function Uo(s,t,e,n,{assignment:i}){if(!t.context)throw new Error("Cannot assign to undefined `context`. Ensure that `context` is defined in the machine config.");const r={},o={context:t.context,event:e.event,spawn:zo(s,t,e.event,r),self:s.self,system:s.system};let a={};if(typeof i=="function")a=i(o,n);else for(const l of Object.keys(i)){const h=i[l];a[l]=typeof h=="function"?h(o,n):h}const c=Object.assign({},t.context,a);return[Tt(t,{context:c,children:Object.keys(r).length?{...t.children,...r}:t.children}),void 0,void 0]}function jo(s){function t(e,n){}return t.type="xstate.assign",t.assignment=s,t.resolve=Uo,t}const Pn=new WeakMap;function St(s,t,e){let n=Pn.get(s);return n?t in n||(n[t]=e()):(n={[t]:e()},Pn.set(s,n)),n[t]}const Fo={},jt=s=>typeof s=="string"?{type:s}:typeof s=="function"?"resolve"in s?{type:s.type}:{type:s.name}:s;class me{constructor(t,e){if(this.config=t,this.key=void 0,this.id=void 0,this.type=void 0,this.path=void 0,this.states=void 0,this.history=void 0,this.entry=void 0,this.exit=void 0,this.parent=void 0,this.machine=void 0,this.meta=void 0,this.output=void 0,this.order=-1,this.description=void 0,this.tags=[],this.transitions=void 0,this.always=void 0,this.parent=e._parent,this.key=e._key,this.machine=e._machine,this.path=this.parent?this.parent.path.concat(this.key):[],this.id=this.config.id||[this.machine.id,...this.path].join(us),this.type=this.config.type||(this.config.states&&Object.keys(this.config.states).length?"compound":this.config.history?"history":"atomic"),this.description=this.config.description,this.order=this.machine.idMap.size,this.machine.idMap.set(this.id,this),this.states=this.config.states?kn(this.config.states,(n,i)=>new me(n,{_parent:this,_key:i,_machine:this.machine})):Fo,this.type==="compound"&&!this.config.initial)throw new Error(`No initial state specified for compound state node "#${this.id}". Try adding { initial: "${Object.keys(this.states)[0]}" } to the state config.`);this.history=this.config.history===!0?"shallow":this.config.history||!1,this.entry=it(this.config.entry).slice(),this.exit=it(this.config.exit).slice(),this.meta=this.config.meta,this.output=this.type==="final"||!this.parent?this.config.output:void 0,this.tags=it(t.tags).slice()}_initialize(){this.transitions=po(this),this.config.always&&(this.always=Ot(this.config.always).map(t=>yt(this,fs,t))),Object.keys(this.states).forEach(t=>{this.states[t]._initialize()})}get definition(){return{id:this.id,key:this.key,version:this.machine.version,type:this.type,initial:this.initial?{target:this.initial.target,source:this,actions:this.initial.actions.map(jt),eventType:null,reenter:!1,toJSON:()=>({target:this.initial.target.map(t=>`#${t.id}`),source:`#${this.id}`,actions:this.initial.actions.map(jt),eventType:null})}:void 0,history:this.history,states:kn(this.states,t=>t.definition),on:this.on,transitions:[...this.transitions.values()].flat().map(t=>({...t,actions:t.actions.map(jt)})),entry:this.entry.map(jt),exit:this.exit.map(jt),meta:this.meta,order:this.order||-1,output:this.output,invoke:this.invoke,description:this.description,tags:this.tags}}toJSON(){return this.definition}get invoke(){return St(this,"invoke",()=>it(this.config.invoke).map((t,e)=>{const{src:n,systemId:i}=t,r=t.id??Cn(this.id,e),o=typeof n=="string"?n:`xstate.invoke.${Cn(this.id,e)}`;return{...t,src:o,id:r,systemId:i,toJSON(){const{onDone:a,onError:c,...l}=t;return{...l,type:"xstate.invoke",src:o,id:r}}}}))}get on(){return St(this,"on",()=>[...this.transitions].flatMap(([e,n])=>n.map(i=>[e,i])).reduce((e,[n,i])=>(e[n]=e[n]||[],e[n].push(i),e),{}))}get after(){return St(this,"delayedTransitions",()=>fo(this))}get initial(){return St(this,"initial",()=>go(this,this.config.initial))}next(t,e){const n=e.type,i=[];let r;const o=St(this,`candidates-${n}`,()=>uo(this,n));for(const a of o){const{guard:c}=a,l=t.context;let h=!1;try{h=!c||ln(c,l,e,t)}catch(d){const u=typeof c=="string"?c:typeof c=="object"?c.type:void 0;throw new Error(`Unable to evaluate guard ${u?`'${u}' `:""}in transition for event '${n}' in state node '${this.id}':
|
|
10
|
-
${
|
|
7
|
+
`):(this.indentate=function(){return""},this.tagEndChar=">",this.newLine="")}ct.prototype.build=function(s){return this.options.preserveOrder?Fi(s,this.options):(Array.isArray(s)&&this.options.arrayNodeName&&this.options.arrayNodeName.length>1&&(s={[this.options.arrayNodeName]:s}),this.j2x(s,0,[]).val)};ct.prototype.j2x=function(s,t,e){let n="",i="";const r=e.join(".");for(let o in s)if(Object.prototype.hasOwnProperty.call(s,o))if(typeof s[o]>"u")this.isAttribute(o)&&(i+="");else if(s[o]===null)this.isAttribute(o)||o===this.options.cdataPropName?i+="":o[0]==="?"?i+=this.indentate(t)+"<"+o+"?"+this.tagEndChar:i+=this.indentate(t)+"<"+o+"/"+this.tagEndChar;else if(s[o]instanceof Date)i+=this.buildTextValNode(s[o],o,"",t);else if(typeof s[o]!="object"){const a=this.isAttribute(o);if(a&&!this.ignoreAttributesFn(a,r))n+=this.buildAttrPairStr(a,""+s[o]);else if(!a)if(o===this.options.textNodeName){let c=this.options.tagValueProcessor(o,""+s[o]);i+=this.replaceEntitiesValue(c)}else i+=this.buildTextValNode(s[o],o,"",t)}else if(Array.isArray(s[o])){const a=s[o].length;let c="",l="";for(let d=0;d<a;d++){const h=s[o][d];if(!(typeof h>"u"))if(h===null)o[0]==="?"?i+=this.indentate(t)+"<"+o+"?"+this.tagEndChar:i+=this.indentate(t)+"<"+o+"/"+this.tagEndChar;else if(typeof h=="object")if(this.options.oneListGroup){const u=this.j2x(h,t+1,e.concat(o));c+=u.val,this.options.attributesGroupName&&h.hasOwnProperty(this.options.attributesGroupName)&&(l+=u.attrStr)}else c+=this.processTextOrObjNode(h,o,t,e);else if(this.options.oneListGroup){let u=this.options.tagValueProcessor(o,h);u=this.replaceEntitiesValue(u),c+=u}else c+=this.buildTextValNode(h,o,"",t)}this.options.oneListGroup&&(c=this.buildObjectNode(c,o,l,t)),i+=c}else if(this.options.attributesGroupName&&o===this.options.attributesGroupName){const a=Object.keys(s[o]),c=a.length;for(let l=0;l<c;l++)n+=this.buildAttrPairStr(a[l],""+s[o][a[l]])}else i+=this.processTextOrObjNode(s[o],o,t,e);return{attrStr:n,val:i}};ct.prototype.buildAttrPairStr=function(s,t){return t=this.options.attributeValueProcessor(s,""+t),t=this.replaceEntitiesValue(t),this.options.suppressBooleanAttributes&&t==="true"?" "+s:" "+s+'="'+t+'"'};function Vi(s,t,e,n){const i=this.j2x(s,e+1,n.concat(t));return s[this.options.textNodeName]!==void 0&&Object.keys(s).length===1?this.buildTextValNode(s[this.options.textNodeName],t,i.attrStr,e):this.buildObjectNode(i.val,t,i.attrStr,e)}ct.prototype.buildObjectNode=function(s,t,e,n){if(s==="")return t[0]==="?"?this.indentate(n)+"<"+t+e+"?"+this.tagEndChar:this.indentate(n)+"<"+t+e+this.closeTag(t)+this.tagEndChar;{let i="</"+t+this.tagEndChar,r="";return t[0]==="?"&&(r="?",i=""),(e||e==="")&&s.indexOf("<")===-1?this.indentate(n)+"<"+t+e+r+">"+s+i:this.options.commentPropName!==!1&&t===this.options.commentPropName&&r.length===0?this.indentate(n)+`<!--${s}-->`+this.newLine:this.indentate(n)+"<"+t+e+r+this.tagEndChar+s+this.indentate(n)+i}};ct.prototype.closeTag=function(s){let t="";return this.options.unpairedTags.indexOf(s)!==-1?this.options.suppressUnpairedNode||(t="/"):this.options.suppressEmptyNode?t="/":t=`></${s}`,t};ct.prototype.buildTextValNode=function(s,t,e,n){if(this.options.cdataPropName!==!1&&t===this.options.cdataPropName)return this.indentate(n)+`<![CDATA[${s}]]>`+this.newLine;if(this.options.commentPropName!==!1&&t===this.options.commentPropName)return this.indentate(n)+`<!--${s}-->`+this.newLine;if(t[0]==="?")return this.indentate(n)+"<"+t+e+"?"+this.tagEndChar;{let i=this.options.tagValueProcessor(t,s);return i=this.replaceEntitiesValue(i),i===""?this.indentate(n)+"<"+t+e+this.closeTag(t)+this.tagEndChar:this.indentate(n)+"<"+t+e+">"+i+"</"+t+this.tagEndChar}};ct.prototype.replaceEntitiesValue=function(s){if(s&&s.length>0&&this.options.processEntities)for(let t=0;t<this.options.entities.length;t++){const e=this.options.entities[t];s=s.replace(e.regex,e.val)}return s};function Ji(s){return this.options.indentBy.repeat(s)}function Xi(s){return s.startsWith(this.options.attributeNamePrefix)&&s!==this.options.textNodeName?s.substr(this.attrPrefixLen):!1}class lt{type;attrs={};styles={};deleteMarker=!1;constructor(t){this.type=t}dx(t){return this.attrs.x==null?this.attrs.x=t:this.attrs.x+=t,this}dy(t){return this.attrs.y==null?this.attrs.y=t:this.attrs.y+=t,this}x(t){return this.attrs.x=t,this}y(t){return this.attrs.y=t,this}size(t,e){return this.attrs.width=t,this.attrs.height=e,this}remove(){this.deleteMarker=!0}left(...t){return`<${[this.type,Vn(this.attrs),cr(this.styles),...t].filter(e=>e!="").join(" ")}>`}right(){return`</${this.type}>`}center(){return""}toString(){return this.deleteMarker?"":`${this.left()}${this.center()}${this.right()}`}attr(t){if(typeof t=="string")return this.attrs[t]??"";for(const[e,n]of Object.entries(t))this.attrs[e]=n;return this}css(t){return this.styles={...this.styles,...t},this}svg(){return this.toString()}}class qe extends lt{attrs={};constructor(t){super("image"),this.attrs={...this.attrs,href:t}}load(t){return this.attrs.href=t,this}}class _e extends lt{attrs={};constructor(t){super("use"),this.attrs={...this.attrs,href:this.make(t)}}use(t){return this.attrs.href=`#${t}`,this}make(t){return t==null?t:`#${t}`}}class Qe extends lt{attrs={};constructor(){super("rect")}fill(t){return this.attrs.fill=t,this}stroke(t){return this.attrs.stroke=t,this}}class At extends lt{attrs;_text="";constructor(t=""){super("text"),this._text=t,this.attrs={}}plain(t){return this._text=t,this}font(t){return this.attrs.fontFamily=t.family,this.attrs.fontSize=t.size,this}center(){return this._text}}let tn=class extends lt{raw;constructor(t){super("symbol"),this.raw=t}id(){return this.attr("id")}center(){return this.raw}};class T extends lt{children=[];rotateMatrix;translateMatrix;constructor(){super("g")}add(t){return this.children.push(t),this}rotate(t,e,n){return this.rotateMatrix=qs(t,e,n),this}translate(t,e){return this.translateMatrix=Me(t,e),this}center(){return this.children.map(t=>t.toString()).join("")}left(...t){const e=[this.translateMatrix,this.rotateMatrix].filter(n=>n!=null);return e.length==0?super.left():super.left(ar(Zs(e)))}each(t,e){for(let n=0;n<this.children.length;n++){const i=this.children[n];i instanceof T&&e&&i.each(t,!0),t(n,this.children)}}}const qi=['xmlns="http://www.w3.org/2000/svg"','version="1.1"','xmlns:xlink="http://www.w3.org/1999/xlink"'];class Zn extends lt{children=[];constructor(){super("svg")}viewBox;add(t){return this.children.push(t),this}center(){return this.children.map(t=>t.toString()).join("")}left(...t){return`<${[this.type,...qi,Vn(this.attrs),or(this.viewBox)].filter(e=>e!="").join(" ")}>`}viewbox(t,e,n,i){return this.viewBox={x:t,y:e,width:n,height:i},this}importSymbol(t){for(const e of lr(t))this.add(e);return this}x(t){throw new Error("unimplemented")}y(t){throw new Error("unimplemented")}dx(t){throw new Error("unimplemented")}dy(t){throw new Error("unimplemented")}each(t,e){for(let n=0;n<this.children.length;n++){const i=this.children[n];i instanceof T&&e&&i.each(t,!0),t(n,this.children)}}}function Yn(){return new Zn}const Qi=Yn,tr=T,er=qe,nr=_e,sr=Qe,ir=At;function rr(s){return s.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}function or(s){return s==null?"":`viewBox="${s.x} ${s.y} ${s.width} ${s.height}"`}function ar(s){return s==null?"":`transform="${Qs(s)}"`}function Vn(s){return Object.entries(s).filter(([t,e])=>e!==void 0).map(([t,e])=>`${rr(t)}="${e}"`).join(" ")}function cr(s){const t=Object.entries(s).map(([e,n])=>`${e}: ${n};`).join(" ");return t!=""?`style="${t}"`:""}function*lr(s){const t=new Ui({ignoreAttributes:!1}),e=new ct({ignoreAttributes:!1}),n=t.parse(s);for(const i of n.svg.symbol){const r=e.build(i),o=new tn(r);for(const[a,c]of Object.entries(i))a.startsWith("@_")&&(o.attrs[a.substring(2)]=c);yield o}}const Ne=(s,t)=>{const e=q(s.tiles[0],t),n=e.baseHeight,i=e.baseWidth;if(s.is(E.SHO_KAN))return{width:i*2+n,height:Math.max(i*2,n)};const r=s.tiles.reduce((a,c)=>{const l=q(c,t).height;return l>a?l:a},0);return{width:s.tiles.reduce((a,c)=>a+q(c,t).width,0),height:r}},q=(s,t)=>{const e=parseFloat((rt.HEIGHT*t).toPrecision(5)),n=parseFloat((rt.WIDTH*t).toPrecision(5)),i=s.has(g.HORIZONTAL)?{width:e,height:n,baseWidth:n,baseHeight:e}:{width:n,height:e,w:n,baseWidth:n,baseHeight:e};return(s.has(g.TSUMO)||s.has(g.IMAGE_DORA))&&(i.width+=n*rt.TEXT_SCALE),i};class Mt{tileWidth;tileHeight;imageHostUrl;imageExt;scale;svgSprite;constructor(t={}){this.scale=t.scale??1,this.imageHostUrl=t.imageHostUrl??"",this.imageExt=t.imageExt??"svg",this.tileWidth=rt.WIDTH*this.scale,this.tileHeight=rt.HEIGHT*this.scale,this.svgSprite=t.svgSprite??!1}getHorizontalTileYOffset(t){const e=q(t,this.scale);return(e.baseHeight-e.baseWidth)/2}image(t){let e=this.svgSprite?new _e().use(Mt.buildID(t)):new qe().load(this.buildURL(t));return t instanceof y&&t.has(g.COLOR_GRAYSCALE)&&e.css({filter:"contrast(65%)"}),e}createImage(t,e,n){const i=q(t,this.scale);return this.image(t).dx(e).dy(n).size(i.baseWidth,i.baseHeight)}createTextImage(t,e,n,i){const r=this.createImage(t,e,n),o=q(t,this.scale),a=o.baseHeight*.2,c=o.baseWidth,l=o.baseHeight,d=new At().plain(i);d.size(o.baseWidth,o.baseHeight).font({family:Ze,size:a}).dx(c).dy(l);const h=new T;return h.add(r).add(d).translate(e,n),h}createRotate90Image(t,e,n,i=!1){const r=this.createImage(t,0,0),o=q(t,this.scale),a=o.baseWidth/2,c=o.baseHeight/2,l=e+this.getHorizontalTileYOffset(t),d=i?n-this.getHorizontalTileYOffset(t):n,h=new T;return h.add(r).translate(l,d).rotate(90,a,c),h}createStick(t){return this.image(t)}static buildID(t){if(t===100)return"stick100";if(t===1e3)return"stick1000";const e=t.t==p.BACK||t.has(g.RED)?0:t.n;return`${t.t}${e}`}buildURL(t){const e=`${Mt.buildID(t)}.${this.imageExt}`;return this.imageHostUrl!=""?`${this.imageHostUrl}${e}`:e}}class en extends Mt{blockMargin=rt.WIDTH*rt.BLOCK_MARGIN_SCALE*this.scale;createBlockDiscard(t){return this.createHorizontalBlock(t.tiles)}createBlockHand(t){return this.createHorizontalBlock(t.tiles)}createBlockChi(t){return this.findHorizontalIndex(t),this.createHorizontalBlock(t.tiles)}createBlockPon(t){return this.findHorizontalIndex(t),this.createHorizontalBlock(t.tiles)}createBlockShoKan(t){const e=this.findHorizontalIndex(t);let n=0;const i=new T,r=t.tiles.reduce((o,a,c)=>a.has(g.HORIZONTAL)?c:o,e);for(let o=0;o<t.tiles.length;o++){const a=q(t.tiles[o],this.scale);if(o==r)continue;if(o==e){const d=t.tiles[e],h=t.tiles[r],u=q(d,this.scale),m=this.createRotate90Image(d,0,0,!0),f=this.createRotate90Image(h,0,u.height,!0);i.add(new T().translate(n,0).add(m).add(f)),n+=u.width;continue}const c=a.width*2-a.height,l=this.createImage(t.tiles[o],n,c);n+=a.width,i.add(l)}return i}createBlockDaiKan(t){return this.findHorizontalIndex(t),this.createHorizontalBlock(t.tiles)}createBlockAnKan(t){return this.createHorizontalBlock(t.tilesWithBack)}createBlockDora(t,e=!0){return this.createBlockSingleText(t,"(ドラ)",e)}createBlockTsumo(t,e=!0){return this.createBlockSingleText(t,"(ツモ)",e)}createBlockSingleText(t,e,n=!0){const i=new T,r=n===!1?this.createImage(t.tiles[0],0,0):this.createTextImage(t.tiles[0],0,0,e);return i.add(r),i}createHorizontalBlock(t){let e=0;const n=new T;for(const i of t){const r=q(i,this.scale);let o;if(i.has(g.HORIZONTAL)){const a=this.getHorizontalTileYOffset(i);o=this.createRotate90Image(i,e,a)}else o=this.createImage(i,e,0);n.add(o),e+=r.width}return n}findHorizontalIndex(t){const e=t.tiles.findIndex(n=>n.has(g.HORIZONTAL));if(e<0)throw new Error(`unable to find horizontal operator in block: ${t}`);return e}}function hr(s,t,e){const{enableDoraText:n,enableTsumoText:i}=e;let r=Ne(s,t.scale),o;if(s instanceof U)o=t.createBlockPon(s);else if(s instanceof F)o=t.createBlockChi(s);else if(s instanceof R)o=t.createBlockAnKan(s);else if(s instanceof M)o=t.createBlockShoKan(s);else if(s instanceof K)o=t.createBlockDaiKan(s);else if(s instanceof bt)o=t.createBlockHand(s);else if(s instanceof we)switch(s.type){case E.IMAGE_DISCARD:o=t.createBlockDiscard(s);break;case E.IMAGE_DORA:{const a=n==!1?new bt([s.tiles[0].clone({remove:g.IMAGE_DORA})]):s;r=Ne(a,t.scale),o=t.createBlockDora(a,n);break}case E.TSUMO:{const a=i==!1?new bt([s.tiles[0].clone({remove:g.TSUMO})]):s;r=Ne(a,t.scale),o=t.createBlockTsumo(a,i);break}default:if(s.tiles.some(a=>a.has(g.TSUMO)||a.has(g.IMAGE_DORA)))throw new Error(`found an unknown block with operator tiles. block: ${s}, type: ${s.type}`);o=t.createBlockDiscard(s)}else throw new Error(`unsupported block type. type: ${s.type}, block: ${s}, instance ${s.constructor.name}`);return{...r,e:o}}const kt=(s,t,e=Jn)=>{const n=t.map(d=>hr(d,s,e)),i=n.reduce((d,h)=>d+h.width,0),o=n.reduce((d,h)=>Math.max(d,h.height),0),a=i+(t.length-1)*s.blockMargin,c=new T;let l=0;for(const d of n){const h=o-d.height,u=new T().translate(l,h);u.add(d.e),c.add(u),l+=d.width+s.blockMargin}return{e:c,width:a,height:o}},Jn={enableDoraText:!0,enableTsumoText:!0},dr=(s,t,e={},n=Jn)=>{const i=new en(e),r=kt(i,t,n);n.responsive||s.size(r.width,r.height),s.viewbox(0,0,r.width,r.height),s.add(r.e)},Xn=()=>{const s=[0,1,2,3,4,5,6,7,8,9];return Object.values(p).flatMap(t=>t===p.BACK?[Mt.buildID(new y(t,0))]:s.map(e=>Mt.buildID(new y(t,e))))},ur=s=>{const t=Xn(),e=[];return s.each((n,i)=>{const r=i[n];if(r instanceof _e){const a=r.attr("href").substring(1);t.includes(a)&&e.push(a)}},!0),e},fr=s=>{const t=Xn(),e=ur(s);s.each((n,i)=>{const r=i[n];r instanceof tn&&(t.includes(r.id())&&e.includes(r.id())||r.remove())},!0)},pr=(s,t=6)=>Array.from({length:Math.ceil(s.length/t)},(e,n)=>s.slice(n*t,(n+1)*t)),G=(s,t,e,n,i=0,r=0)=>{const o=new T().add(s);if(n==90){const a=i,c=r-e;return o.rotate(n,0,e).translate(a,c),new T().add(o)}if(n==180){const a=i+t,c=r-e;return o.rotate(n,0,e).translate(a,c),new T().add(o)}if(n==270){const a=i+e,c=r+(t-e);return o.rotate(n,0,e).translate(a,c),new T().add(o)}return new T().add(o)},se=(s,t)=>{const e=new T,n=pr(s);for(let i=0;i<n.length;i++){const r=n[i],o=i*t.tileHeight,a=t.createBlockDiscard(new we(r,E.IMAGE_DISCARD)).translate(0,o);e.add(a)}return{e,width:t.tileWidth*5+t.tileHeight*1,height:t.tileHeight*n.length}},gr=(s,t,e)=>{const n=t.font,i=t.textWidth,r=t.textHeight,o=e.sticks.dead,a=e.sticks.reach,c=Ce.WIDTH*s.scale,l=Ce.HEIGHT*s.scale,d=i*3,h=r+25*s.scale,u=(c+s.tileWidth+i-d)/2,m=new At().plain(e.round).font(n).x(u).y(0),f=s.tileHeight,w=new T().size(c,f).translate(0,h),b={family:n.family,size:n.size*.7},A=s.createStick(1e3).size(c,l).x(0).y(0),O=new At().plain(a.toString()).font(b).dx(c).dy(l),$=s.createStick(100).size(c,l).x(0).y(l+l),ht=new At().plain(o.toString()).font(b).dx(c).dy(l*3);w.add(A),w.add(O),w.add($),w.add(ht);const tt=s.createImage(e.doras[0],0,0).x(c+i).y(0);w.add(tt);const et=new T;return et.add(m),et.add(w),{e:et,width:c+s.tileWidth+i,height:h+s.tileHeight}},mr=(s,t,e=0)=>{const n=kt(s,t.front),i=kt(s,t.right),r=kt(s,t.opposite),o=kt(s,t.left),a=[n.width,i.width,r.width,o.width].reduce((w,b)=>Math.max(w,b)),c=Math.max(e+s.tileHeight*2+s.blockMargin*2,a+s.tileWidth*2+s.blockMargin),l=c,d=G(n.e,n.width,n.height,0).translate((c-n.width)/2,l-n.height),h=G(i.e,i.width,i.height,270).translate(c-i.height,(c-i.width)/2),u=G(r.e,r.width,r.height,180).translate((c-r.width)/2,0),m=G(o.e,o.width,o.height,90).translate(0,(c-o.width)/2),f=new T().size(c,l);return f.add(d),f.add(h),f.add(u),f.add(m),{e:new T().add(f),width:c,height:l}},yr=s=>{const t=Object.values(ye),e=t.indexOf(s);return[...t.slice(e),...t.slice(0,e)]},wr=(s,t,e)=>{const n=s.tileWidth*5+s.tileHeight*1,i=t.font,r=t.textWidth,o=t.textHeight,a=t.numWidth,c=gr(s,t,e);c.e.translate(n/2-c.width/2,n/2-c.height/2);const l=(Ps,mn,Hs)=>{const Bs=`${Ps} ${mn}`,Ws=new At().plain(Bs).font(i).attr(Hs);return{e:new T().add(Ws),width:r+a*mn.toString().length,height:o}},[d,h,u,m]=yr(e.frontPlace),f=e.scores,b=l(d,f.front,{x:n/2,y:n,"dominant-baseline":"text-after-edge","text-anchor":"middle"}).e,A=l(h,f.right,{"dominant-baseline":"text-after-edge","text-anchor":"middle"}),O=G(A.e,A.width,A.height,270).translate(n,n/2-A.width);let $=l(u,f.opposite,{"text-anchor":"middle","dominant-baseline":"text-after-edge"});const ht=G($.e,$.width,$.height,180).translate(n/2-$.width,-$.height),tt=l(m,f.left,{"dominant-baseline":"ideographic","text-anchor":"middle"}),et=G(tt.e,tt.width,tt.height,90).translate(-tt.height,n/2),dt=new T,$s=new Qe().size(n,n).x(0).y(0).fill("none").stroke("#000000");return dt.add($s),dt.add(c.e),dt.add(b),dt.add(O),dt.add(ht),dt.add(et),{e:dt,width:n,height:n}},Er=(s,t)=>{const e=se(t.front,s),n=se(t.right,s),i=se(t.opposite,s),r=se(t.left,s),o=[e.height,n.height,i.height,r.height].reduce((O,$)=>Math.max(O,$)),a=s.tileWidth*5+s.tileHeight*1,c=o,l=a+o*2+s.blockMargin,d=l,h=new T().size(l,d),u=l/2-a/2,m=d/2-a/2,f=G(e.e,a,c,0).translate(u,d-c),w=G(n.e,a,c,270).translate(l-c,m),b=G(i.e,a,c,180).translate(u,0),A=G(r.e,a,c,90).translate(0,m);return h.add(f),h.add(w),h.add(b),h.add(A),{e:new T().add(h),width:l,height:d}},qn=(s,t,e,n,i)=>{const r=new T,o=Er(s,n),a=mr(s,e,o.height),c=wr(s,t,i);return o.e.translate((a.width-o.width)/2,(a.height-o.height)/2),c.e.translate((a.width-c.width)/2,(a.height-c.height)/2),r.add(a.e),r.add(o.e),r.add(c.e),{e:r,width:a.width,height:a.height}},br=(s,t,e={},n,i={responsive:!1})=>{const r=new en(e),o=n,{discards:a,hands:c,scoreBoard:l}=es(t),d=qn(r,o,c,a,l);i.responsive||s.size(d.width,d.height),s.viewbox(0,0,d.width,d.height),s.add(d.e)};let ve;function Qn(s){return{lang:s?.lang??ve?.lang,message:s?.message,abortEarly:s?.abortEarly??ve?.abortEarly,abortPipeEarly:s?.abortPipeEarly??ve?.abortPipeEarly}}let _r;function Ar(s){return _r?.get(s)}let Ir;function Tr(s){return Ir?.get(s)}let Nr;function vr(s,t){return Nr?.get(s)?.get(t)}function xt(s){const t=typeof s;return t==="string"?`"${s}"`:t==="number"||t==="bigint"||t==="boolean"?`${s}`:t==="object"||t==="function"?(s&&Object.getPrototypeOf(s)?.constructor?.name)??"null":t}function ot(s,t,e,n,i){const r=i&&"input"in i?i.input:e.value,o=i?.expected??s.expects??null,a=i?.received??xt(r),c={kind:s.kind,type:s.type,input:r,expected:o,received:a,message:`Invalid ${t}: ${o?`Expected ${o} but r`:"R"}eceived ${a}`,requirement:s.requirement,path:i?.path,issues:i?.issues,lang:n.lang,abortEarly:n.abortEarly,abortPipeEarly:n.abortPipeEarly},l=s.kind==="schema",d=i?.message??s.message??vr(s.reference,c.lang)??(l?Tr(c.lang):null)??n.message??Ar(c.lang);d!==void 0&&(c.message=typeof d=="function"?d(c):d),l&&(e.typed=!1),e.issues?e.issues.push(c):e.issues=[c]}function Kt(s){return{version:1,vendor:"valibot",validate(t){return s["~run"]({value:t},Qn())}}}function Sr(s,t){const e=[...new Set(s)];return e.length>1?`(${e.join(` ${t} `)})`:e[0]??"never"}function Pe(s,t){return{kind:"validation",type:"max_value",reference:Pe,async:!1,expects:`<=${s instanceof Date?s.toJSON():xt(s)}`,requirement:s,message:t,"~run"(e,n){return e.typed&&!(e.value<=this.requirement)&&ot(this,"value",e,n,{received:e.value instanceof Date?e.value.toJSON():xt(e.value)}),e}}}function He(s,t){return{kind:"validation",type:"min_value",reference:He,async:!1,expects:`>=${s instanceof Date?s.toJSON():xt(s)}`,requirement:s,message:t,"~run"(e,n){return e.typed&&!(e.value>=this.requirement)&&ot(this,"value",e,n,{received:e.value instanceof Date?e.value.toJSON():xt(e.value)}),e}}}function Or(s,t,e){return typeof s.fallback=="function"?s.fallback(t,e):s.fallback}function ts(s,t,e){return typeof s.default=="function"?s.default(t,e):s.default}function he(s){return{kind:"schema",type:"number",reference:he,expects:"number",async:!1,message:s,get"~standard"(){return Kt(this)},"~run"(t,e){return typeof t.value=="number"&&!isNaN(t.value)?t.typed=!0:ot(this,"type",t,e),t}}}function z(s,t){return{kind:"schema",type:"optional",reference:z,expects:`(${s.expects} | undefined)`,async:!1,wrapped:s,default:t,get"~standard"(){return Kt(this)},"~run"(e,n){return e.value===void 0&&(this.default!==void 0&&(e.value=ts(this,e,n)),e.value===void 0)?(e.typed=!0,e):this.wrapped["~run"](e,n)}}}function Be(s,t){return{kind:"schema",type:"picklist",reference:Be,expects:Sr(s.map(xt),"|"),async:!1,options:s,message:t,get"~standard"(){return Kt(this)},"~run"(e,n){return this.options.includes(e.value)?e.typed=!0:ot(this,"type",e,n),e}}}function $t(s,t){return{kind:"schema",type:"strict_object",reference:$t,expects:"Object",async:!1,entries:s,message:t,get"~standard"(){return Kt(this)},"~run"(e,n){const i=e.value;if(i&&typeof i=="object"){e.typed=!0,e.value={};for(const r in this.entries){const o=this.entries[r];if(r in i||(o.type==="exact_optional"||o.type==="optional"||o.type==="nullish")&&o.default!==void 0){const a=r in i?i[r]:ts(o),c=o["~run"]({value:a},n);if(c.issues){const l={type:"object",origin:"value",input:i,key:r,value:a};for(const d of c.issues)d.path?d.path.unshift(l):d.path=[l],e.issues?.push(d);if(e.issues||(e.issues=c.issues),n.abortEarly){e.typed=!1;break}}c.typed||(e.typed=!1),e.value[r]=c.value}else if(o.fallback!==void 0)e.value[r]=Or(o);else if(o.type!=="exact_optional"&&o.type!=="optional"&&o.type!=="nullish"&&(ot(this,"key",e,n,{input:void 0,expected:`"${r}"`,path:[{type:"object",origin:"key",input:i,key:r,value:i[r]}]}),n.abortEarly))break}if(!e.issues||!n.abortEarly){for(const r in i)if(!(r in this.entries)){ot(this,"key",e,n,{input:r,expected:"never",path:[{type:"object",origin:"key",input:i,key:r,value:i[r]}]});break}}}else ot(this,"type",e,n);return e}}}function de(s){return{kind:"schema",type:"string",reference:de,expects:"string",async:!1,message:s,get"~standard"(){return Kt(this)},"~run"(t,e){return typeof t.value=="string"?t.typed=!0:ot(this,"type",t,e),t}}}function Nn(...s){return{...s[0],pipe:s,get"~standard"(){return Kt(this)},"~run"(t,e){for(const n of s)if(n.kind!=="metadata"){if(t.issues&&(n.kind==="schema"||n.kind==="transformation")){t.typed=!1;break}(!t.issues||!e.abortEarly&&!e.abortPipeEarly)&&(t=n["~run"](t,e))}return t}}}function kr(s,t,e){const n=s["~run"]({value:t},Qn(e));return{typed:n.typed,success:!n.issues,output:n.value,issues:n.issues}}const ie=z($t({discard:z(de(),""),hand:z(de(),""),score:z(he(),25e3)}),{discard:"",hand:"",score:25e3}),Cr=$t({[_.E]:ie,[_.S]:ie,[_.W]:ie,[_.N]:ie}),ft={round:k.E1,sticks:{reach:0,dead:0},doras:_.S,front:_.E},Rr=z($t({round:z(Be(Object.keys(Ye)),ft.round),sticks:z($t({reach:z(Nn(he(),He(0,""),Pe(9,"")),ft.sticks.reach),dead:z(Nn(he(),He(0,""),Pe(9,"")),ft.sticks.dead)}),ft.sticks),doras:z(de(),ft.doras),front:z(Be(Object.keys(ye)),ft.front)}),ft),Mr=$t({...Cr.entries,board:Rr}),es=s=>{const t=ns(s);return ss(t)},ns=s=>{const t=xr(s),e=kr(Mr,t);if(!e.success)throw e.issues;return e.output},xr=s=>{const t="table",e="board",n=s.split(`
|
|
8
|
+
`).map(a=>a.trim()).filter(a=>a!="");if(n.length==0)throw new Error("empty input");const i=n.shift();if(!i.startsWith(t))throw new Error(`input does not start with table: ${i}`);const r={};let o=[_.E,_.S,_.W,_.N,e];for(;;){const a=n.shift();if(a==null)break;const c=o.find(l=>a.startsWith(l));if(c==null)throw new Error(`encountered unexpected line ${a}`);if(o=o.filter(l=>!a.startsWith(l)),c==e){const[l,d]=Pr([...n]);r.board=l,n.splice(0,d)}else{const[l,d]=$r([...n]);r[c]=l,n.splice(0,d)}}return r},Y=(s,t)=>s.replace(t,"").replace(":","").trim(),$r=s=>{const t="hand",e="discard",n="score",i={};let r=0;for(;r<s.length;r++){const o=s[r];if(o.startsWith(t))i.hand=Y(o,t);else if(o.startsWith(e))i.discard=Y(o,e);else if(o.startsWith(n))i.score=Number(Y(o,n));else break}return[i,r]},Pr=s=>{const t="doras",e="round",n="front",i="sticks",r="reach",o="dead",a={};let c=0;for(;c<s.length;c++){const l=s[c];if(l.startsWith(t))a.doras=Y(l,t);else if(l.startsWith(e))a.round=Y(l,e);else if(l.startsWith(n))a.front=Y(l,n);else if(l.startsWith(i)){a.sticks={};const d=s[c+1]??"",h=s[c+2]??"";d.startsWith(r)&&(a.sticks.reach=Number(Y(d,r))),d.startsWith(o)&&(a.sticks.dead=Number(Y(d,o))),h.startsWith(r)&&(a.sticks.reach=Number(Y(h,r))),h.startsWith(o)&&(a.sticks.dead=Number(Y(h,o))),a.sticks.dead!=null&&c++,a.sticks.reach!=null&&c++}else break}return[a,c]},ss=s=>{const t=s.board.front,e=Hr(t),n=a=>s[a].discard.replace(/\r?\n/g,""),i={front:new D(n(e.front)).tiles(),right:new D(n(e.right)).tiles(),opposite:new D(n(e.opposite)).tiles(),left:new D(n(e.left)).tiles()},r={front:new D(s[e.front].hand).parse(),right:new D(s[e.right].hand).parse(),opposite:new D(s[e.opposite].hand).parse(),left:new D(s[e.left].hand).parse()},o={round:Ye[s.board.round],frontPlace:ye[t],sticks:s.board.sticks,doras:new D(s.board.doras).tiles(),scores:{front:s[e.front].score,right:s[e.right].score,opposite:s[e.opposite].score,left:s[e.left].score}};return{discards:i,hands:r,scoreBoard:o}},Hr=s=>({front:s,right:_t(s),opposite:_t(_t(s)),left:Ee(s)});function*j(s){const t=s?.filterBy&&s.filterBy.length>0?s?.filterBy:Object.values(p);for(const e of t){if(s?.skipBack&&e==p.BACK)continue;const n=e==p.Z?7:e==p.BACK?1:9;for(let i=1;i<=n;i++)yield[e,i]}}class Ae{data;constructor(t,e=!1){this.data={[p.M]:[0,0,0,0,0,0,0,0,0,0],[p.P]:[0,0,0,0,0,0,0,0,0,0],[p.S]:[0,0,0,0,0,0,0,0,0,0],[p.Z]:[0,0,0,0,0,0,0,0],[p.BACK]:["untouchable",0],called:[],reached:!1,tsumo:null},this.init(t,e)}init(t,e){const n=typeof t=="string"?new D(t).parse():t;for(const i of n){if(i.isCalled()){this.data.called=[...this.called,i];continue}else if(i.is(E.TSUMO)){const r=i.tiles[0];this.inc([r]),this.data.tsumo=r;continue}else if(i.is(E.HAND)){this.inc(i.tiles);continue}else if(typeof t=="string"&&t.split("").every(r=>r===p.BACK)){this.inc(i.tiles);continue}else if(e){this.inc(i.tiles);continue}throw new Error(`unexpected block ${i.type} ${i.toString()}`)}}get hands(){const t=[];for(const[e,n]of j()){let i=this.get(e,n);e!=p.Z&&n==5&&this.get(e,0)>0&&(i-=this.get(e,0),t.push(new y(e,n,[g.RED])));for(let r=0;r<i;r++)t.push(new y(e,n))}if(this.drawn!=null){const e=this.drawn,n=t.findIndex(i=>i.equals(e)&&e.has(g.RED)==i.has(g.RED));I(n>=0,`drawn tile ${this.drawn} not found in hand: ${t.join("")}`),t[n]=t[n].clone({add:g.TSUMO})}return t}toString(){const t=this.called.length>0?`${V}${this.called.join(V)}`:"",e=this.drawn?`${V}${this.drawn.toString()}`:"",n=this.hands.filter(r=>!r.has(g.TSUMO));return`${new bt(n).toString()}${e}${t}`}get called(){return this.data.called}get reached(){return this.data.reached}get drawn(){return this.data.tsumo}get menzen(){return!this.called.some(t=>!(t instanceof R))}sum(t){return Array.from(j({filterBy:[t]})).reduce((e,[n,i])=>e+this.get(n,i),0)}get(t,e){return t==p.BACK?this.data[t][1]:this.data[t][e]}inc(t){const e=[];for(const n of t){const i=n.t!=p.BACK&&this.get(n.t,n.n)>=4,r=n.has(g.RED)&&this.get(n.t,0)>0;if(i||r){this.dec(e);const o=i?`tile ${n} exists more than 4 times`:`red tile ${n} appears more than once`;throw new Error(`invalid hand: ${o} in hand: ${this.toString()}`)}e.push(n),n.t==p.BACK?this.data[n.t][1]+=1:(this.data[n.t][n.n]+=1,n.has(g.RED)&&(this.data[n.t][0]+=1))}return e}dec(t){const e=[];for(const n of t){const i=this.get(n.t,n.n)<1,r=n.has(g.RED)&&this.get(n.t,0)<=0;if(i||r){this.inc(e);const o=i?`tile ${n} does not exist`:`red tile ${n} does not exist`;throw new Error(`invalid hand: ${o} in hand: ${this.toString()}`)}if(e.push(n),n.t==p.BACK?this.data[n.t][1]-=1:(this.data[n.t][n.n]-=1,n.has(g.RED)&&(this.data[n.t][0]-=1)),S(n)&&this.get(n.t,5)==0&&this.get(n.t,0)>0){this.data[n.t][0]=0;const o=e.pop().clone({add:g.RED});e.push(o)}}return e}draw(t){const e=t.clone({add:g.TSUMO});this.inc([e]),this.data.tsumo=e}discard(t){this.dec([t]),this.data.tsumo=null}reach(){if(!this.menzen)throw new Error("cannot declare reach due to called");if(this.data.reached)throw new Error("already declared reach");this.data.reached=!0}call(t){const e=t.tiles.filter(n=>!n.has(g.HORIZONTAL));if(e.length!=t.tiles.length-1)throw new Error(`invalid block: removal tiles: ${e}, block: ${t}`);this.dec(e),this.data.called=[...this.called,t],this.data.tsumo=null}kan(t){if(t instanceof R){this.dec(t.tiles),this.data.called=[...this.called,t],this.data.tsumo=null;return}if(t instanceof M){const e=this.data.called.findIndex(i=>i.is(E.PON)&&i.tiles[0].equals(t.tiles[0]));if(e==-1)throw new Error(`cannot find pon block ${t.tiles[0]} to call shokan: ${t}`);let n=t.tiles[0];n=S(n)?n.clone({remove:g.RED}):n,this.dec([n]),this.data.called=[...this.called.slice(0,e),...this.called.slice(e+1),t],this.data.tsumo=null;return}throw new Error(`unexpected block type ${t}`)}clone(){const t=new Ae(this.toString());return t.data.reached=this.data.reached,t}}class te{hand;constructor(t){this.hand=t}calc(){return Math.min(this.sevenPairs(),this.thirteenOrphans(),this.standardType())}sevenPairs(){if(this.hand.called.length>0)return Number.POSITIVE_INFINITY;let t=0,e=0;for(const[n,i]of j({skipBack:!0}))this.hand.get(n,i)>=2&&t++,this.hand.get(n,i)==1&&e++;return t>7&&(t=7),t+e>=7&&(e=7-t),13-2*t-e}thirteenOrphans(){if(this.hand.called.length>0)return Number.POSITIVE_INFINITY;let t=0,e=0;for(const n of Object.values(p)){if(n==p.BACK)continue;const i=n==p.Z?Pt:J;for(const r of i)this.hand.get(n,r)>=1&&t++,this.hand.get(n,r)>=2&&e++}return e>=1?12-t:13-t}standardType(){const t=n=>{const i=[0,0,0];for(const[u,m]of j({filterBy:[p.Z]}))this.hand.get(u,m)>=3?i[0]++:this.hand.get(u,m)==2?i[1]++:this.hand.get(u,m)==1&&i[2]++;const r=[0,0,0],o=this.hand.get(p.BACK,0),a=o%3;r[0]=Math.floor(o/3),a==2?r[1]=1:a==1&&(r[2]=1);let c=13;const l=this.calcNumberTilePatterns(p.M),d=this.calcNumberTilePatterns(p.P),h=this.calcNumberTilePatterns(p.S);for(const u of[l.patternA,l.patternB])for(const m of[d.patternA,d.patternB])for(const f of[h.patternA,h.patternB]){const w=[this.hand.called.length,0,0];for(let A=0;A<3;A++)w[A]+=u[A]+m[A]+f[A]+i[A]+r[A];const b=this.getStandardTypeShanten(w[0],w[1],w[2],n);b<c&&(c=b)}return c};let e=t(!1);for(const[n,i]of j())if(this.hand.get(n,i)>=2){const r=this.hand.dec(new Array(2).fill(new y(n,i))),o=t(!0);this.hand.inc(r),o<e&&(e=o)}return e}calcNumberTilePatterns(t,e=1){if(e>9)return this.groupRemainingTiles(t);let n=this.calcNumberTilePatterns(t,e+1);if(e<=7&&this.hand.get(t,e)>0&&this.hand.get(t,e+1)>0&&this.hand.get(t,e+2)>0){const i=this.hand.dec([new y(t,e),new y(t,e+1),new y(t,e+2)]),r=this.calcNumberTilePatterns(t,e);this.hand.inc(i),r.patternA[0]++,r.patternB[0]++,(r.patternA[2]<n.patternA[2]||r.patternA[2]==n.patternA[2]&&r.patternA[1]<n.patternA[1])&&(n.patternA=r.patternA),(r.patternB[0]>n.patternB[0]||r.patternB[0]==n.patternB[0]&&r.patternB[1]>n.patternB[1])&&(n.patternB=r.patternB)}if(this.hand.get(t,e)>=3){const i=this.hand.dec(new Array(3).fill(new y(t,e))),r=this.calcNumberTilePatterns(t,e);this.hand.inc(i),r.patternA[0]++,r.patternB[0]++,(r.patternA[2]<n.patternA[2]||r.patternA[2]==n.patternA[2]&&r.patternA[1]<n.patternA[1])&&(n.patternA=r.patternA),(r.patternB[0]>n.patternB[0]||r.patternB[0]==n.patternB[0]&&r.patternB[1]>n.patternB[1])&&(n.patternB=r.patternB)}return n}groupRemainingTiles(t){let e=0,n=0,i=0;for(const[r,o]of j({filterBy:[t]}))i+=this.hand.get(r,o),o<=7&&this.hand.get(r,o+1)==0&&this.hand.get(r,o+2)==0&&(e+=i>>1,n+=i%2,i=0);return e+=i>>1,n+=i%2,{patternA:[0,e,n],patternB:[0,e,n]}}getStandardTypeShanten(t,e,n,i){let r=i?4:5;return t>4&&(e+=t-4,t=4),t+e>4&&(n+=t+e-4,e=4-t),t+e+n>r&&(n=r-t-e),i&&e++,13-t*3-e*2-n}}class is{hand;constructor(t){this.hand=t}calc(t){return this.markedHands([...this.sevenPairs(),...this.thirteenOrphans(),...this.nineGates(),...this.standardType()],t)}markedHands(t,e){return t.length==0?[]:t.map(n=>this.markedHand(n,e)).flat()}markedHand(t,e){if(t.length==0)return[];const n=this.hand.drawn!=null||e.has(g.TSUMO)?g.TSUMO:g.RON,i=[],r={};for(let a=0;a<t.length;a++){const c=t[a];if(c.isCalled())continue;const l=c.tiles.findIndex(h=>h.equals(e)&&e.has(g.RED)==h.has(g.RED));if(l<0)continue;const d=Gt(c);r[d]||(r[d]=!0,i.push([a,l]))}if(i.length==0)throw new Error(`tile ${e.toString()} not found in hand: ${t.toString()}`);const o=[];for(const[a,c]of i){const l=[...t],d=l[a],h=d.tiles[c].clone({add:n});l[a]=d.clone({replace:{idx:c,tile:h}}),o.push(l)}return o}sevenPairs(){if(this.hand.called.length>0)return[];const t=[];for(const[e,n]of j({skipBack:!0})){const i=this.hand.get(e,n);if(i!=0)if(i==2){const r=this.hand.dec(new Array(2).fill(new y(e,n)));t.push(new C(r[0],r[1])),this.hand.inc(r)}else return[]}return[t]}thirteenOrphans(){const t=[];let e=!1;for(const n of Object.values(p)){if(n==p.BACK)continue;const i=n==p.Z?Pt:J;for(let r of i)if(this.hand.get(n,r)==1)t.push(new Je(new y(n,r)));else if(this.hand.get(n,r)==2&&e==!1)t.unshift(new C(new y(n,r),new y(n,r))),e=!0;else return[]}return[t]}nineGates(){const t=(e,n,i)=>i.includes(this.hand.get(e,n));for(const e of Object.values(p)){if(e==p.BACK||e==p.Z)continue;const n=t(e,1,[3,4])&&t(e,9,[3,4])&&t(e,2,[1,2])&&t(e,3,[1,2])&&t(e,4,[1,2])&&t(e,5,[1,2])&&t(e,6,[1,2])&&t(e,7,[1,2])&&t(e,8,[1,2]),i=this.hand.sum(e)==14;if(n&&i)return[[new bt(this.hand.hands)]]}return[]}standardType(){let t=[];for(const[e,n]of j())if(this.hand.get(e,n)>=2){const i=new Array(2).fill(new y(e,n));n==5&&this.hand.get(e,0)>0&&this.hand.get(e,n)>=3&&(i[1]=new y(e,n,[g.RED]));const r=this.hand.dec(i),o=this.calcAllBlockCombinations().filter(a=>a.length==4).map(a=>[new C(r[0],r[1]),...a]);t=[...t,...o],this.hand.inc(r)}return t}calcAllBlockCombinations(){return[this.addRedPatterns(p.M,this.handleNumType(p.M)),this.addRedPatterns(p.P,this.handleNumType(p.P)),this.addRedPatterns(p.S,this.handleNumType(p.S)),this.handleZ(),this.handleBack(),[this.hand.called.concat()]].sort((n,i)=>i.length-n.length).reduce((n,i)=>i.length===0?n:n.flatMap(r=>i.map(o=>[...r,...o])),[[]])}handleBack(){const t=p.BACK,e=this.hand.get(t,0);if(e<3)return[];const n=new y(t,0),i=Array(Math.floor(e/3)).fill(new L([n,n,n]));return i.length==0?[]:[i]}handleZ(){const t=[];for(const[e,n]of j({filterBy:[p.Z]})){if(this.hand.get(e,n)==0)continue;if(this.hand.get(e,n)!=3)return[];const i=new y(e,n);t.push(new L([i,i,i]))}return t.length==0?[]:[t]}addRedPattern(t,e){const n=new y(t,5),i=new y(t,5,[g.RED]),r=[];let o=null;const a={};for(let l=0;l<e.length;l++){const d=e[l],h=d.tiles.findIndex(f=>S(f)&&!f.has(g.RED)),u=d.tiles.findIndex(f=>S(f)&&f.has(g.RED));if(u>-1&&(o=[l,u]),u>-1&&h>-1||h<0)continue;const m=Gt(d);a[m]||(a[m]=!0,r.push([l,h]))}if(o==null)return[e];const c=[e];for(const[l,d]of r){const h=[...e],u=h[l];h[l]=u.clone({replace:{idx:d,tile:i}});const m=h[o[0]];h[o[0]]=m.clone({replace:{idx:o[1],tile:n}}),Gt(u)!=Gt(m)&&c.push(h)}return c}addRedPatterns(t,e){return this.hand.get(t,0)>0&&this.hand.get(t,5)>=2?e.map(n=>this.addRedPattern(t,n)).flat():e}handleNumType(t,e=1){if(e>9)return[];if(this.hand.get(t,e)==0)return this.handleNumType(t,e+1);const n=[];if(e<=7&&this.hand.get(t,e)>0&&this.hand.get(t,e+1)>0&&this.hand.get(t,e+2)>0){const i=this.hand.dec([new y(t,e),new y(t,e+1),new y(t,e+2)]);let r=this.handleNumType(t,e);this.hand.inc(i),r.length==0&&(r=[[]]);for(const o of r)n.push([new nt([i[0],i[1],i[2]]),...o])}if(this.hand.get(t,e)==3){const i=this.hand.dec(new Array(3).fill(new y(t,e)));let r=this.handleNumType(t,e);this.hand.inc(i),r.length==0&&(r=[[]]);for(const o of r)n.push([new L([i[0],i[1],i[2]]),...o])}return n}}const Pt=[1,2,3,4,5,6,7],J=[1,9],Ft=s=>{const t=s.boardContext;return{...s,hand:s.hand.map(N.deserialize),boardContext:{...t,doraIndicators:t.doraIndicators.map(y.from),hiddenDoraIndicators:t.hiddenDoraIndicators?.map(y.from)}}},ue=s=>JSON.parse(JSON.stringify(s)),x={MANGAN:2e3,HANEMAN:3e3,DOUBLE:4e3,TRIPLE:6e3,YAKUMAN:8e3,DOUBLE_YAKUMAN:16e3,DEAD_STICK:300,REACH_STICK:1e3},Br=[{minHan:26,points:x.DOUBLE_YAKUMAN},{minHan:13,points:x.YAKUMAN},{minHan:11,points:x.TRIPLE},{minHan:8,points:x.DOUBLE},{minHan:6,points:x.HANEMAN},{minHan:5,points:x.MANGAN}],Wr={[x.MANGAN]:"満貫",[x.HANEMAN]:"跳満",[x.DOUBLE]:"倍満",[x.TRIPLE]:"三倍満"},X={PARENT_RON:6,CHILD_RON:4,PARENT_TSUMO:2,CHILD_TUMO_FROM_PARENT:2,CHILD_TUMO_FROM_CHILD:1};function rs(s){if(s.isYakuman)return"役満";if(s.isCountableYakuman)return"数え役満";const t=Dr(s.base,s.isTsumo,s.isParent),e=Wr[s.base];return e?`${s.fu}符${s.han}飜 ${e}${t}`:`${s.fu}符${s.han}飜 ${t}`}function Dr(s,t,e){if(t)return e?`${st(s*X.PARENT_TSUMO)}`:`${st(s*X.CHILD_TUMO_FROM_CHILD)}-${st(s*X.CHILD_TUMO_FROM_PARENT)}`;{const n=e?X.PARENT_RON:X.CHILD_RON;return`${st(s*n)}`}}const st=(s,t=100)=>Math.ceil(s/t)*t;class nn{hand;cfg;constructor(t,e){this.hand=t,this.cfg={doras:e.doraIndicators.map(n=>We(n)),hiddenDoras:e.hiddenDoraIndicators==null?[]:e.hiddenDoraIndicators.map(n=>We(n)),roundWind:y.from(Ln(e.round)),myWind:y.from(e.myWind),reached:e.doubleReached?2:t.reached?1:0,sticks:e.sticks??{dead:0,reach:0},replacementWin:e.replacementWin??!1,quadWin:e.quadWin??!1,finalWallWin:e.finalWallWin??!1,finalDiscardWin:e.finalDiscardWin??!1,oneShotWin:e.oneShotWin??!1,enableRoundUpMangan:e.enableRoundUpMangan??!1,disableCountableYakuman:e.disableCountableYakuman??!1,disableDoubleYakuman:e.disableDoubleYakuman??!1,orig:e}}calc(...t){const e=this.getWinningHands(t);if(e.length===0)return!1;const n=this.selectBestHand(e),i=this.calculateScore(n),r=this.calculateDeltas(i.base,i.isTsumo,i.isParent,i.myWind,this.cfg.orig.ronWind),o=r[i.myWind];this.addStickPoints(r,i.myWind,this.cfg.orig.ronWind);const a=rs({base:i.base,fu:i.fu,han:i.han,isTsumo:i.isTsumo,isParent:i.isParent,isYakuman:i.isYakuman,isCountableYakuman:i.isCountableYakuman});return{...n,fu:i.fu,deltas:r,points:r[i.myWind],basePoints:o,boardContext:this.cfg.orig,description:a}}getWinningHands(t){const e=[];if(t.length==0)return e;for(const n of t){const i=[...this.dA13(n),...this.dB13(n),...this.dC13(n),...this.dD13(n),...this.dE13(n),...this.dF13(n),...this.dG13(n),...this.dH13(n),...this.dI13(n),...this.dJ13(n),...this.dK13(n)].map(r=>(this.cfg.disableDoubleYakuman&&r.han>13&&(r.han=13),r));i.length!=0&&e.push({yakus:i,han:i.reduce((r,o)=>r+o.han,0),fu:30,hand:n,isYakuman:!0})}if(e.length>0)return e;for(const n of t){const i=this.calcFu(n),r=[...this.dA1(n),...this.dB1(n),...this.dC1(n),...this.dD1(n),...this.dE1(n),...this.dF1(n),...this.dG1(n),...this.dH1(n),...this.dI1(n),...this.dJ1(n),...this.dK1(n),...this.dA2(n),...this.dB2(n),...this.dC2(n),...this.dD2(n),...this.dE2(n),...this.dF2(n),...this.dG2(n),...this.dH2(n),...this.dI2(n),...this.dJ2(n),...this.dA3(n),...this.dB3(n),...this.dC3(n),...this.dA6(n)];r.length!=0&&(r.push(...this.dX1(n)),e.push({yakus:r,han:r.reduce((o,a)=>o+a.han,0),fu:i,hand:n}))}return e}selectBestHand(t){return t.reduce((e,n)=>{const{han:i,fu:r}=n,{han:o,fu:a}=e;return i>o||i===o&&r>a?n:e})}calculateScore(t){const{han:e}=t,n=t.fu!==25?st(t.fu,10):25,i=t.isYakuman??!1;let r=this.getBasePoints(e,n),o=!1;e>=13&&e<26&&!this.hasYakuman(t.yakus)&&(r=this.cfg.disableCountableYakuman?x.TRIPLE:x.YAKUMAN,o=!this.cfg.disableCountableYakuman),this.cfg.enableRoundUpMangan&&this.isRoundUpMangan(n,e)&&(r=x.MANGAN);const a=this.isTsumoWin(t.hand),c=this.cfg.orig.myWind,l=c===_.E;return{base:r,fu:n,han:e,isYakuman:o?!0:i,isCountableYakuman:o,isTsumo:a,myWind:c,isParent:l}}hasYakuman(t){return t.some(e=>e.isYakuman)}isRoundUpMangan(t,e){return t===30&&e===4||t===60&&e===3}isTsumoWin(t){return t.some(e=>e.tiles.some(n=>n.has(g.TSUMO)))}calculateDeltas(t,e,n,i,r){const o=H(()=>0);return e?this.calculateTsumoDeltas(o,t,n,i):(I(r!=null,"tumo is false but ron wind is null"),this.calculateRonDeltas(o,t,n,i,r)),o}calculateRonDeltas(t,e,n,i,r){const o=n?X.PARENT_RON:X.CHILD_RON,a=st(e*o);t[i]+=a,t[r]-=a}calculateTsumoDeltas(t,e,n,i){if(n){const r=st(e*X.PARENT_TSUMO);t[_.E]+=r*3,t[_.S]-=r,t[_.W]-=r,t[_.N]-=r;return}for(const r of Object.values(_)){if(r==i)continue;const o=r==_.E?X.CHILD_TUMO_FROM_PARENT:X.CHILD_TUMO_FROM_CHILD,a=st(e*o);t[r]-=a,t[i]+=a}}addStickPoints(t,e,n){t[e]+=x.REACH_STICK*this.cfg.sticks.reach;const i=x.DEAD_STICK*this.cfg.sticks.dead;if(n!=null){t[e]+=i,t[n]-=i;return}for(const r of Object.values(_))r==e?t[r]+=i:t[r]-=i/3}getBasePoints(t,e){for(const{minHan:n,points:i}of Br)if(t>=n)return i;return Math.min(e*2**(t+2),x.MANGAN)}getCalledPenalty(){return this.hand.menzen?0:1}dA1(t){return this.cfg.reached==1?[{name:"立直",han:1}]:this.cfg.reached==2?[{name:"ダブル立直",han:2}]:[]}dB1(t){return this.hand.drawn==null,this.getCalledPenalty()!=0?[]:t.some(n=>n.tiles.some(i=>i.has(g.TSUMO)))?[{name:"門前清自摸和",han:1}]:[]}dC1(t){if(this.getCalledPenalty()!=0)return[];const e="平和",n=this.calcFu(t);return n==20?[{name:e,han:1}]:!t.some(i=>i.tiles.some(r=>r.has(g.TSUMO)))&&n==30?[{name:e,han:1}]:[]}dD1(t){return t.some(n=>n.tiles.some(i=>i.t==p.Z||J.includes(i.n)))?[]:[{name:"断么九",han:1}]}dE1(t){return this.getCalledPenalty()!=0?[]:vn(t)==1?[{name:"一盃口",han:1}]:[]}dF1(t){const e=[];return t.forEach(n=>{if(n instanceof C)return;const i=n.tiles[0];i.t==p.Z&&(i.equals(this.cfg.myWind)&&e.push({name:"自風",han:1}),i.equals(this.cfg.roundWind)?e.push({name:"場風",han:1}):i.n==5?e.push({name:"白",han:1}):i.n==6?e.push({name:"發",han:1}):i.n==7&&e.push({name:"中",han:1}))}),e}dG1(t){return this.cfg.oneShotWin?[{name:"一発",han:1}]:[]}dH1(t){return this.cfg.replacementWin?[{name:"嶺上開花",han:1}]:[]}dI1(t){return this.cfg.quadWin?[{name:"搶槓",han:1}]:[]}dJ1(t){return this.cfg.finalWallWin?[{name:"海底摸月",han:1}]:[]}dK1(t){return this.cfg.finalDiscardWin?[{name:"河底撈魚",han:1}]:[]}dX1(t){const e=t.flatMap(a=>a.tiles),n=e.reduce((a,c)=>a+this.cfg.doras.filter(l=>c.equals(l)).length,0),i=e.reduce((a,c)=>a+this.cfg.hiddenDoras.filter(l=>c.equals(l)).length,0),r=e.filter(a=>a.has(g.RED)).length,o=[];return n>0&&o.push({name:"ドラ",han:n}),r>0&&o.push({name:"赤ドラ",han:r}),this.hand.reached&&i>0&&o.push({name:"裏ドラ",han:i}),o}dA2(t){return t.length==7?[{name:"七対子",han:2}]:[]}dB2(t){const e=n=>n instanceof nt||n instanceof F;for(const n of t){if(!e(n)||n.tiles[0].t==p.Z)continue;const i=pt(n),r=[p.M,p.P,p.S].filter(c=>c!=i.t),o=t.some(c=>{const l=new y(r[0],i.n);return e(c)&&l.equals(pt(c))}),a=t.some(c=>{const l=new y(r[1],i.n);return e(c)&&l.equals(pt(c))});if(o&&a)return[{name:"三色同順",han:2-this.getCalledPenalty()}]}return[]}dC2(t){return t.length==7?[]:t.every(n=>n instanceof R||n instanceof M||n instanceof K||n instanceof L||n instanceof U||n instanceof C)?[{name:"対々和",han:2}]:[]}dD2(t){return t.filter(n=>(n instanceof R||n instanceof L)&&!n.tiles.some(i=>i.has(g.RON))).length>=3?[{name:"三暗刻",han:2}]:[]}dE2(t){return t.filter(n=>n instanceof R||n instanceof M||n instanceof K).length>=3?[{name:"三槓子",han:2}]:[]}dF2(t){const e=n=>n instanceof R||n instanceof M||n instanceof K||n instanceof L||n instanceof U;for(const n of t){if(!e(n))continue;const i=pt(n);if(i.t==p.Z)continue;const r=[p.M,p.P,p.S].filter(c=>c!=i.t),o=t.some(c=>{const l=new y(r[0],i.n);return e(c)&&l.equals(pt(c))}),a=t.some(c=>{const l=new y(r[1],i.n);return e(c)&&l.equals(pt(c))});if(o&&a)return[{name:"三色同刻",han:2}]}return[]}dG2(t){return t.length==7?[]:t.filter(n=>{const i=n.tiles[0];return i.t==p.Z&&[5,6,7].includes(i.n)}).length==3?[{name:"小三元",han:2}]:[]}dH2(t){return t.every(n=>{const i=n.tiles[0],r=i.t==p.Z?Pt:J;return(n instanceof R||n instanceof M||n instanceof K||n instanceof L||n instanceof U||n instanceof C)&&r.includes(i.n)})?[{name:"混老頭",han:2}]:[]}dI2(t){return t.length==7?[]:t.some(n=>n instanceof nt||n instanceof F)?t.some(n=>n.tiles[0].t==p.Z)?t.every(n=>{const i=n.tiles[0].t==p.Z?Pt:J;return n.tiles.some(r=>i.includes(r.n))})?[{name:"混全帯么九",han:2-this.getCalledPenalty()}]:[]:[]:[]}dJ2(t){const e={[p.M]:[0,0,0],[p.S]:[0,0,0],[p.P]:[0,0,0]};for(const n of t){const i=pt(n);i.t!=p.BACK&&i.t!=p.Z&&(n instanceof nt||n instanceof F)&&(i.n==1?e[i.t][0]++:i.n==4?e[i.t][1]++:i.n==7&&e[i.t][2]++)}for(const n of Object.values(e))if(n[0]>0&&n[1]>0&&n[2]>0)return[{name:"一気通貫",han:2-this.getCalledPenalty()}];return[]}dA3(t){if(!t.some(n=>n.tiles[0].t==p.Z))return[];for(const n of Object.values(p))if(t.every(r=>r.tiles[0].t==p.Z||r.tiles[0].t==n))return[{name:"混一色",han:3-this.getCalledPenalty()}];return[]}dB3(t){return t.length==7?[]:t.some(n=>n instanceof nt||n instanceof F)?t.some(n=>n.tiles[0].t==p.Z)?[]:t.every(n=>n.tiles.some(i=>J.includes(i.n)))?[{name:"純全帯么九色",han:3-this.getCalledPenalty()}]:[]:[]}dC3(t){return this.getCalledPenalty()!=0?[]:vn(t)==2?[{name:"ニ盃口",han:3}]:[]}dA6(t){if(t.some(e=>e.tiles[0].t==p.Z))return[];for(const e of Object.values(p)){if(e==p.Z)continue;if(t.every(i=>i.tiles[0].t==e))return[{name:"清一色",han:6-this.getCalledPenalty()}]}return[]}dA13(t){return t.length!=13?[]:t.some(n=>n instanceof C&&n.tiles.some(i=>i.has(g.TSUMO)||i.has(g.RON)))?[{name:"国士無双13面待ち",han:26,isYakuman:!0}]:[{name:"国士無双",han:13,isYakuman:!0}]}dB13(t){return t.length==1?[{name:"九蓮宝燈",han:13,isYakuman:!0}]:[]}dC13(t){return t.length==7?[]:t.every(i=>i instanceof R||i instanceof L&&i.tiles.every(r=>!r.has(g.RON))||i instanceof C)?t.some(i=>i instanceof C&&i.tiles.some(r=>r.has(g.TSUMO)||r.has(g.RON)))?[{name:"四暗刻単騎待ち",han:26,isYakuman:!0}]:[{name:"四暗刻",han:13,isYakuman:!0}]:[]}dD13(t){if(t.length==13)return[];const e=[5,6,7];return t.filter(i=>!(i instanceof C)&&i.tiles.some(r=>r.t==p.Z&&e.includes(r.n))).length==3?[{name:"大三元",han:13,isYakuman:!0}]:[]}dE13(t){return t.every(n=>n.tiles[0].t==p.Z)?[{name:"字一色",han:13,isYakuman:!0}]:[]}dF13(t){return t.every(n=>(n instanceof R||n instanceof M||n instanceof K||n instanceof L||n instanceof U||n instanceof C)&&J.includes(n.tiles[0].n))?[{name:"清老頭",han:13,isYakuman:!0}]:[]}dG13(t){return t.length==7?[]:t.every(n=>n instanceof R||n instanceof M||n instanceof K||n instanceof C)?[{name:"四槓子",han:13,isYakuman:!0}]:[]}dH13(t){if(t.length==13)return[];if(t.length==7)return[];const e=[1,2,3,4];return t.filter(r=>{const o=r.tiles[0];return o.t==p.Z&&e.includes(o.n)}).length==4?t.find(r=>r instanceof C).tiles.some(r=>r.t==p.Z&&e.includes(r.n))?[{name:"小四喜",han:13,isYakuman:!0}]:[{name:"大四喜",han:13,isYakuman:!0}]:[]}dI13(t){const e=n=>!!(n.equals(new y(p.Z,6))||n.t==p.S&&[2,3,4,6,8].includes(n.n));return t.every(n=>n.tiles.every(i=>e(i)))?[{name:"緑一色",han:13,isYakuman:!0}]:[]}dJ13(t){return[]}dK13(t){return[]}calcFu(t){if(t.length==7)return 25;const e=20;let n=e;const i=this.cfg.myWind.n,r=this.cfg.roundWind.n,o=t.find(f=>f.tiles.some(w=>w.has(g.TSUMO)||w.has(g.RON))),a=this.getCalledPenalty()==1,c=o.tiles.some(f=>f.has(g.TSUMO)),l=(f,w)=>{const b=f.tiles[0];return b.t==p.Z||J.includes(b.n)?w*2:w};for(const f of t)switch(!0){case f instanceof L:const w=f.tiles.some(b=>b.has(g.RON))?2:4;n+=l(f,w);break;case f instanceof U:n+=l(f,2);break;case(f instanceof K||f instanceof M):n+=l(f,8);break;case f instanceof R:n+=l(f,16);break}n+=(f=>{if(f instanceof L)return 0;if(f instanceof C)return 2;const w=f.tiles,b=w.findIndex(A=>A.has(g.TSUMO)||A.has(g.RON));return b==1||b==0&&w[2].n==9||b==2&&w[0].n==1?2:0})(o);const u=t.find(f=>f instanceof C).tiles[0];u.t==p.Z&&([5,6,7].includes(u.n)&&(n+=2),(u.n==r||u.n==i)&&(n+=2));let m=!1;return!a&&n==e&&(m=!0),c&&!m&&(n+=2),!c&&!a&&(n+=10),!c&&!a&&n==30&&(m=!0),a&&n==e&&(n=30),n}}const Gt=s=>s.tiles.reduce((t,e)=>`${t}${e.n}${e.t}`,""),vn=s=>{const t=s.filter(e=>e instanceof nt).reduce((e,n)=>{const i=Gt(n);return e[i]=(e[i]||0)+1,e},{});return Object.values(t).filter(e=>e>=2).length},pt=s=>[...s.tiles].sort(Qt)[0],We=s=>{const t=s.n,e=s.t;if(e==p.Z){if(t==4)return new y(e,1);if(t==7)return new y(e,5)}return new y(e,t%9+1)};class Ht{static calcEffectiveTiles(t,e,n){if(e.length==0)throw new Error("no tiles available to discard");const i=new Map;let r=Number.POSITIVE_INFINITY;for(const o of e){const a=t.dec([o]),c=Ht.getEffectiveTiles(t,n);t.inc(a);const l=n?.arrangeRed&&o.has(g.RED)?o.clone({removeAll:!0}):o.has(g.RED)?o.clone({removeAll:!0,add:g.RED}):o.clone({removeAll:!0});c.shanten<r?(i.clear(),i.set(l.toString(),{shanten:c.shanten,effectiveTiles:c.effectiveTiles,tile:l}),r=c.shanten):c.shanten==r&&i.set(l.toString(),{shanten:c.shanten,effectiveTiles:c.effectiveTiles,tile:l})}return Array.from(i.values())}static getEffectiveTiles(t,e){let n=Number.POSITIVE_INFINITY,i=[];const r=new te(t);for(const[o,a]of j({skipBack:!0,filterBy:e?.typeFilter})){if(t.get(o,a)>=4)continue;const c=new y(o,a),l=t.inc([c]),d=e?.standardTypeOnly?r.standardType():r.calc();t.dec(l),d<n?(n=d,i=[c]):d==n&&i.push(c)}return{shanten:n,effectiveTiles:i}}}const De=()=>{const s=new Set;return{on(t){s.add(t)},off(t){s.delete(t)},offAll(){s.clear()},emit(t){s.forEach(e=>e(t))}}};function os(s){const t=["RON","DAI_KAN","PON","CHI"],e=s.map(r=>r.choices),i=cs(e,t).map(r=>s[r]);return{events:i,type:ls(t,i[0]?.choices)}}function as(s){const t=["TSUMO","REACH","AN_KAN","SHO_KAN","DRAWN_GAME_BY_NINE_TERMINALS","DISCARD"],e=s.map(r=>r.choices),i=cs(e,t).map(r=>s[r]);return{events:i,type:ls(t,i[0]?.choices)}}function cs(s,t){let e=[],n=Number.POSITIVE_INFINITY;for(let i=0;i<s.length;i++){const r=s[i];if(Lr(r,t)){const o=Kr(t,r);o<n?(n=o,e=[i]):o===n&&e.push(i)}}return e}function Lr(s,t){return t.some(e=>!!s[e])}function Kr(s,t){for(let e=0;e<s.length;e++){const n=s[e];if(t[n])return e}return Number.POSITIVE_INFINITY}function ls(s,t){if(t==null)return!1;for(const e of s)if(t[e])return e;return!1}const Zt=()=>{const s=De(),t=De(),e={emit:s.emit,on:i=>t.on(i)},n={emit:t.emit,on:i=>s.on(i)};return[e,n]},hs=()=>{const s=De();return{emit:n=>{s.emit(n)},on:n=>{s.on(n)}}};class Jt{reachValue=1e3;m;constructor(t){this.m=structuredClone(t)}get summary(){return this.m}reach(t){this.m[t]-=this.reachValue}update(t,e){for(let n in e){const i=e[n],r=t[i];this.m[n]+=r}}}class Xt{playerToWind={};windToPlayer=H(()=>"");_round;_sticks;constructor(t,e){this._round=e?.round??k.E1,this._sticks=structuredClone(e?.sticks)??{reach:0,dead:0},this.playerToWind=structuredClone(t);for(let n in this.playerToWind)this.windToPlayer[this.playerToWind[n]]=n}get sticks(){return this._sticks}get round(){return this._round}update(){for(let t in this.playerToWind){const e=Ee(this.playerToWind[t]);this.playerToWind[t]=e,this.windToPlayer[e]=t}}incrementDeadStick(){this._sticks.dead++}incrementReachStick(){this._sticks.reach++}nextRound(){const t=Vt(this.round);this._round=t,this.update()}resetDeadStick(){this._sticks.dead=0}resetReachStick(){this._sticks.reach=0}is(t){return this.round==t}wind(t){return this.playerToWind[t]}playerID(t){return this.windToPlayer[t]}get playerMap(){return this.playerToWind}}function sn(s){for(let t=s.length-1;t>0;t--){const e=Math.floor(Math.random()*(t+1));[s[t],s[e]]=[s[e],s[t]]}return s}class ds{constructor(t=!1){this.disabled=t,this.c=this.initial()}c;safeTileMap=H(()=>({}));get(t){return t.t==p.BACK?0:this.c[t.t][t.n]}dec(...t){if(!this.disabled){for(let e of t)if(e.t!=p.BACK){if(this.get(e)<=0)throw new Error(`[counter] tile ${e} appears more than 4 times`);if(this.c[e.t][e.n]-=1,e.has(g.RED)){if(this.c[e.t][0]<=0)throw new Error(`[counter] red tile ${e} appears more than once`);this.c[e.t][0]-=1}}}}addTileToSafeMap(t,e){this.disabled||(this.safeTileMap[e][this.key(t.t,t.n)]=!0)}isSafeTile(t,e,n){return this.safeTileMap[n][this.key(t,e)]}key(t,e){return`${t}${e}`}reset(){this.c=this.initial()}initial(){return{[p.M]:[1,4,4,4,4,4,4,4,4,4],[p.S]:[1,4,4,4,4,4,4,4,4,4],[p.P]:[1,4,4,4,4,4,4,4,4,4],[p.Z]:[0,4,4,4,4,4,4,4]}}}class rn{all=[];byWind=new Map;discard(t,e){const n={w:e,t};this.all.push(n);const i=this.byWind.get(e);i?i.push(n):this.byWind.set(e,[n])}discards(t){return t==null?this.all:this.byWind.get(t)??[]}get lastTile(){const t=this.all.at(-1);return I(t!=null,`lastTile is null. river: ${JSON.stringify(this.all,null,2)}`),t}markCalled(){this.lastTile.callMarker=!0}isFourWindsAbort(){if(this.all.length!=4)return!1;const t=this.all[0].t;return t.isNum()?!1:this.all.every(e=>t.equals(e.t))}reset(){this.all=[],this.byWind.clear()}}function zr(){if(typeof globalThis<"u")return globalThis;if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global}function Ur(){const s=zr();if(s.__xstate__)return s.__xstate__}const jr=s=>{if(typeof window>"u")return;const t=Ur();t&&t.register(s)};class Sn{constructor(t){this._process=t,this._active=!1,this._current=null,this._last=null}start(){this._active=!0,this.flush()}clear(){this._current&&(this._current.next=null,this._last=this._current)}enqueue(t){const e={value:t,next:null};if(this._current){this._last.next=e,this._last=e;return}this._current=e,this._last=e,this._active&&this.flush()}flush(){for(;this._current;){const t=this._current;this._process(t.value),this._current=t.next}this._last=null}}const us=".",Fr="",fs="",Gr="#",Zr="*",ps="xstate.init",Le="xstate.stop";function Yr(s,t){return{type:`xstate.after.${s}.${t}`}}function Ke(s,t){return{type:`xstate.done.state.${s}`,output:t}}function Vr(s,t){return{type:`xstate.done.actor.${s}`,output:t,actorId:s}}function Jr(s,t){return{type:`xstate.error.actor.${s}`,error:t,actorId:s}}function gs(s){return{type:ps,input:s}}function Z(s){setTimeout(()=>{throw s})}const Xr=typeof Symbol=="function"&&Symbol.observable||"@@observable";function ms(s,t){const e=On(s),n=On(t);return typeof n=="string"?typeof e=="string"?n===e:!1:typeof e=="string"?e in n:Object.keys(e).every(i=>i in n?ms(e[i],n[i]):!1)}function on(s){if(ws(s))return s;const t=[];let e="";for(let n=0;n<s.length;n++){switch(s.charCodeAt(n)){case 92:e+=s[n+1],n++;continue;case 46:t.push(e),e="";continue}e+=s[n]}return t.push(e),t}function On(s){if(xo(s))return s.value;if(typeof s!="string")return s;const t=on(s);return qr(t)}function qr(s){if(s.length===1)return s[0];const t={};let e=t;for(let n=0;n<s.length-1;n++)if(n===s.length-2)e[s[n]]=s[n+1];else{const i=e;e={},i[s[n]]=e}return t}function kn(s,t){const e={},n=Object.keys(s);for(let i=0;i<n.length;i++){const r=n[i];e[r]=t(s[r],r,s,i)}return e}function ys(s){return ws(s)?s:[s]}function it(s){return s===void 0?[]:ys(s)}function ze(s,t,e,n){return typeof s=="function"?s({context:t,event:e,self:n}):s}function ws(s){return Array.isArray(s)}function Qr(s){return s.type.startsWith("xstate.error.actor")}function Ot(s){return ys(s).map(t=>typeof t>"u"||typeof t=="string"?{target:t}:t)}function Es(s){if(!(s===void 0||s===Fr))return it(s)}function Ue(s,t,e){const n=typeof s=="object",i=n?s:void 0;return{next:(n?s.next:s)?.bind(i),error:(n?s.error:t)?.bind(i),complete:(n?s.complete:e)?.bind(i)}}function Cn(s,t){return`${t}.${s}`}function an(s,t){const e=t.match(/^xstate\.invoke\.(\d+)\.(.*)/);if(!e)return s.implementations.actors[t];const[,n,i]=e,o=s.getStateNodeById(i).config.invoke;return(Array.isArray(o)?o[n]:o).src}function to(s,t){if(t===s||t===Zr)return!0;if(!t.endsWith(".*"))return!1;const e=t.split("."),n=s.split(".");for(let i=0;i<e.length;i++){const r=e[i],o=n[i];if(r==="*")return i===e.length-1;if(r!==o)return!1}return!0}function Rn(s,t){return`${s.sessionId}.${t}`}let eo=0;function no(s,t){const e=new Map,n=new Map,i=new WeakMap,r=new Set,o={},{clock:a,logger:c}=t,l={schedule:(u,m,f,w,b=Math.random().toString(36).slice(2))=>{const A={source:u,target:m,event:f,delay:w,id:b,startedAt:Date.now()},O=Rn(u,b);h._snapshot._scheduledEvents[O]=A;const $=a.setTimeout(()=>{delete o[O],delete h._snapshot._scheduledEvents[O],h._relay(u,m,f)},w);o[O]=$},cancel:(u,m)=>{const f=Rn(u,m),w=o[f];delete o[f],delete h._snapshot._scheduledEvents[f],w!==void 0&&a.clearTimeout(w)},cancelAll:u=>{for(const m in h._snapshot._scheduledEvents){const f=h._snapshot._scheduledEvents[m];f.source===u&&l.cancel(u,f.id)}}},d=u=>{if(!r.size)return;const m={...u,rootId:s.sessionId};r.forEach(f=>f.next?.(m))},h={_snapshot:{_scheduledEvents:(t?.snapshot&&t.snapshot.scheduler)??{}},_bookId:()=>`x:${eo++}`,_register:(u,m)=>(e.set(u,m),u),_unregister:u=>{e.delete(u.sessionId);const m=i.get(u);m!==void 0&&(n.delete(m),i.delete(u))},get:u=>n.get(u),getAll:()=>Object.fromEntries(n.entries()),_set:(u,m)=>{const f=n.get(u);if(f&&f!==m)throw new Error(`Actor with system ID '${u}' already exists.`);n.set(u,m),i.set(m,u)},inspect:u=>{const m=Ue(u);return r.add(m),{unsubscribe(){r.delete(m)}}},_sendInspectionEvent:d,_relay:(u,m,f)=>{h._sendInspectionEvent({type:"@xstate.event",sourceRef:u,actorRef:m,event:f}),m._send(f)},scheduler:l,getSnapshot:()=>({_scheduledEvents:{...h._snapshot._scheduledEvents}}),start:()=>{const u=h._snapshot._scheduledEvents;h._snapshot._scheduledEvents={};for(const m in u){const{source:f,target:w,event:b,delay:A,id:O}=u[m];l.schedule(f,w,b,A,O)}},_clock:a,_logger:c};return h}let Se=!1;const cn=1;let W=(function(s){return s[s.NotStarted=0]="NotStarted",s[s.Running=1]="Running",s[s.Stopped=2]="Stopped",s})({});const so={clock:{setTimeout:(s,t)=>setTimeout(s,t),clearTimeout:s=>clearTimeout(s)},logger:console.log.bind(console),devTools:!1};class io{constructor(t,e){this.logic=t,this._snapshot=void 0,this.clock=void 0,this.options=void 0,this.id=void 0,this.mailbox=new Sn(this._process.bind(this)),this.observers=new Set,this.eventListeners=new Map,this.logger=void 0,this._processingStatus=W.NotStarted,this._parent=void 0,this._syncSnapshot=void 0,this.ref=void 0,this._actorScope=void 0,this.systemId=void 0,this.sessionId=void 0,this.system=void 0,this._doneEvent=void 0,this.src=void 0,this._deferred=[];const n={...so,...e},{clock:i,logger:r,parent:o,syncSnapshot:a,id:c,systemId:l,inspect:d}=n;this.system=o?o.system:no(this,{clock:i,logger:r}),d&&!o&&this.system.inspect(Ue(d)),this.sessionId=this.system._bookId(),this.id=c??this.sessionId,this.logger=e?.logger??this.system._logger,this.clock=e?.clock??this.system._clock,this._parent=o,this._syncSnapshot=a,this.options=n,this.src=n.src??t,this.ref=this,this._actorScope={self:this,id:this.id,sessionId:this.sessionId,logger:this.logger,defer:h=>{this._deferred.push(h)},system:this.system,stopChild:h=>{if(h._parent!==this)throw new Error(`Cannot stop child actor ${h.id} of ${this.id} because it is not a child`);h._stop()},emit:h=>{const u=this.eventListeners.get(h.type),m=this.eventListeners.get("*");if(!u&&!m)return;const f=[...u?u.values():[],...m?m.values():[]];for(const w of f)try{w(h)}catch(b){Z(b)}},actionExecutor:h=>{const u=()=>{if(this._actorScope.system._sendInspectionEvent({type:"@xstate.action",actorRef:this,action:{type:h.type,params:h.params}}),!h.exec)return;const m=Se;try{Se=!0,h.exec(h.info,h.params)}finally{Se=m}};this._processingStatus===W.Running?u():this._deferred.push(u)}},this.send=this.send.bind(this),this.system._sendInspectionEvent({type:"@xstate.actor",actorRef:this}),l&&(this.systemId=l,this.system._set(l,this)),this._initState(e?.snapshot??e?.state),l&&this._snapshot.status!=="active"&&this.system._unregister(this)}_initState(t){try{this._snapshot=t?this.logic.restoreSnapshot?this.logic.restoreSnapshot(t,this._actorScope):t:this.logic.getInitialSnapshot(this._actorScope,this.options?.input)}catch(e){this._snapshot={status:"error",output:void 0,error:e}}}update(t,e){this._snapshot=t;let n;for(;n=this._deferred.shift();)try{n()}catch(i){this._deferred.length=0,this._snapshot={...t,status:"error",error:i}}switch(this._snapshot.status){case"active":for(const i of this.observers)try{i.next?.(t)}catch(r){Z(r)}break;case"done":for(const i of this.observers)try{i.next?.(t)}catch(r){Z(r)}this._stopProcedure(),this._complete(),this._doneEvent=Vr(this.id,this._snapshot.output),this._parent&&this.system._relay(this,this._parent,this._doneEvent);break;case"error":this._error(this._snapshot.error);break}this.system._sendInspectionEvent({type:"@xstate.snapshot",actorRef:this,event:e,snapshot:t})}subscribe(t,e,n){const i=Ue(t,e,n);if(this._processingStatus!==W.Stopped)this.observers.add(i);else switch(this._snapshot.status){case"done":try{i.complete?.()}catch(r){Z(r)}break;case"error":{const r=this._snapshot.error;if(!i.error)Z(r);else try{i.error(r)}catch(o){Z(o)}break}}return{unsubscribe:()=>{this.observers.delete(i)}}}on(t,e){let n=this.eventListeners.get(t);n||(n=new Set,this.eventListeners.set(t,n));const i=e.bind(void 0);return n.add(i),{unsubscribe:()=>{n.delete(i)}}}start(){if(this._processingStatus===W.Running)return this;this._syncSnapshot&&this.subscribe({next:n=>{n.status==="active"&&this.system._relay(this,this._parent,{type:`xstate.snapshot.${this.id}`,snapshot:n})},error:()=>{}}),this.system._register(this.sessionId,this),this.systemId&&this.system._set(this.systemId,this),this._processingStatus=W.Running;const t=gs(this.options.input);switch(this.system._sendInspectionEvent({type:"@xstate.event",sourceRef:this._parent,actorRef:this,event:t}),this._snapshot.status){case"done":return this.update(this._snapshot,t),this;case"error":return this._error(this._snapshot.error),this}if(this._parent||this.system.start(),this.logic.start)try{this.logic.start(this._snapshot,this._actorScope)}catch(n){return this._snapshot={...this._snapshot,status:"error",error:n},this._error(n),this}return this.update(this._snapshot,t),this.options.devTools&&this.attachDevTools(),this.mailbox.start(),this}_process(t){let e,n;try{e=this.logic.transition(this._snapshot,t,this._actorScope)}catch(i){n={err:i}}if(n){const{err:i}=n;this._snapshot={...this._snapshot,status:"error",error:i},this._error(i);return}this.update(e,t),t.type===Le&&(this._stopProcedure(),this._complete())}_stop(){return this._processingStatus===W.Stopped?this:(this.mailbox.clear(),this._processingStatus===W.NotStarted?(this._processingStatus=W.Stopped,this):(this.mailbox.enqueue({type:Le}),this))}stop(){if(this._parent)throw new Error("A non-root actor cannot be stopped directly.");return this._stop()}_complete(){for(const t of this.observers)try{t.complete?.()}catch(e){Z(e)}this.observers.clear(),this.eventListeners.clear()}_reportError(t){if(!this.observers.size){this._parent||Z(t),this.eventListeners.clear();return}let e=!1;for(const n of this.observers){const i=n.error;e||=!i;try{i?.(t)}catch(r){Z(r)}}this.observers.clear(),this.eventListeners.clear(),e&&Z(t)}_error(t){this._stopProcedure(),this._reportError(t),this._parent&&this.system._relay(this,this._parent,Jr(this.id,t))}_stopProcedure(){return this._processingStatus!==W.Running?this:(this.system.scheduler.cancelAll(this),this.mailbox.clear(),this.mailbox=new Sn(this._process.bind(this)),this._processingStatus=W.Stopped,this.system._unregister(this),this)}_send(t){this._processingStatus!==W.Stopped&&this.mailbox.enqueue(t)}send(t){this.system._relay(void 0,this,t)}attachDevTools(){const{devTools:t}=this.options;t&&(typeof t=="function"?t:jr)(this)}toJSON(){return{xstate$$type:cn,id:this.id}}getPersistedSnapshot(t){return this.logic.getPersistedSnapshot(this._snapshot,t)}[Xr](){return this}getSnapshot(){return this._snapshot}}function Bt(s,...[t]){return new io(s,t)}function ro(s,t,e,n,{sendId:i}){const r=typeof i=="function"?i(e,n):i;return[t,{sendId:r},void 0]}function oo(s,t){s.defer(()=>{s.system.scheduler.cancel(s.self,t.sendId)})}function ao(s){function t(e,n){}return t.type="xstate.cancel",t.sendId=s,t.resolve=ro,t.execute=oo,t}function co(s,t,e,n,{id:i,systemId:r,src:o,input:a,syncSnapshot:c}){const l=typeof o=="string"?an(t.machine,o):o,d=typeof i=="function"?i(e):i;let h,u;return l&&(u=typeof a=="function"?a({context:t.context,event:e.event,self:s.self}):a,h=Bt(l,{id:d,src:o,parent:s.self,syncSnapshot:c,systemId:r,input:u})),[Tt(t,{children:{...t.children,[d]:h}}),{id:i,systemId:r,actorRef:h,src:o,input:u},void 0]}function lo(s,{actorRef:t}){t&&s.defer(()=>{t._processingStatus!==W.Stopped&&t.start()})}function ho(...[s,{id:t,systemId:e,input:n,syncSnapshot:i=!1}={}]){function r(o,a){}return r.type="xstate.spawnChild",r.id=t,r.systemId=e,r.src=s,r.input=n,r.syncSnapshot=i,r.resolve=co,r.execute=lo,r}function uo(s,t,e,n,{actorRef:i}){const r=typeof i=="function"?i(e,n):i,o=typeof r=="string"?t.children[r]:r;let a=t.children;return o&&(a={...a},delete a[o.id]),[Tt(t,{children:a}),o,void 0]}function bs(s,t){const e=t.getSnapshot();if(e&&"children"in e)for(const n of Object.values(e.children))bs(s,n);s.system._unregister(t)}function fo(s,t){if(t){if(bs(s,t),t._processingStatus!==W.Running){s.stopChild(t);return}s.defer(()=>{s.stopChild(t)})}}function _s(s){function t(e,n){}return t.type="xstate.stopChild",t.actorRef=s,t.resolve=uo,t.execute=fo,t}function ln(s,t,e,n){const{machine:i}=n,r=typeof s=="function",o=r?s:i.implementations.guards[typeof s=="string"?s:s.type];if(!r&&!o)throw new Error(`Guard '${typeof s=="string"?s:s.type}' is not implemented.'.`);if(typeof o!="function")return ln(o,t,e,n);const a={context:t,event:e},c=r||typeof s=="string"?void 0:"params"in s?typeof s.params=="function"?s.params({context:t,event:e}):s.params:void 0;return"check"in o?o.check(n,a,o):o(a,c)}const hn=s=>s.type==="atomic"||s.type==="final";function Wt(s){return Object.values(s.states).filter(t=>t.type!=="history")}function ee(s,t){const e=[];if(t===s)return e;let n=s.parent;for(;n&&n!==t;)e.push(n),n=n.parent;return e}function fe(s){const t=new Set(s),e=Is(t);for(const n of t)if(n.type==="compound"&&(!e.get(n)||!e.get(n).length))Mn(n).forEach(i=>t.add(i));else if(n.type==="parallel"){for(const i of Wt(n))if(i.type!=="history"&&!t.has(i)){const r=Mn(i);for(const o of r)t.add(o)}}for(const n of t){let i=n.parent;for(;i;)t.add(i),i=i.parent}return t}function As(s,t){const e=t.get(s);if(!e)return{};if(s.type==="compound"){const i=e[0];if(i){if(hn(i))return i.key}else return{}}const n={};for(const i of e)n[i.key]=As(i,t);return n}function Is(s){const t=new Map;for(const e of s)t.has(e)||t.set(e,[]),e.parent&&(t.has(e.parent)||t.set(e.parent,[]),t.get(e.parent).push(e));return t}function Ts(s,t){const e=fe(t);return As(s,Is(e))}function dn(s,t){return t.type==="compound"?Wt(t).some(e=>e.type==="final"&&s.has(e)):t.type==="parallel"?Wt(t).every(e=>dn(s,e)):t.type==="final"}const Ie=s=>s[0]===Gr;function po(s,t){return s.transitions.get(t)||[...s.transitions.keys()].filter(n=>to(t,n)).sort((n,i)=>i.length-n.length).flatMap(n=>s.transitions.get(n))}function go(s){const t=s.config.after;if(!t)return[];const e=i=>{const r=Yr(i,s.id),o=r.type;return s.entry.push(Uo(r,{id:o,delay:i})),s.exit.push(ao(o)),o};return Object.keys(t).flatMap(i=>{const r=t[i],o=typeof r=="string"?{target:r}:r,a=Number.isNaN(+i)?i:+i,c=e(a);return it(o).map(l=>({...l,event:c,delay:a}))}).map(i=>{const{delay:r}=i;return{...yt(s,i.event,i),delay:r}})}function yt(s,t,e){const n=Es(e.target),i=e.reenter??!1,r=wo(s,n),o={...e,actions:it(e.actions),guard:e.guard,target:r,source:s,reenter:i,eventType:t,toJSON:()=>({...o,source:`#${s.id}`,target:r?r.map(a=>`#${a.id}`):void 0})};return o}function mo(s){const t=new Map;if(s.config.on)for(const e of Object.keys(s.config.on)){if(e===fs)throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.');const n=s.config.on[e];t.set(e,Ot(n).map(i=>yt(s,e,i)))}if(s.config.onDone){const e=`xstate.done.state.${s.id}`;t.set(e,Ot(s.config.onDone).map(n=>yt(s,e,n)))}for(const e of s.invoke){if(e.onDone){const n=`xstate.done.actor.${e.id}`;t.set(n,Ot(e.onDone).map(i=>yt(s,n,i)))}if(e.onError){const n=`xstate.error.actor.${e.id}`;t.set(n,Ot(e.onError).map(i=>yt(s,n,i)))}if(e.onSnapshot){const n=`xstate.snapshot.${e.id}`;t.set(n,Ot(e.onSnapshot).map(i=>yt(s,n,i)))}}for(const e of s.after){let n=t.get(e.eventType);n||(n=[],t.set(e.eventType,n)),n.push(e)}return t}function yo(s,t){const e=typeof t=="string"?s.states[t]:t?s.states[t.target]:void 0;if(!e&&t)throw new Error(`Initial state node "${t}" not found on parent state node #${s.id}`);const n={source:s,actions:!t||typeof t=="string"?[]:it(t.actions),eventType:null,reenter:!1,target:e?[e]:[],toJSON:()=>({...n,source:`#${s.id}`,target:e?[`#${e.id}`]:[]})};return n}function wo(s,t){if(t!==void 0)return t.map(e=>{if(typeof e!="string")return e;if(Ie(e))return s.machine.getStateNodeById(e);const n=e[0]===us;if(n&&!s.parent)return pe(s,e.slice(1));const i=n?s.key+e:e;if(s.parent)try{return pe(s.parent,i)}catch(r){throw new Error(`Invalid transition definition for state node '${s.id}':
|
|
9
|
+
${r.message}`)}else throw new Error(`Invalid target: "${e}" is not a valid target from the root node. Did you mean ".${e}"?`)})}function Ns(s){const t=Es(s.config.target);return t?{target:t.map(e=>typeof e=="string"?pe(s.parent,e):e)}:s.parent.initial}function Et(s){return s.type==="history"}function Mn(s){const t=vs(s);for(const e of t)for(const n of ee(e,s))t.add(n);return t}function vs(s){const t=new Set;function e(n){if(!t.has(n)){if(t.add(n),n.type==="compound")e(n.initial.target[0]);else if(n.type==="parallel")for(const i of Wt(n))e(i)}}return e(s),t}function Dt(s,t){if(Ie(t))return s.machine.getStateNodeById(t);if(!s.states)throw new Error(`Unable to retrieve child state '${t}' from '${s.id}'; no child states exist.`);const e=s.states[t];if(!e)throw new Error(`Child state '${t}' does not exist on '${s.id}'`);return e}function pe(s,t){if(typeof t=="string"&&Ie(t))try{return s.machine.getStateNodeById(t)}catch{}const e=on(t).slice();let n=s;for(;e.length;){const i=e.shift();if(!i.length)break;n=Dt(n,i)}return n}function ge(s,t){if(typeof t=="string"){const i=s.states[t];if(!i)throw new Error(`State '${t}' does not exist on '${s.id}'`);return[s,i]}const e=Object.keys(t),n=e.map(i=>Dt(s,i)).filter(Boolean);return[s.machine.root,s].concat(n,e.reduce((i,r)=>{const o=Dt(s,r);if(!o)return i;const a=ge(o,t[r]);return i.concat(a)},[]))}function Eo(s,t,e,n){const r=Dt(s,t).next(e,n);return!r||!r.length?s.next(e,n):r}function bo(s,t,e,n){const i=Object.keys(t),r=Dt(s,i[0]),o=un(r,t[i[0]],e,n);return!o||!o.length?s.next(e,n):o}function _o(s,t,e,n){const i=[];for(const r of Object.keys(t)){const o=t[r];if(!o)continue;const a=Dt(s,r),c=un(a,o,e,n);c&&i.push(...c)}return i.length?i:s.next(e,n)}function un(s,t,e,n){return typeof t=="string"?Eo(s,t,e,n):Object.keys(t).length===1?bo(s,t,e,n):_o(s,t,e,n)}function Ao(s){return Object.keys(s.states).map(t=>s.states[t]).filter(t=>t.type==="history")}function at(s,t){let e=s;for(;e.parent&&e.parent!==t;)e=e.parent;return e.parent===t}function Io(s,t){const e=new Set(s),n=new Set(t);for(const i of e)if(n.has(i))return!0;for(const i of n)if(e.has(i))return!0;return!1}function Ss(s,t,e){const n=new Set;for(const i of s){let r=!1;const o=new Set;for(const a of n)if(Io(je([i],t,e),je([a],t,e)))if(at(i.source,a.source))o.add(a);else{r=!0;break}if(!r){for(const a of o)n.delete(a);n.add(i)}}return Array.from(n)}function To(s){const[t,...e]=s;for(const n of ee(t,void 0))if(e.every(i=>at(i,n)))return n}function fn(s,t){if(!s.target)return[];const e=new Set;for(const n of s.target)if(Et(n))if(t[n.id])for(const i of t[n.id])e.add(i);else for(const i of fn(Ns(n),t))e.add(i);else e.add(n);return[...e]}function Os(s,t){const e=fn(s,t);if(!e)return;if(!s.reenter&&e.every(i=>i===s.source||at(i,s.source)))return s.source;const n=To(e.concat(s.source));if(n)return n;if(!s.reenter)return s.source.machine.root}function je(s,t,e){const n=new Set;for(const i of s)if(i.target?.length){const r=Os(i,e);i.reenter&&i.source===r&&n.add(r);for(const o of t)at(o,r)&&n.add(o)}return[...n]}function No(s,t){if(s.length!==t.size)return!1;for(const e of s)if(!t.has(e))return!1;return!0}function Fe(s,t,e,n,i,r){if(!s.length)return t;const o=new Set(t._nodes);let a=t.historyValue;const c=Ss(s,o,a);let l=t;i||([l,a]=ko(l,n,e,c,o,a,r,e.actionExecutor)),l=Lt(l,n,e,c.flatMap(h=>h.actions),r,void 0),l=So(l,n,e,c,o,r,a,i);const d=[...o];l.status==="done"&&(l=Lt(l,n,e,d.sort((h,u)=>u.order-h.order).flatMap(h=>h.exit),r,void 0));try{return a===t.historyValue&&No(t._nodes,o)?l:Tt(l,{_nodes:d,historyValue:a})}catch(h){throw h}}function vo(s,t,e,n,i){if(n.output===void 0)return;const r=Ke(i.id,i.output!==void 0&&i.parent?ze(i.output,s.context,t,e.self):void 0);return ze(n.output,s.context,r,e.self)}function So(s,t,e,n,i,r,o,a){let c=s;const l=new Set,d=new Set;Oo(n,o,d,l),a&&d.add(s.machine.root);const h=new Set;for(const u of[...l].sort((m,f)=>m.order-f.order)){i.add(u);const m=[];m.push(...u.entry);for(const f of u.invoke)m.push(ho(f.src,{...f,syncSnapshot:!!f.onSnapshot}));if(d.has(u)){const f=u.initial.actions;m.push(...f)}if(c=Lt(c,t,e,m,r,u.invoke.map(f=>f.id)),u.type==="final"){const f=u.parent;let w=f?.type==="parallel"?f:f?.parent,b=w||u;for(f?.type==="compound"&&r.push(Ke(f.id,u.output!==void 0?ze(u.output,c.context,t,e.self):void 0));w?.type==="parallel"&&!h.has(w)&&dn(i,w);)h.add(w),r.push(Ke(w.id)),b=w,w=w.parent;if(w)continue;c=Tt(c,{status:"done",output:vo(c,t,e,c.machine.root,b)})}}return c}function Oo(s,t,e,n){for(const i of s){const r=Os(i,t);for(const a of i.target||[])!Et(a)&&(i.source!==a||i.source!==r||i.reenter)&&(n.add(a),e.add(a)),Ct(a,t,e,n);const o=fn(i,t);for(const a of o){const c=ee(a,r);r?.type==="parallel"&&c.push(r),ks(n,t,e,c,!i.source.parent&&i.reenter?void 0:r)}}}function Ct(s,t,e,n){if(Et(s))if(t[s.id]){const i=t[s.id];for(const r of i)n.add(r),Ct(r,t,e,n);for(const r of i)Oe(r,s.parent,n,t,e)}else{const i=Ns(s);for(const r of i.target)n.add(r),i===s.parent?.initial&&e.add(s.parent),Ct(r,t,e,n);for(const r of i.target)Oe(r,s.parent,n,t,e)}else if(s.type==="compound"){const[i]=s.initial.target;Et(i)||(n.add(i),e.add(i)),Ct(i,t,e,n),Oe(i,s,n,t,e)}else if(s.type==="parallel")for(const i of Wt(s).filter(r=>!Et(r)))[...n].some(r=>at(r,i))||(Et(i)||(n.add(i),e.add(i)),Ct(i,t,e,n))}function ks(s,t,e,n,i){for(const r of n)if((!i||at(r,i))&&s.add(r),r.type==="parallel")for(const o of Wt(r).filter(a=>!Et(a)))[...s].some(a=>at(a,o))||(s.add(o),Ct(o,t,e,s))}function Oe(s,t,e,n,i){ks(e,n,i,ee(s,t))}function ko(s,t,e,n,i,r,o,a){let c=s;const l=je(n,i,r);l.sort((h,u)=>u.order-h.order);let d;for(const h of l)for(const u of Ao(h)){let m;u.history==="deep"?m=f=>hn(f)&&at(f,h):m=f=>f.parent===h,d??={...r},d[u.id]=Array.from(i).filter(m)}for(const h of l)c=Lt(c,t,e,[...h.exit,...h.invoke.map(u=>_s(u.id))],o,void 0),i.delete(h);return[c,d||r]}function Co(s,t){return s.implementations.actions[t]}function Cs(s,t,e,n,i,r){const{machine:o}=s;let a=s;for(const c of n){const l=typeof c=="function",d=l?c:Co(o,typeof c=="string"?c:c.type),h={context:a.context,event:t,self:e.self,system:e.system},u=l||typeof c=="string"?void 0:"params"in c?typeof c.params=="function"?c.params({context:a.context,event:t}):c.params:void 0;if(!d||!("resolve"in d)){e.actionExecutor({type:typeof c=="string"?c:typeof c=="object"?c.type:c.name||"(anonymous)",info:h,params:u,exec:d});continue}const m=d,[f,w,b]=m.resolve(e,a,h,u,d,i);a=f,"retryResolve"in m&&r?.push([m,w]),"execute"in m&&e.actionExecutor({type:m.type,info:h,params:w,exec:m.execute.bind(null,e,w)}),b&&(a=Cs(a,t,e,b,i,r))}return a}function Lt(s,t,e,n,i,r){const o=r?[]:void 0,a=Cs(s,t,e,n,{internalQueue:i,deferredActorIds:r},o);return o?.forEach(([c,l])=>{c.retryResolve(e,a,l)}),a}function ke(s,t,e,n){let i=s;const r=[];function o(l,d,h){e.system._sendInspectionEvent({type:"@xstate.microstep",actorRef:e.self,event:d,snapshot:l,_transitions:h}),r.push(l)}if(t.type===Le)return i=Tt(xn(i,t,e),{status:"stopped"}),o(i,t,[]),{snapshot:i,microstates:r};let a=t;if(a.type!==ps){const l=a,d=Qr(l),h=$n(l,i);if(d&&!h.length)return i=Tt(s,{status:"error",error:l.error}),o(i,l,[]),{snapshot:i,microstates:r};i=Fe(h,s,e,a,!1,n),o(i,l,h)}let c=!0;for(;i.status==="active";){let l=c?Ro(i,a):[];const d=l.length?i:void 0;if(!l.length){if(!n.length)break;a=n.shift(),l=$n(a,i)}i=Fe(l,i,e,a,!1,n),c=i!==d,o(i,a,l)}return i.status!=="active"&&xn(i,a,e),{snapshot:i,microstates:r}}function xn(s,t,e){return Lt(s,t,e,Object.values(s.children).map(n=>_s(n)),[],void 0)}function $n(s,t){return t.machine.getTransitionData(t,s)}function Ro(s,t){const e=new Set,n=s._nodes.filter(hn);for(const i of n)t:for(const r of[i].concat(ee(i,void 0)))if(r.always){for(const o of r.always)if(o.guard===void 0||ln(o.guard,s.context,t,s)){e.add(o);break t}}return Ss(Array.from(e),new Set(s._nodes),s.historyValue)}function Mo(s,t){const e=fe(ge(s,t));return Ts(s,[...e])}function xo(s){return!!s&&typeof s=="object"&&"machine"in s&&"value"in s}const $o=function(t){return ms(t,this.value)},Po=function(t){return this.tags.has(t)},Ho=function(t){const e=this.machine.getTransitionData(this,t);return!!e?.length&&e.some(n=>n.target!==void 0||n.actions.length)},Bo=function(){const{_nodes:t,tags:e,machine:n,getMeta:i,toJSON:r,can:o,hasTag:a,matches:c,...l}=this;return{...l,tags:Array.from(e)}},Wo=function(){return this._nodes.reduce((t,e)=>(e.meta!==void 0&&(t[e.id]=e.meta),t),{})};function ae(s,t){return{status:s.status,output:s.output,error:s.error,machine:t,context:s.context,_nodes:s._nodes,value:Ts(t.root,s._nodes),tags:new Set(s._nodes.flatMap(e=>e.tags)),children:s.children,historyValue:s.historyValue||{},matches:$o,hasTag:Po,can:Ho,getMeta:Wo,toJSON:Bo}}function Tt(s,t={}){return ae({...s,...t},s.machine)}function Do(s){if(typeof s!="object"||s===null)return{};const t={};for(const e in s){const n=s[e];Array.isArray(n)&&(t[e]=n.map(i=>({id:i.id})))}return t}function Lo(s,t){const{_nodes:e,tags:n,machine:i,children:r,context:o,can:a,hasTag:c,matches:l,getMeta:d,toJSON:h,...u}=s,m={};for(const w in r){const b=r[w];m[w]={snapshot:b.getPersistedSnapshot(t),src:b.src,systemId:b.systemId,syncSnapshot:b._syncSnapshot}}return{...u,context:Rs(o),children:m,historyValue:Do(u.historyValue)}}function Rs(s){let t;for(const e in s){const n=s[e];if(n&&typeof n=="object")if("sessionId"in n&&"send"in n&&"ref"in n)t??=Array.isArray(s)?s.slice():{...s},t[e]={xstate$$type:cn,id:n.id};else{const i=Rs(n);i!==n&&(t??=Array.isArray(s)?s.slice():{...s},t[e]=i)}}return t??s}function Ko(s,t,e,n,{event:i,id:r,delay:o},{internalQueue:a}){const c=t.machine.implementations.delays;if(typeof i=="string")throw new Error(`Only event objects may be used with raise; use raise({ type: "${i}" }) instead`);const l=typeof i=="function"?i(e,n):i;let d;if(typeof o=="string"){const h=c&&c[o];d=typeof h=="function"?h(e,n):h}else d=typeof o=="function"?o(e,n):o;return typeof d!="number"&&a.push(l),[t,{event:l,id:r,delay:d},void 0]}function zo(s,t){const{event:e,delay:n,id:i}=t;if(typeof n=="number"){s.defer(()=>{const r=s.self;s.system.scheduler.schedule(r,r,e,n,i)});return}}function Uo(s,t){function e(n,i){}return e.type="xstate.raise",e.event=s,e.id=t?.id,e.delay=t?.delay,e.resolve=Ko,e.execute=zo,e}function jo(s,{machine:t,context:e},n,i){const r=(o,a)=>{if(typeof o=="string"){const c=an(t,o);if(!c)throw new Error(`Actor logic '${o}' not implemented in machine '${t.id}'`);const l=Bt(c,{id:a?.id,parent:s.self,syncSnapshot:a?.syncSnapshot,input:typeof a?.input=="function"?a.input({context:e,event:n,self:s.self}):a?.input,src:o,systemId:a?.systemId});return i[l.id]=l,l}else return Bt(o,{id:a?.id,parent:s.self,syncSnapshot:a?.syncSnapshot,input:a?.input,src:o,systemId:a?.systemId})};return(o,a)=>{const c=r(o,a);return i[c.id]=c,s.defer(()=>{c._processingStatus!==W.Stopped&&c.start()}),c}}function Fo(s,t,e,n,{assignment:i}){if(!t.context)throw new Error("Cannot assign to undefined `context`. Ensure that `context` is defined in the machine config.");const r={},o={context:t.context,event:e.event,spawn:jo(s,t,e.event,r),self:s.self,system:s.system};let a={};if(typeof i=="function")a=i(o,n);else for(const l of Object.keys(i)){const d=i[l];a[l]=typeof d=="function"?d(o,n):d}const c=Object.assign({},t.context,a);return[Tt(t,{context:c,children:Object.keys(r).length?{...t.children,...r}:t.children}),void 0,void 0]}function Go(s){function t(e,n){}return t.type="xstate.assign",t.assignment=s,t.resolve=Fo,t}const Pn=new WeakMap;function St(s,t,e){let n=Pn.get(s);return n?t in n||(n[t]=e()):(n={[t]:e()},Pn.set(s,n)),n[t]}const Zo={},jt=s=>typeof s=="string"?{type:s}:typeof s=="function"?"resolve"in s?{type:s.type}:{type:s.name}:s;class me{constructor(t,e){if(this.config=t,this.key=void 0,this.id=void 0,this.type=void 0,this.path=void 0,this.states=void 0,this.history=void 0,this.entry=void 0,this.exit=void 0,this.parent=void 0,this.machine=void 0,this.meta=void 0,this.output=void 0,this.order=-1,this.description=void 0,this.tags=[],this.transitions=void 0,this.always=void 0,this.parent=e._parent,this.key=e._key,this.machine=e._machine,this.path=this.parent?this.parent.path.concat(this.key):[],this.id=this.config.id||[this.machine.id,...this.path].join(us),this.type=this.config.type||(this.config.states&&Object.keys(this.config.states).length?"compound":this.config.history?"history":"atomic"),this.description=this.config.description,this.order=this.machine.idMap.size,this.machine.idMap.set(this.id,this),this.states=this.config.states?kn(this.config.states,(n,i)=>new me(n,{_parent:this,_key:i,_machine:this.machine})):Zo,this.type==="compound"&&!this.config.initial)throw new Error(`No initial state specified for compound state node "#${this.id}". Try adding { initial: "${Object.keys(this.states)[0]}" } to the state config.`);this.history=this.config.history===!0?"shallow":this.config.history||!1,this.entry=it(this.config.entry).slice(),this.exit=it(this.config.exit).slice(),this.meta=this.config.meta,this.output=this.type==="final"||!this.parent?this.config.output:void 0,this.tags=it(t.tags).slice()}_initialize(){this.transitions=mo(this),this.config.always&&(this.always=Ot(this.config.always).map(t=>yt(this,fs,t))),Object.keys(this.states).forEach(t=>{this.states[t]._initialize()})}get definition(){return{id:this.id,key:this.key,version:this.machine.version,type:this.type,initial:this.initial?{target:this.initial.target,source:this,actions:this.initial.actions.map(jt),eventType:null,reenter:!1,toJSON:()=>({target:this.initial.target.map(t=>`#${t.id}`),source:`#${this.id}`,actions:this.initial.actions.map(jt),eventType:null})}:void 0,history:this.history,states:kn(this.states,t=>t.definition),on:this.on,transitions:[...this.transitions.values()].flat().map(t=>({...t,actions:t.actions.map(jt)})),entry:this.entry.map(jt),exit:this.exit.map(jt),meta:this.meta,order:this.order||-1,output:this.output,invoke:this.invoke,description:this.description,tags:this.tags}}toJSON(){return this.definition}get invoke(){return St(this,"invoke",()=>it(this.config.invoke).map((t,e)=>{const{src:n,systemId:i}=t,r=t.id??Cn(this.id,e),o=typeof n=="string"?n:`xstate.invoke.${Cn(this.id,e)}`;return{...t,src:o,id:r,systemId:i,toJSON(){const{onDone:a,onError:c,...l}=t;return{...l,type:"xstate.invoke",src:o,id:r}}}}))}get on(){return St(this,"on",()=>[...this.transitions].flatMap(([e,n])=>n.map(i=>[e,i])).reduce((e,[n,i])=>(e[n]=e[n]||[],e[n].push(i),e),{}))}get after(){return St(this,"delayedTransitions",()=>go(this))}get initial(){return St(this,"initial",()=>yo(this,this.config.initial))}next(t,e){const n=e.type,i=[];let r;const o=St(this,`candidates-${n}`,()=>po(this,n));for(const a of o){const{guard:c}=a,l=t.context;let d=!1;try{d=!c||ln(c,l,e,t)}catch(h){const u=typeof c=="string"?c:typeof c=="object"?c.type:void 0;throw new Error(`Unable to evaluate guard ${u?`'${u}' `:""}in transition for event '${n}' in state node '${this.id}':
|
|
10
|
+
${h.message}`)}if(d){i.push(...a.actions),r=a;break}}return r?[r]:void 0}get events(){return St(this,"events",()=>{const{states:t}=this,e=new Set(this.ownEvents);if(t)for(const n of Object.keys(t)){const i=t[n];if(i.states)for(const r of i.events)e.add(`${r}`)}return Array.from(e)})}get ownEvents(){const t=Object.keys(Object.fromEntries(this.transitions)),e=new Set(t.filter(n=>this.transitions.get(n).some(i=>!(!i.target&&!i.actions.length&&!i.reenter))));return Array.from(e)}}const Yo="#";class pn{constructor(t,e){this.config=t,this.version=void 0,this.schemas=void 0,this.implementations=void 0,this.__xstatenode=!0,this.idMap=new Map,this.root=void 0,this.id=void 0,this.states=void 0,this.events=void 0,this.id=t.id||"(machine)",this.implementations={actors:e?.actors??{},actions:e?.actions??{},delays:e?.delays??{},guards:e?.guards??{}},this.version=this.config.version,this.schemas=this.config.schemas,this.transition=this.transition.bind(this),this.getInitialSnapshot=this.getInitialSnapshot.bind(this),this.getPersistedSnapshot=this.getPersistedSnapshot.bind(this),this.restoreSnapshot=this.restoreSnapshot.bind(this),this.start=this.start.bind(this),this.root=new me(t,{_key:this.id,_machine:this}),this.root._initialize(),this.states=this.root.states,this.events=this.root.events}provide(t){const{actions:e,guards:n,actors:i,delays:r}=this.implementations;return new pn(this.config,{actions:{...e,...t.actions},guards:{...n,...t.guards},actors:{...i,...t.actors},delays:{...r,...t.delays}})}resolveState(t){const e=Mo(this.root,t.value),n=fe(ge(this.root,e));return ae({_nodes:[...n],context:t.context||{},children:{},status:dn(n,this.root)?"done":t.status||"active",output:t.output,error:t.error,historyValue:t.historyValue},this)}transition(t,e,n){return ke(t,e,n,[]).snapshot}microstep(t,e,n){return ke(t,e,n,[]).microstates}getTransitionData(t,e){return un(this.root,t.value,t,e)||[]}getPreInitialState(t,e,n){const{context:i}=this.config,r=ae({context:typeof i!="function"&&i?i:{},_nodes:[this.root],children:{},status:"active"},this);return typeof i=="function"?Lt(r,e,t,[Go(({spawn:a,event:c,self:l})=>i({spawn:a,input:c.input,self:l}))],n,void 0):r}getInitialSnapshot(t,e){const n=gs(e),i=[],r=this.getPreInitialState(t,n,i),o=Fe([{target:[...vs(this.root)],source:this.root,reenter:!0,actions:[],eventType:null,toJSON:null}],r,t,n,!0,i),{snapshot:a}=ke(o,n,t,i);return a}start(t){Object.values(t.children).forEach(e=>{e.getSnapshot().status==="active"&&e.start()})}getStateNodeById(t){const e=on(t),n=e.slice(1),i=Ie(e[0])?e[0].slice(Yo.length):e[0],r=this.idMap.get(i);if(!r)throw new Error(`Child state node '#${i}' does not exist on machine '${this.id}'`);return pe(r,n)}get definition(){return this.root.definition}toJSON(){return this.definition}getPersistedSnapshot(t,e){return Lo(t,e)}restoreSnapshot(t,e){const n={},i=t.children;Object.keys(i).forEach(h=>{const u=i[h],m=u.snapshot,f=u.src,w=typeof f=="string"?an(this,f):f;if(!w)return;const b=Bt(w,{id:h,parent:e.self,syncSnapshot:u.syncSnapshot,snapshot:m,src:f,systemId:u.systemId});n[h]=b});function r(h,u){if(u instanceof me)return u;try{return h.machine.getStateNodeById(u.id)}catch{}}function o(h,u){if(!u||typeof u!="object")return{};const m={};for(const f in u){const w=u[f];for(const b of w){const A=r(h,b);A&&(m[f]??=[],m[f].push(A))}}return m}const a=o(this.root,t.historyValue),c=ae({...t,children:n,_nodes:Array.from(fe(ge(this.root,t.value))),historyValue:a},this),l=new Set;function d(h,u){if(!l.has(h)){l.add(h);for(const m in h){const f=h[m];if(f&&typeof f=="object"){if("xstate$$type"in f&&f.xstate$$type===cn){h[m]=u[f.id];continue}d(f,u)}}}}return d(c.context,n),c}}function Vo(s,t){return new pn(s,t)}const re=s=>s===!1?!1:s.map(t=>t.serialize()),Jo=s=>s===!1?!1:s.serialize(),Xo=s=>s===!1?!1:s.map(t=>({tile:t.tile.toString(),effectiveTiles:t.effectiveTiles.map(e=>e.toString()),shanten:t.shanten})),oe=s=>s===!1?!1:ue(s),Ge=s=>Vo({id:"Untitled",initial:"distribute",context:{currentWind:_.E,oneShotMap:H(()=>!1),missingMap:H(()=>!1),controller:s,genEventID:Ms()},states:{distribute:{on:{NEXT:{target:"drawn"}},entry:{type:"notify_distribution"}},drawn:{entry:{type:"notify_draw"},on:{NEXT:{target:"waiting_user_event_after_drawn",actions:{type:"notify_choice_after_drawn"},description:`可能なアクションとその詳細を通知\\
|
|
11
11
|
DISCARD の場合は捨てられる牌の一覧`}}},waiting_user_event_after_drawn:{description:"ツモった1ユーザからのレスポンス待ち",on:{TSUMO:{target:"tsumo",guard:"canWin"},REACH:{target:"waiting_reach_acceptance",actions:[{type:"notify_reach"},{type:"notify_choice_for_reach_acceptance"}],guard:{type:"canReach"}},SHO_KAN:{target:"an_sho_kaned"},AN_KAN:{target:"an_sho_kaned"},DISCARD:{target:"discarded",description:"入力に牌が必須",actions:{type:"disable_one_shot_for_me"}},DRAWN_GAME_BY_NINE_TERMINALS:{target:"drawn_game"}}},discarded:{entry:{type:"notify_discard"},on:{NEXT:{target:"waiting_user_event_after_discarded",actions:{type:"notify_choice_after_discarded"},description:`可能なアクションとその詳細を通知\\
|
|
12
12
|
CHI/PON の場合は鳴ける組み合わせの一覧`}}},tsumo:{exit:[{type:"notify_tsumo"},{type:"notify_end"}],type:"final"},waiting_reach_acceptance:{on:{REACH_ACCEPT:{target:"reached"},RON:{target:"roned",guard:{type:"canWin"}}},description:"リーチに対するアクションは RON か ACCEPT のみである"},waiting_user_event_after_discarded:{description:`最大 4人から choice に対するレスポンスを待つ\\
|
|
13
13
|
ユーザからではなく、controller が優先順位を考慮して遷移させる必要がある\\
|
|
14
|
-
通知する choice がない場合、controller が\\*で遷移させる`,on:{RON:{target:"roned",guard:"canWin"},PON:{target:"poned",guard:"canPon"},CHI:{target:"chied",guard:"canChi"},DAI_KAN:{target:"dai_kaned"},"*":{target:"wildcard_after_discarded"}}},reached:{on:{NEXT:{target:"waiting_user_event_after_discarded",actions:{type:"notify_choice_after_discarded"}}},entry:{type:"notify_reach_accepted"}},roned:{exit:[{type:"notify_ron"},{type:"notify_end"}],type:"final"},poned:{on:{NEXT:{target:"waiting_discard_event",actions:{type:"notify_choice_after_called"}}},entry:[{type:"notify_call"},{type:"disable_none_shot"}]},chied:{on:{NEXT:{target:"waiting_discard_event",actions:{type:"notify_choice_after_called",params:{action:"chi"}}}},entry:[{type:"notify_call"},{type:"disable_one_shot"}]},wildcard_after_discarded:{exit:[],always:[{target:"drawn_game",guard:"cannotContinue"},{target:"drawn",actions:[{type:"updateNextWind"}]}]},waiting_discard_event:{description:"鳴いたユーザからの DISCARD イベントを待つ",on:{DISCARD:{target:"discarded"}}},dai_kaned:{on:{NEXT:{target:"waiting_user_event_after_drawn",actions:[{type:"notify_draw",params:{action:"kan"}},{type:"notify_choice_after_drawn",params:{replacementWin:!0}}]}},entry:[{type:"notify_call"},{type:"disable_one_shot"}]},an_sho_kaned:{always:{target:"waiting_chankan_event"},entry:[{type:"notify_call"},{type:"disable_one_shot"},{type:"notify_new_dora_if_needed"},{type:"notify_choice_for_chankan"}]},waiting_chankan_event:{description:"チャンカンを待つ",on:{"*":{target:"waiting_user_event_after_drawn",actions:[{type:"notify_draw",params:{action:"kan"}},{type:"notify_choice_after_drawn",params:{replacementWin:!0}}]},RON:{target:"roned",guard:{type:"canWin"}}}},drawn_game:{exit:{type:"notify_end",params:{}},type:"final"}},types:{events:{},context:{}}},{actions:{updateNextWind:({context:t,event:e})=>{const n=t.currentWind;t.currentWind=bt(n)},notify_distribution:({context:t,event:e})=>{const n=t.genEventID(),i=t.controller.initialHands();for(const r of Object.values(_)){const o=H("_____________");o[r]=i[r].toString();const a={id:n,type:"DISTRIBUTE",hands:o,wind:r,doraIndicator:t.controller.wall.doraIndicators[0].toString(),sticks:t.controller.placeManager.sticks,round:t.controller.placeManager.round,players:t.controller.playerIDs,places:t.controller.placeManager.playerMap,scores:t.controller.scoreManager.summary};t.controller.emit(a)}t.controller.next()},notify_choice_after_drawn:({context:t,event:e},n)=>{const i=t.currentWind,r=t.controller.hand(i).drawn,o=t.genEventID(),a={id:o,type:"CHOICE_AFTER_DRAWN",wind:i,drawerInfo:{wind:i,tile:r.toString()},choices:{TSUMO:oe(t.controller.doWin(i,r,{oneShot:t.oneShotMap[i],replacementWin:n?.replacementWin})),REACH:Vo(t.controller.doReach(i)),AN_KAN:re(t.controller.doAnKan(i)),SHO_KAN:re(t.controller.doShoKan(i)),DISCARD:t.controller.doDiscard(i).map(c=>c.toString()),DRAWN_GAME_BY_NINE_TERMINALS:t.controller.canDeclareNineTerminalsAbort(i)}};t.controller.emit(a),t.controller.pollReplies(o,[i])},notify_choice_after_discarded:({context:t,event:e})=>{const n=t.genEventID(),i=t.controller.river.lastTile,r=i.t.clone({add:g.HORIZONTAL});for(const o of Object.values(_)){const a={id:n,type:"CHOICE_AFTER_DISCARDED",wind:o,discarterInfo:{wind:i.w,tile:i.t.toString()},choices:{RON:oe(t.controller.doWin(o,r,{discardedBy:i.w,oneShot:t.oneShotMap[o],missingRon:t.missingMap[o]})),PON:re(t.controller.doPon(o,i.w,r)),CHI:re(t.controller.doChi(o,i.w,r)),DAI_KAN:Yo(t.controller.doDaiKan(o,i.w,r))}};a.choices.RON&&(t.missingMap[o]=!0),t.controller.emit(a)}t.controller.pollReplies(n,Object.values(_))},notify_choice_after_called:({context:t,event:e},n)=>{const i=t.genEventID(),r=t.currentWind;let o=t.controller.doDiscard(r);const a=t.controller.hand(t.currentWind).called.at(-1);(a instanceof F||a instanceof U)&&(o=t.controller.doDiscard(r,a));const c={id:i,type:"CHOICE_AFTER_CALLED",wind:r,choices:{DISCARD:o.map(l=>l.toString())}};t.controller.emit(c),t.controller.pollReplies(i,[r])},notify_choice_for_reach_acceptance:({context:t,event:e})=>{const n=t.genEventID(),i=t.controller.river.lastTile,r=i.t.clone({add:g.HORIZONTAL});for(const o of Object.values(_)){const a={id:n,type:"CHOICE_FOR_REACH_ACCEPTANCE",wind:o,reacherInfo:{wind:i.w,tile:r.toString()},choices:{RON:oe(t.controller.doWin(o,r,{discardedBy:i.w,oneShot:t.oneShotMap[o],missingRon:t.missingMap[o]}))}};t.controller.emit(a)}t.controller.pollReplies(n,Object.values(_))},notify_choice_for_chankan:({context:t,event:e})=>{I(e.type=="SHO_KAN"||e.type=="AN_KAN",`unexpected event ${e.type}`);const n=t.genEventID(),i=e.block.tiles[0].clone({remove:g.HORIZONTAL});for(const r of Object.values(_)){const o=t.controller.doWin(r,e.block.tiles[0].clone({remove:g.HORIZONTAL}),{discardedBy:e.iam,quadWin:!0,oneShot:t.oneShotMap[r],missingRon:t.missingMap[e.iam]}),a={id:n,type:"CHOICE_FOR_CHAN_KAN",wind:r,callerInfo:{wind:e.iam,tile:i.toString()},choices:{RON:e.type=="SHO_KAN"?oe(o):!1}};a.choices.RON&&(t.missingMap[r]=!0),t.controller.emit(a)}t.controller.pollReplies(n,Object.values(_))},notify_call:({context:t,event:e})=>{I(e.type=="CHI"||e.type=="PON"||e.type=="DAI_KAN"||e.type=="AN_KAN"||e.type=="SHO_KAN",`unexpected event ${e.type}`);const n=t.genEventID(),i=e.iam;t.currentWind=i;for(const r of Object.values(_)){const o={id:n,type:e.type,iam:i,wind:r,block:e.block.serialize()};t.controller.emit(o)}t.controller.next()},notify_discard:({context:t,event:e})=>{I(e.type=="DISCARD",`unexpected event ${e.type}`);const n=t.genEventID(),i=t.currentWind,r=e.tile;for(const o of Object.values(_)){const a={id:n,type:"DISCARD",iam:i,wind:o,tile:r.toString()};t.controller.emit(a)}t.controller.next()},notify_draw:({context:t,event:e},n)=>{const i=t.genEventID(),r=n?.action,o=r=="kan"?t.controller.wall.kan():t.controller.wall.draw(),a=t.currentWind;t.controller.hand(a).reached||(t.missingMap[a]=!1);for(const c of Object.values(_)){const l=c==a?o:new y(p.BACK,0,[g.TSUMO]),h={id:i,type:"DRAW",subType:r,iam:a,wind:c,tile:l.toString()};t.controller.emit(h)}t.controller.next()},notify_ron:({context:t,event:e})=>{I(e.type=="RON");const n=t.genEventID(),i=e.iam;for(const r of Object.values(_)){const o={id:n,type:e.type,iam:i,wind:r,victimInfo:{wind:e.targetInfo.wind,tile:e.targetInfo.tile.toString()},ret:ue(e.ret)};t.controller.emit(o)}},notify_tsumo:({context:t,event:e})=>{I(e.type=="TSUMO",`unexpected event ${e.type}`);const n=t.genEventID(),i=t.currentWind;for(const r of Object.values(_)){const o={id:n,type:e.type,iam:i,wind:r,lastTile:t.controller.hand(i).drawn.toString(),ret:ue(e.ret)};t.controller.emit(o)}},notify_reach:({context:t,event:e})=>{I(e.type=="REACH",`unexpected event ${e.type}`);const n=t.genEventID(),i=e.iam,r=e.tile.clone({add:g.HORIZONTAL});t.oneShotMap[i]=!0;for(const o of Object.values(_)){const a={id:n,type:e.type,iam:i,wind:o,tile:r.toString()};t.controller.emit(a)}},notify_reach_accepted:({context:t,event:e})=>{I(e.type=="REACH_ACCEPT");const n=t.genEventID();for(const i of Object.values(_)){const r={id:n,type:"REACH_ACCEPTED",reacherInfo:{wind:e.reacherInfo.wind,tile:e.reacherInfo.tile.toString()},wind:i};t.controller.emit(r)}t.controller.next()},notify_new_dora_if_needed:({context:t,event:e})=>{const n=t.genEventID();if(e.type=="AN_KAN"){const i=t.controller.wall.openDoraIndicator();for(const r of Object.values(_)){const o={id:n,type:"NEW_DORA",wind:r,doraIndicator:i.toString()};t.controller.emit(o)}}e.type=="SHO_KAN"},disable_one_shot:({context:t,event:e})=>{for(const n of Object.values(_))t.oneShotMap[n]=!1},disable_one_shot_for_me:({context:t,event:e})=>{t.oneShotMap[t.currentWind]=!1},notify_end:({context:t,event:e})=>{const n=t.genEventID(),i=H("");if(e.type=="DRAWN_GAME_BY_NINE_TERMINALS"){i[e.iam]=t.controller.hand(e.iam).toString();for(const r of Object.values(_)){const o={id:n,type:"END_GAME",subType:"NINE_TERMINALS",wind:r,shouldContinue:!0,sticks:t.controller.placeManager.sticks,scores:t.controller.scoreManager.summary,deltas:H(0),hands:i};t.controller.emit(o)}}else if(e.type=="RON"||e.type=="TSUMO"){const r=e.iam==_.E,o=t.controller.finalResult(e.ret,e.iam);for(const a of Object.values(_)){i[e.iam]=t.controller.hand(e.iam).toString();const c={id:n,type:"END_GAME",subType:"WIN_GAME",wind:a,shouldContinue:r,sticks:{reach:0,dead:0},scores:t.controller.scoreManager.summary,deltas:o.deltas,hands:i};t.controller.emit(c)}}else if(!t.controller.wall.canKan||t.controller.river.isFourWindsAbort()){const r=t.controller.wall.canKan?"FOUR_WINDS":"FOUR_KANS";for(const o of Object.values(_)){const a={id:n,type:"END_GAME",subType:r,wind:o,shouldContinue:!0,sticks:t.controller.placeManager.sticks,scores:t.controller.scoreManager.summary,deltas:H(0),hands:H("")};t.controller.emit(a)}}else{if(t.controller.wall.canDraw)throw new Error(`unexpected event ${e.type}`);{const r=[];for(const l of Object.values(_)){const h=t.controller.hand(l);new te(h).calc()==0&&(r.push(l),i[l]=h.toString())}const o=r.length==0||r.length==4,a=H(0);for(const l of Object.values(_))r.includes(l)?a[l]+=o?0:3e3/r.length:a[l]-=o?0:3e3/(4-r.length);const c=r.length==4||a[_.E]>0;for(const l of Object.values(_)){const h={id:n,type:"END_GAME",subType:"DRAWN_GAME",wind:l,shouldContinue:c,sticks:t.controller.placeManager.sticks,scores:t.controller.scoreManager.summary,deltas:a,hands:i};t.controller.emit(h)}}}}},actors:{},guards:{canChi:({context:t,event:e},n)=>e.type=="CHI"?!!t.controller.doChi(e.iam,t.controller.river.lastTile.w,t.controller.river.lastTile.t):(console.error(`guards.canChi receive ${e.type}`),!1),canPon:({context:t,event:e},n)=>e.type=="PON"?!!t.controller.doPon(e.iam,t.controller.river.lastTile.w,t.controller.river.lastTile.t):(console.error(`guards.canPon receive ${e.type}`),!1),canWin:({context:t,event:e},n)=>e.type=="TSUMO"||e.type=="RON"?!0:(console.error(`guards.canWin receive ${e.type}`),!1),canReach:({context:t,event:e},n)=>e.type=="REACH"?!!t.controller.doReach(e.iam):(console.error(`guards.canReach receive ${e.type}`),!1),cannotContinue:({context:t,event:e},n)=>!t.controller.wall.canDraw||!t.controller.wall.canKan||t.controller.river.isFourWindsAbort()},delays:{}});function Rs(s=0){let t=s;return()=>(t++).toString()}class It{walls={replacement:[],dead:[],doraIndicators:[],hiddenDoraIndicators:[],drawable:[]};backup;openedDoraCount=1;constructor(t){this.init(t),this.backup=It.clone(this.walls)}kan(){if(this.walls.replacement.length==0)throw new Error("exceeded maximum kan");const t=this.walls.replacement.pop();return this.walls.drawable.pop(),y.from(t)}draw(){if(!this.walls.drawable)throw new Error("cannot draw any more");return y.from(this.walls.drawable.pop())}openDoraIndicator(){if(this.openedDoraCount>=4)throw new Error("exceeded maximum open dora");return this.openedDoraCount++,y.from(this.walls.doraIndicators[this.openedDoraCount-1])}get doraIndicators(){return this.walls.doraIndicators.slice(0,this.openedDoraCount).map(y.from)}get hiddenDoraIndicators(){return this.walls.hiddenDoraIndicators.slice(0,this.openedDoraCount).map(y.from)}get canKan(){return this.walls.replacement.length>0}get canDraw(){return this.walls.drawable.length>0}initialHands(){const t=H("");for(let e=0;e<3;e++)for(const n of Object.values(_))for(let i=0;i<4;i++)t[n]+=this.draw().toString();for(const e of Object.values(_))t[e]+=this.draw().toString();return t}init(t){if(t!=null){this.walls=It.clone(t);return}else{for(let e of Object.values(p)){if(e==p.BACK)continue;const n=e==p.Z?[1,2,3,4,5,6,7]:[1,2,3,4,5,6,7,8,9];for(let i=0;i<4;i++)for(let r of n){let o=new y(e,r);e!=p.Z&&i==3&&r==5&&(o=o.clone({add:g.RED})),this.walls.drawable.push(o.toString())}}sn(this.walls.drawable)}for(let e=0;e<14;e++)this.walls.dead.push(this.walls.drawable.pop());for(let e=0;e<4;e++)this.walls.hiddenDoraIndicators.push(this.walls.dead.pop());for(let e=0;e<4;e++)this.walls.doraIndicators.push(this.walls.dead.pop());for(let e=0;e<4;e++)this.walls.replacement.push(this.walls.dead.pop())}export(){return this.backup}static clone(t){return{drawable:t.drawable.concat(),dead:t.dead.concat(),doraIndicators:t.doraIndicators.concat(),hiddenDoraIndicators:t.hiddenDoraIndicators.concat(),replacement:t.replacement.concat()}}}class ne{wall=new It;playerIDs;actor=Bt(Ge(this),{});observer;handlers={};mailBox={};histories=[];debugMode;constructor(t,e){this.debugMode=e?.debug??!1,this.handlers=Object.fromEntries(t.map(o=>[o.id,o.handler])),this.playerIDs=t.map(o=>o.id),t.forEach(o=>o.handler.on(a=>this.enqueue(a)));const n=ds();this.observer=new Ms(n),this.observer.eventHandler.on(o=>this.observer.handleEvent(o));const i=Object.fromEntries(this.playerIDs.map(o=>[o,25e3]));this.observer.scoreManager=new Jt(i);const r=e?.shuffle==!1?this.playerIDs:sn([...this.playerIDs]);this.observer.placeManager=new Xt({[r[0]]:_.E,[r[1]]:_.S,[r[2]]:_.W,[r[3]]:_.N})}getBaseBoardParams(t){return{doraIndicators:this.observer.doraIndicators,round:this.placeManager.round,myWind:t,sticks:this.observer.placeManager.sticks}}hand(t){return this.observer.hand(t)}get placeManager(){return this.observer.placeManager}get scoreManager(){return this.observer.scoreManager}get river(){return this.observer.river}next(t){(!this.debugMode||t)&&this.actor.send({type:"NEXT"})}emit(t){const e=this.observer.placeManager.playerID(t.wind);this.handlers[e].emit(t);const n=t.iam;t.wind==n?this.observer.eventHandler.emit(t):n==null&&(!this.observer.applied[t.id]||t.type=="DISTRIBUTE")&&(this.observer.eventHandler.emit(t),this.observer.applied[t.id]=!0)}enqueue(t){this.mailBox[t.id]==null&&(this.mailBox[t.id]=[]),this.mailBox[t.id].push(t)}pollReplies(t,e){const n=this.mailBox[t];if(n==null)throw new Error(`${t} is not enqueued at ${this.actor.getSnapshot().value}`);if(n.length!=e.length)throw new Error(`${t}: num of events: got: ${e.length}, want: ${n.length}`);if(e.length==0){console.warn("no events to handle");return}const i=n[0];if(i.type=="CHOICE_AFTER_DISCARDED"){const r=os(n);if(r.events.length==0){this.actor.send({type:""});return}const o=r.events[0];switch(r.type){case"RON":I(o.choices.RON,"RON choice is not available"),this.actor.send({type:r.type,iam:o.wind,ret:Ft(o.choices.RON),targetInfo:{wind:o.discarterInfo.wind,tile:y.from(o.discarterInfo.tile)}});break;case"DAI_KAN":I(o.choices.DAI_KAN,"DAI_KAN choice is not available"),this.actor.send({type:r.type,iam:o.wind,block:K.from(o.choices.DAI_KAN.tiles)});break;case"CHI":case"PON":const a=o.choices[r.type];I(a,`${r.type} choice is not available"`),I(r.events.length==1,`found more than one selected: ${JSON.stringify(r,null,2)}`);const c=N.deserialize(a[0]);this.actor.send({type:r.type,iam:o.wind,block:c});break}}else if(i.type=="CHOICE_AFTER_DRAWN"){const r=as(n);I(r.events.length==1,`found more than one selected: ${JSON.stringify(r,null,2)}`);const o=r.events[0],a=o.wind;switch(r.type){case"TSUMO":I(o.choices.TSUMO,"TSUMO choice is not available"),this.actor.send({type:r.type,ret:Ft(o.choices.TSUMO),lastTile:y.from(o.drawerInfo.tile),iam:a});break;case"REACH":const c=o.choices[r.type];I(c,`${r.type} candidates are not available`),this.actor.send({type:"REACH",tile:y.from(c[0].tile),iam:a});break;case"DISCARD":const l=o.choices[r.type];I(l,`${r.type} choice is not available`),this.actor.send({type:r.type,tile:y.from(l[0]).clone({remove:g.TSUMO}),iam:a});break;case"AN_KAN":{const h=o.choices[r.type];I(h,`${r.type} choice is not available`),this.actor.send({type:r.type,block:R.from(h[0].tiles),iam:a});break}case"SHO_KAN":{const h=o.choices[r.type];I(h,`${r.type} choice is not available`),this.actor.send({type:r.type,block:M.from(h[0].tiles),iam:a});break}case"DRAWN_GAME_BY_NINE_TERMINALS":this.actor.send({type:"DRAWN_GAME_BY_NINE_TERMINALS",iam:a});break}}else if(i.type=="CHOICE_AFTER_CALLED"){I(i.choices.DISCARD,`discard candidate tile is not available: ${JSON.stringify(i,null,2)} ${this.hand(i.wind).toString()}`);const r=i.wind,o=y.from(i.choices.DISCARD[0]);this.actor.send({type:"DISCARD",tile:o,iam:r})}else if(i.type=="CHOICE_FOR_REACH_ACCEPTANCE"){const r=n.filter(a=>(I(a.type=="CHOICE_FOR_REACH_ACCEPTANCE"),a.choices.RON!==!1));if(r.length==0){this.actor.send({type:"REACH_ACCEPT",reacherInfo:{tile:y.from(i.reacherInfo.tile),wind:i.reacherInfo.wind}});return}const o=r[0];this.actor.send({type:"RON",iam:o.wind,ret:Ft(o.choices.RON),targetInfo:{wind:o.reacherInfo.wind,tile:y.from(o.reacherInfo.tile)}});return}else if(i.type=="CHOICE_FOR_CHAN_KAN"){const r=n.filter(a=>a.choices.RON!==!1);if(r.length==0){this.actor.send({type:""});return}const o=r[0];I(o.choices.RON,"RON choice is not available"),this.actor.send({type:"RON",iam:o.wind,ret:Ft(o.choices.RON),quadWin:!0,targetInfo:{wind:o.callerInfo.wind,tile:y.from(o.callerInfo.tile)}});return}else throw new Error(`controller found an unexpected event: ${i.type}`)}export(){return this.histories.concat()}static load(t){const e=t.choiceEvents,n=Object.keys(t.players),i={emit:a=>{},on:a=>{}},r=n.map(a=>({id:a,handler:i})),o=new ne(r);return o.playerIDs=n,o.mailBox=e,o.observer.placeManager=new Xt(t.players,{round:t.round,sticks:t.sticks}),o.observer.scoreManager=new Jt(t.scores),o.wall=new It(t.wall),o}start(){this.actor.subscribe(n=>{console.debug("State:",n.value)});const t={scores:this.scoreManager.summary,round:this.placeManager.round,players:this.placeManager.playerMap,wall:this.wall.export(),choiceEvents:this.mailBox,sticks:this.placeManager.sticks};this.actor.start(),this.histories.push(t);const e=this.actor.getSnapshot().status;if(e!="done")throw new Error(`unexpected state ${this.actor.getSnapshot().value}(${e})`)}startGame(){for(;console.debug(`start========${this.placeManager.round}=============`),this.start(),this.wall=new It,this.observer.applied={},this.mailBox={},this.actor=Bt(Ge(this)),!this.placeManager.is(k.W1););}finalResult(t,e){const n=this.hand(e),i=n.reached?this.wall.hiddenDoraIndicators:void 0,r=new nn(n,{...t.boardContext,sticks:this.placeManager.sticks,hiddenDoraIndicators:i}).calc(t.hand);return I(r,"[bug] the final result is false"),r}doWin(t,e,n){if(e==null)return!1;const i=this.hand(t),r=this.river.discards(t);let o=i;const c={...this.getBaseBoardParams(t)};if(o.drawn==null){if(n==null)throw new Error("should ron but params == null");if(n.discardedBy==t||n.missingRon)return!1;o=o.clone(),c.ronWind=n.discardedBy,c.finalDiscardWin=!this.wall.canDraw,c.quadWin=n.quadWin,o.inc([e])}else c.finalWallWin=!this.wall.canDraw,c.replacementWin=n?.replacementWin;return c.oneShotWin=n?.oneShot,c.doubleReached=r.length==0||r.length==1&&r[0].t.has(g.HORIZONTAL),Q.doWin(i,c,e,r)}doPon(t,e,n){if(n==null)return!1;const i=this.hand(t);return Q.doPon(i,t,e,n)}doChi(t,e,n){if(n==null)return!1;const i=this.hand(t);return Q.doChi(i,t,e,n)}doReach(t){const e=this.hand(t);return Q.doReach(e)}doDiscard(t,e){const n=this.hand(t);return Q.doDiscard(n,e)}doAnKan(t){const e=this.hand(t);return Q.doAnkan(e)}doShoKan(t){const e=this.hand(t);return Q.doShoKan(e)}doDaiKan(t,e,n){const i=this.hand(t);return Q.doDaiKan(i,t,e,n)}canDeclareNineTerminalsAbort(t){if(this.river.discards(t).length!=0)return!1;const e=this.hand(t);let n=0;for(const i of Object.values(p)){if(i==p.BACK)continue;const r=i==p.Z?Pt:J;for(const o of r)e.get(i,o)>0&&n++}return n>=9}initialHands(){return this.wall.initialHands()}}class Q{static doWin(t,e,n,i){const r=e.ronWind!=null,o=r?t.clone():t;r&&o.inc([n]);const a=new is(o),c=new nn(o,e),l=a.calc(n),h=c.calc(...l);if(!h)return!1;if(r){const d=Ht.getEffectiveTiles(t).effectiveTiles;if(i.some(u=>d.some(m=>m.equals(u.t))))return!1}return h}static doChi(t,e,n,i){if(!i.isNum()||bt(n)!=e||t.reached||t.hands.length<3)return!1;const r=i.clone({remove:g.TSUMO,add:[g.HORIZONTAL]}),o=[];r.n-2>=1&&t.get(i.t,r.n-2)>0&&t.get(i.t,r.n-1)>0&&o.push(new F([r,new y(i.t,r.n-1),new y(i.t,r.n-2)])),r.n+2<=9&&t.get(i.t,r.n+1)>0&&t.get(i.t,r.n+2)>0&&o.push(new F([r,new y(i.t,r.n+1),new y(i.t,r.n+2)])),r.n-1>=1&&r.n+1<=9&&t.get(i.t,r.n-1)>0&&t.get(i.t,r.n+1)>0&&o.push(new F([r,new y(i.t,r.n-1),new y(i.t,r.n+1)]));for(let f=0;f<o.length;f++){const w=o[f],b=Hn(w),A=[];for(const dt of b){const tt=t.get(dt.t,dt.n);for(let et=0;et<tt;et++)A.push(dt.clone({remove:g.RED}))}const O=t.dec([...A,w.tiles[1],w.tiles[2]]),$=t.hands.length==0;t.inc(O),$&&o.splice(f,1)}if(o.length==0)return!1;const h=o.filter(f=>S(f.tiles[1])||S(f.tiles[2]));if(h.length==0)return o;const d=o.filter(f=>!S(f.tiles[1])&&!S(f.tiles[2])),u=t.get(i.t,0)>0;if(!u)return o;const m=u?Jo(h):[];return m.length>0&&u&&t.get(i.t,5)==1?[...d,...m]:[...o,...m]}static doPon(t,e,n,i){if(e==n||t.reached||t.hands.length<3||t.get(i.t,i.n)<2)return!1;const r=i.clone({removeAll:!0}),o=Re(e,n,E.PON),a=new U([r,r,r]).clone({replace:{idx:o,tile:i.clone({add:g.HORIZONTAL})}});if(S(i)&&i.has(g.RED))return[a.clone({replace:{idx:o,tile:r.clone({add:[g.RED,g.HORIZONTAL]})}})];const c=o%2+1;if(S(i)&&t.get(i.t,0)>0){const l=a.clone({replace:{idx:c,tile:r.clone({add:g.RED})}});if(t.get(r.t,5)==3){const h=a.clone({replace:{idx:c,tile:r}});return[l,h]}else return[l]}return[a]}static doReach(t){return t.reached||!t.menzen||new te(t).calc()>0?!1:Ht.calcEffectiveTiles(t,t.hands)}static doDiscard(t,e){if(t.reached)return[t.drawn];const n=t.hands;if(e==null)return n;if(e instanceof U)return n.filter(o=>!o.equals(e.tiles[0]));const i=Hn(e),r=n.filter(o=>!i.some(a=>o.equals(a)));return I(r.length>0,`[bug] no tiles to discard. hand: ${t}, forbidden tiles: ${i}, block-chi: ${e}`),r}static doDaiKan(t,e,n,i){if(t.reached||e==n)return!1;const r=i.clone({removeAll:!0});if(t.get(r.t,r.n)!=3)return!1;const o=Re(e,n,E.DAI_KAN),a=new K([r,r,r,r]).clone({replace:{idx:o,tile:r.clone({add:g.HORIZONTAL})}});let c=a;if(S(i)&&i.has(g.RED))c=a.clone({replace:{idx:o,tile:r.clone({add:[g.HORIZONTAL,g.RED]})}});else if(S(i)&&!i.has(g.RED)){I(t.get(i.t,0)>0,`[bug] hand does not have red tile to daikan: ${t.toString()}`);const l=o%3+1;c=a.clone({replace:{idx:l,tile:r.clone({add:g.RED})}})}return I(c.tiles.filter(l=>l.has(g.HORIZONTAL)).length==1,`[bug] daikan has unexpected horizontal operators: ${c.toString()}`),c}static doAnkan(t){if(t.reached)return!1;const e=[];for(const[n,i]of j())if(t.get(n,i)==4){const r=new y(n,i),o=[r,r,r,r];S(r)&&(o[1]=r.clone({add:g.RED})),e.push(new R(o))}if(e.length==0)return!1;for(const n of e)I(n.tiles.filter(i=>i.has(g.HORIZONTAL)).length==0,`[bug] ankan has horizontal op: ${n.toString()}`);return e}static doShoKan(t){if(t.reached)return!1;const e=t.called.filter(i=>i instanceof U);if(e.length==0)return!1;const n=[];for(const i of e){const r=i.tiles[0].clone({removeAll:!0,add:g.HORIZONTAL});if(t.get(r.t,r.n)==1){const o=S(r)&&t.get(r.t,0)>0?r.clone({add:g.RED}):r;n.push(M.fromPon(i,o))}}if(n.length==0)return!1;for(const i of n)I(i.tiles.filter(r=>r.has(g.HORIZONTAL)).length==2,`[bug] shokan has unexpected horizontal operators: ${i.toString()}`);return n}}function Jo(s){return s.length==0?[]:s.map(t=>{if(S(t.tiles[1])){const e=t.tiles[1].clone({add:g.RED});return t.clone({replace:{idx:1,tile:e}})}else if(S(t.tiles[2])){const e=t.tiles[2].clone({add:g.RED});return t.clone({replace:{idx:2,tile:e}})}}).filter(t=>t!=null)}function Hn(s){const t=s.tiles[0],e=s.tiles[1].n;return e!=1&&t.n-2==e?[new y(t.t,t.n-3),t]:e!=8&&t.n+1==e?[new y(t.t,t.n+3),t]:[t]}class Nt extends Ae{isBackHand(){for(const t of Object.values(p))if(t!=p.BACK&&this.sum(t)>0)return!1;return this.sum(p.BACK)>0}clone(){const t=new Nt(this.toString());return t.data.reached=this.data.reached,t}dec(t){return this.isBackHand()?(super.dec(t.map(()=>new y(p.BACK,0))),[...t]):super.dec(t)}}class gn{id;river=new rn;placeManager=new Xt({});scoreManager=new Jt({});hands=H(new Nt(""));counter=new hs;_doraIndicators=[];eventHandler;constructor(t,e){this.id=t,this.eventHandler=e}get doraIndicators(){return this._doraIndicators}hand(t){return this.hands[t]}handleEvent(t){switch(t.type){case"CHOICE_AFTER_CALLED":case"CHOICE_AFTER_DISCARDED":case"CHOICE_AFTER_DRAWN":case"CHOICE_FOR_CHAN_KAN":case"CHOICE_FOR_REACH_ACCEPTANCE":break;case"DISTRIBUTE":this.counter.reset();const e=y.from(t.doraIndicator);this.setHands(t),this.placeManager=new Xt(t.places,{round:t.round,sticks:t.sticks}),this.scoreManager=new Jt(t.scores),this._doraIndicators=[e],this.counter.dec(e);for(const i of Object.values(_))i==t.wind&&this.counter.dec(...this.hand(i).hands);break;case"DRAW":{const i=y.from(t.tile);this.hands[t.iam].draw(i),this.counter.dec(i);break}case"DISCARD":{const i=y.from(t.tile);if(this.river.discard(i,t.iam),this.hands[t.iam].discard(i),t.iam!=t.wind){this.counter.dec(i),this.counter.addTileToSafeMap(i,t.iam);for(const r of Object.values(_))this.hand(r).reached&&this.counter.addTileToSafeMap(i,r)}break}case"PON":case"CHI":case"DAI_KAN":{const i=N.deserialize(t.block);this.hands[t.iam].call(i),this.river.markCalled(),t.iam!=t.wind&&this.counter.dec(...i.tiles.filter(r=>!r.has(g.HORIZONTAL)));break}case"SHO_KAN":{const i=M.from(t.block.tiles);this.hands[t.iam].kan(i),t.iam!=t.wind&&this.counter.dec(i.tiles.filter(r=>r.has(g.HORIZONTAL))[0]);break}case"AN_KAN":{const i=R.from(t.block.tiles);this.hands[t.iam].kan(i),t.iam!=t.wind&&this.counter.dec(...i.tiles.filter(r=>!r.has(g.HORIZONTAL)));break}case"REACH":{this.hands[t.iam].reach();const i=y.from(t.tile);if(this.river.discard(i,t.iam),this.hands[t.iam].discard(i),t.iam!=t.wind){this.counter.dec(i),this.counter.addTileToSafeMap(i,t.iam);for(const r of Object.values(_))this.hand(r).reached&&this.counter.addTileToSafeMap(i,r)}break}case"REACH_ACCEPTED":const n=this.placeManager.playerID(t.reacherInfo.wind);this.scoreManager.reach(n),this.placeManager.incrementReachStick();break;case"NEW_DORA":{const i=y.from(t.doraIndicator);this._doraIndicators.push(i),this.counter.dec(i);break}case"TSUMO":break;case"RON":break;case"END_GAME":switch(t.subType){case"NINE_TERMINALS":case"FOUR_KANS":case"FOUR_WINDS":this.placeManager.incrementDeadStick();break;case"DRAWN_GAME":{const i=this.placeManager.playerMap;this.scoreManager.update(t.deltas,i),this.placeManager.incrementDeadStick(),t.shouldContinue||this.placeManager.nextRound();break}case"WIN_GAME":{const i=this.placeManager.playerMap;this.scoreManager.update(t.deltas,i),t.shouldContinue?this.placeManager.incrementDeadStick():(this.placeManager.nextRound(),this.placeManager.resetDeadStick()),this.placeManager.resetReachStick();break}}break;default:throw new Error(`unexpected event ${JSON.stringify(t,null,2)}`)}}}class Ms extends gn{applied={};constructor(t){super("observer",t),this.counter.disabled=!0,this.hands=H(new Nt("_____________"))}setHands(t){this.hands[t.wind]=new Nt(t.hands[t.wind])}handleEvent(t){switch(super.handleEvent(t),t.type){case"DISTRIBUTE":let e=!0;for(const n of Object.values(_))e&&=this.hand(n).get(p.BACK,0)==0;if(!e)break;console.debug("DISTRIBUTE:",`round: ${this.placeManager.round}`,`scores: ${JSON.stringify(this.scoreManager.summary,null,2)}`,`map: ${JSON.stringify(this.placeManager.playerMap,null,2)}`,`sticks: ${JSON.stringify(this.placeManager.sticks,null,2)}`);for(const n of Object.values(_))console.debug(`${this.placeManager.playerID(n)}(${n})`,`init hand: ${this.hand(n).toString()}`);break;case"DRAW":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`draw: ${this.hand(t.iam).drawn}`,`hand: ${this.hand(t.iam).toString()}`);break;case"DISCARD":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`discard: ${t.tile.toString()}`,`hand: ${this.hand(t.iam).toString()}`);break;case"CHI":case"PON":case"DAI_KAN":case"AN_KAN":case"SHO_KAN":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`call: ${t.block.tiles}`,`hand: ${this.hand(t.iam).toString()}`);break;case"REACH":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`reach: ${t.tile}`,`hand: ${this.hand(t.iam).toString()}`);break;case"TSUMO":case"RON":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`ron/tsumo: ${JSON.stringify(t.ret,null,2)}`,`hand: ${this.hand(t.iam).toString()}`);break;case"END_GAME":for(const n of Object.values(_))console.debug(`${this.placeManager.playerID(n)}(${Ee(n)})`,`end hand: ${this.hand(n).toString()}`);console.debug("END_GAME",t.subType,"scores",JSON.stringify(this.scoreManager.summary,null,2),`sticks: ${JSON.stringify(this.placeManager.sticks,null,2)}`)}}}class Yt extends gn{river=new rn;doras=[];constructor(t,e){super(t,e),this.eventHandler.on(n=>this.handleEvent(n))}get myWind(){return this.placeManager.wind(this.id)}setHands(t){for(const e of Object.values(_))this.hands[e]=new Nt(t.hands[e])}handleDiscard(t){const e=Object.values(_).filter(l=>l==this.myWind?!1:this.hand(l).reached),n=new te(this.hand(this.myWind)).calc();if(e.length>0&&n>=2)return Rt.selectTile(this.counter,e,t);const i=Ht.calcEffectiveTiles(this.hand(this.myWind),t),o=qt.analyzePlayerEfficiency(this.counter,i).sort((l,h)=>h.sum-l.sum),a=o.filter(l=>l.sum==o[0].sum);return qt.selectMinPriority(this.counter,a,this.doras).tile}handleEvent(t){switch(t.type){case"CHOICE_AFTER_DISCARDED":this.eventHandler.emit(t);break;case"CHOICE_AFTER_CALLED":case"CHOICE_AFTER_DRAWN":if(t.choices.DISCARD){const e=this.handleDiscard(t.choices.DISCARD.map(y.from));t.choices.DISCARD=[e.toString()]}this.eventHandler.emit(t);break;case"CHOICE_FOR_REACH_ACCEPTANCE":this.eventHandler.emit(t);break;case"CHOICE_FOR_CHAN_KAN":this.eventHandler.emit(t);break;default:super.handleEvent(t)}}}class Xo{index=0;histories=[];constructor(t){this.histories=JSON.parse(t)}next(){I(this.index<this.histories.length),this.index++}prev(){this.index--,I(this.index<0)}start(){ne.load(this.histories[this.index]).start()}auto(){for(;this.index<this.histories.length;this.next())this.start()}}const qo=s=>{const[t,e]=Zt(),[n,i]=Zt(),[r,o]=Zt(),[a,c]=Zt(),l=["player-1","player-2","player-3","player-4"],h=s?.playerInjection,d=h?.p1??Yt,u=h?.p2??Yt,m=h?.p3??Yt,f=h?.p4??Yt,w=new d(l[0],e),b=new u(l[1],i),A=new m(l[2],o),O=new f(l[3],c),$=[{handler:t,id:l[0]},{handler:n,id:l[1]},{handler:r,id:l[2]},{handler:a,id:l[3]}];return{c:new ne($,{debug:s?.debug,shuffle:s?.shuffle}),p1:w,p2:b,p3:A,p4:O}},gt=(s,t)=>{let n=1;for(let i of t)i.equals(s)&&(n*=2);return n};class qt{static analyzePlayerEfficiency(t,e){let n=[];for(let i of e){let r=0,o=[];for(let a of i.effectiveTiles)o.push({tile:a.clone(),count:t.get(a)}),r+=t.get(a);n.push({sum:r,tile:i.tile,effectiveTiles:o,shanten:i.shanten})}return n}static selectMinPriority(t,e,n){I(e.length>0);let i=0,r=0;for(let o=0;o<e.length;o++){const a=qt.calcPriority(t,e[o],n);a<i&&(i=a,r=o)}return e[r]}static calcPriority(t,e,n){const i=e.tile;let r=0;if(i.t==p.Z)return r=t.get(i),(i.n==5||i.n==6||i.n==7)&&(r*=2),r*gt(i,n);{const o=t.get(i);r+=o*gt(i,n);const a=t.get(new y(i.t,i.n+1)),c=t.get(new y(i.t,i.n+2)),l=t.get(new y(i.t,i.n-1)),h=t.get(new y(i.t,i.n-2)),d=i.n-2>0?Math.min(l,h):0,u=i.n+2<=9?Math.min(a,c):0,m=i.n-1>=1&&i.n+1<=9?Math.min(a,l):0,f=Math.max(d,m),w=Math.max(m,u);return r+=o*gt(i,n),r+=d*gt(new y(i.t,i.n-2),n),r+=u*gt(new y(i.t,i.n+2),n),r+=f*gt(new y(i.t,i.n-1),n),r+=w*gt(new y(i.t,i.n+1),n),i.n==0,r}}}class Rt{static selectTile(t,e,n){I(e.length>0&&n.length>0);let i=n[0],r=Number.POSITIVE_INFINITY;for(let o of n){const a=Rt.rank(t,e,o);a<r&&(i=o,r=a)}return i}static rank(t,e,n){let i=0;const r=n.isNum()?Rt.rankN:Rt.rankZ;for(let o of e){const a=r(t,o,n);i<a&&(i=a)}return i}static rankZ(t,e,n){if(n.t!=p.Z)throw new Error(`expected TYPE.Z but ${n.toString()}`);if(t.isSafeTile(n.t,n.n,e))return 0;const i=t.get(n);return Math.min(i,3)}static rankN(t,e,n){if(!n.isNum())throw new Error(`expected TYPE.NUMBER but ${n.toString()}`);const i=n.n,r=n.t;if(t.isSafeTile(r,i,e))return 0;if(i==1)return t.isSafeTile(r,4,e)?3:6;if(i==9)return t.isSafeTile(r,6,e)?3:6;if(i==2||i==8)return t.isSafeTile(r,5,e)?4:8;if(i==3)return t.isSafeTile(r,6,e)?5:8;if(i==7)return t.isSafeTile(r,4,e)?5:8;const o=t.isSafeTile(r,i-3,e),a=t.isSafeTile(r,i+3,e);return o&&a?4:o||a?8:12}}exports.ActionLogic=Q;exports.ActorHand=Nt;exports.BLOCK=E;exports.BaseActor=gn;exports.Block=N;exports.BlockAnKan=R;exports.BlockCalculator=is;exports.BlockChi=F;exports.BlockDaiKan=K;exports.BlockHand=_t;exports.BlockIsolated=Je;exports.BlockOther=we;exports.BlockPair=C;exports.BlockPon=U;exports.BlockRun=nt;exports.BlockShoKan=M;exports.BlockThree=L;exports.Controller=ne;exports.Counter=hs;exports.Efficiency=Ht;exports.FONT_FAMILY=Ze;exports.G=T;exports.Hand=Ae;exports.INPUT_SEPARATOR=V;exports.Image=qe;exports.ImageHelper=en;exports.Mark=lt;exports.MeasureText=Ws;exports.MyG=Qi;exports.MyImage=tr;exports.MyRect=nr;exports.MySVG=qi;exports.MyText=sr;exports.MyUse=er;exports.N19=J;exports.NZ=Pt;exports.OP=g;exports.Observer=Ms;exports.Parser=D;exports.PlaceManager=Xt;exports.Player=Yt;exports.PlayerEfficiency=qt;exports.PointCalculator=nn;exports.ROUND=k;exports.ROUND_MAP=Ye;exports.Rect=Qe;exports.Replayer=Xo;exports.RiskRank=Rt;exports.River=rn;exports.STICK_CONTEXT=Ce;exports.SVG=Yn;exports.ScoreManager=Jt;exports.ShantenCalculator=te;exports.Svg=Zn;exports.Symbol=tn;exports.TABLE_CONTEXT=Bn;exports.TILE_CONTEXT=rt;exports.TYPE=p;exports.Text=At;exports.Tile=y;exports.Use=be;exports.WIND=_;exports.WIND_MAP=ye;exports.Wall=It;exports.compareTiles=Qt;exports.convertInput=ss;exports.createBlockHand=kt;exports.createControllerMachine=Ge;exports.createEventEmitter=ds;exports.createEventPipe=Zt;exports.createLocalGame=qo;exports.createTable=qn;exports.createWindMap=H;exports.deserializeWinResult=Ft;exports.drawBlocks=dr;exports.drawTable=Er;exports.forHand=j;exports.getCallBlockIndex=Re;exports.getPointDescription=rs;exports.incrementalIDGenerator=Rs;exports.is5Tile=S;exports.nextRound=Vt;exports.nextWind=bt;exports.optimizeSVG=ur;exports.parse=es;exports.parseTableInput=ns;exports.prevRound=Fs;exports.prevWind=Ee;exports.prioritizeDiscardedEvents=os;exports.prioritizeDrawnEvents=as;exports.roundWind=Ln;exports.serializeWinResult=ue;exports.shuffle=sn;exports.sortCalledTiles=Wn;exports.toDora=We;
|
|
14
|
+
通知する choice がない場合、controller が\\*で遷移させる`,on:{RON:{target:"roned",guard:"canWin"},PON:{target:"poned",guard:"canPon"},CHI:{target:"chied",guard:"canChi"},DAI_KAN:{target:"dai_kaned"},"*":{target:"wildcard_after_discarded"}}},reached:{on:{NEXT:{target:"waiting_user_event_after_discarded",actions:{type:"notify_choice_after_discarded"}}},entry:{type:"notify_reach_accepted"}},roned:{exit:[{type:"notify_ron"},{type:"notify_end"}],type:"final"},poned:{on:{NEXT:{target:"waiting_discard_event",actions:{type:"notify_choice_after_called"}}},entry:[{type:"notify_call"},{type:"disable_none_shot"}]},chied:{on:{NEXT:{target:"waiting_discard_event",actions:{type:"notify_choice_after_called",params:{action:"chi"}}}},entry:[{type:"notify_call"},{type:"disable_one_shot"}]},wildcard_after_discarded:{exit:[],always:[{target:"drawn_game",guard:"cannotContinue"},{target:"drawn",actions:[{type:"updateNextWind"}]}]},waiting_discard_event:{description:"鳴いたユーザからの DISCARD イベントを待つ",on:{DISCARD:{target:"discarded"}}},dai_kaned:{on:{NEXT:{target:"waiting_user_event_after_drawn",actions:[{type:"notify_draw",params:{action:"kan"}},{type:"notify_choice_after_drawn",params:{replacementWin:!0}}]}},entry:[{type:"notify_call"},{type:"disable_one_shot"}]},an_sho_kaned:{always:{target:"waiting_chankan_event"},entry:[{type:"notify_call"},{type:"disable_one_shot"},{type:"notify_new_dora_if_needed"},{type:"notify_choice_for_chankan"}]},waiting_chankan_event:{description:"チャンカンを待つ",on:{"*":{target:"waiting_user_event_after_drawn",actions:[{type:"notify_draw",params:{action:"kan"}},{type:"notify_choice_after_drawn",params:{replacementWin:!0}}]},RON:{target:"roned",guard:{type:"canWin"}}}},drawn_game:{exit:{type:"notify_end",params:{}},type:"final"}},types:{events:{},context:{}}},{actions:{updateNextWind:({context:t,event:e})=>{const n=t.currentWind;t.currentWind=_t(n)},notify_distribution:({context:t,event:e})=>{const n=t.genEventID(),i=t.controller.initialHands();for(const r of Object.values(_)){const o=H(()=>"_____________");o[r]=i[r].toString();const a={id:n,type:"DISTRIBUTE",hands:o,wind:r,doraIndicator:t.controller.wall.doraIndicators[0].toString(),sticks:t.controller.placeManager.sticks,round:t.controller.placeManager.round,players:t.controller.playerIDs,places:t.controller.placeManager.playerMap,scores:t.controller.scoreManager.summary};t.controller.emit(a)}t.controller.next()},notify_choice_after_drawn:({context:t,event:e},n)=>{const i=t.currentWind,r=t.controller.hand(i).drawn,o=t.genEventID(),a={id:o,type:"CHOICE_AFTER_DRAWN",wind:i,drawerInfo:{wind:i,tile:r.toString()},choices:{TSUMO:oe(t.controller.doWin(i,r,{oneShot:t.oneShotMap[i],replacementWin:n?.replacementWin})),REACH:Xo(t.controller.doReach(i)),AN_KAN:re(t.controller.doAnKan(i)),SHO_KAN:re(t.controller.doShoKan(i)),DISCARD:t.controller.doDiscard(i).map(c=>c.toString()),DRAWN_GAME_BY_NINE_TERMINALS:t.controller.canDeclareNineTerminalsAbort(i)}};t.controller.emit(a),t.controller.pollReplies(o,[i])},notify_choice_after_discarded:({context:t,event:e})=>{const n=t.genEventID(),i=t.controller.river.lastTile,r=i.t.clone({add:g.HORIZONTAL});for(const o of Object.values(_)){const a={id:n,type:"CHOICE_AFTER_DISCARDED",wind:o,discarterInfo:{wind:i.w,tile:i.t.toString()},choices:{RON:oe(t.controller.doWin(o,r,{discardedBy:i.w,oneShot:t.oneShotMap[o],missingRon:t.missingMap[o]})),PON:re(t.controller.doPon(o,i.w,r)),CHI:re(t.controller.doChi(o,i.w,r)),DAI_KAN:Jo(t.controller.doDaiKan(o,i.w,r))}};a.choices.RON&&(t.missingMap[o]=!0),t.controller.emit(a)}t.controller.pollReplies(n,Object.values(_))},notify_choice_after_called:({context:t,event:e},n)=>{const i=t.genEventID(),r=t.currentWind;let o=t.controller.doDiscard(r);const a=t.controller.hand(t.currentWind).called.at(-1);(a instanceof F||a instanceof U)&&(o=t.controller.doDiscard(r,a));const c={id:i,type:"CHOICE_AFTER_CALLED",wind:r,choices:{DISCARD:o.map(l=>l.toString())}};t.controller.emit(c),t.controller.pollReplies(i,[r])},notify_choice_for_reach_acceptance:({context:t,event:e})=>{const n=t.genEventID(),i=t.controller.river.lastTile,r=i.t.clone({add:g.HORIZONTAL});for(const o of Object.values(_)){const a={id:n,type:"CHOICE_FOR_REACH_ACCEPTANCE",wind:o,reacherInfo:{wind:i.w,tile:r.toString()},choices:{RON:oe(t.controller.doWin(o,r,{discardedBy:i.w,oneShot:t.oneShotMap[o],missingRon:t.missingMap[o]}))}};t.controller.emit(a)}t.controller.pollReplies(n,Object.values(_))},notify_choice_for_chankan:({context:t,event:e})=>{I(e.type=="SHO_KAN"||e.type=="AN_KAN",`unexpected event ${e.type}`);const n=t.genEventID(),i=e.block.tiles[0].clone({remove:g.HORIZONTAL});for(const r of Object.values(_)){const o=t.controller.doWin(r,e.block.tiles[0].clone({remove:g.HORIZONTAL}),{discardedBy:e.iam,quadWin:!0,oneShot:t.oneShotMap[r],missingRon:t.missingMap[e.iam]}),a={id:n,type:"CHOICE_FOR_CHAN_KAN",wind:r,callerInfo:{wind:e.iam,tile:i.toString()},choices:{RON:e.type=="SHO_KAN"?oe(o):!1}};a.choices.RON&&(t.missingMap[r]=!0),t.controller.emit(a)}t.controller.pollReplies(n,Object.values(_))},notify_call:({context:t,event:e})=>{I(e.type=="CHI"||e.type=="PON"||e.type=="DAI_KAN"||e.type=="AN_KAN"||e.type=="SHO_KAN",`unexpected event ${e.type}`);const n=t.genEventID(),i=e.iam;t.currentWind=i;for(const r of Object.values(_)){const o={id:n,type:e.type,iam:i,wind:r,block:e.block.serialize()};t.controller.emit(o)}t.controller.next()},notify_discard:({context:t,event:e})=>{I(e.type=="DISCARD",`unexpected event ${e.type}`);const n=t.genEventID(),i=t.currentWind,r=e.tile;for(const o of Object.values(_)){const a={id:n,type:"DISCARD",iam:i,wind:o,tile:r.toString()};t.controller.emit(a)}t.controller.next()},notify_draw:({context:t,event:e},n)=>{const i=t.genEventID(),r=n?.action,o=r=="kan"?t.controller.wall.kan():t.controller.wall.draw(),a=t.currentWind;t.controller.hand(a).reached||(t.missingMap[a]=!1);for(const c of Object.values(_)){const l=c==a?o:new y(p.BACK,0,[g.TSUMO]),d={id:i,type:"DRAW",subType:r,iam:a,wind:c,tile:l.toString()};t.controller.emit(d)}t.controller.next()},notify_ron:({context:t,event:e})=>{I(e.type=="RON");const n=t.genEventID(),i=e.iam;for(const r of Object.values(_)){const o={id:n,type:e.type,iam:i,wind:r,victimInfo:{wind:e.targetInfo.wind,tile:e.targetInfo.tile.toString()},ret:ue(e.ret)};t.controller.emit(o)}},notify_tsumo:({context:t,event:e})=>{I(e.type=="TSUMO",`unexpected event ${e.type}`);const n=t.genEventID(),i=t.currentWind;for(const r of Object.values(_)){const o={id:n,type:e.type,iam:i,wind:r,lastTile:t.controller.hand(i).drawn.toString(),ret:ue(e.ret)};t.controller.emit(o)}},notify_reach:({context:t,event:e})=>{I(e.type=="REACH",`unexpected event ${e.type}`);const n=t.genEventID(),i=e.iam,r=e.tile.clone({add:g.HORIZONTAL});t.oneShotMap[i]=!0;for(const o of Object.values(_)){const a={id:n,type:e.type,iam:i,wind:o,tile:r.toString()};t.controller.emit(a)}},notify_reach_accepted:({context:t,event:e})=>{I(e.type=="REACH_ACCEPT");const n=t.genEventID();for(const i of Object.values(_)){const r={id:n,type:"REACH_ACCEPTED",reacherInfo:{wind:e.reacherInfo.wind,tile:e.reacherInfo.tile.toString()},wind:i};t.controller.emit(r)}t.controller.next()},notify_new_dora_if_needed:({context:t,event:e})=>{const n=t.genEventID();if(e.type=="AN_KAN"){const i=t.controller.wall.openDoraIndicator();for(const r of Object.values(_)){const o={id:n,type:"NEW_DORA",wind:r,doraIndicator:i.toString()};t.controller.emit(o)}}e.type=="SHO_KAN"},disable_one_shot:({context:t,event:e})=>{for(const n of Object.values(_))t.oneShotMap[n]=!1},disable_one_shot_for_me:({context:t,event:e})=>{t.oneShotMap[t.currentWind]=!1},notify_end:({context:t,event:e})=>{const n=t.genEventID(),i=H(()=>"");if(e.type=="DRAWN_GAME_BY_NINE_TERMINALS"){i[e.iam]=t.controller.hand(e.iam).toString();for(const r of Object.values(_)){const o={id:n,type:"END_GAME",subType:"NINE_TERMINALS",wind:r,shouldContinue:!0,sticks:t.controller.placeManager.sticks,scores:t.controller.scoreManager.summary,deltas:H(()=>0),hands:i};t.controller.emit(o)}}else if(e.type=="RON"||e.type=="TSUMO"){const r=e.iam==_.E,o=t.controller.finalResult(e.ret,e.iam);for(const a of Object.values(_)){i[e.iam]=t.controller.hand(e.iam).toString();const c={id:n,type:"END_GAME",subType:"WIN_GAME",wind:a,shouldContinue:r,sticks:{reach:0,dead:0},scores:t.controller.scoreManager.summary,deltas:o.deltas,hands:i};t.controller.emit(c)}}else if(!t.controller.wall.canKan||t.controller.river.isFourWindsAbort()){const r=t.controller.wall.canKan?"FOUR_WINDS":"FOUR_KANS";for(const o of Object.values(_)){const a={id:n,type:"END_GAME",subType:r,wind:o,shouldContinue:!0,sticks:t.controller.placeManager.sticks,scores:t.controller.scoreManager.summary,deltas:H(()=>0),hands:H(()=>"")};t.controller.emit(a)}}else{if(t.controller.wall.canDraw)throw new Error(`unexpected event ${e.type}`);{const r=[];for(const l of Object.values(_)){const d=t.controller.hand(l);new te(d).calc()==0&&(r.push(l),i[l]=d.toString())}const o=r.length==0||r.length==4,a=H(()=>0);for(const l of Object.values(_))r.includes(l)?a[l]+=o?0:3e3/r.length:a[l]-=o?0:3e3/(4-r.length);const c=r.length==4||a[_.E]>0;for(const l of Object.values(_)){const d={id:n,type:"END_GAME",subType:"DRAWN_GAME",wind:l,shouldContinue:c,sticks:t.controller.placeManager.sticks,scores:t.controller.scoreManager.summary,deltas:a,hands:i};t.controller.emit(d)}}}}},actors:{},guards:{canChi:({context:t,event:e},n)=>e.type=="CHI"?!!t.controller.doChi(e.iam,t.controller.river.lastTile.w,t.controller.river.lastTile.t):(console.error(`guards.canChi receive ${e.type}`),!1),canPon:({context:t,event:e},n)=>e.type=="PON"?!!t.controller.doPon(e.iam,t.controller.river.lastTile.w,t.controller.river.lastTile.t):(console.error(`guards.canPon receive ${e.type}`),!1),canWin:({context:t,event:e},n)=>e.type=="TSUMO"||e.type=="RON"?!0:(console.error(`guards.canWin receive ${e.type}`),!1),canReach:({context:t,event:e},n)=>e.type=="REACH"?!!t.controller.doReach(e.iam):(console.error(`guards.canReach receive ${e.type}`),!1),cannotContinue:({context:t,event:e},n)=>!t.controller.wall.canDraw||!t.controller.wall.canKan||t.controller.river.isFourWindsAbort()},delays:{}});function Ms(s=0){let t=s;return()=>(t++).toString()}class It{walls={replacement:[],dead:[],doraIndicators:[],hiddenDoraIndicators:[],drawable:[]};backup;openedDoraCount=1;constructor(t){this.init(t),this.backup=It.clone(this.walls)}kan(){if(this.walls.replacement.length==0)throw new Error("exceeded maximum kan");const t=this.walls.replacement.pop();return this.walls.drawable.pop(),y.from(t)}draw(){if(!this.walls.drawable)throw new Error("cannot draw any more");return y.from(this.walls.drawable.pop())}openDoraIndicator(){if(this.openedDoraCount>=4)throw new Error("exceeded maximum open dora");return this.openedDoraCount++,y.from(this.walls.doraIndicators[this.openedDoraCount-1])}get doraIndicators(){return this.walls.doraIndicators.slice(0,this.openedDoraCount).map(y.from)}get hiddenDoraIndicators(){return this.walls.hiddenDoraIndicators.slice(0,this.openedDoraCount).map(y.from)}get canKan(){return this.walls.replacement.length>0}get canDraw(){return this.walls.drawable.length>0}initialHands(){const t=H(()=>"");for(let e=0;e<3;e++)for(const n of Object.values(_))for(let i=0;i<4;i++)t[n]+=this.draw().toString();for(const e of Object.values(_))t[e]+=this.draw().toString();return t}init(t){if(t!=null){this.walls=It.clone(t);return}else{for(let e of Object.values(p)){if(e==p.BACK)continue;const n=e==p.Z?[1,2,3,4,5,6,7]:[1,2,3,4,5,6,7,8,9];for(let i=0;i<4;i++)for(let r of n){let o=new y(e,r);e!=p.Z&&i==3&&r==5&&(o=o.clone({add:g.RED})),this.walls.drawable.push(o.toString())}}sn(this.walls.drawable)}for(let e=0;e<14;e++)this.walls.dead.push(this.walls.drawable.pop());for(let e=0;e<4;e++)this.walls.hiddenDoraIndicators.push(this.walls.dead.pop());for(let e=0;e<4;e++)this.walls.doraIndicators.push(this.walls.dead.pop());for(let e=0;e<4;e++)this.walls.replacement.push(this.walls.dead.pop())}export(){return this.backup}static clone(t){return{drawable:t.drawable.concat(),dead:t.dead.concat(),doraIndicators:t.doraIndicators.concat(),hiddenDoraIndicators:t.hiddenDoraIndicators.concat(),replacement:t.replacement.concat()}}}class ne{wall=new It;playerIDs;actor=Bt(Ge(this),{});observer;handlers={};mailBox={};histories=[];debugMode;constructor(t,e){this.debugMode=e?.debug??!1,this.handlers=Object.fromEntries(t.map(o=>[o.id,o.handler])),this.playerIDs=t.map(o=>o.id),t.forEach(o=>o.handler.on(a=>this.enqueue(a)));const n=hs();this.observer=new xs(n),this.observer.eventHandler.on(o=>this.observer.handleEvent(o));const i=Object.fromEntries(this.playerIDs.map(o=>[o,25e3]));this.observer.scoreManager=new Jt(i);const r=e?.shuffle==!1?this.playerIDs:sn([...this.playerIDs]);this.observer.placeManager=new Xt({[r[0]]:_.E,[r[1]]:_.S,[r[2]]:_.W,[r[3]]:_.N})}getBaseBoardParams(t){return{doraIndicators:this.observer.doraIndicators,round:this.placeManager.round,myWind:t,sticks:this.observer.placeManager.sticks}}hand(t){return this.observer.hand(t)}get placeManager(){return this.observer.placeManager}get scoreManager(){return this.observer.scoreManager}get river(){return this.observer.river}next(t){(!this.debugMode||t)&&this.actor.send({type:"NEXT"})}emit(t){const e=this.observer.placeManager.playerID(t.wind);this.handlers[e].emit(t);const n=t.iam;t.wind==n?this.observer.eventHandler.emit(t):n==null&&(!this.observer.applied[t.id]||t.type=="DISTRIBUTE")&&(this.observer.eventHandler.emit(t),this.observer.applied[t.id]=!0)}enqueue(t){this.mailBox[t.id]==null&&(this.mailBox[t.id]=[]),this.mailBox[t.id].push(t)}pollReplies(t,e){const n=this.mailBox[t];if(n==null)throw new Error(`${t} is not enqueued at ${this.actor.getSnapshot().value}`);if(n.length!=e.length)throw new Error(`${t}: num of events: got: ${e.length}, want: ${n.length}`);if(e.length==0){console.warn("no events to handle");return}const i=n[0];if(i.type=="CHOICE_AFTER_DISCARDED"){const r=os(n);if(r.events.length==0){this.actor.send({type:""});return}const o=r.events[0];switch(r.type){case"RON":I(o.choices.RON,"RON choice is not available"),this.actor.send({type:r.type,iam:o.wind,ret:Ft(o.choices.RON),targetInfo:{wind:o.discarterInfo.wind,tile:y.from(o.discarterInfo.tile)}});break;case"DAI_KAN":I(o.choices.DAI_KAN,"DAI_KAN choice is not available"),this.actor.send({type:r.type,iam:o.wind,block:K.from(o.choices.DAI_KAN.tiles)});break;case"CHI":case"PON":const a=o.choices[r.type];I(a,`${r.type} choice is not available"`),I(r.events.length==1,`found more than one selected: ${JSON.stringify(r,null,2)}`);const c=N.deserialize(a[0]);this.actor.send({type:r.type,iam:o.wind,block:c});break}}else if(i.type=="CHOICE_AFTER_DRAWN"){const r=as(n);I(r.events.length==1,`found more than one selected: ${JSON.stringify(r,null,2)}`);const o=r.events[0],a=o.wind;switch(r.type){case"TSUMO":I(o.choices.TSUMO,"TSUMO choice is not available"),this.actor.send({type:r.type,ret:Ft(o.choices.TSUMO),lastTile:y.from(o.drawerInfo.tile),iam:a});break;case"REACH":const c=o.choices[r.type];I(c,`${r.type} candidates are not available`),this.actor.send({type:"REACH",tile:y.from(c[0].tile),iam:a});break;case"DISCARD":const l=o.choices[r.type];I(l,`${r.type} choice is not available`),this.actor.send({type:r.type,tile:y.from(l[0]).clone({remove:g.TSUMO}),iam:a});break;case"AN_KAN":{const d=o.choices[r.type];I(d,`${r.type} choice is not available`),this.actor.send({type:r.type,block:R.from(d[0].tiles),iam:a});break}case"SHO_KAN":{const d=o.choices[r.type];I(d,`${r.type} choice is not available`),this.actor.send({type:r.type,block:M.from(d[0].tiles),iam:a});break}case"DRAWN_GAME_BY_NINE_TERMINALS":this.actor.send({type:"DRAWN_GAME_BY_NINE_TERMINALS",iam:a});break}}else if(i.type=="CHOICE_AFTER_CALLED"){I(i.choices.DISCARD,`discard candidate tile is not available: ${JSON.stringify(i,null,2)} ${this.hand(i.wind).toString()}`);const r=i.wind,o=y.from(i.choices.DISCARD[0]);this.actor.send({type:"DISCARD",tile:o,iam:r})}else if(i.type=="CHOICE_FOR_REACH_ACCEPTANCE"){const r=n.filter(a=>(I(a.type=="CHOICE_FOR_REACH_ACCEPTANCE"),a.choices.RON!==!1));if(r.length==0){this.actor.send({type:"REACH_ACCEPT",reacherInfo:{tile:y.from(i.reacherInfo.tile),wind:i.reacherInfo.wind}});return}const o=r[0];this.actor.send({type:"RON",iam:o.wind,ret:Ft(o.choices.RON),targetInfo:{wind:o.reacherInfo.wind,tile:y.from(o.reacherInfo.tile)}});return}else if(i.type=="CHOICE_FOR_CHAN_KAN"){const r=n.filter(a=>a.choices.RON!==!1);if(r.length==0){this.actor.send({type:""});return}const o=r[0];I(o.choices.RON,"RON choice is not available"),this.actor.send({type:"RON",iam:o.wind,ret:Ft(o.choices.RON),quadWin:!0,targetInfo:{wind:o.callerInfo.wind,tile:y.from(o.callerInfo.tile)}});return}else throw new Error(`controller found an unexpected event: ${i.type}`)}export(){return this.histories.concat()}static load(t){const e=t.choiceEvents,n=Object.keys(t.players),i={emit:a=>{},on:a=>{}},r=n.map(a=>({id:a,handler:i})),o=new ne(r);return o.playerIDs=n,o.mailBox=e,o.observer.placeManager=new Xt(t.players,{round:t.round,sticks:t.sticks}),o.observer.scoreManager=new Jt(t.scores),o.wall=new It(t.wall),o}start(){this.actor.subscribe(n=>{console.debug("State:",n.value)});const t={scores:this.scoreManager.summary,round:this.placeManager.round,players:this.placeManager.playerMap,wall:this.wall.export(),choiceEvents:this.mailBox,sticks:this.placeManager.sticks};this.actor.start(),this.histories.push(t);const e=this.actor.getSnapshot().status;if(e!="done")throw new Error(`unexpected state ${this.actor.getSnapshot().value}(${e})`)}startGame(){for(;console.debug(`start========${this.placeManager.round}=============`),this.start(),this.wall=new It,this.observer.applied={},this.mailBox={},this.actor=Bt(Ge(this)),!this.placeManager.is(k.W1););}finalResult(t,e){const n=this.hand(e),i=n.reached?this.wall.hiddenDoraIndicators:void 0,r=new nn(n,{...t.boardContext,sticks:this.placeManager.sticks,hiddenDoraIndicators:i}).calc(t.hand);return I(r,"[bug] the final result is false"),r}doWin(t,e,n){if(e==null)return!1;const i=this.hand(t),r=this.river.discards(t);let o=i;const c={...this.getBaseBoardParams(t)};if(o.drawn==null){if(n==null)throw new Error("should ron but params == null");if(n.discardedBy==t||n.missingRon)return!1;o=o.clone(),c.ronWind=n.discardedBy,c.finalDiscardWin=!this.wall.canDraw,c.quadWin=n.quadWin,o.inc([e])}else c.finalWallWin=!this.wall.canDraw,c.replacementWin=n?.replacementWin;return c.oneShotWin=n?.oneShot,c.doubleReached=r.length==0||r.length==1&&r[0].t.has(g.HORIZONTAL),Q.doWin(i,c,e,r)}doPon(t,e,n){if(n==null)return!1;const i=this.hand(t);return Q.doPon(i,t,e,n)}doChi(t,e,n){if(n==null)return!1;const i=this.hand(t);return Q.doChi(i,t,e,n)}doReach(t){const e=this.hand(t);return Q.doReach(e)}doDiscard(t,e){const n=this.hand(t);return Q.doDiscard(n,e)}doAnKan(t){const e=this.hand(t);return Q.doAnkan(e)}doShoKan(t){const e=this.hand(t);return Q.doShoKan(e)}doDaiKan(t,e,n){const i=this.hand(t);return Q.doDaiKan(i,t,e,n)}canDeclareNineTerminalsAbort(t){if(this.river.discards(t).length!=0)return!1;const e=this.hand(t);let n=0;for(const i of Object.values(p)){if(i==p.BACK)continue;const r=i==p.Z?Pt:J;for(const o of r)e.get(i,o)>0&&n++}return n>=9}initialHands(){return this.wall.initialHands()}}class Q{static doWin(t,e,n,i){const r=e.ronWind!=null,o=r?t.clone():t;r&&o.inc([n]);const a=new is(o),c=new nn(o,e),l=a.calc(n),d=c.calc(...l);if(!d)return!1;if(r){const h=Ht.getEffectiveTiles(t).effectiveTiles;if(i.some(u=>h.some(m=>m.equals(u.t))))return!1}return d}static doChi(t,e,n,i){if(!i.isNum()||_t(n)!=e||t.reached||t.hands.length<3)return!1;const r=i.clone({remove:g.TSUMO,add:[g.HORIZONTAL]}),o=[];r.n-2>=1&&t.get(i.t,r.n-2)>0&&t.get(i.t,r.n-1)>0&&o.push(new F([r,new y(i.t,r.n-1),new y(i.t,r.n-2)])),r.n+2<=9&&t.get(i.t,r.n+1)>0&&t.get(i.t,r.n+2)>0&&o.push(new F([r,new y(i.t,r.n+1),new y(i.t,r.n+2)])),r.n-1>=1&&r.n+1<=9&&t.get(i.t,r.n-1)>0&&t.get(i.t,r.n+1)>0&&o.push(new F([r,new y(i.t,r.n-1),new y(i.t,r.n+1)]));for(let f=0;f<o.length;f++){const w=o[f],b=Hn(w),A=[];for(const ht of b){const tt=t.get(ht.t,ht.n);for(let et=0;et<tt;et++)A.push(ht.clone({remove:g.RED}))}const O=t.dec([...A,w.tiles[1],w.tiles[2]]),$=t.hands.length==0;t.inc(O),$&&o.splice(f,1)}if(o.length==0)return!1;const d=o.filter(f=>S(f.tiles[1])||S(f.tiles[2]));if(d.length==0)return o;const h=o.filter(f=>!S(f.tiles[1])&&!S(f.tiles[2])),u=t.get(i.t,0)>0;if(!u)return o;const m=u?qo(d):[];return m.length>0&&u&&t.get(i.t,5)==1?[...h,...m]:[...o,...m]}static doPon(t,e,n,i){if(e==n||t.reached||t.hands.length<3||t.get(i.t,i.n)<2)return!1;const r=i.clone({removeAll:!0}),o=Re(e,n,E.PON),a=new U([r,r,r]).clone({replace:{idx:o,tile:i.clone({add:g.HORIZONTAL})}});if(S(i)&&i.has(g.RED))return[a.clone({replace:{idx:o,tile:r.clone({add:[g.RED,g.HORIZONTAL]})}})];const c=o%2+1;if(S(i)&&t.get(i.t,0)>0){const l=a.clone({replace:{idx:c,tile:r.clone({add:g.RED})}});if(t.get(r.t,5)==3){const d=a.clone({replace:{idx:c,tile:r}});return[l,d]}else return[l]}return[a]}static doReach(t){return t.reached||!t.menzen||new te(t).calc()>0?!1:Ht.calcEffectiveTiles(t,t.hands)}static doDiscard(t,e){if(t.reached)return[t.drawn];const n=t.hands;if(e==null)return n;if(e instanceof U)return n.filter(o=>!o.equals(e.tiles[0]));const i=Hn(e),r=n.filter(o=>!i.some(a=>o.equals(a)));return I(r.length>0,`[bug] no tiles to discard. hand: ${t}, forbidden tiles: ${i}, block-chi: ${e}`),r}static doDaiKan(t,e,n,i){if(t.reached||e==n)return!1;const r=i.clone({removeAll:!0});if(t.get(r.t,r.n)!=3)return!1;const o=Re(e,n,E.DAI_KAN),a=new K([r,r,r,r]).clone({replace:{idx:o,tile:r.clone({add:g.HORIZONTAL})}});let c=a;if(S(i)&&i.has(g.RED))c=a.clone({replace:{idx:o,tile:r.clone({add:[g.HORIZONTAL,g.RED]})}});else if(S(i)&&!i.has(g.RED)){I(t.get(i.t,0)>0,`[bug] hand does not have red tile to daikan: ${t.toString()}`);const l=o%3+1;c=a.clone({replace:{idx:l,tile:r.clone({add:g.RED})}})}return I(c.tiles.filter(l=>l.has(g.HORIZONTAL)).length==1,`[bug] daikan has unexpected horizontal operators: ${c.toString()}`),c}static doAnkan(t){if(t.reached)return!1;const e=[];for(const[n,i]of j())if(t.get(n,i)==4){const r=new y(n,i),o=[r,r,r,r];S(r)&&(o[1]=r.clone({add:g.RED})),e.push(new R(o))}if(e.length==0)return!1;for(const n of e)I(n.tiles.filter(i=>i.has(g.HORIZONTAL)).length==0,`[bug] ankan has horizontal op: ${n.toString()}`);return e}static doShoKan(t){if(t.reached)return!1;const e=t.called.filter(i=>i instanceof U);if(e.length==0)return!1;const n=[];for(const i of e){const r=i.tiles[0].clone({removeAll:!0,add:g.HORIZONTAL});if(t.get(r.t,r.n)==1){const o=S(r)&&t.get(r.t,0)>0?r.clone({add:g.RED}):r;n.push(M.fromPon(i,o))}}if(n.length==0)return!1;for(const i of n)I(i.tiles.filter(r=>r.has(g.HORIZONTAL)).length==2,`[bug] shokan has unexpected horizontal operators: ${i.toString()}`);return n}}function qo(s){return s.length==0?[]:s.map(t=>{if(S(t.tiles[1])){const e=t.tiles[1].clone({add:g.RED});return t.clone({replace:{idx:1,tile:e}})}else if(S(t.tiles[2])){const e=t.tiles[2].clone({add:g.RED});return t.clone({replace:{idx:2,tile:e}})}}).filter(t=>t!=null)}function Hn(s){const t=s.tiles[0],e=s.tiles[1].n;return e!=1&&t.n-2==e?[new y(t.t,t.n-3),t]:e!=8&&t.n+1==e?[new y(t.t,t.n+3),t]:[t]}class Nt extends Ae{isBackHand(){for(const t of Object.values(p))if(t!=p.BACK&&this.sum(t)>0)return!1;return this.sum(p.BACK)>0}clone(){const t=new Nt(this.toString());return t.data.reached=this.data.reached,t}dec(t){return this.isBackHand()?(super.dec(t.map(()=>new y(p.BACK,0))),[...t]):super.dec(t)}}class gn{id;river=new rn;placeManager=new Xt({});scoreManager=new Jt({});hands=H(()=>new Nt(""));counter=new ds;_doraIndicators=[];eventHandler;constructor(t,e){this.id=t,this.eventHandler=e}get doraIndicators(){return this._doraIndicators}hand(t){return this.hands[t]}handleEvent(t){switch(t.type){case"CHOICE_AFTER_CALLED":case"CHOICE_AFTER_DISCARDED":case"CHOICE_AFTER_DRAWN":case"CHOICE_FOR_CHAN_KAN":case"CHOICE_FOR_REACH_ACCEPTANCE":break;case"DISTRIBUTE":this.counter.reset();const e=y.from(t.doraIndicator);this.setHands(t),this.placeManager=new Xt(t.places,{round:t.round,sticks:t.sticks}),this.scoreManager=new Jt(t.scores),this._doraIndicators=[e],this.counter.dec(e);for(const i of Object.values(_))i==t.wind&&this.counter.dec(...this.hand(i).hands);break;case"DRAW":{const i=y.from(t.tile);this.hands[t.iam].draw(i),this.counter.dec(i);break}case"DISCARD":{const i=y.from(t.tile);if(this.river.discard(i,t.iam),this.hands[t.iam].discard(i),t.iam!=t.wind){this.counter.dec(i),this.counter.addTileToSafeMap(i,t.iam);for(const r of Object.values(_))this.hand(r).reached&&this.counter.addTileToSafeMap(i,r)}break}case"PON":case"CHI":case"DAI_KAN":{const i=N.deserialize(t.block);this.hands[t.iam].call(i),this.river.markCalled(),t.iam!=t.wind&&this.counter.dec(...i.tiles.filter(r=>!r.has(g.HORIZONTAL)));break}case"SHO_KAN":{const i=M.from(t.block.tiles);this.hands[t.iam].kan(i),t.iam!=t.wind&&this.counter.dec(i.tiles.filter(r=>r.has(g.HORIZONTAL))[0]);break}case"AN_KAN":{const i=R.from(t.block.tiles);this.hands[t.iam].kan(i),t.iam!=t.wind&&this.counter.dec(...i.tiles.filter(r=>!r.has(g.HORIZONTAL)));break}case"REACH":{this.hands[t.iam].reach();const i=y.from(t.tile);if(this.river.discard(i,t.iam),this.hands[t.iam].discard(i),t.iam!=t.wind){this.counter.dec(i),this.counter.addTileToSafeMap(i,t.iam);for(const r of Object.values(_))this.hand(r).reached&&this.counter.addTileToSafeMap(i,r)}break}case"REACH_ACCEPTED":const n=this.placeManager.playerID(t.reacherInfo.wind);this.scoreManager.reach(n),this.placeManager.incrementReachStick();break;case"NEW_DORA":{const i=y.from(t.doraIndicator);this._doraIndicators.push(i),this.counter.dec(i);break}case"TSUMO":break;case"RON":break;case"END_GAME":switch(t.subType){case"NINE_TERMINALS":case"FOUR_KANS":case"FOUR_WINDS":this.placeManager.incrementDeadStick();break;case"DRAWN_GAME":{const i=this.placeManager.playerMap;this.scoreManager.update(t.deltas,i),this.placeManager.incrementDeadStick(),t.shouldContinue||this.placeManager.nextRound();break}case"WIN_GAME":{const i=this.placeManager.playerMap;this.scoreManager.update(t.deltas,i),t.shouldContinue?this.placeManager.incrementDeadStick():(this.placeManager.nextRound(),this.placeManager.resetDeadStick()),this.placeManager.resetReachStick();break}}break;default:throw new Error(`unexpected event ${JSON.stringify(t,null,2)}`)}}}class xs extends gn{applied={};constructor(t){super("observer",t),this.counter.disabled=!0,this.hands=H(()=>new Nt("_____________"))}setHands(t){this.hands[t.wind]=new Nt(t.hands[t.wind])}handleEvent(t){switch(super.handleEvent(t),t.type){case"DISTRIBUTE":let e=!0;for(const n of Object.values(_))e&&=this.hand(n).get(p.BACK,0)==0;if(!e)break;console.debug("DISTRIBUTE:",`round: ${this.placeManager.round}`,`scores: ${JSON.stringify(this.scoreManager.summary,null,2)}`,`map: ${JSON.stringify(this.placeManager.playerMap,null,2)}`,`sticks: ${JSON.stringify(this.placeManager.sticks,null,2)}`);for(const n of Object.values(_))console.debug(`${this.placeManager.playerID(n)}(${n})`,`init hand: ${this.hand(n).toString()}`);break;case"DRAW":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`draw: ${this.hand(t.iam).drawn}`,`hand: ${this.hand(t.iam).toString()}`);break;case"DISCARD":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`discard: ${t.tile.toString()}`,`hand: ${this.hand(t.iam).toString()}`);break;case"CHI":case"PON":case"DAI_KAN":case"AN_KAN":case"SHO_KAN":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`call: ${t.block.tiles}`,`hand: ${this.hand(t.iam).toString()}`);break;case"REACH":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`reach: ${t.tile}`,`hand: ${this.hand(t.iam).toString()}`);break;case"TSUMO":case"RON":console.debug(`${this.placeManager.playerID(t.iam)}(${t.iam})`,`ron/tsumo: ${JSON.stringify(t.ret,null,2)}`,`hand: ${this.hand(t.iam).toString()}`);break;case"END_GAME":for(const n of Object.values(_))console.debug(`${this.placeManager.playerID(n)}(${Ee(n)})`,`end hand: ${this.hand(n).toString()}`);console.debug("END_GAME",t.subType,"scores",JSON.stringify(this.scoreManager.summary,null,2),`sticks: ${JSON.stringify(this.placeManager.sticks,null,2)}`)}}}class Yt extends gn{river=new rn;doras=[];constructor(t,e){super(t,e),this.eventHandler.on(n=>this.handleEvent(n))}get myWind(){return this.placeManager.wind(this.id)}setHands(t){for(const e of Object.values(_))this.hands[e]=new Nt(t.hands[e])}handleDiscard(t){const e=Object.values(_).filter(l=>l==this.myWind?!1:this.hand(l).reached),n=new te(this.hand(this.myWind)).calc();if(e.length>0&&n>=2)return Rt.selectTile(this.counter,e,t);const i=Ht.calcEffectiveTiles(this.hand(this.myWind),t),o=qt.analyzePlayerEfficiency(this.counter,i).sort((l,d)=>d.sum-l.sum),a=o.filter(l=>l.sum==o[0].sum);return qt.selectMinPriority(this.counter,a,this.doras).tile}handleEvent(t){switch(t.type){case"CHOICE_AFTER_DISCARDED":this.eventHandler.emit(t);break;case"CHOICE_AFTER_CALLED":case"CHOICE_AFTER_DRAWN":if(t.choices.DISCARD){const e=this.handleDiscard(t.choices.DISCARD.map(y.from));t.choices.DISCARD=[e.toString()]}this.eventHandler.emit(t);break;case"CHOICE_FOR_REACH_ACCEPTANCE":this.eventHandler.emit(t);break;case"CHOICE_FOR_CHAN_KAN":this.eventHandler.emit(t);break;default:super.handleEvent(t)}}}class Qo{index=0;histories=[];constructor(t){this.histories=JSON.parse(t)}next(){I(this.index<this.histories.length),this.index++}prev(){this.index--,I(this.index<0)}start(){ne.load(this.histories[this.index]).start()}auto(){for(;this.index<this.histories.length;this.next())this.start()}}const ta=s=>{const[t,e]=Zt(),[n,i]=Zt(),[r,o]=Zt(),[a,c]=Zt(),l=["player-1","player-2","player-3","player-4"],d=s?.playerInjection,h=d?.p1??Yt,u=d?.p2??Yt,m=d?.p3??Yt,f=d?.p4??Yt,w=new h(l[0],e),b=new u(l[1],i),A=new m(l[2],o),O=new f(l[3],c),$=[{handler:t,id:l[0]},{handler:n,id:l[1]},{handler:r,id:l[2]},{handler:a,id:l[3]}];return{c:new ne($,{debug:s?.debug,shuffle:s?.shuffle}),p1:w,p2:b,p3:A,p4:O}},gt=(s,t)=>{let n=1;for(let i of t)i.equals(s)&&(n*=2);return n};class qt{static analyzePlayerEfficiency(t,e){let n=[];for(let i of e){let r=0,o=[];for(let a of i.effectiveTiles)o.push({tile:a.clone(),count:t.get(a)}),r+=t.get(a);n.push({sum:r,tile:i.tile,effectiveTiles:o,shanten:i.shanten})}return n}static selectMinPriority(t,e,n){I(e.length>0);let i=0,r=0;for(let o=0;o<e.length;o++){const a=qt.calcPriority(t,e[o],n);a<i&&(i=a,r=o)}return e[r]}static calcPriority(t,e,n){const i=e.tile;let r=0;if(i.t==p.Z)return r=t.get(i),(i.n==5||i.n==6||i.n==7)&&(r*=2),r*gt(i,n);{const o=t.get(i);r+=o*gt(i,n);const a=t.get(new y(i.t,i.n+1)),c=t.get(new y(i.t,i.n+2)),l=t.get(new y(i.t,i.n-1)),d=t.get(new y(i.t,i.n-2)),h=i.n-2>0?Math.min(l,d):0,u=i.n+2<=9?Math.min(a,c):0,m=i.n-1>=1&&i.n+1<=9?Math.min(a,l):0,f=Math.max(h,m),w=Math.max(m,u);return r+=o*gt(i,n),r+=h*gt(new y(i.t,i.n-2),n),r+=u*gt(new y(i.t,i.n+2),n),r+=f*gt(new y(i.t,i.n-1),n),r+=w*gt(new y(i.t,i.n+1),n),i.n==0,r}}}class Rt{static selectTile(t,e,n){I(e.length>0&&n.length>0);let i=n[0],r=Number.POSITIVE_INFINITY;for(let o of n){const a=Rt.rank(t,e,o);a<r&&(i=o,r=a)}return i}static rank(t,e,n){let i=0;const r=n.isNum()?Rt.rankN:Rt.rankZ;for(let o of e){const a=r(t,o,n);i<a&&(i=a)}return i}static rankZ(t,e,n){if(n.t!=p.Z)throw new Error(`expected TYPE.Z but ${n.toString()}`);if(t.isSafeTile(n.t,n.n,e))return 0;const i=t.get(n);return Math.min(i,3)}static rankN(t,e,n){if(!n.isNum())throw new Error(`expected TYPE.NUMBER but ${n.toString()}`);const i=n.n,r=n.t;if(t.isSafeTile(r,i,e))return 0;if(i==1)return t.isSafeTile(r,4,e)?3:6;if(i==9)return t.isSafeTile(r,6,e)?3:6;if(i==2||i==8)return t.isSafeTile(r,5,e)?4:8;if(i==3)return t.isSafeTile(r,6,e)?5:8;if(i==7)return t.isSafeTile(r,4,e)?5:8;const o=t.isSafeTile(r,i-3,e),a=t.isSafeTile(r,i+3,e);return o&&a?4:o||a?8:12}}exports.ActionLogic=Q;exports.ActorHand=Nt;exports.BLOCK=E;exports.BaseActor=gn;exports.Block=N;exports.BlockAnKan=R;exports.BlockCalculator=is;exports.BlockChi=F;exports.BlockDaiKan=K;exports.BlockHand=bt;exports.BlockIsolated=Je;exports.BlockOther=we;exports.BlockPair=C;exports.BlockPon=U;exports.BlockRun=nt;exports.BlockShoKan=M;exports.BlockThree=L;exports.Controller=ne;exports.Counter=ds;exports.Efficiency=Ht;exports.FONT_FAMILY=Ze;exports.G=T;exports.Hand=Ae;exports.INPUT_SEPARATOR=V;exports.Image=qe;exports.ImageHelper=en;exports.Mark=lt;exports.MeasureText=Ds;exports.MyG=tr;exports.MyImage=er;exports.MyRect=sr;exports.MySVG=Qi;exports.MyText=ir;exports.MyUse=nr;exports.N19=J;exports.NZ=Pt;exports.OP=g;exports.Observer=xs;exports.Parser=D;exports.PlaceManager=Xt;exports.Player=Yt;exports.PlayerEfficiency=qt;exports.PointCalculator=nn;exports.ROUND=k;exports.ROUND_MAP=Ye;exports.Rect=Qe;exports.Replayer=Qo;exports.RiskRank=Rt;exports.River=rn;exports.STICK_CONTEXT=Ce;exports.SVG=Yn;exports.ScoreManager=Jt;exports.ShantenCalculator=te;exports.Svg=Zn;exports.Symbol=tn;exports.TABLE_CONTEXT=Bn;exports.TILE_CONTEXT=rt;exports.TYPE=p;exports.Text=At;exports.Tile=y;exports.Use=_e;exports.WIND=_;exports.WIND_MAP=ye;exports.Wall=It;exports.compareCalledTiles=Wn;exports.compareTiles=Qt;exports.convertInput=ss;exports.createBlockHand=kt;exports.createControllerMachine=Ge;exports.createEventEmitter=hs;exports.createEventPipe=Zt;exports.createLocalGame=ta;exports.createTable=qn;exports.createWindMap=H;exports.deserializeWinResult=Ft;exports.drawBlocks=dr;exports.drawTable=br;exports.forHand=j;exports.getCallBlockIndex=Re;exports.getPointDescription=rs;exports.incrementalIDGenerator=Ms;exports.is5Tile=S;exports.nextRound=Vt;exports.nextWind=_t;exports.optimizeSVG=fr;exports.parse=es;exports.parseTableInput=ns;exports.prevRound=Gs;exports.prevWind=Ee;exports.prioritizeDiscardedEvents=os;exports.prioritizeDrawnEvents=as;exports.roundWind=Ln;exports.serializeWinResult=ue;exports.shuffle=sn;exports.toDora=We;
|