{"version":3,"file":"./lib/fxp.min.js","mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,GACe,iBAAZC,QACdA,QAAa,IAAID,IAEjBD,EAAU,IAAIC,GACf,CATD,CASGK,KAAM,I,mBCRT,IAAIC,EAAsB,CCA1BA,EAAwB,CAACL,EAASM,KACjC,IAAI,IAAIC,KAAOD,EACXD,EAAoBG,EAAEF,EAAYC,KAASF,EAAoBG,EAAER,EAASO,IAC5EE,OAAOC,eAAeV,EAASO,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,MCJ3EF,EAAwB,CAACQ,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFT,EAAyBL,IACH,oBAAXkB,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAeV,EAASkB,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAeV,EAAS,aAAc,CAAEoB,OAAO,M,4ECHvD,IAAMC,EAAgB,gLAGhBC,EAAY,IAAIC,OAAO,KADGF,EAAgB,KAD/BA,EAEY,mDAkBhBG,EAAS,SAAUC,GAE9B,QAAQ,MADMH,EAAUI,KAAKD,GAE/B,EAqBaE,EAA2B,CAItC,iBACA,WACA,UACA,mBACA,mBACA,mBACA,oBAGWC,EAAqB,CAAC,YAAa,cAAe,aCxDzDC,EAAiB,CACrBC,wBAAwB,EACxBC,aAAc,IAIT,SAASC,EAASC,EAASC,GAChCA,EAAUzB,OAAO0B,OAAO,CAAC,EAAGN,EAAgBK,GAK5C,IAAME,EAAO,GACTC,GAAW,EAGXC,GAAc,EAEC,WAAfL,EAAQ,KAEVA,EAAUA,EAAQM,OAAO,IAG3B,IAAK,IAAIC,EAAI,EAAGA,EAAIP,EAAQQ,OAAQD,IAElC,GAAmB,MAAfP,EAAQO,IAAiC,MAAnBP,EAAQO,EAAI,IAGpC,IADAA,EAAIE,EAAOT,EADXO,GAAK,IAECG,IAAK,OAAOH,MACb,IAAmB,MAAfP,EAAQO,GA0IZ,CACL,GAAII,EAAaX,EAAQO,IACvB,SAEF,OAAOK,EAAe,cAAe,SAAWZ,EAAQO,GAAK,qBAAsBM,EAAyBb,EAASO,GACvH,CA5IE,IAAIO,EAAcP,EAGlB,GAAmB,MAAfP,IAFJO,GAEwB,CACtBA,EAAIQ,EAAoBf,EAASO,GACjC,QACF,CACE,IAAIS,GAAa,EACE,MAAfhB,EAAQO,KAEVS,GAAa,EACbT,KAIF,IADA,IAAIU,EAAU,GACPV,EAAIP,EAAQQ,QACF,MAAfR,EAAQO,IACO,MAAfP,EAAQO,IACO,OAAfP,EAAQO,IACO,OAAfP,EAAQO,IACO,OAAfP,EAAQO,GAAaA,IAErBU,GAAWjB,EAAQO,GAWrB,GANoC,OAHpCU,EAAUA,EAAQC,QAGND,EAAQT,OAAS,KAE3BS,EAAUA,EAAQE,UAAU,EAAGF,EAAQT,OAAS,GAEhDD,MAEGa,EAAgBH,GAOnB,OAAOL,EAAe,aALQ,IAA1BK,EAAQC,OAAOV,OACX,2BAEA,QAAUS,EAAU,wBAEaJ,EAAyBb,EAASO,IAG7E,IAAMc,EAASC,EAAiBtB,EAASO,GACzC,IAAe,IAAXc,EACF,OAAOT,EAAe,cAAe,mBAAqBK,EAAU,qBAAsBJ,EAAyBb,EAASO,IAE9H,IAAIgB,EAAUF,EAAOlC,MAGrB,GAFAoB,EAAIc,EAAOG,MAEyB,MAAhCD,EAAQA,EAAQf,OAAS,GAAY,CAEvC,IAAMiB,EAAelB,EAAIgB,EAAQf,OAE3BkB,EAAUC,EADhBJ,EAAUA,EAAQJ,UAAU,EAAGI,EAAQf,OAAS,GACCP,GACjD,IAAgB,IAAZyB,EAOF,OAAOd,EAAec,EAAQhB,IAAIkB,KAAMF,EAAQhB,IAAImB,IAAKhB,EAAyBb,EAASyB,EAAeC,EAAQhB,IAAIoB,OANtH1B,GAAW,CAQf,MAAO,GAAIY,EAAY,CACrB,IAAKK,EAAOU,UACV,OAAOnB,EAAe,aAAc,gBAAkBK,EAAU,iCAAkCJ,EAAyBb,EAASO,IAC/H,GAAIgB,EAAQL,OAAOV,OAAS,EACjC,OAAOI,EAAe,aAAc,gBAAkBK,EAAU,+CAAgDJ,EAAyBb,EAASc,IAC7I,GAAoB,IAAhBX,EAAKK,OACd,OAAOI,EAAe,aAAc,gBAAkBK,EAAU,yBAA0BJ,EAAyBb,EAASc,IAE5H,IAAMkB,EAAM7B,EAAK8B,MACjB,GAAIhB,IAAYe,EAAIf,QAAS,CAC3B,IAAIiB,EAAUrB,EAAyBb,EAASgC,EAAIlB,aACpD,OAAOF,EAAe,aACpB,yBAA2BoB,EAAIf,QAAU,qBAAuBiB,EAAQJ,KAAO,SAAWI,EAAQC,IAAM,6BAA+BlB,EAAU,KACjJJ,EAAyBb,EAASc,GACtC,CAGmB,GAAfX,EAAKK,SACPH,GAAc,EAGpB,KAAO,CACL,IAAMqB,EAAUC,EAAwBJ,EAAStB,GACjD,IAAgB,IAAZyB,EAIF,OAAOd,EAAec,EAAQhB,IAAIkB,KAAMF,EAAQhB,IAAImB,IAAKhB,EAAyBb,EAASO,EAAIgB,EAAQf,OAASkB,EAAQhB,IAAIoB,OAI9H,IAAoB,IAAhBzB,EACF,OAAOO,EAAe,aAAc,sCAAuCC,EAAyBb,EAASO,KACzD,IAA3CN,EAAQH,aAAasC,QAAQnB,IAGtCd,EAAKkC,KAAK,CAAEpB,QAAAA,EAASH,YAAAA,IAEvBV,GAAW,CACb,CAIA,IAAKG,IAAKA,EAAIP,EAAQQ,OAAQD,IAC5B,GAAmB,MAAfP,EAAQO,GAAY,CACtB,GAAuB,MAAnBP,EAAQO,EAAI,GAAY,CAG1BA,EAAIQ,EAAoBf,IADxBO,GAEA,QACF,CAAO,GAAuB,MAAnBP,EAAQO,EAAI,GAIrB,MAFA,IADAA,EAAIE,EAAOT,IAAWO,IAChBG,IAAK,OAAOH,CAItB,MAAO,GAAmB,MAAfP,EAAQO,GAAY,CAC7B,IAAM+B,EAAWC,EAAkBvC,EAASO,GAC5C,IAAiB,GAAb+B,EACF,OAAO1B,EAAe,cAAe,4BAA6BC,EAAyBb,EAASO,IACtGA,EAAI+B,CACN,MACE,IAAoB,IAAhBjC,IAAyBM,EAAaX,EAAQO,IAChD,OAAOK,EAAe,aAAc,wBAAyBC,EAAyBb,EAASO,IAIlF,MAAfP,EAAQO,IACVA,GAQN,CAGF,OAAKH,EAEqB,GAAfD,EAAKK,OACPI,EAAe,aAAc,iBAAmBT,EAAK,GAAGc,QAAU,KAAMJ,EAAyBb,EAASG,EAAK,GAAGW,gBAChHX,EAAKK,OAAS,IAChBI,EAAe,aAAc,YAClC4B,KAAKC,UAAUtC,EAAKuC,IAAI,SAAAC,GAAC,OAAIA,EAAE1B,OAAO,GAAG,KAAM,GAAG2B,QAAQ,SAAU,IACpE,WAAY,CAAEd,KAAM,EAAGK,IAAK,IANvBvB,EAAe,aAAc,sBAAuB,EAU/D,CAEA,SAASD,EAAakC,GACpB,MAAgB,MAATA,GAAyB,OAATA,GAA0B,OAATA,GAA0B,OAATA,CAC3D,CAMA,SAASpC,EAAOT,EAASO,GAEvB,IADA,IAAMuC,EAAQvC,EACPA,EAAIP,EAAQQ,OAAQD,IACzB,GAAkB,KAAdP,EAAQO,IAA2B,KAAdP,EAAQO,QAAjC,CAEE,IAAMwC,EAAU/C,EAAQM,OAAOwC,EAAOvC,EAAIuC,GAC1C,GAAIvC,EAAI,GAAiB,QAAZwC,EACX,OAAOnC,EAAe,aAAc,6DAA8DC,EAAyBb,EAASO,IAC/H,GAAkB,KAAdP,EAAQO,IAA+B,KAAlBP,EAAQO,EAAI,GAAW,CAErDA,IACA,KACF,CAGF,CAEF,OAAOA,CACT,CAEA,SAASQ,EAAoBf,EAASO,GACpC,GAAIP,EAAQQ,OAASD,EAAI,GAAwB,MAAnBP,EAAQO,EAAI,IAAiC,MAAnBP,EAAQO,EAAI,IAElE,IAAKA,GAAK,EAAGA,EAAIP,EAAQQ,OAAQD,IAC/B,GAAmB,MAAfP,EAAQO,IAAiC,MAAnBP,EAAQO,EAAI,IAAiC,MAAnBP,EAAQO,EAAI,GAAY,CAC1EA,GAAK,EACL,KACF,OAEG,GACLP,EAAQQ,OAASD,EAAI,GACF,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,GACZ,CACA,IAAIyC,EAAqB,EACzB,IAAKzC,GAAK,EAAGA,EAAIP,EAAQQ,OAAQD,IAC/B,GAAmB,MAAfP,EAAQO,GACVyC,SACK,GAAmB,MAAfhD,EAAQO,IAEU,MAD3ByC,EAEE,KAIR,MAAO,GACLhD,EAAQQ,OAASD,EAAI,GACF,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,GAEZ,IAAKA,GAAK,EAAGA,EAAIP,EAAQQ,OAAQD,IAC/B,GAAmB,MAAfP,EAAQO,IAAiC,MAAnBP,EAAQO,EAAI,IAAiC,MAAnBP,EAAQO,EAAI,GAAY,CAC1EA,GAAK,EACL,KACF,CAIJ,OAAOA,CACT,CAEA,IAAM0C,EAAc,IACdC,EAAc,IAOpB,SAAS5B,EAAiBtB,EAASO,GAIjC,IAHA,IAAIgB,EAAU,GACV4B,EAAY,GACZpB,GAAY,EACTxB,EAAIP,EAAQQ,OAAQD,IAAK,CAC9B,GAAIP,EAAQO,KAAO0C,GAAejD,EAAQO,KAAO2C,EAC7B,KAAdC,EACFA,EAAYnD,EAAQO,GACX4C,IAAcnD,EAAQO,KAG/B4C,EAAY,SAET,GAAmB,MAAfnD,EAAQO,IACC,KAAd4C,EAAkB,CACpBpB,GAAY,EACZ,KACF,CAEFR,GAAWvB,EAAQO,EACrB,CACA,MAAkB,KAAd4C,GAIG,CACLhE,MAAOoC,EACPC,MAAOjB,EACPwB,UAAWA,EAEf,CAsGA,SAASJ,EAAwBJ,EAAStB,GAQxC,IAHA,IAAMmD,EAzER,SAA6B7B,GAK3B,IAJA,IAAM8B,EAAS,GACTC,EAAM/B,EAAQf,OAChBD,EAAI,EAEDA,EAAI+C,GAAK,CAId,IAHA,IAAMC,EAAahD,EAGZA,EAAI+C,GAAO3C,EAAaY,EAAQhB,KAAKA,IAC5C,GAAIA,GAAK+C,EAAK,MAEd,GAAmB,MAAf/B,EAAQhB,GAAZ,CAWA,IAJA,IAAMiD,EAAYjC,EAAQkC,MAAMF,EAAYhD,GAGtCmD,EAAYnD,EACXA,EAAI+C,IAAQ3C,EAAaY,EAAQhB,KAAsB,MAAfgB,EAAQhB,IAAYA,IAMnE,IALA,IAAMoD,EAAOpC,EAAQkC,MAAMC,EAAWnD,GAGlCqD,OAAW,EACXC,EAAItD,EACDsD,EAAIP,GAAO3C,EAAaY,EAAQsC,KAAKA,IACxCA,EAAIP,GAAsB,MAAf/B,EAAQsC,KACrBD,EAAcrC,EAAQkC,MAAMlD,EAAGsD,EAAI,GACnCtD,EAAIsD,EAAI,GAOV,IAHA,IAAIC,OAAS,EACT3E,OAAK,EACL4E,EAAIxD,EACDwD,EAAIT,GAAO3C,EAAaY,EAAQwC,KAAKA,IAC5C,GAAIA,EAAIT,IAAuB,MAAf/B,EAAQwC,IAA6B,MAAfxC,EAAQwC,IAAa,CACzD,IAAMC,EAAaD,EAAI,EACjBE,EAAW1C,EAAQa,QAAQb,EAAQwC,GAAIC,IAC3B,IAAdC,IACFH,EAAYvC,EAAQwC,GACpB5E,EAAQoC,EAAQkC,MAAMO,EAAYC,GAClC1D,EAAI0D,EAAW,EAKnB,CAEA,IAAMC,EAAQ,CAAEC,WAAYZ,GAC5BW,EAAM,GAAKV,EACXU,EAAM,GAAKP,EACXO,EAAM,GAAKN,EACXM,EAAM,QAAmBE,IAAdN,QAAiCM,EAC5CF,EAAM,GAAKJ,EACXI,EAAM,GAAK/E,EACXkE,EAAOhB,KAAK6B,EA3CZ,MAFE3D,EAAIgD,EAAa,CA8CrB,CAEA,OAAOF,CACT,CASkBgB,CAAoB9C,GAC9B+C,EAAY,CAAC,EAEV/D,EAAI,EAAGA,EAAI6C,EAAQ5C,OAAQD,IAAK,CACvC,GAA6B,IAAzB6C,EAAQ7C,GAAG,GAAGC,OAEhB,OAAOI,EAAe,cAAe,cAAgBwC,EAAQ7C,GAAG,GAAK,8BAA+BgE,EAAqBnB,EAAQ7C,KAC5H,QAAsB6D,IAAlBhB,EAAQ7C,GAAG,SAAsC6D,IAAlBhB,EAAQ7C,GAAG,GACnD,OAAOK,EAAe,cAAe,cAAgBwC,EAAQ7C,GAAG,GAAK,sBAAuBgE,EAAqBnB,EAAQ7C,KACpH,QAAsB6D,IAAlBhB,EAAQ7C,GAAG,KAAqBN,EAAQJ,uBAEjD,OAAOe,EAAe,cAAe,sBAAwBwC,EAAQ7C,GAAG,GAAK,oBAAqBgE,EAAqBnB,EAAQ7C,KAKjI,IAAMiE,EAAWpB,EAAQ7C,GAAG,GAC5B,IAAKkE,EAAiBD,GACpB,OAAO5D,EAAe,cAAe,cAAgB4D,EAAW,wBAAyBD,EAAqBnB,EAAQ7C,KAExH,GAAK/B,OAAOM,UAAUC,eAAeC,KAAKsF,EAAWE,GAInD,OAAO5D,EAAe,cAAe,cAAgB4D,EAAW,iBAAkBD,EAAqBnB,EAAQ7C,KAF/G+D,EAAUE,GAAY,CAI1B,CAEA,OAAO,CACT,CAiBA,SAASjC,EAAkBvC,EAASO,GAGlC,GAAmB,MAAfP,IADJO,GAEE,OAAQ,EACV,GAAmB,MAAfP,EAAQO,GAEV,OAtBJ,SAAiCP,EAASO,GACxC,IAAImE,EAAK,KAKT,IAJmB,MAAf1E,EAAQO,KACVA,IACAmE,EAAK,cAEAnE,EAAIP,EAAQQ,OAAQD,IAAK,CAC9B,GAAmB,MAAfP,EAAQO,GACV,OAAOA,EACT,IAAKP,EAAQO,GAAGoE,MAAMD,GACpB,KACJ,CACA,OAAQ,CACV,CASWE,CAAwB5E,IAD/BO,GAIF,IADA,IAAIsE,EAAQ,EACLtE,EAAIP,EAAQQ,OAAQD,IAAKsE,IAC9B,KAAI7E,EAAQO,GAAGoE,MAAM,OAASE,EAAQ,IAAtC,CAEA,GAAmB,MAAf7E,EAAQO,GACV,MACF,OAAQ,CAHE,CAKZ,OAAOA,CACT,CAEA,SAASK,EAAegB,EAAMkD,EAASC,GACrC,MAAO,CACLrE,IAAK,CACHkB,KAAMA,EACNC,IAAKiD,EACLhD,KAAMiD,EAAWjD,MAAQiD,EACzB5C,IAAK4C,EAAW5C,KAGtB,CAEA,SAASsC,EAAiBD,GACxB,OAAOjF,EAAOiF,EAChB,CAIA,SAASpD,EAAgB2B,GACvB,OAAOxD,EAAOwD,EAChB,CAGA,SAASlC,EAAyBb,EAASwB,GACzC,IAAMwD,EAAQhF,EAAQmB,UAAU,EAAGK,GAAOyD,MAAM,SAChD,MAAO,CACLnD,KAAMkD,EAAMxE,OAGZ2B,IAAK6C,EAAMA,EAAMxE,OAAS,GAAGA,OAAS,EAE1C,CAGA,SAAS+D,EAAqBI,GAC5B,OAAOA,EAAMR,WAAaQ,EAAM,GAAGnE,MACrC,CClgBA,IAAM0E,EAA6B,SAACvB,GAClC,OAAIjE,EAAyByF,SAASxB,GAC7B,KAAOA,EAETA,CACT,EAGa/D,EAAiB,CAC5BwF,eAAe,EACfC,oBAAqB,KACrBC,qBAAqB,EACrBC,aAAc,QACdC,kBAAkB,EAClBC,gBAAgB,EAChB5F,wBAAwB,EAExB6F,eAAe,EACfC,qBAAqB,EACrBC,YAAY,EACZC,eAAe,EACfC,mBAAoB,CAClBC,KAAK,EACLC,cAAc,EACdC,WAAW,EACXC,SAAS,GAEXC,kBAAmB,SAAUlF,EAASmF,GACpC,OAAOA,CACT,EACAC,wBAAyB,SAAU7B,EAAU4B,GAC3C,OAAOA,CACT,EACAE,UAAW,GACXC,sBAAsB,EACtBC,QAAS,WAAF,OAAQ,CAAK,EACpBC,iBAAiB,EACjB3G,aAAc,GACd4G,iBAAiB,EACjBC,cAAc,EACdC,cAAe,KACfC,mBAAmB,EACnBC,cAAc,EACdC,kBAAkB,EAClBC,wBAAwB,EACxBC,UAAW,SAAUhG,EAASiG,EAAOC,GACnC,OAAOlG,CACT,EAEAmG,iBAAiB,EACjBC,cAAe,IACfC,qBAAqB,EACrBJ,OAAO,EACPK,oBAAqBrC,GAUvB,SAASsC,EAAqBC,EAAcC,GAC1C,GAA4B,iBAAjBD,EAAX,CAIA,IAAME,EAAaF,EAAaG,cAChC,GAAIlI,EAAyBmI,KAAK,SAAAC,GAAS,OAAIH,IAAeG,EAAUF,aAAa,GACnF,MAAM,IAAIG,MAAM,sBACQL,EAAU,MAAMD,EAAY,2EAItD,GAAI9H,EAAmBkI,KAAK,SAAAC,GAAS,OAAIH,IAAeG,EAAUF,aAAa,GAC7E,MAAM,IAAIG,MAAM,sBACQL,EAAU,MAAMD,EAAY,0EAXtD,CAcF,CAOA,SAASO,EAAyB7I,EAAOwH,GAEvC,MAAqB,kBAAVxH,EACF,CACL8I,QAAS9I,EACT+I,cAAe,IACfC,kBAAmB,IACnBC,mBAAoBC,IACpBC,kBAAmB,IACnBC,eAAgB,IAChBC,YAAa,KACbC,UAAW,KACXC,UAAW,OAKM,iBAAVvJ,GAAgC,OAAVA,EACxB,CACL8I,SAA2B,IAAlB9I,EAAM8I,QACfC,cAAeS,KAAKC,IAAI,EAAsB,OAArBC,EAAE1J,EAAM+I,eAAaW,EAAI,KAClDV,kBAAmBQ,KAAKC,IAAI,EAA0B,OAAzBE,EAAE3J,EAAMgJ,mBAAiBW,EAAI,KAC1DV,mBAAoBO,KAAKC,IAAI,EAA2B,OAA1BG,EAAE5J,EAAMiJ,oBAAkBW,EAAIV,KAC5DC,kBAAmBK,KAAKC,IAAI,EAA0B,OAAzBI,EAAE7J,EAAMmJ,mBAAiBU,EAAI,KAC1DT,eAAgBI,KAAKC,IAAI,EAAuB,OAAtBK,EAAE9J,EAAMoJ,gBAAcU,EAAI,KACpDT,YAA8B,OAAnBU,EAAE/J,EAAMqJ,aAAWU,EAAI,KAClCT,UAA0B,OAAjBU,EAAEhK,EAAMsJ,WAASU,EAAI,KAC9BT,UAA0B,OAAjBU,EAAEjK,EAAMuJ,WAASU,EAAI,OAK3BpB,GAAyB,GAfkB,IAADa,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,CAgBnD,CAEO,IC3HHC,ED2HSC,EAAe,SAAUrJ,GAYpC,IAXA,IAAMsJ,EAAQ/K,OAAO0B,OAAO,CAAC,EAAGN,EAAgBK,GAWhDuJ,EAAA,EAAAC,EAR4B,CAC1B,CAAEtK,MAAOoK,EAAMlE,oBAAqB1B,KAAM,uBAC1C,CAAExE,MAAOoK,EAAMjE,oBAAqB3B,KAAM,uBAC1C,CAAExE,MAAOoK,EAAMhE,aAAc5B,KAAM,gBACnC,CAAExE,MAAOoK,EAAM1D,cAAelC,KAAM,iBACpC,CAAExE,MAAOoK,EAAM9C,gBAAiB9C,KAAM,oBAGS6F,EAAAC,EAAAjJ,OAAAgJ,IAAE,CAA9C,IAAAE,EAAAD,EAAAD,GAAQrK,EAAKuK,EAALvK,MAAOwE,EAAI+F,EAAJ/F,KACdxE,GACFqI,EAAqBrI,EAAOwE,EAEhC,CAqBA,OAnBkC,OAA9B4F,EAAMhC,sBACRgC,EAAMhC,oBAAsBrC,GAI9BqE,EAAM7C,gBAAkBsB,EAAyBuB,EAAM7C,gBAAiB6C,EAAM5C,cAC9E4C,EAAMI,gBAAkB,IAAIC,IAAIL,EAAMzJ,cAElCyJ,EAAMjD,WAAauD,MAAMrD,QAAQ+C,EAAMjD,aACzCiD,EAAMjD,UAAYiD,EAAMjD,UAAU5D,IAAI,SAAAoH,GACpC,MAAoB,iBAATA,GAAqBA,EAAKC,WAAW,MAGvC,KAAOD,EAAK3I,UAAU,GAExB2I,CACT,IAGKP,CACT,EC9JEF,EADoB,mBAAXpK,OACS,gBAEAA,OAAO,qBAC1B,IAEoB+K,EAAO,WAC1B,SAAAA,EAAYjH,GACV5E,KAAK4E,QAAUA,EACf5E,KAAK8L,MAAQ,GACb9L,KAAK,MAAQK,OAAO0L,OAAO,KAC7B,CAAC,IAAAC,EAAAH,EAAAlL,UAqCA,OArCA,EACDsL,IAAA,SAAI9L,EAAK8H,GAAM,IAADiE,EAEA,cAAR/L,IAAqBA,EAAM,cAC/BH,KAAK8L,MAAM5H,OAAIgI,EAAA,IAAI/L,GAAM8H,EAAGiE,GAC9B,EAAC,EACDC,SAAA,SAASR,EAAM3F,GAE0C,IAADoG,EAE/CC,EAHc,cAAjBV,EAAK/G,UAAyB+G,EAAK/G,QAAU,cAC7C+G,EAAK,OAAStL,OAAOiM,KAAKX,EAAK,OAAOtJ,OAAS,EACjDrC,KAAK8L,MAAM5H,OAAIkI,EAAA,IAAIT,EAAK/G,SAAU+G,EAAKG,MAAKM,EAAG,MAAOT,EAAK,MAAKS,IAEhEpM,KAAK8L,MAAM5H,OAAImI,EAAA,IAAIV,EAAK/G,SAAU+G,EAAKG,MAAKO,IAG9CrM,KAAKuM,cAAcvG,EACrB,EAAC,EAEDuG,cAAA,SAAcvG,QACOC,IAAfD,IAGFhG,KAAK8L,MAAM9L,KAAK8L,MAAMzJ,OAAS,GAAG6I,GAAmB,CAAElF,WAAAA,GAE3D,EAAC,EAEDwG,YAAA,SAAYC,GACV,IAAMC,EAAY1M,KAAK8L,MAAM9L,KAAK8L,MAAMzJ,OAAS,QAG/B4D,IAAdyG,QAA0DzG,IAA/ByG,EAAUxB,SACIjF,IAAxCyG,EAAUxB,GAAiBuB,WAC9BC,EAAUxB,GAAiBuB,SAAWA,EAE1C,EACA,EACOE,kBAAP,WACE,OAAOzB,CACT,EAACW,CAAA,CA1CyB,GCmB5B,MAAMe,EACJ,+CAoCIC,EACJ,8CAYIC,EACJD,sBAeIE,EAAeA,CAAC/H,EAAWN,EAAMsI,EAAQ,MAC7C,MAEMC,EAAY,IAFFjI,EAAUP,QAAQ,IAAK,QACxBC,EAAKD,QAAQ,IAAK,QAGjC,MAAO,CACLe,KAAM,IAAIrE,OAAO,KAAK6D,MAAcN,OAAWsI,GAC/CE,OAAQ,IAAI/L,OAAO,IAAI8L,KAAcD,GACrCG,MAAO,IAAIhM,OAAO,IAAI8L,QAAgBA,OAAgBD,GACtDI,QAAS,IAAIjM,OAAO,KAAKuD,OAAWsI,GACpCK,SAAU,IAAIlM,OAAO,KAAKuD,cAAiBA,SAAasI,KAItDM,EAAYP,EAAaH,EAnE7BA,sBAoEIW,EAAYR,EAAaF,EAAiBC,EAAY,KAuBtDU,EAAqB,WAGrBC,EAAeV,EAAaS,EAFZA,EAAqB,aA2C9BL,EAAQA,CAACO,GAAOC,aAAa,MAAOC,aAAY,GAAU,CAAC,IAvCrDC,EAACF,EAAa,MAAOC,GAAY,IAC9CA,EAAkBH,EACA,QAAfE,EAAuBJ,EAAYD,EAsC1CO,CAAWF,EAAYC,GAAWT,MAAMW,KAAKJ,GClLF,IAExBK,EAAa,WAC9B,SAAAA,EAAYjM,EAAS6L,GACjB3N,KAAKgO,uBAAyBlM,EAC9B9B,KAAK8B,QAAUA,EACf9B,KAAK2N,WAAaA,GAAc,CACpC,CAAC,IAAA3B,EAAA+B,EAAApN,UAwYA,OAxYA,EAEDsN,cAAA,SAAcN,QAAU,IAAVA,IAAAA,EAAa,GACvB3N,KAAK2N,WAAaA,CACtB,EAAC,EACDO,YAAA,SAAYrM,EAASO,GACjB,IAAM+L,EAAW9N,OAAO0L,OAAO,MAC3BqC,EAAc,EAElB,GAAuB,MAAnBvM,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,IACO,MAAnBP,EAAQO,EAAI,GA+EZ,MAAM,IAAIwH,MAAM,kCA9EhBxH,GAAQ,EAKR,IAJA,IAAIyC,EAAqB,EACrBwJ,GAAU,EAAOC,GAAU,EAC3B3I,EAAY,KAETvD,EAAIP,EAAQQ,OAAQD,IAIvB,GAAkB,OAAduD,EAKJ,GAAK0I,GAAYC,GAA2B,MAAfzM,EAAQO,IAA6B,MAAfP,EAAQO,GAM3D,GAAmB,MAAfP,EAAQO,IAAekM,EAoCpB,GAAmB,MAAfzM,EAAQO,IASf,GARIkM,EACuB,MAAnBzM,EAAQO,EAAI,IAAiC,MAAnBP,EAAQO,EAAI,KACtCkM,GAAU,EACVzJ,KAGJA,IAEuB,IAAvBA,EACA,UAEkB,MAAfhD,EAAQO,GACfiM,GAAU,EAEHxM,EAAQO,OAnDiB,CAChC,GAAIiM,GAAWE,EAAO1M,EAAS,UAAWO,GAAI,CAC1CA,GAAK,EACL,IAAIoM,EAAYvG,OAAG,EAACwG,EACGzO,KAAK0O,cAAc7M,EAASO,EAAI,EAAGpC,KAAKgO,uBAC/D,GADCQ,EAAUC,EAAA,GAAExG,EAAGwG,EAAA,GAAErM,EAACqM,EAAA,IACO,IAAtBxG,EAAIhE,QAAQ,KAAa,CACzB,IAA6B,IAAzBjE,KAAK8B,QAAQgI,SACkB,MAA/B9J,KAAK8B,QAAQsI,gBACbgE,GAAepO,KAAK8B,QAAQsI,eAC5B,MAAM,IAAIR,MAAM,kBACKwE,EAAc,GAAC,8BAA8BpO,KAAK8B,QAAQsI,eAAc,KAKjG+D,EAASK,GAAcvG,EACvBmG,GACJ,CACJ,MACK,GAAIC,GAAWE,EAAO1M,EAAS,WAAYO,GAC5CA,GAAK,EAELA,EADkBpC,KAAK2O,eAAe9M,EAASO,EAAI,GAA3CiB,WAEL,GAAIgL,GAAWE,EAAO1M,EAAS,WAAYO,GAC9CA,GAAK,OAGF,GAAIiM,GAAWE,EAAO1M,EAAS,YAAaO,GAC/CA,GAAK,EAELA,EADkBpC,KAAK4O,gBAAgB/M,EAASO,EAAI,EAAGpC,KAAKgO,uBAApD3K,UAEL,KAAIkL,EAAO1M,EAAS,MAAOO,GAC7B,MAAM,IAAIwH,MAAM,mBADiB0E,GAAU,CACT,CAEvCzJ,GAEJ,MAzCIc,EAAY9D,EAAQO,GACbP,EAAQO,QANXP,EAAQO,KAAOuD,IAAWA,EAAY,MACnC9D,EAAQO,GA+DvB,GAAkB,OAAduD,GAA6C,IAAvBd,EACtB,MAAM,IAAI+E,MAAM,oBAKxB,MAAO,CAAEuE,SAAAA,EAAU/L,EAAAA,EACvB,EAAC,EACDsM,cAAA,SAAc7M,EAASO,GAenB,IADA,IAAM4D,EAHN5D,EAAIyM,EAAehN,EAASO,GAIrBA,EAAIP,EAAQQ,SAAW,KAAKyL,KAAKjM,EAAQO,KAAsB,MAAfP,EAAQO,IAA6B,MAAfP,EAAQO,IACjFA,IAEJ,IAAIoM,EAAa3M,EAAQmB,UAAUgD,EAAY5D,GAQ/C,GANA0M,EAAmBN,EAAY,CAAEb,WAAY3N,KAAK2N,aAGlDvL,EAAIyM,EAAehN,EAASO,IAGvBpC,KAAKgO,sBAAuB,CAC7B,GAAkD,WAA9CnM,EAAQmB,UAAUZ,EAAGA,EAAI,GAAG2M,cAC5B,MAAM,IAAInF,MAAM,uCACb,GAAmB,MAAf/H,EAAQO,GACf,MAAM,IAAIwH,MAAM,uCAExB,CAGA,IAAIoF,EAGJC,EAFmBjP,KAAKkP,kBAAkBrN,EAASO,EAAG,UAGtD,GAHCA,EAAC6M,EAAA,GAAED,EAAWC,EAAA,IAGc,IAAzBjP,KAAK8B,QAAQgI,SACiB,MAA9B9J,KAAK8B,QAAQiI,eACbiF,EAAY3M,OAASrC,KAAK8B,QAAQiI,cAClC,MAAM,IAAIH,MAAM,WACD4E,EAAU,WAAWQ,EAAY3M,OAAM,mCAAmCrC,KAAK8B,QAAQiI,cAAa,KAKvH,MAAO,CAACyE,EAAYQ,IADpB5M,EAEJ,EAAC,EAEDwM,gBAAA,SAAgB/M,EAASO,GAOrB,IADA,IAAM4D,EAJN5D,EAAIyM,EAAehN,EAASO,GAKrBA,EAAIP,EAAQQ,SAAW,KAAKyL,KAAKjM,EAAQO,KAC5CA,IAEJ,IAAI+M,EAAetN,EAAQmB,UAAUgD,EAAY5D,IAEhDpC,KAAKgO,uBAAyBc,EAAmBK,EAAc,CAAExB,WAAY3N,KAAK2N,aAGnFvL,EAAIyM,EAAehN,EAASO,GAG5B,IAAMgN,EAAiBvN,EAAQmB,UAAUZ,EAAGA,EAAI,GAAG2M,cACnD,IAAK/O,KAAKgO,uBAA4C,WAAnBoB,GAAkD,WAAnBA,EAC9D,MAAM,IAAIxF,MAAM,qCAAqCwF,EAAc,KAEvEhN,GAAKgN,EAAe/M,OAGpBD,EAAIyM,EAAehN,EAASO,GAG5B,IAAIiN,EAAmB,KACnBC,EAAmB,KAEvB,GAAuB,WAAnBF,EAA6B,CAG7B,IAAAG,EAFwBvP,KAAKkP,kBAAkBrN,EAASO,EAAG,oBAM3D,GANCA,EAACmN,EAAA,GAAEF,EAAgBE,EAAA,GAMD,MAAf1N,EAHJO,EAAIyM,EAAehN,EAASO,KAGa,MAAfP,EAAQO,GAAY,CAAC,IAADoN,EAClBxP,KAAKkP,kBAAkBrN,EAASO,EAAG,oBAA1DA,EAACoN,EAAA,GAAEF,EAAgBE,EAAA,EACxB,CACJ,MAAO,GAAuB,WAAnBJ,EAA6B,CACpC,IAAAK,EACwBzP,KAAKkP,kBAAkBrN,EAASO,EAAG,oBAE3D,GAFCA,EAACqN,EAAA,GAAEH,EAAgBG,EAAA,IAEfzP,KAAKgO,wBAA0BsB,EAChC,MAAM,IAAI1F,MAAM,0DAExB,CAEA,MAAO,CAAEuF,aAAAA,EAAcE,iBAAAA,EAAkBC,iBAAAA,EAAkBjM,QAASjB,EACxE,EAAC,EAED8M,kBAAA,SAAkBrN,EAASO,EAAGsN,GAC1B,IAAIC,EACE3K,EAAYnD,EAAQO,GAC1B,GAAkB,MAAd4C,GAAmC,MAAdA,EACrB,MAAM,IAAI4E,MAAM,kCAAkC5E,EAAS,KAK/D,IADA,IAAMgB,IAFN5D,EAGOA,EAAIP,EAAQQ,QAAUR,EAAQO,KAAO4C,GACxC5C,IAIJ,GAFAuN,EAAgB9N,EAAQmB,UAAUgD,EAAY5D,GAE1CP,EAAQO,KAAO4C,EACf,MAAM,IAAI4E,MAAM,gBAAgB8F,EAAI,UAGxC,MAAO,GADPtN,EACWuN,EACf,EAAC,EAEDhB,eAAA,SAAe9M,EAASO,GAYpB,IADA,IAAM4D,EAHN5D,EAAIyM,EAAehN,EAASO,GAIrBA,EAAIP,EAAQQ,SAAW,KAAKyL,KAAKjM,EAAQO,KAC5CA,IAEJ,IAAIwN,EAAc/N,EAAQmB,UAAUgD,EAAY5D,GAGhD,IAAKpC,KAAKgO,wBAA0B5M,EAAOwO,EAAa,CAAEjC,WAAY3N,KAAK2N,aACvE,MAAM,IAAI/D,MAAM,0BAA0BgG,EAAW,KAKzD,IAAIC,EAAe,GAEnB,GAAmB,MAAfhO,EAHJO,EAAIyM,EAAehN,EAASO,KAGFmM,EAAO1M,EAAS,OAAQO,GAAIA,GAAK,OACtD,GAAmB,MAAfP,EAAQO,IAAcmM,EAAO1M,EAAS,KAAMO,GAAIA,GAAK,OACzD,GAAmB,MAAfP,EAAQO,GAAY,CAKzB,IADA,IAAM4D,IAHN5D,EAIOA,EAAIP,EAAQQ,QAAyB,MAAfR,EAAQO,IACjCA,IAIJ,GAFAyN,EAAehO,EAAQmB,UAAUgD,EAAY5D,GAE1B,MAAfP,EAAQO,GACR,MAAM,IAAIwH,MAAM,6BAGxB,MAAO,IAAK5J,KAAKgO,sBACb,MAAM,IAAIpE,MAAM,sCAAsC/H,EAAQO,GAAE,KAGpE,MAAO,CACHwN,YAAAA,EACAC,aAAcA,EAAa9M,OAC3BM,MAAOjB,EAEf,EAAC,EAED0N,eAAA,SAAejO,EAASO,GAMpB,IADA,IAAI4D,EAHJ5D,EAAIyM,EAAehN,EAASO,GAIrBA,EAAIP,EAAQQ,SAAW,KAAKyL,KAAKjM,EAAQO,KAC5CA,IAEJ,IAAIwN,EAAc/N,EAAQmB,UAAUgD,EAAY5D,GAUhD,IAPA0M,EAAmBc,EAAa,CAAEjC,WAAY3N,KAAK2N,aAMnD3H,EAHA5D,EAAIyM,EAAehN,EAASO,GAIrBA,EAAIP,EAAQQ,SAAW,KAAKyL,KAAKjM,EAAQO,KAC5CA,IAEJ,IAAI2N,EAAgBlO,EAAQmB,UAAUgD,EAAY5D,GAGlD,IAAK0M,EAAmBiB,EAAe,CAAEpC,WAAY3N,KAAK2N,aACtD,MAAM,IAAI/D,MAAM,4BAA4BmG,EAAa,KAI7D3N,EAAIyM,EAAehN,EAASO,GAG5B,IAAI4N,EAAgB,GACpB,GAAkD,aAA9CnO,EAAQmB,UAAUZ,EAAGA,EAAI,GAAG2M,cAA8B,CAQ1D,GAPAiB,EAAgB,WAOG,MAAfnO,EAHJO,EAAIyM,EAAehN,EAHnBO,GAAK,IAOD,MAAM,IAAIwH,MAAM,yBAAwB/H,EAAQO,GAAE,KAEtDA,IAIA,IADA,IAAI6N,EAAmB,GAChB7N,EAAIP,EAAQQ,QAAyB,MAAfR,EAAQO,IAAY,CAI7C,IADA,IAAM4D,EAAa5D,EACZA,EAAIP,EAAQQ,QAAyB,MAAfR,EAAQO,IAA6B,MAAfP,EAAQO,IACvDA,IAEJ,IAAI8N,EAAWrO,EAAQmB,UAAUgD,EAAY5D,GAI7C,IAAK0M,EADLoB,EAAWA,EAASnN,OACc,CAAE4K,WAAY3N,KAAK2N,aACjD,MAAM,IAAI/D,MAAM,2BAA2BsG,EAAQ,KAGvDD,EAAiB/L,KAAKgM,GAGH,MAAfrO,EAAQO,KACRA,IACAA,EAAIyM,EAAehN,EAASO,GAEpC,CAEA,GAAmB,MAAfP,EAAQO,GACR,MAAM,IAAIwH,MAAM,kCAEpBxH,IAGA4N,GAAiB,KAAOC,EAAiBE,KAAK,KAAO,GACzD,KAAO,CAGH,IADA,IAAMnK,EAAa5D,EACZA,EAAIP,EAAQQ,SAAW,KAAKyL,KAAKjM,EAAQO,KAC5CA,IAMJ,GAJA4N,GAAiBnO,EAAQmB,UAAUgD,EAAY5D,IAI1CpC,KAAKgO,wBADS,CAAC,QAAS,KAAM,QAAS,SAAU,SAAU,WAAY,UAAW,YACxChH,SAASgJ,EAAcjB,eAClE,MAAM,IAAInF,MAAM,4BAA4BoG,EAAa,IAEjE,CAGA5N,EAAIyM,EAAehN,EAASO,GAG5B,IAAIgO,EAAe,GACnB,GAAkD,cAA9CvO,EAAQmB,UAAUZ,EAAGA,EAAI,GAAG2M,cAC5BqB,EAAe,YACfhO,GAAK,OACF,GAAkD,aAA9CP,EAAQmB,UAAUZ,EAAGA,EAAI,GAAG2M,cACnCqB,EAAe,WACfhO,GAAK,MACF,CAAC,IAADiO,EACiBrQ,KAAKkP,kBAAkBrN,EAASO,EAAG,WAAtDA,EAACiO,EAAA,GAAED,EAAYC,EAAA,EACpB,CAEA,MAAO,CACHT,YAAAA,EACAG,cAAAA,EACAC,cAAAA,EACAI,aAAAA,EACA/M,MAAOjB,EAEf,EAAC2L,CAAA,CA7Y6B,GAkZ5Bc,EAAiB,SAACyB,EAAMjN,GAC1B,KAAOA,EAAQiN,EAAKjO,QAAU,KAAKyL,KAAKwC,EAAKjN,KACzCA,IAEJ,OAAOA,CACX,EAIA,SAASkL,EAAO+B,EAAMC,EAAKnO,GACvB,IAAK,IAAIsD,EAAI,EAAGA,EAAI6K,EAAIlO,OAAQqD,IAC5B,GAAI6K,EAAI7K,KAAO4K,EAAKlO,EAAIsD,EAAI,GAAI,OAAO,EAE3C,OAAO,CACX,CAEA,SAASoJ,EAAmBtJ,EAAMmI,GAC9B,GAAIvM,EAAOoE,EAAM,CAAEmI,WAAYA,IAC3B,OAAOnI,EAEP,MAAM,IAAIoE,MAAM,uBAAuBpE,EAC/C,CC3ZA,MAAMgL,EAAe,CAEnB,GAGA,KACA,KAGA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KAGA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KAGA,MAGA,OACA,OACA,OACA,OACA,OAGA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,OACA,OACA,OACA,OACA,QAMIC,EAAW,IAAIC,IAMfC,EAHU,KAKVC,EAAQ,IAAIC,WADCC,OACsBC,KATvB,KAWlB,IAAK,MAAMC,KAAQR,EACjB,IAAK,IAAIS,EAAI,EAAGA,EAAI,GAAIA,IAAK,CAC3B,MAAMC,EAAKF,EAAOC,EACdC,GAXQ,MAYVN,EAAMM,EAAKP,GAAgBM,EAE3BR,EAASU,IAAID,EAAID,EAErB,CC5GF,MAiBMG,EAAY,IAAI3F,IAAI,CAAC,KAAQ,MAAQ,QCrBrC4F,EAAW,wBACXC,EAAW,YACXC,EAAW,aACXC,EAAW,qCAIXC,EAAW,CACb7J,KAAK,EACL8J,QAAQ,EACRC,OAAO,EACP9J,cAAc,EACd+J,aAAc,IACd9J,WAAW,EAEX+J,SAAU,WACV9J,SAAS,GAGE,SAAS+J,EAASpE,EAAK5L,EAAU,CAAC,GAE7C,GADAA,EAAUzB,OAAO0B,OAAO,CAAC,EAAG0P,EAAU3P,IACjC4L,GAAsB,iBAARA,EAAkB,OAAOA,EAE5C,IAAIqE,EAAarE,EAAI3K,OAErB,GAA0B,IAAtBgP,EAAW1P,OAAc,OAAOqL,EAC/B,QAAyBzH,IAArBnE,EAAQkQ,UAA0BlQ,EAAQkQ,SAASlE,KAAKiE,GAAa,OAAOrE,EAChF,GAAmB,MAAfqE,EAAoB,OAAO,EAEpC,GAAIjQ,EAAQiG,UACRgK,EDSR,SAAgBrE,GACd,GAAmB,iBAARA,EAAkB,OAAOA,EAEpC,MAAMvI,EAAMuI,EAAIrL,OAChB,GAAY,IAAR8C,EAAW,OAAOuI,EAItB,IAAIuE,GAAY,EAEhB,IAAK,IAAI7P,EAAI,EAAGA,EAAI+C,EAAK/C,IAAK,CAC5B,MAAM8P,EAAKxE,EAAIyE,WAAW/P,GAG1B,KAAK8P,GAjDM,IAiDUA,GAhDV,IACI,KA+CuBA,GAGtC,GAAIA,EAAKvB,GACP,GAAIS,EAAUgB,IAAIF,GAAK,CAAED,EAAW7P,EAAG,KAAO,OAKhD,GAAI8P,GAAM,OAAUA,GAAM,OACxB,GAAI9P,EAAI,EAAI+C,EAAK,CACf,MAAMkN,EAAM3E,EAAIyE,WAAW/P,EAAI,GAC/B,GAAIiQ,GAAO,OAAUA,GAAO,MAAQ,CAClC,MAAMnB,EAAK,OAAYgB,EAAK,OAAW,KAAOG,EAAM,OACpD,GAAI5B,EAAS2B,IAAIlB,GAAK,CAAEe,EAAW7P,EAAG,KAAO,CAC/C,CACF,OAKF,GDmBc,MCnBVwO,EAAMsB,EAAKvB,IAA+BS,EAAUgB,IAAIF,GAAK,CAC/DD,EAAW7P,EACX,KACF,CACF,CAGA,IAAkB,IAAd6P,EAAiB,OAAOvE,EAG5B,MAAM4E,EAAQ,GAEVL,EAAW,GAAGK,EAAMpO,KAAKwJ,EAAIpI,MAAM,EAAG2M,IAE1C,IAAK,IAAI7P,EAAI6P,EAAU7P,EAAI+C,EAAK/C,IAAK,CACnC,MAAM8P,EAAKxE,EAAIyE,WAAW/P,GAG1B,GAAK8P,GAxFM,IAwFUA,GAvFV,IACI,KAsFuBA,EAAmB,CACvDI,EAAMpO,KAAKwJ,EAAItL,IACf,QACF,CAGA,GAAI8P,EAAKvB,EAAc,CACrB2B,EAAMpO,KAAKkN,EAAUgB,IAAIF,GAAM,IAAMxE,EAAItL,IACzC,QACF,CAGA,GAAI8P,GAAM,OAAUA,GAAM,MAAQ,CAChC,GAAI9P,EAAI,EAAI+C,EAAK,CACf,MAAMkN,EAAM3E,EAAIyE,WAAW/P,EAAI,GAC/B,GAAIiQ,GAAO,OAAUA,GAAO,MAAQ,CAClC,MAAMnB,EAAK,OAAYgB,EAAK,OAAW,KAAOG,EAAM,OAC9CpB,EAAIR,EAASjQ,IAAI0Q,GACvB,QAAUjL,IAANgL,EAAiB,CACnBqB,EAAMpO,KAAKqO,OAAOC,aAAavB,EAAI,KACnC7O,IACA,QACF,CACF,CACF,CACAkQ,EAAMpO,KAAKwJ,EAAItL,IACf,QACF,CAGA,GAAIgP,EAAUgB,IAAIF,GAAK,CACrBI,EAAMpO,KAAK,KACX,QACF,CACA,MAAM+M,EAAIL,EAAMsB,EAAKvB,GACrB2B,EAAMpO,KDlCQ,MCkCH+M,EAAkBsB,OAAOC,aAAavB,EAAI,IAAMvD,EAAItL,GACjE,CAEA,OAAOkQ,EAAMnC,KAAK,GACpB,CCrGqBsC,CAAOV,GACD,MAAfA,GAAoB,OAAO,EAEnC,GAAIjQ,EAAQ8F,KAAOyJ,EAASvD,KAAKiE,GAC7B,OAAOW,GAAUX,EAAY,IAC1B,GAAIjQ,EAAQ4P,QAAUJ,EAASxD,KAAKiE,GACvC,OAAOW,GAAUX,EAAY,GAC1B,GAAIjQ,EAAQ6P,OAASJ,EAASzD,KAAKiE,GACtC,OAAOW,GAAUX,EAAY,GAC1B,GAAKY,SAASZ,GAEd,IAAIA,EAAW/K,SAAS,MAAQ+K,EAAW/K,SAAS,KACvD,OAmDR,SAA0B0G,EAAKqE,EAAYjQ,GACvC,IAAKA,EAAQgG,UAAW,OAAO4F,EAC/B,MAAMwC,EAAW6B,EAAWvL,MAAMoM,GAClC,GAAI1C,EAAU,CACV,IAAI2C,EAAO3C,EAAS,IAAM,GAC1B,MAAM4C,GAAsC,IAA9B5C,EAAS,GAAGjM,QAAQ,KAAc,IAAM,IAChD4D,EAAeqI,EAAS,GACxB6C,EAA0BF,EAC5BnF,EAAI7F,EAAaxF,OAAS,KAAOyQ,EAC/BpF,EAAI7F,EAAaxF,UAAYyQ,EAEnC,OAAIjL,EAAaxF,OAAS,GAAK0Q,EAAgCrF,GAC9B,IAAxB7F,EAAaxF,SACd6N,EAAS,GAAGtE,WAAW,IAAIkH,MAAY5C,EAAS,GAAG,KAAO4C,IAEvDjL,EAAaxF,OAAS,EAEzBP,EAAQ+F,eAAiBkL,GACzBhB,GAAc7B,EAAS,IAAM,IAAMA,EAAS,GACrC8C,OAAOjB,IACJrE,EANPsF,OAAOjB,EAWtB,CACI,OAAOrE,CAEf,CA/EeuF,CAAiBvF,EAAKqE,EAAYjQ,GACtC,CAEH,MAAM0E,EAAQgL,EAASlQ,KAAKyQ,GAE5B,GAAIvL,EAAO,CACP,MAAMqM,EAAOrM,EAAM,IAAM,GACnBqB,EAAerB,EAAM,GAC3B,IAAI0M,EA8EhB,SAAmBC,GACf,GAAIA,IAAmC,IAAzBA,EAAOlP,QAAQ,KAAa,CAGtC,IAAImP,EAAMD,EAAO9Q,OACjB,KAAO+Q,EAAM,GAAoC,KAA/BD,EAAOhB,WAAWiB,EAAM,IAAqBA,IAK/D,MAHe,OADfD,EAASA,EAAO7N,MAAM,EAAG8N,IACLD,EAAS,IACN,MAAdA,EAAO,GAAYA,EAAS,IAAMA,EACJ,MAA9BA,EAAOA,EAAO9Q,OAAS,KAAY8Q,EAASA,EAAOnQ,UAAU,EAAGmQ,EAAO9Q,OAAS,IAClF8Q,CACX,CACA,OAAOA,CACX,CA3FoCE,CAAU7M,EAAM,IACxC,MAAM8M,EAAgCT,EACD,MAAjCnF,EAAI7F,EAAaxF,OAAS,GACK,MAA7BqL,EAAI7F,EAAaxF,QAGvB,IAAKP,EAAQ+F,eACLA,EAAaxF,OAAS,GACM,IAAxBwF,EAAaxF,SAAiBiR,GAEtC,OAAO5F,EAEN,CACD,MAAM6F,EAAMP,OAAOjB,GACbyB,EAAYjB,OAAOgB,GAEzB,GAAY,IAARA,EAAW,OAAOA,EACtB,IAAkC,IAA9BC,EAAUC,OAAO,QACjB,OAAI3R,EAAQgG,UAAkByL,EAClB7F,EACT,IAAiC,IAA7BqE,EAAW9N,QAAQ,KAC1B,MAAkB,MAAduP,GACKA,IAAcN,GACdM,IAAc,GAAGX,IAAOK,IAFHK,EAGlB7F,EAGhB,IAAIgG,EAAI7L,EAAeqL,EAAoBnB,EAC3C,OAAIlK,EAEQ6L,IAAMF,GAAeX,EAAOa,IAAMF,EAAaD,EAAM7F,EAGrDgG,IAAMF,GAAeE,IAAMb,EAAOW,EAAaD,EAAM7F,CAErE,CACJ,CACI,OAAOA,CAEf,EAjDI,OAwHR,SAAwBA,EAAK6F,EAAKzR,GAC9B,MAAM6R,EAAaJ,IAAQrJ,IAE3B,OAAQpI,EAAQ+P,SAASpI,eACrB,IAAK,OACD,OAAO,KACX,IAAK,WACD,OAAO8J,EACX,IAAK,SACD,OAAOI,EAAa,WAAa,YAErC,QACI,OAAOjG,EAEnB,CAtIekG,CAAelG,EAAKsF,OAAOjB,GAAajQ,EAkDvD,CAEA,MAAM8Q,EAAgB,0CAmDtB,SAASF,GAAUS,EAAQU,GACvB,MAAMnG,EAAMyF,EAAOpQ,OAGnB,GAFa,IAAT8Q,GAAuB,IAATA,IAAYV,EAASzF,EAAI1K,UAAU,IAEjD8Q,SAAU,OAAOA,SAASX,EAAQU,GACjC,GAAIb,OAAOc,SAAU,OAAOd,OAAOc,SAASX,EAAQU,GACpD,GAAIE,QAAUA,OAAOD,SAAU,OAAOC,OAAOD,SAASX,EAAQU,GAC9D,MAAM,IAAIjK,MAAM,+DACzB,C,uGClIO,MAAMoK,GAIXC,WAAAA,CAAYC,GACVlU,KAAKmU,SAAWD,CAClB,CAMA,aAAIE,GACF,OAAOpU,KAAKmU,SAASC,SACvB,CAMAC,aAAAA,GACE,MAAMC,EAAOtU,KAAKmU,SAASG,KAC3B,OAAOA,EAAKjS,OAAS,EAAIiS,EAAKA,EAAKjS,OAAS,GAAGkS,SAAMtO,CACvD,CAMAuO,mBAAAA,GACE,MAAMF,EAAOtU,KAAKmU,SAASG,KAC3B,OAAOA,EAAKjS,OAAS,EAAIiS,EAAKA,EAAKjS,OAAS,GAAGoS,eAAYxO,CAC7D,CAOAyO,YAAAA,CAAarO,GACX,MAAMiO,EAAOtU,KAAKmU,SAASG,KAC3B,GAAoB,IAAhBA,EAAKjS,OACT,OAAOiS,EAAKA,EAAKjS,OAAS,GAAGsS,SAAStO,EACxC,CAOAuO,OAAAA,CAAQvO,GACN,MAAMiO,EAAOtU,KAAKmU,SAASG,KAC3B,GAAoB,IAAhBA,EAAKjS,OAAc,OAAO,EAC9B,MAAMwS,EAAUP,EAAKA,EAAKjS,OAAS,GACnC,YAA0B4D,IAAnB4O,EAAQF,QAAwBtO,KAAYwO,EAAQF,MAC7D,CAQAG,gBAAAA,CAAiBzO,GACf,OAAOrG,KAAKmU,SAASW,iBAAiBzO,EACxC,CAQA0O,gBAAAA,CAAiB1O,GACf,OAAOrG,KAAKmU,SAASY,iBAAiB1O,EACxC,CAMA2O,WAAAA,GACE,MAAMV,EAAOtU,KAAKmU,SAASG,KAC3B,OAAoB,IAAhBA,EAAKjS,QAAsB,EACxBiS,EAAKA,EAAKjS,OAAS,GAAG4S,UAAY,CAC3C,CAMAC,UAAAA,GACE,MAAMZ,EAAOtU,KAAKmU,SAASG,KAC3B,OAAoB,IAAhBA,EAAKjS,QAAsB,EACxBiS,EAAKA,EAAKjS,OAAS,GAAG8S,SAAW,CAC1C,CAOAC,QAAAA,GACE,OAAOpV,KAAKgV,aACd,CAMAK,QAAAA,GACE,OAAOrV,KAAKmU,SAASG,KAAKjS,MAC5B,CAQAiT,QAAAA,CAASlB,EAAWmB,GAAmB,GACrC,OAAOvV,KAAKmU,SAASmB,SAASlB,EAAWmB,EAC3C,CAMAC,OAAAA,GACE,OAAOxV,KAAKmU,SAASG,KAAK/P,IAAImP,GAAKA,EAAEa,IACvC,CAOAtP,OAAAA,CAAQwQ,GACN,OAAOzV,KAAKmU,SAASlP,QAAQwQ,EAC/B,CAOAC,UAAAA,CAAWC,GACT,OAAOA,EAAQD,WAAW1V,KAAKmU,SACjC,EAsBa,MAAMyB,GAMnB3B,WAAAA,CAAYnS,EAAU,CAAC,GACrB9B,KAAKoU,UAAYtS,EAAQsS,WAAa,IACtCpU,KAAKsU,KAAO,GACZtU,KAAK6V,cAAgB,GAIrB7V,KAAK8V,iBAAmB,KACxB9V,KAAK+V,MAAQ,IAAI/B,GAAYhU,MAG7BA,KAAKgW,WAAa,EACpB,CAUA9R,IAAAA,CAAKpB,EAASmT,EAAa,KAAMxB,EAAY,KAAM3S,EAAU,MAC3D9B,KAAK8V,iBAAmB,KAGpB9V,KAAKsU,KAAKjS,OAAS,IACrBrC,KAAKsU,KAAKtU,KAAKsU,KAAKjS,OAAS,GAAGsS,YAAS1O,GAI3C,MAAMiQ,EAAelW,KAAKsU,KAAKjS,OAC/B,IAAI8T,EAAQnW,KAAK6V,cAAcK,GAC1BC,IAMHA,EAAQ,CAAEC,OAAQ,IAAI1F,IAAO2F,MAAO,GACpCrW,KAAK6V,cAAcK,GAAgBC,GAIrC,MAAMG,EAAa7B,EAAY,GAAGA,KAAa3R,IAAYA,EAGrDqS,EAAUgB,EAAMC,OAAO5V,IAAI8V,IAAe,EAG1CrB,EAAWkB,EAAME,MAGvBF,EAAMC,OAAOjF,IAAImF,EAAYnB,EAAU,GACvCgB,EAAME,QAGN,MAAM1K,EAAO,CACX4I,IAAKzR,EACLmS,SAAUA,EACVE,QAASA,GAGPV,UACF9I,EAAK8I,UAAYA,GAGfwB,UACFtK,EAAKgJ,OAASsB,GAGhBjW,KAAKsU,KAAKpQ,KAAKyH,GAGf,MAAM4K,EAAQvW,KAAKsU,KAAKjS,OAOlBmU,EAAmB,OAAZ1U,EAAmBA,EAAQ0U,KAAO,KAC/C,GAAIA,SAAuCA,EAAKnU,OAAS,GAAK4T,EAC5D,IAAK,IAAI7T,EAAI,EAAGA,EAAIoU,EAAKnU,OAAQD,IAAK,CACpC,MAAMoD,EAAOgR,EAAKpU,QACO6D,IAArBgQ,EAAWzQ,IACbxF,KAAKgW,WAAW9R,KAAK,CAAEqS,QAAO/Q,OAAMxE,MAAOiV,EAAWzQ,IAE1D,CAEJ,CAMA1B,GAAAA,GACE,GAAyB,IAArB9D,KAAKsU,KAAKjS,OAAc,OAC5BrC,KAAK8V,iBAAmB,KAExB,MAAMnK,EAAO3L,KAAKsU,KAAKxQ,MAEnB9D,KAAK6V,cAAcxT,OAASrC,KAAKsU,KAAKjS,OAAS,IACjDrC,KAAK6V,cAAcxT,OAASrC,KAAKsU,KAAKjS,OAAS,GAOjD,MAAMoU,EAAczW,KAAKsU,KAAKjS,OAAS,EACvC,KACErC,KAAKgW,WAAW3T,OAAS,GACzBrC,KAAKgW,WAAWhW,KAAKgW,WAAW3T,OAAS,GAAGkU,OAASE,GAErDzW,KAAKgW,WAAWlS,MAGlB,OAAO6H,CACT,CAOA+K,aAAAA,CAAcT,GACZ,GAAIjW,KAAKsU,KAAKjS,OAAS,EAAG,CACxB,MAAMwS,EAAU7U,KAAKsU,KAAKtU,KAAKsU,KAAKjS,OAAS,GACzC4T,UACFpB,EAAQF,OAASsB,EAErB,CACF,CAMA5B,aAAAA,GACE,OAAOrU,KAAKsU,KAAKjS,OAAS,EAAIrC,KAAKsU,KAAKtU,KAAKsU,KAAKjS,OAAS,GAAGkS,SAAMtO,CACtE,CAMAuO,mBAAAA,GACE,OAAOxU,KAAKsU,KAAKjS,OAAS,EAAIrC,KAAKsU,KAAKtU,KAAKsU,KAAKjS,OAAS,GAAGoS,eAAYxO,CAC5E,CAOAyO,YAAAA,CAAarO,GACX,GAAyB,IAArBrG,KAAKsU,KAAKjS,OACd,OAAOrC,KAAKsU,KAAKtU,KAAKsU,KAAKjS,OAAS,GAAGsS,SAAStO,EAClD,CAOAuO,OAAAA,CAAQvO,GACN,GAAyB,IAArBrG,KAAKsU,KAAKjS,OAAc,OAAO,EACnC,MAAMwS,EAAU7U,KAAKsU,KAAKtU,KAAKsU,KAAKjS,OAAS,GAC7C,YAA0B4D,IAAnB4O,EAAQF,QAAwBtO,KAAYwO,EAAQF,MAC7D,CAYAG,gBAAAA,CAAiBzO,GACf,MAAMsQ,EAAO3W,KAAKgW,WAClB,IAAK,IAAI5T,EAAIuU,EAAKtU,OAAS,EAAGD,GAAK,EAAGA,IACpC,GAAIuU,EAAKvU,GAAGoD,OAASa,EAAU,OAAOsQ,EAAKvU,GAAGpB,KAGlD,CAQA+T,gBAAAA,CAAiB1O,GACf,MAAMsQ,EAAO3W,KAAKgW,WAClB,IAAK,IAAI5T,EAAIuU,EAAKtU,OAAS,EAAGD,GAAK,EAAGA,IACpC,GAAIuU,EAAKvU,GAAGoD,OAASa,EAAU,OAAO,EAExC,OAAO,CACT,CAMA2O,WAAAA,GACE,OAAyB,IAArBhV,KAAKsU,KAAKjS,QAAsB,EAC7BrC,KAAKsU,KAAKtU,KAAKsU,KAAKjS,OAAS,GAAG4S,UAAY,CACrD,CAMAC,UAAAA,GACE,OAAyB,IAArBlV,KAAKsU,KAAKjS,QAAsB,EAC7BrC,KAAKsU,KAAKtU,KAAKsU,KAAKjS,OAAS,GAAG8S,SAAW,CACpD,CAOAC,QAAAA,GACE,OAAOpV,KAAKgV,aACd,CAMAK,QAAAA,GACE,OAAOrV,KAAKsU,KAAKjS,MACnB,CAQAiT,QAAAA,CAASlB,EAAWmB,GAAmB,GACrC,MAAMqB,EAAMxC,GAAapU,KAAKoU,UAG9B,GAFmBwC,IAAQ5W,KAAKoU,YAAkC,IAArBmB,EAE9B,CACb,GAA8B,OAA1BvV,KAAK8V,iBACP,OAAO9V,KAAK8V,iBAEd,MAAM5S,EAASlD,KAAKsU,KAAK/P,IAAImP,GAC1BA,EAAEe,UAAa,GAAGf,EAAEe,aAAaf,EAAEa,MAAQb,EAAEa,KAC9CpE,KAAKyG,GAEP,OADA5W,KAAK8V,iBAAmB5S,EACjBA,CACT,CAEA,OAAOlD,KAAKsU,KAAK/P,IAAImP,GAClB6B,GAAoB7B,EAAEe,UAAa,GAAGf,EAAEe,aAAaf,EAAEa,MAAQb,EAAEa,KAClEpE,KAAKyG,EACT,CAMApB,OAAAA,GACE,OAAOxV,KAAKsU,KAAK/P,IAAImP,GAAKA,EAAEa,IAC9B,CAKAsC,KAAAA,GACE7W,KAAK8V,iBAAmB,KACxB9V,KAAKsU,KAAO,GACZtU,KAAK6V,cAAgB,GACrB7V,KAAKgW,WAAa,EACpB,CAOA/Q,OAAAA,CAAQwQ,GACN,MAAMqB,EAAWrB,EAAWqB,SAE5B,OAAwB,IAApBA,EAASzU,SAIToT,EAAWsB,kBACN/W,KAAKgX,uBAAuBF,GAG9B9W,KAAKiX,aAAaH,GAC3B,CAKAG,YAAAA,CAAaH,GACX,GAAI9W,KAAKsU,KAAKjS,SAAWyU,EAASzU,OAChC,OAAO,EAGT,IAAK,IAAID,EAAI,EAAGA,EAAI0U,EAASzU,OAAQD,IACnC,IAAKpC,KAAKkX,cAAcJ,EAAS1U,GAAIpC,KAAKsU,KAAKlS,GAAIA,IAAMpC,KAAKsU,KAAKjS,OAAS,GAC1E,OAAO,EAIX,OAAO,CACT,CAKA2U,sBAAAA,CAAuBF,GACrB,IAAIK,EAAUnX,KAAKsU,KAAKjS,OAAS,EAC7B+U,EAASN,EAASzU,OAAS,EAE/B,KAAO+U,GAAU,GAAKD,GAAW,GAAG,CAClC,MAAME,EAAUP,EAASM,GAEzB,GAAqB,kBAAjBC,EAAQ3H,KAA0B,CAGpC,GAFA0H,IAEIA,EAAS,EACX,OAAO,EAGT,MAAME,EAAUR,EAASM,GACzB,IAAIG,GAAQ,EAEZ,IAAK,IAAInV,EAAI+U,EAAS/U,GAAK,EAAGA,IAC5B,GAAIpC,KAAKkX,cAAcI,EAAStX,KAAKsU,KAAKlS,GAAIA,IAAMpC,KAAKsU,KAAKjS,OAAS,GAAI,CACzE8U,EAAU/U,EAAI,EACdgV,IACAG,GAAQ,EACR,KACF,CAGF,IAAKA,EACH,OAAO,CAEX,KAAO,CACL,IAAKvX,KAAKkX,cAAcG,EAASrX,KAAKsU,KAAK6C,GAAUA,IAAYnX,KAAKsU,KAAKjS,OAAS,GAClF,OAAO,EAET8U,IACAC,GACF,CACF,CAEA,OAAOA,EAAS,CAClB,CAKAF,aAAAA,CAAcG,EAAS1L,EAAM6L,GAC3B,GAAoB,MAAhBH,EAAQ9C,KAAe8C,EAAQ9C,MAAQ5I,EAAK4I,IAC9C,OAAO,EAGT,QAA0BtO,IAAtBoR,EAAQ5C,WACgB,MAAtB4C,EAAQ5C,WAAqB4C,EAAQ5C,YAAc9I,EAAK8I,UAC1D,OAAO,EAIX,QAAyBxO,IAArBoR,EAAQhR,SAAwB,CAClC,IAAKmR,EACH,OAAO,EAGT,IAAK7L,EAAKgJ,UAAY0C,EAAQhR,YAAYsF,EAAKgJ,QAC7C,OAAO,EAGT,QAA0B1O,IAAtBoR,EAAQI,WACNlF,OAAO5G,EAAKgJ,OAAO0C,EAAQhR,aAAekM,OAAO8E,EAAQI,WAC3D,OAAO,CAGb,CAEA,QAAyBxR,IAArBoR,EAAQpC,SAAwB,CAClC,IAAKuC,EACH,OAAO,EAGT,MAAMrC,EAAUxJ,EAAKwJ,SAAW,EAEhC,GAAyB,UAArBkC,EAAQpC,UAAoC,IAAZE,EAClC,OAAO,EACF,GAAyB,QAArBkC,EAAQpC,UAAsBE,EAAU,GAAM,EACvD,OAAO,EACF,GAAyB,SAArBkC,EAAQpC,UAAuBE,EAAU,GAAM,EACxD,OAAO,EACF,GAAyB,QAArBkC,EAAQpC,UAAsBE,IAAYkC,EAAQK,cAC3D,OAAO,CAEX,CAEA,OAAO,CACT,CAOAhC,UAAAA,CAAWC,GACT,OAAOA,EAAQD,WAAW1V,KAC5B,CAMA2X,QAAAA,GACE,MAAO,CACLrD,KAAMtU,KAAKsU,KAAK/P,IAAIoH,IAAQ,IAAMA,KAClCkK,cAAe7V,KAAK6V,cAActR,IAAI4R,GAASA,EAAQ,CAAEC,OAAQ,IAAI1F,IAAIyF,EAAMC,QAASC,MAAOF,EAAME,OAAUF,GAC/GyB,UAAW5X,KAAKgW,WAAWzR,IAAIsT,IAAS,IAAMA,KAElD,CAMAC,OAAAA,CAAQH,GACN3X,KAAK8V,iBAAmB,KACxB9V,KAAKsU,KAAOqD,EAASrD,KAAK/P,IAAIoH,IAAQ,IAAMA,KAC5C3L,KAAK6V,cAAgB8B,EAAS9B,cAActR,IAAI4R,GAASA,EAAQ,CAAEC,OAAQ,IAAI1F,IAAIyF,EAAMC,QAASC,MAAOF,EAAME,OAAUF,GACzHnW,KAAKgW,YAAc2B,EAASC,WAAa,IAAIrT,IAAIsT,IAAS,IAAMA,IAClE,CAkBAE,QAAAA,GACE,OAAO/X,KAAK+V,KACd,EC3oBa,MAAMiC,GAOnB/D,WAAAA,CAAYgE,EAASnW,EAAU,CAAC,EAAGwO,GACjCtQ,KAAKiY,QAAUA,EACfjY,KAAKoU,UAAYtS,EAAQsS,WAAa,IACtCpU,KAAK8W,SAAW9W,KAAKkY,OAAOD,GAC5BjY,KAAKsQ,KAAOA,EAEZtQ,KAAKmY,iBAAmBnY,KAAK8W,SAASpN,KAAK0O,GAAoB,kBAAbA,EAAI1I,MACtD1P,KAAKqY,uBAAyBrY,KAAK8W,SAASpN,KAAK0O,QAAwBnS,IAAjBmS,EAAI/R,UAC5DrG,KAAKsY,qBAAuBtY,KAAK8W,SAASpN,KAAK0O,QAAwBnS,IAAjBmS,EAAInD,SAC5D,CAQAiD,MAAAA,CAAOD,GACL,MAAMnB,EAAW,GAGjB,IAAI1U,EAAI,EACJmW,EAAc,GAElB,KAAOnW,EAAI6V,EAAQ5V,QACb4V,EAAQ7V,KAAOpC,KAAKoU,UAElBhS,EAAI,EAAI6V,EAAQ5V,QAAU4V,EAAQ7V,EAAI,KAAOpC,KAAKoU,WAEhDmE,EAAYxV,SACd+T,EAAS5S,KAAKlE,KAAKwY,cAAcD,EAAYxV,SAC7CwV,EAAc,IAGhBzB,EAAS5S,KAAK,CAAEwL,KAAM,kBACtBtN,GAAK,IAGDmW,EAAYxV,QACd+T,EAAS5S,KAAKlE,KAAKwY,cAAcD,EAAYxV,SAE/CwV,EAAc,GACdnW,MAGFmW,GAAeN,EAAQ7V,GACvBA,KASJ,OAJImW,EAAYxV,QACd+T,EAAS5S,KAAKlE,KAAKwY,cAAcD,EAAYxV,SAGxC+T,CACT,CAQA0B,aAAAA,CAAcC,GACZ,MAAMpB,EAAU,CAAE3H,KAAM,OAwBxB,IAAIgJ,EAAiB,KACjBC,EAAkBF,EAEtB,MAAMG,EAAeH,EAAKjS,MAAM,8BAChC,GAAIoS,IACFD,EAAkBC,EAAa,GAAKA,EAAa,GAC7CA,EAAa,IAAI,CACnB,MAAMC,EAAUD,EAAa,GAAGtT,MAAM,GAAI,GACtCuT,IACFH,EAAiBG,EAErB,CAIF,IAAIpE,EAcAF,EAbAuE,EAAiBH,EAErB,GAAIA,EAAgB3R,SAAS,MAAO,CAClC,MAAM+R,EAAUJ,EAAgB1U,QAAQ,MAIxC,GAHAwQ,EAAYkE,EAAgB3V,UAAU,EAAG+V,GAAShW,OAClD+V,EAAiBH,EAAgB3V,UAAU+V,EAAU,GAAGhW,QAEnD0R,EACH,MAAM,IAAI7K,MAAM,iCAAiC6O,IAErD,CAIA,IAAIO,EAAgB,KAEpB,GAAIF,EAAe9R,SAAS,KAAM,CAChC,MAAMiS,EAAaH,EAAeI,YAAY,KACxCC,EAAUL,EAAe9V,UAAU,EAAGiW,GAAYlW,OAClDqW,EAAUN,EAAe9V,UAAUiW,EAAa,GAAGlW,OAG/B,CAAC,QAAS,OAAQ,MAAO,QAAQiE,SAASoS,IAClE,eAAetL,KAAKsL,IAGpB7E,EAAM4E,EACNH,EAAgBI,GAGhB7E,EAAMuE,CAEV,MACEvE,EAAMuE,EAGR,IAAKvE,EACH,MAAM,IAAI3K,MAAM,4BAA4B6O,KAS9C,GANApB,EAAQ9C,IAAMA,EACVE,IACF4C,EAAQ5C,UAAYA,GAIlBiE,EACF,GAAIA,EAAe1R,SAAS,KAAM,CAChC,MAAMqS,EAAUX,EAAezU,QAAQ,KACvCoT,EAAQhR,SAAWqS,EAAe1V,UAAU,EAAGqW,GAAStW,OACxDsU,EAAQI,UAAYiB,EAAe1V,UAAUqW,EAAU,GAAGtW,MAC5D,MACEsU,EAAQhR,SAAWqS,EAAe3V,OAKtC,GAAIiW,EAAe,CACjB,MAAMM,EAAWN,EAAcxS,MAAM,kBACjC8S,GACFjC,EAAQpC,SAAW,MACnBoC,EAAQK,cAAgB5D,SAASwF,EAAS,GAAI,KAE9CjC,EAAQpC,SAAW+D,CAEvB,CAEA,OAAO3B,CACT,CAMA,UAAIhV,GACF,OAAOrC,KAAK8W,SAASzU,MACvB,CAMA0U,eAAAA,GACE,OAAO/W,KAAKmY,gBACd,CAMAoB,qBAAAA,GACE,OAAOvZ,KAAKqY,sBACd,CAMAmB,mBAAAA,GACE,OAAOxZ,KAAKsY,oBACd,CAMAhD,QAAAA,GACE,OAAOtV,KAAKiY,OACd,EC7Ma,MAAMwB,GACnBxF,WAAAA,GAEEjU,KAAK0Z,eAAiB,IAAIhJ,IAG1B1Q,KAAK2Z,iBAAmB,IAAIjJ,IAG5B1Q,KAAK4Z,eAAiB,GAGtB5Z,KAAK6Z,mBAAqB,IAAInJ,IAG9B1Q,KAAK8Z,UAAY,IAAIrO,IAGrBzL,KAAK+Z,SAAU,CACjB,CAcA9N,GAAAA,CAAIwJ,GACF,GAAIzV,KAAK+Z,QACP,MAAM,IAAIC,UACR,gFAKJ,GAAIha,KAAK8Z,UAAU1H,IAAIqD,EAAWwC,SAAU,OAAOjY,KAGnD,GAFAA,KAAK8Z,UAAU7N,IAAIwJ,EAAWwC,SAE1BxC,EAAWsB,kBAAmB,CAChC,MAAMkD,EAAUxE,EAAWqB,SAASrB,EAAWqB,SAASzU,OAAS,GACjE,GAAI4X,GAA4B,kBAAjBA,EAAQvK,MAA4C,MAAhBuK,EAAQ1F,IAAa,CACtE,MAAMA,EAAM0F,EAAQ1F,IACfvU,KAAK6Z,mBAAmBzH,IAAImC,IAAMvU,KAAK6Z,mBAAmB1I,IAAIoD,EAAK,IACxEvU,KAAK6Z,mBAAmBrZ,IAAI+T,GAAKrQ,KAAKuR,EACxC,MACEzV,KAAK4Z,eAAe1V,KAAKuR,GAE3B,OAAOzV,IACT,CAEA,MAAMuW,EAAQd,EAAWpT,OACnB4X,EAAUxE,EAAWqB,SAASrB,EAAWqB,SAASzU,OAAS,GAC3DkS,EAAM0F,GAAS1F,IAErB,GAAKA,GAAe,MAARA,EAIL,CAEL,MAAMpU,EAAM,GAAGoW,KAAShC,IACnBvU,KAAK0Z,eAAetH,IAAIjS,IAAMH,KAAK0Z,eAAevI,IAAIhR,EAAK,IAChEH,KAAK0Z,eAAelZ,IAAIL,GAAK+D,KAAKuR,EACpC,MAPOzV,KAAK2Z,iBAAiBvH,IAAImE,IAAQvW,KAAK2Z,iBAAiBxI,IAAIoF,EAAO,IACxEvW,KAAK2Z,iBAAiBnZ,IAAI+V,GAAOrS,KAAKuR,GAQxC,OAAOzV,IACT,CAcAka,MAAAA,CAAOC,GACL,IAAK,MAAMC,KAAQD,EAAana,KAAKiM,IAAImO,GACzC,OAAOpa,IACT,CAQAoS,GAAAA,CAAIqD,GACF,OAAOzV,KAAK8Z,UAAU1H,IAAIqD,EAAWwC,QACvC,CAMA,QAAIoC,GACF,OAAOra,KAAK8Z,UAAUO,IACxB,CASAC,IAAAA,GAEE,OADAta,KAAK+Z,SAAU,EACR/Z,IACT,CAMA,YAAIua,GACF,OAAOva,KAAK+Z,OACd,CAkBArE,UAAAA,CAAWxB,GACT,OAAmC,OAA5BlU,KAAKwa,UAAUtG,EACxB,CAkBAsG,SAAAA,CAAUtG,GACR,MAAMqC,EAAQrC,EAAQmB,WAChBd,EAAML,EAAQG,gBAGdoG,EAAW,GAAGlE,KAAShC,IACvBmG,EAAc1a,KAAK0Z,eAAelZ,IAAIia,GAC5C,GAAIC,EACF,IAAK,IAAItY,EAAI,EAAGA,EAAIsY,EAAYrY,OAAQD,IACtC,GAAI8R,EAAQjP,QAAQyV,EAAYtY,IAAK,OAAOsY,EAAYtY,GAK5D,MAAMuY,EAAiB3a,KAAK2Z,iBAAiBnZ,IAAI+V,GACjD,GAAIoE,EACF,IAAK,IAAIvY,EAAI,EAAGA,EAAIuY,EAAetY,OAAQD,IACzC,GAAI8R,EAAQjP,QAAQ0V,EAAevY,IAAK,OAAOuY,EAAevY,GAKlE,MAAMwY,EAAa5a,KAAK6Z,mBAAmBrZ,IAAI+T,GAC/C,GAAIqG,EACF,IAAK,IAAIxY,EAAI,EAAGA,EAAIwY,EAAWvY,OAAQD,IACrC,GAAI8R,EAAQjP,QAAQ2V,EAAWxY,IAAK,OAAOwY,EAAWxY,GAG1D,IAAK,IAAIA,EAAI,EAAGA,EAAIpC,KAAK4Z,eAAevX,OAAQD,IAC9C,GAAI8R,EAAQjP,QAAQjF,KAAK4Z,eAAexX,IAAK,OAAOpC,KAAK4Z,eAAexX,GAG1E,OAAO,IACT,ECtNK,MAw9BMyY,GAAW,CACtBC,KAAM,IACNC,MAAO,IACPC,OAAQ,IACRC,IAAK,IACLC,KAAM,IACNC,OAAQ,IACRC,KAAM,IACNC,IAAK,IACLC,GAAI,IACJC,KAAM,KACNC,KAAM,IACNC,IAAK,IACLC,IAAK,IACLC,KAAM,IACNC,MAAO,KAkGIC,GAAM,CACjBC,IAAK,IACLC,KAAM,IACNC,GAAI,IACJC,GAAI,IACJC,KAAM,KAEKC,GAAc,CACzBC,KAAM,IACNC,KAAM,IACNC,IAAK,IACLC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,OAAQ,IACRC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,KAAM,IACNC,KAAM,IACNC,KAAM,IACNC,IAAK,IACLC,OAAQ,IACRC,OAAQ,IACRC,OAAQ,KCvlCGC,GAAgBnd,OAAOod,OAAO,CAEzCC,MAAO,QAEPC,MAAO,QAEPC,MAAO,UAOHC,GAAgB,IAAIpS,IAAI,0BAQ9B,SAASqD,GAAmBtJ,GAC1B,GAAgB,MAAZA,EAAK,GACP,MAAM,IAAIoE,MAAM,2DAA2DpE,MAE7E,IAAK,MAAMsY,KAAMtY,EACf,GAAIqY,GAAczL,IAAI0L,GACpB,MAAM,IAAIlU,MAAM,uCAAuCkU,uBAAwBtY,MAGnF,OAAOA,CACT,CAaA,SAASuY,MAAmBC,GAC1B,MAAMC,EAAM5d,OAAO0L,OAAO,MAC1B,IAAK,MAAMxH,KAAOyZ,EAChB,GAAKzZ,EACL,IAAK,MAAMpE,KAAOE,OAAOiM,KAAK/H,GAAM,CAClC,MAAM2Z,EAAM3Z,EAAIpE,GAChB,GAAmB,iBAAR+d,EACTD,EAAI9d,GAAO+d,OACN,GAAIA,GAAsB,iBAARA,QAAgCjY,IAAZiY,EAAIjW,IAAmB,CAElE,MAAMA,EAAMiW,EAAIjW,IACG,iBAARA,IACTgW,EAAI9d,GAAO8H,EAGf,CACF,CAEF,OAAOgW,CACT,CAMA,MAAME,GAAsB,WACtBC,GAAkB,OAClBC,GAAiB,MAuBjBC,GAAYje,OAAOod,OAAO,CAAEc,MAAO,EAAGC,MAAO,EAAGC,OAAQ,EAAGC,MAAO,IAIlEC,GAAmB,IAAIlT,IAAI,CAAC,EAAM,GAAM,KAgD/B,MAAMmT,GAoCnB3K,WAAAA,CAAYnS,EAAU,CAAC,GAtGzB,IAAyBoc,EAuGrBle,KAAK6e,OAAS/c,EAAQgd,OAAS,CAAC,EAChC9e,KAAK+e,oBAAsB/e,KAAK6e,OAAO5U,oBAAsB,EAC7DjK,KAAKgf,mBAAqBhf,KAAK6e,OAAO1U,mBAAqB,EAC3DnK,KAAKif,WAA0C,mBAAtBnd,EAAQod,UAA2Bpd,EAAQod,UAAYC,GAAKA,EACrFnf,KAAKof,aA3GgBlB,EA2Gcle,KAAK6e,OAAOQ,eAAiBlB,KA1GtDD,IAAQC,GAChBD,IAAQG,GAAuB,IAAI5S,IAAI,CAAC4S,KACxCH,IAAQE,GAAwB,IAAI3S,IAAI,CAAC2S,KACzC1S,MAAMrD,QAAQ6V,GAAa,IAAIzS,IAAIyS,GAChC,IAAIzS,IAAI,CAAC0S,KAJgC,IAAI1S,IAAI,CAAC0S,KA2GvDne,KAAKsf,gBAAkBxd,EAAQyd,iBAAkB,EAEjDvf,KAAKwf,SAAWzB,GAAgB0B,GAAsB3d,EAAQ4d,eAAiB,MAK/E1f,KAAK2f,aAAetf,OAAO0L,OAAO,MAIlC/L,KAAK4f,UAAYvf,OAAO0L,OAAO,MAG/B/L,KAAK6f,iBAAmB,EACxB7f,KAAK8f,gBAAkB,EAIvB9f,KAAK+f,WAAa,IAAItU,IAAI3J,EAAQ2c,QAAU/S,MAAMrD,QAAQvG,EAAQ2c,QAAU3c,EAAQ2c,OAAS,IAE7Fze,KAAKggB,UAAY,IAAIvU,IAAI3J,EAAQ0c,OAAS9S,MAAMrD,QAAQvG,EAAQ0c,OAAS1c,EAAQ0c,MAAQ,IAGzF,MAAMyB,EA3GV,SAAwBC,GACtB,IAAKA,EACH,MAAO,CAAEvS,WAAY,EAAKwS,QAAS7B,GAAUC,MAAO6B,UAAW9B,GAAUG,QAE3E,MAAM9Q,EAAgC,MAAnBuS,EAAIvS,WAAqB,IAAM,EAC5CwS,EAAU7B,GAAU4B,EAAIG,QAAU/B,GAAUC,MAC5C6B,EAAY9B,GAAU4B,EAAII,UAAYhC,GAAUG,OAGtD,MAAO,CAAE9Q,aAAYwS,UAASC,UADV5V,KAAKC,IAAI2V,EAAW9B,GAAUG,QAEpD,CAiGmB8B,CAAeze,EAAQoe,KACtClgB,KAAKwgB,eAAiBP,EAAOtS,WAC7B3N,KAAKygB,YAAcR,EAAOE,QAC1BngB,KAAK0gB,cAAgBT,EAAOG,UAI5BpgB,KAAK2gB,kBAAwD,mBAA7B7e,EAAQ8e,iBACpC9e,EAAQ8e,iBACR,KAEJ5gB,KAAK6gB,eAAkD,mBAA1B/e,EAAQgf,cACjChf,EAAQgf,cACR,IACN,CAiBAC,sBAAAA,CAAuBC,EAAMxb,EAAMxE,EAAOigB,GACxC,IAAKD,EAAM,OAAO,EAClB,MAAME,EAASF,EAAKxb,EAAMxE,GAC1B,GAAIkgB,IAAW1D,GAAcG,MAAO,OAAO,EAC3C,GAAIuD,IAAW1D,GAAcI,MAC3B,MAAM,IAAIhU,MACR,mCAAmCqX,cAAoBzb,4BAG3D,OAAO,CACT,CAcA2b,mBAAAA,CAAoB5c,GAClB,GAAIA,EACF,IAAK,MAAMpE,KAAOE,OAAOiM,KAAK/H,GAC5BuK,GAAmB3O,GAGvB,IAAKH,KAAK2gB,kBAER,YADA3gB,KAAK2f,aAAe5B,GAAgBxZ,IAItC,MAAM6c,EAAOrD,GAAgBxZ,GACvB8c,EAAWhhB,OAAO0L,OAAO,MAC/B,IAAK,MAAOvG,EAAMxE,KAAUX,OAAOihB,QAAQF,GACrCphB,KAAK+gB,uBAAuB/gB,KAAK2gB,kBAAmBnb,EAAMxE,EAAO,cACnEqgB,EAAS7b,GAAQxE,GAGrBhB,KAAK2f,aAAe0B,CACtB,CASAE,iBAAAA,CAAkBphB,EAAKa,GACrB8N,GAAmB3O,GACE,iBAAVa,IAA8C,IAAxBA,EAAMiD,QAAQ,MACzCjE,KAAK+gB,uBAAuB/gB,KAAK2gB,kBAAmBxgB,EAAKa,EAAO,cAClEhB,KAAK2f,aAAaxf,GAAOa,EAG/B,CAaAwgB,gBAAAA,CAAiBjd,GAGf,GAFAvE,KAAK6f,iBAAmB,EACxB7f,KAAK8f,gBAAkB,GAClB9f,KAAK6gB,eAER,YADA7gB,KAAK4f,UAAY7B,GAAgBxZ,IAGnC,MAAM6c,EAAOrD,GAAgBxZ,GACvB8c,EAAWhhB,OAAO0L,OAAO,MAC/B,IAAK,MAAOvG,EAAMxE,KAAUX,OAAOihB,QAAQF,GACrCphB,KAAK+gB,uBAAuB/gB,KAAK6gB,eAAgBrb,EAAMxE,EAAO,WAChEqgB,EAAS7b,GAAQxE,GAGrBhB,KAAK4f,UAAYyB,CACnB,CAWAxK,KAAAA,GAIE,OAHA7W,KAAK4f,UAAYvf,OAAO0L,OAAO,MAC/B/L,KAAK6f,iBAAmB,EACxB7f,KAAK8f,gBAAkB,EAChB9f,IACT,CAWAiO,aAAAA,CAAcwT,GACZzhB,KAAKwgB,eAA6B,MAAZiB,EAAkB,IAAM,CAChD,CAYAC,MAAAA,CAAOhU,GACL,GAAmB,iBAARA,GAAmC,IAAfA,EAAIrL,OAAc,OAAOqL,EAExD,IAA0B,IAAtBA,EAAIzJ,QAAQ,KAAa,OAAOyJ,EAEpC,MAAMiU,EAAWjU,EACXkU,EAAS,GACTzc,EAAMuI,EAAIrL,OAChB,IAAIwf,EAAO,EACPzf,EAAI,EAER,MAAM0f,EAAkB9hB,KAAK+e,oBAAsB,EAC7CgD,EAAc/hB,KAAKgf,mBAAqB,EACxCgD,EAAcF,GAAmBC,EAEvC,KAAO3f,EAAI+C,GAAK,CAEd,GAA0B,KAAtBuI,EAAIyE,WAAW/P,GAAqB,CAAEA,IAAK,QAAU,CAKzD,IAAIsD,EAAItD,EAAI,EACZ,KAAOsD,EAAIP,GAA6B,KAAtBuI,EAAIyE,WAAWzM,IAAwBA,EAAItD,GAAM,IAAIsD,IAEvE,GAAIA,GAAKP,GAA6B,KAAtBuI,EAAIyE,WAAWzM,GAAW,CAExCtD,IACA,QACF,CAGA,MAAM2D,EAAQ2H,EAAIpI,MAAMlD,EAAI,EAAGsD,GAC/B,GAAqB,IAAjBK,EAAM1D,OAAc,CAAED,IAAK,QAAU,CAEzC,IAAI6f,EACAC,EAEJ,GAAIliB,KAAK+f,WAAW3N,IAAIrM,GAEtBkc,EAAc,QAGDhc,IAATic,IACFA,EAAO/D,QAEJ,IAAIne,KAAKggB,UAAU5N,IAAIrM,GAAQ,CAEpC3D,IACA,QACF,CAAO,GAA4B,KAAxB2D,EAAMoM,WAAW,GAAqB,CAI/C,MAAMgQ,EAAYniB,KAAKoiB,YAAYrc,GACnC,QAAkBE,IAAdkc,EAAyB,CAE3B/f,IACA,QACF,CACA6f,EAAcE,EACdD,EAAO9D,EACT,KAAO,CAEL,MAAMiE,EAAWriB,KAAKsiB,aAAavc,GACnCkc,EAAcI,GAAUrhB,MACxBkhB,EAAOG,GAAUH,IACnB,EAEA,QAAoBjc,IAAhBgc,GAaJ,GANI7f,EAAIyf,GAAMD,EAAO1d,KAAKwJ,EAAIpI,MAAMuc,EAAMzf,IAC1Cwf,EAAO1d,KAAK+d,GACZJ,EAAOnc,EAAI,EACXtD,EAAIyf,EAGAG,GAAehiB,KAAKuiB,YAAYL,GAAO,CACzC,GAAIJ,IACF9hB,KAAK6f,mBACD7f,KAAK6f,iBAAmB7f,KAAK+e,qBAC/B,MAAM,IAAInV,MAER,2DAAG5J,KAAK6f,sBAAsB7f,KAAK+e,uBAIzC,GAAIgD,EAAa,CAEf,MAAMS,EAAQP,EAAY5f,QAAU0D,EAAM1D,OAAS,GACnD,GAAImgB,EAAQ,IACVxiB,KAAK8f,iBAAmB0C,EACpBxiB,KAAK8f,gBAAkB9f,KAAKgf,oBAC9B,MAAM,IAAIpV,MAER,4DAAG5J,KAAK8f,qBAAqB9f,KAAKgf,qBAI1C,CACF,OAlCE5c,GAmCJ,CAGIyf,EAAO1c,GAAKyc,EAAO1d,KAAKwJ,EAAIpI,MAAMuc,IAGtC,MAAM3e,EAA2B,IAAlB0e,EAAOvf,OAAeqL,EAAMkU,EAAOzR,KAAK,IAEvD,OAAOnQ,KAAKif,WAAW/b,EAAQye,EACjC,CAYAY,WAAAA,CAAYL,GACV,QAAIliB,KAAKof,YAAYhN,IAAIiM,KAClBre,KAAKof,YAAYhN,IAAI8P,EAC9B,CAcAI,YAAAA,CAAa9c,GAGX,OAAIA,KAAQxF,KAAK4f,UAAkB,CAAE5e,MAAOhB,KAAK4f,UAAUpa,GAAO0c,KAAM/D,IACpE3Y,KAAQxF,KAAK2f,aAAqB,CAAE3e,MAAOhB,KAAK2f,aAAana,GAAO0c,KAAM/D,IAC1E3Y,KAAQxF,KAAKwf,SAAiB,CAAExe,MAAOhB,KAAKwf,SAASha,GAAO0c,KAAM9D,SAAtE,CAEF,CAeAqE,YAAAA,CAAavR,GAEX,OAAW,IAAPA,EAAiBlR,KAAK0gB,cAGtBxP,GAAM,OAAUA,GAAM,OAGE,IAAxBlR,KAAKwgB,gBACHtP,GAAM,GAAQA,GAAM,KAASyN,GAAiBvM,IAAIlB,GAJfoN,GAAUG,QAO3C,CACV,CAcAiE,eAAAA,CAAgBxB,EAAQnb,EAAOmL,GAC7B,OAAQgQ,GACN,KAAK5C,GAAUC,MAAO,OAAOhM,OAAOoQ,cAAczR,GAClD,KAAKoN,GAAUG,OAAQ,MAAO,GAC9B,KAAKH,GAAUE,MAAO,OACtB,KAAKF,GAAUI,MACb,MAAM,IAAI9U,MAER,2DAAI7D,SAAamL,EAAGoE,SAAS,IAAIvG,cAAc6T,SAAS,EAAG,SAE/D,QAAS,OAAOrQ,OAAOoQ,cAAczR,GAEzC,CAkBAkR,WAAAA,CAAYrc,GAEV,MAAM8c,EAAS9c,EAAMoM,WAAW,GAChC,IAAIjB,EAQJ,GANEA,EADa,MAAX2R,GAAqC,KAAXA,EACvB/O,SAAS/N,EAAMT,MAAM,GAAI,IAEzBwO,SAAS/N,EAAMT,MAAM,GAAI,IAI5B0N,OAAO8P,MAAM5R,IAAOA,EAAK,GAAKA,EAAK,QAAU,OAGjD,MAAM6R,EAAU/iB,KAAKyiB,aAAavR,GAGlC,IAAKlR,KAAKsf,iBAAmByD,EAAUzE,GAAUG,OAAQ,OAGzD,MAAMuE,GAAyB,IAAbD,EACd/iB,KAAKygB,YACLjW,KAAKC,IAAIzK,KAAKygB,YAAasC,GAG/B,OAAO/iB,KAAK0iB,gBAAgBM,EAAWjd,EAAOmL,EAChD,ECpnBF,MAgFA,GAhFqB,CACnB,CACE+R,GAAI,yBACJC,YAAa,sEACbjL,QAAS,QAEX,CACEgL,GAAI,mBACJC,YAAa,8DACbjL,QAAS,4CAEX,CACEgL,GAAI,iBACJC,YAAa,yCACbjL,QAAS,0BAEX,CACEgL,GAAI,oBACJC,YAAa,4CACbjL,QAAS,6BAEX,CACEgL,GAAI,kBACJC,YAAa,+BACbjL,QAAS,2BAEX,CACEgL,GAAI,kBACJC,YAAa,wCACbjL,QAAS,2BAEX,CACEgL,GAAI,iBACJC,YAAa,+CAEbjL,QAAS,kCAEX,CACEgL,GAAI,cACJC,YAAa,uDACbjL,QAAS,8BAEX,CACEgL,GAAI,uBACJC,YAAa,4DAEbjL,QAAS,sDAEX,CACEgL,GAAI,wBACJC,YAAa,4BACbjL,QAAS,4BAEX,CACEgL,GAAI,uBACJC,YAAa,4BACbjL,QAAS,4BAEX,CACEgL,GAAI,sBACJC,YAAa,qDACbjL,QAAS,+BAEX,CACEgL,GAAI,oBACJC,YAAa,kDACbjL,QAAS,6BAEX,CACEgL,GAAI,oBACJC,YAAa,uDACbjL,QAAS,0BAEX,CACEgL,GAAI,yBACJC,YAAa,yEACbjL,QAAS,4BC5Cb,GAF4B,IAAIkL,GAlB9B,CACEF,GAAI,mBACJC,YAAa,+DACbjL,QAAS,cAEX,CACEgL,GAAI,oBACJC,YAAa,mEACbjL,QAAS,sEAEX,CACEgL,GAAI,mBACJC,YAAa,yDACbjL,QAAS,sBC8Db,GA3FsB,CACpB,CACEgL,GAAI,mBACJC,YAAa,sBACbjL,QAAS,kBAEX,CACEgL,GAAI,oBACJC,YAAa,wBACbjL,QAAS,mBAEX,CACEgL,GAAI,2BACJC,YAAa,6DAEbjL,QAAS,oHAEX,CACEgL,GAAI,yBACJC,YAAa,uBACbjL,QAAS,wBAEX,CACEgL,GAAI,iBACJC,YAAa,uDACbjL,QAAS,wCAEX,CACEgL,GAAI,kBACJC,YAAa,iCACbjL,QAAS,gDAEX,CACEgL,GAAI,gBACJC,YAAa,+CACbjL,QAAS,6CAEX,CACEgL,GAAI,4BACJC,YAAa,qEAEbjL,QAAS,qBAEX,CACEgL,GAAI,gCACJC,YAAa,gEAEbjL,QAAS,4CAEX,CACEgL,GAAI,oCACJC,YAAa,sFACbjL,QAAS,uEAEX,CACEgL,GAAI,wBACJC,YAAa,+DACbjL,QAAS,qCAEX,CACEgL,GAAI,oBACJC,YAAa,sDACbjL,QAAS,4BAEX,CACEgL,GAAI,gBACJC,YAAa,uDACbjL,QAAS,eAEX,CACEgL,GAAI,oBACJC,YAAa,kDACbjL,QAAS,mDAEX,CACEgL,GAAI,cACJC,YAAa,kEACbjL,QAAS,eAEX,CACEgL,GAAI,cACJC,YAAa,cACbjL,QAAS,kBAEX,CACEgL,GAAI,YACJC,YAAa,yEACbjL,QAAS,iBCpBb,GAjEqB,CACnB,CACEgL,GAAI,sBACJC,YAAa,qEACbjL,QAAS,gBAEX,CACEgL,GAAI,kBACJC,YAAa,qEACbjL,QAAS,SAEX,CACEgL,GAAI,6BACJC,YAAa,6DACbjL,QAAS,4BAEX,CACEgL,GAAI,wBACJC,YAAa,gEAEbjL,QAAS,yBAEX,CACEgL,GAAI,oBACJC,YAAa,8DACbjL,QAAS,oBAEX,CACEgL,GAAI,oBACJC,YAAa,8DACbjL,QAAS,oBAEX,CACEgL,GAAI,yBACJC,YAAa,6EACbjL,QAAS,kBAEX,CACEgL,GAAI,qBACJC,YAAa,6EAEbjL,QAAS,sBAEX,CACEgL,GAAI,0BACJC,YAAa,0EACbjL,QAAS,iCAEX,CACEgL,GAAI,wBACJC,YAAa,iEACbjL,QAAS,QAEX,CACEgL,GAAI,oBACJC,YAAa,yCACbjL,QAAS,OAEX,CACEgL,GAAI,eACJC,YAAa,gDACbjL,QAAS,QCOb,GAtEqB,CACnB,CACEgL,GAAI,qBACJC,YAAa,iDACbjL,QAAS,kBAEX,CACEgL,GAAI,4BACJC,YAAa,iEACbjL,QAAS,kDAEX,CACEgL,GAAI,sBACJC,YAAa,+DACbjL,QAAS,sCAEX,CACEgL,GAAI,oBACJC,YAAa,8DACbjL,QAAS,yBAEX,CACEgL,GAAI,mBACJC,YAAa,2EAGbjL,QAAS,uEAEX,CACEgL,GAAI,mBACJC,YAAa,6EACbjL,QAAS,8DAEX,CACEgL,GAAI,wBACJC,YAAa,sCACbjL,QAAS,0EAEX,CACEgL,GAAI,qBACJC,YAAa,oEACbjL,QAAS,oDAEX,CACEgL,GAAI,oBACJC,YAAa,8EACbjL,QAAS,gGAEX,CACEgL,GAAI,sBACJC,YAAa,mDACbjL,QAAS,qBAEX,CACEgL,GAAI,qBACJC,YAAa,qEACbjL,QAAS,kDAEX,CACEgL,GAAI,qBACJC,YAAa,2DACbjL,QAAS,oFAEX,CACEgL,GAAI,uBACJC,YAAa,gFACbjL,QAAS,yCC4Bb,GAhGuB,CACrB,CACEgL,GAAI,4BACJC,YAAa,0DACbjL,QAAS,UAEX,CACEgL,GAAI,+BACJC,YAAa,6DACbjL,QAAS,UAEX,CACEgL,GAAI,+BACJC,YAAa,qDACbjL,QAAS,2BAEX,CACEgL,GAAI,kBACJC,YAAa,8EACbjL,QAAS,YAEX,CACEgL,GAAI,kBACJC,YAAa,0CACbjL,QAAS,KAEX,CACEgL,GAAI,aACJC,YAAa,6BACbjL,QAAS,MAEX,CACEgL,GAAI,qBACJC,YAAa,6BACbjL,QAAS,MAEX,CACEgL,GAAI,oBACJC,YAAa,4BACbjL,QAAS,QAEX,CACEgL,GAAI,iBACJC,YAAa,uCACbjL,QAAS,KAEX,CACEgL,GAAI,qBACJC,YAAa,4CACbjL,QAAS,QAEX,CACEgL,GAAI,qBACJC,YAAa,wEACbjL,QAAS,QAEX,CACEgL,GAAI,qBACJC,YAAa,gDACbjL,QAAS,UAEX,CACEgL,GAAI,oBACJC,YAAa,gCACbjL,QAAS,KAEX,CACEgL,GAAI,0BACJC,YAAa,gEACbjL,QAAS,UAEX,CACEgL,GAAI,kBACJC,YAAa,0DAEbjL,QAAS,aAEX,CACEgL,GAAI,sBACJC,YAAa,2EACbjL,QAAS,gBAEX,CACEgL,GAAI,sBACJC,YAAa,mDACbjL,QAAS,mBAEX,CACEgL,GAAI,kBACJC,YAAa,yEAGbjL,QAAS,kDCzCb,GA/CuB,CACrB,CACEgL,GAAI,+BACJC,YAAa,gFAEbjL,QAAS,wBAEX,CACEgL,GAAI,+BACJC,YAAa,kEACbjL,QAAS,wBAEX,CACEgL,GAAI,sBACJC,YAAa,qEACbjL,QAAS,8BAEX,CACEgL,GAAI,4BACJC,YAAa,yEAEbjL,QAAS,+DAEX,CACEgL,GAAI,yBACJC,YAAa,sDACbjL,QAAS,kCAEX,CACEgL,GAAI,wBACJC,YAAa,yDACbjL,QAAS,mBAEX,CACEgL,GAAI,yBACJC,YAAa,sGAEbjL,QAAS,uBAEX,CACEgL,GAAI,iCACJC,YAAa,6EAEbjL,QAAS,yCC/BPrB,GAAM,aAyFZ,GAvFuB,CAErB,CACEqM,GAAI,uBACJC,YAAa,gEACbjL,QAAS,IAAI9W,OAAO,WAAWyV,KAAO,MAExC,CACEqM,GAAI,oBACJC,YAAa,4DACbjL,QAAS,IAAI9W,OAAO,QAAQyV,KAAO,MAErC,CACEqM,GAAI,oBACJC,YAAa,4DACbjL,QAAS,IAAI9W,OAAO,UAAUyV,KAAO,MAEvC,CACEqM,GAAI,oBACJC,YAAa,2CACbjL,QAAS,IAAI9W,OAAO,UAAUyV,KAAO,MAEvC,CACEqM,GAAI,uBACJC,YAAa,gFACbjL,QAAS,IAAI9W,OAAO,WAAWyV,KAAO,MAExC,CACEqM,GAAI,oBACJC,YAAa,0DACbjL,QAAS,IAAI9W,OAAO,QAAQyV,YAAc,MAE5C,CACEqM,GAAI,qBACJC,YAAa,wCACbjL,QAAS,IAAI9W,OAAO,SAASyV,YAAc,MAE7C,CACEqM,GAAI,qBACJC,YAAa,wCACbjL,QAAS,IAAI9W,OAAO,SAASyV,YAAc,MAE7C,CACEqM,GAAI,wBACJC,YAAa,qDACbjL,QAAS,IAAI9W,OAAO,YAAYyV,KAAO,MAEzC,CACEqM,GAAI,oBACJC,YAAa,0DACbjL,QAAS,IAAI9W,OAAO,QAAQyV,YAAc,MAE5C,CACEqM,GAAI,sBACJC,YAAa,mEACbjL,QAAS,IAAI9W,OAAO,UAAUyV,KAAO,MAEvC,CACEqM,GAAI,0BACJC,YAAa,4DACbjL,QAAS,IAAI9W,OAAO,cAAcyV,KAAO,MAE3C,CACEqM,GAAI,6BACJC,YAAa,gEACbjL,QAAS,IAAI9W,OAAO,iBAAiByV,KAAO,MAG9C,CACEqM,GAAI,wBACJC,YAAa,2DACbjL,QAAS,aAEX,CACEgL,GAAI,8BACJC,YAAa,4FAGbjL,QAAS,sCAEX,CACEgL,GAAI,sBACJC,YAAa,uDACbjL,QAAS,0BCZb,GA5EqB,CAEnB,CACEgL,GAAI,qBACJC,YAAa,2DACbjL,QAAS,UAEX,CACEgL,GAAI,uBACJC,YAAa,qEACbjL,QAAS,YAEX,CACEgL,GAAI,sBACJC,YAAa,kFACbjL,QAAS,kBAIX,CACEgL,GAAI,qBACJC,YAAa,wEACbjL,QAAS,iBAEX,CACEgL,GAAI,2BACJC,YAAa,oFAEbjL,QAAS,WAEX,CACEgL,GAAI,mBACJC,YAAa,8EACbjL,QAAS,8DAIX,CACEgL,GAAI,wBACJC,YAAa,qEACbjL,QAAS,wBAEX,CACEgL,GAAI,sBACJC,YAAa,iEACbjL,QAAS,qBAEX,CACEgL,GAAI,wBACJC,YAAa,6FAIbjL,QAAS,oFAEX,CACEgL,GAAI,uBACJC,YAAa,sDACbjL,QAAS,qBAIX,CACEgL,GAAI,gBACJC,YAAa,yEACbjL,QAAS,YAIX,CACEgL,GAAI,kBACJC,YAAa,mFACbjL,QAAS,WC2Db,SAASmL,GAAUpiB,EAAOqiB,GACxB,MAAMC,EAAQD,EAAKC,OAAS,SAC5B,IAAK,MAAMC,KAAQF,EACjB,GAAIE,EAAKtL,QAAQnK,KAAK9M,GACpB,MAAO,CAAEigB,QAASqC,EAAOL,GAAIM,EAAKN,GAAIC,YAAaK,EAAKL,YAAajL,QAASsL,EAAKtL,SAGvF,OAAO,IACT,CAsBA,SAASuL,GAASxiB,EAAOigB,IAzFzB,SAAsBjgB,GACpB,GAAqB,iBAAVA,EACT,MAAM,IAAIgZ,UACR,0DAA0DhZ,EAGhE,EAoFEyiB,CAAaziB,GA/Ef,SAAuBigB,GACrB,KAAIA,aAAmB9f,QAAvB,CAEA,IAAIuK,MAAMrD,QAAQ4Y,GAmBlB,MAAM,IAAIjH,UACR,uIACyEiH,GApBzE,GAAuB,IAAnBA,EAAQ5e,OACV,MAAM,IAAI2X,UAAU,iDAGtB,GAAItO,MAAMrD,QAAQ4Y,EAAQ,IAExB,IAAK,MAAMoC,KAAQpC,EACjB,IAAKvV,MAAMrD,QAAQgb,IAAyB,IAAhBA,EAAKhhB,OAC/B,MAAM,IAAI2X,UACR,uFAZ2B,CAyBvC,CAsDE0J,CAAczC,GAEd,MAAM,MAAE0C,EAAK,MAAEC,GAhDjB,SAAmB3C,GACjB,OAAIA,aAAmB9f,OAAe,CAAEwiB,MAAO,KAAMC,MAAO3C,GAExDvV,MAAMrD,QAAQ4Y,EAAQ,IAAY,CAAE0C,MAAO1C,EAAS2C,MAAO,MACxD,CAAED,MAAO,CAAC1C,GAAU2C,MAAO,KACpC,CA2C2BC,CAAU5C,GAEnC,GAAI2C,EAAO,OAAOA,EAAM9V,KAAK9M,GAE7B,IAAK,MAAMqiB,KAAQM,EACjB,GAA+B,OAA3BP,GAAUpiB,EAAOqiB,GAAgB,OAAO,EAE9C,OAAO,CACT,CCjMA,SAAAS,KAAA,OAAAA,GAAAzjB,OAAA0B,OAAA1B,OAAA0B,OAAAgiB,OAAA,SAAArQ,GAAA,QAAAsQ,EAAA,EAAAA,EAAAC,UAAA5hB,OAAA2hB,IAAA,KAAAxf,EAAAyf,UAAAD,GAAA,QAAA7E,KAAA3a,GAAA,IAAA5D,eAAAC,KAAA2D,EAAA2a,KAAAzL,EAAAyL,GAAA3a,EAAA2a,GAAA,QAAAzL,CAAA,EAAAoQ,GAAAI,MAAA,KAAAD,UAAA,CA4BA,SAASE,GAAqBC,EAAetiB,GAC3C,IAAKsiB,EAAe,MAAO,CAAC,EAG5B,IAAMpb,EAAQlH,EAAQqF,oBAClBid,EAActiB,EAAQqF,qBACtBid,EAEJ,IAAKpb,EAAO,MAAO,CAAC,EAEpB,IAAMqb,EAAW,CAAC,EAClB,IAAK,IAAMlkB,KAAO6I,EAEZ7I,EAAIyL,WAAW9J,EAAQoF,qBAEzBmd,EADgBlkB,EAAI6C,UAAUlB,EAAQoF,oBAAoB7E,SACtC2G,EAAM7I,GAG1BkkB,EAASlkB,GAAO6I,EAAM7I,GAG1B,OAAOkkB,CACT,CAOA,SAASC,GAAiBC,GACxB,GAAKA,GAAoC,iBAAfA,EAA1B,CAEA,IAAMtL,EAAasL,EAAWtgB,QAAQ,KACtC,IAAoB,IAAhBgV,GAAqBA,EAAa,EAAG,CACvC,IAAMuL,EAAKD,EAAWvhB,UAAU,EAAGiW,GAEnC,GAAW,UAAPuL,EACF,OAAOA,CAEX,CATmE,CAWrE,CDtBAC,GAAKnB,MAAc,OACnBzH,GAAIyH,MAAe,MACnBoB,GAAIpB,MAAe,MACnBqB,GAAIrB,MAAe,MACnBsB,GAAWtB,MAAQ,aACnBuB,GAAMvB,MAAa,QACnBwB,GAAMxB,MAAa,QACnByB,GAAMzB,MAAa,QACnB0B,GAAI1B,MAAe,MAEWjjB,OAAOod,OAAO,CAC1CgH,KAAI,GACJ5I,IAAG,GACH6I,IAAG,GACHC,IAAG,GACH,aAAcC,GACdC,MAAK,GACLC,MAAK,GACLC,MAAK,GACLC,IAAGA,KCGJ,IAEoBC,GACnB,SAAYnjB,EAASojB,GCzER,IAA+B7d,ED0E1CrH,KAAK8B,QAAUA,EACf9B,KAAKmlB,YAAc,KACnBnlB,KAAKolB,cAAgB,GACrBplB,KAAKqlB,SAAWA,GAChBrlB,KAAKslB,cAAgBA,GACrBtlB,KAAKulB,iBAAmBA,GACxBvlB,KAAKwlB,mBAAqBA,GAC1BxlB,KAAKylB,aAAeA,GACpBzlB,KAAK0lB,qBAAuBA,GAC5B1lB,KAAK2lB,iBAAmBA,GACxB3lB,KAAK4lB,oBAAsBA,GAC3B5lB,KAAKmM,SAAWA,GAChBnM,KAAK6lB,mBCrF2B,mBADUxe,EDsFMrH,KAAK8B,QAAQuF,kBCpFlDA,EAEPqE,MAAMrD,QAAQhB,GACP,SAAChB,GACJ,QAAsCyf,EAAtCC,E,8rBAAAC,CAAsB3e,KAAgBye,EAAAC,KAAAE,MAAE,CAAC,IAA9BhO,EAAO6N,EAAA9kB,MACd,GAAuB,iBAAZiX,GAAwB5R,IAAa4R,EAC5C,OAAO,EAEX,GAAIA,aAAmB9W,QAAU8W,EAAQnK,KAAKzH,GAC1C,OAAO,CAEf,CACJ,EAEG,kBAAM,CAAK,EDuElBrG,KAAKkmB,qBAAuB,EAC5BlmB,KAAKmmB,sBAAwB,EAC7BnmB,KAAKomB,cAAe,EACpB,IAAI1G,EAAaoE,GAAA,GAAQjI,IACrB7b,KAAK8B,QAAQ2G,cACfzI,KAAKyI,cAAgBzI,KAAK8B,QAAQ2G,eAEO,iBAA9BzI,KAAK8B,QAAQ0G,aAA2BkX,EAAgB1f,KAAK8B,QAAQ0G,cACzC,IAA9BxI,KAAK8B,QAAQ0G,eAAuBkX,EAAaoE,GAAA,GAAQ3H,GAAgBtB,KAClF7a,KAAKyI,cAAgB,IAAImW,GAAc,CACrCc,cAAaoE,GAAA,GAAOpE,EAAkBwF,GACtC3F,eAAgBvf,KAAK8B,QAAQ0G,aAC7BsW,MAAO,CACL7U,mBAAoBjK,KAAK8B,QAAQyG,gBAAgB0B,mBACjDE,kBAAmBnK,KAAK8B,QAAQyG,gBAAgB4B,kBAChDkV,cAAerf,KAAK8B,QAAQyG,gBAAgBgC,WAG9CuW,cAAe,SAACtb,EAAMxE,GAAK,OAEzBwiB,GAASxiB,EAAO,CAACqlB,GAAcC,KAAgB9I,GAAcG,MAAQH,GAAcE,KAAK,KAO9F1d,KAAKkU,QAAU,IAAI0B,GACnB5V,KAAKumB,gBAAkBvmB,KAAKkU,QAAQ6D,WAGpC/X,KAAKwmB,uBAAwB,EAG7BxmB,KAAKymB,uBAAyB,IAAIhN,GAClC,IAAMiN,EAAgB1mB,KAAK8B,QAAQqG,UACnC,GAAIue,GAAiBA,EAAcrkB,OAAS,EAAG,CAC7C,IAAK,IAAID,EAAI,EAAGA,EAAIskB,EAAcrkB,OAAQD,IAAK,CAC7C,IAAMukB,EAAcD,EAActkB,GACP,iBAAhBukB,EAET3mB,KAAKymB,uBAAuBxa,IAAI,IAAI+L,GAAW2O,IACtCA,aAAuB3O,IAEhChY,KAAKymB,uBAAuBxa,IAAI0a,EAEpC,CACA3mB,KAAKymB,uBAAuBnM,MAC9B,CACF,EAcF,SAASgL,GAAcrd,EAAKnF,EAASiG,EAAO6d,EAAUC,EAAeC,EAAYC,GAC/E,IAAMjlB,EAAU9B,KAAK8B,QACrB,QAAYmE,IAARgC,IACEnG,EAAQ2F,aAAemf,IACzB3e,EAAMA,EAAIlF,QAERkF,EAAI5F,OAAS,GAAG,CACb0kB,IAAgB9e,EAAMjI,KAAK0lB,qBAAqBzd,EAAKnF,EAASiG,IAGnE,IAAMie,EAAiBllB,EAAQiH,MAAQA,EAAMuM,WAAavM,EACpDke,EAASnlB,EAAQkG,kBAAkBlF,EAASmF,EAAK+e,EAAgBH,EAAeC,GACtF,OAAIG,QAEKhf,SACSgf,UAAkBhf,GAAOgf,IAAWhf,EAE7Cgf,EACEnlB,EAAQ2F,YAGEQ,EAAIlF,SACJkF,EAHZif,GAAWjf,EAAKnG,EAAQyF,cAAezF,EAAQ6F,oBAM7CM,CAGb,CAEJ,CAEA,SAASsd,GAAiB3gB,GACxB,GAAI5E,KAAK8B,QAAQwF,eAAgB,CAC/B,IAAMtF,EAAO4C,EAAQkC,MAAM,KACrBqgB,EAA+B,MAAtBviB,EAAQwiB,OAAO,GAAa,IAAM,GACjD,GAAgB,UAAZplB,EAAK,GACP,MAAO,GAEW,IAAhBA,EAAKK,SACPuC,EAAUuiB,EAASnlB,EAAK,GAE5B,CACA,OAAO4C,CACT,CAIA,IAAMyiB,GAAY,IAAIlmB,OAAO,+CAAgD,MAE7E,SAASqkB,GAAmBpiB,EAAS2F,EAAOjG,EAASwkB,QAAK,IAALA,IAAAA,GAAQ,GAC3D,IAAMxlB,EAAU9B,KAAK8B,QACrB,IAAc,IAAVwlB,IAAgD,IAA7BxlB,EAAQuF,kBAAgD,iBAAZjE,EAAuB,CAcxF,IAVA,IAAM6B,ExBvMH,SAAuB5D,EAAQuiB,GAGpC,IAFA,IAAM3e,EAAU,GACZuB,EAAQod,EAAMtiB,KAAKD,GAChBmF,GAAO,CACZ,IAAM+gB,EAAa,GACnBA,EAAWvhB,WAAa4d,EAAM4D,UAAYhhB,EAAM,GAAGnE,OAEnD,IADA,IAAM8C,EAAMqB,EAAMnE,OACTgB,EAAQ,EAAGA,EAAQ8B,EAAK9B,IAC/BkkB,EAAWrjB,KAAKsC,EAAMnD,IAExB4B,EAAQf,KAAKqjB,GACb/gB,EAAQod,EAAMtiB,KAAKD,EACrB,CACA,OAAO4D,CACT,CwByLoBwiB,CAAcrkB,EAASikB,IACjCliB,EAAMF,EAAQ5C,OACd2G,EAAQ,CAAC,EAIT0e,EAAgB,IAAIhc,MAAMvG,GAC5BwiB,GAAc,EACZC,EAAqB,CAAC,EAEnBxlB,EAAI,EAAGA,EAAI+C,EAAK/C,IAAK,CAC5B,IAAMiE,EAAWrG,KAAKulB,iBAAiBtgB,EAAQ7C,GAAG,IAC5CylB,EAAS5iB,EAAQ7C,GAAG,GAE1B,GAAIiE,EAAShE,aAAqB4D,IAAX4hB,EAAsB,CAC3C,IAAI5f,EAAM4f,EACN/lB,EAAQ2F,aAAYQ,EAAMA,EAAIlF,QAClCkF,EAAMjI,KAAK0lB,qBAAqBzd,EAAKnF,EAAS9C,KAAKumB,iBACnDmB,EAActlB,GAAK6F,EAEnB2f,EAAmBvhB,GAAY4B,EAC/B0f,GAAc,CAChB,CACF,CAGIA,GAAgC,iBAAV5e,GAAsBA,EAAM2N,eACpD3N,EAAM2N,cAAckR,GAQtB,IAJA,IAAME,EAAWhmB,EAAQiH,MAAQA,EAAMuM,WAAatV,KAAKumB,gBAGrDwB,GAAW,EACN3lB,EAAI,EAAGA,EAAI+C,EAAK/C,IAAK,CAC5B,IAAMiE,EAAWrG,KAAKulB,iBAAiBtgB,EAAQ7C,GAAG,IAElD,IAAIpC,KAAK6lB,mBAAmBxf,EAAUyhB,GAAtC,CAEA,IAAIE,EAAQlmB,EAAQoF,oBAAsBb,EAE1C,GAAIA,EAAShE,OAMX,GALIP,EAAQ+G,yBACVmf,EAAQlmB,EAAQ+G,uBAAuBmf,IAEzCA,EAAQC,GAAaD,EAAOlmB,QAENmE,IAAlBhB,EAAQ7C,GAAG,GAAkB,CAE/B,IAAMylB,EAASH,EAActlB,GAEvB8lB,EAASpmB,EAAQoG,wBAAwB7B,EAAUwhB,EAAQC,GAE/D9e,EAAMgf,GADJE,QACaL,SACCK,UAAkBL,GAAUK,IAAWL,EACxCK,EAEAhB,GAAWW,EAAQ/lB,EAAQ0F,oBAAqB1F,EAAQ6F,oBAEzEogB,GAAW,CACb,MAAWjmB,EAAQJ,yBACjBsH,EAAMgf,IAAS,EACfD,GAAW,EAzB0C,CA4B3D,CAEA,IAAKA,EAAU,OAEf,GAAIjmB,EAAQqF,sBAAwBrF,EAAQmF,cAAe,CACzD,IAAMkhB,EAAiB,CAAC,EAExB,OADAA,EAAermB,EAAQqF,qBAAuB6B,EACvCmf,CACT,CACA,OAAOnf,CACT,CACF,CACA,IAAMqc,GAAW,SAAUxjB,GACzBA,EAAUA,EAAQ4C,QAAQ,SAAU,MACpC,IAAM2jB,EAAS,IAAIC,EAAQ,QACvBlD,EAAciD,EACdE,EAAW,GAGftoB,KAAKkU,QAAQ2C,QACb7W,KAAKyI,cAAcoO,QAGnB7W,KAAKkmB,qBAAuB,EAC5BlmB,KAAKmmB,sBAAwB,EAC7BnmB,KAAKomB,cAAe,EAIpB,IAHA,IAAMtkB,EAAU9B,KAAK8B,QACfymB,EAAgB,IAAIxa,EAAcjM,EAAQyG,iBAC1CigB,EAAS3mB,EAAQQ,OACdD,EAAI,EAAGA,EAAIomB,EAAQpmB,IAE1B,GAAW,MADAP,EAAQO,GACH,CAGd,IAAMqmB,EAAK5mB,EAAQsQ,WAAW/P,EAAI,GAClC,GAAW,KAAPqmB,EAAW,CACb,IAAMC,EAAaC,GAAiB9mB,EAAS,IAAKO,EAAG,8BACjDU,EAAUjB,EAAQmB,UAAUZ,EAAI,EAAGsmB,GAAY3lB,OAEnD,GAAIjB,EAAQwF,eAAgB,CAC1B,IAAM2R,EAAanW,EAAQmB,QAAQ,MACf,IAAhBgV,IACFnW,EAAUA,EAAQX,OAAO8W,EAAa,GAE1C,CAEAnW,EAAU8F,GAAiB9G,EAAQ8G,iBAAkB9F,EAAS,GAAIhB,GAASgB,QAEvEqiB,IACFmD,EAAWtoB,KAAK4lB,oBAAoB0C,EAAUnD,EAAanlB,KAAKumB,kBAIlE,IAAMqC,EAAc5oB,KAAKkU,QAAQG,gBACjC,GAAIvR,GAAWhB,EAAQ0J,gBAAgB4G,IAAItP,GACzC,MAAM,IAAI8G,MAAM,kDAAkD9G,EAAO,KAEvE8lB,GAAe9mB,EAAQ0J,gBAAgB4G,IAAIwW,KAE7C5oB,KAAKkU,QAAQpQ,MACb9D,KAAKolB,cAActhB,OAGrB9D,KAAKkU,QAAQpQ,MACb9D,KAAKwmB,uBAAwB,EAG7BrB,EAAcnlB,KAAKolB,cAActhB,OAASskB,EAEtCtmB,EAAQmH,iBAAmBkc,GAC7BA,EAAY3Y,YAAYkc,EAAa,GAEvCJ,EAAW,GACXlmB,EAAIsmB,CACN,MAAO,GAAW,KAAPD,EAAW,CAEpB,IAAII,EAAUC,GAAWjnB,EAASO,GAAG,EAAO,MAC5C,IAAKymB,EAAS,MAAM,IAAIjf,MAAM,yBAE9B0e,EAAWtoB,KAAK4lB,oBAAoB0C,EAAUnD,EAAanlB,KAAKumB,iBAChE,IAAMwC,EAAU/oB,KAAKwlB,mBAAmBqD,EAAQG,OAAQhpB,KAAKkU,QAAS2U,EAAQ/lB,SAAS,GACvF,GAAIimB,EAAS,CACX,IAAME,EAAMF,EAAQ/oB,KAAK8B,QAAQoF,oBAAsB,WACvDlH,KAAKyI,cAAcwF,cAAc+E,OAAOiW,IAAQ,GAChDV,EAActa,cAAc+E,OAAOiW,IAAQ,EAC7C,CACA,GAAKnnB,EAAQ4G,mBAAyC,SAApBmgB,EAAQ/lB,SAAuBhB,EAAQ6G,kBAElE,CAEL,IAAMugB,EAAY,IAAIb,EAAQQ,EAAQ/lB,SACtComB,EAAUjd,IAAInK,EAAQsF,aAAc,IAEhCyhB,EAAQ/lB,UAAY+lB,EAAQG,QAAUH,EAAQM,iBAA+C,IAA7BrnB,EAAQuF,mBAC1E6hB,EAAU,MAAQH,GAEpB/oB,KAAKmM,SAASgZ,EAAa+D,EAAWlpB,KAAKumB,gBAAiBnkB,GAExDN,EAAQmH,iBAEVkc,EAAY3Y,YAAYqc,EAAQH,WAAa,EAEjD,CAGAtmB,EAAIymB,EAAQH,WAAa,CAC3B,MAAO,GAAW,KAAPD,GACwB,KAA9B5mB,EAAQsQ,WAAW/P,EAAI,IACO,KAA9BP,EAAQsQ,WAAW/P,EAAI,GAAW,CACrC,IAAMqK,EAAWkc,GAAiB9mB,EAAS,SAAOO,EAAI,EAAG,0BACzD,GAAIN,EAAQwG,gBAAiB,CAAC,IAAD8gB,EACrB9a,EAAUzM,EAAQmB,UAAUZ,EAAI,EAAGqK,EAAW,GAEpD6b,EAAWtoB,KAAK4lB,oBAAoB0C,EAAUnD,EAAanlB,KAAKumB,iBAEhEpB,EAAYlZ,IAAInK,EAAQwG,gBAAiB,EAAA8gB,EAAA,GAAAA,EAAItnB,EAAQsF,cAAekH,EAAO8a,IAC7E,CACAhnB,EAAIqK,CACN,MAAO,GAAW,KAAPgc,GACwB,KAA9B5mB,EAAQsQ,WAAW/P,EAAI,GAAW,CACrC,GAAIpC,KAAKomB,aAAc,MAAM,IAAIxc,MAAM,wCACvC5J,KAAKomB,cAAe,EACpB,IAAMljB,EAASqlB,EAAcra,YAAYrM,EAASO,GAClDpC,KAAKyI,cAAc+Y,iBAAiBte,EAAOiL,UAC3C/L,EAAIc,EAAOd,CACb,MAAO,GAAW,KAAPqmB,GACwB,KAA9B5mB,EAAQsQ,WAAW/P,EAAI,GAAW,CACrC,IAAMsmB,EAAaC,GAAiB9mB,EAAS,MAAOO,EAAG,wBAA0B,EAC3E4mB,EAASnnB,EAAQmB,UAAUZ,EAAI,EAAGsmB,GAExCJ,EAAWtoB,KAAK4lB,oBAAoB0C,EAAUnD,EAAanlB,KAAKumB,iBAEhE,IAI2B8C,EAJvBphB,EAAMjI,KAAKslB,cAAc0D,EAAQ7D,EAAYvgB,QAAS5E,KAAKumB,iBAAiB,GAAM,GAAO,GAAM,GACxFtgB,MAAPgC,IAAkBA,EAAM,IAGxBnG,EAAQ4F,cACVyd,EAAYlZ,IAAInK,EAAQ4F,cAAe,EAAA2hB,EAAA,GAAAA,EAAIvnB,EAAQsF,cAAe4hB,EAAMK,KAExElE,EAAYlZ,IAAInK,EAAQsF,aAAca,GAGxC7F,EAAIsmB,EAAa,CACnB,KAAO,CACL,IAAIxlB,EAAS4lB,GAAWjnB,EAASO,EAAGN,EAAQwF,gBAG5C,IAAKpE,EAAQ,CAEX,IAAM+d,EAAUpf,EAAQmB,UAAUwH,KAAKC,IAAI,EAAGrI,EAAI,IAAKoI,KAAK8e,IAAId,EAAQpmB,EAAI,KAC5E,MAAM,IAAIwH,MAAM,6CAA6CxH,EAAC,eAAe6e,EAAO,IACtF,CAEA,IAAIne,EAAUI,EAAOJ,QACfyhB,EAAarhB,EAAOqhB,WACtByE,EAAS9lB,EAAO8lB,OAChBG,EAAiBjmB,EAAOimB,eACxBT,EAAaxlB,EAAOwlB,WAAWa,EAEZ3gB,GAAiB9G,EAAQ8G,iBAAkB9F,EAASkmB,EAAQlnB,GAEnF,GAFGgB,EAAOymB,EAAPzmB,QAASkmB,EAAMO,EAANP,OAERlnB,EAAQqH,sBACTrG,IAAYhB,EAAQwG,iBAChBxF,IAAYhB,EAAQ4F,eACpB5E,IAAYhB,EAAQsF,cACpBtE,IAAYhB,EAAQqF,qBAEzB,MAAM,IAAIyC,MAAM,qBAAqB9G,GAInCqiB,GAAemD,GACW,SAAxBnD,EAAYvgB,UAEd0jB,EAAWtoB,KAAK4lB,oBAAoB0C,EAAUnD,EAAanlB,KAAKumB,iBAAiB,IAKrF,IAAMiD,EAAUrE,EACZqE,GAAW1nB,EAAQ0J,gBAAgB4G,IAAIoX,EAAQ5kB,WACjDugB,EAAcnlB,KAAKolB,cAActhB,MACjC9D,KAAKkU,QAAQpQ,OAKf,IAAI2lB,GAAgB,EAChBT,EAAO3mB,OAAS,GAAK2mB,EAAO9P,YAAY,OAAS8P,EAAO3mB,OAAS,IACnEonB,GAAgB,EAGdT,EAFkC,MAAhClmB,EAAQA,EAAQT,OAAS,GAC3BS,EAAUA,EAAQX,OAAO,EAAGW,EAAQT,OAAS,GAGpC2mB,EAAO7mB,OAAO,EAAG6mB,EAAO3mB,OAAS,GAI5C8mB,EAAkBrmB,IAAYkmB,GAIhC,IAEIvU,EAFA2P,EAAgB,KAKpB3P,EAAY6P,GAAiBC,GAGzBzhB,IAAYslB,EAAOxjB,SACrB5E,KAAKkU,QAAQhQ,KAAKpB,EAAS,CAAC,EAAG2R,GAI7B3R,IAAYkmB,GAAUG,IAGxB/E,EAAgBpkB,KAAKwlB,mBAAmBwD,EAAQhpB,KAAKkU,QAASpR,KAKjDqhB,GAAqBC,EAAetiB,GAK/CgB,IAAYslB,EAAOxjB,UACrB5E,KAAKwmB,sBAAwBxmB,KAAKylB,gBAGpC,IAAMzf,EAAa5D,EACnB,GAAIpC,KAAKwmB,sBAAuB,CAC9B,IAAIkD,EAAa,GAGjB,GAAID,EACFrnB,EAAIc,EAAOwlB,gBAGR,GAAI5mB,EAAQ0J,gBAAgB4G,IAAItP,GACnCV,EAAIc,EAAOwlB,eAGR,CAEH,IAAMxlB,EAASlD,KAAK2lB,iBAAiB9jB,EAAS0iB,EAAYmE,EAAa,GACvE,IAAKxlB,EAAQ,MAAM,IAAI0G,MAAM,qBAAqB2a,GAClDniB,EAAIc,EAAOd,EACXsnB,EAAaxmB,EAAOwmB,UACtB,CAEA,IAAMR,EAAY,IAAIb,EAAQvlB,GAE1BshB,IACF8E,EAAU,MAAQ9E,GAIpB8E,EAAUjd,IAAInK,EAAQsF,aAAcsiB,GAEpC1pB,KAAKkU,QAAQpQ,MACb9D,KAAKwmB,uBAAwB,EAE7BxmB,KAAKmM,SAASgZ,EAAa+D,EAAWlpB,KAAKumB,gBAAiBvgB,GAExDlE,EAAQmH,iBACVkc,EAAY3Y,YAAYpK,EAAI,EAEhC,KAAO,CAEL,GAAIqnB,EAAe,CAAC,IAADE,EACM/gB,GAAiB9G,EAAQ8G,iBAAkB9F,EAASkmB,EAAQlnB,GAAhFgB,EAAO6mB,EAAP7mB,QAASkmB,EAAMW,EAANX,OAEZ,IAAME,EAAY,IAAIb,EAAQvlB,GAC1BshB,IACF8E,EAAU,MAAQ9E,GAEpBpkB,KAAKmM,SAASgZ,EAAa+D,EAAWlpB,KAAKumB,gBAAiBvgB,GAExDlE,EAAQmH,iBACVkc,EAAY3Y,YAAYkc,EAAa,GAEvC1oB,KAAKkU,QAAQpQ,MACb9D,KAAKwmB,uBAAwB,CAC/B,KACK,IAAI1kB,EAAQ0J,gBAAgB4G,IAAItP,GAAU,CAC7C,IAAMomB,EAAY,IAAIb,EAAQvlB,GAC1BshB,IACF8E,EAAU,MAAQ9E,GAEpBpkB,KAAKmM,SAASgZ,EAAa+D,EAAWlpB,KAAKumB,gBAAiBvgB,GAExDlE,EAAQmH,iBACVkc,EAAY3Y,YAAYtJ,EAAOwlB,WAAa,GAE9C1oB,KAAKkU,QAAQpQ,MACb9D,KAAKwmB,uBAAwB,EAC7BpkB,EAAIc,EAAOwlB,WAEX,QACF,CAGE,IAAMQ,EAAY,IAAIb,EAAQvlB,GAC9B,GAAI9C,KAAKolB,cAAc/iB,OAASP,EAAQoH,cACtC,MAAM,IAAIU,MAAM,gCAElB5J,KAAKolB,cAAclhB,KAAKihB,GAEpBf,IACF8E,EAAU,MAAQ9E,GAEpBpkB,KAAKmM,SAASgZ,EAAa+D,EAAWlpB,KAAKumB,gBAAiBvgB,GAC5Dmf,EAAc+D,CAChB,CACAZ,EAAW,GACXlmB,EAAIsmB,CACN,CACF,CACF,MACEJ,GAAYzmB,EAAQO,GAGxB,OAAOgmB,EAAOtc,KAChB,EAEA,SAASK,GAASgZ,EAAa+D,EAAWhV,EAASlO,GAE5ChG,KAAK8B,QAAQmH,kBAAiBjD,OAAaC,GAGhD,IAAM+gB,EAAiBhnB,KAAK8B,QAAQiH,MAAQmL,EAAQoB,WAAapB,EAC3DhR,EAASlD,KAAK8B,QAAQgH,UAAUogB,EAAUtkB,QAASoiB,EAAgBkC,EAAU,QACpE,IAAXhmB,IAEyB,iBAAXA,GAChBgmB,EAAUtkB,QAAU1B,EACpBiiB,EAAYhZ,SAAS+c,EAAWljB,IAEhCmf,EAAYhZ,SAAS+c,EAAWljB,GAEpC,CAOA,SAAS0f,GAAqBzd,EAAKnF,EAASiG,GAC1C,IAAM6gB,EAAe5pB,KAAK8B,QAAQyG,gBAElC,IAAKqhB,IAAiBA,EAAa9f,QACjC,OAAO7B,EAIT,GAAI2hB,EAAavf,YAAa,CAC5B,IAAM2c,EAAiBhnB,KAAK8B,QAAQiH,MAAQA,EAAMuM,WAAavM,EAK/D,KAJgB2C,MAAMrD,QAAQuhB,EAAavf,aACvCuf,EAAavf,YAAYrD,SAASlE,GAClC8mB,EAAavf,YAAYvH,EAASkkB,IAGpC,OAAO/e,CAEX,CAGA,GAAI2hB,EAAatf,UAAW,CAC1B,IAAM0c,EAAiBhnB,KAAK8B,QAAQiH,MAAQA,EAAMuM,WAAavM,EAC/D,IAAK6gB,EAAatf,UAAUxH,EAASkkB,GACnC,OAAO/e,CAEX,CAEA,OAAOjI,KAAKyI,cAAciZ,OAAOzZ,EACnC,CAGA,SAAS2d,GAAoB0C,EAAUuB,EAAY3V,EAAS4S,GAe1D,OAdIwB,SACiBriB,IAAf6gB,IAA0BA,EAAyC,IAA5B+C,EAAW/d,MAAMzJ,aAS3C4D,KAPjBqiB,EAAWtoB,KAAKslB,cAAcgD,EAC5BuB,EAAWjlB,QACXsP,GACA,IACA2V,EAAW,OAAiD,IAAzCxpB,OAAOiM,KAAKud,EAAW,OAAOxnB,OACjDykB,KAEyC,KAAbwB,GAC5BuB,EAAW5d,IAAIjM,KAAK8B,QAAQsF,aAAckhB,GAC5CA,EAAW,IAENA,CACT,CAMA,SAAS7C,KACP,OAAyC,IAArCzlB,KAAKymB,uBAAuBpM,MAEzBra,KAAKkU,QAAQwB,WAAW1V,KAAKymB,uBACtC,CA4CA,SAASkC,GAAiB9mB,EAAS6L,EAAKtL,EAAG0nB,GACzC,IAAMC,EAAeloB,EAAQoC,QAAQyJ,EAAKtL,GAC1C,IAAsB,IAAlB2nB,EACF,MAAM,IAAIngB,MAAMkgB,GAEhB,OAAOC,EAAerc,EAAIrL,OAAS,CAEvC,CAEA,SAAS2nB,GAAgBnoB,EAAS6C,EAAMtC,EAAG0nB,GACzC,IAAMC,EAAeloB,EAAQoC,QAAQS,EAAMtC,GAC3C,IAAsB,IAAlB2nB,EAAqB,MAAM,IAAIngB,MAAMkgB,GACzC,OAAOC,CACT,CAEA,SAASjB,GAAWjnB,EAASO,EAAGkF,EAAgB2iB,QAAW,IAAXA,IAAAA,EAAc,KAC5D,IAAM/mB,EApDR,SAAgCrB,EAASO,EAAG6nB,QAAW,IAAXA,IAAAA,EAAc,KAWxD,IARA,IAAIC,EAAe,EACb/kB,EAAMtD,EAAQQ,OACd8nB,EAAaF,EAAY9X,WAAW,GACpCiY,EAAaH,EAAY5nB,OAAS,EAAI4nB,EAAY9X,WAAW,IAAM,EAErEjP,EAAS,GACTmnB,EAAejoB,EAEViB,EAAQjB,EAAGiB,EAAQ8B,EAAK9B,IAAS,CACxC,IAAMI,EAAO5B,EAAQsQ,WAAW9O,GAEhC,GAAI6mB,EACEzmB,IAASymB,IAAcA,EAAe,QACrC,GAAa,KAATzmB,GAAwB,KAATA,EACxBymB,EAAezmB,OACV,GAAIA,IAAS0mB,EAAY,CAC9B,IAAoB,IAAhBC,EAOF,MAAO,CAAE9Z,KADTpN,GAAUrB,EAAQmB,UAAUqnB,EAAchnB,GACnBA,MAAAA,GANvB,GAAIxB,EAAQsQ,WAAW9O,EAAQ,KAAO+mB,EAEpC,MAAO,CAAE9Z,KADTpN,GAAUrB,EAAQmB,UAAUqnB,EAAchnB,GACnBA,MAAAA,EAM7B,MAAoB,IAATI,GAAeymB,IAExBhnB,GAAUrB,EAAQmB,UAAUqnB,EAAchnB,GAAS,IACnDgnB,EAAehnB,EAAQ,EAE3B,CACF,CAkBiBinB,CAAuBzoB,EAASO,EAAI,EAAG6nB,GACtD,GAAK/mB,EAAL,CACA,IAAI8lB,EAAS9lB,EAAOoN,KACdoY,EAAaxlB,EAAOG,MACpBknB,EAAiBvB,EAAOvV,OAAO,MACjC3Q,EAAUkmB,EACVG,GAAiB,GACG,IAApBoB,IACFznB,EAAUkmB,EAAOhmB,UAAU,EAAGunB,GAC9BvB,EAASA,EAAOhmB,UAAUunB,EAAiB,GAAGC,aAGhD,IAAMjG,EAAazhB,EACnB,GAAIwE,EAAgB,CAClB,IAAM2R,EAAanW,EAAQmB,QAAQ,MACf,IAAhBgV,IAEFkQ,GADArmB,EAAUA,EAAQX,OAAO8W,EAAa,MACT/V,EAAOoN,KAAKnO,OAAO8W,EAAa,GAEjE,CAEA,MAAO,CACLnW,QAASA,EACTkmB,OAAQA,EACRN,WAAYA,EACZS,eAAgBA,EAChB5E,WAAYA,EAzBK,CA2BrB,CAOA,SAASoB,GAAiB9jB,EAASiB,EAASV,GAM1C,IALA,IAAM4D,EAAa5D,EAEfqoB,EAAe,EAEbC,EAAS7oB,EAAQQ,OAChBD,EAAIsoB,EAAQtoB,IACjB,GAAmB,MAAfP,EAAQO,GAAY,CACtB,IAAMqmB,EAAK5mB,EAAQsQ,WAAW/P,EAAI,GAClC,GAAW,KAAPqmB,EAAW,CACb,IAAMC,EAAasB,GAAgBnoB,EAAS,IAAKO,EAAMU,EAAO,kBAE9D,GADmBjB,EAAQmB,UAAUZ,EAAI,EAAGsmB,GAAY3lB,SACnCD,GAEE,MADrB2nB,EAEE,MAAO,CACLf,WAAY7nB,EAAQmB,UAAUgD,EAAY5D,GAC1CA,EAAGsmB,GAITtmB,EAAIsmB,CACN,MAAO,GAAW,KAAPD,EAETrmB,EADmBumB,GAAiB9mB,EAAS,KAAMO,EAAI,EAAG,gCAErD,GAAW,KAAPqmB,GACwB,KAA9B5mB,EAAQsQ,WAAW/P,EAAI,IACO,KAA9BP,EAAQsQ,WAAW/P,EAAI,GAE1BA,EADmBumB,GAAiB9mB,EAAS,SAAOO,EAAI,EAAG,gCAEtD,GAAW,KAAPqmB,GACwB,KAA9B5mB,EAAQsQ,WAAW/P,EAAI,GAE1BA,EADmBumB,GAAiB9mB,EAAS,MAAOO,EAAG,2BAA6B,MAE/E,CACL,IAAMymB,EAAUC,GAAWjnB,EAASO,GAAG,GAEnCymB,KACkBA,GAAWA,EAAQ/lB,WACnBA,GAAyD,MAA9C+lB,EAAQG,OAAOH,EAAQG,OAAO3mB,OAAS,IACpEooB,IAEFroB,EAAIymB,EAAQH,WAEhB,CACF,CAEJ,CAEA,SAASxB,GAAWjf,EAAK0iB,EAAa7oB,GACpC,GAAI6oB,GAA8B,iBAAR1iB,EAAkB,CAE1C,IAAMgf,EAAShf,EAAIlF,OACnB,MAAe,SAAXkkB,GACgB,UAAXA,GACGnV,EAAS7J,EAAKnG,EAC5B,CACE,YxBlyBkB,IwBkyBNmG,EACHA,EAEA,EAGb,CAYA,SAASW,GAAiBgiB,EAAI9nB,EAASkmB,EAAQlnB,GAC7C,GAAI8oB,EAAI,CACN,IAAMC,EAAaD,EAAG9nB,GAClBkmB,IAAWlmB,IACbkmB,EAAS6B,GAEX/nB,EAAU+nB,CACZ,CAEA,MAAO,CAAE/nB,QADTA,EAAUmlB,GAAanlB,EAAShB,GACdknB,OAAAA,EACpB,CAIA,SAASf,GAAaziB,EAAM1D,GAC1B,GAAIN,EAAmBwF,SAASxB,GAC9B,MAAM,IAAIoE,MAAM,6BAA6BpE,EAAI,2EAC5C,OAAIjE,EAAyByF,SAASxB,GACpC1D,EAAQsH,oBAAoB5D,GAE9BA,CACT,CEj2BA,IAAM0F,GAAkBW,EAAQc,oBAQhC,SAASme,GAAqB9hB,EAAOme,GACnC,IAAKne,GAA0B,iBAAVA,EAAoB,MAAO,CAAC,EACjD,IAAKme,EAAQ,OAAOne,EAEpB,IAAMqb,EAAW,CAAC,EAClB,IAAK,IAAMlkB,KAAO6I,EACZ7I,EAAIyL,WAAWub,GAEjB9C,EADgBlkB,EAAI6C,UAAUmkB,EAAO9kB,SACjB2G,EAAM7I,GAG1BkkB,EAASlkB,GAAO6I,EAAM7I,GAG1B,OAAOkkB,CACT,CASe,SAAS0G,GAASpf,EAAM7J,EAASoS,EAASqS,GACvD,OAAOyE,GAASrf,EAAM7J,EAASoS,EAASqS,EAC1C,CAQA,SAASyE,GAASC,EAAKnpB,EAASoS,EAASqS,GAGvC,IAFA,IAAI2E,EACEC,EAAgB,CAAC,EACd/oB,EAAI,EAAGA,EAAI6oB,EAAI5oB,OAAQD,IAAK,CACnC,IAAMgpB,EAASH,EAAI7oB,GACbipB,EAAWC,GAASF,GAG1B,QAAiBnlB,IAAbolB,GAA0BA,IAAavpB,EAAQsF,aAAc,CAC/D,IAAMid,EAAWyG,GACfM,EAAO,OAAS,CAAC,EACjBtpB,EAAQoF,qBAEVgN,EAAQhQ,KAAKmnB,EAAUhH,EACzB,CAEA,GAAIgH,IAAavpB,EAAQsF,kBACVnB,IAATilB,EAAoBA,EAAOE,EAAOC,GACjCH,GAAQ,GAAKE,EAAOC,OACpB,SAAiBplB,IAAbolB,EACT,SACK,GAAID,EAAOC,GAAW,CAE3B,IAAIpjB,EAAM+iB,GAASI,EAAOC,GAAWvpB,EAASoS,EAASqS,GACjDgF,EAASC,GAAUvjB,EAAKnG,GAoB9B,GAlBgC,IAA5BzB,OAAOiM,KAAKrE,GAAK5F,QAAgBP,EAAQsG,uBAC3CH,EAAInG,EAAQsF,cAAgB,IAG1BgkB,EAAO,MACTK,GAAiBxjB,EAAKmjB,EAAO,MAAO7E,EAAiBzkB,GAChB,IAA5BzB,OAAOiM,KAAKrE,GAAK5F,aAA8C4D,IAA9BgC,EAAInG,EAAQsF,eAAgCtF,EAAQsG,qBAEzD,IAA5B/H,OAAOiM,KAAKrE,GAAK5F,SACtBP,EAAQsG,qBAAsBH,EAAInG,EAAQsF,cAAgB,GACzDa,EAAM,IAHXA,EAAMA,EAAInG,EAAQsF,mBAMYnB,IAA5BmlB,EAAOlgB,KAAiD,iBAARjD,GAA4B,OAARA,IACtEA,EAAIiD,IAAmBkgB,EAAOlgB,UAIAjF,IAA5BklB,EAAcE,IAA2BhrB,OAAOM,UAAUC,eAAeC,KAAKsqB,EAAeE,GAC1F3f,MAAMrD,QAAQ8iB,EAAcE,MAC/BF,EAAcE,GAAY,CAACF,EAAcE,KAE3CF,EAAcE,GAAUnnB,KAAK+D,OACxB,CAKL,IAAM+e,EAAiBllB,EAAQiH,MAAQwd,EAAgBjR,WAAaiR,EAChEzkB,EAAQuG,QAAQgjB,EAAUrE,EAAgBuE,GAC5CJ,EAAcE,GAAY,CAACpjB,GAE3BkjB,EAAcE,GAAYpjB,CAE9B,MAGiBhC,IAAbolB,GAA0BA,IAAavpB,EAAQsF,cACjD8M,EAAQpQ,KAEZ,EAEF,CAOA,MALoB,iBAATonB,EACLA,EAAK7oB,OAAS,IAAG8oB,EAAcrpB,EAAQsF,cAAgB8jB,QACzCjlB,IAATilB,IAAoBC,EAAcrpB,EAAQsF,cAAgB8jB,GAG9DC,CACT,CAEA,SAASG,GAAS7qB,GAEhB,IADA,IAAM6L,EAAOjM,OAAOiM,KAAK7L,GAChB2B,EAAI,EAAGA,EAAIkK,EAAKjK,OAAQD,IAAK,CACpC,IAAMjC,EAAMmM,EAAKlK,GACjB,GAAY,OAARjC,EAAc,OAAOA,CAC3B,CACF,CAEA,SAASsrB,GAAiBhrB,EAAKirB,EAASnF,EAAiBzkB,GACvD,GAAI4pB,EAGF,IAFA,IAAMpf,EAAOjM,OAAOiM,KAAKof,GACnBvmB,EAAMmH,EAAKjK,OACRD,EAAI,EAAGA,EAAI+C,EAAK/C,IAAK,CAC5B,IAAMupB,EAAWrf,EAAKlK,GAGhBwpB,EAAcD,EAAS/f,WAAW9J,EAAQoF,qBAC5CykB,EAAS3oB,UAAUlB,EAAQoF,oBAAoB7E,QAC/CspB,EAIE3E,EAAiBllB,EAAQiH,MAC3Bwd,EAAgBjR,WAAa,IAAMsW,EACnCrF,EAEAzkB,EAAQuG,QAAQsjB,EAAU3E,GAAgB,GAAM,GAClDvmB,EAAIkrB,GAAY,CAACD,EAAQC,IAEzBlrB,EAAIkrB,GAAYD,EAAQC,EAE5B,CAEJ,CAEA,SAASH,GAAU/qB,EAAKqB,GACtB,IAAQsF,EAAiBtF,EAAjBsF,aACFykB,EAAYxrB,OAAOiM,KAAK7L,GAAK4B,OAEnC,OAAkB,IAAdwpB,KAKY,IAAdA,IACCprB,EAAI2G,IAA8C,kBAAtB3G,EAAI2G,IAAqD,IAAtB3G,EAAI2G,GAMxE,CC3KmC,IAEd0kB,GAAS,WAE1B,SAAAA,EAAYhqB,GACR9B,KAAKklB,iBAAmB,CAAC,EACzBllB,KAAK8B,QAAUqJ,EAAarJ,EAEhC,CACA,IAAAkK,EAAA8f,EAAAnrB,UA6DC,OA7DD,EAKAorB,MAAA,SAAMlqB,EAASmqB,GACX,GAAuB,iBAAZnqB,GAAwBA,EAAQyT,SAGnCzT,EAFAA,aAAmBgP,aACC,oBAAXob,SAA0BA,OAAOC,SAASrqB,IACzC,IAAIsqB,YAAY,QAAS,CAAEC,WAAW,IAAQ1K,OAAO7f,GAErDA,EAAQyT,gBAEnB,GAAuB,iBAAZzT,EACd,MAAM,IAAI+H,MAAM,mDAGpB,GAAIoiB,EAAkB,EACO,IAArBA,IAA2BA,EAAmB,CAAC,GAEnD,IAAM9oB,EAAStB,EAASC,EAASmqB,GACjC,IAAe,IAAX9oB,EACA,MAAM0G,MAAS1G,EAAOX,IAAImB,IAAG,IAAIR,EAAOX,IAAIoB,KAAI,IAAIT,EAAOX,IAAIyB,IAEvE,CACA,IAAMqoB,EAAmB,IAAIpH,GAAiBjlB,KAAK8B,QAAS9B,KAAKklB,kBAE3DoH,EAAgBD,EAAiBhH,SAASxjB,GAChD,OAAI7B,KAAK8B,QAAQmF,oBAAmChB,IAAlBqmB,EAAoCA,EAC1DvB,GAASuB,EAAetsB,KAAK8B,QAASuqB,EAAiBnY,QAASmY,EAAiB9F,gBACjG,EAEA,EAKAgG,UAAA,SAAUpsB,EAAKa,GACX,IAA4B,IAAxBA,EAAMiD,QAAQ,KACd,MAAM,IAAI2F,MAAM,+BACb,IAA0B,IAAtBzJ,EAAI8D,QAAQ,OAAqC,IAAtB9D,EAAI8D,QAAQ,KAC9C,MAAM,IAAI2F,MAAM,wEACb,GAAc,MAAV5I,EACP,MAAM,IAAI4I,MAAM,6CAEhB5J,KAAKklB,iBAAiB/kB,GAAOa,CAErC,EAEA,EAUO2L,kBAAP,WACI,OAAOd,EAAQc,mBACnB,EAACmf,CAAA,CApEyB,GCLvB,SAASU,GAAYvkB,GAC1B,OAAOsK,OAAOtK,GACXxD,QAAQ,MAAO,OACfA,QAAQ,MAAO,OACfA,QAAQ,KAAM,KACnB,CAEO,SAASgoB,GAAUxkB,GACxB,OAAOsK,OAAOtK,GAAKxD,QAAQ,SAAU,kBACvC,CAEO,SAASioB,GAAgBzkB,GAC9B,OAAOsK,OAAOtK,GAAKxD,QAAQ,KAAM,UAAUA,QAAQ,KAAM,SAC3D,CCcA,MAAMmI,GACJ,+CAoCIC,GACJ,8CAYIC,GACJD,uBAeIE,GAAeA,CAAC/H,EAAWN,EAAMsI,EAAQ,MAC7C,MAEMC,EAAY,IAFFjI,EAAUP,QAAQ,IAAK,QACxBC,EAAKD,QAAQ,IAAK,QAGjC,MAAO,CACLe,KAAM,IAAIrE,OAAO,KAAK6D,MAAcN,OAAWsI,GAC/CE,OAAQ,IAAI/L,OAAO,IAAI8L,KAAcD,GACrCG,MAAO,IAAIhM,OAAO,IAAI8L,QAAgBA,OAAgBD,GACtDI,QAAS,IAAIjM,OAAO,KAAKuD,OAAWsI,GACpCK,SAAU,IAAIlM,OAAO,KAAKuD,cAAiBA,SAAasI,KAItDM,GAAYP,GAAaH,GAnE7BA,uBAoEIW,GAAYR,GAAaF,GAAiBC,GAAY,KA8B/CK,GAAQA,CAACO,GAAOC,aAAa,OAAU,CAAC,IA5BlCE,EAACF,EAAa,QAChB,QAAfA,EAAuBJ,GAAYD,GA4BnCO,CAAWF,GAAYR,MAAMW,KAAKJ,GCrGpC,SAASif,GAAennB,EAAMonB,EAAa9qB,EAASoS,EAASvG,GACzD,OAAK7L,EAAQmmB,aACT9a,GAAM3H,EAAM,CAAEmI,eAAsBnI,EACjC1D,EAAQmmB,aAAaziB,EAAM,CAAEonB,cAAa1Y,QAASA,EAAQ6D,aAFhCvS,CAGtC,CAOe,SAASqnB,GAAMC,EAAQhrB,GAClC,IAAIirB,EAAc,GACdjrB,EAAQkrB,SACRD,EAlDI,MAsDR,MAAME,EAAsB,GAC5B,GAAInrB,EAAQqG,WAAauD,MAAMrD,QAAQvG,EAAQqG,WAC3C,IAAK,IAAI/F,EAAI,EAAGA,EAAIN,EAAQqG,UAAU9F,OAAQD,IAAK,CAC/C,MAAMuJ,EAAO7J,EAAQqG,UAAU/F,GACX,iBAATuJ,EACPshB,EAAoB/oB,KAAK,IAAI8T,GAAWrM,IACjCA,aAAgBqM,IACvBiV,EAAoB/oB,KAAKyH,EAEjC,CAIJ,MAAMgC,EAzDV,SAAmCmf,EAAQhrB,GACvC,IAAK4J,MAAMrD,QAAQykB,IAA6B,IAAlBA,EAAOzqB,OAAc,MAAO,MAC1D,MAAM6qB,EAAQJ,EAAO,GAErB,GAAiB,SADAxB,GAAS4B,GACD,CACrB,MAAMlkB,EAAQkkB,EAAM,MACpB,GAAIlkB,EAAO,CACP,MAAMmkB,EAAarrB,EAAQoF,oBAAsB,UACjD,GAAI8B,EAAMmkB,GAAa,OAAOnkB,EAAMmkB,EACxC,CACJ,CACA,MAAO,KACX,CA6CuBC,CAA0BN,EAAQhrB,GAKrD,OAAOurB,GAASP,EAAQhrB,EAASirB,EAFjB,IAAInX,GAEmCqX,EAAqBtf,EAChF,CAEA,SAAS0f,GAASpC,EAAKnpB,EAASirB,EAAa7Y,EAAS+Y,EAAqBtf,GACvE,IAAI2f,EAAS,GACTC,GAAuB,EAE3B,GAAIzrB,EAAQoH,eAAiBgL,EAAQmB,WAAavT,EAAQoH,cACtD,MAAM,IAAIU,MAAM,gCAGpB,IAAK8B,MAAMrD,QAAQ4iB,GAAM,CAErB,GAAIA,QAAmC,CACnC,IAAIC,EAAOD,EAAI3V,WAEf,OADA4V,EAAOxF,GAAqBwF,EAAMppB,GAC3BopB,CACX,CACA,MAAO,EACX,CAEA,IAAK,IAAI9oB,EAAI,EAAGA,EAAI6oB,EAAI5oB,OAAQD,IAAK,CACjC,MAAMgpB,EAASH,EAAI7oB,GACbmiB,EAAa+G,GAASF,GAC5B,QAAmBnlB,IAAfse,EAA0B,SAI9B,MAMMzhB,EANgByhB,IAAeziB,EAAQsF,cACtCmd,IAAeziB,EAAQ4F,eACvB6c,IAAeziB,EAAQwG,iBACL,MAAlBic,EAAW,GAIZA,EACAoI,GAAepI,GAAY,EAAOziB,EAASoS,EAASvG,GAGpDsI,EAAauX,GAAuBpC,EAAO,MAAOtpB,GAGxDoS,EAAQhQ,KAAKpB,EAASmT,GAGtB,MAAMwX,EAAaC,GAAcxZ,EAAS+Y,GAE1C,GAAInqB,IAAYhB,EAAQsF,aAAc,CAClC,IAAIumB,EAAUvC,EAAO7G,GAChBkJ,IACDE,EAAU7rB,EAAQkG,kBAAkBlF,EAAS6qB,GAC7CA,EAAUjI,GAAqBiI,EAAS7rB,IAExCyrB,IACAD,GAAUP,GAEdO,GAAUK,EACVJ,GAAuB,EACvBrZ,EAAQpQ,MACR,QACJ,CAAO,GAAIhB,IAAYhB,EAAQ4F,cAAe,CACtC6lB,IACAD,GAAUP,GAIdO,GAAU,YADMb,GADJrB,EAAO7G,GAAY,GAAGziB,EAAQsF,oBAG1CmmB,GAAuB,EACvBrZ,EAAQpQ,MACR,QACJ,CAAO,GAAIhB,IAAYhB,EAAQwG,gBAAiB,CAG5CglB,GAAUP,EAAc,UADRP,GADJpB,EAAO7G,GAAY,GAAGziB,EAAQsF,uBAG1CmmB,GAAuB,EACvBrZ,EAAQpQ,MACR,QACJ,CAAO,GAAmB,MAAfhB,EAAQ,GAAY,CAK3BwqB,IAH4B,SAAZxqB,EAAqB,GAAKiqB,GAGtB,IAAIjqB,IAJT8qB,GAAYxC,EAAO,MAAOtpB,EAAS2rB,EAAYvZ,EAASvG,OAKvE4f,GAAuB,EACvBrZ,EAAQpQ,MACR,QACJ,CAEA,IAAI+pB,EAAgBd,EACE,KAAlBc,IACAA,GAAiB/rB,EAAQgsB,UAI7B,MACMC,EAAWhB,EAAc,IAAIjqB,IADpB8qB,GAAYxC,EAAO,MAAOtpB,EAAS2rB,EAAYvZ,EAASvG,KAIvE,IAAIqgB,EAEAA,EADAP,EACWQ,GAAc7C,EAAO7G,GAAaziB,GAElCurB,GAASjC,EAAO7G,GAAaziB,EAAS+rB,EAAe3Z,EAAS+Y,EAAqBtf,IAGnD,IAA3C7L,EAAQH,aAAasC,QAAQnB,GACzBhB,EAAQosB,qBAAsBZ,GAAUS,EAAW,IAClDT,GAAUS,EAAW,KACjBC,GAAgC,IAApBA,EAAS3rB,SAAiBP,EAAQqsB,kBAEhDH,GAAYA,EAASI,SAAS,KACrCd,GAAUS,EAAW,IAAIC,IAAWjB,MAAgBjqB,MAEpDwqB,GAAUS,EAAW,IACjBC,GAA4B,KAAhBjB,IAAuBiB,EAAShnB,SAAS,OAASgnB,EAAShnB,SAAS,OAChFsmB,GAAUP,EAAcjrB,EAAQgsB,SAAWE,EAAWjB,EAEtDO,GAAUU,EAEdV,GAAU,KAAKxqB,MAVfwqB,GAAUS,EAAW,KAYzBR,GAAuB,EAGvBrZ,EAAQpQ,KACZ,CAEA,OAAOwpB,CACX,CAMA,SAASE,GAAuB9B,EAAS5pB,GACrC,IAAK4pB,GAAW5pB,EAAQuF,iBAAkB,OAAO,KAEjD,MAAM4O,EAAa,CAAC,EACpB,IAAI8R,GAAW,EAEf,IAAK,IAAIsG,KAAQ3C,EACRrrB,OAAOM,UAAUC,eAAeC,KAAK6qB,EAAS2C,KAKnDpY,EAHsBoY,EAAKziB,WAAW9J,EAAQoF,qBACxCmnB,EAAKlsB,OAAOL,EAAQoF,oBAAoB7E,QACxCgsB,GACsB3B,GAAgBhB,EAAQ2C,IACpDtG,GAAW,GAGf,OAAOA,EAAW9R,EAAa,IACnC,CAMA,SAASgY,GAAchD,EAAKnpB,GACxB,IAAK4J,MAAMrD,QAAQ4iB,GAEf,OAAIA,QACOA,EAAI3V,WAER,GAGX,IAAIuD,EAAU,GACd,IAAK,IAAIzW,EAAI,EAAGA,EAAI6oB,EAAI5oB,OAAQD,IAAK,CACjC,MAAMksB,EAAOrD,EAAI7oB,GACXU,EAAUwoB,GAASgD,GAEzB,GAAIxrB,IAAYhB,EAAQsF,aAEpByR,GAAWyV,EAAKxrB,QACb,GAAIA,IAAYhB,EAAQ4F,cAE3BmR,GAAWyV,EAAKxrB,GAAS,GAAGhB,EAAQsF,mBACjC,GAAItE,IAAYhB,EAAQwG,gBAE3BuQ,GAAWyV,EAAKxrB,GAAS,GAAGhB,EAAQsF,kBACjC,IAAItE,GAA0B,MAAfA,EAAQ,GAE1B,SACG,GAAIA,EAAS,CAEhB,MAAMyrB,EAASC,GAAgBF,EAAK,MAAOxsB,GACrC2sB,EAAgBR,GAAcK,EAAKxrB,GAAUhB,GAE9C2sB,GAA0C,IAAzBA,EAAcpsB,OAGhCwW,GAAW,IAAI/V,IAAUyrB,KAAUE,MAAkB3rB,KAFrD+V,GAAW,IAAI/V,IAAUyrB,KAIjC,EACJ,CACA,OAAO1V,CACX,CAKA,SAAS2V,GAAgB9C,EAAS5pB,GAC9B,IAAIsB,EAAU,GACd,GAAIsoB,IAAY5pB,EAAQuF,iBACpB,IAAK,IAAIgnB,KAAQ3C,EAAS,CACtB,IAAKrrB,OAAOM,UAAUC,eAAeC,KAAK6qB,EAAS2C,GAAO,SAE1D,IAAIK,EAAUhD,EAAQ2C,IACN,IAAZK,GAAoB5sB,EAAQ6sB,0BAC5BvrB,GAAW,IAAIirB,EAAKlsB,OAAOL,EAAQoF,oBAAoB7E,UAEvDe,GAAW,IAAIirB,EAAKlsB,OAAOL,EAAQoF,oBAAoB7E,YAAYqqB,GAAgBgC,KAE3F,CAEJ,OAAOtrB,CACX,CAEA,SAASkoB,GAAS7qB,GACd,MAAM6L,EAAOjM,OAAOiM,KAAK7L,GACzB,IAAK,IAAI2B,EAAI,EAAGA,EAAIkK,EAAKjK,OAAQD,IAAK,CAClC,MAAMjC,EAAMmM,EAAKlK,GACjB,GAAK/B,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKN,IACnC,OAARA,EAAc,OAAOA,CAC7B,CACJ,CAMA,SAASytB,GAAYlC,EAAS5pB,EAAS2rB,EAAYvZ,EAASvG,GACxD,IAAIvK,EAAU,GACd,GAAIsoB,IAAY5pB,EAAQuF,iBACpB,IAAK,IAAIgnB,KAAQ3C,EAAS,CACtB,IAAKrrB,OAAOM,UAAUC,eAAeC,KAAK6qB,EAAS2C,GAAO,SAG1D,MAAMO,EAAgBP,EAAKlsB,OAAOL,EAAQoF,oBAAoB7E,QACxDwsB,EAAmBpB,EACnBmB,EACAjC,GAAeiC,GAAe,EAAM9sB,EAASoS,EAASvG,GAE5D,IAAI+gB,EACAjB,EAEAiB,EAAUhD,EAAQ2C,IAGlBK,EAAU5sB,EAAQoG,wBAAwBmmB,EAAM3C,EAAQ2C,IACxDK,EAAUhJ,GAAqBgJ,EAAS5sB,KAG5B,IAAZ4sB,GAAoB5sB,EAAQ6sB,0BAC5BvrB,GAAW,IAAIyrB,IAEfzrB,GAAW,IAAIyrB,MAAqBnC,GAAgBgC,KAE5D,CAEJ,OAAOtrB,CACX,CAEA,SAASsqB,GAAcxZ,EAAS+Y,GAC5B,IAAKA,GAAsD,IAA/BA,EAAoB5qB,OAAc,OAAO,EAErE,IAAK,IAAID,EAAI,EAAGA,EAAI6qB,EAAoB5qB,OAAQD,IAC5C,GAAI8R,EAAQjP,QAAQgoB,EAAoB7qB,IACpC,OAAO,EAGf,OAAO,CACX,CAEA,SAASsjB,GAAqBoJ,EAAWhtB,GACrC,GAAIgtB,GAAaA,EAAUzsB,OAAS,GAAKP,EAAQyG,gBAC7C,IAAK,IAAInG,EAAI,EAAGA,EAAIN,EAAQqM,SAAS9L,OAAQD,IAAK,CAC9C,MAAM2sB,EAASjtB,EAAQqM,SAAS/L,GAChC0sB,EAAYA,EAAUrqB,QAAQsqB,EAAOnL,MAAOmL,EAAO9mB,IACvD,CAEJ,OAAO6mB,CACX,CC9VA,MAAMrtB,GAAiB,CACrByF,oBAAqB,KACrBC,qBAAqB,EACrBC,aAAc,QACdC,kBAAkB,EAClBK,eAAe,EACfslB,QAAQ,EACRc,SAAU,KACVK,mBAAmB,EACnBD,sBAAsB,EACtBS,2BAA2B,EAC3B3mB,kBAAmB,SAAU7H,EAAK6uB,GAChC,OAAOA,CACT,EACA9mB,wBAAyB,SAAU7B,EAAU2oB,GAC3C,OAAOA,CACT,EACA/nB,eAAe,EACfqB,iBAAiB,EACjB3G,aAAc,GACdwM,SAAU,CACR,CAAEyV,MAAO,IAAIziB,OAAO,IAAK,KAAM8G,IAAK,SACpC,CAAE2b,MAAO,IAAIziB,OAAO,IAAK,KAAM8G,IAAK,QACpC,CAAE2b,MAAO,IAAIziB,OAAO,IAAK,KAAM8G,IAAK,QACpC,CAAE2b,MAAO,IAAIziB,OAAO,IAAM,KAAM8G,IAAK,UACrC,CAAE2b,MAAO,IAAIziB,OAAO,IAAM,KAAM8G,IAAK,WAEvCM,iBAAiB,EACjBJ,UAAW,GAGX8mB,cAAc,EACd/lB,cAAe,IACfH,OAAO,EACPkf,cAAc,GAMD,SAASiH,GAAQptB,GAkB9B,GAjBA9B,KAAK8B,QAAUzB,OAAO0B,OAAO,CAAC,EAAGN,GAAgBK,GAK7C9B,KAAK8B,QAAQqG,WAAauD,MAAMrD,QAAQrI,KAAK8B,QAAQqG,aACvDnI,KAAK8B,QAAQqG,UAAYnI,KAAK8B,QAAQqG,UAAU5D,IAAIoH,GAC9B,iBAATA,GAAqBA,EAAKC,WAAW,MAEvC,KAAOD,EAAK3I,UAAU,GAExB2I,IAKX3L,KAAKitB,oBAAsB,GACvBjtB,KAAK8B,QAAQqG,WAAauD,MAAMrD,QAAQrI,KAAK8B,QAAQqG,WACvD,IAAK,IAAI/F,EAAI,EAAGA,EAAIpC,KAAK8B,QAAQqG,UAAU9F,OAAQD,IAAK,CACtD,MAAMuJ,EAAO3L,KAAK8B,QAAQqG,UAAU/F,GAChB,iBAATuJ,EACT3L,KAAKitB,oBAAoB/oB,KAAK,IAAI8T,GAAWrM,IACpCA,aAAgBqM,IACzBhY,KAAKitB,oBAAoB/oB,KAAKyH,EAElC,CC1EW,IAA+BtE,GD6EN,IAAlCrH,KAAK8B,QAAQuF,kBAA6BrH,KAAK8B,QAAQqF,oBACzDnH,KAAK4sB,YAAc,WACjB,OAAO,CACT,GAEA5sB,KAAK6lB,mBCjF2B,mBADUxe,EDkFMrH,KAAK8B,QAAQuF,kBChFlDA,EAEPqE,MAAMrD,QAAQhB,GACNhB,IACJ,IAAK,MAAM4R,KAAW5Q,EAAkB,CACpC,GAAuB,iBAAZ4Q,GAAwB5R,IAAa4R,EAC5C,OAAO,EAEX,GAAIA,aAAmB9W,QAAU8W,EAAQnK,KAAKzH,GAC1C,OAAO,CAEf,GAGD,KAAM,EDmEbrG,KAAKmvB,cAAgBnvB,KAAK8B,QAAQoF,oBAAoB7E,OACtDrC,KAAK4sB,YAAcA,IAGrB5sB,KAAKovB,qBAAuBA,GAExBpvB,KAAK8B,QAAQkrB,QACfhtB,KAAKqvB,UAAYA,GACjBrvB,KAAKsvB,WAAa,MAClBtvB,KAAKuvB,QAAU,OAEfvvB,KAAKqvB,UAAY,WACf,MAAO,EACT,EACArvB,KAAKsvB,WAAa,IAClBtvB,KAAKuvB,QAAU,GAEnB,CAkCA,SAAS5C,GAAennB,EAAMonB,EAAa9qB,EAASoS,EAASvG,GAC3D,OAAK7L,EAAQmmB,aACT9a,GAAM3H,EAAM,CAAEmI,eAAsBnI,EACjC1D,EAAQmmB,aAAaziB,EAAM,CAAEonB,cAAa1Y,QAASA,EAAQ6D,aAFhCvS,CAGpC,CAqLA,SAAS4pB,GAAqBI,EAAQrvB,EAAKgW,EAAOjC,EAASvG,GAEzD,MAAMsI,EAAajW,KAAKyvB,kBAAkBD,GAQ1C,GALAtb,EAAQhQ,KAAK/D,EAAK8V,GAGCjW,KAAK0tB,cAAcxZ,GAEtB,CAEd,MAAMwb,EAAa1vB,KAAK2vB,gBAAgBH,GAClCpsB,EAAUpD,KAAK4vB,2BAA2BJ,GAEhD,OADAtb,EAAQpQ,MACD9D,KAAK6vB,gBAAgBH,EAAYvvB,EAAKiD,EAAS+S,EACxD,CAEA,MAAMjT,EAASlD,KAAK8vB,IAAIN,EAAQrZ,EAAQ,EAAGjC,EAASvG,GAMpD,OAJAuG,EAAQpQ,MAIO,MAAX3D,EAAI,GACCH,KAAK+vB,iBAAiB,GAAI5vB,EAAK+C,EAAOE,QAAS+S,EAAOjC,QACdjO,IAAtCupB,EAAOxvB,KAAK8B,QAAQsF,eAA8D,IAA/B/G,OAAOiM,KAAKkjB,GAAQntB,OACzErC,KAAK+vB,iBAAiBP,EAAOxvB,KAAK8B,QAAQsF,cAAejH,EAAK+C,EAAOE,QAAS+S,EAAOjC,GAErFlU,KAAK6vB,gBAAgB3sB,EAAO+E,IAAK9H,EAAK+C,EAAOE,QAAS+S,EAEjE,CA8OA,SAASkZ,GAAUlZ,GACjB,OAAOnW,KAAK8B,QAAQgsB,SAASkC,OAAO7Z,EACtC,CAEA,SAASyW,GAAYpnB,GACnB,SAAIA,EAAKoG,WAAW5L,KAAK8B,QAAQoF,sBAAwB1B,IAASxF,KAAK8B,QAAQsF,eACtE5B,EAAKrD,OAAOnC,KAAKmvB,cAI5B,CA1cAD,GAAQvuB,UAAUsvB,MAAQ,SAAUC,GAClC,GAAIlwB,KAAK8B,QAAQmF,cACf,OAAOkpB,GAAmBD,EAAMlwB,KAAK8B,SAChC,CACD4J,MAAMrD,QAAQ6nB,IAASlwB,KAAK8B,QAAQsuB,eAAiBpwB,KAAK8B,QAAQsuB,cAAc/tB,OAAS,IAC3F6tB,EAAO,CACL,CAAClwB,KAAK8B,QAAQsuB,eAAgBF,IAIlC,MAAMhc,EAAU,IAAI0B,GACdjI,EA5CV,SAAiCuiB,EAAMpuB,GACrC,MAAMuuB,EAAOH,EAAK,QAClB,GAAIG,GAAwB,iBAATA,EAAmB,CAEpC,GAAIvuB,EAAQqF,qBAAuBkpB,EAAKvuB,EAAQqF,qBAAsB,CACpE,MAAMmpB,EAAID,EAAKvuB,EAAQqF,qBAAqBrF,EAAQoF,oBAAsB,WAC1E,GAAIopB,EAAG,OAAOA,CAChB,CAEA,MAAMA,EAAID,EAAKvuB,EAAQoF,oBAAsB,WAC7C,GAAIopB,EAAG,OAAOA,CAChB,CACA,MAAO,KACT,CA+BuBC,CAAwBL,EAAMlwB,KAAK8B,SACtD,OAAO9B,KAAK8vB,IAAII,EAAM,EAAGhc,EAASvG,GAAY1F,GAChD,CACF,EAEAinB,GAAQvuB,UAAUmvB,IAAM,SAAUI,EAAM/Z,EAAOjC,EAASvG,GACtD,IAAIvK,EAAU,GACV6E,EAAM,GACV,GAAIjI,KAAK8B,QAAQoH,eAAiBgL,EAAQmB,YAAcrV,KAAK8B,QAAQoH,cACnE,MAAM,IAAIU,MAAM,gCAGlB,MAAMb,EAAQ/I,KAAK8B,QAAQiH,MAAQmL,EAAQoB,WAAapB,EAGlDsc,EAAoBxwB,KAAK0tB,cAAcxZ,GAE7C,IAAK,IAAI/T,KAAO+vB,EAAM,CACpB,IAAK7vB,OAAOM,UAAUC,eAAeC,KAAKqvB,EAAM/vB,GAAM,SAMtD,MAOMswB,EAPetwB,IAAQH,KAAK8B,QAAQsF,cACrCjH,IAAQH,KAAK8B,QAAQ4F,eACrBvH,IAAQH,KAAK8B,QAAQwG,iBACpBtI,KAAK8B,QAAQqF,qBAAuBhH,IAAQH,KAAK8B,QAAQqF,qBAC1DnH,KAAK4sB,YAAYzsB,IACN,MAAXA,EAAI,GAGLA,EACAwsB,GAAexsB,GAAK,EAAOH,KAAK8B,QAASoS,EAASvG,GAEtD,QAAyB,IAAduiB,EAAK/vB,GAEVH,KAAK4sB,YAAYzsB,KACnB8H,GAAO,SAEJ,GAAkB,OAAdioB,EAAK/vB,GAEVH,KAAK4sB,YAAYzsB,IAEVswB,IAAgBzwB,KAAK8B,QAAQ4F,eAAiB+oB,IAAgBzwB,KAAK8B,QAAQwG,gBADpFL,GAAO,GAGqB,MAAnBwoB,EAAY,GACrBxoB,GAAOjI,KAAKqvB,UAAUlZ,GAAS,IAAMsa,EAAc,IAAMzwB,KAAKsvB,WAE9DrnB,GAAOjI,KAAKqvB,UAAUlZ,GAAS,IAAMsa,EAAc,IAAMzwB,KAAKsvB,gBAE3D,GAAIY,EAAK/vB,aAAgBuwB,KAC9BzoB,GAAOjI,KAAK+vB,iBAAiBG,EAAK/vB,GAAMswB,EAAa,GAAIta,EAAOjC,QAC3D,GAAyB,iBAAdgc,EAAK/vB,GAAmB,CAExC,MAAMkuB,EAAOruB,KAAK4sB,YAAYzsB,GAC9B,GAAIkuB,IAASruB,KAAK6lB,mBAAmBwI,EAAMtlB,GAAQ,CAEjD,MAAM4nB,EAAehE,GAAe0B,GAAM,EAAMruB,KAAK8B,QAASoS,EAASvG,GACvEvK,GAAWpD,KAAK4wB,iBAAiBD,EAAc,GAAKT,EAAK/vB,GAAMqwB,EACjE,MAAO,IAAKnC,EAEV,GAAIluB,IAAQH,KAAK8B,QAAQsF,aAAc,CACrC,IAAI6f,EAASjnB,KAAK8B,QAAQkG,kBAAkB7H,EAAK,GAAK+vB,EAAK/vB,IAC3D8H,GAAOjI,KAAK0lB,qBAAqBuB,EACnC,KAAO,CAEL/S,EAAQhQ,KAAKusB,GACb,MAAMhD,EAAaztB,KAAK0tB,cAAcxZ,GAGtC,GAFAA,EAAQpQ,MAEJ2pB,EAAY,CAEd,MAAMqB,EAAY,GAAKoB,EAAK/vB,GAE1B8H,GADgB,KAAd6mB,EACK9uB,KAAKqvB,UAAUlZ,GAAS,IAAMsa,EAAczwB,KAAK6wB,SAASJ,GAAezwB,KAAKsvB,WAE9EtvB,KAAKqvB,UAAUlZ,GAAS,IAAMsa,EAAc,IAAM3B,EAAY,KAAO2B,EAAczwB,KAAKsvB,UAEnG,MACErnB,GAAOjI,KAAK+vB,iBAAiBG,EAAK/vB,GAAMswB,EAAa,GAAIta,EAAOjC,EAEpE,CAEJ,MAAO,GAAIxI,MAAMrD,QAAQ6nB,EAAK/vB,IAAO,CAEnC,MAAM2wB,EAASZ,EAAK/vB,GAAKkC,OACzB,IAAI0uB,EAAa,GACbC,EAAc,GAClB,IAAK,IAAItrB,EAAI,EAAGA,EAAIorB,EAAQprB,IAAK,CAC/B,MAAM4oB,EAAO4B,EAAK/vB,GAAKuF,GACvB,QAAoB,IAAT4oB,QAEJ,GAAa,OAATA,EACc,MAAnBmC,EAAY,GAAYxoB,GAAOjI,KAAKqvB,UAAUlZ,GAAS,IAAMsa,EAAc,IAAMzwB,KAAKsvB,WACrFrnB,GAAOjI,KAAKqvB,UAAUlZ,GAAS,IAAMsa,EAAc,IAAMzwB,KAAKsvB,gBAC9D,GAAoB,iBAAThB,EAChB,GAAItuB,KAAK8B,QAAQmtB,aAAc,CAE7B/a,EAAQhQ,KAAKusB,GACb,MAAMvtB,EAASlD,KAAK8vB,IAAIxB,EAAMnY,EAAQ,EAAGjC,EAASvG,GAElDuG,EAAQpQ,MAERitB,GAAc7tB,EAAO+E,IACjBjI,KAAK8B,QAAQqF,qBAAuBmnB,EAAK1tB,eAAeZ,KAAK8B,QAAQqF,uBACvE6pB,GAAe9tB,EAAOE,QAE1B,MACE2tB,GAAc/wB,KAAKovB,qBAAqBd,EAAMmC,EAAata,EAAOjC,EAASvG,QAG7E,GAAI3N,KAAK8B,QAAQmtB,aAAc,CAC7B,IAAIH,EAAY9uB,KAAK8B,QAAQkG,kBAAkByoB,EAAanC,GAC5DQ,EAAY9uB,KAAK0lB,qBAAqBoJ,GACtCiC,GAAcjC,CAChB,KAAO,CAEL5a,EAAQhQ,KAAKusB,GACb,MAAMhD,EAAaztB,KAAK0tB,cAAcxZ,GAGtC,GAFAA,EAAQpQ,MAEJ2pB,EAAY,CAEd,MAAMqB,EAAY,GAAKR,EAErByC,GADgB,KAAdjC,EACY9uB,KAAKqvB,UAAUlZ,GAAS,IAAMsa,EAAczwB,KAAK6wB,SAASJ,GAAezwB,KAAKsvB,WAE9EtvB,KAAKqvB,UAAUlZ,GAAS,IAAMsa,EAAc,IAAM3B,EAAY,KAAO2B,EAAczwB,KAAKsvB,UAE1G,MACEyB,GAAc/wB,KAAK+vB,iBAAiBzB,EAAMmC,EAAa,GAAIta,EAAOjC,EAEtE,CAEJ,CACIlU,KAAK8B,QAAQmtB,eACf8B,EAAa/wB,KAAK6vB,gBAAgBkB,EAAYN,EAAaO,EAAa7a,IAE1ElO,GAAO8oB,CACT,MAEE,GAAI/wB,KAAK8B,QAAQqF,qBAAuBhH,IAAQH,KAAK8B,QAAQqF,oBAAqB,CAChF,MAAM8pB,EAAK5wB,OAAOiM,KAAK4jB,EAAK/vB,IACtB+wB,EAAID,EAAG5uB,OACb,IAAK,IAAIqD,EAAI,EAAGA,EAAIwrB,EAAGxrB,IAAK,CAE1B,MAAMirB,EAAehE,GAAesE,EAAGvrB,IAAI,EAAM1F,KAAK8B,QAASoS,EAASvG,GACxEvK,GAAWpD,KAAK4wB,iBAAiBD,EAAc,GAAKT,EAAK/vB,GAAK8wB,EAAGvrB,IAAK8qB,EACxE,CACF,MACEvoB,GAAOjI,KAAKovB,qBAAqBc,EAAK/vB,GAAMswB,EAAata,EAAOjC,EAASvG,EAG/E,CACA,MAAO,CAAEvK,QAASA,EAAS6E,IAAKA,EAClC,EAEAinB,GAAQvuB,UAAUiwB,iBAAmB,SAAUvqB,EAAU4B,EAAKwlB,GAK5D,OAJKA,IACHxlB,EAAMjI,KAAK8B,QAAQoG,wBAAwB7B,EAAU,GAAK4B,GAC1DA,EAAMjI,KAAK0lB,qBAAqBzd,IAE9BjI,KAAK8B,QAAQ6sB,2BAAqC,SAAR1mB,EACrC,IAAM5B,EACD,IAAMA,EAAW,KAAOqmB,GAAgBzkB,GAAO,GAC/D,EAoCAinB,GAAQvuB,UAAU8uB,kBAAoB,SAAUhvB,GAC9C,IAAKA,GAAsB,iBAARA,EAAkB,OAAO,KAE5C,MAAMwV,EAAa,CAAC,EACpB,IAAI8R,GAAW,EAGf,GAAI/nB,KAAK8B,QAAQqF,qBAAuB1G,EAAIT,KAAK8B,QAAQqF,qBAAsB,CAC7E,MAAMgqB,EAAY1wB,EAAIT,KAAK8B,QAAQqF,qBACnC,IAAK,IAAIiqB,KAAWD,EACb9wB,OAAOM,UAAUC,eAAeC,KAAKswB,EAAWC,KAKrDnb,EAHiBmb,EAAQxlB,WAAW5L,KAAK8B,QAAQoF,qBAC7CkqB,EAAQpuB,UAAUhD,KAAK8B,QAAQoF,oBAAoB7E,QACnD+uB,GACmB1E,GAAgByE,EAAUC,IACjDrJ,GAAW,EAEf,MAEE,IAAK,IAAI5nB,KAAOM,EAAK,CACnB,IAAKJ,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKN,GAAM,SACrD,MAAMkuB,EAAOruB,KAAK4sB,YAAYzsB,GAC1BkuB,IACFpY,EAAWoY,GAAQ3B,GAAgBjsB,EAAIN,IACvC4nB,GAAW,EAEf,CAGF,OAAOA,EAAW9R,EAAa,IACjC,EAGAiZ,GAAQvuB,UAAUgvB,gBAAkB,SAAUlvB,GAC5C,GAAmB,iBAARA,EACT,OAAOA,EAGT,GAAmB,iBAARA,GAA4B,OAARA,EAC7B,OAAO8R,OAAO9R,GAIhB,QAAuCwF,IAAnCxF,EAAIT,KAAK8B,QAAQsF,cACnB,OAAO3G,EAAIT,KAAK8B,QAAQsF,cAI1B,IAAIyR,EAAU,GAEd,IAAK,IAAI1Y,KAAOM,EAAK,CACnB,IAAKJ,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKN,GAAM,SAGrD,GAAIH,KAAK4sB,YAAYzsB,GAAM,SAC3B,GAAIH,KAAK8B,QAAQqF,qBAAuBhH,IAAQH,KAAK8B,QAAQqF,oBAAqB,SAElF,MAAMnG,EAAQP,EAAIN,GAElB,GAAIA,IAAQH,KAAK8B,QAAQsF,aACvByR,GAAW7X,OACN,GAAI0K,MAAMrD,QAAQrH,IAEvB,IAAK,IAAIstB,KAAQttB,EACf,GAAoB,iBAATstB,GAAqC,iBAATA,EACrCzV,GAAW,IAAI1Y,KAAOmuB,MAASnuB,UAC1B,GAAoB,iBAATmuB,GAA8B,OAATA,EAAe,CACpD,MAAMG,EAAgBzuB,KAAK2vB,gBAAgBrB,GACrC+C,EAAcrxB,KAAK4vB,2BAA2BtB,GAElDzV,GADoB,KAAlB4V,EACS,IAAItuB,IAAMkxB,MAEV,IAAIlxB,IAAMkxB,KAAe5C,MAAkBtuB,IAE1D,OAEG,GAAqB,iBAAVa,GAAgC,OAAVA,EAAgB,CAEtD,MAAMytB,EAAgBzuB,KAAK2vB,gBAAgB3uB,GACrCqwB,EAAcrxB,KAAK4vB,2BAA2B5uB,GAElD6X,GADoB,KAAlB4V,EACS,IAAItuB,IAAMkxB,MAEV,IAAIlxB,IAAMkxB,KAAe5C,MAAkBtuB,IAE1D,MAEE0Y,GAAW,IAAI1Y,KAAOa,MAAUb,IAEpC,CAEA,OAAO0Y,CACT,EAGAqW,GAAQvuB,UAAUivB,2BAA6B,SAAUnvB,GACvD,IAAKA,GAAsB,iBAARA,EAAkB,MAAO,GAE5C,IAAI2C,EAAU,GAGd,GAAIpD,KAAK8B,QAAQqF,qBAAuB1G,EAAIT,KAAK8B,QAAQqF,qBAAsB,CAC7E,MAAMgqB,EAAY1wB,EAAIT,KAAK8B,QAAQqF,qBACnC,IAAK,IAAIiqB,KAAWD,EAAW,CAC7B,IAAK9wB,OAAOM,UAAUC,eAAeC,KAAKswB,EAAWC,GAAU,SAC/D,MAAME,EAAWF,EAAQxlB,WAAW5L,KAAK8B,QAAQoF,qBAC7CkqB,EAAQpuB,UAAUhD,KAAK8B,QAAQoF,oBAAoB7E,QACnD+uB,EACEnpB,EAAMkpB,EAAUC,IACV,IAARnpB,GAAgBjI,KAAK8B,QAAQ6sB,0BAC/BvrB,GAAW,IAAMkuB,EAEjBluB,GAAW,IAAMkuB,EAAW,KAAOrpB,EAAM,GAE7C,CACF,MAEE,IAAK,IAAI9H,KAAOM,EAAK,CACnB,IAAKJ,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKN,GAAM,SACrD,MAAMkuB,EAAOruB,KAAK4sB,YAAYzsB,GAC9B,GAAIkuB,EAAM,CACR,MAAMpmB,EAAMxH,EAAIN,IACJ,IAAR8H,GAAgBjI,KAAK8B,QAAQ6sB,0BAC/BvrB,GAAW,IAAMirB,EAEjBjrB,GAAW,IAAMirB,EAAO,KAAOpmB,EAAM,GAEzC,CACF,CAGF,OAAO7E,CACT,EAEA8rB,GAAQvuB,UAAUkvB,gBAAkB,SAAU5nB,EAAK9H,EAAKiD,EAAS+S,GAC/D,GAAY,KAARlO,EACF,MAAe,MAAX9H,EAAI,GAAmBH,KAAKqvB,UAAUlZ,GAAS,IAAMhW,EAAMiD,EAAU,IAAMpD,KAAKsvB,WAE3EtvB,KAAKqvB,UAAUlZ,GAAS,IAAMhW,EAAMiD,EAAUpD,KAAK6wB,SAAS1wB,GAAOH,KAAKsvB,WAE5E,GAAe,MAAXnvB,EAAI,GAEb,OAAOH,KAAKqvB,UAAUlZ,GAAS,IAAMhW,EAAMiD,EAAU,IAAMpD,KAAKsvB,WAC3D,CACL,IAAIiC,EAAY,KAAOpxB,EAAMH,KAAKsvB,WAC9BkC,EAAgB,GAQpB,MANe,MAAXrxB,EAAI,KACNqxB,EAAgB,IAChBD,EAAY,KAITnuB,GAAuB,KAAZA,IAAyC,IAAtB6E,EAAIhE,QAAQ,MAEH,IAAjCjE,KAAK8B,QAAQwG,iBAA6BnI,IAAQH,KAAK8B,QAAQwG,iBAA4C,IAAzBkpB,EAAcnvB,OAClGrC,KAAKqvB,UAAUlZ,GAAS,UAAOlO,UAAWjI,KAAKuvB,QAGpDvvB,KAAKqvB,UAAUlZ,GAAS,IAAMhW,EAAMiD,EAAUouB,EAAgBxxB,KAAKsvB,WACnErnB,EACAjI,KAAKqvB,UAAUlZ,GAASob,EAPlBvxB,KAAKqvB,UAAUlZ,GAAS,IAAMhW,EAAMiD,EAAUouB,EAAgB,IAAMvpB,EAAMspB,CAStF,CACF,EAEArC,GAAQvuB,UAAUkwB,SAAW,SAAU1wB,GACrC,IAAI0wB,EAAW,GAQf,OAPgD,IAA5C7wB,KAAK8B,QAAQH,aAAasC,QAAQ9D,GAC/BH,KAAK8B,QAAQosB,uBAAsB2C,EAAW,KAEnDA,EADS7wB,KAAK8B,QAAQqsB,kBACX,IAEA,MAAMhuB,IAEZ0wB,CACT,EAEA3B,GAAQvuB,UAAU+sB,cAAgB,SAAUxZ,GAC1C,IAAKlU,KAAKitB,qBAA2D,IAApCjtB,KAAKitB,oBAAoB5qB,OAAc,OAAO,EAE/E,IAAK,IAAID,EAAI,EAAGA,EAAIpC,KAAKitB,oBAAoB5qB,OAAQD,IACnD,GAAI8R,EAAQjP,QAAQjF,KAAKitB,oBAAoB7qB,IAC3C,OAAO,EAGX,OAAO,CACT,EAaA8sB,GAAQvuB,UAAUovB,iBAAmB,SAAU9nB,EAAK9H,EAAKiD,EAAS+S,EAAOjC,GACvE,IAAmC,IAA/BlU,KAAK8B,QAAQ4F,eAA2BvH,IAAQH,KAAK8B,QAAQ4F,cAAe,CAC9E,MAAM+pB,EAAUhF,GAAUxkB,GAC1B,OAAOjI,KAAKqvB,UAAUlZ,GAAS,YAAYsb,OAAezxB,KAAKuvB,OACjE,CAAO,IAAqC,IAAjCvvB,KAAK8B,QAAQwG,iBAA6BnI,IAAQH,KAAK8B,QAAQwG,gBAAiB,CACzF,MAAMmpB,EAAUjF,GAAYvkB,GAC5B,OAAOjI,KAAKqvB,UAAUlZ,GAAS,UAAOsb,UAAezxB,KAAKuvB,OAC5D,CAAO,GAAe,MAAXpvB,EAAI,GACb,OAAOH,KAAKqvB,UAAUlZ,GAAS,IAAMhW,EAAMiD,EAAU,IAAMpD,KAAKsvB,WAC3D,CAEL,IAAIR,EAAY9uB,KAAK8B,QAAQkG,kBAAkB7H,EAAK8H,GAGpD,OAFA6mB,EAAY9uB,KAAK0lB,qBAAqBoJ,GAEpB,KAAdA,EACK9uB,KAAKqvB,UAAUlZ,GAAS,IAAMhW,EAAMiD,EAAUpD,KAAK6wB,SAAS1wB,GAAOH,KAAKsvB,WAExEtvB,KAAKqvB,UAAUlZ,GAAS,IAAMhW,EAAMiD,EAAU,IACnD0rB,EACA,KAAO3uB,EAAMH,KAAKsvB,UAExB,CACF,EAEAJ,GAAQvuB,UAAU+kB,qBAAuB,SAAUoJ,GACjD,GAAIA,GAAaA,EAAUzsB,OAAS,GAAKrC,KAAK8B,QAAQyG,gBACpD,IAAK,IAAInG,EAAI,EAAGA,EAAIpC,KAAK8B,QAAQqM,SAAS9L,OAAQD,IAAK,CACrD,MAAM2sB,EAAS/uB,KAAK8B,QAAQqM,SAAS/L,GACrC0sB,EAAYA,EAAUrqB,QAAQsqB,EAAOnL,MAAOmL,EAAO9mB,IACrD,CAEF,OAAO6mB,CACT,EExkBA,YCIA,IAAM4C,GAAe,CACnB9vB,SAAUA,G","sources":["webpack://fxp/webpack/universalModuleDefinition","webpack://fxp/webpack/bootstrap","webpack://fxp/webpack/runtime/define property getters","webpack://fxp/webpack/runtime/hasOwnProperty shorthand","webpack://fxp/webpack/runtime/make namespace object","webpack://fxp/./src/util.js","webpack://fxp/./src/validator.js","webpack://fxp/./src/xmlparser/OptionsBuilder.js","webpack://fxp/./src/xmlparser/xmlNode.js","webpack://fxp/./node_modules/xml-naming/src/index.js","webpack://fxp/./src/xmlparser/DocTypeReader.js","webpack://fxp/./node_modules/anynum/digitTable.js","webpack://fxp/./node_modules/anynum/anynum.js","webpack://fxp/./node_modules/strnum/strnum.js","webpack://fxp/./node_modules/path-expression-matcher/src/Matcher.js","webpack://fxp/./node_modules/path-expression-matcher/src/Expression.js","webpack://fxp/./node_modules/path-expression-matcher/src/ExpressionSet.js","webpack://fxp/./node_modules/@nodable/entities/src/entities.js","webpack://fxp/./node_modules/@nodable/entities/src/EntityDecoder.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/sql.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/sql-strict.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/html.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/xml.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/svg.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/shell.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/redos.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/nosql.js","webpack://fxp/./node_modules/is-unsafe/src/contexts/log.js","webpack://fxp/./node_modules/is-unsafe/src/index.js","webpack://fxp/./src/xmlparser/OrderedObjParser.js","webpack://fxp/./src/ignoreAttributes.js","webpack://fxp/./src/xmlparser/node2json.js","webpack://fxp/./src/xmlparser/XMLParser.js","webpack://fxp/./node_modules/fast-xml-builder/src/util.js","webpack://fxp/./node_modules/fast-xml-builder/node_modules/xml-naming/src/index.js","webpack://fxp/./node_modules/fast-xml-builder/src/orderedJs2Xml.js","webpack://fxp/./node_modules/fast-xml-builder/src/fxb.js","webpack://fxp/./node_modules/fast-xml-builder/src/ignoreAttributes.js","webpack://fxp/./src/xmlbuilder/json2xml.js","webpack://fxp/./src/fxp.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"fxp\"] = factory();\n\telse\n\t\troot[\"fxp\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","'use strict';\n\nconst nameStartChar = ':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';\nconst nameChar = nameStartChar + '\\\\-.\\\\d\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\nexport const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';\nconst regexName = new RegExp('^' + nameRegexp + '$');\n\nexport function getAllMatches(string, regex) {\n const matches = [];\n let match = regex.exec(string);\n while (match) {\n const allmatches = [];\n allmatches.startIndex = regex.lastIndex - match[0].length;\n const len = match.length;\n for (let index = 0; index < len; index++) {\n allmatches.push(match[index]);\n }\n matches.push(allmatches);\n match = regex.exec(string);\n }\n return matches;\n}\n\nexport const isName = function (string) {\n const match = regexName.exec(string);\n return !(match === null || typeof match === 'undefined');\n}\n\nexport function isExist(v) {\n return typeof v !== 'undefined';\n}\n\nexport function isEmptyObject(obj) {\n return Object.keys(obj).length === 0;\n}\n\nexport function getValue(v) {\n if (exports.isExist(v)) {\n return v;\n } else {\n return '';\n }\n}\n\n/**\n * Dangerous property names that could lead to prototype pollution or security issues\n */\nexport const DANGEROUS_PROPERTY_NAMES = [\n // '__proto__',\n // 'constructor',\n // 'prototype',\n 'hasOwnProperty',\n 'toString',\n 'valueOf',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__'\n];\n\nexport const criticalProperties = [\"__proto__\", \"constructor\", \"prototype\"];","'use strict';\n\nimport { isName } from './util.js';\n\nconst defaultOptions = {\n allowBooleanAttributes: false, //A tag can have attributes without any value\n unpairedTags: []\n};\n\n//const tagsPattern = new RegExp(\"<\\\\/?([\\\\w:\\\\-_\\.]+)\\\\s*\\/?>\",\"g\");\nexport function validate(xmlData, options) {\n options = Object.assign({}, defaultOptions, options);\n\n //xmlData = xmlData.replace(/(\\r\\n|\\n|\\r)/gm,\"\");//make it single line\n //xmlData = xmlData.replace(/(^\\s*<\\?xml.*?\\?>)/g,\"\");//Remove XML starting tag\n //xmlData = xmlData.replace(/()/g,\"\");//Remove DOCTYPE\n const tags = [];\n let tagFound = false;\n\n //indicates that the root tag has been closed (aka. depth 0 has been reached)\n let reachedRoot = false;\n\n if (xmlData[0] === '\\ufeff') {\n // check for byte order mark (BOM)\n xmlData = xmlData.substr(1);\n }\n\n for (let i = 0; i < xmlData.length; i++) {\n\n if (xmlData[i] === '<' && xmlData[i + 1] === '?') {\n i += 2;\n i = readPI(xmlData, i);\n if (i.err) return i;\n } else if (xmlData[i] === '<') {\n //starting of tag\n //read until you reach to '>' avoiding any '>' in attribute value\n let tagStartPos = i;\n i++;\n\n if (xmlData[i] === '!') {\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else {\n let closingTag = false;\n if (xmlData[i] === '/') {\n //closing tag\n closingTag = true;\n i++;\n }\n //read tagname\n let tagName = '';\n for (; i < xmlData.length &&\n xmlData[i] !== '>' &&\n xmlData[i] !== ' ' &&\n xmlData[i] !== '\\t' &&\n xmlData[i] !== '\\n' &&\n xmlData[i] !== '\\r'; i++\n ) {\n tagName += xmlData[i];\n }\n tagName = tagName.trim();\n //console.log(tagName);\n\n if (tagName[tagName.length - 1] === '/') {\n //self closing tag without attributes\n tagName = tagName.substring(0, tagName.length - 1);\n //continue;\n i--;\n }\n if (!validateTagName(tagName)) {\n let msg;\n if (tagName.trim().length === 0) {\n msg = \"Invalid space after '<'.\";\n } else {\n msg = \"Tag '\" + tagName + \"' is an invalid name.\";\n }\n return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));\n }\n\n const result = readAttributeStr(xmlData, i);\n if (result === false) {\n return getErrorObject('InvalidAttr', \"Attributes for '\" + tagName + \"' have open quote.\", getLineNumberForPosition(xmlData, i));\n }\n let attrStr = result.value;\n i = result.index;\n\n if (attrStr[attrStr.length - 1] === '/') {\n //self closing tag\n const attrStrStart = i - attrStr.length;\n attrStr = attrStr.substring(0, attrStr.length - 1);\n const isValid = validateAttributeString(attrStr, options);\n if (isValid === true) {\n tagFound = true;\n //continue; //text may presents after self closing tag\n } else {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));\n }\n } else if (closingTag) {\n if (!result.tagClosed) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' doesn't have proper closing.\", getLineNumberForPosition(xmlData, i));\n } else if (attrStr.trim().length > 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' can't have attributes or invalid starting.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else if (tags.length === 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' has not been opened.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else {\n const otg = tags.pop();\n if (tagName !== otg.tagName) {\n let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);\n return getErrorObject('InvalidTag',\n \"Expected closing tag '\" + otg.tagName + \"' (opened in line \" + openPos.line + \", col \" + openPos.col + \") instead of closing tag '\" + tagName + \"'.\",\n getLineNumberForPosition(xmlData, tagStartPos));\n }\n\n //when there are no more tags, we reached the root level.\n if (tags.length == 0) {\n reachedRoot = true;\n }\n }\n } else {\n const isValid = validateAttributeString(attrStr, options);\n if (isValid !== true) {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));\n }\n\n //if the root level has been reached before ...\n if (reachedRoot === true) {\n return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));\n } else if (options.unpairedTags.indexOf(tagName) !== -1) {\n //don't push into stack\n } else {\n tags.push({ tagName, tagStartPos });\n }\n tagFound = true;\n }\n\n //skip tag text value\n //It may include comments and CDATA value\n for (i++; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n if (xmlData[i + 1] === '!') {\n //comment or CADATA\n i++;\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else if (xmlData[i + 1] === '?') {\n i = readPI(xmlData, ++i);\n if (i.err) return i;\n } else {\n break;\n }\n } else if (xmlData[i] === '&') {\n const afterAmp = validateAmpersand(xmlData, i);\n if (afterAmp == -1)\n return getErrorObject('InvalidChar', \"char '&' is not expected.\", getLineNumberForPosition(xmlData, i));\n i = afterAmp;\n } else {\n if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {\n return getErrorObject('InvalidXml', \"Extra text at the end\", getLineNumberForPosition(xmlData, i));\n }\n }\n } //end of reading tag text value\n if (xmlData[i] === '<') {\n i--;\n }\n }\n } else {\n if (isWhiteSpace(xmlData[i])) {\n continue;\n }\n return getErrorObject('InvalidChar', \"char '\" + xmlData[i] + \"' is not expected.\", getLineNumberForPosition(xmlData, i));\n }\n }\n\n if (!tagFound) {\n return getErrorObject('InvalidXml', 'Start tag expected.', 1);\n } else if (tags.length == 1) {\n return getErrorObject('InvalidTag', \"Unclosed tag '\" + tags[0].tagName + \"'.\", getLineNumberForPosition(xmlData, tags[0].tagStartPos));\n } else if (tags.length > 0) {\n return getErrorObject('InvalidXml', \"Invalid '\" +\n JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\\r?\\n/g, '') +\n \"' found.\", { line: 1, col: 1 });\n }\n\n return true;\n};\n\nfunction isWhiteSpace(char) {\n return char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n}\n/**\n * Read Processing insstructions and skip\n * @param {*} xmlData\n * @param {*} i\n */\nfunction readPI(xmlData, i) {\n const start = i;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] == '?' || xmlData[i] == ' ') {\n //tagname\n const tagname = xmlData.substr(start, i - start);\n if (i > 5 && tagname === 'xml') {\n return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));\n } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {\n //check if valid attribut string\n i++;\n break;\n } else {\n continue;\n }\n }\n }\n return i;\n}\n\nfunction readCommentAndCDATA(xmlData, i) {\n if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {\n //comment\n for (i += 3; i < xmlData.length; i++) {\n if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n } else if (\n xmlData.length > i + 8 &&\n xmlData[i + 1] === 'D' &&\n xmlData[i + 2] === 'O' &&\n xmlData[i + 3] === 'C' &&\n xmlData[i + 4] === 'T' &&\n xmlData[i + 5] === 'Y' &&\n xmlData[i + 6] === 'P' &&\n xmlData[i + 7] === 'E'\n ) {\n let angleBracketsCount = 1;\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n angleBracketsCount++;\n } else if (xmlData[i] === '>') {\n angleBracketsCount--;\n if (angleBracketsCount === 0) {\n break;\n }\n }\n }\n } else if (\n xmlData.length > i + 9 &&\n xmlData[i + 1] === '[' &&\n xmlData[i + 2] === 'C' &&\n xmlData[i + 3] === 'D' &&\n xmlData[i + 4] === 'A' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'A' &&\n xmlData[i + 7] === '['\n ) {\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n }\n\n return i;\n}\n\nconst doubleQuote = '\"';\nconst singleQuote = \"'\";\n\n/**\n * Keep reading xmlData until '<' is found outside the attribute value.\n * @param {string} xmlData\n * @param {number} i\n */\nfunction readAttributeStr(xmlData, i) {\n let attrStr = '';\n let startChar = '';\n let tagClosed = false;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {\n if (startChar === '') {\n startChar = xmlData[i];\n } else if (startChar !== xmlData[i]) {\n //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa\n } else {\n startChar = '';\n }\n } else if (xmlData[i] === '>') {\n if (startChar === '') {\n tagClosed = true;\n break;\n }\n }\n attrStr += xmlData[i];\n }\n if (startChar !== '') {\n return false;\n }\n\n return {\n value: attrStr,\n index: i,\n tagClosed: tagClosed\n };\n}\n\n/**\n * Walk `attrStr` once, left to right, splitting it into attribute tokens.\n *\n * This replaces a regex that used to do the same job\n * (`(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?`). That regex led with an\n * optional whitespace group followed by a required \"non-whitespace\" group.\n * On a long run of whitespace that never resolves into an attribute name\n * (e.g. a tag with thousands of trailing spaces before `>`), the engine\n * backtracks the whitespace group one character at a time before giving up\n * and moving to the next starting position — one full backtrack per\n * position, which is quadratic in the length of the run.\n *\n * A single forward-only scan can never backtrack, so it can't be made slow\n * this way no matter how much whitespace the input contains — it's always\n * proportional to the length of the string, once.\n *\n * Each returned token mirrors the shape the old regex match array had, so\n * the validation logic below (which reads token[1]..token[6]) didn't need\n * to change:\n * token.startIndex - where this token begins in attrStr\n * token[1] - leading whitespace before the name\n * token[2] - the attribute name\n * token[3] - whitespace + '=' if present, else undefined\n * token[4] - marker (any defined value) if a quoted value was found\n * token[5] - the quote character used ('\"' or \"'\")\n * token[6] - the value's text, without the surrounding quotes\n *\n * A malformed leading character (e.g. a stray '=' with no name before it)\n * is simply skipped over, one character at a time — the same outcome the\n * old regex produced by failing to match at that position and retrying at\n * the next one.\n */\nfunction scanAttributeTokens(attrStr) {\n const tokens = [];\n const len = attrStr.length;\n let i = 0;\n\n while (i < len) {\n const tokenStart = i;\n\n // Leading whitespace before the name.\n while (i < len && isWhiteSpace(attrStr[i])) i++;\n if (i >= len) break; // trailing whitespace only — nothing left to read\n\n if (attrStr[i] === '=') {\n // No name before this '=' — not a valid attribute start. Move past\n // just this one character and try again from the next position.\n i = tokenStart + 1;\n continue;\n }\n\n const leadingWs = attrStr.slice(tokenStart, i);\n\n // Attribute name — everything up to the next whitespace or '='.\n const nameStart = i;\n while (i < len && !isWhiteSpace(attrStr[i]) && attrStr[i] !== '=') i++;\n const name = attrStr.slice(nameStart, i);\n\n // Optional whitespace + '='.\n let equalsGroup; // whitespace + '=' text, or undefined if absent\n let j = i;\n while (j < len && isWhiteSpace(attrStr[j])) j++;\n if (j < len && attrStr[j] === '=') {\n equalsGroup = attrStr.slice(i, j + 1);\n i = j + 1;\n }\n\n // Optional whitespace + quoted value.\n let quoteChar;\n let value;\n let k = i;\n while (k < len && isWhiteSpace(attrStr[k])) k++;\n if (k < len && (attrStr[k] === '\"' || attrStr[k] === \"'\")) {\n const valueStart = k + 1;\n const closeIdx = attrStr.indexOf(attrStr[k], valueStart);\n if (closeIdx !== -1) {\n quoteChar = attrStr[k];\n value = attrStr.slice(valueStart, closeIdx);\n i = closeIdx + 1;\n }\n // No closing quote found anywhere in the rest of the string — leave\n // quoteChar/value undefined, same as the old regex's group failing\n // to match a backreference-less run.\n }\n\n const token = { startIndex: tokenStart };\n token[1] = leadingWs;\n token[2] = name;\n token[3] = equalsGroup;\n token[4] = quoteChar !== undefined ? true : undefined;\n token[5] = quoteChar;\n token[6] = value;\n tokens.push(token);\n }\n\n return tokens;\n}\n\n//attr, =\"sd\", a=\"amit's\", a=\"sd\"b=\"saf\", ab cd=\"\"\n\nfunction validateAttributeString(attrStr, options) {\n //console.log(\"start:\"+attrStr+\":end\");\n\n //if(attrStr.trim().length === 0) return true; //empty string\n\n const matches = scanAttributeTokens(attrStr);\n const attrNames = {};\n\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][1].length === 0) {\n //nospace before attribute name: a=\"sd\"b=\"saf\"\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' has no space in starting.\", getPositionFromMatch(matches[i]))\n } else if (matches[i][3] !== undefined && matches[i][4] === undefined) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' is without value.\", getPositionFromMatch(matches[i]));\n } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {\n //independent attribute: ab\n return getErrorObject('InvalidAttr', \"boolean attribute '\" + matches[i][2] + \"' is not allowed.\", getPositionFromMatch(matches[i]));\n }\n /* else if(matches[i][6] === undefined){//attribute without value: ab=\n return { err: { code:\"InvalidAttr\",msg:\"attribute \" + matches[i][2] + \" has no value assigned.\"}};\n } */\n const attrName = matches[i][2];\n if (!validateAttrName(attrName)) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is an invalid name.\", getPositionFromMatch(matches[i]));\n }\n if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) {\n //check for duplicate attribute.\n attrNames[attrName] = 1;\n } else {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is repeated.\", getPositionFromMatch(matches[i]));\n }\n }\n\n return true;\n}\n\nfunction validateNumberAmpersand(xmlData, i) {\n let re = /\\d/;\n if (xmlData[i] === 'x') {\n i++;\n re = /[\\da-fA-F]/;\n }\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === ';')\n return i;\n if (!xmlData[i].match(re))\n break;\n }\n return -1;\n}\n\nfunction validateAmpersand(xmlData, i) {\n // https://www.w3.org/TR/xml/#dt-charref\n i++;\n if (xmlData[i] === ';')\n return -1;\n if (xmlData[i] === '#') {\n i++;\n return validateNumberAmpersand(xmlData, i);\n }\n let count = 0;\n for (; i < xmlData.length; i++, count++) {\n if (xmlData[i].match(/\\w/) && count < 20)\n continue;\n if (xmlData[i] === ';')\n break;\n return -1;\n }\n return i;\n}\n\nfunction getErrorObject(code, message, lineNumber) {\n return {\n err: {\n code: code,\n msg: message,\n line: lineNumber.line || lineNumber,\n col: lineNumber.col,\n },\n };\n}\n\nfunction validateAttrName(attrName) {\n return isName(attrName);\n}\n\n// const startsWithXML = /^xml/i;\n\nfunction validateTagName(tagname) {\n return isName(tagname) /* && !tagname.match(startsWithXML) */;\n}\n\n//this function returns the line number for the character at the given index\nfunction getLineNumberForPosition(xmlData, index) {\n const lines = xmlData.substring(0, index).split(/\\r?\\n/);\n return {\n line: lines.length,\n\n // column number is last line's length + 1, because column numbering starts at 1:\n col: lines[lines.length - 1].length + 1\n };\n}\n\n//this function returns the position of the first character of match within attrStr\nfunction getPositionFromMatch(match) {\n return match.startIndex + match[1].length;\n}","import { DANGEROUS_PROPERTY_NAMES, criticalProperties } from \"../util.js\";\nimport { COMMON_HTML, CURRENCY } from '@nodable/entities';\n\nconst defaultOnDangerousProperty = (name) => {\n if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return \"__\" + name;\n }\n return name;\n};\n\n\nexport const defaultOptions = {\n preserveOrder: false,\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n removeNSPrefix: false, // remove NS from tag name or attribute name if true\n allowBooleanAttributes: false, //a tag can have attributes without any value\n //ignoreRootElement : false,\n parseTagValue: true,\n parseAttributeValue: false,\n trimValues: true, //Trim string values of tag and attributes\n cdataPropName: false,\n numberParseOptions: {\n hex: true,\n leadingZeros: true,\n eNotation: true,\n unicode: false\n },\n tagValueProcessor: function (tagName, val) {\n return val;\n },\n attributeValueProcessor: function (attrName, val) {\n return val;\n },\n stopNodes: [], //nested tags will not be parsed even for errors\n alwaysCreateTextNode: false,\n isArray: () => false,\n commentPropName: false,\n unpairedTags: [],\n processEntities: true,\n htmlEntities: false,\n entityDecoder: null,\n ignoreDeclaration: false,\n ignorePiTags: false,\n transformTagName: false,\n transformAttributeName: false,\n updateTag: function (tagName, jPath, attrs) {\n return tagName\n },\n // skipEmptyListItem: false\n captureMetaData: false,\n maxNestedTags: 100,\n strictReservedNames: true,\n jPath: true, // if true, pass jPath string to callbacks; if false, pass matcher instance\n onDangerousProperty: defaultOnDangerousProperty\n};\n\n\n/**\n * Validates that a property name is safe to use\n * @param {string} propertyName - The property name to validate\n * @param {string} optionName - The option field name (for error message)\n * @throws {Error} If property name is dangerous\n */\nfunction validatePropertyName(propertyName, optionName) {\n if (typeof propertyName !== 'string') {\n return; // Only validate string property names\n }\n\n const normalized = propertyName.toLowerCase();\n if (DANGEROUS_PROPERTY_NAMES.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n\n if (criticalProperties.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n}\n\n/**\n * Normalizes processEntities option for backward compatibility\n * @param {boolean|object} value \n * @returns {object} Always returns normalized object\n */\nfunction normalizeProcessEntities(value, htmlEntities) {\n // Boolean backward compatibility\n if (typeof value === 'boolean') {\n return {\n enabled: value, // true or false\n maxEntitySize: 10000,\n maxExpansionDepth: 10000,\n maxTotalExpansions: Infinity,\n maxExpandedLength: 100000,\n maxEntityCount: 1000,\n allowedTags: null,\n tagFilter: null,\n appliesTo: \"all\",\n };\n }\n\n // Object config - merge with defaults\n if (typeof value === 'object' && value !== null) {\n return {\n enabled: value.enabled !== false,\n maxEntitySize: Math.max(1, value.maxEntitySize ?? 10000),\n maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10000),\n maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? Infinity),\n maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 100000),\n maxEntityCount: Math.max(1, value.maxEntityCount ?? 1000),\n allowedTags: value.allowedTags ?? null,\n tagFilter: value.tagFilter ?? null,\n appliesTo: value.appliesTo ?? \"all\",\n };\n }\n\n // Default to enabled with limits\n return normalizeProcessEntities(true);\n}\n\nexport const buildOptions = function (options) {\n const built = Object.assign({}, defaultOptions, options);\n\n // Validate property names to prevent prototype pollution\n const propertyNameOptions = [\n { value: built.attributeNamePrefix, name: 'attributeNamePrefix' },\n { value: built.attributesGroupName, name: 'attributesGroupName' },\n { value: built.textNodeName, name: 'textNodeName' },\n { value: built.cdataPropName, name: 'cdataPropName' },\n { value: built.commentPropName, name: 'commentPropName' }\n ];\n\n for (const { value, name } of propertyNameOptions) {\n if (value) {\n validatePropertyName(value, name);\n }\n }\n\n if (built.onDangerousProperty === null) {\n built.onDangerousProperty = defaultOnDangerousProperty;\n }\n\n // Always normalize processEntities for backward compatibility and validation\n built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities);\n built.unpairedTagsSet = new Set(built.unpairedTags);\n // Convert old-style stopNodes for backward compatibility\n if (built.stopNodes && Array.isArray(built.stopNodes)) {\n built.stopNodes = built.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Old syntax: *.tagname meant \"tagname anywhere\"\n // Convert to new syntax: ..tagname\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n //console.debug(built.processEntities)\n return built;\n};","'use strict';\n\nlet METADATA_SYMBOL;\n\nif (typeof Symbol !== \"function\") {\n METADATA_SYMBOL = \"@@xmlMetadata\";\n} else {\n METADATA_SYMBOL = Symbol(\"XML Node Metadata\");\n}\n\nexport default class XmlNode {\n constructor(tagname) {\n this.tagname = tagname;\n this.child = []; //nested tags, text, cdata, comments in order\n this[\":@\"] = Object.create(null); //attributes map\n }\n add(key, val) {\n // this.child.push( {name : key, val: val, isCdata: isCdata });\n if (key === \"__proto__\") key = \"#__proto__\";\n this.child.push({ [key]: val });\n }\n addChild(node, startIndex) {\n if (node.tagname === \"__proto__\") node.tagname = \"#__proto__\";\n if (node[\":@\"] && Object.keys(node[\":@\"]).length > 0) {\n this.child.push({ [node.tagname]: node.child, [\":@\"]: node[\":@\"] });\n } else {\n this.child.push({ [node.tagname]: node.child });\n }\n // if requested, add the startIndex\n this.addStartIndex(startIndex);\n }\n\n addStartIndex(startIndex) {\n if (startIndex !== undefined) {\n // Note: for now we just overwrite the metadata. If we had more complex metadata,\n // we might need to do an object append here: metadata = { ...metadata, startIndex }\n this.child[this.child.length - 1][METADATA_SYMBOL] = { startIndex };\n }\n }\n\n addEndIndex(endIndex) {\n const lastChild = this.child[this.child.length - 1];\n // endIndex is write-once: when updateTag drops a node, the last child is a\n // previously completed sibling whose endIndex must not be overwritten\n if (lastChild !== undefined && lastChild[METADATA_SYMBOL] !== undefined\n && lastChild[METADATA_SYMBOL].endIndex === undefined) {\n lastChild[METADATA_SYMBOL].endIndex = endIndex;\n }\n }\n /** symbol used for metadata */\n static getMetaDataSymbol() {\n return METADATA_SYMBOL;\n }\n}\n","/**\n * xml-naming\n * Validates XML Name productions as defined in the XML 1.0 and 1.1 specifications.\n * Covers: Name, NCName, QName, NMToken, NMTokens\n *\n * XML 1.0 spec: https://www.w3.org/TR/xml/#NT-Name\n * XML 1.1 spec: https://www.w3.org/TR/xml11/#NT-NameStartChar\n * XML NS spec: https://www.w3.org/TR/xml-names/#NT-NCName\n */\n\n// ---------------------------------------------------------------------------\n// Character class strings — XML 1.0\n//\n// NameStartChar ::= \":\" | [A-Z] | \"_\" | [a-z]\n// | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF]\n// | [#x370-#x37D] | [#x37F-#x1FFF] <- split to exclude #x0487\n// | [#x200C-#x200D]\n// | [#x2070-#x218F] | [#x2C00-#x2FEF]\n// | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD]\n//\n// NameChar ::= NameStartChar | \"-\" | \".\" | [0-9]\n// | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]\n//\n// Note: \\u0487 (Combining Cyrillic Millions Sign) was added in Unicode 4.0,\n// after XML 1.0 was defined against Unicode 2.0. It falls inside the range\n// \\u037F-\\u1FFF but must be excluded. We split that range into\n// \\u037F-\\u0486 and \\u0488-\\u1FFF to exclude it explicitly.\n// ---------------------------------------------------------------------------\n\nconst nameStartChar10 =\n ':A-Za-z_' +\n '\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF' +\n '\\u0370-\\u037D' +\n '\\u037F-\\u0486\\u0488-\\u1FFF' + // split to exclude \\u0487\n '\\u200C-\\u200D' +\n '\\u2070-\\u218F' +\n '\\u2C00-\\u2FEF' +\n '\\u3001-\\uD7FF' +\n '\\uF900-\\uFDCF' +\n '\\uFDF0-\\uFFFD';\n\nconst nameChar10 =\n nameStartChar10 +\n '\\\\-\\\\.\\\\d' +\n '\\u00B7' +\n '\\u0300-\\u036F' +\n '\\u203F-\\u2040';\n\n// ---------------------------------------------------------------------------\n// Character class strings — XML 1.1\n//\n// Differences from XML 1.0:\n//\n// NameStartChar:\n// 1.0 has split ranges: \\u00C0-\\u00D6, \\u00D8-\\u00F6, \\u00F8-\\u02FF\n// 1.1 merges them into: \\u00C0-\\u02FF\n// (\\u00D7 x and \\u00F7 / are division symbols, excluded in both versions)\n//\n// 1.0 tops out at \\uFFFD (BMP only)\n// 1.1 adds \\u{10000}-\\u{EFFFF} (supplementary planes)\n// These require the /u flag on the RegExp — see buildRegexes below.\n//\n// NameChar:\n// 1.1 adds \\u0487 (Combining Cyrillic Millions Sign, added in Unicode 4.0)\n// ---------------------------------------------------------------------------\n\nconst nameStartChar11 =\n ':A-Za-z_' +\n '\\u00C0-\\u02FF' + // merged — 1.0 had three split ranges here\n '\\u0370-\\u037D' +\n '\\u037F-\\u0486\\u0488-\\u1FFF' + // split to exclude \\u0487 (combining mark, never a NameStartChar)\n '\\u200C-\\u200D' +\n '\\u2070-\\u218F' +\n '\\u2C00-\\u2FEF' +\n '\\u3001-\\uD7FF' +\n '\\uF900-\\uFDCF' +\n '\\uFDF0-\\uFFFD' +\n '\\u{10000}-\\u{EFFFF}'; // supplementary planes — REQUIRES /u flag on RegExp\n\nconst nameChar11 =\n nameStartChar11 +\n '\\\\-\\\\.\\\\d' +\n '\\u00B7' +\n '\\u0300-\\u036F' +\n '\\u0487' + // Combining Cyrillic Millions Sign — valid in 1.1, not 1.0\n '\\u203F-\\u2040';\n\n// ---------------------------------------------------------------------------\n// Regex builders\n//\n// XML 1.0 regexes: no flags — BMP only, standard JS regex behaviour.\n// XML 1.1 regexes: /u flag — required for \\u{10000}-\\u{EFFFF} to match actual\n// supplementary code points rather than lone surrogates (which are illegal XML).\n// ---------------------------------------------------------------------------\n\nconst buildRegexes = (startChar, char, flags = '') => {\n const ncStart = startChar.replace(':', '');\n const ncChar = char.replace(':', '');\n const ncNamePat = `[${ncStart}][${ncChar}]*`;\n\n return {\n name: new RegExp(`^[${startChar}][${char}]*$`, flags),\n ncName: new RegExp(`^${ncNamePat}$`, flags),\n qName: new RegExp(`^${ncNamePat}(?::${ncNamePat})?$`, flags),\n nmToken: new RegExp(`^[${char}]+$`, flags),\n nmTokens: new RegExp(`^[${char}]+(?:\\\\s+[${char}]+)*$`, flags),\n };\n};\n\nconst regexes10 = buildRegexes(nameStartChar10, nameChar10); // no /u — BMP only\nconst regexes11 = buildRegexes(nameStartChar11, nameChar11, 'u'); // /u — enables \\u{10000}-\\u{EFFFF}\n\n// ---------------------------------------------------------------------------\n// ASCII-only fast path (opt-in, off by default)\n//\n// The XML 1.0 vs 1.1 NameStartChar/NameChar productions differ *only* in\n// their non-ASCII ranges (merged vs split Latin-1 ranges, \\u0487, and\n// supplementary planes). Restricted to ASCII, both versions collapse to the\n// same character classes, so a single regex pair covers both xmlVersion\n// values — no /u flag needed.\n//\n// Rationale: unicode-aware regexes (the /u flag, required for XML 1.1's\n// supplementary-plane range) are measurably slower in V8 than plain\n// non-unicode regexes on the same input, even when the input is pure ASCII.\n// For the common case — HTML/SVG ids, XML tags — names are ASCII, so callers\n// who know this can opt in to skip the unicode-aware matching path entirely.\n// This is a real but *conditional* win: mainly for XML 1.1 input (avoids /u),\n// or at scale where the larger unicode character classes add engine\n// overhead. It also changes behaviour (rejects legitimate non-ASCII XML\n// 1.0/1.1 names), so it must never be silently enabled — hence off by\n// default.\n// ---------------------------------------------------------------------------\n\nconst nameStartCharAscii = ':A-Za-z_';\nconst nameCharAscii = nameStartCharAscii + '\\\\-\\\\.\\\\d';\n\nconst regexesAscii = buildRegexes(nameStartCharAscii, nameCharAscii); // no /u — ASCII only\n\nconst getRegexes = (xmlVersion = '1.0', asciiOnly = false) => {\n if (asciiOnly) return regexesAscii;\n return xmlVersion === '1.1' ? regexes11 : regexes10;\n};\n\n// ---------------------------------------------------------------------------\n// Boolean validators\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if the string is a valid XML Name.\n * Colons are allowed anywhere (Name production).\n * Used for: DOCTYPE entity names, notation names, DTD element declarations.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const name = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).name.test(str);\n\n/**\n * Returns true if the string is a valid NCName (Non-Colonized Name).\n * Colons are not permitted.\n * Used for: namespace prefixes, local names, SVG id attributes.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const ncName = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).ncName.test(str);\n\n/**\n * Returns true if the string is a valid QName (Qualified Name).\n * Allows exactly one colon as a prefix separator: prefix:localName.\n * Used for: element and attribute names in namespace-aware XML/SVG.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const qName = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).qName.test(str);\n\n/**\n * Returns true if the string is a valid NMToken.\n * Like Name but no restriction on the first character.\n * Used for: DTD NMTOKEN attribute values.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const nmToken = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).nmToken.test(str);\n\n/**\n * Returns true if the string is a valid NMTokens value.\n * A whitespace-separated list of NMToken values.\n * Used for: DTD NMTOKENS attribute values.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const nmTokens = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).nmTokens.test(str);\n\n// ---------------------------------------------------------------------------\n// Memoized validator factory\n//\n// Real documents reuse a small vocabulary of tag/attribute names across many\n// siblings (e.g. `id`, `class`, `href` repeated across hundreds of elements).\n// The plain boolean validators above re-run the regex on every call\n// regardless of repeats. `createValidator` returns a closure with a private\n// string -> boolean cache, so repeated names after the first become O(1)\n// lookups instead of regex tests.\n//\n// - opts (xmlVersion, asciiOnly) are fixed at creation time, so the regex is\n// resolved once, not on every call.\n// - The cache is private to the returned closure — no shared/global state,\n// no cross-caller pollution.\n// - `maxCacheSize` bounds memory: once the cache reaches this many entries,\n// it stops accepting new ones (existing entries keep serving hits; new\n// misses just fall through to the regex, uncached). This avoids unbounded\n// growth against adversarial/high-cardinality input (e.g. validating\n// attacker-supplied names with no repeats) without the cost/complexity of\n// a full LRU, and without the perf cliff of reset-and-refill thrashing.\n// - Call `.reset()` on the returned function to clear the cache manually\n// (e.g. between unrelated parse calls).\n// ---------------------------------------------------------------------------\n\nconst PRODUCTIONS = ['name', 'ncName', 'qName', 'nmToken', 'nmTokens'];\n\n/**\n * Returns a memoized boolean validator function for a single production,\n * with opts fixed at creation time.\n *\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean, maxCacheSize?: number }} [opts]\n * maxCacheSize: max number of distinct strings to cache (default 2048).\n * Once reached, new strings are validated but not cached; existing cached\n * entries keep being served.\n * @returns {((str: string) => boolean) & { reset: () => void }}\n */\nexport const createValidator = (production, { xmlVersion = '1.0', asciiOnly = false, maxCacheSize = 2048 } = {}) => {\n if (!PRODUCTIONS.includes(production)) {\n throw new TypeError(\n `Unknown production \"${production}\". Must be one of: ${PRODUCTIONS.join(', ')}`\n );\n }\n\n const regex = getRegexes(xmlVersion, asciiOnly)[production];\n let cache = new Map();\n\n const validator = (str) => {\n const cached = cache.get(str);\n if (cached !== undefined) return cached;\n\n const result = regex.test(str);\n if (cache.size < maxCacheSize) cache.set(str, result);\n return result;\n };\n\n validator.reset = () => { cache = new Map(); };\n\n return validator;\n};\n\n// ---------------------------------------------------------------------------\n// Diagnostic validator\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a string against a named production and returns a detailed result.\n *\n * @param {string} str\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * @returns {{ valid: boolean, production: string, input: string, reason?: string, position?: number }}\n */\nexport const validate = (str, production, { xmlVersion = '1.0', asciiOnly = false } = {}) => {\n if (!PRODUCTIONS.includes(production)) {\n throw new TypeError(\n `Unknown production \"${production}\". Must be one of: ${PRODUCTIONS.join(', ')}`\n );\n }\n\n const validators = { name, ncName, qName, nmToken, nmTokens };\n const isValid = validators[production](str, { xmlVersion, asciiOnly });\n\n if (isValid) return { valid: true, production, input: str };\n\n let reason = 'Does not match the production rules';\n let position;\n\n // Diagnostic fallback char checks must mirror the same character set the\n // boolean validator above used, or the reported reason/position could\n // contradict the `valid: false` result (e.g. flagging a char as illegal\n // that the unicode-aware check would have accepted).\n const startCharPattern = asciiOnly ? /^[:A-Za-z_]/ : /^[:A-Za-z_\\u00C0-\\uFFFD]/;\n const namePattern = asciiOnly ? /[\\w\\-\\\\.:]/ : /[\\w\\-\\\\.:\\u00B7\\u00C0-\\uFFFD]/;\n\n if (str.length === 0) {\n reason = 'Input is empty';\n } else if (production === 'ncName' && str.includes(':')) {\n position = str.indexOf(':');\n reason = 'Colon is not allowed in NCName';\n } else if (production === 'qName' && str.startsWith(':')) {\n reason = 'QName cannot start with a colon';\n position = 0;\n } else if (production === 'qName' && str.endsWith(':')) {\n reason = 'QName cannot end with a colon';\n position = str.length - 1;\n } else if (production === 'qName' && (str.match(/:/g) || []).length > 1) {\n reason = 'QName can have at most one colon';\n position = str.lastIndexOf(':');\n } else if (\n ['name', 'ncName', 'qName'].includes(production) &&\n !startCharPattern.test(str[0])\n ) {\n reason = `First character \"${str[0]}\" is not a valid NameStartChar`;\n position = 0;\n } else {\n for (let i = 0; i < str.length; i++) {\n if (!namePattern.test(str[i])) {\n reason = `Character \"${str[i]}\" at position ${i} is not a valid NameChar`;\n position = i;\n break;\n }\n }\n }\n\n return { valid: false, production, input: str, reason, position };\n};\n\n// ---------------------------------------------------------------------------\n// Batch validator\n// ---------------------------------------------------------------------------\n\n/**\n * Validates an array of strings against a named production.\n *\n * @param {string[]} strings\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * @returns {Array<{ valid: boolean, production: string, input: string, reason?: string, position?: number }>}\n */\nexport const validateAll = (strings, production, opts = {}) =>\n strings.map(str => validate(str, production, opts));\n\n// ---------------------------------------------------------------------------\n// Sanitizer\n// ---------------------------------------------------------------------------\n\n/**\n * Transforms an invalid string into the nearest valid XML name for the given production.\n *\n * @param {string} str\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ replacement?: string, asciiOnly?: boolean }} [opts]\n * asciiOnly: also replace any non-ASCII character, not just XML-illegal\n * ones (default false).\n * @returns {string}\n */\nexport const sanitize = (str, production = 'name', { replacement = '_', asciiOnly = false } = {}) => {\n if (!str) return replacement;\n\n let result = str;\n\n // Strip colons for NCName\n if (production === 'ncName') {\n result = result.replace(/:/g, '');\n }\n\n // Replace illegal characters\n const allowedCharPattern = asciiOnly ? /[^\\w\\-\\.:]/g : /[^\\w\\-\\.:\\u00B7\\u00C0-\\uFFFD]/g;\n result = result.replace(allowedCharPattern, replacement);\n\n // Fix invalid start character for Name / NCName / QName\n if (production !== 'nmToken' && production !== 'nmTokens') {\n if (/^[\\-\\.\\d]/.test(result)) {\n result = replacement + result;\n }\n }\n\n return result || replacement;\n};","import { qName as isName } from 'xml-naming';\n\nexport default class DocTypeReader {\n constructor(options, xmlVersion) {\n this.suppressValidationErr = !options;\n this.options = options;\n this.xmlVersion = xmlVersion || 1.0;\n }\n\n setXmlVersion(xmlVersion = 1.0) {\n this.xmlVersion = xmlVersion;\n }\n readDocType(xmlData, i) {\n const entities = Object.create(null);\n let entityCount = 0;\n\n if (xmlData[i + 3] === 'O' &&\n xmlData[i + 4] === 'C' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'Y' &&\n xmlData[i + 7] === 'P' &&\n xmlData[i + 8] === 'E') {\n i = i + 9;\n let angleBracketsCount = 1;\n let hasBody = false, comment = false;\n let quoteChar = null; // tracks an open SYSTEM/PUBLIC literal before the '[' body\n let exp = \"\";\n for (; i < xmlData.length; i++) {\n // Inside a quoted external-identifier literal — XML allows '<'\n // and '>' as plain data here, so they must not be interpreted\n // as DOCTYPE structure until the matching quote closes.\n if (quoteChar !== null) {\n if (xmlData[i] === quoteChar) quoteChar = null;\n exp += xmlData[i];\n continue;\n }\n if (!hasBody && !comment && (xmlData[i] === '\"' || xmlData[i] === \"'\")) {\n quoteChar = xmlData[i];\n exp += xmlData[i];\n continue;\n }\n\n if (xmlData[i] === '<' && !comment) { //Determine the tag type\n if (hasBody && hasSeq(xmlData, \"!ENTITY\", i)) {\n i += 7;\n let entityName, val;\n [entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);\n if (val.indexOf(\"&\") === -1) { //Parameter entities are not supported\n if (this.options.enabled !== false &&\n this.options.maxEntityCount != null &&\n entityCount >= this.options.maxEntityCount) {\n throw new Error(\n `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`\n );\n }\n //const escaped = entityName.replace(/[.\\-+*:]/g, '\\\\.');\n //const escaped = entityName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n entities[entityName] = val;\n entityCount++;\n }\n }\n else if (hasBody && hasSeq(xmlData, \"!ELEMENT\", i)) {\n i += 8;//Not supported\n const { index } = this.readElementExp(xmlData, i + 1);\n i = index;\n } else if (hasBody && hasSeq(xmlData, \"!ATTLIST\", i)) {\n i += 8;//Not supported\n // const {index} = this.readAttlistExp(xmlData,i+1);\n // i = index;\n } else if (hasBody && hasSeq(xmlData, \"!NOTATION\", i)) {\n i += 9;//Not supported\n const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);\n i = index;\n } else if (hasSeq(xmlData, \"!--\", i)) comment = true;\n else throw new Error(`Invalid DOCTYPE`);\n\n angleBracketsCount++;\n exp = \"\";\n } else if (xmlData[i] === '>') { //Read tag content\n if (comment) {\n if (xmlData[i - 1] === \"-\" && xmlData[i - 2] === \"-\") {\n comment = false;\n angleBracketsCount--;\n }\n } else {\n angleBracketsCount--;\n }\n if (angleBracketsCount === 0) {\n break;\n }\n } else if (xmlData[i] === '[') {\n hasBody = true;\n } else {\n exp += xmlData[i];\n }\n }\n if (quoteChar !== null || angleBracketsCount !== 0) {\n throw new Error(`Unclosed DOCTYPE`);\n }\n } else {\n throw new Error(`Invalid Tag instead of DOCTYPE`);\n }\n return { entities, i };\n }\n readEntityExp(xmlData, i) {\n //External entities are not supported\n // \n\n //Parameter entities are not supported\n // \n\n //Internal entities are supported\n // \n\n // Skip leading whitespace after this.options.maxEntitySize) {\n throw new Error(\n `Entity \"${entityName}\" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`\n );\n }\n\n i--;\n return [entityName, entityValue, i];\n }\n\n readNotationExp(xmlData, i) {\n // Skip leading whitespace after \n // \n // \n // \n // \n\n // Skip leading whitespace after {\n while (index < data.length && /\\s/.test(data[index])) {\n index++;\n }\n return index;\n};\n\n\n\nfunction hasSeq(data, seq, i) {\n for (let j = 0; j < seq.length; j++) {\n if (seq[j] !== data[i + j + 1]) return false;\n }\n return true;\n}\n\nfunction validateEntityName(name, xmlVersion) {\n if (isName(name, { xmlVersion: xmlVersion }))\n return name;\n else\n throw new Error(`Invalid entity name ${name}`);\n}","/**\n * Flat lookup table: maps Unicode code point → ASCII digit (0-9).\n * Only decimal digit characters (Unicode category Nd) are included.\n *\n * Strategy: Int32Array of size (maxCodePoint - minCodePoint + 1).\n * Value 0xFF means \"not a digit\". Value 0-9 is the ASCII digit value.\n * This gives O(1) lookup with no branching, no bisect, no loop.\n *\n * Memory: range is 0x0660 to 0x1FBF0 → ~129,936 entries × 1 byte = ~127 KB.\n * Acceptable for a one-time init; lookup is a single array index.\n */\n\n// All known Unicode Nd (decimal digit) script zero code points.\n// Each script has exactly 10 consecutive digits: zero+0 .. zero+9.\nconst SCRIPT_ZEROS = [\n // Basic Latin (ASCII) — included for completeness / pass-through\n 0x0030, // 0-9\n\n // Arabic scripts\n 0x0660, // Arabic-Indic ٠١٢٣٤٥٦٧٨٩\n 0x06F0, // Extended Arabic-Indic (Urdu/Persian/Sindhi) ۰۱۲۳\n\n // Indic scripts\n 0x0966, // Devanagari ०१२३४५६७८९\n 0x09E6, // Bengali ০১২৩৪৫৬৭৮৯\n 0x0A66, // Gurmukhi ੦੧੨੩੪੫੬੭੮੯\n 0x0AE6, // Gujarati ૦૧૨૩૪૫૬૭૮૯\n 0x0B66, // Odia ୦୧୨୩୪୫୬୭୮୯\n 0x0BE6, // Tamil ௦௧௨௩௪௫௬௭௮௯\n 0x0C66, // Telugu ౦౧౨౩౪౫౬౭౮౯\n 0x0CE6, // Kannada ೦೧೨೩೪೫೬೭೮೯\n 0x0D66, // Malayalam ൦൧൨൩൪൫൬൭൮൯\n 0x0DE6, // Sinhala Archaic ෦෧෨෩෪෫෬෭෮෯\n\n // Southeast Asian scripts\n 0x0E50, // Thai ๐๑๒๓๔๕๖๗๘๙\n 0x0ED0, // Lao ໐໑໒໓໔໕໖໗໘໙\n 0x0F20, // Tibetan ༠༡༢༣༤༥༦༧༨༩\n 0x1040, // Myanmar ၀၁၂၃၄၅၆၇၈၉\n 0x1090, // Myanmar Shan ႐႑႒႓႔႕႖႗႘႙\n 0x17E0, // Khmer ០១២៣៤៥៦៧៨៩\n 0x1810, // Mongolian ᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙\n 0x1946, // Limbu ᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏\n 0x19D0, // New Tai Lue ᧐᧑᧒᧓᧔᧕᧖᧗᧘᧙\n 0x1A80, // Tai Tham Hora ᪀᪁᪂᪃᪄᪅᪆᪇᪈᪉\n 0x1A90, // Tai Tham Tham ᪐᪑᪒᪓᪔᪕᪖᪗᪘᪙\n 0x1B50, // Balinese ᭐᭑᭒᭓᭔᭕᭖᭗᭘᭙\n 0x1BB0, // Sundanese ᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹\n 0x1C40, // Lepcha ᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉\n 0x1C50, // Ol Chiki ᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙\n\n // Fullwidth (CJK context)\n 0xFF10, // Fullwidth 0123456789\n\n // Mathematical digit variants (Unicode math block)\n 0x1D7CE, // Mathematical Bold\n 0x1D7D8, // Mathematical Double-Struck\n 0x1D7E2, // Mathematical Sans-Serif\n 0x1D7EC, // Mathematical Sans-Serif Bold\n 0x1D7F6, // Mathematical Monospace\n\n // Other scripts\n 0x104A0, // Osmanya 𐒠𐒡𐒢𐒣𐒤𐒥𐒦𐒧𐒨𐒩\n 0x10D30, // Hanifi Rohingya 𐴰𐴱𐴲𐴳𐴴𐴵𐴶𐴷𐴸𐴹\n 0x11066, // Brahmi 𑁦𑁧𑁨𑁩𑁪𑁫𑁬𑁭𑁮𑁯\n 0x110F0, // Sora Sompeng 𑃰𑃱𑃲𑃳𑃴𑃵𑃶𑃷𑃸𑃹\n 0x11136, // Chakma 𑄶𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑄿\n 0x111D0, // Sharada 𑇐𑇑𑇒𑇓𑇔𑇕𑇖𑇗𑇘𑇙\n 0x112F0, // Khudawadi 𑋰𑋱𑋲𑋳𑋴𑋵𑋶𑋷𑋸𑋹\n 0x11450, // Newa 𑑐𑑑𑑒𑑓𑑔𑑕𑑖𑑗𑑘𑑙\n 0x114D0, // Tirhuta 𑓐𑓑𑓒𑓓𑓔𑓕𑓖𑓗𑓘𑓙\n 0x11650, // Modi 𑙐𑙑𑙒𑙓𑙔𑙕𑙖𑙗𑙘𑙙\n 0x116C0, // Takri 𑛀𑛁𑛂𑛃𑛄𑛅𑛆𑛇𑛈𑛉\n 0x11730, // Ahom 𑜰𑜱𑜲𑜳𑜴𑜵𑜶𑜷𑜸𑜹\n 0x118E0, // Warang Citi 𑣠𑣡𑣢𑣣𑣤𑣥𑣦𑣧𑣨𑣩\n 0x11950, // Dives Akuru 𑥐𑥑𑥒𑥓𑥔𑥕𑥖𑥗𑥘𑥙\n 0x11BF0, // Khitan Small Script 𑯰𑯱𑯲𑯳𑯴𑯵𑯶𑯷𑯸𑯹\n 0x11C50, // Bhaiksuki 𑱐𑱑𑱒𑱓𑱔𑱕𑱖𑱗𑱘𑱙\n 0x11D50, // Masaram Gondi 𑵐𑵑𑵒𑵓𑵔𑵕𑵖𑵗𑵘𑵙\n 0x11DA0, // Gunjala Gondi 𑶠𑶡𑶢𑶣𑶤𑶥𑶦𑶧𑶨𑶩\n 0x11F50, // Kawi 𑽐𑽑𑽒𑽓𑽔𑽕𑽖𑽗𑽘𑽙\n 0x16A60, // Mro 𖩠𖩡𖩢𖩣𖩤𖩥𖩦𖩧𖩨𖩩\n 0x16AC0, // Tangsa 𖫀𖫁𖫂𖫃𖫄𖫅𖫆𖫇𖫈𖫉\n 0x16B50, // Pahawh Hmong 𖭐𖭑𖭒𖭓𖭔𖭕𖭖𖭗𖭘𖭙\n 0x1E140, // Nyiakeng Puachue Hmong 𞅀𞅁𞅂𞅃𞅄𞅅𞅆𞅇𞅈𞅉\n 0x1E2F0, // Wancho 𞋰𞋱𞋲𞋳𞋴𞋵𞋶𞋷𞋸𞋹\n 0x1E4F0, // Nag Mundari 𞓰𞓱𞓲𞓳𞓴𞓵𞓶𞓷𞓸𞓹\n 0x1E950, // Adlam 𞥐𞥑𞥒𞥓𞥔𞥕𞥖𞥗𞥘𞥙\n 0x1FBF0, // Segmented digit symbols 🯰🯱🯲🯳🯴🯵🯶🯷🯸🯹\n];\n\n// Build a sparse Map for scripts above 0xFFFF (surrogate-pair range).\n// These can't go into a flat Uint8Array indexed by code point efficiently.\nconst NOT_DIGIT = 0xFF;\nconst HIGH_MAP = new Map(); // codePoint → digit value (0-9)\n\nconst LOW_MAX = 0xFFFF;\nconst LOW_MIN = 0x0660; // first non-ASCII digit script\n\n// Flat Uint8Array covering 0x0660 .. 0xFFFF\nconst TABLE_OFFSET = LOW_MIN;\nconst TABLE_SIZE = LOW_MAX - LOW_MIN + 1;\nconst TABLE = new Uint8Array(TABLE_SIZE).fill(NOT_DIGIT);\n\nfor (const zero of SCRIPT_ZEROS) {\n for (let d = 0; d < 10; d++) {\n const cp = zero + d;\n if (cp <= LOW_MAX) {\n TABLE[cp - TABLE_OFFSET] = d;\n } else {\n HIGH_MAP.set(cp, d);\n }\n }\n}\n\nexport { TABLE, TABLE_OFFSET, HIGH_MAP, NOT_DIGIT };\n","'use strict';\n\nimport { TABLE, TABLE_OFFSET, HIGH_MAP, NOT_DIGIT } from './digitTable.js';\n\nconst CHAR_0 = 48; // '0'.charCodeAt(0)\nconst CHAR_9 = 57; // '9'.charCodeAt(0)\nconst CHAR_MINUS = 45; // '-'.charCodeAt(0)\n\n// Unicode minus/hyphen variants worth normalizing to ASCII '-' in numeric context:\n// U+2212 MINUS SIGN − (mathematically correct minus)\n// U+FF0D FULLWIDTH HYPHEN-MINUS - (Japanese fullwidth context)\n// U+FE63 SMALL HYPHEN-MINUS ﹣ (small form variant)\n//\n// NOT normalized (deliberate):\n// U+2013 EN DASH – (punctuation, not a numeric sign)\n// U+2014 EM DASH — (punctuation)\n// U+2010 HYPHEN ‐ (typographic hyphen)\n//\n// Rationale: only characters a human or locale formatter would plausibly use\n// as a numeric minus sign are normalized. Dashes used for punctuation are left\n// alone to avoid mangling non-numeric strings.\nconst MINUS_SET = new Set([0x2212, 0xFF0D, 0xFE63]);\n\n/**\n * Normalize all Unicode decimal digit characters in a string to ASCII (0-9),\n * and normalize Unicode minus variants to ASCII '-' (U+002D).\n *\n * Non-digit, non-minus characters are passed through unchanged.\n *\n * Performance design:\n * - Fast path: if the string has no convertible characters, return it unchanged\n * (zero allocation).\n * - BMP digits (0x0660..0xFFFF excl. surrogates): flat Uint8Array lookup (O(1)).\n * - Supplementary plane digits (> 0xFFFF, encoded as surrogate pairs): Map lookup.\n * - Minus variants: checked inline with a small fixed Set.\n *\n * @param {string} str\n * @returns {string}\n */\nfunction anynum(str) {\n if (typeof str !== 'string') return str;\n\n const len = str.length;\n if (len === 0) return str;\n\n // Scan for first character needing conversion.\n // If none found, return original string (zero allocation).\n let firstHit = -1;\n\n for (let i = 0; i < len; i++) {\n const cc = str.charCodeAt(i);\n\n // ASCII digit or ASCII minus — already normalized, skip fast\n if ((cc >= CHAR_0 && cc <= CHAR_9) || cc === CHAR_MINUS) continue;\n\n // Below first unicode digit script — check minus variants only\n if (cc < TABLE_OFFSET) {\n if (MINUS_SET.has(cc)) { firstHit = i; break; }\n continue;\n }\n\n // Surrogate pairs live in BMP range 0xD800-0xDFFF — check before TABLE\n if (cc >= 0xD800 && cc <= 0xDBFF) {\n if (i + 1 < len) {\n const low = str.charCodeAt(i + 1);\n if (low >= 0xDC00 && low <= 0xDFFF) {\n const cp = 0x10000 + ((cc - 0xD800) << 10) + (low - 0xDC00);\n if (HIGH_MAP.has(cp)) { firstHit = i; break; }\n }\n }\n continue;\n }\n\n // BMP non-surrogate: flat table lookup; also check minus variants in this range\n if (TABLE[cc - TABLE_OFFSET] !== NOT_DIGIT || MINUS_SET.has(cc)) {\n firstHit = i;\n break;\n }\n }\n\n // Nothing to replace — return original, zero allocation\n if (firstHit === -1) return str;\n\n // Build result: copy unchanged prefix, then convert from firstHit onward\n const chars = [];\n\n if (firstHit > 0) chars.push(str.slice(0, firstHit));\n\n for (let i = firstHit; i < len; i++) {\n const cc = str.charCodeAt(i);\n\n // ASCII digit or ASCII minus — pass through\n if ((cc >= CHAR_0 && cc <= CHAR_9) || cc === CHAR_MINUS) {\n chars.push(str[i]);\n continue;\n }\n\n // Below TABLE_OFFSET — check minus variants, else pass through\n if (cc < TABLE_OFFSET) {\n chars.push(MINUS_SET.has(cc) ? '-' : str[i]);\n continue;\n }\n\n // Surrogate pairs\n if (cc >= 0xD800 && cc <= 0xDBFF) {\n if (i + 1 < len) {\n const low = str.charCodeAt(i + 1);\n if (low >= 0xDC00 && low <= 0xDFFF) {\n const cp = 0x10000 + ((cc - 0xD800) << 10) + (low - 0xDC00);\n const d = HIGH_MAP.get(cp);\n if (d !== undefined) {\n chars.push(String.fromCharCode(d + 48));\n i++; // consume low surrogate\n continue;\n }\n }\n }\n chars.push(str[i]);\n continue;\n }\n\n // BMP non-surrogate: flat table lookup + minus variants\n if (MINUS_SET.has(cc)) {\n chars.push('-');\n continue;\n }\n const d = TABLE[cc - TABLE_OFFSET];\n chars.push(d !== NOT_DIGIT ? String.fromCharCode(d + 48) : str[i]);\n }\n\n return chars.join('');\n}\n\nexport { anynum };\nexport default anynum;","const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;\nconst binRegex = /^0b[01]+$/;\nconst octRegex = /^0o[0-7]+$/;\nconst numRegex = /^([\\-\\+])?(0*)([0-9]*(\\.[0-9]*)?)$/;\n\nimport anynum from \"anynum\";\n\nconst consider = {\n hex: true,\n binary: false,\n octal: false,\n leadingZeros: true,\n decimalPoint: \"\\.\",\n eNotation: true,\n //skipLike: /regex/,\n infinity: \"original\", // \"null\", \"infinity\" (Infinity type), \"string\" (\"Infinity\" (the string literal))\n unicode: false,\n};\n\nexport default function toNumber(str, options = {}) {\n options = Object.assign({}, consider, options);\n if (!str || typeof str !== \"string\") return str;\n\n let trimmedStr = str.trim();\n\n if (trimmedStr.length === 0) return str;\n else if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;\n else if (trimmedStr === \"0\") return 0;\n\n if (options.unicode) {\n trimmedStr = anynum(trimmedStr);\n if (trimmedStr === \"0\") return 0; // re-check after normalization\n }\n if (options.hex && hexRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 16);\n } else if (options.binary && binRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 2);\n } else if (options.octal && octRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 8);\n } else if (!isFinite(trimmedStr)) { //Infinity\n return handleInfinity(str, Number(trimmedStr), options);\n } else if (trimmedStr.includes('e') || trimmedStr.includes('E')) { //eNotation\n return resolveEnotation(str, trimmedStr, options);\n } else {\n //separate negative sign, leading zeros, and rest number\n const match = numRegex.exec(trimmedStr);\n // +00.123 => [ , '+', '00', '.123', ..\n if (match) {\n const sign = match[1] || \"\";\n const leadingZeros = match[2];\n let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros\n const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.\n str[leadingZeros.length + 1] === \".\"\n : str[leadingZeros.length] === \".\";\n\n //trim ending zeros for floating number\n if (!options.leadingZeros //leading zeros are not allowed\n && (leadingZeros.length > 1\n || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))) {\n // 00, 00.3, +03.24, 03, 03.24\n return str;\n }\n else {//no leading zeros or leading zeros are allowed\n const num = Number(trimmedStr);\n const parsedStr = String(num);\n\n if (num === 0) return num;\n if (parsedStr.search(/[eE]/) !== -1) { //given number is long and parsed to eNotation\n if (options.eNotation) return num;\n else return str;\n } else if (trimmedStr.indexOf(\".\") !== -1) { //floating number\n if (parsedStr === \"0\") return num; //0.0\n else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000\n else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;\n else return str;\n }\n\n let n = leadingZeros ? numTrimmedByZeros : trimmedStr;\n if (leadingZeros) {\n // -009 => -9\n return (n === parsedStr) || (sign + n === parsedStr) ? num : str\n } else {\n // +9\n return (n === parsedStr) || (n === sign + parsedStr) ? num : str\n }\n }\n } else { //non-numeric string\n return str;\n }\n }\n}\n\nconst eNotationRegx = /^([-+])?(0*)(\\d*(\\.\\d*)?[eE][-\\+]?\\d+)$/;\nfunction resolveEnotation(str, trimmedStr, options) {\n if (!options.eNotation) return str;\n const notation = trimmedStr.match(eNotationRegx);\n if (notation) {\n let sign = notation[1] || \"\";\n const eChar = notation[3].indexOf(\"e\") === -1 ? \"E\" : \"e\";\n const leadingZeros = notation[2];\n const eAdjacentToLeadingZeros = sign ? // 0E.\n str[leadingZeros.length + 1] === eChar\n : str[leadingZeros.length] === eChar;\n\n if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;\n else if (leadingZeros.length === 1\n && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {\n return Number(trimmedStr);\n } else if (leadingZeros.length > 0) {\n // Has leading zeros — only accept if leadingZeros option allows it\n if (options.leadingZeros && !eAdjacentToLeadingZeros) {\n trimmedStr = (notation[1] || \"\") + notation[3];\n return Number(trimmedStr);\n } else return str;\n } else {\n // No leading zeros — always valid e-notation, parse it\n return Number(trimmedStr);\n }\n } else {\n return str;\n }\n}\n\n/**\n * \n * @param {string} numStr without leading zeros\n * @returns \n */\nfunction trimZeros(numStr) {\n if (numStr && numStr.indexOf(\".\") !== -1) {//float\n //remove ending zeros without the O(n^2) backtracking that /0+$/ hits\n //when the string doesn't end in 0 but has a long internal zero-run\n let end = numStr.length;\n while (end > 0 && numStr.charCodeAt(end - 1) === 48 /* '0' */) end--;\n numStr = numStr.slice(0, end);\n if (numStr === \".\") numStr = \"0\";\n else if (numStr[0] === \".\") numStr = \"0\" + numStr;\n else if (numStr[numStr.length - 1] === \".\") numStr = numStr.substring(0, numStr.length - 1);\n return numStr;\n }\n return numStr;\n}\n\nfunction parse_int(numStr, base) {\n const str = numStr.trim();\n if (base === 2 || base === 8) numStr = str.substring(2);\n\n if (parseInt) return parseInt(numStr, base);\n else if (Number.parseInt) return Number.parseInt(numStr, base);\n else if (window && window.parseInt) return window.parseInt(numStr, base);\n else throw new Error(\"parseInt, Number.parseInt, window.parseInt are not supported\");\n}\n\n/**\n * Handle infinite values based on user option\n * @param {string} str - original input string\n * @param {number} num - parsed number (Infinity or -Infinity)\n * @param {object} options - user options\n * @returns {string|number|null} based on infinity option\n */\nfunction handleInfinity(str, num, options) {\n const isPositive = num === Infinity;\n\n switch (options.infinity.toLowerCase()) {\n case \"null\":\n return null;\n case \"infinity\":\n return num; // Return Infinity or -Infinity\n case \"string\":\n return isPositive ? \"Infinity\" : \"-Infinity\";\n case \"original\":\n default:\n return str; // Return original string like \"1e1000\"\n }\n}","import ExpressionSet from \"./ExpressionSet.js\";\n\n/**\n * MatcherView - A lightweight read-only view over a Matcher's internal state.\n *\n * Created once by Matcher and reused across all callbacks. Holds a direct\n * reference to the parent Matcher so it always reflects current parser state\n * with zero copying or freezing overhead.\n *\n * Users receive this via {@link Matcher#readOnly} or directly from parser\n * callbacks. It exposes all query and matching methods but has no mutation\n * methods — misuse is caught at the TypeScript level rather than at runtime.\n *\n * @example\n * const matcher = new Matcher();\n * const view = matcher.readOnly();\n *\n * matcher.push(\"root\", {});\n * view.getCurrentTag(); // \"root\"\n * view.getDepth(); // 1\n */\nexport class MatcherView {\n /**\n * @param {Matcher} matcher - The parent Matcher instance to read from.\n */\n constructor(matcher) {\n this._matcher = matcher;\n }\n\n /**\n * Get the path separator used by the parent matcher.\n * @returns {string}\n */\n get separator() {\n return this._matcher.separator;\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return undefined;\n return path[path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return false;\n const current = path[path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get the value of a \"kept\" attribute from the nearest ancestor (or\n * current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {*}\n */\n getAnyParentAttr(attrName) {\n return this._matcher.getAnyParentAttr(attrName);\n }\n\n /**\n * Check whether any ancestor (or the current node) kept the given\n * attribute via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAnyParentAttr(attrName) {\n return this._matcher.hasAnyParentAttr(attrName);\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this._matcher.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n return this._matcher.toString(separator, includeNamespace);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this._matcher.path.map(n => n.tag);\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n return this._matcher.matches(expression);\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this._matcher);\n }\n}\n\n/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions.\n *\n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n *\n * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to\n * user callbacks — it always reflects current state with no Proxy overhead.\n *\n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n *\n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher.\n * @param {Object} [options={}]\n * @param {string} [options.separator='.'] - Default path separator\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag, values, position, counter, namespace? }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n this._pathStringCache = null;\n this._view = new MatcherView(this);\n\n // Kept-attribute stack: only populated when push() is called with options.keep.\n this._keptAttrs = [];\n }\n\n /**\n * Push a new tag onto the path.\n * @param {string} tagName\n * @param {Object|null} [attrValues=null]\n * @param {string|null} [namespace=null]\n * @param {Object|null} [options=null]\n * @param {string[]} [options.keep] - Names of attributes (from attrValues)\n */\n push(tagName, attrValues = null, namespace = null, options = null) {\n this._pathStringCache = null;\n\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n this.path[this.path.length - 1].values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n let level = this.siblingStacks[currentLevel];\n if (!level) {\n // `counts` tells same-name siblings apart (the \"counter\" — nth \n // among other s). `total` is every child seen at this level so\n // far, kept as a running number instead of re-added from `counts` on\n // every push — a parent with many differently-named children would\n // otherwise cost more per child the more distinct names it has.\n level = { counts: new Map(), total: 0 };\n this.siblingStacks[currentLevel] = level;\n }\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = level.counts.get(siblingKey) || 0;\n\n // Position = total children at this level seen before this one.\n const position = level.total;\n\n // Update sibling count for this tag, and the level's running total.\n level.counts.set(siblingKey, counter + 1);\n level.total++;\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n\n // Depth of the node we just pushed (1-based, matches this.path.length)\n const depth = this.path.length;\n\n // Copy only the requested attributes into the kept-attrs stack. This is\n // the one part of push() whose cost scales with input (O(keep.length))\n // rather than being O(1) — by design, since the caller is explicitly\n // opting in for specific attribute names. No options/keep => zero added\n // cost beyond the two property reads below.\n const keep = options !== null ? options.keep : null;\n if (keep !== null && keep !== undefined && keep.length > 0 && attrValues) {\n for (let i = 0; i < keep.length; i++) {\n const name = keep[i];\n if (attrValues[name] !== undefined) {\n this._keptAttrs.push({ depth, name, value: attrValues[name] });\n }\n }\n }\n }\n\n /**\n * Pop the last tag from the path.\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) return undefined;\n this._pathStringCache = null;\n\n const node = this.path.pop();\n\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n // Drop any kept attributes that belonged to the popped node (or deeper).\n // _keptAttrs is depth-ordered (push only ever appends increasing depths),\n // so this is a backward scan that stops at the first surviving entry —\n // typically O(1) since kept attrs are rare by design.\n const poppedDepth = this.path.length + 1;\n while (\n this._keptAttrs.length > 0 &&\n this._keptAttrs[this._keptAttrs.length - 1].depth >= poppedDepth\n ) {\n this._keptAttrs.pop();\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values.\n * Useful when attributes are parsed after push.\n * @param {Object} attrValues\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n return this.path[this.path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get the value of a \"kept\" attribute from the nearest ancestor (or\n * current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.\n * Unlike getAttrValue(), this works regardless of how deep the path has\n * gone since the attribute was pushed — but only for attribute names that\n * were explicitly marked with `keep` at push time. Cost is proportional to\n * the number of currently-kept attributes (typically 0-3), not path depth.\n * @param {string} attrName\n * @returns {*} the value, or undefined if no ancestor kept this attribute\n */\n getAnyParentAttr(attrName) {\n const kept = this._keptAttrs;\n for (let i = kept.length - 1; i >= 0; i--) {\n if (kept[i].name === attrName) return kept[i].value;\n }\n return undefined;\n }\n\n /**\n * Check whether any ancestor (or the current node) kept the given\n * attribute via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAnyParentAttr(attrName) {\n const kept = this._keptAttrs;\n for (let i = kept.length - 1; i >= 0; i--) {\n if (kept[i].name === attrName) return true;\n }\n return false;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n const isDefault = (sep === this.separator && includeNamespace === true);\n\n if (isDefault) {\n if (this._pathStringCache !== null) {\n return this._pathStringCache;\n }\n const result = this.path.map(n =>\n (n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n this._pathStringCache = result;\n return result;\n }\n\n return this.path.map(n =>\n (includeNamespace && n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty.\n */\n reset() {\n this._pathStringCache = null;\n this.path = [];\n this.siblingStacks = [];\n this._keptAttrs = [];\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n return this._matchSimple(segments);\n }\n\n /**\n * @private\n */\n _matchSimple(segments) {\n if (this.path.length !== segments.length) {\n return false;\n }\n\n for (let i = 0; i < segments.length; i++) {\n if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1;\n let segIdx = segments.length - 1;\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n segIdx--;\n\n if (segIdx < 0) {\n return true;\n }\n\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n return segIdx < 0;\n }\n\n /**\n * @private\n */\n _matchSegment(segment, node, isCurrentNode) {\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n if (segment.namespace !== undefined) {\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n if (segment.attrValue !== undefined) {\n if (String(node.values[segment.attrName]) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth' && counter !== segment.positionValue) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this);\n }\n\n /**\n * Create a snapshot of current state.\n * @returns {Object}\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(level => level ? { counts: new Map(level.counts), total: level.total } : level),\n keptAttrs: this._keptAttrs.map(entry => ({ ...entry }))\n };\n }\n\n /**\n * Restore state from snapshot.\n * @param {Object} snapshot\n */\n restore(snapshot) {\n this._pathStringCache = null;\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(level => level ? { counts: new Map(level.counts), total: level.total } : level);\n this._keptAttrs = (snapshot.keptAttrs || []).map(entry => ({ ...entry }));\n }\n\n /**\n * Return the read-only {@link MatcherView} for this matcher.\n *\n * The same instance is returned on every call — no allocation occurs.\n * It always reflects the current parser state and is safe to pass to\n * user callbacks without risk of accidental mutation.\n *\n * @returns {MatcherView}\n *\n * @example\n * const view = matcher.readOnly();\n * // pass view to callbacks — it stays in sync automatically\n * view.matches(expr); // ✓\n * view.getCurrentTag(); // ✓\n * // view.push(...) // ✗ method does not exist — caught by TypeScript\n */\n readOnly() {\n return this._view;\n }\n}\n","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}, data) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n this.data = data;\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","/**\n * ExpressionSet - An indexed collection of Expressions for efficient bulk matching\n *\n * Instead of iterating all expressions on every tag, ExpressionSet pre-indexes\n * them at insertion time by depth and terminal tag name. At match time, only\n * the relevant bucket is evaluated — typically reducing checks from O(E) to O(1)\n * lookup plus O(small bucket) matches.\n *\n * Three buckets are maintained:\n * - `_byDepthAndTag` — exact depth + exact tag name (tightest, used first)\n * - `_wildcardByDepth` — exact depth + wildcard tag `*` (depth-matched only)\n * - `_deepWildcards` — expressions containing `..` (cannot be depth-indexed)\n *\n * @example\n * import { Expression, ExpressionSet } from 'fast-xml-tagger';\n *\n * // Build once at config time\n * const stopNodes = new ExpressionSet();\n * stopNodes.add(new Expression('root.users.user'));\n * stopNodes.add(new Expression('root.config.setting'));\n * stopNodes.add(new Expression('..script'));\n *\n * // Query on every tag — hot path\n * if (stopNodes.matchesAny(matcher)) { ... }\n */\nexport default class ExpressionSet {\n constructor() {\n /** @type {Map} depth:tag → expressions */\n this._byDepthAndTag = new Map();\n\n /** @type {Map} depth → wildcard-tag expressions */\n this._wildcardByDepth = new Map();\n\n /** @type {import('./Expression.js').default[]} expressions containing deep wildcard (..) */\n this._deepWildcards = [];\n\n /** @type {Map} terminalTag → deep wildcard expressions */\n this._deepByTerminalTag = new Map();\n\n /** @type {Set} pattern strings already added — used for deduplication */\n this._patterns = new Set();\n\n /** @type {boolean} whether the set is sealed against further additions */\n this._sealed = false;\n }\n\n /**\n * Add an Expression to the set.\n * Duplicate patterns (same pattern string) are silently ignored.\n *\n * @param {import('./Expression.js').default} expression - A pre-constructed Expression instance\n * @returns {this} for chaining\n * @throws {TypeError} if called after seal()\n *\n * @example\n * set.add(new Expression('root.users.user'));\n * set.add(new Expression('..script'));\n */\n add(expression) {\n if (this._sealed) {\n throw new TypeError(\n 'ExpressionSet is sealed. Create a new ExpressionSet to add more expressions.'\n );\n }\n\n // Deduplicate by pattern string\n if (this._patterns.has(expression.pattern)) return this;\n this._patterns.add(expression.pattern);\n\n if (expression.hasDeepWildcard()) {\n const lastSeg = expression.segments[expression.segments.length - 1];\n if (lastSeg && lastSeg.type !== 'deep-wildcard' && lastSeg.tag !== '*') {\n const tag = lastSeg.tag;\n if (!this._deepByTerminalTag.has(tag)) this._deepByTerminalTag.set(tag, []);\n this._deepByTerminalTag.get(tag).push(expression);\n } else {\n this._deepWildcards.push(expression);\n }\n return this;\n }\n\n const depth = expression.length;\n const lastSeg = expression.segments[expression.segments.length - 1];\n const tag = lastSeg?.tag;\n\n if (!tag || tag === '*') {\n // Can index by depth but not by tag\n if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []);\n this._wildcardByDepth.get(depth).push(expression);\n } else {\n // Tightest bucket: depth + tag\n const key = `${depth}:${tag}`;\n if (!this._byDepthAndTag.has(key)) this._byDepthAndTag.set(key, []);\n this._byDepthAndTag.get(key).push(expression);\n }\n\n return this;\n }\n\n /**\n * Add multiple expressions at once.\n *\n * @param {import('./Expression.js').default[]} expressions - Array of Expression instances\n * @returns {this} for chaining\n *\n * @example\n * set.addAll([\n * new Expression('root.users.user'),\n * new Expression('root.config.setting'),\n * ]);\n */\n addAll(expressions) {\n for (const expr of expressions) this.add(expr);\n return this;\n }\n\n /**\n * Check whether a pattern string is already present in the set.\n *\n * @param {import('./Expression.js').default} expression\n * @returns {boolean}\n */\n has(expression) {\n return this._patterns.has(expression.pattern);\n }\n\n /**\n * Number of expressions in the set.\n * @type {number}\n */\n get size() {\n return this._patterns.size;\n }\n\n /**\n * Seal the set against further modifications.\n * Useful to prevent accidental mutations after config is built.\n * Calling add() or addAll() on a sealed set throws a TypeError.\n *\n * @returns {this}\n */\n seal() {\n this._sealed = true;\n return this;\n }\n\n /**\n * Whether the set has been sealed.\n * @type {boolean}\n */\n get isSealed() {\n return this._sealed;\n }\n\n /**\n * Test whether the matcher's current path matches any expression in the set.\n *\n * Evaluation order (cheapest → most expensive):\n * 1. Exact depth + tag bucket — O(1) lookup, typically 0–2 expressions\n * 2. Depth-only wildcard bucket — O(1) lookup, rare\n * 3. Deep-wildcard list — always checked, but usually small\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {boolean} true if any expression matches the current path\n *\n * @example\n * if (stopNodes.matchesAny(matcher)) {\n * // handle stop node\n * }\n */\n matchesAny(matcher) {\n return this.findMatch(matcher) !== null;\n }\n /**\n * Find and return the first Expression that matches the matcher's current path.\n *\n * Uses the same evaluation order as matchesAny (cheapest → most expensive):\n * 1. Exact depth + tag bucket\n * 2. Depth-only wildcard bucket\n * 3. Deep-wildcard list\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {import('./Expression.js').default | null} the first matching Expression, or null\n *\n * @example\n * const expr = stopNodes.findMatch(matcher);\n * if (expr) {\n * // access expr.config, expr.pattern, etc.\n * }\n */\n findMatch(matcher) {\n const depth = matcher.getDepth();\n const tag = matcher.getCurrentTag();\n\n // 1. Tightest bucket — most expressions live here\n const exactKey = `${depth}:${tag}`;\n const exactBucket = this._byDepthAndTag.get(exactKey);\n if (exactBucket) {\n for (let i = 0; i < exactBucket.length; i++) {\n if (matcher.matches(exactBucket[i])) return exactBucket[i];\n }\n }\n\n // 2. Depth-matched wildcard-tag expressions\n const wildcardBucket = this._wildcardByDepth.get(depth);\n if (wildcardBucket) {\n for (let i = 0; i < wildcardBucket.length; i++) {\n if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i];\n }\n }\n\n // 3. Deep wildcards — indexed by terminal tag, then unindexed fallback\n const deepBucket = this._deepByTerminalTag.get(tag);\n if (deepBucket) {\n for (let i = 0; i < deepBucket.length; i++) {\n if (matcher.matches(deepBucket[i])) return deepBucket[i];\n }\n }\n for (let i = 0; i < this._deepWildcards.length; i++) {\n if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i];\n }\n\n return null;\n }\n}\n","// ---------------------------------------------------------------------------\n// Complete HTML5 named entity reference\n// Organized by logical categories for easy maintenance and selective importing\n// ---------------------------------------------------------------------------\n\n/**\n * Basic Latin & Special Characters\n * @type {Record}\n */\nexport const BASIC_LATIN = {\n amp: '&',\n AMP: '&',\n lt: '<',\n LT: '<',\n gt: '>',\n GT: '>',\n quot: '\"',\n QUOT: '\"',\n apos: \"'\",\n lsquo: '‘',\n rsquo: '’',\n ldquo: '“',\n rdquo: '”',\n lsquor: '‚',\n rsquor: '’',\n ldquor: '„',\n bdquo: '„',\n comma: ',',\n period: '.',\n colon: ':',\n semi: ';',\n excl: '!',\n quest: '?',\n num: '#',\n dollar: '$',\n percent: '%',\n ast: '*',\n commat: '@',\n lowbar: '_',\n verbar: '|',\n vert: '|',\n sol: '/',\n bsol: '\\\\',\n lbrace: '{',\n rbrace: '}',\n lbrack: '[',\n rbrack: ']',\n lpar: '(',\n rpar: ')',\n nbsp: '\\u00a0',\n iexcl: '¡',\n cent: '¢',\n pound: '£',\n curren: '¤',\n yen: '¥',\n brvbar: '¦',\n sect: '§',\n uml: '¨',\n copy: '©',\n COPY: '©',\n ordf: 'ª',\n laquo: '«',\n not: '¬',\n shy: '\\u00ad',\n reg: '®',\n REG: '®',\n macr: '¯',\n deg: '°',\n plusmn: '±',\n sup2: '²',\n sup3: '³',\n acute: '´',\n micro: 'µ',\n para: '¶',\n middot: '·',\n cedil: '¸',\n sup1: '¹',\n ordm: 'º',\n raquo: '»',\n frac14: '¼',\n frac12: '½',\n half: '½',\n frac34: '¾',\n iquest: '¿',\n times: '×',\n div: '÷',\n divide: '÷',\n};\n\n/**\n * Latin Extended & Accented Letters (A-Z)\n * @type {Record}\n */\nexport const LATIN_ACCENTS = {\n Agrave: 'À',\n agrave: 'à',\n Aacute: 'Á',\n aacute: 'á',\n Acirc: 'Â',\n acirc: 'â',\n Atilde: 'Ã',\n atilde: 'ã',\n Auml: 'Ä',\n auml: 'ä',\n Aring: 'Å',\n aring: 'å',\n AElig: 'Æ',\n aelig: 'æ',\n Ccedil: 'Ç',\n ccedil: 'ç',\n Egrave: 'È',\n egrave: 'è',\n Eacute: 'É',\n eacute: 'é',\n Ecirc: 'Ê',\n ecirc: 'ê',\n Euml: 'Ë',\n euml: 'ë',\n Igrave: 'Ì',\n igrave: 'ì',\n Iacute: 'Í',\n iacute: 'í',\n Icirc: 'Î',\n icirc: 'î',\n Iuml: 'Ï',\n iuml: 'ï',\n ETH: 'Ð',\n eth: 'ð',\n Ntilde: 'Ñ',\n ntilde: 'ñ',\n Ograve: 'Ò',\n ograve: 'ò',\n Oacute: 'Ó',\n oacute: 'ó',\n Ocirc: 'Ô',\n ocirc: 'ô',\n Otilde: 'Õ',\n otilde: 'õ',\n Ouml: 'Ö',\n ouml: 'ö',\n Oslash: 'Ø',\n oslash: 'ø',\n Ugrave: 'Ù',\n ugrave: 'ù',\n Uacute: 'Ú',\n uacute: 'ú',\n Ucirc: 'Û',\n ucirc: 'û',\n Uuml: 'Ü',\n uuml: 'ü',\n Yacute: 'Ý',\n yacute: 'ý',\n THORN: 'Þ',\n thorn: 'þ',\n szlig: 'ß',\n yuml: 'ÿ',\n Yuml: 'Ÿ',\n};\n\n/**\n * Latin Extended (Letters with diacritics)\n * @type {Record}\n */\nexport const LATIN_EXTENDED = {\n Amacr: 'Ā',\n amacr: 'ā',\n Abreve: 'Ă',\n abreve: 'ă',\n Aogon: 'Ą',\n aogon: 'ą',\n Cacute: 'Ć',\n cacute: 'ć',\n Ccirc: 'Ĉ',\n ccirc: 'ĉ',\n Cdot: 'Ċ',\n cdot: 'ċ',\n Ccaron: 'Č',\n ccaron: 'č',\n Dcaron: 'Ď',\n dcaron: 'ď',\n Dstrok: 'Đ',\n dstrok: 'đ',\n Emacr: 'Ē',\n emacr: 'ē',\n Ecaron: 'Ě',\n ecaron: 'ě',\n Edot: 'Ė',\n edot: 'ė',\n Eogon: 'Ę',\n eogon: 'ę',\n Gcirc: 'Ĝ',\n gcirc: 'ĝ',\n Gbreve: 'Ğ',\n gbreve: 'ğ',\n Gdot: 'Ġ',\n gdot: 'ġ',\n Gcedil: 'Ģ',\n Hcirc: 'Ĥ',\n hcirc: 'ĥ',\n Hstrok: 'Ħ',\n hstrok: 'ħ',\n Itilde: 'Ĩ',\n itilde: 'ĩ',\n Imacr: 'Ī',\n imacr: 'ī',\n Iogon: 'Į',\n iogon: 'į',\n Idot: 'İ',\n IJlig: 'IJ',\n ijlig: 'ij',\n Jcirc: 'Ĵ',\n jcirc: 'ĵ',\n Kcedil: 'Ķ',\n kcedil: 'ķ',\n kgreen: 'ĸ',\n Lacute: 'Ĺ',\n lacute: 'ĺ',\n Lcedil: 'Ļ',\n lcedil: 'ļ',\n Lcaron: 'Ľ',\n lcaron: 'ľ',\n Lmidot: 'Ŀ',\n lmidot: 'ŀ',\n Lstrok: 'Ł',\n lstrok: 'ł',\n Nacute: 'Ń',\n nacute: 'ń',\n Ncaron: 'Ň',\n ncaron: 'ň',\n Ncedil: 'Ņ',\n ncedil: 'ņ',\n ENG: 'Ŋ',\n eng: 'ŋ',\n Omacr: 'Ō',\n omacr: 'ō',\n Odblac: 'Ő',\n odblac: 'ő',\n OElig: 'Œ',\n oelig: 'œ',\n Racute: 'Ŕ',\n racute: 'ŕ',\n Rcaron: 'Ř',\n rcaron: 'ř',\n Rcedil: 'Ŗ',\n rcedil: 'ŗ',\n Sacute: 'Ś',\n sacute: 'ś',\n Scirc: 'Ŝ',\n scirc: 'ŝ',\n Scedil: 'Ş',\n scedil: 'ş',\n Scaron: 'Š',\n scaron: 'š',\n Tcedil: 'Ţ',\n tcedil: 'ţ',\n Tcaron: 'Ť',\n tcaron: 'ť',\n Tstrok: 'Ŧ',\n tstrok: 'ŧ',\n Utilde: 'Ũ',\n utilde: 'ũ',\n Umacr: 'Ū',\n umacr: 'ū',\n Ubreve: 'Ŭ',\n ubreve: 'ŭ',\n Uring: 'Ů',\n uring: 'ů',\n Udblac: 'Ű',\n udblac: 'ű',\n Uogon: 'Ų',\n uogon: 'ų',\n Wcirc: 'Ŵ',\n wcirc: 'ŵ',\n Ycirc: 'Ŷ',\n ycirc: 'ŷ',\n Zacute: 'Ź',\n zacute: 'ź',\n Zdot: 'Ż',\n zdot: 'ż',\n Zcaron: 'Ž',\n zcaron: 'ž',\n};\n\n/**\n * Greek Letters\n * @type {Record}\n */\nexport const GREEK = {\n Alpha: 'Α',\n alpha: 'α',\n Beta: 'Β',\n beta: 'β',\n Gamma: 'Γ',\n gamma: 'γ',\n Delta: 'Δ',\n delta: 'δ',\n Epsilon: 'Ε',\n epsilon: 'ε',\n epsiv: 'ϵ',\n varepsilon: 'ϵ',\n Zeta: 'Ζ',\n zeta: 'ζ',\n Eta: 'Η',\n eta: 'η',\n Theta: 'Θ',\n theta: 'θ',\n thetasym: 'ϑ',\n vartheta: 'ϑ',\n Iota: 'Ι',\n iota: 'ι',\n Kappa: 'Κ',\n kappa: 'κ',\n kappav: 'ϰ',\n varkappa: 'ϰ',\n Lambda: 'Λ',\n lambda: 'λ',\n Mu: 'Μ',\n mu: 'μ',\n Nu: 'Ν',\n nu: 'ν',\n Xi: 'Ξ',\n xi: 'ξ',\n Omicron: 'Ο',\n omicron: 'ο',\n Pi: 'Π',\n pi: 'π',\n piv: 'ϖ',\n varpi: 'ϖ',\n Rho: 'Ρ',\n rho: 'ρ',\n rhov: 'ϱ',\n varrho: 'ϱ',\n Sigma: 'Σ',\n sigma: 'σ',\n sigmaf: 'ς',\n sigmav: 'ς',\n varsigma: 'ς',\n Tau: 'Τ',\n tau: 'τ',\n Upsilon: 'Υ',\n upsilon: 'υ',\n upsi: 'υ',\n Upsi: 'ϒ',\n upsih: 'ϒ',\n Phi: 'Φ',\n phi: 'φ',\n phiv: 'ϕ',\n varphi: 'ϕ',\n Chi: 'Χ',\n chi: 'χ',\n Psi: 'Ψ',\n psi: 'ψ',\n Omega: 'Ω',\n omega: 'ω',\n ohm: 'Ω',\n Gammad: 'Ϝ',\n gammad: 'ϝ',\n digamma: 'ϝ',\n};\n\n/**\n * Cyrillic Letters\n * @type {Record}\n */\nexport const CYRILLIC = {\n Afr: '𝔄',\n afr: '𝔞',\n Acy: 'А',\n acy: 'а',\n Bcy: 'Б',\n bcy: 'б',\n Vcy: 'В',\n vcy: 'в',\n Gcy: 'Г',\n gcy: 'г',\n Dcy: 'Д',\n dcy: 'д',\n IEcy: 'Е',\n iecy: 'е',\n IOcy: 'Ё',\n iocy: 'ё',\n ZHcy: 'Ж',\n zhcy: 'ж',\n Zcy: 'З',\n zcy: 'з',\n Icy: 'И',\n icy: 'и',\n Jcy: 'Й',\n jcy: 'й',\n Kcy: 'К',\n kcy: 'к',\n Lcy: 'Л',\n lcy: 'л',\n Mcy: 'М',\n mcy: 'м',\n Ncy: 'Н',\n ncy: 'н',\n Ocy: 'О',\n ocy: 'о',\n Pcy: 'П',\n pcy: 'п',\n Rcy: 'Р',\n rcy: 'р',\n Scy: 'С',\n scy: 'с',\n Tcy: 'Т',\n tcy: 'т',\n Ucy: 'У',\n ucy: 'у',\n Fcy: 'Ф',\n fcy: 'ф',\n KHcy: 'Х',\n khcy: 'х',\n TScy: 'Ц',\n tscy: 'ц',\n CHcy: 'Ч',\n chcy: 'ч',\n SHcy: 'Ш',\n shcy: 'ш',\n SHCHcy: 'Щ',\n shchcy: 'щ',\n HARDcy: 'Ъ',\n hardcy: 'ъ',\n Ycy: 'Ы',\n ycy: 'ы',\n SOFTcy: 'Ь',\n softcy: 'ь',\n Ecy: 'Э',\n ecy: 'э',\n YUcy: 'Ю',\n yucy: 'ю',\n YAcy: 'Я',\n yacy: 'я',\n DJcy: 'Ђ',\n djcy: 'ђ',\n GJcy: 'Ѓ',\n gjcy: 'ѓ',\n Jukcy: 'Є',\n jukcy: 'є',\n DScy: 'Ѕ',\n dscy: 'ѕ',\n Iukcy: 'І',\n iukcy: 'і',\n YIcy: 'Ї',\n yicy: 'ї',\n Jsercy: 'Ј',\n jsercy: 'ј',\n LJcy: 'Љ',\n ljcy: 'љ',\n NJcy: 'Њ',\n njcy: 'њ',\n TSHcy: 'Ћ',\n tshcy: 'ћ',\n KJcy: 'Ќ',\n kjcy: 'ќ',\n Ubrcy: 'Ў',\n ubrcy: 'ў',\n DZcy: 'Џ',\n dzcy: 'џ',\n};\n\n/**\n * Mathematical Operators & Relations\n * @type {Record}\n */\nexport const MATH = {\n plus: '+',\n pm: '±',\n times: '×',\n div: '÷',\n divide: '÷',\n sdot: '⋅',\n star: '☆',\n starf: '★',\n bigstar: '★',\n lowast: '∗',\n ast: '*',\n midast: '*',\n compfn: '∘',\n smallcircle: '∘',\n bullet: '•',\n bull: '•',\n nbsp: '\\u00a0',\n hellip: '…',\n mldr: '…',\n prime: '′',\n Prime: '″',\n tprime: '‴',\n bprime: '‵',\n backprime: '‵',\n minus: '−',\n minusd: '∸',\n dotminus: '∸',\n plusdo: '∔',\n dotplus: '∔',\n plusmn: '±',\n minusplus: '∓',\n mnplus: '∓',\n mp: '∓',\n setminus: '∖',\n smallsetminus: '∖',\n Backslash: '∖',\n setmn: '∖',\n ssetmn: '∖',\n lowbar: '_',\n verbar: '|',\n vert: '|',\n VerticalLine: '|',\n colon: ':',\n Colon: '∷',\n Proportion: '∷',\n ratio: '∶',\n equals: '=',\n ne: '≠',\n nequiv: '≢',\n equiv: '≡',\n Congruent: '≡',\n sim: '∼',\n thicksim: '∼',\n thksim: '∼',\n sime: '≃',\n simeq: '≃',\n TildeEqual: '≃',\n asymp: '≈',\n approx: '≈',\n thickapprox: '≈',\n thkap: '≈',\n TildeTilde: '≈',\n ncong: '≇',\n cong: '≅',\n TildeFullEqual: '≅',\n asympeq: '≍',\n CupCap: '≍',\n bump: '≎',\n Bumpeq: '≎',\n HumpDownHump: '≎',\n bumpe: '≏',\n bumpeq: '≏',\n HumpEqual: '≏',\n le: '≤',\n LessEqual: '≤',\n ge: '≥',\n GreaterEqual: '≥',\n lesseqgtr: '⋚',\n lesseqqgtr: '⪋',\n greater: '>',\n less: '<',\n};\n\n/**\n * Mathematical Operators (Advanced)\n * @type {Record}\n */\nexport const MATH_ADVANCED = {\n alefsym: 'ℵ',\n aleph: 'ℵ',\n beth: 'ℶ',\n gimel: 'ℷ',\n daleth: 'ℸ',\n forall: '∀',\n ForAll: '∀',\n part: '∂',\n PartialD: '∂',\n exist: '∃',\n Exists: '∃',\n nexist: '∄',\n nexists: '∄',\n empty: '∅',\n emptyset: '∅',\n emptyv: '∅',\n varnothing: '∅',\n nabla: '∇',\n Del: '∇',\n isin: '∈',\n isinv: '∈',\n in: '∈',\n Element: '∈',\n notin: '∉',\n notinva: '∉',\n ni: '∋',\n niv: '∋',\n SuchThat: '∋',\n ReverseElement: '∋',\n notni: '∌',\n notniva: '∌',\n prod: '∏',\n Product: '∏',\n coprod: '∐',\n Coproduct: '∐',\n sum: '∑',\n Sum: '∑',\n minus: '−',\n mp: '∓',\n plusdo: '∔',\n dotplus: '∔',\n setminus: '∖',\n lowast: '∗',\n radic: '√',\n Sqrt: '√',\n prop: '∝',\n propto: '∝',\n Proportional: '∝',\n varpropto: '∝',\n infin: '∞',\n infintie: '⧝',\n ang: '∠',\n angle: '∠',\n angmsd: '∡',\n measuredangle: '∡',\n angsph: '∢',\n mid: '∣',\n VerticalBar: '∣',\n nmid: '∤',\n nsmid: '∤',\n npar: '∦',\n parallel: '∥',\n spar: '∥',\n nparallel: '∦',\n nspar: '∦',\n and: '∧',\n wedge: '∧',\n or: '∨',\n vee: '∨',\n cap: '∩',\n cup: '∪',\n int: '∫',\n Integral: '∫',\n conint: '∮',\n ContourIntegral: '∮',\n Conint: '∯',\n DoubleContourIntegral: '∯',\n Cconint: '∰',\n there4: '∴',\n therefore: '∴',\n Therefore: '∴',\n becaus: '∵',\n because: '∵',\n Because: '∵',\n ratio: '∶',\n Proportion: '∷',\n minusd: '∸',\n dotminus: '∸',\n mDDot: '∺',\n homtht: '∻',\n sim: '∼',\n bsimg: '∽',\n backsim: '∽',\n ac: '∾',\n mstpos: '∾',\n acd: '∿',\n VerticalTilde: '≀',\n wr: '≀',\n wreath: '≀',\n nsime: '≄',\n nsimeq: '≄',\n ncong: '≇',\n simne: '≆',\n ncongdot: '⩭̸',\n ngsim: '≵',\n nsim: '≁',\n napprox: '≉',\n nap: '≉',\n ngeq: '≱',\n nge: '≱',\n nleq: '≰',\n nle: '≰',\n ngtr: '≯',\n ngt: '≯',\n nless: '≮',\n nlt: '≮',\n nprec: '⊀',\n npr: '⊀',\n nsucc: '⊁',\n nsc: '⊁',\n};\n\n/**\n * Arrows\n * @type {Record}\n */\nexport const ARROWS = {\n larr: '←',\n leftarrow: '←',\n LeftArrow: '←',\n uarr: '↑',\n uparrow: '↑',\n UpArrow: '↑',\n rarr: '→',\n rightarrow: '→',\n RightArrow: '→',\n darr: '↓',\n downarrow: '↓',\n DownArrow: '↓',\n harr: '↔',\n leftrightarrow: '↔',\n LeftRightArrow: '↔',\n varr: '↕',\n updownarrow: '↕',\n UpDownArrow: '↕',\n nwarr: '↖',\n nwarrow: '↖',\n UpperLeftArrow: '↖',\n nearr: '↗',\n nearrow: '↗',\n UpperRightArrow: '↗',\n searr: '↘',\n searrow: '↘',\n LowerRightArrow: '↘',\n swarr: '↙',\n swarrow: '↙',\n LowerLeftArrow: '↙',\n lArr: '⇐',\n Leftarrow: '⇐',\n uArr: '⇑',\n Uparrow: '⇑',\n rArr: '⇒',\n Rightarrow: '⇒',\n dArr: '⇓',\n Downarrow: '⇓',\n hArr: '⇔',\n Leftrightarrow: '⇔',\n iff: '⇔',\n vArr: '⇕',\n Updownarrow: '⇕',\n lAarr: '⇚',\n Lleftarrow: '⇚',\n rAarr: '⇛',\n Rrightarrow: '⇛',\n lrarr: '⇆',\n leftrightarrows: '⇆',\n rlarr: '⇄',\n rightleftarrows: '⇄',\n lrhar: '⇋',\n leftrightharpoons: '⇋',\n ReverseEquilibrium: '⇋',\n rlhar: '⇌',\n rightleftharpoons: '⇌',\n Equilibrium: '⇌',\n udarr: '⇅',\n UpArrowDownArrow: '⇅',\n duarr: '⇵',\n DownArrowUpArrow: '⇵',\n llarr: '⇇',\n leftleftarrows: '⇇',\n rrarr: '⇉',\n rightrightarrows: '⇉',\n ddarr: '⇊',\n downdownarrows: '⇊',\n har: '↽',\n lhard: '↽',\n leftharpoondown: '↽',\n lharu: '↼',\n leftharpoonup: '↼',\n rhard: '⇁',\n rightharpoondown: '⇁',\n rharu: '⇀',\n rightharpoonup: '⇀',\n lsh: '↰',\n Lsh: '↰',\n rsh: '↱',\n Rsh: '↱',\n ldsh: '↲',\n rdsh: '↳',\n hookleftarrow: '↩',\n hookrightarrow: '↪',\n mapstoleft: '↤',\n mapstoup: '↥',\n map: '↦',\n mapsto: '↦',\n mapstodown: '↧',\n crarr: '↵',\n nleftarrow: '↚',\n nleftrightarrow: '↮',\n nrightarrow: '↛',\n nrarr: '↛',\n larrtl: '↢',\n rarrtl: '↣',\n leftarrowtail: '↢',\n rightarrowtail: '↣',\n twoheadleftarrow: '↞',\n twoheadrightarrow: '↠',\n Larr: '↞',\n Rarr: '↠',\n larrhk: '↩',\n rarrhk: '↪',\n larrlp: '↫',\n looparrowleft: '↫',\n rarrlp: '↬',\n looparrowright: '↬',\n harrw: '↭',\n leftrightsquigarrow: '↭',\n nrarrw: '↝̸',\n rarrw: '↝',\n rightsquigarrow: '↝',\n larrbfs: '⤟',\n rarrbfs: '⤠',\n nvHarr: '⤄',\n nvlArr: '⤂',\n nvrArr: '⤃',\n larrfs: '⤝',\n rarrfs: '⤞',\n Map: '⤅',\n larrsim: '⥳',\n rarrsim: '⥴',\n harrcir: '⥈',\n Uarrocir: '⥉',\n lurdshar: '⥊',\n ldrdhar: '⥧',\n ldrushar: '⥋',\n rdldhar: '⥩',\n lrhard: '⥭',\n uharr: '↾',\n uharl: '↿',\n dharr: '⇂',\n dharl: '⇃',\n Uarr: '↟',\n Darr: '↡',\n zigrarr: '⇝',\n nwArr: '⇖',\n neArr: '⇗',\n seArr: '⇘',\n swArr: '⇙',\n nharr: '↮',\n nhArr: '⇎',\n nlarr: '↚',\n nlArr: '⇍',\n nrArr: '⇏',\n larrb: '⇤',\n LeftArrowBar: '⇤',\n rarrb: '⇥',\n RightArrowBar: '⇥',\n};\n\n/**\n * Geometric Shapes\n * @type {Record}\n */\nexport const SHAPES = {\n square: '□',\n Square: '□',\n squ: '□',\n squf: '▪',\n squarf: '▪',\n blacksquar: '▪',\n blacksquare: '▪',\n FilledVerySmallSquare: '▪',\n blk34: '▓',\n blk12: '▒',\n blk14: '░',\n block: '█',\n srect: '▭',\n rect: '▭',\n sdot: '⋅',\n sdotb: '⊡',\n dotsquare: '⊡',\n triangle: '▵',\n tri: '▵',\n trine: '▵',\n utri: '▵',\n triangledown: '▿',\n dtri: '▿',\n tridown: '▿',\n triangleleft: '◃',\n ltri: '◃',\n triangleright: '▹',\n rtri: '▹',\n blacktriangle: '▴',\n utrif: '▴',\n blacktriangledown: '▾',\n dtrif: '▾',\n blacktriangleleft: '◂',\n ltrif: '◂',\n blacktriangleright: '▸',\n rtrif: '▸',\n loz: '◊',\n lozenge: '◊',\n blacklozenge: '⧫',\n lozf: '⧫',\n bigcirc: '◯',\n xcirc: '◯',\n circ: 'ˆ',\n Circle: '○',\n cir: '○',\n o: '○',\n bullet: '•',\n bull: '•',\n hellip: '…',\n mldr: '…',\n nldr: '‥',\n boxh: '─',\n HorizontalLine: '─',\n boxv: '│',\n boxdr: '┌',\n boxdl: '┐',\n boxur: '└',\n boxul: '┘',\n boxvr: '├',\n boxvl: '┤',\n boxhd: '┬',\n boxhu: '┴',\n boxvh: '┼',\n boxH: '═',\n boxV: '║',\n boxdR: '╒',\n boxDr: '╓',\n boxDR: '╔',\n boxDl: '╕',\n boxdL: '╖',\n boxDL: '╗',\n boxuR: '╘',\n boxUr: '╙',\n boxUR: '╚',\n boxUl: '╜',\n boxuL: '╛',\n boxUL: '╝',\n boxvR: '╞',\n boxVr: '╟',\n boxVR: '╠',\n boxVl: '╢',\n boxvL: '╡',\n boxVL: '╣',\n boxHd: '╤',\n boxhD: '╥',\n boxHD: '╦',\n boxHu: '╧',\n boxhU: '╨',\n boxHU: '╩',\n boxvH: '╪',\n boxVh: '╫',\n boxVH: '╬',\n};\n\n/**\n * Punctuation & Diacritics\n * @type {Record}\n */\nexport const PUNCTUATION = {\n excl: '!',\n iexcl: '¡',\n brvbar: '¦',\n sect: '§',\n uml: '¨',\n copy: '©',\n ordf: 'ª',\n laquo: '«',\n not: '¬',\n shy: '\\u00ad',\n reg: '®',\n macr: '¯',\n deg: '°',\n plusmn: '±',\n sup2: '²',\n sup3: '³',\n acute: '´',\n micro: 'µ',\n para: '¶',\n middot: '·',\n cedil: '¸',\n sup1: '¹',\n ordm: 'º',\n raquo: '»',\n frac14: '¼',\n frac12: '½',\n frac34: '¾',\n iquest: '¿',\n nbsp: '\\u00a0',\n comma: ',',\n period: '.',\n colon: ':',\n semi: ';',\n vert: '|',\n Verbar: '‖',\n verbar: '|',\n dblac: '˝',\n circ: 'ˆ',\n caron: 'ˇ',\n breve: '˘',\n dot: '˙',\n ring: '˚',\n ogon: '˛',\n tilde: '˜',\n DiacriticalGrave: '`',\n DiacriticalAcute: '´',\n DiacriticalTilde: '˜',\n DiacriticalDot: '˙',\n DiacriticalDoubleAcute: '˝',\n grave: '`',\n};\n\n/**\n * Currency Symbols\n * @type {Record}\n */\nexport const CURRENCY = {\n cent: '¢',\n pound: '£',\n curren: '¤',\n yen: '¥',\n euro: '€',\n dollar: '$',\n fnof: 'ƒ',\n inr: '₹',\n af: '؋',\n birr: 'ብር',\n peso: '₱',\n rub: '₽',\n won: '₩',\n yuan: '¥',\n cedil: '¸',\n};\n\n/**\n * Fractions\n * @type {Record}\n */\nexport const FRACTIONS = {\n frac12: '½',\n half: '½',\n frac13: '⅓',\n frac14: '¼',\n frac15: '⅕',\n frac16: '⅙',\n frac18: '⅛',\n frac23: '⅔',\n frac25: '⅖',\n frac34: '¾',\n frac35: '⅗',\n frac38: '⅜',\n frac45: '⅘',\n frac56: '⅚',\n frac58: '⅝',\n frac78: '⅞',\n frasl: '⁄',\n};\n\n/**\n * Miscellaneous Symbols\n * @type {Record}\n */\nexport const MISC_SYMBOLS = {\n trade: '™',\n TRADE: '™',\n telrec: '⌕',\n target: '⌖',\n ulcorn: '⌜',\n ulcorner: '⌜',\n urcorn: '⌝',\n urcorner: '⌝',\n dlcorn: '⌞',\n llcorner: '⌞',\n drcorn: '⌟',\n lrcorner: '⌟',\n intercal: '⊺',\n intcal: '⊺',\n oplus: '⊕',\n CirclePlus: '⊕',\n ominus: '⊖',\n CircleMinus: '⊖',\n otimes: '⊗',\n CircleTimes: '⊗',\n osol: '⊘',\n odot: '⊙',\n CircleDot: '⊙',\n oast: '⊛',\n circledast: '⊛',\n odash: '⊝',\n circleddash: '⊝',\n ocirc: '⊚',\n circledcirc: '⊚',\n boxplus: '⊞',\n plusb: '⊞',\n boxminus: '⊟',\n minusb: '⊟',\n boxtimes: '⊠',\n timesb: '⊠',\n boxdot: '⊡',\n sdotb: '⊡',\n veebar: '⊻',\n vee: '∨',\n barvee: '⊽',\n and: '∧',\n wedge: '∧',\n Cap: '⋒',\n Cup: '⋓',\n Fork: '⋔',\n pitchfork: '⋔',\n epar: '⋕',\n ltlarr: '⥶',\n nvap: '≍⃒',\n nvsim: '∼⃒',\n nvge: '≥⃒',\n nvle: '≤⃒',\n nvlt: '<⃒',\n nvgt: '>⃒',\n nvltrie: '⊴⃒',\n nvrtrie: '⊵⃒',\n Vdash: '⊩',\n dashv: '⊣',\n vDash: '⊨',\n Vvdash: '⊪',\n nvdash: '⊬',\n nvDash: '⊭',\n nVdash: '⊮',\n nVDash: '⊯',\n};\n\nexport const XML = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n quot: \"\\\"\"\n}\nexport const COMMON_HTML = {\n nbsp: '\\u00a0',\n copy: '\\u00a9',\n reg: '\\u00ae',\n trade: '\\u2122',\n mdash: '\\u2014',\n ndash: '\\u2013',\n hellip: '\\u2026',\n laquo: '\\u00ab',\n raquo: '\\u00bb',\n lsquo: '\\u2018',\n rsquo: '\\u2019',\n ldquo: '\\u201c',\n rdquo: '\\u201d',\n bull: '\\u2022',\n para: '\\u00b6',\n sect: '\\u00a7',\n deg: '\\u00b0',\n frac12: '\\u00bd',\n frac14: '\\u00bc',\n frac34: '\\u00be',\n}\n// ---------------------------------------------------------------------------\n// Note: NUMERIC_ENTITIES (&#NNN; / &#xHH;) are handled by the scanner directly\n// via String.fromCodePoint() without any map lookup.\n// ---------------------------------------------------------------------------","// ---------------------------------------------------------------------------\n// Built-in named entity map (name → replacement string)\n// No regex, no {regex,val} objects — just flat key/value pairs.\n// ---------------------------------------------------------------------------\n\nimport { XML as DEFAULT_XML_ENTITIES } from \"./entities.js\"\n\n// ---------------------------------------------------------------------------\n// Entity hook action constants\n// ---------------------------------------------------------------------------\n\n/**\n * Action constants for `onExternalEntity` and `onInputEntity` hooks.\n *\n * Use these instead of raw strings to avoid typos:\n *\n * @example\n * import EntityDecoder, { ENTITY_ACTION } from './EntityDecoder.js';\n * const dec = new EntityDecoder({\n * onInputEntity: (name, value) => ENTITY_ACTION.BLOCK,\n * });\n */\nexport const ENTITY_ACTION = Object.freeze({\n /** Resolve and expand the entity normally. */\n ALLOW: 'allow',\n /** Silently skip this entity — it will not be registered. */\n BLOCK: 'block',\n /** Throw an error, aborting entity registration entirely. */\n THROW: 'throw',\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst SPECIAL_CHARS = new Set('!?\\\\\\\\/[]$%{}^&*()<>|+');\n\n/**\n * Validate that an entity name contains no dangerous characters.\n * @param {string} name\n * @returns {string} the name, unchanged\n * @throws {Error} on invalid characters\n */\nfunction validateEntityName(name) {\n if (name[0] === '#') {\n throw new Error(`[EntityReplacer] Invalid character '#' in entity name: \"${name}\"`);\n }\n for (const ch of name) {\n if (SPECIAL_CHARS.has(ch)) {\n throw new Error(`[EntityReplacer] Invalid character '${ch}' in entity name: \"${name}\"`);\n }\n }\n return name;\n}\n\n/**\n * Merge one or more entity maps into a flat name→string map.\n * Accepts either:\n * - plain string values: { amp: '&' }\n * - legacy {regex,val} / {regx,val}: { lt: { regex: /.../, val: '<' } }\n *\n * Values containing '&' are skipped (recursive expansion risk).\n *\n * @param {...object} maps\n * @returns {Record}\n */\nfunction mergeEntityMaps(...maps) {\n const out = Object.create(null);\n for (const map of maps) {\n if (!map) continue;\n for (const key of Object.keys(map)) {\n const raw = map[key];\n if (typeof raw === 'string') {\n out[key] = raw;\n } else if (raw && typeof raw === 'object' && raw.val !== undefined) {\n // Legacy {regex,val} or {regx,val} — extract the string val only\n const val = raw.val;\n if (typeof val === 'string') {\n out[key] = val;\n }\n // function vals are not supported in the scanner — skip\n }\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// applyLimitsTo helpers\n// ---------------------------------------------------------------------------\n\nconst LIMIT_TIER_EXTERNAL = 'external'; // input/runtime + persistent external maps\nconst LIMIT_TIER_BASE = 'base'; // DEFAULT_XML_ENTITIES + namedEntities (system) maps\nconst LIMIT_TIER_ALL = 'all'; // every entity regardless of tier\n\n/**\n * Resolve `applyLimitsTo` option into a normalised Set of tier strings.\n * Accepted values: 'external' | 'base' | 'all' | string[]\n * Default: 'external' (only untrusted injected entities are counted).\n * @param {string|string[]|undefined} raw\n * @returns {Set}\n */\nfunction parseLimitTiers(raw) {\n if (!raw || raw === LIMIT_TIER_EXTERNAL) return new Set([LIMIT_TIER_EXTERNAL]);\n if (raw === LIMIT_TIER_ALL) return new Set([LIMIT_TIER_ALL]);\n if (raw === LIMIT_TIER_BASE) return new Set([LIMIT_TIER_BASE]);\n if (Array.isArray(raw)) return new Set(raw);\n return new Set([LIMIT_TIER_EXTERNAL]); // safe default for unrecognised values\n}\n\n// ---------------------------------------------------------------------------\n// NCR (Numeric Character Reference) classification\n// ---------------------------------------------------------------------------\n\n// Severity order — higher number = stricter action.\n// Used to enforce minimum action levels for specific codepoint ranges.\nconst NCR_LEVEL = Object.freeze({ allow: 0, leave: 1, remove: 2, throw: 3 });\n\n// XML 1.0 §2.2: allowed chars are #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n// Restricted C0: U+0001–U+001F excluding U+0009, U+000A, U+000D\nconst XML10_ALLOWED_C0 = new Set([0x09, 0x0A, 0x0D]);\n\n/**\n * Parse the `ncr` constructor option into flat, hot-path-friendly fields.\n * @param {object|undefined} ncr\n * @returns {{ xmlVersion: number, onLevel: number, nullLevel: number }}\n */\nfunction parseNCRConfig(ncr) {\n if (!ncr) {\n return { xmlVersion: 1.0, onLevel: NCR_LEVEL.allow, nullLevel: NCR_LEVEL.remove };\n }\n const xmlVersion = ncr.xmlVersion === 1.1 ? 1.1 : 1.0;\n const onLevel = NCR_LEVEL[ncr.onNCR] ?? NCR_LEVEL.allow;\n const nullLevel = NCR_LEVEL[ncr.nullNCR] ?? NCR_LEVEL.remove;\n // 'allow' is not meaningful for null — clamp to at least 'remove'\n const clampedNull = Math.max(nullLevel, NCR_LEVEL.remove);\n return { xmlVersion, onLevel, nullLevel: clampedNull };\n}\n\n// ---------------------------------------------------------------------------\n// EntityReplacer\n// ---------------------------------------------------------------------------\n\n/**\n * Single-pass, zero-regex entity replacer for XML/HTML content.\n *\n * Algorithm: scan the string once for '&', read to ';', resolve via map\n * or direct codepoint conversion, build output chunks, join once at the end.\n *\n * Entity lookup priority (highest → lowest):\n * 1. input / runtime (DOCTYPE entities for current document)\n * 2. persistent external (survive across documents)\n * 3. base named map (DEFAULT_XML_ENTITIES + user-supplied namedEntities)\n *\n * Both input and external resolve as the 'external' tier for limit purposes.\n * Base map entities resolve as the 'base' tier.\n *\n * Numeric / hex references (&#NNN; / &#xHH;) are resolved directly via\n * String.fromCodePoint() — no map needed. They count as 'base' tier.\n *\n * @example\n * const replacer = new EntityReplacer({ namedEntities: COMMON_HTML });\n * replacer.setExternalEntities({ brand: 'Acme' });\n *\n * const instance = replacer.reset();\n * instance.addInputEntities({ version: '1.0' });\n * instance.encode('&brand; v&version; <'); // 'Acme v1.0 <'\n */\nexport default class EntityDecoder {\n /**\n * @param {object} [options]\n * @param {object|null} [options.namedEntities] — extra named entities merged into base map\n * @param {object} [options.limit] — security limits\n * @param {number} [options.limit.maxTotalExpansions=0] — 0 = unlimited\n * @param {number} [options.limit.maxExpandedLength=0] — 0 = unlimited\n * @param {'external'|'base'|'all'|string[]} [options.limit.applyLimitsTo='external']\n * Which entity tiers count against the security limits:\n * - 'external' (default) — only input/runtime + persistent external entities\n * - 'base' — only DEFAULT_XML_ENTITIES + namedEntities\n * - 'all' — every entity regardless of tier\n * - string[] — explicit combination, e.g. ['external', 'base']\n * @param {((resolved: string, original: string) => string)|null} [options.postCheck=null]\n * @param {string[]} [options.remove=[]] — entity names (e.g. ['nbsp', '#13']) to delete (replace with empty string)\n * @param {string[]} [options.leave=[]] — entity names to keep as literal (unchanged in output)\n * @param {object} [options.ncr] — Numeric Character Reference controls\n * @param {1.0|1.1} [options.ncr.xmlVersion=1.0]\n * XML version governing which codepoint ranges are restricted:\n * - 1.0 — C0 controls U+0001–U+001F (except U+0009/000A/000D) are prohibited\n * - 1.1 — C0 controls are allowed when written as NCRs; C1 (U+007F–U+009F) decoded as-is\n * @param {'allow'|'leave'|'remove'|'throw'} [options.ncr.onNCR='allow']\n * Base action for numeric references. Severity order: allow < leave < remove < throw.\n * For codepoint ranges that carry a minimum level (surrogates → remove, XML 1.0 C0 → remove),\n * the effective action is max(onNCR, rangeMinimum).\n * @param {'remove'|'throw'} [options.ncr.nullNCR='remove']\n * Action for U+0000 (null). 'allow' and 'leave' are clamped to 'remove' since null is never safe.\n * @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} [options.onExternalEntity=null]\n * Hook called when an external entity is registered via `setExternalEntities()` or\n * `addExternalEntity()`. Return `ENTITY_ACTION.ALLOW` to accept the entity,\n * `ENTITY_ACTION.BLOCK` to silently skip it, or `ENTITY_ACTION.THROW` to abort with an error.\n * @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} [options.onInputEntity=null]\n * Hook called when an input entity is registered via `addInputEntities()`. Return\n * `ENTITY_ACTION.ALLOW` to accept, `ENTITY_ACTION.BLOCK` to silently skip, or\n * `ENTITY_ACTION.THROW` to abort with an error.\n */\n constructor(options = {}) {\n this._limit = options.limit || {};\n this._maxTotalExpansions = this._limit.maxTotalExpansions || 0;\n this._maxExpandedLength = this._limit.maxExpandedLength || 0;\n this._postCheck = typeof options.postCheck === 'function' ? options.postCheck : r => r;\n this._limitTiers = parseLimitTiers(this._limit.applyLimitsTo ?? LIMIT_TIER_EXTERNAL);\n this._numericAllowed = options.numericAllowed ?? true;\n // Base map: DEFAULT_XML_ENTITIES + user-supplied extras. Immutable after construction.\n this._baseMap = mergeEntityMaps(DEFAULT_XML_ENTITIES, options.namedEntities || null);\n\n // Persistent external entities — survive across documents.\n // Stored as a separate map so reset() never touches them.\n /** @type {Record} */\n this._externalMap = Object.create(null);\n\n // Input / runtime entities — current document only, wiped on reset().\n /** @type {Record} */\n this._inputMap = Object.create(null);\n\n // Per-document counters\n this._totalExpansions = 0;\n this._expandedLength = 0;\n\n // --- New: remove / leave sets ---\n /** @type {Set} */\n this._removeSet = new Set(options.remove && Array.isArray(options.remove) ? options.remove : []);\n /** @type {Set} */\n this._leaveSet = new Set(options.leave && Array.isArray(options.leave) ? options.leave : []);\n\n // --- NCR config (parsed into flat fields for hot-path speed) ---\n const ncrCfg = parseNCRConfig(options.ncr);\n this._ncrXmlVersion = ncrCfg.xmlVersion;\n this._ncrOnLevel = ncrCfg.onLevel;\n this._ncrNullLevel = ncrCfg.nullLevel;\n\n // --- Registration hooks ---\n /** @type {((name: string, value: string) => 'allow'|'block'|'throw')|null} */\n this._onExternalEntity = typeof options.onExternalEntity === 'function'\n ? options.onExternalEntity\n : null;\n /** @type {((name: string, value: string) => 'allow'|'block'|'throw')|null} */\n this._onInputEntity = typeof options.onInputEntity === 'function'\n ? options.onInputEntity\n : null;\n }\n\n // -------------------------------------------------------------------------\n // Private: registration hook dispatch\n // -------------------------------------------------------------------------\n\n /**\n * Invoke a registration hook for a single entity name/value pair.\n * Returns true when the entity should be accepted, false when it should be\n * silently skipped (BLOCK), and throws when the hook returns THROW.\n *\n * @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} hook\n * @param {string} name\n * @param {string} value\n * @param {string} context — used in error messages ('external' | 'input')\n * @returns {boolean} true = accept, false = skip\n */\n _applyRegistrationHook(hook, name, value, context) {\n if (!hook) return true; // no hook → always accept\n const action = hook(name, value);\n if (action === ENTITY_ACTION.BLOCK) return false;\n if (action === ENTITY_ACTION.THROW) {\n throw new Error(\n `[EntityDecoder] Registration of ${context} entity \"&${name};\" was rejected by hook`\n );\n }\n return true; // ALLOW or any unknown return value → accept\n }\n\n // -------------------------------------------------------------------------\n // Persistent external entity registration\n // -------------------------------------------------------------------------\n\n /**\n * Replace the full set of persistent external entities.\n * All keys are validated — throws on invalid characters.\n * If `onExternalEntity` is set, it is called once per entry; entries that\n * return `ENTITY_ACTION.BLOCK` are silently omitted, `ENTITY_ACTION.THROW`\n * aborts the whole call.\n * @param {Record} map\n */\n setExternalEntities(map) {\n if (map) {\n for (const key of Object.keys(map)) {\n validateEntityName(key);\n }\n }\n if (!this._onExternalEntity) {\n this._externalMap = mergeEntityMaps(map);\n return;\n }\n // Hook present — resolve values first, then filter\n const flat = mergeEntityMaps(map);\n const filtered = Object.create(null);\n for (const [name, value] of Object.entries(flat)) {\n if (this._applyRegistrationHook(this._onExternalEntity, name, value, 'external')) {\n filtered[name] = value;\n }\n }\n this._externalMap = filtered;\n }\n\n /**\n * Add a single persistent external entity.\n * If `onExternalEntity` is set it is called before the entity is stored;\n * `ENTITY_ACTION.BLOCK` silently skips storage, `ENTITY_ACTION.THROW` raises.\n * @param {string} key\n * @param {string} value\n */\n addExternalEntity(key, value) {\n validateEntityName(key);\n if (typeof value === 'string' && value.indexOf('&') === -1) {\n if (this._applyRegistrationHook(this._onExternalEntity, key, value, 'external')) {\n this._externalMap[key] = value;\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Input / runtime entity registration (per document)\n // -------------------------------------------------------------------------\n\n /**\n * Inject DOCTYPE entities for the current document.\n * Also resets per-document expansion counters.\n * If `onInputEntity` is set it is called once per entry; entries returning\n * `ENTITY_ACTION.BLOCK` are silently omitted, `ENTITY_ACTION.THROW` aborts.\n * @param {Record} map\n */\n addInputEntities(map) {\n this._totalExpansions = 0;\n this._expandedLength = 0;\n if (!this._onInputEntity) {\n this._inputMap = mergeEntityMaps(map);\n return;\n }\n const flat = mergeEntityMaps(map);\n const filtered = Object.create(null);\n for (const [name, value] of Object.entries(flat)) {\n if (this._applyRegistrationHook(this._onInputEntity, name, value, 'input')) {\n filtered[name] = value;\n }\n }\n this._inputMap = filtered;\n }\n\n // -------------------------------------------------------------------------\n // Per-document reset\n // -------------------------------------------------------------------------\n\n /**\n * Wipe input/runtime entities and reset counters.\n * Call this before processing each new document.\n * @returns {this}\n */\n reset() {\n this._inputMap = Object.create(null);\n this._totalExpansions = 0;\n this._expandedLength = 0;\n return this;\n }\n\n // -------------------------------------------------------------------------\n // XML version (can be set after construction, e.g. once parser reads )\n // -------------------------------------------------------------------------\n\n /**\n * Update the XML version used for NCR classification.\n * Call this as soon as the document's `` declaration is parsed.\n * @param {1.0|1.1|number} version\n */\n setXmlVersion(version) {\n this._ncrXmlVersion = version === 1.1 ? 1.1 : 1.0;\n }\n\n // -------------------------------------------------------------------------\n // Primary API\n // -------------------------------------------------------------------------\n\n /**\n * Replace all entity references in `str` in a single pass.\n *\n * @param {string} str\n * @returns {string}\n */\n decode(str) {\n if (typeof str !== 'string' || str.length === 0) return str;\n //TODO: check if needed\n if (str.indexOf('&') === -1) return str; // fast path — no entities at all\n\n const original = str;\n const chunks = [];\n const len = str.length;\n let last = 0; // start of next unprocessed literal chunk\n let i = 0;\n\n const limitExpansions = this._maxTotalExpansions > 0;\n const limitLength = this._maxExpandedLength > 0;\n const checkLimits = limitExpansions || limitLength;\n\n while (i < len) {\n // Scan forward to next '&'\n if (str.charCodeAt(i) !== 38 /* '&' */) { i++; continue; }\n\n // --- Found '&' at position i ---\n\n // Scan forward to ';'\n let j = i + 1;\n while (j < len && str.charCodeAt(j) !== 59 /* ';' */ && (j - i) <= 32) j++;\n\n if (j >= len || str.charCodeAt(j) !== 59) {\n // No closing ';' within window — treat '&' as literal\n i++;\n continue;\n }\n\n // Raw token between '&' and ';' (exclusive)\n const token = str.slice(i + 1, j);\n if (token.length === 0) { i++; continue; }\n\n let replacement;\n let tier; // which limit tier this entity belongs to\n\n if (this._removeSet.has(token)) {\n // Remove entity: replace with empty string\n replacement = '';\n // If entity was unknown (replacement undefined), we still need a tier for limits.\n // Treat as external tier because it's user-directed removal of an unknown reference.\n if (tier === undefined) {\n tier = LIMIT_TIER_EXTERNAL;\n }\n } else if (this._leaveSet.has(token)) {\n // Do not replace — keep original &token; as literal\n i++;\n continue;\n } else if (token.charCodeAt(0) === 35 /* '#' */) {\n // ---- Numeric / NCR reference ----\n // NCR classification always runs first — prohibited codepoints must be\n // caught regardless of numericAllowed.\n const ncrResult = this._resolveNCR(token);\n if (ncrResult === undefined) {\n // 'leave' action — keep original &token; as-is\n i++;\n continue;\n }\n replacement = ncrResult; // '' for remove, char string for allow\n tier = LIMIT_TIER_BASE;\n } else {\n // ---- Named reference ----\n const resolved = this._resolveName(token);\n replacement = resolved?.value;\n tier = resolved?.tier;\n }\n\n if (replacement === undefined) {\n // Unknown entity — leave as-is, advance past '&' only\n i++;\n continue;\n }\n\n // Flush literal chunk before this entity\n if (i > last) chunks.push(str.slice(last, i));\n chunks.push(replacement);\n last = j + 1; // skip past ';'\n i = last;\n\n // Apply expansion limits only if this tier is being tracked\n if (checkLimits && this._tierCounts(tier)) {\n if (limitExpansions) {\n this._totalExpansions++;\n if (this._totalExpansions > this._maxTotalExpansions) {\n throw new Error(\n `[EntityReplacer] Entity expansion count limit exceeded: ` +\n `${this._totalExpansions} > ${this._maxTotalExpansions}`\n );\n }\n }\n if (limitLength) {\n // delta: replacement.length minus the raw &token; length (token.length + 2 for '&' and ';')\n const delta = replacement.length - (token.length + 2);\n if (delta > 0) {\n this._expandedLength += delta;\n if (this._expandedLength > this._maxExpandedLength) {\n throw new Error(\n `[EntityReplacer] Expanded content length limit exceeded: ` +\n `${this._expandedLength} > ${this._maxExpandedLength}`\n );\n }\n }\n }\n }\n }\n\n // Flush trailing literal\n if (last < len) chunks.push(str.slice(last));\n\n // If nothing was replaced, chunks is empty — return original\n const result = chunks.length === 0 ? str : chunks.join('');\n\n return this._postCheck(result, original);\n }\n\n // -------------------------------------------------------------------------\n // Private: limit tier check\n // -------------------------------------------------------------------------\n\n /**\n * Returns true if a resolved entity of the given tier should count\n * against the expansion/length limits.\n * @param {string} tier — LIMIT_TIER_EXTERNAL | LIMIT_TIER_BASE\n * @returns {boolean}\n */\n _tierCounts(tier) {\n if (this._limitTiers.has(LIMIT_TIER_ALL)) return true;\n return this._limitTiers.has(tier);\n }\n\n // -------------------------------------------------------------------------\n // Private: entity resolution\n // -------------------------------------------------------------------------\n\n /**\n * Resolve a named entity token (without & and ;).\n * Priority: inputMap > externalMap > baseMap\n * Returns the resolved value tagged with its limit tier.\n *\n * @param {string} name\n * @returns {{ value: string, tier: string }|undefined}\n */\n _resolveName(name) {\n // input and external both count as 'external' tier for limit purposes —\n // they are injected at runtime and are the untrusted surface.\n if (name in this._inputMap) return { value: this._inputMap[name], tier: LIMIT_TIER_EXTERNAL };\n if (name in this._externalMap) return { value: this._externalMap[name], tier: LIMIT_TIER_EXTERNAL };\n if (name in this._baseMap) return { value: this._baseMap[name], tier: LIMIT_TIER_BASE };\n return undefined;\n }\n\n /**\n * Classify a codepoint and return the minimum action level that must be applied.\n * Returns -1 when no minimum is imposed (normal allow path).\n *\n * Ranges checked (in priority order):\n * 1. U+0000 — null, governed by nullNCR (always ≥ remove)\n * 2. U+D800–U+DFFF — surrogates, always prohibited (min: remove)\n * 3. U+0001–U+001F \\ {0x09,0x0A,0x0D} — XML 1.0 restricted C0 (min: remove)\n * (skipped in XML 1.1 — C0 controls are allowed when written as NCRs)\n *\n * @param {number} cp — codepoint\n * @returns {number} — minimum NCR_LEVEL value, or -1 for no restriction\n */\n _classifyNCR(cp) {\n // 1. Null\n if (cp === 0) return this._ncrNullLevel;\n\n // 2. Surrogates — always prohibited, minimum 'remove'\n if (cp >= 0xD800 && cp <= 0xDFFF) return NCR_LEVEL.remove;\n\n // 3. XML 1.0 restricted C0 controls\n if (this._ncrXmlVersion === 1.0) {\n if (cp >= 0x01 && cp <= 0x1F && !XML10_ALLOWED_C0.has(cp)) return NCR_LEVEL.remove;\n }\n\n return -1; // no restriction\n }\n\n /**\n * Execute a resolved NCR action.\n *\n * @param {number} action — NCR_LEVEL value\n * @param {string} token — raw token (e.g. '#38') for error messages\n * @param {number} cp — codepoint, used only for error messages\n * @returns {string|undefined}\n * - decoded character string → 'allow'\n * - '' → 'remove'\n * - undefined → 'leave' (caller must skip past '&' only)\n * - throws Error → 'throw'\n */\n _applyNCRAction(action, token, cp) {\n switch (action) {\n case NCR_LEVEL.allow: return String.fromCodePoint(cp);\n case NCR_LEVEL.remove: return '';\n case NCR_LEVEL.leave: return undefined; // signal: keep literal\n case NCR_LEVEL.throw:\n throw new Error(\n `[EntityDecoder] Prohibited numeric character reference ` +\n `&${token}; (U+${cp.toString(16).toUpperCase().padStart(4, '0')})`\n );\n default: return String.fromCodePoint(cp);\n }\n }\n\n /**\n * Full NCR resolution pipeline for a numeric token.\n *\n * Steps:\n * 1. Parse the codepoint (decimal or hex).\n * 2. Validate the raw codepoint range (NaN, <0, >0x10FFFF).\n * 3. If numericAllowed is false and no minimum restriction applies → leave as-is.\n * 4. Classify the codepoint to find the minimum required action level.\n * 5. Resolve effective action = max(onNCR, minimum).\n * 6. Apply and return.\n *\n * @param {string} token — e.g. '#38', '#x26', '#X26'\n * @returns {string|undefined}\n * - string (incl. '') — replacement ('' = remove)\n * - undefined — leave original &token; as-is\n */\n _resolveNCR(token) {\n // Step 1: parse codepoint\n const second = token.charCodeAt(1);\n let cp;\n if (second === 120 /* x */ || second === 88 /* X */) {\n cp = parseInt(token.slice(2), 16);\n } else {\n cp = parseInt(token.slice(1), 10);\n }\n\n // Step 2: out-of-range → leave as-is unconditionally\n if (Number.isNaN(cp) || cp < 0 || cp > 0x10FFFF) return undefined;\n\n // Step 3: classify to get minimum action level\n const minimum = this._classifyNCR(cp);\n\n // Step 4: if numericAllowed is false and no hard minimum → leave\n if (!this._numericAllowed && minimum < NCR_LEVEL.remove) return undefined;\n\n // Step 5: effective action = max(configured onNCR, range minimum)\n const effective = minimum === -1\n ? this._ncrOnLevel\n : Math.max(this._ncrOnLevel, minimum);\n\n // Step 6: apply\n return this._applyNCRAction(effective, token, cp);\n }\n}","/**\n * SQL context patterns — high-precision rules only.\n *\n * These rules have very low false-positive risk and are safe to apply to\n * general user text (names, descriptions, search queries, etc.).\n * All patterns are ReDoS-safe — unlike the `sql-injection` npm package\n * which has an active CVE on its own detection regexes.\n *\n * For exhaustive coverage including noisier heuristics (comment sequences,\n * hex literals, stacked queries with semicolons), use 'SQL-STRICT' instead.\n * Apply 'SQL-STRICT' only to strings that are specifically SQL fragments,\n * not to general free-text fields.\n */\n\nconst SQL_PATTERNS = [\n {\n id: 'sql-block-comment-open',\n description: 'SQL block comment open: /* ... */ — unusual in legitimate user text',\n pattern: /\\/\\*/,\n },\n {\n id: 'sql-union-select',\n description: 'UNION SELECT — most common SQL injection aggregation attack',\n pattern: /\\bUNION\\s{1,20}(?:ALL\\s{1,20})?SELECT\\b/i,\n },\n {\n id: 'sql-drop-table',\n description: 'DROP TABLE — destructive DDL injection',\n pattern: /\\bDROP\\s{1,20}TABLE\\b/i,\n },\n {\n id: 'sql-drop-database',\n description: 'DROP DATABASE — destructive DDL injection',\n pattern: /\\bDROP\\s{1,20}DATABASE\\b/i,\n },\n {\n id: 'sql-insert-into',\n description: 'INSERT INTO — data injection',\n pattern: /\\bINSERT\\s{1,20}INTO\\b/i,\n },\n {\n id: 'sql-delete-from',\n description: 'DELETE FROM — data deletion injection',\n pattern: /\\bDELETE\\s{1,20}FROM\\b/i,\n },\n {\n id: 'sql-update-set',\n description: 'UPDATE ... SET — data modification injection',\n // Allows arbitrary content between UPDATE and SET (table name, alias, etc.)\n pattern: /\\bUPDATE\\b[\\s\\S]{1,60}\\bSET\\b/i,\n },\n {\n id: 'sql-exec-xp',\n description: 'EXEC xp_ — MSSQL extended stored procedure execution',\n pattern: /\\bEXEC(?:UTE)?\\s{1,20}xp_/i,\n },\n {\n id: 'sql-tautology-string',\n description: \"Classic string tautology: ' OR '1'='1 or \\\" OR \\\"1\\\"=\\\"1\\\"\",\n // Last quote is optional — injection may truncate it: ' OR '1'='1--\n pattern: /'\\s{0,10}OR\\s{0,10}'[^']{0,20}'\\s*=\\s*'[^']{0,20}/i,\n },\n {\n id: 'sql-tautology-numeric',\n description: 'Numeric tautology: OR 1=1',\n pattern: /\\bOR\\s{1,10}1\\s*=\\s*1\\b/i,\n },\n {\n id: 'sql-always-true-zero',\n description: 'Numeric tautology: OR 0=0',\n pattern: /\\bOR\\s{1,10}0\\s*=\\s*0\\b/i,\n },\n {\n id: 'sql-sleep-benchmark',\n description: 'Time-based blind injection: SLEEP() or BENCHMARK()',\n pattern: /\\b(?:SLEEP|BENCHMARK)\\s*\\(/i,\n },\n {\n id: 'sql-waitfor-delay',\n description: 'MSSQL time-based blind injection: WAITFOR DELAY',\n pattern: /\\bWAITFOR\\s{1,20}DELAY\\b/i,\n },\n {\n id: 'sql-char-function',\n description: 'CHAR() function — used to obfuscate injected strings',\n pattern: /\\bCHAR\\s*\\(\\s*\\d{1,3}/i,\n },\n {\n id: 'sql-information-schema',\n description: 'INFORMATION_SCHEMA — reconnaissance query for table/column enumeration',\n pattern: /\\bINFORMATION_SCHEMA\\b/i,\n },\n];\n\nexport default SQL_PATTERNS;\n","/**\n * SQL-STRICT context patterns.\n *\n * Extends the base 'SQL' context with three additional rules that are\n * effective at detecting real injections but carry a higher false-positive\n * risk on general free-text input.\n *\n * Use 'SQL-STRICT' when:\n * - The string is specifically a SQL fragment or database identifier\n * - You control the input domain (e.g. a dedicated SQL search field)\n * - You can tolerate occasional false positives in exchange for broader coverage\n *\n * Use 'SQL' (not STRICT) when:\n * - The field is general user text (names, descriptions, comments)\n * - False positives would block legitimate content (e.g. \"see note -- above\")\n *\n * Rules moved here from 'SQL' due to false-positive risk:\n *\n * sql-line-comment — \"--\" fires on \"see note -- above\", \"value--\", CSS var(--primary)\n * sql-stacked-query — \"; SELECT\" fires on legitimate prose with semicolons + SQL words\n * sql-hex-encoding — \"0xDEAD\" fires on hex values in technical docs and log output\n */\n\nimport SQL_PATTERNS from './sql.js';\n\nconst SQL_STRICT_EXTRA = [\n {\n id: 'sql-line-comment',\n description: 'SQL line comment: -- followed by whitespace or end of string',\n pattern: /--(?:\\s|$)/,\n },\n {\n id: 'sql-stacked-query',\n description: 'Stacked queries: semicolon immediately followed by a SQL keyword',\n pattern: /;\\s{0,10}(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|EXEC)\\b/i,\n },\n {\n id: 'sql-hex-encoding',\n description: 'Hex-encoded string injection: 0x41414141 style (MySQL)',\n pattern: /\\b0x[0-9a-f]{4,}/i,\n },\n];\n\n// SQL-STRICT = all base SQL rules + the three noisy extras\nconst SQL_STRICT_PATTERNS = [...SQL_PATTERNS, ...SQL_STRICT_EXTRA];\n\nexport default SQL_STRICT_PATTERNS;\n","/**\n * HTML context patterns.\n *\n * Detects XSS vectors that are dangerous when a string ends up rendered as HTML.\n * All patterns use bounded quantifiers to ensure linear-time matching (ReDoS-safe).\n *\n * Each entry is { pattern: RegExp, id: string, description: string }\n * so callers can inspect which rule fired if they need to.\n */\n\nconst HTML_PATTERNS = [\n {\n id: 'html-script-open',\n description: ']/i,\n },\n {\n id: 'html-javascript-protocol',\n description: 'javascript: URI scheme (with optional whitespace/encoding)',\n // Handles javascript:, j\\u0061vascript:, and whitespace variants\n pattern: /j[\\t\\n\\r ]*a[\\t\\n\\r ]*v[\\t\\n\\r ]*a[\\t\\n\\r ]*s[\\t\\n\\r ]*c[\\t\\n\\r ]*r[\\t\\n\\r ]*i[\\t\\n\\r ]*p[\\t\\n\\r ]*t[\\t\\n\\r ]*:/i,\n },\n {\n id: 'html-vbscript-protocol',\n description: 'vbscript: URI scheme',\n pattern: /vbscript[\\t\\n\\r ]*:/i,\n },\n {\n id: 'html-data-html',\n description: 'data:text/html URI — can execute scripts in browsers',\n pattern: /data[\\t\\n\\r ]*:[\\t\\n\\r ]*text\\/html/i,\n },\n {\n id: 'html-data-xhtml',\n description: 'data:application/xhtml+xml URI',\n pattern: /data[\\t\\n\\r ]*:[\\t\\n\\r ]*application\\/xhtml/i,\n },\n {\n id: 'html-data-svg',\n description: 'data:image/svg+xml URI — can execute scripts',\n pattern: /data[\\t\\n\\r ]*:[\\t\\n\\r ]*image\\/svg\\+xml/i,\n },\n {\n id: 'html-inline-event-handler',\n description: 'Inline event handler attributes: onclick=, onerror=, onload=, etc.',\n // \\bon ensures we match a word boundary so \"phonetic=\" is not caught\n pattern: /\\bon\\w{1,30}\\s*=/i,\n },\n {\n id: 'html-entity-obfuscated-script',\n description: 'HTML-entity-encoded ', HTML) // true\n * isUnsafe('hello world', HTML) // false\n * isUnsafe('value', [HTML, SQL]) // false\n * isUnsafe('value', /my-pattern/i) // false\n */\nfunction isUnsafe(value, context) {\n assertString(value);\n assertContext(context);\n\n const { lists, regex } = normalise(context);\n\n if (regex) return regex.test(value);\n\n for (const list of lists) {\n if (matchList(value, list) !== null) return true;\n }\n return false;\n}\n\n/**\n * Like `isUnsafe`, but returns the first `MatchResult` describing **why**\n * the value was flagged, or `null` if it is safe.\n *\n * @param {string} value\n * @param {PatternList | PatternList[] | RegExp} context\n * @returns {MatchResult|null}\n *\n * @example\n * import { whyUnsafe, HTML } from 'is-unsafe';\n *\n * whyUnsafe('', HTML)\n * // { context: 'HTML', id: 'html-script-open', description: '...', pattern: /.../ }\n */\nfunction whyUnsafe(value, context) {\n assertString(value);\n assertContext(context);\n\n const { lists, regex } = normalise(context);\n\n if (regex) {\n return regex.test(value)\n ? { context: 'CUSTOM', id: 'custom-regex', description: 'Matched caller-supplied pattern', pattern: regex }\n : null;\n }\n\n for (const list of lists) {\n const result = matchList(value, list);\n if (result !== null) return result;\n }\n return null;\n}\n\n/**\n * Returns **all** matching rules across the given context(s), or an empty\n * array if the value is safe. Useful for comprehensive auditing.\n *\n * @param {string} value\n * @param {PatternList | PatternList[] | RegExp} context\n * @returns {MatchResult[]}\n */\nfunction allUnsafe(value, context) {\n assertString(value);\n assertContext(context);\n\n const { lists, regex } = normalise(context);\n const results = [];\n\n if (regex) {\n if (regex.test(value)) {\n results.push({ context: 'CUSTOM', id: 'custom-regex', description: 'Matched caller-supplied pattern', pattern: regex });\n }\n return results;\n }\n\n for (const list of lists) {\n const label = list.label ?? 'CUSTOM';\n for (const rule of list) {\n if (rule.pattern.test(value)) {\n results.push({ context: label, id: rule.id, description: rule.description, pattern: rule.pattern });\n }\n }\n }\n\n return results;\n}\n\nexport { isUnsafe, whyUnsafe, allUnsafe };\nexport default isUnsafe;\n","'use strict';\n///@ts-check\n\nimport { getAllMatches, isExist, DANGEROUS_PROPERTY_NAMES, criticalProperties } from '../util.js';\nimport xmlNode from './xmlNode.js';\nimport DocTypeReader from './DocTypeReader.js';\nimport toNumber from \"strnum\";\nimport getIgnoreAttributesFn from \"../ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\nimport { ExpressionSet } from 'path-expression-matcher';\nimport { EntityDecoder, XML, CURRENCY, COMMON_HTML, ENTITY_ACTION } from '@nodable/entities';\nimport { isUnsafe, HTML as HTML_CONTEXT, XML as XML_CONTEXT } from \"is-unsafe\"\n\n\n// const regx =\n// '<((!\\\\[CDATA\\\\[([\\\\s\\\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\\\/)(NAME)\\\\s*>))([^<]*)'\n// .replace(/NAME/g, util.nameRegexp);\n\n//const tagsRegx = new RegExp(\"<(\\\\/?[\\\\w:\\\\-\\._]+)([^>]*)>(\\\\s*\"+cdataRegx+\")*([^<]+)?\",\"g\");\n//const tagsRegx = new RegExp(\"<(\\\\/?)((\\\\w*:)?([\\\\w:\\\\-\\._]+))([^>]*)>([^<]*)(\"+cdataRegx+\"([^<]*))*([^<]+)?\",\"g\");\n\n// Helper functions for attribute and namespace handling\n\n/**\n * Extract raw attributes (without prefix) from prefixed attribute map\n * @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap\n * @param {object} options - Parser options containing attributeNamePrefix\n * @returns {object} Raw attributes for matcher\n */\nfunction extractRawAttributes(prefixedAttrs, options) {\n if (!prefixedAttrs) return {};\n\n // Handle attributesGroupName option\n const attrs = options.attributesGroupName\n ? prefixedAttrs[options.attributesGroupName]\n : prefixedAttrs;\n\n if (!attrs) return {};\n\n const rawAttrs = {};\n for (const key in attrs) {\n // Remove the attribute prefix to get raw name\n if (key.startsWith(options.attributeNamePrefix)) {\n const rawName = key.substring(options.attributeNamePrefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * Extract namespace from raw tag name\n * @param {string} rawTagName - Tag name possibly with namespace (e.g., \"soap:Envelope\")\n * @returns {string|undefined} Namespace or undefined\n */\nfunction extractNamespace(rawTagName) {\n if (!rawTagName || typeof rawTagName !== 'string') return undefined;\n\n const colonIndex = rawTagName.indexOf(':');\n if (colonIndex !== -1 && colonIndex > 0) {\n const ns = rawTagName.substring(0, colonIndex);\n // Don't treat xmlns as a namespace\n if (ns !== 'xmlns') {\n return ns;\n }\n }\n return undefined;\n}\n\nexport default class OrderedObjParser {\n constructor(options, externalEntities) {\n this.options = options;\n this.currentNode = null;\n this.tagsNodeStack = [];\n this.parseXml = parseXml;\n this.parseTextData = parseTextData;\n this.resolveNameSpace = resolveNameSpace;\n this.buildAttributesMap = buildAttributesMap;\n this.isItStopNode = isItStopNode;\n this.replaceEntitiesValue = replaceEntitiesValue;\n this.readStopNodeData = readStopNodeData;\n this.saveTextToParentTag = saveTextToParentTag;\n this.addChild = addChild;\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n this.doctypefound = false;\n let namedEntities = { ...XML };\n if (this.options.entityDecoder) {\n this.entityDecoder = this.options.entityDecoder\n } else {\n if (typeof this.options.htmlEntities === \"object\") namedEntities = this.options.htmlEntities;\n else if (this.options.htmlEntities === true) namedEntities = { ...COMMON_HTML, ...CURRENCY };\n this.entityDecoder = new EntityDecoder({\n namedEntities: { ...namedEntities, ...externalEntities },\n numericAllowed: this.options.htmlEntities,\n limit: {\n maxTotalExpansions: this.options.processEntities.maxTotalExpansions,\n maxExpandedLength: this.options.processEntities.maxExpandedLength,\n applyLimitsTo: this.options.processEntities.appliesTo,\n },\n // onExternalEntity: (name, value) => isUnsafe(value) ? 'block' : 'allow',\n onInputEntity: (name, value) =>\n //TODO: VALID_CONTEXTS.HTML should be set only if this.options.htmlEntities\n isUnsafe(value, [HTML_CONTEXT, XML_CONTEXT]) ? ENTITY_ACTION.BLOCK : ENTITY_ACTION.ALLOW,\n\n //postCheck: resolved => resolved\n });\n }\n\n // Initialize path matcher for path-expression-matcher\n this.matcher = new Matcher();\n this.readonlyMatcher = this.matcher.readOnly();\n\n // Flag to track if current node is a stop node (optimization)\n this.isCurrentNodeStopNode = false;\n\n // Pre-compile stopNodes expressions\n this.stopNodeExpressionsSet = new ExpressionSet();\n const stopNodesOpts = this.options.stopNodes;\n if (stopNodesOpts && stopNodesOpts.length > 0) {\n for (let i = 0; i < stopNodesOpts.length; i++) {\n const stopNodeExp = stopNodesOpts[i];\n if (typeof stopNodeExp === 'string') {\n // Convert string to Expression object\n this.stopNodeExpressionsSet.add(new Expression(stopNodeExp));\n } else if (stopNodeExp instanceof Expression) {\n // Already an Expression object\n this.stopNodeExpressionsSet.add(stopNodeExp);\n }\n }\n this.stopNodeExpressionsSet.seal();\n }\n }\n\n}\n\n\n/**\n * @param {string} val\n * @param {string} tagName\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n * @param {boolean} dontTrim\n * @param {boolean} hasAttributes\n * @param {boolean} isLeafNode\n * @param {boolean} escapeEntities\n */\nfunction parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {\n const options = this.options;\n if (val !== undefined) {\n if (options.trimValues && !dontTrim) {\n val = val.trim();\n }\n if (val.length > 0) {\n if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? jPath.toString() : jPath;\n const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);\n if (newval === null || newval === undefined) {\n //don't parse\n return val;\n } else if (typeof newval !== typeof val || newval !== val) {\n //overwrite\n return newval;\n } else if (options.trimValues) {\n return parseValue(val, options.parseTagValue, options.numberParseOptions);\n } else {\n const trimmedVal = val.trim();\n if (trimmedVal === val) {\n return parseValue(val, options.parseTagValue, options.numberParseOptions);\n } else {\n return val;\n }\n }\n }\n }\n}\n\nfunction resolveNameSpace(tagname) {\n if (this.options.removeNSPrefix) {\n const tags = tagname.split(':');\n const prefix = tagname.charAt(0) === '/' ? '/' : '';\n if (tags[0] === 'xmlns') {\n return '';\n }\n if (tags.length === 2) {\n tagname = prefix + tags[1];\n }\n }\n return tagname;\n}\n\n//TODO: change regex to capture NS\n//const attrsRegx = new RegExp(\"([\\\\w\\\\-\\\\.\\\\:]+)\\\\s*=\\\\s*(['\\\"])((.|\\n)*?)\\\\2\",\"gm\");\nconst attrsRegx = new RegExp('([^\\\\s=]+)\\\\s*(=\\\\s*([\\'\"])([\\\\s\\\\S]*?)\\\\3)?', 'gm');\n\nfunction buildAttributesMap(attrStr, jPath, tagName, force = false) {\n const options = this.options;\n if (force === true || (options.ignoreAttributes !== true && typeof attrStr === 'string')) {\n // attrStr = attrStr.replace(/\\r?\\n/g, ' ');\n //attrStr = attrStr || attrStr.trim();\n\n const matches = getAllMatches(attrStr, attrsRegx);\n const len = matches.length; //don't make it inline\n const attrs = {};\n\n // Pre-process values once: trim + entity replacement\n // Reused in both matcher update and second pass\n const processedVals = new Array(len);\n let hasRawAttrs = false;\n const rawAttrsForMatcher = {};\n\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n const oldVal = matches[i][4];\n\n if (attrName.length && oldVal !== undefined) {\n let val = oldVal;\n if (options.trimValues) val = val.trim();\n val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher);\n processedVals[i] = val;\n\n rawAttrsForMatcher[attrName] = val;\n hasRawAttrs = true;\n }\n }\n\n // Update matcher ONCE before second pass, if applicable\n if (hasRawAttrs && typeof jPath === 'object' && jPath.updateCurrent) {\n jPath.updateCurrent(rawAttrsForMatcher);\n }\n\n // Hoist toString() once — path doesn't change during attribute processing\n const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher;\n\n // Second pass: apply processors, build final attrs\n let hasAttrs = false;\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n\n if (this.ignoreAttributesFn(attrName, jPathStr)) continue;\n\n let aName = options.attributeNamePrefix + attrName;\n\n if (attrName.length) {\n if (options.transformAttributeName) {\n aName = options.transformAttributeName(aName);\n }\n aName = sanitizeName(aName, options);\n\n if (matches[i][4] !== undefined) {\n // Reuse already-processed value — no double entity replacement\n const oldVal = processedVals[i];\n\n const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr);\n if (newVal === null || newVal === undefined) {\n attrs[aName] = oldVal;\n } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {\n attrs[aName] = newVal;\n } else {\n attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions);\n }\n hasAttrs = true;\n } else if (options.allowBooleanAttributes) {\n attrs[aName] = true;\n hasAttrs = true;\n }\n }\n }\n\n if (!hasAttrs) return;\n\n if (options.attributesGroupName && !options.preserveOrder) {\n const attrCollection = {};\n attrCollection[options.attributesGroupName] = attrs;\n return attrCollection;\n }\n return attrs;\n }\n}\nconst parseXml = function (xmlData) {\n xmlData = xmlData.replace(/\\r\\n?/g, \"\\n\"); //TODO: remove this line\n const xmlObj = new xmlNode('!xml');\n let currentNode = xmlObj;\n let textData = \"\";\n\n // Reset matcher for new document\n this.matcher.reset();\n this.entityDecoder.reset();\n\n // Reset entity expansion counters for this document\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n this.doctypefound = false;\n const options = this.options;\n const docTypeReader = new DocTypeReader(options.processEntities);\n const xmlLen = xmlData.length;\n for (let i = 0; i < xmlLen; i++) {//for each char in XML data\n const ch = xmlData[i];\n if (ch === '<') {\n // const nextIndex = i+1;\n // const _2ndChar = xmlData[nextIndex];\n const c1 = xmlData.charCodeAt(i + 1);\n if (c1 === 47) {//Closing Tag '/'\n const closeIndex = findClosingIndex(xmlData, \">\", i, \"Closing Tag is not closed.\")\n let tagName = xmlData.substring(i + 2, closeIndex).trim();\n\n if (options.removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n }\n }\n\n tagName = transformTagName(options.transformTagName, tagName, \"\", options).tagName;\n\n if (currentNode) {\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n }\n\n //check if last tag of nested tag was unpaired tag\n const lastTagName = this.matcher.getCurrentTag();\n if (tagName && options.unpairedTagsSet.has(tagName)) {\n throw new Error(`Unpaired tag can not be used as closing tag: `);\n }\n if (lastTagName && options.unpairedTagsSet.has(lastTagName)) {\n // Pop the unpaired tag\n this.matcher.pop();\n this.tagsNodeStack.pop();\n }\n // Pop the closing tag\n this.matcher.pop();\n this.isCurrentNodeStopNode = false; // Reset flag when closing tag\n\n //a closing tag with no matching opening tag leaves the stack empty\n currentNode = this.tagsNodeStack.pop() || xmlObj;//avoid recursion, set the parent tag scope\n\n if (options.captureMetaData && currentNode) {\n currentNode.addEndIndex(closeIndex + 1);\n }\n textData = \"\";\n i = closeIndex;\n } else if (c1 === 63) { //'?'\n\n let tagData = readTagExp(xmlData, i, false, \"?>\");\n if (!tagData) throw new Error(\"Pi Tag is not closed.\");\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n const attsMap = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName, true);\n if (attsMap) {\n const ver = attsMap[this.options.attributeNamePrefix + \"version\"];\n this.entityDecoder.setXmlVersion(Number(ver) || 1.0);\n docTypeReader.setXmlVersion(Number(ver) || 1.0);\n }\n if ((options.ignoreDeclaration && tagData.tagName === \"?xml\") || options.ignorePiTags) {\n //do nothing\n } else {\n\n const childNode = new xmlNode(tagData.tagName);\n childNode.add(options.textNodeName, \"\");\n\n if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) {\n childNode[\":@\"] = attsMap\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, i);\n\n if (options.captureMetaData) {\n // closeIndex points at '?' of the closing '?>'\n currentNode.addEndIndex(tagData.closeIndex + 2);\n }\n }\n\n\n i = tagData.closeIndex + 1;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 45\n && xmlData.charCodeAt(i + 3) === 45) { //'!--'\n const endIndex = findClosingIndex(xmlData, \"-->\", i + 4, \"Comment is not closed.\")\n if (options.commentPropName) {\n const comment = xmlData.substring(i + 4, endIndex - 2);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n\n currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]);\n }\n i = endIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 68) { //'!D'\n if (this.doctypefound) throw new Error(\"Multiple DOCTYPE declarations found.\");\n this.doctypefound = true;\n const result = docTypeReader.readDocType(xmlData, i);\n this.entityDecoder.addInputEntities(result.entities);\n i = result.i;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 91) { // '!['\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"CDATA is not closed.\") - 2;\n const tagExp = xmlData.substring(i + 9, closeIndex);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n\n let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);\n if (val == undefined) val = \"\";\n\n //cdata should be set even if it is 0 length string\n if (options.cdataPropName) {\n currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]);\n } else {\n currentNode.add(options.textNodeName, val);\n }\n\n i = closeIndex + 2;\n } else {//Opening tag\n let result = readTagExp(xmlData, i, options.removeNSPrefix);\n\n // Safety check: readTagExp can return undefined\n if (!result) {\n // Log context for debugging\n const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50));\n throw new Error(`readTagExp returned undefined at position ${i}. Context: \"${context}\"`);\n }\n\n let tagName = result.tagName;\n const rawTagName = result.rawTagName;\n let tagExp = result.tagExp;\n let attrExpPresent = result.attrExpPresent;\n let closeIndex = result.closeIndex;\n\n ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));\n\n if (options.strictReservedNames &&\n (tagName === options.commentPropName\n || tagName === options.cdataPropName\n || tagName === options.textNodeName\n || tagName === options.attributesGroupName\n )) {\n throw new Error(`Invalid tag name: ${tagName}`);\n }\n\n //save text as child node\n if (currentNode && textData) {\n if (currentNode.tagname !== '!xml') {\n //when nested tag is found\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);\n }\n }\n\n //check if last tag was unpaired tag\n const lastTag = currentNode;\n if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) {\n currentNode = this.tagsNodeStack.pop();\n this.matcher.pop();\n }\n\n // Clean up self-closing syntax BEFORE processing attributes\n // This is where tagExp gets the trailing / removed\n let isSelfClosing = false;\n if (tagExp.length > 0 && tagExp.lastIndexOf(\"/\") === tagExp.length - 1) {\n isSelfClosing = true;\n if (tagName[tagName.length - 1] === \"/\") {\n tagName = tagName.substr(0, tagName.length - 1);\n tagExp = tagName;\n } else {\n tagExp = tagExp.substr(0, tagExp.length - 1);\n }\n\n // Re-check attrExpPresent after cleaning\n attrExpPresent = (tagName !== tagExp);\n }\n\n // Now process attributes with CLEAN tagExp (no trailing /)\n let prefixedAttrs = null;\n let rawAttrs = {};\n let namespace = undefined;\n\n // Extract namespace from rawTagName\n namespace = extractNamespace(rawTagName);\n\n // Push tag to matcher FIRST (with empty attrs for now) so callbacks see correct path\n if (tagName !== xmlObj.tagname) {\n this.matcher.push(tagName, {}, namespace);\n }\n\n // Now build attributes - callbacks will see correct matcher state\n if (tagName !== tagExp && attrExpPresent) {\n // Build attributes (returns prefixed attributes for the tree)\n // Note: buildAttributesMap now internally updates the matcher with raw attributes\n prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);\n\n if (prefixedAttrs) {\n // Extract raw attributes (without prefix) for our use\n //TODO: seems a performance overhead\n rawAttrs = extractRawAttributes(prefixedAttrs, options);\n }\n }\n\n // Now check if this is a stop node (after attributes are set)\n if (tagName !== xmlObj.tagname) {\n this.isCurrentNodeStopNode = this.isItStopNode();\n }\n\n const startIndex = i;\n if (this.isCurrentNodeStopNode) {\n let tagContent = \"\";\n\n // For self-closing tags, content is empty\n if (isSelfClosing) {\n i = result.closeIndex;\n }\n //unpaired tag\n else if (options.unpairedTagsSet.has(tagName)) {\n i = result.closeIndex;\n }\n //normal tag\n else {\n //read until closing tag is found\n const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);\n if (!result) throw new Error(`Unexpected end of ${rawTagName}`);\n i = result.i;\n tagContent = result.tagContent;\n }\n\n const childNode = new xmlNode(tagName);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n\n // For stop nodes, store raw content as-is without any processing\n childNode.add(options.textNodeName, tagContent);\n\n this.matcher.pop(); // Pop the stop node tag\n this.isCurrentNodeStopNode = false; // Reset flag\n\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n\n if (options.captureMetaData) {\n currentNode.addEndIndex(i + 1);\n }\n } else {\n //selfClosing tag\n if (isSelfClosing) {\n ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));\n\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n\n if (options.captureMetaData) {\n currentNode.addEndIndex(closeIndex + 1);\n }\n this.matcher.pop(); // Pop self-closing tag\n this.isCurrentNodeStopNode = false; // Reset flag\n }\n else if (options.unpairedTagsSet.has(tagName)) {//unpaired tag\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n\n if (options.captureMetaData) {\n currentNode.addEndIndex(result.closeIndex + 1);\n }\n this.matcher.pop(); // Pop unpaired tag\n this.isCurrentNodeStopNode = false; // Reset flag\n i = result.closeIndex;\n // Continue to next iteration without changing currentNode\n continue;\n }\n //opening tag\n else {\n const childNode = new xmlNode(tagName);\n if (this.tagsNodeStack.length > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n this.tagsNodeStack.push(currentNode);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n currentNode = childNode;\n }\n textData = \"\";\n i = closeIndex;\n }\n }\n } else {\n textData += xmlData[i];\n }\n }\n return xmlObj.child;\n}\n\nfunction addChild(currentNode, childNode, matcher, startIndex) {\n // unset startIndex if not requested\n if (!this.options.captureMetaData) startIndex = undefined;\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;\n const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[\":@\"])\n if (result === false) {\n //do nothing\n } else if (typeof result === \"string\") {\n childNode.tagname = result\n currentNode.addChild(childNode, startIndex);\n } else {\n currentNode.addChild(childNode, startIndex);\n }\n}\n\n/**\n * @param {object} val - Entity object with regex and val properties\n * @param {string} tagName - Tag name\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n */\nfunction replaceEntitiesValue(val, tagName, jPath) {\n const entityConfig = this.options.processEntities;\n\n if (!entityConfig || !entityConfig.enabled) {\n return val;\n }\n\n // Check if tag is allowed to contain entities\n if (entityConfig.allowedTags) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const allowed = Array.isArray(entityConfig.allowedTags)\n ? entityConfig.allowedTags.includes(tagName)\n : entityConfig.allowedTags(tagName, jPathOrMatcher);\n\n if (!allowed) {\n return val;\n }\n }\n\n // Apply custom tag filter if provided\n if (entityConfig.tagFilter) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {\n return val; // Skip based on custom filter\n }\n }\n\n return this.entityDecoder.decode(val);\n}\n\n\nfunction saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {\n if (textData) { //store previously collected data as textNode\n if (isLeafNode === undefined) isLeafNode = parentNode.child.length === 0\n\n textData = this.parseTextData(textData,\n parentNode.tagname,\n matcher,\n false,\n parentNode[\":@\"] ? Object.keys(parentNode[\":@\"]).length !== 0 : false,\n isLeafNode);\n\n if (textData !== undefined && textData !== \"\")\n parentNode.add(this.options.textNodeName, textData);\n textData = \"\";\n }\n return textData;\n}\n\n/**\n * @param {Array} stopNodeExpressions - Array of compiled Expression objects\n * @param {Matcher} matcher - Current path matcher\n */\nfunction isItStopNode() {\n if (this.stopNodeExpressionsSet.size === 0) return false;\n\n return this.matcher.matchesAny(this.stopNodeExpressionsSet);\n}\n\n/**\n * Returns the tag Expression and where it is ending handling single-double quotes situation\n * @param {string} xmlData \n * @param {number} i starting index\n * @returns \n */\nfunction tagExpWithClosingIndex(xmlData, i, closingChar = \">\") {\n //TODO: ignore boolean attributes in tag expression\n //TODO: if ignore attributes, dont read full attribute expression but the end. But read for xml declaration\n let attrBoundary = 0;\n const len = xmlData.length;\n const closeCode0 = closingChar.charCodeAt(0);\n const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;\n\n let result = '';\n let segmentStart = i;\n\n for (let index = i; index < len; index++) {\n const code = xmlData.charCodeAt(index);\n\n if (attrBoundary) {\n if (code === attrBoundary) attrBoundary = 0;\n } else if (code === 34 || code === 39) { // \" or '\n attrBoundary = code;\n } else if (code === closeCode0) {\n if (closeCode1 !== -1) {\n if (xmlData.charCodeAt(index + 1) === closeCode1) {\n result += xmlData.substring(segmentStart, index);\n return { data: result, index };\n }\n } else {\n result += xmlData.substring(segmentStart, index);\n return { data: result, index };\n }\n } else if (code === 9 && !attrBoundary) { // \\t - only replace with space outside attribute values\n // Flush accumulated segment, add space, start new segment\n result += xmlData.substring(segmentStart, index) + ' ';\n segmentStart = index + 1;\n }\n }\n}\n\nfunction findClosingIndex(xmlData, str, i, errMsg) {\n const closingIndex = xmlData.indexOf(str, i);\n if (closingIndex === -1) {\n throw new Error(errMsg)\n } else {\n return closingIndex + str.length - 1;\n }\n}\n\nfunction findClosingChar(xmlData, char, i, errMsg) {\n const closingIndex = xmlData.indexOf(char, i);\n if (closingIndex === -1) throw new Error(errMsg);\n return closingIndex; // no offset needed\n}\n\nfunction readTagExp(xmlData, i, removeNSPrefix, closingChar = \">\") {\n const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);\n if (!result) return;\n let tagExp = result.data;\n const closeIndex = result.index;\n const separatorIndex = tagExp.search(/\\s/);\n let tagName = tagExp;\n let attrExpPresent = true;\n if (separatorIndex !== -1) {//separate tag name and attributes expression\n tagName = tagExp.substring(0, separatorIndex);\n tagExp = tagExp.substring(separatorIndex + 1).trimStart();\n }\n\n const rawTagName = tagName;\n if (removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n attrExpPresent = tagName !== result.data.substr(colonIndex + 1);\n }\n }\n\n return {\n tagName: tagName,\n tagExp: tagExp,\n closeIndex: closeIndex,\n attrExpPresent: attrExpPresent,\n rawTagName: rawTagName,\n }\n}\n/**\n * find paired tag for a stop node\n * @param {string} xmlData \n * @param {string} tagName \n * @param {number} i \n */\nfunction readStopNodeData(xmlData, tagName, i) {\n const startIndex = i;\n // Starting at 1 since we already have an open tag\n let openTagCount = 1;\n\n const xmllen = xmlData.length;\n for (; i < xmllen; i++) {\n if (xmlData[i] === \"<\") {\n const c1 = xmlData.charCodeAt(i + 1);\n if (c1 === 47) {//close tag '/'\n const closeIndex = findClosingChar(xmlData, \">\", i, `${tagName} is not closed`);\n let closeTagName = xmlData.substring(i + 2, closeIndex).trim();\n if (closeTagName === tagName) {\n openTagCount--;\n if (openTagCount === 0) {\n return {\n tagContent: xmlData.substring(startIndex, i),\n i: closeIndex\n }\n }\n }\n i = closeIndex;\n } else if (c1 === 63) { //?\n const closeIndex = findClosingIndex(xmlData, \"?>\", i + 1, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 45\n && xmlData.charCodeAt(i + 3) === 45) { // '!--'\n const closeIndex = findClosingIndex(xmlData, \"-->\", i + 3, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 91) { // '!['\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"StopNode is not closed.\") - 2;\n i = closeIndex;\n } else {\n const tagData = readTagExp(xmlData, i, false)\n\n if (tagData) {\n const openTagName = tagData && tagData.tagName;\n if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== \"/\") {\n openTagCount++;\n }\n i = tagData.closeIndex;\n }\n }\n }\n }//end for loop\n}\n\nfunction parseValue(val, shouldParse, options) {\n if (shouldParse && typeof val === 'string') {\n //console.log(options)\n const newval = val.trim();\n if (newval === 'true') return true;\n else if (newval === 'false') return false;\n else return toNumber(val, options);\n } else {\n if (isExist(val)) {\n return val;\n } else {\n return '';\n }\n }\n}\n\nfunction fromCodePoint(str, base, prefix) {\n const codePoint = Number.parseInt(str, base);\n\n if (codePoint >= 0 && codePoint <= 0x10FFFF) {\n return String.fromCodePoint(codePoint);\n } else {\n return prefix + str + \";\";\n }\n}\n\nfunction transformTagName(fn, tagName, tagExp, options) {\n if (fn) {\n const newTagName = fn(tagName);\n if (tagExp === tagName) {\n tagExp = newTagName\n }\n tagName = newTagName;\n }\n tagName = sanitizeName(tagName, options);\n return { tagName, tagExp };\n}\n\n\n\nfunction sanitizeName(name, options) {\n if (criticalProperties.includes(name)) {\n throw new Error(`[SECURITY] Invalid name: \"${name}\" is a reserved JavaScript keyword that could cause prototype pollution`);\n } else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return options.onDangerousProperty(name);\n }\n return name;\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","'use strict';\n\nimport XmlNode from './xmlNode.js';\nimport { Matcher } from 'path-expression-matcher';\n\nconst METADATA_SYMBOL = XmlNode.getMetaDataSymbol();\n\n/**\n * Helper function to strip attribute prefix from attribute map\n * @param {object} attrs - Attributes with prefix (e.g., {\"@_class\": \"code\"})\n * @param {string} prefix - Attribute prefix to remove (e.g., \"@_\")\n * @returns {object} Attributes without prefix (e.g., {\"class\": \"code\"})\n */\nfunction stripAttributePrefix(attrs, prefix) {\n if (!attrs || typeof attrs !== 'object') return {};\n if (!prefix) return attrs;\n\n const rawAttrs = {};\n for (const key in attrs) {\n if (key.startsWith(prefix)) {\n const rawName = key.substring(prefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * \n * @param {array} node \n * @param {any} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns \n */\nexport default function prettify(node, options, matcher, readonlyMatcher) {\n return compress(node, options, matcher, readonlyMatcher);\n}\n\n/**\n * @param {array} arr \n * @param {object} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns object\n */\nfunction compress(arr, options, matcher, readonlyMatcher) {\n let text;\n const compressedObj = {}; //This is intended to be a plain object\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const property = propName(tagObj);\n\n // Push current property to matcher WITH RAW ATTRIBUTES (no prefix)\n if (property !== undefined && property !== options.textNodeName) {\n const rawAttrs = stripAttributePrefix(\n tagObj[\":@\"] || {},\n options.attributeNamePrefix\n );\n matcher.push(property, rawAttrs);\n }\n\n if (property === options.textNodeName) {\n if (text === undefined) text = tagObj[property];\n else text += \"\" + tagObj[property];\n } else if (property === undefined) {\n continue;\n } else if (tagObj[property]) {\n\n let val = compress(tagObj[property], options, matcher, readonlyMatcher);\n const isLeaf = isLeafTag(val, options);\n\n if (Object.keys(val).length === 0 && options.alwaysCreateTextNode) {\n val[options.textNodeName] = \"\";\n }\n\n if (tagObj[\":@\"]) {\n assignAttributes(val, tagObj[\":@\"], readonlyMatcher, options);\n } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {\n val = val[options.textNodeName];\n } else if (Object.keys(val).length === 0) {\n if (options.alwaysCreateTextNode) val[options.textNodeName] = \"\";\n else val = \"\";\n }\n\n if (tagObj[METADATA_SYMBOL] !== undefined && typeof val === \"object\" && val !== null) {\n val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL]; // copy over metadata\n }\n\n\n if (compressedObj[property] !== undefined && Object.prototype.hasOwnProperty.call(compressedObj, property)) {\n if (!Array.isArray(compressedObj[property])) {\n compressedObj[property] = [compressedObj[property]];\n }\n compressedObj[property].push(val);\n } else {\n //TODO: if a node is not an array, then check if it should be an array\n //also determine if it is a leaf node\n\n // Pass jPath string or readonlyMatcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher;\n if (options.isArray(property, jPathOrMatcher, isLeaf)) {\n compressedObj[property] = [val];\n } else {\n compressedObj[property] = val;\n }\n }\n\n // Pop property from matcher after processing\n if (property !== undefined && property !== options.textNodeName) {\n matcher.pop();\n }\n }\n\n }\n // if(text && text.length > 0) compressedObj[options.textNodeName] = text;\n if (typeof text === \"string\") {\n if (text.length > 0) compressedObj[options.textNodeName] = text;\n } else if (text !== undefined) compressedObj[options.textNodeName] = text;\n\n\n return compressedObj;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== \":@\") return key;\n }\n}\n\nfunction assignAttributes(obj, attrMap, readonlyMatcher, options) {\n if (attrMap) {\n const keys = Object.keys(attrMap);\n const len = keys.length; //don't make it inline\n for (let i = 0; i < len; i++) {\n const atrrName = keys[i]; // This is the PREFIXED name (e.g., \"@_class\")\n\n // Strip prefix for matcher path (for isArray callback)\n const rawAttrName = atrrName.startsWith(options.attributeNamePrefix)\n ? atrrName.substring(options.attributeNamePrefix.length)\n : atrrName;\n\n // For attributes, we need to create a temporary path\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath\n ? readonlyMatcher.toString() + \".\" + rawAttrName\n : readonlyMatcher;\n\n if (options.isArray(atrrName, jPathOrMatcher, true, true)) {\n obj[atrrName] = [attrMap[atrrName]];\n } else {\n obj[atrrName] = attrMap[atrrName];\n }\n }\n }\n}\n\nfunction isLeafTag(obj, options) {\n const { textNodeName } = options;\n const propCount = Object.keys(obj).length;\n\n if (propCount === 0) {\n return true;\n }\n\n if (\n propCount === 1 &&\n (obj[textNodeName] || typeof obj[textNodeName] === \"boolean\" || obj[textNodeName] === 0)\n ) {\n return true;\n }\n\n return false;\n}","/* global Uint8Array */\nimport { buildOptions } from './OptionsBuilder.js';\nimport OrderedObjParser from './OrderedObjParser.js';\nimport prettify from './node2json.js';\nimport { validate } from \"../validator.js\";\nimport XmlNode from './xmlNode.js';\n\nexport default class XMLParser {\n\n constructor(options) {\n this.externalEntities = {};\n this.options = buildOptions(options);\n\n }\n /**\n * Parse XML dats to JS object \n * @param {string|Uint8Array} xmlData \n * @param {boolean|Object} validationOption \n */\n parse(xmlData, validationOption) {\n if (typeof xmlData !== \"string\" && xmlData.toString) {\n if (xmlData instanceof Uint8Array &&\n !(typeof Buffer !== \"undefined\" && Buffer.isBuffer(xmlData))) {\n xmlData = new TextDecoder(\"utf-8\", { ignoreBOM: true }).decode(xmlData);\n } else {\n xmlData = xmlData.toString();\n }\n } else if (typeof xmlData !== \"string\") {\n throw new Error(\"XML data is accepted in String or Bytes[] form.\")\n }\n\n if (validationOption) {\n if (validationOption === true) validationOption = {}; //validate with default options\n\n const result = validate(xmlData, validationOption);\n if (result !== true) {\n throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`)\n }\n }\n const orderedObjParser = new OrderedObjParser(this.options, this.externalEntities);\n // orderedObjParser.entityDecoder.setExternalEntities(this.externalEntities);\n const orderedResult = orderedObjParser.parseXml(xmlData);\n if (this.options.preserveOrder || orderedResult === undefined) return orderedResult;\n else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);\n }\n\n /**\n * Add Entity which is not by default supported by this library\n * @param {string} key \n * @param {string} value \n */\n addEntity(key, value) {\n if (value.indexOf(\"&\") !== -1) {\n throw new Error(\"Entity value can't have '&'\")\n } else if (key.indexOf(\"&\") !== -1 || key.indexOf(\";\") !== -1) {\n throw new Error(\"An entity must be set without '&' and ';'. Eg. use '#xD' for ' '\")\n } else if (value === \"&\") {\n throw new Error(\"An entity with value '&' is not permitted\");\n } else {\n this.externalEntities[key] = value;\n }\n }\n\n /**\n * Returns a Symbol that can be used to access the metadata\n * property on a node.\n * \n * If Symbol is not available in the environment, an ordinary property is used\n * and the name of the property is here returned.\n * \n * The XMLMetaData property is only present when `captureMetaData`\n * is true in the options.\n */\n static getMetaDataSymbol() {\n return XmlNode.getMetaDataSymbol();\n }\n}","\n\nexport function safeComment(val) {\n return String(val)\n .replace(/--/g, '- -') // -- is illegal anywhere in comment content\n .replace(/--/g, '- -') // handle the scenario when 2 consiucative dashes appears \n .replace(/-$/, '- '); // trailing - would form -- with the closing -->\n}\n\nexport function safeCdata(val) {\n return String(val).replace(/\\]\\]>/g, ']]]]>')\n}\n\nexport function escapeAttribute(val) {\n return String(val).replace(/\"/g, '"').replace(/'/g, ''')\n}","/**\n * xml-naming\n * Validates XML Name productions as defined in the XML 1.0 and 1.1 specifications.\n * Covers: Name, NCName, QName, NMToken, NMTokens\n *\n * XML 1.0 spec: https://www.w3.org/TR/xml/#NT-Name\n * XML 1.1 spec: https://www.w3.org/TR/xml11/#NT-NameStartChar\n * XML NS spec: https://www.w3.org/TR/xml-names/#NT-NCName\n */\n\n// ---------------------------------------------------------------------------\n// Character class strings — XML 1.0\n//\n// NameStartChar ::= \":\" | [A-Z] | \"_\" | [a-z]\n// | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF]\n// | [#x370-#x37D] | [#x37F-#x1FFF] <- split to exclude #x0487\n// | [#x200C-#x200D]\n// | [#x2070-#x218F] | [#x2C00-#x2FEF]\n// | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD]\n//\n// NameChar ::= NameStartChar | \"-\" | \".\" | [0-9]\n// | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]\n//\n// Note: \\u0487 (Combining Cyrillic Millions Sign) was added in Unicode 4.0,\n// after XML 1.0 was defined against Unicode 2.0. It falls inside the range\n// \\u037F-\\u1FFF but must be excluded. We split that range into\n// \\u037F-\\u0486 and \\u0488-\\u1FFF to exclude it explicitly.\n// ---------------------------------------------------------------------------\n\nconst nameStartChar10 =\n ':A-Za-z_' +\n '\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF' +\n '\\u0370-\\u037D' +\n '\\u037F-\\u0486\\u0488-\\u1FFF' + // split to exclude \\u0487\n '\\u200C-\\u200D' +\n '\\u2070-\\u218F' +\n '\\u2C00-\\u2FEF' +\n '\\u3001-\\uD7FF' +\n '\\uF900-\\uFDCF' +\n '\\uFDF0-\\uFFFD';\n\nconst nameChar10 =\n nameStartChar10 +\n '\\\\-\\\\.\\\\d' +\n '\\u00B7' +\n '\\u0300-\\u036F' +\n '\\u203F-\\u2040';\n\n// ---------------------------------------------------------------------------\n// Character class strings — XML 1.1\n//\n// Differences from XML 1.0:\n//\n// NameStartChar:\n// 1.0 has split ranges: \\u00C0-\\u00D6, \\u00D8-\\u00F6, \\u00F8-\\u02FF\n// 1.1 merges them into: \\u00C0-\\u02FF\n// (\\u00D7 x and \\u00F7 / are division symbols, excluded in both versions)\n//\n// 1.0 tops out at \\uFFFD (BMP only)\n// 1.1 adds \\u{10000}-\\u{EFFFF} (supplementary planes)\n// These require the /u flag on the RegExp — see buildRegexes below.\n//\n// NameChar:\n// 1.1 adds \\u0487 (Combining Cyrillic Millions Sign, added in Unicode 4.0)\n// ---------------------------------------------------------------------------\n\nconst nameStartChar11 =\n ':A-Za-z_' +\n '\\u00C0-\\u02FF' + // merged — 1.0 had three split ranges here\n '\\u0370-\\u037D' +\n '\\u037F-\\u0486\\u0488-\\u1FFF' + // split to exclude \\u0487 (combining mark, never a NameStartChar)\n '\\u200C-\\u200D' +\n '\\u2070-\\u218F' +\n '\\u2C00-\\u2FEF' +\n '\\u3001-\\uD7FF' +\n '\\uF900-\\uFDCF' +\n '\\uFDF0-\\uFFFD' +\n '\\u{10000}-\\u{EFFFF}'; // supplementary planes — REQUIRES /u flag on RegExp\n\nconst nameChar11 =\n nameStartChar11 +\n '\\\\-\\\\.\\\\d' +\n '\\u00B7' +\n '\\u0300-\\u036F' +\n '\\u0487' + // Combining Cyrillic Millions Sign — valid in 1.1, not 1.0\n '\\u203F-\\u2040';\n\n// ---------------------------------------------------------------------------\n// Regex builders\n//\n// XML 1.0 regexes: no flags — BMP only, standard JS regex behaviour.\n// XML 1.1 regexes: /u flag — required for \\u{10000}-\\u{EFFFF} to match actual\n// supplementary code points rather than lone surrogates (which are illegal XML).\n// ---------------------------------------------------------------------------\n\nconst buildRegexes = (startChar, char, flags = '') => {\n const ncStart = startChar.replace(':', '');\n const ncChar = char.replace(':', '');\n const ncNamePat = `[${ncStart}][${ncChar}]*`;\n\n return {\n name: new RegExp(`^[${startChar}][${char}]*$`, flags),\n ncName: new RegExp(`^${ncNamePat}$`, flags),\n qName: new RegExp(`^${ncNamePat}(?::${ncNamePat})?$`, flags),\n nmToken: new RegExp(`^[${char}]+$`, flags),\n nmTokens: new RegExp(`^[${char}]+(?:\\\\s+[${char}]+)*$`, flags),\n };\n};\n\nconst regexes10 = buildRegexes(nameStartChar10, nameChar10); // no /u — BMP only\nconst regexes11 = buildRegexes(nameStartChar11, nameChar11, 'u'); // /u — enables \\u{10000}-\\u{EFFFF}\n\nconst getRegexes = (xmlVersion = '1.0') =>\n xmlVersion === '1.1' ? regexes11 : regexes10;\n\n// ---------------------------------------------------------------------------\n// Boolean validators\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if the string is a valid XML Name.\n * Colons are allowed anywhere (Name production).\n * Used for: DOCTYPE entity names, notation names, DTD element declarations.\n */\nexport const name = (str, { xmlVersion = '1.0' } = {}) =>\n getRegexes(xmlVersion).name.test(str);\n\n/**\n * Returns true if the string is a valid NCName (Non-Colonized Name).\n * Colons are not permitted.\n * Used for: namespace prefixes, local names, SVG id attributes.\n */\nexport const ncName = (str, { xmlVersion = '1.0' } = {}) =>\n getRegexes(xmlVersion).ncName.test(str);\n\n/**\n * Returns true if the string is a valid QName (Qualified Name).\n * Allows exactly one colon as a prefix separator: prefix:localName.\n * Used for: element and attribute names in namespace-aware XML/SVG.\n */\nexport const qName = (str, { xmlVersion = '1.0' } = {}) =>\n getRegexes(xmlVersion).qName.test(str);\n\n/**\n * Returns true if the string is a valid NMToken.\n * Like Name but no restriction on the first character.\n * Used for: DTD NMTOKEN attribute values.\n */\nexport const nmToken = (str, { xmlVersion = '1.0' } = {}) =>\n getRegexes(xmlVersion).nmToken.test(str);\n\n/**\n * Returns true if the string is a valid NMTokens value.\n * A whitespace-separated list of NMToken values.\n * Used for: DTD NMTOKENS attribute values.\n */\nexport const nmTokens = (str, { xmlVersion = '1.0' } = {}) =>\n getRegexes(xmlVersion).nmTokens.test(str);\n\n// ---------------------------------------------------------------------------\n// Diagnostic validator\n// ---------------------------------------------------------------------------\n\nconst PRODUCTIONS = ['name', 'ncName', 'qName', 'nmToken', 'nmTokens'];\n\n/**\n * Validates a string against a named production and returns a detailed result.\n *\n * @param {string} str\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1' }} [opts]\n * @returns {{ valid: boolean, production: string, input: string, reason?: string, position?: number }}\n */\nexport const validate = (str, production, { xmlVersion = '1.0' } = {}) => {\n if (!PRODUCTIONS.includes(production)) {\n throw new TypeError(\n `Unknown production \"${production}\". Must be one of: ${PRODUCTIONS.join(', ')}`\n );\n }\n\n const validators = { name, ncName, qName, nmToken, nmTokens };\n const isValid = validators[production](str, { xmlVersion });\n\n if (isValid) return { valid: true, production, input: str };\n\n let reason = 'Does not match the production rules';\n let position;\n\n if (str.length === 0) {\n reason = 'Input is empty';\n } else if (production === 'ncName' && str.includes(':')) {\n position = str.indexOf(':');\n reason = 'Colon is not allowed in NCName';\n } else if (production === 'qName' && str.startsWith(':')) {\n reason = 'QName cannot start with a colon';\n position = 0;\n } else if (production === 'qName' && str.endsWith(':')) {\n reason = 'QName cannot end with a colon';\n position = str.length - 1;\n } else if (production === 'qName' && (str.match(/:/g) || []).length > 1) {\n reason = 'QName can have at most one colon';\n position = str.lastIndexOf(':');\n } else if (\n ['name', 'ncName', 'qName'].includes(production) &&\n !/^[:A-Za-z_\\u00C0-\\uFFFD]/.test(str[0])\n ) {\n reason = `First character \"${str[0]}\" is not a valid NameStartChar`;\n position = 0;\n } else {\n for (let i = 0; i < str.length; i++) {\n if (!/[\\w\\-\\\\.:\\u00B7\\u00C0-\\uFFFD]/.test(str[i])) {\n reason = `Character \"${str[i]}\" at position ${i} is not a valid NameChar`;\n position = i;\n break;\n }\n }\n }\n\n return { valid: false, production, input: str, reason, position };\n};\n\n// ---------------------------------------------------------------------------\n// Batch validator\n// ---------------------------------------------------------------------------\n\n/**\n * Validates an array of strings against a named production.\n *\n * @param {string[]} strings\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1' }} [opts]\n * @returns {Array<{ valid: boolean, production: string, input: string, reason?: string, position?: number }>}\n */\nexport const validateAll = (strings, production, opts = {}) =>\n strings.map(str => validate(str, production, opts));\n\n// ---------------------------------------------------------------------------\n// Sanitizer\n// ---------------------------------------------------------------------------\n\n/**\n * Transforms an invalid string into the nearest valid XML name for the given production.\n *\n * @param {string} str\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ replacement?: string }} [opts]\n * @returns {string}\n */\nexport const sanitize = (str, production = 'name', { replacement = '_' } = {}) => {\n if (!str) return replacement;\n\n let result = str;\n\n // Strip colons for NCName\n if (production === 'ncName') {\n result = result.replace(/:/g, '');\n }\n\n // Replace illegal characters\n result = result.replace(/[^\\w\\-\\.:\\u00B7\\u00C0-\\uFFFD]/g, replacement);\n\n // Fix invalid start character for Name / NCName / QName\n if (production !== 'nmToken' && production !== 'nmTokens') {\n if (/^[\\-\\.\\d]/.test(result)) {\n result = replacement + result;\n }\n }\n\n return result || replacement;\n};","import { Expression, Matcher } from 'path-expression-matcher';\nimport { safeComment, safeCdata, escapeAttribute } from \"./util.js\";\nimport { qName } from 'xml-naming';\n\nconst EOL = \"\\n\";\n\n/**\n * Detect XML version from the first element of the ordered array input.\n * The first element must be a ?xml processing instruction with a version attribute.\n * Returns '1.0' if not found.\n *\n * @param {array} jArray\n * @param {object} options\n */\nfunction detectXmlVersionFromArray(jArray, options) {\n if (!Array.isArray(jArray) || jArray.length === 0) return '1.0';\n const first = jArray[0];\n const firstKey = propName(first);\n if (firstKey === '?xml') {\n const attrs = first[':@'];\n if (attrs) {\n const versionKey = options.attributeNamePrefix + 'version';\n if (attrs[versionKey]) return attrs[versionKey];\n }\n }\n return '1.0';\n}\n\n/**\n * Resolve a tag or attribute name through sanitizeName if configured.\n * Validation via xml-naming's qName is performed first; the sanitizeName\n * callback is invoked only when the name is invalid. If sanitizeName is\n * false (default), no validation occurs and the name is used as-is.\n *\n * @param {string} name - raw name from the JS object\n * @param {boolean} isAttribute - true when resolving an attribute name\n * @param {object} options\n * @param {Matcher} matcher - current matcher state (readonly from callback perspective)\n * @param {string} xmlVersion - '1.0' or '1.1', forwarded to xml-naming\n */\nfunction resolveTagName(name, isAttribute, options, matcher, xmlVersion) {\n if (!options.sanitizeName) return name;\n if (qName(name, { xmlVersion })) return name;\n return options.sanitizeName(name, { isAttribute, matcher: matcher.readOnly() });\n}\n\n/**\n * @param {array} jArray\n * @param {any} options\n * @returns\n */\nexport default function toXml(jArray, options) {\n let indentation = \"\";\n if (options.format) {\n indentation = EOL;\n }\n\n // Pre-compile stopNode expressions for pattern matching\n const stopNodeExpressions = [];\n if (options.stopNodes && Array.isArray(options.stopNodes)) {\n for (let i = 0; i < options.stopNodes.length; i++) {\n const node = options.stopNodes[i];\n if (typeof node === 'string') {\n stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n stopNodeExpressions.push(node);\n }\n }\n }\n\n // Detect XML version for use in name validation\n const xmlVersion = detectXmlVersionFromArray(jArray, options);\n\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n\n return arrToStr(jArray, options, indentation, matcher, stopNodeExpressions, xmlVersion);\n}\n\nfunction arrToStr(arr, options, indentation, matcher, stopNodeExpressions, xmlVersion) {\n let xmlStr = \"\";\n let isPreviousElementTag = false;\n\n if (options.maxNestedTags && matcher.getDepth() > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n\n if (!Array.isArray(arr)) {\n // Non-array values (e.g. string tag values) should be treated as text content\n if (arr !== undefined && arr !== null) {\n let text = arr.toString();\n text = replaceEntitiesValue(text, options);\n return text;\n }\n return \"\";\n }\n\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const rawTagName = propName(tagObj);\n if (rawTagName === undefined) continue;\n\n // Special names are exempt from sanitizeName: internal conventions and PI tags\n // are not user-supplied XML element names.\n const isSpecialName = rawTagName === options.textNodeName\n || rawTagName === options.cdataPropName\n || rawTagName === options.commentPropName\n || rawTagName[0] === '?';\n\n // Resolve tag name (may transform it; may throw for invalid names)\n const tagName = isSpecialName\n ? rawTagName\n : resolveTagName(rawTagName, false, options, matcher, xmlVersion);\n\n // Extract attributes from \":@\" property\n const attrValues = extractAttributeValues(tagObj[\":@\"], options);\n\n // Push resolved tag to matcher WITH attributes\n matcher.push(tagName, attrValues);\n\n // Check if this is a stop node using Expression matching\n const isStopNode = checkStopNode(matcher, stopNodeExpressions);\n\n if (tagName === options.textNodeName) {\n let tagText = tagObj[rawTagName];\n if (!isStopNode) {\n tagText = options.tagValueProcessor(tagName, tagText);\n tagText = replaceEntitiesValue(tagText, options);\n }\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n xmlStr += tagText;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.cdataPropName) {\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n const val = tagObj[rawTagName][0][options.textNodeName];\n const safeVal = safeCdata(val);\n xmlStr += ``;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.commentPropName) {\n const val = tagObj[rawTagName][0][options.textNodeName];\n const safeVal = safeComment(val);\n xmlStr += indentation + ``;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n } else if (tagName[0] === \"?\") {\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode, matcher, xmlVersion);\n const tempInd = tagName === \"?xml\" ? \"\" : indentation;\n // Text node content on PI/XML declaration tags is intentionally ignored.\n // Only attributes are valid on these tags per the XML spec.\n xmlStr += tempInd + `<${tagName}${attStr}?>`;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n }\n\n let newIdentation = indentation;\n if (newIdentation !== \"\") {\n newIdentation += options.indentBy;\n }\n\n // Pass isStopNode to attr_to_str so attributes are also not processed for stopNodes\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode, matcher, xmlVersion);\n const tagStart = indentation + `<${tagName}${attStr}`;\n\n // If this is a stopNode, get raw content without processing\n let tagValue;\n if (isStopNode) {\n tagValue = getRawContent(tagObj[rawTagName], options);\n } else {\n tagValue = arrToStr(tagObj[rawTagName], options, newIdentation, matcher, stopNodeExpressions, xmlVersion);\n }\n\n if (options.unpairedTags.indexOf(tagName) !== -1) {\n if (options.suppressUnpairedNode) xmlStr += tagStart + \">\";\n else xmlStr += tagStart + \"/>\";\n } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) {\n xmlStr += tagStart + \"/>\";\n } else if (tagValue && tagValue.endsWith(\">\")) {\n xmlStr += tagStart + `>${tagValue}${indentation}`;\n } else {\n xmlStr += tagStart + \">\";\n if (tagValue && indentation !== \"\" && (tagValue.includes(\"/>\") || tagValue.includes(\"`;\n }\n isPreviousElementTag = true;\n\n // Pop tag from matcher\n matcher.pop();\n }\n\n return xmlStr;\n}\n\n/**\n * Extract attribute values from the \":@\" object and return as plain object\n * for passing to matcher.push()\n */\nfunction extractAttributeValues(attrMap, options) {\n if (!attrMap || options.ignoreAttributes) return null;\n\n const attrValues = {};\n let hasAttrs = false;\n\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // Remove the attribute prefix to get clean attribute name\n const cleanAttrName = attr.startsWith(options.attributeNamePrefix)\n ? attr.substr(options.attributeNamePrefix.length)\n : attr;\n attrValues[cleanAttrName] = escapeAttribute(attrMap[attr]);\n hasAttrs = true;\n }\n\n return hasAttrs ? attrValues : null;\n}\n\n/**\n * Extract raw content from a stopNode without any processing\n * This preserves the content exactly as-is, including special characters\n */\nfunction getRawContent(arr, options) {\n if (!Array.isArray(arr)) {\n // Non-array values return as-is\n if (arr !== undefined && arr !== null) {\n return arr.toString();\n }\n return \"\";\n }\n\n let content = \"\";\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n const tagName = propName(item);\n\n if (tagName === options.textNodeName) {\n // Raw text content - NO processing, NO entity replacement\n content += item[tagName];\n } else if (tagName === options.cdataPropName) {\n // CDATA content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName === options.commentPropName) {\n // Comment content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName && tagName[0] === \"?\") {\n // Processing instruction - skip for stopNodes\n continue;\n } else if (tagName) {\n // Nested tags within stopNode — no sanitizeName, content is raw\n const attStr = attr_to_str_raw(item[\":@\"], options);\n const nestedContent = getRawContent(item[tagName], options);\n\n if (!nestedContent || nestedContent.length === 0) {\n content += `<${tagName}${attStr}/>`;\n } else {\n content += `<${tagName}${attStr}>${nestedContent}`;\n }\n }\n }\n return content;\n}\n\n/**\n * Build attribute string for stopNodes - NO entity replacement\n */\nfunction attr_to_str_raw(attrMap, options) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // For stopNodes, use raw value without processing\n let attrVal = attrMap[attr];\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${escapeAttribute(attrVal)}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n if (key !== \":@\") return key;\n }\n}\n\n/**\n * Build attribute string, resolving attribute names through sanitizeName when configured.\n * Accepts matcher so the callback has path context.\n */\nfunction attr_to_str(attrMap, options, isStopNode, matcher, xmlVersion) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n\n // Strip prefix to get the clean XML attribute name, then optionally sanitize it\n const cleanAttrName = attr.substr(options.attributeNamePrefix.length);\n const resolvedAttrName = isStopNode\n ? cleanAttrName // stopNodes are raw — skip sanitizeName for attr names too\n : resolveTagName(cleanAttrName, true, options, matcher, xmlVersion);\n\n let attrVal;\n if (isStopNode) {\n // For stopNodes, use raw value without any processing\n attrVal = attrMap[attr];\n } else {\n // Normal processing: apply attributeValueProcessor and entity replacement\n attrVal = options.attributeValueProcessor(attr, attrMap[attr]);\n attrVal = replaceEntitiesValue(attrVal, options);\n }\n\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${resolvedAttrName}`;\n } else {\n attrStr += ` ${resolvedAttrName}=\"${escapeAttribute(attrVal)}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction checkStopNode(matcher, stopNodeExpressions) {\n if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;\n\n for (let i = 0; i < stopNodeExpressions.length; i++) {\n if (matcher.matches(stopNodeExpressions[i])) {\n return true;\n }\n }\n return false;\n}\n\nfunction replaceEntitiesValue(textValue, options) {\n if (textValue && textValue.length > 0 && options.processEntities) {\n for (let i = 0; i < options.entities.length; i++) {\n const entity = options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}","'use strict';\n//parse Empty Node as self closing node\nimport buildFromOrderedJs from './orderedJs2Xml.js';\nimport getIgnoreAttributesFn from \"./ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\nimport { safeComment, safeCdata, escapeAttribute } from './util.js';\nimport { qName } from 'xml-naming';\n\nconst defaultOptions = {\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n cdataPropName: false,\n format: false,\n indentBy: ' ',\n suppressEmptyNode: false,\n suppressUnpairedNode: true,\n suppressBooleanAttributes: true,\n tagValueProcessor: function (key, a) {\n return a;\n },\n attributeValueProcessor: function (attrName, a) {\n return a;\n },\n preserveOrder: false,\n commentPropName: false,\n unpairedTags: [],\n entities: [\n { regex: new RegExp(\"&\", \"g\"), val: \"&\" },//it must be on top\n { regex: new RegExp(\">\", \"g\"), val: \">\" },\n { regex: new RegExp(\"<\", \"g\"), val: \"<\" },\n { regex: new RegExp(\"\\'\", \"g\"), val: \"'\" },\n { regex: new RegExp(\"\\\"\", \"g\"), val: \""\" }\n ],\n processEntities: true,\n stopNodes: [],\n // transformTagName: false,\n // transformAttributeName: false,\n oneListGroup: false,\n maxNestedTags: 100,\n jPath: true, // When true, callbacks receive string jPath; when false, receive Matcher instance\n sanitizeName: false // false = allow all names as-is (default, backward-compatible).\n // Set to a function (name, { isAttribute, matcher }) => string to\n // validate/sanitize tag and attribute names. Throw inside the function\n // to reject an invalid name.\n};\n\nexport default function Builder(options) {\n this.options = Object.assign({}, defaultOptions, options);\n\n // Convert old-style stopNodes for backward compatibility\n // Old syntax: \"*.tag\" meant \"tag anywhere in tree\"\n // New syntax: \"..tag\" means \"tag anywhere in tree\"\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n this.options.stopNodes = this.options.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Convert old wildcard syntax to deep wildcard\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n\n // Pre-compile stopNode expressions for pattern matching\n this.stopNodeExpressions = [];\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n for (let i = 0; i < this.options.stopNodes.length; i++) {\n const node = this.options.stopNodes[i];\n if (typeof node === 'string') {\n this.stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n this.stopNodeExpressions.push(node);\n }\n }\n }\n\n if (this.options.ignoreAttributes === true || this.options.attributesGroupName) {\n this.isAttribute = function (/*a*/) {\n return false;\n };\n } else {\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.attrPrefixLen = this.options.attributeNamePrefix.length;\n this.isAttribute = isAttribute;\n }\n\n this.processTextOrObjNode = processTextOrObjNode\n\n if (this.options.format) {\n this.indentate = indentate;\n this.tagEndChar = '>\\n';\n this.newLine = '\\n';\n } else {\n this.indentate = function () {\n return '';\n };\n this.tagEndChar = '>';\n this.newLine = '';\n }\n}\n\n/**\n * Detect XML version from the ?xml declaration at the root of a plain-object input.\n * Checks both attributesGroupName and flat attribute forms.\n * Returns '1.0' if no declaration is found.\n */\nfunction detectXmlVersionFromObj(jObj, options) {\n const decl = jObj['?xml'];\n if (decl && typeof decl === 'object') {\n // attributesGroupName path e.g. { '$$': { '@_version': '1.1' } }\n if (options.attributesGroupName && decl[options.attributesGroupName]) {\n const v = decl[options.attributesGroupName][options.attributeNamePrefix + 'version'];\n if (v) return v;\n }\n // flat attribute path e.g. { '@_version': '1.1' }\n const v = decl[options.attributeNamePrefix + 'version'];\n if (v) return v;\n }\n return '1.0';\n}\n\n/**\n * Resolve a tag or attribute name through sanitizeName if configured.\n * Validation via xml-naming's qName is performed first; the sanitizeName\n * callback is invoked only when the name is invalid. If sanitizeName is\n * false (default), no validation occurs and the name is used as-is.\n *\n * @param {string} name - raw name from the JS object\n * @param {boolean} isAttribute - true when resolving an attribute name\n * @param {object} options\n * @param {Matcher} matcher - current matcher state (readonly from callback perspective)\n * @param {string} xmlVersion - '1.0' or '1.1', forwarded to xml-naming\n */\nfunction resolveTagName(name, isAttribute, options, matcher, xmlVersion) {\n if (!options.sanitizeName) return name;\n if (qName(name, { xmlVersion })) return name;\n return options.sanitizeName(name, { isAttribute, matcher: matcher.readOnly() });\n}\n\nBuilder.prototype.build = function (jObj) {\n if (this.options.preserveOrder) {\n return buildFromOrderedJs(jObj, this.options);\n } else {\n if (Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1) {\n jObj = {\n [this.options.arrayNodeName]: jObj\n }\n }\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n const xmlVersion = detectXmlVersionFromObj(jObj, this.options);\n return this.j2x(jObj, 0, matcher, xmlVersion).val;\n }\n};\n\nBuilder.prototype.j2x = function (jObj, level, matcher, xmlVersion) {\n let attrStr = '';\n let val = '';\n if (this.options.maxNestedTags && matcher.getDepth() >= this.options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n // Get jPath based on option: string for backward compatibility, or Matcher for new features\n const jPath = this.options.jPath ? matcher.toString() : matcher;\n\n // Check if current node is a stopNode (will be used for attribute encoding)\n const isCurrentStopNode = this.checkStopNode(matcher);\n\n for (let key in jObj) {\n if (!Object.prototype.hasOwnProperty.call(jObj, key)) continue;\n\n // Resolve the key through sanitizeName before any use.\n // Special keys (textNodeName, cdataPropName, commentPropName, attributeNamePrefix,\n // attributesGroupName, \"?\" PI tags) are exempt — they are builder-internal conventions,\n // not user-supplied XML names.\n const isSpecialKey = key === this.options.textNodeName\n || key === this.options.cdataPropName\n || key === this.options.commentPropName\n || (this.options.attributesGroupName && key === this.options.attributesGroupName)\n || this.isAttribute(key)\n || key[0] === '?';\n\n const resolvedKey = isSpecialKey\n ? key\n : resolveTagName(key, false, this.options, matcher, xmlVersion);\n\n if (typeof jObj[key] === 'undefined') {\n // supress undefined node only if it is not an attribute\n if (this.isAttribute(key)) {\n val += '';\n }\n } else if (jObj[key] === null) {\n // null attribute should be ignored by the attribute list, but should not cause the tag closing\n if (this.isAttribute(key)) {\n val += '';\n } else if (resolvedKey === this.options.cdataPropName || resolvedKey === this.options.commentPropName) {\n val += '';\n } else if (resolvedKey[0] === '?') {\n val += this.indentate(level) + '<' + resolvedKey + '?' + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + resolvedKey + '/' + this.tagEndChar;\n }\n } else if (jObj[key] instanceof Date) {\n val += this.buildTextValNode(jObj[key], resolvedKey, '', level, matcher);\n } else if (typeof jObj[key] !== 'object') {\n //premitive type\n const attr = this.isAttribute(key);\n if (attr && !this.ignoreAttributesFn(attr, jPath)) {\n // Resolve the attribute name through sanitizeName\n const resolvedAttr = resolveTagName(attr, true, this.options, matcher, xmlVersion);\n attrStr += this.buildAttrPairStr(resolvedAttr, '' + jObj[key], isCurrentStopNode);\n } else if (!attr) {\n //tag value\n if (key === this.options.textNodeName) {\n let newval = this.options.tagValueProcessor(key, '' + jObj[key]);\n val += this.replaceEntitiesValue(newval);\n } else {\n // Check if this is a stopNode before building\n matcher.push(resolvedKey);\n const isStopNode = this.checkStopNode(matcher);\n matcher.pop();\n\n if (isStopNode) {\n // Build as raw content without encoding\n const textValue = '' + jObj[key];\n if (textValue === '') {\n val += this.indentate(level) + '<' + resolvedKey + this.closeTag(resolvedKey) + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + resolvedKey + '>' + textValue + '' + textValue + '${item}`;\n } else if (typeof item === 'object' && item !== null) {\n const nestedContent = this.buildRawContent(item);\n const nestedAttrs = this.buildAttributesForStopNode(item);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n }\n }\n } else if (typeof value === 'object' && value !== null) {\n // Nested object\n const nestedContent = this.buildRawContent(value);\n const nestedAttrs = this.buildAttributesForStopNode(value);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n } else {\n // Primitive value\n content += `<${key}>${value}`;\n }\n }\n\n return content;\n};\n\n// Build attribute string for stopNode (no entity encoding)\nBuilder.prototype.buildAttributesForStopNode = function (obj) {\n if (!obj || typeof obj !== 'object') return '';\n\n let attrStr = '';\n\n // Check for attributesGroupName (when attributes are grouped)\n if (this.options.attributesGroupName && obj[this.options.attributesGroupName]) {\n const attrGroup = obj[this.options.attributesGroupName];\n for (let attrKey in attrGroup) {\n if (!Object.prototype.hasOwnProperty.call(attrGroup, attrKey)) continue;\n const cleanKey = attrKey.startsWith(this.options.attributeNamePrefix)\n ? attrKey.substring(this.options.attributeNamePrefix.length)\n : attrKey;\n const val = attrGroup[attrKey];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + cleanKey;\n } else {\n attrStr += ' ' + cleanKey + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n } else {\n // Look for individual attributes\n for (let key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n const attr = this.isAttribute(key);\n if (attr) {\n const val = obj[key];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + attr;\n } else {\n attrStr += ' ' + attr + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n }\n }\n\n return attrStr;\n};\n\nBuilder.prototype.buildObjectNode = function (val, key, attrStr, level) {\n if (val === \"\") {\n if (key[0] === \"?\") return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n else {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n }\n } else if (key[0] === \"?\") {\n // PI/XML-declaration tags never have body content — treat them like empty.\n return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n } else {\n let tagEndExp = '' + val + tagEndExp);\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) {\n return this.indentate(level) + `` + this.newLine;\n } else {\n return (\n this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar +\n val +\n this.indentate(level) + tagEndExp);\n }\n }\n}\n\nBuilder.prototype.closeTag = function (key) {\n let closeTag = \"\";\n if (this.options.unpairedTags.indexOf(key) !== -1) { //unpaired\n if (!this.options.suppressUnpairedNode) closeTag = \"/\"\n } else if (this.options.suppressEmptyNode) { //empty\n closeTag = \"/\";\n } else {\n closeTag = `>` + this.newLine;\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName) {\n const safeVal = safeComment(val);\n return this.indentate(level) + `` + this.newLine;\n } else if (key[0] === \"?\") {//PI tag\n return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n } else {\n // Normal processing: apply tagValueProcessor and entity replacement\n let textValue = this.options.tagValueProcessor(key, val);\n textValue = this.replaceEntitiesValue(textValue);\n\n if (textValue === '') {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n } else {\n return this.indentate(level) + '<' + key + attrStr + '>' +\n textValue +\n ' 0 && this.options.processEntities) {\n for (let i = 0; i < this.options.entities.length; i++) {\n const entity = this.options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}\n\nfunction indentate(level) {\n return this.options.indentBy.repeat(level);\n}\n\nfunction isAttribute(name /*, options*/) {\n if (name.startsWith(this.options.attributeNamePrefix) && name !== this.options.textNodeName) {\n return name.substr(this.attrPrefixLen);\n } else {\n return false;\n }\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","// Re-export from fast-xml-builder for backward compatibility\nimport XMLBuilder from 'fast-xml-builder';\nexport default XMLBuilder;\n\n// If there are any named exports you also want to re-export:\nexport * from 'fast-xml-builder';","'use strict';\n\nimport { validate } from './validator.js';\nimport XMLParser from './xmlparser/XMLParser.js';\nimport XMLBuilder from './xmlbuilder/json2xml.js';\n\nconst XMLValidator = {\n validate: validate\n}\nexport {\n XMLParser,\n XMLValidator,\n XMLBuilder\n};"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","nameStartChar","regexName","RegExp","isName","string","exec","DANGEROUS_PROPERTY_NAMES","criticalProperties","defaultOptions","allowBooleanAttributes","unpairedTags","validate","xmlData","options","assign","tags","tagFound","reachedRoot","substr","i","length","readPI","err","isWhiteSpace","getErrorObject","getLineNumberForPosition","tagStartPos","readCommentAndCDATA","closingTag","tagName","trim","substring","validateTagName","result","readAttributeStr","attrStr","index","attrStrStart","isValid","validateAttributeString","code","msg","line","tagClosed","otg","pop","openPos","col","indexOf","push","afterAmp","validateAmpersand","JSON","stringify","map","t","replace","char","start","tagname","angleBracketsCount","doubleQuote","singleQuote","startChar","matches","tokens","len","tokenStart","leadingWs","slice","nameStart","name","equalsGroup","j","quoteChar","k","valueStart","closeIdx","token","startIndex","undefined","scanAttributeTokens","attrNames","getPositionFromMatch","attrName","validateAttrName","re","match","validateNumberAmpersand","count","message","lineNumber","lines","split","defaultOnDangerousProperty","includes","preserveOrder","attributeNamePrefix","attributesGroupName","textNodeName","ignoreAttributes","removeNSPrefix","parseTagValue","parseAttributeValue","trimValues","cdataPropName","numberParseOptions","hex","leadingZeros","eNotation","unicode","tagValueProcessor","val","attributeValueProcessor","stopNodes","alwaysCreateTextNode","isArray","commentPropName","processEntities","htmlEntities","entityDecoder","ignoreDeclaration","ignorePiTags","transformTagName","transformAttributeName","updateTag","jPath","attrs","captureMetaData","maxNestedTags","strictReservedNames","onDangerousProperty","validatePropertyName","propertyName","optionName","normalized","toLowerCase","some","dangerous","Error","normalizeProcessEntities","enabled","maxEntitySize","maxExpansionDepth","maxTotalExpansions","Infinity","maxExpandedLength","maxEntityCount","allowedTags","tagFilter","appliesTo","Math","max","_value$maxEntitySize","_value$maxExpansionDe","_value$maxTotalExpans","_value$maxExpandedLen","_value$maxEntityCount","_value$allowedTags","_value$tagFilter","_value$appliesTo","METADATA_SYMBOL","buildOptions","built","_i","_propertyNameOptions","_propertyNameOptions$","unpairedTagsSet","Set","Array","node","startsWith","XmlNode","child","create","_proto","add","_this$child$push","addChild","_this$child$push2","_this$child$push3","keys","addStartIndex","addEndIndex","endIndex","lastChild","getMetaDataSymbol","nameStartChar10","nameStartChar11","nameChar11","buildRegexes","flags","ncNamePat","ncName","qName","nmToken","nmTokens","regexes10","regexes11","nameStartCharAscii","regexesAscii","str","xmlVersion","asciiOnly","getRegexes","test","DocTypeReader","suppressValidationErr","setXmlVersion","readDocType","entities","entityCount","hasBody","comment","hasSeq","entityName","_this$readEntityExp","readEntityExp","readElementExp","readNotationExp","skipWhitespace","validateEntityName","toUpperCase","entityValue","_this$readIdentifierV","readIdentifierVal","notationName","identifierType","publicIdentifier","systemIdentifier","_this$readIdentifierV2","_this$readIdentifierV3","_this$readIdentifierV4","type","identifierVal","elementName","contentModel","readAttlistExp","attributeName","attributeType","allowedNotations","notation","join","defaultValue","_this$readIdentifierV5","data","seq","SCRIPT_ZEROS","HIGH_MAP","Map","TABLE_OFFSET","TABLE","Uint8Array","LOW_MAX","fill","zero","d","cp","set","MINUS_SET","hexRegex","binRegex","octRegex","numRegex","consider","binary","octal","decimalPoint","infinity","toNumber","trimmedStr","skipLike","firstHit","cc","charCodeAt","has","low","chars","String","fromCharCode","anynum","parse_int","isFinite","eNotationRegx","sign","eChar","eAdjacentToLeadingZeros","Number","resolveEnotation","numTrimmedByZeros","numStr","end","trimZeros","decimalAdjacentToLeadingZeros","num","parsedStr","search","n","isPositive","handleInfinity","base","parseInt","window","MatcherView","constructor","matcher","_matcher","separator","getCurrentTag","path","tag","getCurrentNamespace","namespace","getAttrValue","values","hasAttr","current","getAnyParentAttr","hasAnyParentAttr","getPosition","position","getCounter","counter","getIndex","getDepth","toString","includeNamespace","toArray","expression","matchesAny","exprSet","Matcher","siblingStacks","_pathStringCache","_view","_keptAttrs","attrValues","currentLevel","level","counts","total","siblingKey","depth","keep","poppedDepth","updateCurrent","kept","sep","reset","segments","hasDeepWildcard","_matchWithDeepWildcard","_matchSimple","_matchSegment","pathIdx","segIdx","segment","nextSeg","found","isCurrentNode","attrValue","positionValue","snapshot","keptAttrs","entry","restore","readOnly","Expression","pattern","_parse","_hasDeepWildcard","seg","_hasAttributeCondition","_hasPositionSelector","currentPart","_parseSegment","part","bracketContent","withoutBrackets","bracketMatch","content","tagAndPosition","nsIndex","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","eqIndex","nthMatch","hasAttributeCondition","hasPositionSelector","ExpressionSet","_byDepthAndTag","_wildcardByDepth","_deepWildcards","_deepByTerminalTag","_patterns","_sealed","TypeError","lastSeg","addAll","expressions","expr","size","seal","isSealed","findMatch","exactKey","exactBucket","wildcardBucket","deepBucket","CURRENCY","cent","pound","curren","yen","euro","dollar","fnof","inr","af","birr","peso","rub","won","yuan","cedil","XML","amp","apos","gt","lt","quot","COMMON_HTML","nbsp","copy","reg","trade","mdash","ndash","hellip","laquo","raquo","lsquo","rsquo","ldquo","rdquo","bull","para","sect","deg","frac12","frac14","frac34","ENTITY_ACTION","freeze","ALLOW","BLOCK","THROW","SPECIAL_CHARS","ch","mergeEntityMaps","maps","out","raw","LIMIT_TIER_EXTERNAL","LIMIT_TIER_BASE","LIMIT_TIER_ALL","NCR_LEVEL","allow","leave","remove","throw","XML10_ALLOWED_C0","EntityDecoder","_limit","limit","_maxTotalExpansions","_maxExpandedLength","_postCheck","postCheck","r","_limitTiers","applyLimitsTo","_numericAllowed","numericAllowed","_baseMap","DEFAULT_XML_ENTITIES","namedEntities","_externalMap","_inputMap","_totalExpansions","_expandedLength","_removeSet","_leaveSet","ncrCfg","ncr","onLevel","nullLevel","onNCR","nullNCR","parseNCRConfig","_ncrXmlVersion","_ncrOnLevel","_ncrNullLevel","_onExternalEntity","onExternalEntity","_onInputEntity","onInputEntity","_applyRegistrationHook","hook","context","action","setExternalEntities","flat","filtered","entries","addExternalEntity","addInputEntities","version","decode","original","chunks","last","limitExpansions","limitLength","checkLimits","replacement","tier","ncrResult","_resolveNCR","resolved","_resolveName","_tierCounts","delta","_classifyNCR","_applyNCRAction","fromCodePoint","padStart","second","isNaN","minimum","effective","id","description","SQL_PATTERNS","matchList","list","label","rule","isUnsafe","assertString","assertContext","lists","regex","normalise","_extends","bind","e","arguments","apply","extractRawAttributes","prefixedAttrs","rawAttrs","extractNamespace","rawTagName","ns","HTML","SVG","SQL","SQL_STRICT","SHELL","REDOS","NOSQL","LOG","OrderedObjParser","externalEntities","currentNode","tagsNodeStack","parseXml","parseTextData","resolveNameSpace","buildAttributesMap","isItStopNode","replaceEntitiesValue","readStopNodeData","saveTextToParentTag","ignoreAttributesFn","_step","_iterator","_createForOfIteratorHelperLoose","done","entityExpansionCount","currentExpandedLength","doctypefound","HTML_CONTEXT","XML_CONTEXT","readonlyMatcher","isCurrentNodeStopNode","stopNodeExpressionsSet","stopNodesOpts","stopNodeExp","dontTrim","hasAttributes","isLeafNode","escapeEntities","jPathOrMatcher","newval","parseValue","prefix","charAt","attrsRegx","force","allmatches","lastIndex","getAllMatches","processedVals","hasRawAttrs","rawAttrsForMatcher","oldVal","jPathStr","hasAttrs","aName","sanitizeName","newVal","attrCollection","xmlObj","xmlNode","textData","docTypeReader","xmlLen","c1","closeIndex","findClosingIndex","lastTagName","tagData","readTagExp","attsMap","tagExp","ver","childNode","attrExpPresent","_ref","_ref2","min","_transformTagName","lastTag","isSelfClosing","tagContent","_transformTagName2","entityConfig","parentNode","errMsg","closingIndex","findClosingChar","closingChar","attrBoundary","closeCode0","closeCode1","segmentStart","tagExpWithClosingIndex","separatorIndex","trimStart","openTagCount","xmllen","shouldParse","fn","newTagName","stripAttributePrefix","prettify","compress","arr","text","compressedObj","tagObj","property","propName","isLeaf","isLeafTag","assignAttributes","attrMap","atrrName","rawAttrName","propCount","XMLParser","parse","validationOption","Buffer","isBuffer","TextDecoder","ignoreBOM","orderedObjParser","orderedResult","addEntity","safeComment","safeCdata","escapeAttribute","resolveTagName","isAttribute","toXml","jArray","indentation","format","stopNodeExpressions","first","versionKey","detectXmlVersionFromArray","arrToStr","xmlStr","isPreviousElementTag","extractAttributeValues","isStopNode","checkStopNode","tagText","attr_to_str","newIdentation","indentBy","tagStart","tagValue","getRawContent","suppressUnpairedNode","suppressEmptyNode","endsWith","attr","item","attStr","attr_to_str_raw","nestedContent","attrVal","suppressBooleanAttributes","cleanAttrName","resolvedAttrName","textValue","entity","a","oneListGroup","Builder","attrPrefixLen","processTextOrObjNode","indentate","tagEndChar","newLine","object","extractAttributes","rawContent","buildRawContent","buildAttributesForStopNode","buildObjectNode","j2x","buildTextValNode","repeat","build","jObj","buildFromOrderedJs","arrayNodeName","decl","v","detectXmlVersionFromObj","isCurrentStopNode","resolvedKey","Date","resolvedAttr","buildAttrPairStr","closeTag","arrLen","listTagVal","listTagAttr","Ks","L","attrGroup","attrKey","nestedAttrs","cleanKey","tagEndExp","piClosingChar","safeVal","XMLValidator"],"sourceRoot":""}