@konoui/mjimage 0.0.52 → 0.0.53

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 CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var Ms=Object.defineProperty;var $s=(n,t,e)=>t in n?Ms(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var _=(n,t,e)=>$s(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ze="MS Gothic, sans-serif",et={WIDTH:66,HEIGHT:90,TEXT_SCALE:.8,BLOCK_MARGIN_SCALE:.3},Se={WIDTH:125,HEIGHT:27.5},$n={BASE:40},q=",",p={M:"m",P:"p",S:"s",Z:"z",BACK:"_"},y={TSUMO:"t",RON:"v",DORA:"d",HORIZONTAL:"-",RED:"r",COLOR_GRAYSCALE:"^"},b={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"},A={E:"1w",S:"2w",W:"3w",N:"4w"},k={E1:"1w1",E2:"1w2",E3:"1w3",E4:"1w4",S1:"2w1",S2:"2w2",S3:"2w3",S4:"2w4",W1:"3w1",W2:"3w2",W3:"3w3",W4:"3w4",N1:"4w1",N2:"4w2",N3:"4w3",N4:"4w4"},ue={[A.E]:"東",[A.S]:"南",[A.W]:"西",[A.N]:"北"},je={[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 S(n,t){if(!n)throw new Error(t)}class Ps{constructor(t="東",e="2"){_(this,"ctx",null);_(this,"strText");_(this,"numText");_(this,"measure",(t,e)=>{this.ctx==null&&(this.ctx=document.createElement("canvas").getContext("2d"),S(this.ctx,"context is null"));const s=this.ctx;s.font=e;const r=s.measureText(t);let i=r.width,o=r.actualBoundingBoxAscent+r.actualBoundingBoxDescent;return[i,o]});_(this,"measureFontContext",(t,e)=>{const s={family:t,size:e},r=`${s.size}px ${s.family}`,[i,o]=this.measure(this.strText,r),[a,c]=this.measure(this.numText,r);return{font:{family:t,size:e},textWidth:i,textHeight:o,numWidth:a,numHeight:c}});_(this,"measureTableFontContext",t=>{const e=this.measureFontContext(ze,$n.BASE*t);return e.textHeight=e.textWidth,e.numHeight=e.numWidth,e});this.strText=t,this.numText=e}}class Hs{constructor(t){_(this,"input");_(this,"position");_(this,"nextPosition");_(this,"char");_(this,"eof","\0");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 Vt=(n,t)=>{if(n.t==t.t){if(C(n)&&C(t)){if(n.has(y.RED))return-1;if(t.has(y.RED))return 1}return n.n-t.n}const e={[p.M]:1,[p.P]:2,[p.S]:3,[p.Z]:4,[p.BACK]:5};return e[n.t]-e[t.t]},Ws=(n,t)=>{const e={[y.HORIZONTAL]:1,[y.TSUMO]:2,[y.RON]:3,[y.DORA]:4,[y.COLOR_GRAYSCALE]:5,[y.RED]:6};return e[n]-e[t]},Pn=n=>{const t=[];n.forEach((s,r)=>{s.has(y.HORIZONTAL)&&t.push(r)});const e=n.filter(s=>!s.has(y.HORIZONTAL)).sort(Vt);return t.forEach(s=>{e.splice(s,0,n[s])}),e};function C(n){return n.isNum()&&n.n==5}function Bs(n){for(const t of Object.values(p))if(t==n)return[t,!0];return[p.BACK,!1]}class w{constructor(t,e,s=[]){this.t=t,this.n=e,this.ops=s}static from(t){const e=new W(t).tiles();if(e.length!=1)throw new Error(`input is not a single tile ${t}`);return e[0]}toString(){return this.t===p.BACK?this.t:`${[...this.ops].sort(Ws).join("")}${this.n}${this.t}`}toJSON(){return this.toString()}clone(t){const e=(t==null?void 0:t.t)??this.t,s=(t==null?void 0:t.n)??this.n,r=t!=null&&t.removeAll?[]:this.ops.filter(o=>Array.isArray(t==null?void 0:t.remove)?!t.remove.includes(o):(t==null?void 0:t.remove)!=o),i=new Set([...r]);return t!=null&&t.add&&(Array.isArray(t.add)?t.add.forEach(o=>i.add(o)):i.add(t.add)),new w(e,s,Array.from(i))}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 T{constructor(t,e){_(this,"_tiles");_(this,"_type");if(this._tiles=t,this._type=e,this.isCalled()){this._tiles=Pn(this._tiles);return}if(this._type!=b.IMAGE_DISCARD){this._tiles=[...this._tiles].sort(Vt);return}}static from(t){const e=new W(t).parse();if(e.length!=1)throw new Error(`block must be 1: ${t}`);return e[0]}static deserialize(t){const e=T.from(t.tiles),s=e.type;if(!(t.type==b.PAIR||t.type==b.ISOLATED||t.type==b.THREE||t.type==b.RUN)&&s!=t.type)throw new Error(`input type is ${t.type} but got is ${s}: ${t.tiles}`);return se(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(){return[b.PON.toString(),b.CHI.toString(),b.DAI_KAN.toString(),b.SHO_KAN.toString(),b.AN_KAN.toString()].includes(this._type.toString())}clone(t){const e=t==null?void 0:t.replace,s=[...this.tiles];return e&&(s[e.idx]=e.tile),se(s,this._type)}}const bt=n=>{let t="";for(const e of n){if(e.t==p.BACK)return n.join("");t+=e.toString().slice(0,-1)}return`${t}${n[0].t}`},Fe=n=>{let t=n[0].t,e="";for(const r of n){const i=r.t,o=i==p.BACK?r.toString():r.toString().slice(0,-1);i!=t&&t!=p.BACK&&(e+=t),t=i,e+=o}const s=n.at(-1);return s.t!=p.BACK&&(e+=s.t),e};class Z extends T{constructor(t){super(t,b.CHI)}static from(t){return T.deserialize({tiles:t,type:b.CHI})}toString(){return bt(this.tiles)}}class V extends T{constructor(t){super(t,b.PON)}static from(t){return T.deserialize({tiles:t,type:b.PON})}toString(){return bt(this.tiles)}}class x extends T{constructor(t){const e=t.filter(r=>r.t!=p.BACK),s=e[0];if(e.length<t.length){if(C(s)){const r=new w(s.t,5);super([r.clone({add:y.RED}),r,r,r],b.AN_KAN);return}super([s,s,s,s],b.AN_KAN);return}super(t,b.AN_KAN)}get tilesWithBack(){const t=this.tiles[0].clone({remove:y.RED}),e=C(t)?t.clone({add:y.RED}):t;return[new w(p.BACK,0),e,t,new w(p.BACK,0)]}static from(t){return T.deserialize({tiles:t,type:b.AN_KAN})}toString(){return Fe(this.tilesWithBack)}}class Y extends T{constructor(t){super(t,b.DAI_KAN)}static from(t){return T.deserialize({tiles:t,type:b.DAI_KAN})}toString(){return bt(this.tiles)}}class D extends T{constructor(t){super(t,b.SHO_KAN)}static from(t){return T.deserialize({tiles:t,type:b.SHO_KAN})}static fromPon(t,e){const s=t.tiles.findIndex(i=>i.has(y.HORIZONTAL)),r=[...t.tiles];return r.splice(s,0,e.clone({add:y.HORIZONTAL})),new D(r)}toString(){return bt(this.tiles)}}class H extends T{constructor(t,e){super([t,e],b.PAIR)}toString(){return bt(this.tiles)}static from(t){return T.deserialize({tiles:t,type:b.PAIR})}}class z extends T{constructor(t){super(t,b.THREE)}static from(t){return T.deserialize({tiles:t,type:b.THREE})}toString(){return bt(this.tiles)}}class Q extends T{constructor(t){super(t,b.RUN)}static from(t){return T.deserialize({tiles:t,type:b.RUN})}toString(){return bt(this.tiles)}}class Ge extends T{constructor(t){super([t],b.ISOLATED)}static from(t){return T.deserialize({tiles:t,type:b.ISOLATED})}toString(){return this.tiles[0].toString()}}class Ot extends T{constructor(t){super(t,b.HAND)}static from(t){return T.deserialize({tiles:t,type:b.HAND})}toString(){return Fe(this.tiles)}}class Ue extends T{constructor(t,e){super(t,e)}toString(){return this.is(b.IMAGE_DISCARD)?this.tiles.join(""):Fe(this.tiles)}}const se=(n,t)=>{switch(t){case b.CHI:return new Z([n[0],n[1],n[2]]);case b.PON:return new V([n[0],n[1],n[2]]);case b.AN_KAN:return new x(n);case b.DAI_KAN:return new Y(n);case b.SHO_KAN:return new D(n);case b.THREE:return new z(n);case b.RUN:return new Q(n);case b.PAIR:return new H(n[0],n[1]);case b.ISOLATED:return new Ge(n[0]);case b.HAND:return new Ot(n);default:return new Ue(n,t)}};class W{constructor(t){_(this,"maxInputLength",600);this.input=t,this.input=t.replace(/\s/g,"")}parse(){const t=this.tileSeparators();return this.makeBlocks(t)}tiles(){return this.tileSeparators().filter(t=>t!=q)}tileSeparators(){const t=new Hs(this.input),e=[];let s=[];for(this.validate(this.input);;){t.skipWhitespace();const r=t.char;if(r===t.eof)break;if(r==q){e.push(q),t.readChar();continue}const[i,o]=gn(r,s);if(o){if(i==p.BACK){e.push(new w(i,0)),t.readChar();continue}e.push(...Ks(s,i)),s=[],t.readChar();continue}else{const[a,c]=Ls(t);if(c){s.push(a),t.readChar();continue}const[l,u]=Hn(r);if(!u)throw new Error(`encounter unexpected number. n: ${l}, current: ${r}, input: ${t.input}`);s.push({n:l})}t.readChar()}if(s.length>0)throw new Error(`remaining values ${s.toString()}`);return e}makeBlocks(t){let e=[];const s=[];if(t.length==0)return s;for(const o of t){if(o==q){const a=pn(e),c=se(e,a);s.push(c),e=[];continue}e.push(o)}const r=pn(e),i=se(e,r);return s.push(i),e=[],s}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),[s,r]=gn(e,[new w(p.BACK,1)]);if(!r)throw new Error(`last character(${e}) is not type value`)}}function pn(n){if(n.length===0)return b.UNKNOWN;if(n.length===1)return n[0].has(y.DORA)?b.IMAGE_DORA:n[0].has(y.TSUMO)?b.TSUMO:b.HAND;const t=n.every(i=>i.equals(n[0])),e=n.filter(i=>i.has(y.HORIZONTAL)).length,s=n.filter(i=>i.has(y.TSUMO)||i.has(y.DORA)).length,r=n.filter(i=>i.t==p.BACK).length;if(s>0)return b.UNKNOWN;if(e==0&&r==0)return b.HAND;if(n.length===3&&r===0)return t?b.PON:e==1&&Ds(n)?b.CHI:b.IMAGE_DISCARD;if(n.length==4&&r==2)return b.AN_KAN;if(n.length==4&&t){if(e==1)return b.DAI_KAN;if(e==2)return b.SHO_KAN}return e==1||s==0?b.IMAGE_DISCARD:b.UNKNOWN}function Ds(n){const t=[...n].sort(Vt);if(t.some(s=>t[0].t!=s.t))return!1;const e=t.map(s=>s.n);for(let s=0;s<e.length-1;s++)if(e[s]!=e[s+1]-1)return!1;return!0}function Ks(n,t){return n.map(e=>{const s=new w(t,e.n,e.ops);return s.isNum()&&s.n==0?s.clone({n:5,add:y.RED}):s})}function gn(n,t){const[e,s]=Bs(n);if(s)return[e,!0];if((n==="w"||n==="d")&&t.length>0){for(let i=0;i<t.length;i++){const o=t[i];n==="d"&&(t[i].n=o.n+4)}return[p.Z,!0]}return[p.BACK,!1]}function Hn(n){const t=Number(n),e=0<=t&&t<=9;return[t,e]}function Ls(n){const t=Object.values(y);if(!t.includes(n.char))return[new w(p.BACK,0),!1];const e=[];for(let s=0;s<4;s++){const r=n.peekCharN(s);if(t.includes(r))e.push(r);else{const[i,o]=Hn(r);if(!o)break;for(const c of e)n.readChar();const a=new w(p.BACK,i,e);if(a.has(y.RED)&&a.n!=5)throw new Error(`found ${y.RED} but number is not 5: ${i}`);if(a.has(y.DORA)&&a.has(y.TSUMO))throw new Error(`unable to specify both ${y.DORA} and ${y.TSUMO}`);return[a,!0]}}return[new w(p.BACK,0),!1]}function $(n,t=!1){const e={[A.E]:n,[A.S]:n,[A.W]:n,[A.N]:n};if(t)for(let s of Object.values(A))e[s]=structuredClone(n);return e}const Ft=n=>{let t=n.substring(0,2),e=Number(n.substring(2,3));return e==4?(e=1,t=pt(t)):e++,`${t}${e}`},zs=n=>Ft(Ft(Ft(n))),pt=n=>{let t=Number(n.toString()[0]);return t=t%4+1,`${t}w`},he=n=>{let t=Number(n.toString()[0]);return t=t%2+1,`${t}w`},ve=(n,t,e)=>{const s=Math.abs(Number(n[0])-Number(t[0]));return S(s==1||s==2||s==3),e==b.PON?s==3?0:s==2?1:2:s==3?0:s==1?3:2};function yn(n){return typeof n>"u"}function Te(n,t=0){return{a:1,c:0,e:n,b:0,d:1,f:t}}function Ze(...n){n=Array.isArray(n[0])?n[0]:n;const t=(e,s)=>({a:e.a*s.a+e.c*s.b,c:e.a*s.c+e.c*s.d,e:e.a*s.e+e.c*s.f+e.e,b:e.b*s.a+e.d*s.b,d:e.b*s.c+e.d*s.d,f:e.b*s.e+e.d*s.f+e.f});switch(n.length){case 0:throw new Error("no matrices provided");case 1:return n[0];case 2:return t(n[0],n[1]);default:{const[e,s,...r]=n,i=t(e,s);return Ze(i,...r)}}}function js(...n){return Ze(...n)}const{cos:Fs,sin:Gs,PI:Us}=Math;function Zs(n,t,e){const s=Fs(n),r=Gs(n),i={a:s,c:-r,e:0,b:r,d:s,f:0};return yn(t)||yn(e)?i:Ze([Te(t,e),i,Te(-t,-e)])}function Vs(n,t=void 0,e=void 0){return Zs(n*Us/180,t,e)}function Js(n){return Xs(n)}function Xs(n){return`matrix(${n.a},${n.b},${n.c},${n.d},${n.e},${n.f})`}function Ys(n,t){function e(){this.constructor=n}e.prototype=t.prototype,n.prototype=new e}function de(n,t,e,s){var r=Error.call(this,n);return Object.setPrototypeOf&&Object.setPrototypeOf(r,de.prototype),r.expected=t,r.found=e,r.location=s,r.name="SyntaxError",r}Ys(de,Error);function ye(n,t,e){return e=e||" ",n.length>t?n:(t-=n.length,e+=e.repeat(t),n+e.slice(0,t))}de.prototype.format=function(n){var t="Error: "+this.message;if(this.location){var e=null,s;for(s=0;s<n.length;s++)if(n[s].source===this.location.source){e=n[s].text.split(/\r\n|\n|\r/g);break}var r=this.location.start,i=this.location.source&&typeof this.location.source.offset=="function"?this.location.source.offset(r):r,o=this.location.source+":"+i.line+":"+i.column;if(e){var a=this.location.end,c=ye("",i.line.toString().length," "),l=e[r.line-1],u=r.line===a.line?a.column:l.length+1,h=u-r.column||1;t+=`
1
+ "use strict";var Ms=Object.defineProperty;var $s=(n,t,e)=>t in n?Ms(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var _=(n,t,e)=>$s(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ze="MS Gothic, sans-serif",et={WIDTH:66,HEIGHT:90,TEXT_SCALE:.8,BLOCK_MARGIN_SCALE:.3},Se={WIDTH:125,HEIGHT:27.5},$n={BASE:40},q=",",p={M:"m",P:"p",S:"s",Z:"z",BACK:"_"},y={TSUMO:"t",RON:"v",DORA:"d",HORIZONTAL:"-",RED:"r",COLOR_GRAYSCALE:"^"},b={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"},A={E:"1w",S:"2w",W:"3w",N:"4w"},k={E1:"1w1",E2:"1w2",E3:"1w3",E4:"1w4",S1:"2w1",S2:"2w2",S3:"2w3",S4:"2w4",W1:"3w1",W2:"3w2",W3:"3w3",W4:"3w4",N1:"4w1",N2:"4w2",N3:"4w3",N4:"4w4"},ue={[A.E]:"東",[A.S]:"南",[A.W]:"西",[A.N]:"北"},je={[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 S(n,t){if(!n)throw new Error(t)}class Ps{constructor(t="東",e="2"){_(this,"ctx",null);_(this,"strText");_(this,"numText");_(this,"measure",(t,e)=>{this.ctx==null&&(this.ctx=document.createElement("canvas").getContext("2d"),S(this.ctx,"context is null"));const s=this.ctx;s.font=e;const r=s.measureText(t);let i=r.width,o=r.actualBoundingBoxAscent+r.actualBoundingBoxDescent;return[i,o]});_(this,"measureFontContext",(t,e)=>{const s={family:t,size:e},r=`${s.size}px ${s.family}`,[i,o]=this.measure(this.strText,r),[a,c]=this.measure(this.numText,r);return{font:{family:t,size:e},textWidth:i,textHeight:o,numWidth:a,numHeight:c}});_(this,"measureTableFontContext",t=>{const e=this.measureFontContext(ze,$n.BASE*t);return e.textHeight=e.textWidth,e.numHeight=e.numWidth,e});this.strText=t,this.numText=e}}class Hs{constructor(t){_(this,"input");_(this,"position");_(this,"nextPosition");_(this,"char");_(this,"eof","\0");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 Vt=(n,t)=>{if(n.t==t.t){if(C(n)&&C(t)){if(n.has(y.RED))return-1;if(t.has(y.RED))return 1}return n.n-t.n}const e={[p.M]:1,[p.P]:2,[p.S]:3,[p.Z]:4,[p.BACK]:5};return e[n.t]-e[t.t]},Ws=(n,t)=>{const e={[y.HORIZONTAL]:1,[y.TSUMO]:2,[y.RON]:3,[y.DORA]:4,[y.COLOR_GRAYSCALE]:5,[y.RED]:6};return e[n]-e[t]},Pn=n=>{const t=[];n.forEach((s,r)=>{s.has(y.HORIZONTAL)&&t.push(r)});const e=n.filter(s=>!s.has(y.HORIZONTAL)).sort(Vt);return t.forEach(s=>{e.splice(s,0,n[s])}),e};function C(n){return n.isNum()&&n.n==5}function Bs(n){for(const t of Object.values(p))if(t==n)return[t,!0];return[p.BACK,!1]}class w{constructor(t,e,s=[]){this.t=t,this.n=e,this.ops=s}static from(t){const e=new W(t).tiles();if(e.length!=1)throw new Error(`input is not a single tile ${t}`);return e[0]}toString(){return this.t===p.BACK?this.t:`${[...this.ops].sort(Ws).join("")}${this.n}${this.t}`}toJSON(){return this.toString()}clone(t){const e=(t==null?void 0:t.t)??this.t,s=(t==null?void 0:t.n)??this.n,r=t!=null&&t.removeAll?[]:this.ops.filter(o=>Array.isArray(t==null?void 0:t.remove)?!t.remove.includes(o):(t==null?void 0:t.remove)!=o),i=new Set([...r]);return t!=null&&t.add&&(Array.isArray(t.add)?t.add.forEach(o=>i.add(o)):i.add(t.add)),new w(e,s,Array.from(i))}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 T{constructor(t,e){_(this,"_tiles");_(this,"_type");if(this._tiles=t,this._type=e,this.isCalled()){this._tiles=Pn(this._tiles);return}if(this._type!=b.IMAGE_DISCARD){this._tiles=[...this._tiles].sort(Vt);return}}static from(t){const e=new W(t).parse();if(e.length!=1)throw new Error(`block must be 1: ${t}`);return e[0]}static deserialize(t){const e=T.from(t.tiles),s=e.type;if(!(t.type==b.PAIR||t.type==b.ISOLATED||t.type==b.THREE||t.type==b.RUN)&&s!=t.type)throw new Error(`input type is ${t.type} but got is ${s}: ${t.tiles}`);return se(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(){return[b.PON.toString(),b.CHI.toString(),b.DAI_KAN.toString(),b.SHO_KAN.toString(),b.AN_KAN.toString()].includes(this._type.toString())}clone(t){const e=t==null?void 0:t.replace,s=[...this.tiles];return e&&(s[e.idx]=e.tile),se(s,this._type)}}const bt=n=>{let t="";for(const e of n){if(e.t==p.BACK)return n.join("");t+=e.toString().slice(0,-1)}return`${t}${n[0].t}`},Fe=n=>{let t=n[0].t,e="";for(const r of n){const i=r.t,o=i==p.BACK?r.toString():r.toString().slice(0,-1);i!=t&&t!=p.BACK&&(e+=t),t=i,e+=o}const s=n.at(-1);return s.t!=p.BACK&&(e+=s.t),e};class Z extends T{constructor(t){super(t,b.CHI)}static from(t){return T.deserialize({tiles:t,type:b.CHI})}toString(){return bt(this.tiles)}}class V extends T{constructor(t){super(t,b.PON)}static from(t){return T.deserialize({tiles:t,type:b.PON})}toString(){return bt(this.tiles)}}class x extends T{constructor(t){const e=t.filter(r=>r.t!=p.BACK),s=e[0];if(e.length<t.length){if(C(s)){const r=new w(s.t,5);super([r.clone({add:y.RED}),r,r,r],b.AN_KAN);return}super([s,s,s,s],b.AN_KAN);return}super(t,b.AN_KAN)}get tilesWithBack(){const t=this.tiles[0].clone({remove:y.RED}),e=C(t)?t.clone({add:y.RED}):t;return[new w(p.BACK,0),e,t,new w(p.BACK,0)]}static from(t){return T.deserialize({tiles:t,type:b.AN_KAN})}toString(){return Fe(this.tilesWithBack)}}class Y extends T{constructor(t){super(t,b.DAI_KAN)}static from(t){return T.deserialize({tiles:t,type:b.DAI_KAN})}toString(){return bt(this.tiles)}}class D extends T{constructor(t){super(t,b.SHO_KAN)}static from(t){return T.deserialize({tiles:t,type:b.SHO_KAN})}static fromPon(t,e){const s=t.tiles.findIndex(i=>i.has(y.HORIZONTAL)),r=[...t.tiles];return r.splice(s,0,e.clone({add:y.HORIZONTAL})),new D(r)}toString(){return bt(this.tiles)}}class H extends T{constructor(t,e){super([t,e],b.PAIR)}toString(){return bt(this.tiles)}static from(t){return T.deserialize({tiles:t,type:b.PAIR})}}class z extends T{constructor(t){super(t,b.THREE)}static from(t){return T.deserialize({tiles:t,type:b.THREE})}toString(){return bt(this.tiles)}}class Q extends T{constructor(t){super(t,b.RUN)}static from(t){return T.deserialize({tiles:t,type:b.RUN})}toString(){return bt(this.tiles)}}class Ge extends T{constructor(t){super([t],b.ISOLATED)}static from(t){return T.deserialize({tiles:t,type:b.ISOLATED})}toString(){return this.tiles[0].toString()}}class Ot extends T{constructor(t){super(t,b.HAND)}static from(t){return T.deserialize({tiles:t,type:b.HAND})}toString(){return Fe(this.tiles)}}class Ue extends T{constructor(t,e){super(t,e)}toString(){return this.is(b.IMAGE_DISCARD)?this.tiles.join(""):Fe(this.tiles)}}const se=(n,t)=>{switch(t){case b.CHI:return new Z([n[0],n[1],n[2]]);case b.PON:return new V([n[0],n[1],n[2]]);case b.AN_KAN:return new x(n);case b.DAI_KAN:return new Y(n);case b.SHO_KAN:return new D(n);case b.THREE:return new z(n);case b.RUN:return new Q(n);case b.PAIR:return new H(n[0],n[1]);case b.ISOLATED:return new Ge(n[0]);case b.HAND:return new Ot(n);default:return new Ue(n,t)}};class W{constructor(t){_(this,"maxInputLength",600);this.input=t,this.input=t.replace(/\s/g,"")}parse(){const t=this.tileSeparators();return this.makeBlocks(t)}tiles(){return this.tileSeparators().filter(t=>t!=q)}tileSeparators(){const t=new Hs(this.input),e=[];let s=[];for(this.validate(this.input);;){t.skipWhitespace();const r=t.char;if(r===t.eof)break;if(r==q){e.push(q),t.readChar();continue}const[i,o]=gn(r,s);if(o){if(i==p.BACK){e.push(new w(i,0)),t.readChar();continue}e.push(...Ks(s,i)),s=[],t.readChar();continue}else{const[a,c]=Ls(t);if(c){s.push(a),t.readChar();continue}const[l,u]=Hn(r);if(!u)throw new Error(`encounter unexpected number. n: ${l}, current: ${r}, input: ${t.input}`);s.push({n:l})}t.readChar()}if(s.length>0)throw new Error(`remaining values ${s.toString()}`);return e}makeBlocks(t){let e=[];const s=[];if(t.length==0)return s;for(const o of t){if(o==q){const a=pn(e),c=se(e,a);s.push(c),e=[];continue}e.push(o)}const r=pn(e),i=se(e,r);return s.push(i),e=[],s}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),[s,r]=gn(e,[new w(p.BACK,1)]);if(!r)throw new Error(`last character(${e}) is not type value`)}}function pn(n){if(n.length===0)return b.UNKNOWN;if(n.length===1)return n[0].has(y.DORA)?b.IMAGE_DORA:n[0].has(y.TSUMO)?b.TSUMO:b.HAND;const t=n.every(i=>i.equals(n[0])),e=n.filter(i=>i.has(y.HORIZONTAL)).length,s=n.filter(i=>i.has(y.TSUMO)||i.has(y.DORA)).length,r=n.filter(i=>i.t==p.BACK).length;if(s>0)return b.UNKNOWN;if(e==0&&r==0)return b.HAND;if(n.length===3&&r===0)return t?b.PON:e==1&&Ds(n)?b.CHI:b.IMAGE_DISCARD;if(n.length==4&&r==2)return b.AN_KAN;if(n.length==4&&t){if(e==1)return b.DAI_KAN;if(e==2)return b.SHO_KAN}return e==1||s==0?b.IMAGE_DISCARD:b.UNKNOWN}function Ds(n){const t=[...n].sort(Vt);if(t.some(s=>t[0].t!=s.t))return!1;const e=t.map(s=>s.n);for(let s=0;s<e.length-1;s++)if(e[s]!=e[s+1]-1)return!1;return!0}function Ks(n,t){return n.map(e=>{const s=new w(t,e.n,e.ops);return s.isNum()&&s.n==0?s.clone({n:5,add:y.RED}):s})}function gn(n,t){const[e,s]=Bs(n);if(s)return[e,!0];if((n==="w"||n==="d")&&t.length>0){for(let i=0;i<t.length;i++){const o=t[i];n==="d"&&(t[i].n=o.n+4)}return[p.Z,!0]}return[p.BACK,!1]}function Hn(n){const t=Number(n),e=0<=t&&t<=9;return[t,e]}function Ls(n){const t=Object.values(y);if(!t.includes(n.char))return[new w(p.BACK,0),!1];const e=[];for(let s=0;s<4;s++){const r=n.peekCharN(s);if(t.includes(r))e.push(r);else{const[i,o]=Hn(r);if(!o)break;for(const c of e)n.readChar();const a=new w(p.BACK,i,e);if(a.has(y.RED)&&a.n!=5)throw new Error(`found ${y.RED} but number is not 5: ${i}`);if(a.has(y.DORA)&&a.has(y.TSUMO))throw new Error(`unable to specify both ${y.DORA} and ${y.TSUMO}`);return[a,!0]}}return[new w(p.BACK,0),!1]}function $(n,t=!1){const e={[A.E]:n,[A.S]:n,[A.W]:n,[A.N]:n};if(t)for(let s of Object.values(A))e[s]=structuredClone(n);return e}const Ft=n=>{let t=n.substring(0,2),e=Number(n.substring(2,3));return e==4?(e=1,t=pt(t)):e++,`${t}${e}`},zs=n=>Ft(Ft(Ft(n))),pt=n=>{let t=Number(n.toString()[0]);return t=t%4+1,`${t}w`},he=n=>{let t=Number(n.toString()[0]);const e=[1,4,3,2],s=e.indexOf(t);return`${e[(s+1)%e.length]}w`},ve=(n,t,e)=>{const s=Math.abs(Number(n[0])-Number(t[0]));return S(s==1||s==2||s==3),e==b.PON?s==3?0:s==2?1:2:s==3?0:s==1?3:2};function yn(n){return typeof n>"u"}function Te(n,t=0){return{a:1,c:0,e:n,b:0,d:1,f:t}}function Ze(...n){n=Array.isArray(n[0])?n[0]:n;const t=(e,s)=>({a:e.a*s.a+e.c*s.b,c:e.a*s.c+e.c*s.d,e:e.a*s.e+e.c*s.f+e.e,b:e.b*s.a+e.d*s.b,d:e.b*s.c+e.d*s.d,f:e.b*s.e+e.d*s.f+e.f});switch(n.length){case 0:throw new Error("no matrices provided");case 1:return n[0];case 2:return t(n[0],n[1]);default:{const[e,s,...r]=n,i=t(e,s);return Ze(i,...r)}}}function js(...n){return Ze(...n)}const{cos:Fs,sin:Gs,PI:Us}=Math;function Zs(n,t,e){const s=Fs(n),r=Gs(n),i={a:s,c:-r,e:0,b:r,d:s,f:0};return yn(t)||yn(e)?i:Ze([Te(t,e),i,Te(-t,-e)])}function Vs(n,t=void 0,e=void 0){return Zs(n*Us/180,t,e)}function Js(n){return Xs(n)}function Xs(n){return`matrix(${n.a},${n.b},${n.c},${n.d},${n.e},${n.f})`}function Ys(n,t){function e(){this.constructor=n}e.prototype=t.prototype,n.prototype=new e}function de(n,t,e,s){var r=Error.call(this,n);return Object.setPrototypeOf&&Object.setPrototypeOf(r,de.prototype),r.expected=t,r.found=e,r.location=s,r.name="SyntaxError",r}Ys(de,Error);function ye(n,t,e){return e=e||" ",n.length>t?n:(t-=n.length,e+=e.repeat(t),n+e.slice(0,t))}de.prototype.format=function(n){var t="Error: "+this.message;if(this.location){var e=null,s;for(s=0;s<n.length;s++)if(n[s].source===this.location.source){e=n[s].text.split(/\r\n|\n|\r/g);break}var r=this.location.start,i=this.location.source&&typeof this.location.source.offset=="function"?this.location.source.offset(r):r,o=this.location.source+":"+i.line+":"+i.column;if(e){var a=this.location.end,c=ye("",i.line.toString().length," "),l=e[r.line-1],u=r.line===a.line?a.column:l.length+1,h=u-r.column||1;t+=`
2
2
  --> `+o+`
3
3
  `+c+` |
4
4
  `+i.line+" | "+l+`
package/dist/index.js CHANGED
@@ -630,7 +630,8 @@ const Jt = (n) => {
630
630
  return t = t % 4 + 1, `${t}w`;
631
631
  }, Pe = (n) => {
632
632
  let t = Number(n.toString()[0]);
633
- return t = t % 2 + 1, `${t}w`;
633
+ const e = [1, 4, 3, 2], s = e.indexOf(t);
634
+ return `${e[(s + 1) % e.length]}w`;
634
635
  }, en = (n, t, e) => {
635
636
  const s = Math.abs(Number(n[0]) - Number(t[0]));
636
637
  return S(s == 1 || s == 2 || s == 3), e == b.PON ? s == 3 ? 0 : s == 2 ? 1 : 2 : s == 3 ? 0 : s == 1 ? 3 : 2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konoui/mjimage",
3
- "version": "0.0.52",
3
+ "version": "0.0.53",
4
4
  "description": "Generates Mahjong tiles in SVG format.",
5
5
  "author": "konoui",
6
6
  "license": "MIT",